Android用のマインドマッピングツールを開発しています。このタイプのマインド マップのレイアウトを作成していますhttp://www.examtime.com/files/2013/08/How-to-create-an-online-mind-map.jpg。これらのタイプの線(画像で作成されたもの)を作成して、実行時にオブジェクトを接続する方法はありますか? 助けてください
1 に答える
3 次ベジエ曲線 (スプライン) を調べる必要があります。これを Canvas で簡単に行う方法はありません。概要は次のとおりです。
ベジェ曲線は、2 つの点 (P0 - 起点と P1 - 終点) と 2 つのベクトル (V0 - 曲線が P0 を出る方向、V1 - 曲線が P1 に入る方向) を使用します。この目的のために、P0、P1、V0、V1 はすべて型でなければなりませんPointF
。
パス上の位置を示すために t を使用します。t = 0 の場合、位置は P0 にあり、t = 1 の場合、位置は P1 にあります。0 と 1 の間の t の任意の値がパスに沿っています。0 <= t <= 1。
ここで、例として、「完璧な人はいない」ノードと「後で片付ける」ノードを結ぶ曲線を見てみましょう。
この場合、P0 は「Nobody's perfect」の右中辺、P1 は「Tidy up later」の下中辺になります。
両方のベクトルを出入りするノードに対して垂直にします。したがって、V0 の値は {P1.x - P0.x, 0} になります。このベクトルは右を指し、2 つのノード間の距離に相当する強度を持ちます。同様の方法で、ノードに向かって上向きの V1 ベクトルを作成します: {0, P0.y - P1.y}
ベクトルと点が揃ったので、曲線の描画を開始します。これを行うには、1 で割り切れる小さなステップ値 (0.1、0.025、0.001 など) を使用して t を反復処理します。この値を「ステップ」と呼びましょう。反復ごとに曲線上の点が生成されます。これらの各点の間を線で結びます。
この部分のコード サンプルは次のとおりです。
PointF start, end;
for (float t = 0; t < 1; t += step)
{
start = getBezierPosition(t);
end = getBezierPosition(t + step)
canvas.drawLine(start.x, start.y, end.x, end.y, paint);
}
さて、難しい部分 - 位置 t でのベジエ曲線の位置を計算します。
private PointF getBezierPosition(float t)
{
PointF result = new PointF();
float oneMinusT, x, y;
oneMinusT = 1 - t;
x = oneMinusT * oneMinusT * oneMinusT * P0.x +
3 * oneMinusT * oneMinusT * t * V0.x +
3 * oneMinusT * t * t * V1.x +
t * t * t * P1.x;
y = oneMinusT * oneMinusT * oneMinusT * P0.y +
3 * oneMinusT * oneMinusT * t * V0.y +
3 * oneMinusT * t * t * V1.y +
t * t * t * P1.y;
result.set(x, y);
return result;
}
これは、3 次ベジエ曲線の式です。詳細については、こちらをご覧ください。
P0 と P1 の位置、および V0 と V1 の方向を決定するロジックを実装させます (最良の結果を得るには、出入りするノードに対して常に垂直である必要があることに注意してください)。Pがノードのどちら側にあるかを判断するには、ロジックをいじる必要があります。これは、ノードを1位に配置するために適用するロジックにリンクされる可能性が最も高いです。
また、最良の結果を得るには、描画しているペイントのストローク幅をいじってみてください。たとえば、t = 0 の場合、サイズ 5 のストローク幅を使用し、t = 1 の場合、ストローク サイズ 3 を使用します。それらの間をスムーズに繰り返すようにしてください (したがって、t = 0.5 の場合、ストローク幅は 4 になります)。 .
認めますが、これは数学的に少し重く、初心者の快適ゾーンではないかもしれませんが、その写真で示したような動的な曲線を実現したい場合は、手が汚れないように。
頑張ってね!それがどうなったか教えてください:)