【问题标题】:Divide a 2D path created from points XY into equal chunks Java将从点 XY 创建的 2D 路径划分为相等的块 Java
【发布时间】:2012-02-26 21:21:20
【问题描述】:

我有一个 A、B、C、D、E...N 点数组,它们在连接时会形成一条路径。

如何将此路径划分为相等的块并获取每个块 XY 的位置?

编辑:正如用户 Hedja 建议的那样,我已经创建了处理此问题的函数,但我无法检测到块在两个子路径上拆分的情况

public ArrayList<PointF> getPositions(ArrayList<PointF> mInput,float mChunkSize){
    ArrayList<PointF> mResult = new ArrayList<PointF>();
    float mModulo = 0f;
    for (int i = 0;i<mInput.size()-1;i++){
        //distance to next
        float mDistanceAB = MyGameMath.distance(mInput.get(i).x, mInput.get(i).y,mInput.get(i+1).x,mInput.get(i+1).y);
        //how many parts will fit 
        float mCountParts = (float) (mDistanceAB/mChunkSize); //how much parts will fit 
        //if distance is greater than chunk size 
        if (Math.abs(mDistanceAB)>=mChunkSize) {
            Log.i("Chunk","Index "+(i)+" -> "+(i+1)+" = "+mCountParts+", rest="+mModulo);
            float dx = mInput.get(i+1).x-mInput.get(i).x;
            float dy = mInput.get(i+1).y-mInput.get(i).y;
            float ux = dx/mDistanceAB;
            float uy = dy/mDistanceAB;
            for (int y=0;y<=mCountParts;y++){
                //for every part
                float nx = mInput.get(i).x+ux*mChunkSize*y;
                float ny = mInput.get(i).y+uy*mChunkSize*y;
                                    //Log.i("Chunk","at:"+nx+","+ny);
                mResult.add(new PointF(nx, ny));
            }
        } 
        mModulo = mDistanceAB%mChunkSize; //how much left from previous subpath
    }
    return mResult;
}

【问题讨论】:

  • 包含x个元素的等长块,x是你指定的?如果你有 12 分,而 x 是 5 怎么办?更具体。

标签: java android math path line


【解决方案1】:

所以我假设您有类似的情况,其中Point 是一个具有xy 属性的对象。

Point[] points = new Points[]{ //Your Points }
List<Point> chunkedPoints = new ArrayList<Point>();

我还假设“等块”是指每条路径的距离。

首先您将遍历数组,因为您不需要计算最后一个点之后的“下一个点”,您可以将其添加到末尾。:

for(int i = 0; i < points.length-1; i++) { //Skip the last element
    //chunking here
}
chunkedPoints.add(points[points.length-1]); //Add the last element

您需要找到单位向量,即您前往下一个点的方向。所以首先你需要从一个点和下一个点得到 x 和 y 的差异:

double dx = point[i].x - point[i+1].x;
double dy = point[i].y - point[i+1].y;

然后从那个点到下一个点的距离(简单的毕达哥拉斯): 双倍距离 = Math.sqrt(dx*dx+dy*dy);

现在可以计算单位向量了

double ux = dx/distance;
double uy = dy/distance;

所以现在你知道要去哪里旅行,你需要指定你想沿着它旅行多远,我会称之为CHUNK_SIZE

double nx = point[i].x + ux*CHUNK_SIZE;
double ny = point[i].y + uy*CHUNK_SIZE;

nxny 是新点的坐标。但是,您需要检查您是否已经通过了下一个点,以便您可以停下来。你的问题没有说明当你到达一个子路径的末端而不移动块大小时你会做什么,所以我假设你只是停在它上面,所以代码变成:

double nx = point[i].x;
double ny = point[i].y;
for(
    //This part can be tidier
    int count = 0;
    count < CHUNK_SIZE && nx+ux != points[i+1].x && ny+uy != points[i+1].y;
    count++
) {
    nx += ux;
    ny += uy;
}
Point newPoint = new Point(nx, ny);

现在您有了新的点,您可以从那里开始,瞄准与之前相同的点,或者如果它与下一个点相同,则从之后的点开始。所以你的循环现在类似于

chunkedPoints.add(points[0]);
for(int i = 0; i < points.length-1; i++) { //Skip the last element
    Point newPoint;
    do {
        //chunking
        newPoint = new Point(nx, ny);
        chunkedPoints.add(newPoint);
    } while(!newPoint.equals(points[i+1]));
}
chunkedPoints.add(points[points.length-1]); //Add the last element

希望有所帮助。

我没有对此进行测试,但我过去做过非常相似的事情,所以它应该可以工作。

编辑:好的,我看过你的编辑,老实说不知道你的问题在问什么。对不起。

【讨论】:

  • 非常感谢您的宝贵时间,我上传了图表以便更好地理解我在说什么:)
  • 啊,我知道了,我发布的方法应该可以解决 chunkedPoints 包含所有点 XY(如 Point 对象)的问题。也许我在某个地方错了?
  • 是的,您的解决方案工作得很好,经过小的更改后我无法检测到从一条路径切换到另一条路径的情况,请查看我粘贴的函数
  • @PawełPlewa 你能发布一些测试用例的输入/输出吗?看起来,y for 循环应该是for(int y=0;y&lt;mCountParts;y++)(没有等号),但我可能是错的。此外,如果下一个点不够远,if-branch if(Math.abs(mDistanceAB)&gt;=mChunkSize) 将跳过该点,您可能需要一个“else”分支,将单点添加到结果中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多