java填充算法_JAVA实现扫描线算法(超详细)

首先说一下,教科书上的扫描线算法确实是用c++很好实现,而且网上有很多源码,而java实现的基本没有(可能是我没看到),所以肖先生还是打算自己码(实验作业写这个而自己又个是写java的猿0.0)。

对于扫描线的实现过程,我只在这里大概讲下书本上的内容(自己去看),主要还是讲一下自己实现时算法的改动和实现方法。

扫描线算法:顾名思义,就是从Ymin开始扫描,然后构建出NET,之后根据NET建立AET。

贴个图:

e8be26d1ba7f05c7b7d125749f26d70b.png

54da0d322203a844873fcde719db7492.png

实现的时候首先是构造NET,因为对于java来说不能像c++一样直接用指针所以我用对象数组和Node类(如下代码)构造了类似数组+指针的数据结构。在实现了NET后开始通过NET实现AET,在这里我改变了一种实现方式,教科书上是一次次遍历扫描线,然后将NET插入AET后进行排序等一系列操作,而我因为是自己写的数据结构,如果说再建个表按书上的方式来最后还得自己实现链表排序等一系列操作。所以我这里直接用一个包含Arraylist的对象数组代替了。我的方法是:直接从NET开始遍历每个节点,得到节点后将它以及它自己之后会引申出的插入AET的节点(比如当前扫描线y=0 节点  X:1 dx:-1  Ymax:3 那之后会插入AET的就是 0 -1 1  和   -1  -1  2 )将这些节点不论顺序的先插入AET对应扫描线位置的对象数组的list中,将NET中节点全部遍历完之后再最后对AET中每个对象数组的list进行排序。最后得到了NET在进行打印。

贴个代码(仅供参考学习交流):

package PolygonScanningAndFilling;

public class Node { //新编表记录x,dx,yMax

public int x;

public float dx;

public int yMax;

public Node next;

public int ymin;

public Node(int x, int dx, int yMax){

this.x=x;

this.dx=dx;

this.yMax=yMax;

}

public void getYmin(int Ymin){

this.ymin=Ymin;

}

}

package PolygonScanningAndFilling;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

public class classAndArray {

public List list = new ArrayList();

public classAndArray(){

}

public void listSort() {

Collections.sort(list);

}

}

package PolygonScanningAndFilling;

import java.util.Iterator;

import java.util.Timer;

import java.util.TimerTask;

import javax.swing.*;

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.io.IOException;

public class PolygonScanning extends JPanel {

static int X0;

static int Y0;

static int X1;

static int Y1;

static int a[]=new int [10]; //保存点击的10个x坐标

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
扫描线种子填充算法是一种图形学算法,用于将一个封闭图形的内部区域填充为指定的颜色。下面是一份 Java 代码实现。 ```java import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.LinkedList; import java.util.Queue; import javax.swing.JFrame; import javax.swing.JPanel; public class ScanlineSeedFill extends JPanel { private static final long serialVersionUID = 1L; private static final int WIDTH = 500; private static final int HEIGHT = 500; private static final int SEED_X = 250; private static final int SEED_Y = 250; private int[][] pixels = new int[WIDTH][HEIGHT]; private Queue<Point> queue = new LinkedList<>(); public ScanlineSeedFill() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(WIDTH, HEIGHT); frame.add(this); frame.setVisible(true); // 初始化像素数组,将所有像素设为白色 for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { pixels[i][j] = Color.WHITE.getRGB(); } } // 将种子点入队,并设置为黑色 queue.add(new Point(SEED_X, SEED_Y)); pixels[SEED_X][SEED_Y] = Color.BLACK.getRGB(); // 扫描线种子填充算法 while (!queue.isEmpty()) { Point p = queue.remove(); int x = p.x; int y = p.y; // 向上填充 int i = x; int j = y - 1; while (j >= 0 && pixels[i][j] != Color.BLACK.getRGB()) { pixels[i][j] = Color.BLACK.getRGB(); if (i > 0 && pixels[i - 1][j] != Color.BLACK.getRGB()) { queue.add(new Point(i - 1, j)); } if (i < WIDTH - 1 && pixels[i + 1][j] != Color.BLACK.getRGB()) { queue.add(new Point(i + 1, j)); } j--; } // 向下填充 i = x; j = y + 1; while (j < HEIGHT && pixels[i][j] != Color.BLACK.getRGB()) { pixels[i][j] = Color.BLACK.getRGB(); if (i > 0 && pixels[i - 1][j] != Color.BLACK.getRGB()) { queue.add(new Point(i - 1, j)); } if (i < WIDTH - 1 && pixels[i + 1][j] != Color.BLACK.getRGB()) { queue.add(new Point(i + 1, j)); } j++; } // 向左填充 i = x - 1; j = y; while (i >= 0 && pixels[i][j] != Color.BLACK.getRGB()) { pixels[i][j] = Color.BLACK.getRGB(); if (j > 0 && pixels[i][j - 1] != Color.BLACK.getRGB()) { queue.add(new Point(i, j - 1)); } if (j < HEIGHT - 1 && pixels[i][j + 1] != Color.BLACK.getRGB()) { queue.add(new Point(i, j + 1)); } i--; } // 向右填充 i = x + 1; j = y; while (i < WIDTH && pixels[i][j] != Color.BLACK.getRGB()) { pixels[i][j] = Color.BLACK.getRGB(); if (j > 0 && pixels[i][j - 1] != Color.BLACK.getRGB()) { queue.add(new Point(i, j - 1)); } if (j < HEIGHT - 1 && pixels[i][j + 1] != Color.BLACK.getRGB()) { queue.add(new Point(i, j + 1)); } i++; } // 刷新画面 repaint(); } } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { g.setColor(new Color(pixels[i][j])); g.drawLine(i, j, i, j); } } } public static void main(String[] args) { new ScanlineSeedFill(); } } ``` 上述代码中,像素数组 `pixels` 表示所有像素的颜色,种子点 `(SEED_X, SEED_Y)` 表示填充的起点。将种子点入队后,不断执行以下操作: 1. 取出队首点 `(x, y)`; 2. 向上、下、左、右四个方向填充,直至遇到边界或已填充的像素; 3. 将新的像素点入队; 4. 重复执行步骤 1。 最终,所有与种子点相连的区域都将被填充为黑色。在每次填充后都刷新画面,可以看到填充的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值