Java 扫描线算法:如何计算交点

Java 扫描线算法:如何计算交点,java,scanline,Java,Scanline,我必须从我们的教授那里实现一个扫描线算法,但我真的不明白如何从扫描线和多边形中获得交点。 以下是算法: 我已经实现了自己的多边形(使用paint(),contains()等方法),多边形的所有边都保存在如下数组中: int[] pointsX; int[] pointsY; public boolean contains(Point test) { boolean result = false; java.awt.Polygon polygon = new java.awt

我必须从我们的教授那里实现一个扫描线算法,但我真的不明白如何从扫描线和多边形中获得交点。 以下是算法:

我已经实现了自己的多边形(使用
paint()
contains()
等方法),多边形的所有边都保存在如下数组中:

int[] pointsX;
int[] pointsY;
public boolean contains(Point test) {
    boolean result = false;

    java.awt.Polygon polygon = new java.awt.Polygon(pointsX, pointsY, pointsX.length);
    if (polygon.contains(test)) {
        result = true;
    }

    return result;
}
for (int c = ymin; c <= ymax; c++) {
        for (int xTemp = xmin; xTemp <= xmax; xTemp++) {
            for (int currentEdge = 0; currentEdge < edges.size() - 1; currentEdge++) {
                int x1 = edges.get(currentEdge).x;
                int x2 = edges.get(currentEdge + 1).x;
                int y1 = edges.get(currentEdge).y;
                int y2 = edges.get(currentEdge + 1).y;
                if ((y1 <= c && y2 > c) || (y2 <= c && y1 > c)) {
                    intersectionPoints.add(new Point((x1 + (x2 - x1) / (y2 - y1) * (c - y1)),c));
                }
            }
        }
    }
我把x和y的最小值和最大值保存在

int ymin, ymax, xmin, xmax;
所以我的第一个想法是,我必须从
0,ymin
开始创建一条扫描线,并检查下一个点是否在多边形内。我是这样实现这个方法的:

int[] pointsX;
int[] pointsY;
public boolean contains(Point test) {
    boolean result = false;

    java.awt.Polygon polygon = new java.awt.Polygon(pointsX, pointsY, pointsX.length);
    if (polygon.contains(test)) {
        result = true;
    }

    return result;
}
for (int c = ymin; c <= ymax; c++) {
        for (int xTemp = xmin; xTemp <= xmax; xTemp++) {
            for (int currentEdge = 0; currentEdge < edges.size() - 1; currentEdge++) {
                int x1 = edges.get(currentEdge).x;
                int x2 = edges.get(currentEdge + 1).x;
                int y1 = edges.get(currentEdge).y;
                int y2 = edges.get(currentEdge + 1).y;
                if ((y1 <= c && y2 > c) || (y2 <= c && y1 > c)) {
                    intersectionPoints.add(new Point((x1 + (x2 - x1) / (y2 - y1) * (c - y1)),c));
                }
            }
        }
    }
当下一个点在多边形内时,我有一个交点,依此类推。为此,我有一个循环:

ArrayList<Point> intersectionPoints = new ArrayList<>();
wasInside = false;
    for (int yTemp = ymin; yTemp <= ymax; yTemp++) {
        for (int xTemp = xmin; xTemp <= xmax; xTemp++) {
            if (wasInside != this.contains(new Point(xTemp, yTemp))) {
                intersectionPoints.add(new Point(xTemp, yTemp));
                wasInside = !wasInside;
            }
        }
    }
ArrayList intersectionPoints=new ArrayList();
wasinder=false;

对于(int yTemp=ymin;yTemp来说,问题是我用
int
数字进行计算,一个
int
除以另一个
int
会导致不准确。所以用
double
数字进行计算就解决了这个问题

这是我计算交点的方法:
edges
是包含边点的
ArrayList
ymin
是最低的y值,`ymax``是最高的y值

for (int yTemp = ymin; yTemp <= ymax; yTemp++) {
        ArrayList<Point> intersectionPoints = new ArrayList<>();

        for (int p = 0; p < edges.size() - 1; p++) {
            int x1, x2, y1, y2;
            double deltax, deltay, x;
            x1 = edges.get(p).x;
            y1 = edges.get(p).y;
            x2 = edges.get(p + 1).x;
            y2 = edges.get(p + 1).y;

            deltax = x2 - x1;
            deltay = y2 - y1;

            int roundedX;
            x = x1 + deltax / deltay * (yTemp - y1);
            roundedX = (int) Math.round(x);
            if ((y1 <= yTemp && y2 > yTemp) || (y2 <= yTemp && y1 > yTemp)) {
                intersectionPoints.add(new Point(roundedX, yTemp));
            }
        }
        //for the last interval
        int x1, x2, y1, y2;
        x1 = edges.get(edges.size() - 1).x;
        y1 = edges.get(edges.size() - 1).y;
        x2 = edges.get(0).x;
        y2 = edges.get(0).y;
        if ((y1 <= yTemp && y2 > yTemp) || (y2 <= yTemp && y1 > yTemp)) {
            intersectionPoints.add(new Point(x1 + (x2 - x1) / (y2 - y1) * yTemp - y1, yTemp));
        }
        //you have to sort the intersection points of every scanline from the lowest x value to thr highest
        Collections.sort(intersectionPoints, new SortXPoints());
        pointsOfScanline.add(intersectionPoints);

for(int yTemp=ymin;yTemp)扫描线agorithm通常保持一组“活动边”(即与当前扫描线相交的边)。“c”只是扫描线的当前y位置。以及(x1,y1)和(x2,y2)点只是一条活动边的端点。你必须根据它们的y值对所有边进行排序,然后让c从ymin移动到ymax,每当你扫描一个角时更新活动边集。谢谢你的提示。我添加了我的尝试,以计算相交点,但其中有错误。我做错了什么?我想我没有我不太理解这个算法……你从来没有说出你要计算的东西。“扫描行”是一类可以计算很多东西的算法。正如@Marco13所说,扫描线本身是一种数据结构,通常包括它当前相交的边、线段、圆弧等的列表。边的端点等以及相交点都作为“事件”处理这会改变扫描线。很抱歉,我想用扫描线算法填充多边形。