1

平面セグメント内の点と、セグメントに対する[0,1][0,1]内のその座標を知りたいのですが。例:左下隅0,0、右上隅1,1、中央0.5,0.5

これらは私がすでに知っていることです:

-ポイントは平面セグメントと同じ平面上にあります。-平面セグメントの4点の座標。しかし、それらは時計回りの順序でも、私が知っている順序でもありません。-平面の法線と原点までの距離。そのような; ax + by + cz+d。x、y、z、dは既知です。

これが私が行ったスケッチです: 飛行機 A、B、Cポイントは平面セグメントと同じ平面上にあります。P1、P2、P3、P4座標は既知ですが、意味のある方法で順序付けられていません。

ありがとうございました。

編集:

私が持っている1つのアイデアは

  • ソートポイント

  • 各ポイント間にベクトルを作成します

  • 2点からベクトルを作成する

  • ドット積それら

  • 次数が0から90の間の場合、それは内部にあります

これはうまくいくでしょうか?優れたリアルタイムパフォーマンスが必要ですが、ドット積はCPUで低速ではありませんか?ポイントの相対座標を見つけるにはどうすればよいですか?

4

2 に答える 2

1

私の意見では、これを確認する最良の方法は、平面全体と点を座標系の原点に変換することです。左下の点が座標系の中心になるようにすべての点を変換し、通常のベクトルが次のようになるようにすべてを回転します。軸の1つと平行を指しています。これは、すべてのポイントの行列乗算を意味しますが、この後、どのポイントが長方形にあるかを簡単に確認できます。これはXNAC#の実装ですが、ロジックはどこでも同じです:(入力にスケッチを使用しようとしました)

// Inputs - Right handed coordinate system
Vector3 p1 = new Vector3(-1.0f, 1.0f, 1.0f);  // left top
Vector3 p2 = new Vector3(1.0f, -1.0f, 0.0f);  // right bottom
Vector3 p3 = new Vector3(1.0f, 1.0f, 1.0f);   // right top, redundant if this is a rectangle
Vector3 p4 = new Vector3(-1.0f, -1.0f, 0.0f); // left bottom

Vector3 a = new Vector3(-0.5f, 0.0f, 0.5f);

// Calculating transformation matrix
Vector3 right = Vector3.Normalize(p2 - p4);
Vector3 forward = Vector3.Normalize(p1 - p4);
Vector3 up = Vector3.Cross(right, forward);

Matrix transform = new Matrix();
transform.M11 = right.X;
transform.M12 = right.Y;
transform.M13 = right.Z;
transform.M14 = 0.0f;
transform.M21 = forward.X;
transform.M22 = forward.Y;
transform.M23 = forward.Z;
transform.M24 = 0.0f;
transform.M31 = up.X;
transform.M32 = up.Y;
transform.M33 = up.Z;
transform.M34 = 0.0f;
transform.M41 = p4.X;
transform.M42 = p4.Y;
transform.M43 = p4.Z;
transform.M44 = 1.0f;

transform = Matrix.Invert(transform);

// Transforming
Vector3 tp1 = Vector3.Transform(p1, transform);
Vector3 tp2 = Vector3.Transform(p2, transform);
Vector3 tp3 = Vector3.Transform(p3, transform);
Vector3 tp4 = Vector3.Transform(p4, transform);
Vector3 ta = Vector3.Transform(a, transform);

ta.X /= tp2.X; // divide with rectangle width
ta.Y /= tp1.Y; // divide with rectangle height

// Now everything is on the XY plane
// P1: {X:0    Y:2.236068 Z:0}
// P2: {X:2    Y:0        Z:0}
// P3: {X:2    Y:2.236068 Z:0}
// P4: {X:0    Y:0        Z:0}
// A:  {X:0.25 Y:0.5      Z:0}

これは、任意の4つのポイントで機能します。

これは最速のソリューションではありませんが、行列変換を知っている場合は、最もクリーンでシンプルなソリューションであると確信しています。より速くてシンプルな解決策を見つけたら、私も興味がありますが、おそらくパフォーマンスの問題はないでしょう。私のIntel2.4ghzプロセッサでは、この計算は1秒間に100万回以上問題なく行われます。これがお役に立てば幸いです。

于 2012-03-09T18:11:29.150 に答える
0

欲しいものを見つける方法を見つけました。ここにあります:(コードはC++/Ogreです)

    // top or bottom vector of rectangle
Ogre::Vector3 right = Ogre::Vector3(vertices[3] - vertices[2]); 
right.normalise();
    // vector opposite of the top vector
Ogre::Vector3 left = Ogre::Vector3(vertices[0] - vertices[1]); 
left.normalise();


    // you may store above values if rectangle doesnt move much. this would reduce amount of operations


    // vector from top vertex to position we are checking
Ogre::Vector3 p2ToPos = Ogre::Vector3(pos - vertices[2]);
p2ToPos.normalise();

    // vector from bot vertex to position we are checking
Ogre::Vector3 p1ToPos = Ogre::Vector3(pos - vertices[1]);
p1ToPos.normalise();

    // angle between our vectors
Ogre::Real dot1 = p2ToPos.dotProduct(right);
Ogre::Real dot2 = p1ToPos.dotProduct(left);

    // is both dot products (which gives cos) are positive point is between our rectangle
if(dot1 > 0 && dot2 > 0)
    return true;

これは、2 つの正規化関数と 2 つの内積だけで必要なものを計算します。

于 2012-03-10T14:43:55.183 に答える