4

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

我想沿弧线绘制n 个刻度线(其中 n 是算法的输入)。我还需要在弧的开始和结束处画一个刻度。

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

4

2 回答 2

2

您真的想使用PathIterator(通过 GeneralPath.getPath 沿着构成您的弧线的(略微扁平的)段行走。您可以进行两次传递 - 一次计算这些段的总长度,另一次实际绘制刻度。在两次通过之间,您可以计算最接近所需刻度长度的刻度数,同时仍保证开始和结束的刻度(或者您可以允许开始或结束刻度距离其他刻度太近,并且那么你只需要一次通过)。

实际的绘图代码与 Thomas 的代码类似,但随着迭代器通过扁平路径前进时会发生段跳跃。

于 2012-07-16T09:16:58.977 回答
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;    
}

这应该为您提供线上刻度线的位置。请注意,您可能应该将计算放入表示 2D 矢量的类中 - 或者更好的是,使用现有的几何库。

更新

由于您使用的是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)
}
于 2012-07-16T08:06:00.573 回答