私は持っています、Path
そしてユーザーがセグメントをクリックするとき、私はそれを2つのセグメントに分割しなければなりません。
ユーザーがクリックするポイントがありますが、そのポイントを含むを取得する方法が見つかりませんLineSegment
。
要素を見つける必要はありませんPath
...しかし、クリックされたパスLineSegment
を作成するセグメントのコレクションの。PathGeometry
どのようにできるのか?
私は持っています、Path
そしてユーザーがセグメントをクリックするとき、私はそれを2つのセグメントに分割しなければなりません。
ユーザーがクリックするポイントがありますが、そのポイントを含むを取得する方法が見つかりませんLineSegment
。
要素を見つける必要はありませんPath
...しかし、クリックされたパスLineSegment
を作成するセグメントのコレクションの。PathGeometry
どのようにできるのか?
これを行うコードがいくつかあります。私の各ポイントは、LineSegmentsとして保存されるのではなく、Pointsコレクションに保存されますが、うまくいくはずです。太さパラメータは線の太さです。
public int HitTestSegments(Point point, double thickness)
{
for (int i = 0; i < Points.Count; ++i)
{
Point p0 = Points[i];
Point p1 = (i + 1 < Points.Count) ? Points[i + 1] : Points[0];
Vector v = p1 - p0;
Vector w = point - p0;
double c1 = w * v;
double c2 = v * v;
double b = c1 / c2;
Point pb = p0 + b * v;
double distance = (point - pb).Length;
if (distance < thickness)
{
return i;
}
}
return -1;
}
私はインターネット上のさまざまなサンプルからこれを一緒にハッキングしました、そして私の数学は驚くべきものではありません。最良のコードではない可能性があります。そうでない場合は、改善を提案してください。
Shaman&lukasが言ったことを拡張するには、本当にやりたいことは、クリックポイントに最も近い線分を見つけることです(ユーザーが線を正確にクリックすることは期待できなかったため)
これを行うには、各線分を調べて、 `(y1-y2)* x +(x2-x1)* y +(x1 * y2-x2 * y1)'式を適用し、回答-最小の結果を生成する線分は、クリックポイントに最も近い線分です。
パスに多数のセグメントがある場合、実行に時間がかかる可能性があるため、おそらくいくつかの最適化を行う必要がありますが、それはまったく新しい話です。
ただし、Pointプロパティがあるため、基本的にn+1ポイントのコレクションがあります。ポイント間の線は単純なlinien方程式です。マウスのポイントがこの方程式を解くかどうかを確認する必要があります(すべての行のコレクションを介して相互作用します)。
方程式:0 = Ax + By+Cまたは単にy=ax + b
そのパラメータを取得する方法はたくさんあります。
ジオメトリから、(y1 --y2)* x +(x2 --x1)* y +(x1 * y2 --x2 * y1)= 0であることがわかります。ここで、x1、y1は線分の最初の点であり、x2、y2 2番目です。これが線の公式です。特定の点P(X、Y)が線に属しているかどうかを判断するには、その座標を線の数式の左側に置き換える必要があり、右側の結果は0または0+-\epsilonになります。
ただし、行がなく、セグメントがあるため、チェックを追加する必要があります。たとえば、Pxはx1以上、x2以下にする必要があります。