任意の数のセグメントの円弧に目盛りを描画しようとしています。円弧はGeneralPath
オブジェクトです。
円弧に沿ってn 個の目盛りを描画したい(n はアルゴリズムへの入力)。また、弧の始まりと終わりに目盛りを描く必要があります。
そのようなアルゴリズムを見つけることができる場所のポインタはありますか?
任意の数のセグメントの円弧に目盛りを描画しようとしています。円弧はGeneralPath
オブジェクトです。
円弧に沿ってn 個の目盛りを描画したい(n はアルゴリズムへの入力)。また、弧の始まりと終わりに目盛りを描く必要があります。
そのようなアルゴリズムを見つけることができる場所のポインタはありますか?
そうですね、線は 2D ベクトルです。方向を取り、長さを取得し、それを 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 で割ったものになり、パスの長さは個々のセグメントの長さの合計になります。
次に、セグメントを反復し、2 つのティックの間に頂点 (セグメントの始点/終点) がある場合は、その頂点から最後のティックまでの距離を計算し、その頂点から次のティックまでの距離を使用して上記のアルゴリズムを開始します。 .
そんな感じ:
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)
}
PathIteratorを ( GeneralPath. getPath経由で)使用して、アークを構成する (わずかに平坦化された) セグメントに沿って移動する必要があります。2 つのパスを作成できます。1 つはこれらのセグメントの全長を計算するためのもので、もう 1 つは実際にティックを描画するためのものです。2 つのパスの間で、最初と最後のティックを保証しながら、目的のティック長に最も近いティック数を計算できます (または、開始ティックまたは終了ティックが他のティックに近すぎるようにすることもできます。その場合は、1 つのパスのみが必要です)。
実際の描画コードは Thomas のコードに似ていますが、イテレータが平坦化されたパスを進むときにセグメント ジャンプが行われます。