线段划分的算法

4

我正在尝试在任意数量的片段弧上绘制刻度线。该弧是一个GeneralPath对象。

我想沿着弧线绘制n个刻度线(其中n是算法的输入)。我还需要在弧的起点和终点绘制刻度线。

有没有人知道在哪里可以找到这样的算法?


1
这条线是水平的还是可以倾斜?你使用哪种坐标系?刻度线需要垂直于线吗?还是要与它相交等等? - El Ronnoco
2个回答

2

嗯,一条线是一个二维向量。获取它的方向,计算长度,将其除以n,然后使用起点、方向向量和起点与刻度之间的距离计算刻度的位置。

编辑:

还有一些伪代码:

double unnormalizedDir.x = end.x - start.x;
double unnormalizedDir.y = end.y - start.y;

double length = sqrt(unnormalizedDir.x * unnormalizedDir.x + unnormalizedDir.y * unnormalizedDir.y );

double dir.x = unnormalizedDir.x / length;
double dir.y = unnormalizedDir.y / length;

double tickLength = length / n;

for( int i = 1; i <= n; i++ ) {
  double tick.x = start.x + dir.x * i * ticklength;
  double tick.y = start.y + dir.y * i * ticklength;    
}

这应该为您提供线上刻度的位置。请注意,您可能应该将计算放入表示二维向量的类中 - 或者更好地,使用现有的几何库。
更新:
由于您正在使用GeneralPath,因此此方法仅部分适用。我目前想不出一个聪明的算法,但您可以将路径段视为线或弧,并对其进行迭代。然后,刻度之间的距离将是路径长度除以n,而路径长度将是各个段长度的总和。
然后遍历各个段,如果在两个刻度之间有一个顶点(段的起点/终点),则计算该顶点到上一个刻度的距离,并使用该顶点到下一个刻度的距离开始上述算法。
大致如此:
double distToNextTick = pathLength / n;
double distLastTickToNextVertex = ... ; //calculate
while( distToNextTick > distLastTickToNextVertex ) {
   Point2D nextVertex = ... // get the vertex
   distToNextTick -= distLastTickToNextVertex;

   distLastTickToNextVertex = ...;// calculate again
}

if( distToNextTick == 0.0 ) {
  //the tick is exactly on a vertex
}
else {
  //the tick is on the segment starting at the last vertex
  //for straight lines calculate as above
  //for curves use an appropriate algorithm (depending on the type of curve)
}

2
你真的想要使用 PathIterator(通过 GeneralPath.getPath)来沿着组成弧形的(稍微扁平化的)线段行走。你可以进行两次遍历 - 一次计算这些线段的总长度,另一次实际绘制刻度。在两次遍历之间,你可以计算出最接近所需刻度长度的刻度数,同时仍保证在开始和结束时有刻度(或者你可以允许起始或结束刻度与其他刻度太接近,然后你只需要进行一次遍历)。
实际绘制代码与 Thomas 的类似,但是你的迭代器在穿过扁平化路径时会跳过线段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接