计算圆中的每个笛卡尔点

时间:2012-03-25 19:30:57

标签: java arrays algorithm geometry

我有一个数组:int [] [] lawn = new int [980] [1280];

将叶片高度的值存储在草坪上。

在我的模拟中,我有一个机器人绕着草坪切割刀片。

我的机器人具有直径(rDiameter)的圆形。 坐标系用Double完成,我的草坪用Integer。

我开发了两种“算法”,允许机器人切割草坪,但我不满意,因为我的算法精度不够高,性能也不错。

我的问题是,除了我已经想到的想法之外,有没有办法做到这一点?

或者我是否需要更改草坪的实施以获得更好的效果?

如果我不够清楚,请随时提出任何问题。

这是我的两个算法的代码(k代表机器人),centerPosition返回机器人的中心(所以圆圈的中心)

approach with square
    int bottomLeftCornerX = (int) (k.getCenterPosition().getX() - simulParams.getKDiameter() / 2);
    int bottomLeftCornerY = (int) (k.getCenterPosition().getY() - simulParams.getKDiameter() / 2);

    for (int i = bottomLeftCornerX; i < bottomLeftCornerX + simulParams.getKDiameter(); i++) {
        for (int j = bottomLeftCornerY; j < bottomLeftCornerY + simulParams.getKDiameter(); j++) {
            ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(j, i);
        }
    }

这里有一个圆圈方法(基本上它是维基百科中的圆形公式......):

for (int r = 0; r < simulParams.getKDiameter() / 2; r++) {

        for (double t = 0; t < 2 * Math.PI; t = t + 0.1) {
            Point2D p = circumference(k.getCenterPosition().getX(), k.getCenterPosition().getY(), t, r);
            int intX = (int) Math.ceil(p.getX());
            int intY = (int) Math.ceil(p.getY());
                ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(intY, intX);
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

第一种方法(基于边界框)是一个良好的开端。但是你现在只需要添加一个条件来检查边界框内的每个点是否也在圆圈内。

类似的东西:

for each (point p inside bounding-box) {
    if (p inside circle centred at k) {
        cutBlade(p);
    }
}

您可以通过注意到在边界框的每一行(或列)中,需要剪切的刀片集都是邻居来改进这一点。如果计算此范围的终点,则不需要任何条件。

类似的东西:

for each (x inside bounding-box) {
    calculate y_first;
    calculate y_last;
    for (y = y_first; y < y_last; y++) {
        cutBlade(x,y);
    }
}

答案 1 :(得分:0)

为了便于阅读: k.x是x坐标, k.y是y坐标, k.r是半径。

for(int y = (int)Math.max(0, Math.ceil(k.y - k.r)); y <= (int)Math.min(980, Math.floor(k.y + k.r)); y++) {
    doulbe dx = Math.sqrt(k.r * k.r - Math.abs(y-k.y) * Math.abs(y-k.y));
    for(int x = Math.max(0, (int)Math.ceil(k.x - dx)); x <= (int)Math.min(1280, Math.floor(k.x + dx)); x++) {
        cut(x,y);
    }
}

有两个循环:
第一个循环用于y坐标,从k.y - k.r开始直到k.y + k.r如果圆圈完全在场上(我没有知道它是否一直是,如果是,则你无法到达角落,所以从屏幕的顶部到底部 第二个是x坐标。在公式(k.x - x)²+(k.y - y)²=k.r²的帮助下计算出小和最大的x。
有了这个,你只能得到你圈子里的积分。由于doubleint的转化,它有点小。