web-dev-qa-db-ja.com

幾何学的な線をプログラムで表す方法は?

私は、その次元に関係なく、ユークリッド空間でいくつかの単純な幾何学的計算を実行するライブラリを設計しようとしています。ポイント、ベクトル、超球、超平面を一般的な方法で表すのは簡単ですが、ラインが次元間でプロパティを共有している場合でも、(無限)ラインを表す一般的な方法を見つけることができません。

私の推測では、パラメトリック方程式を任意の次元の空間の線に拡張するのは簡単であるため、そのパラメトリック方程式のパラメータの一部を保存できると思います。

x = x0 + at
y = y0 + bt
z = z0 + ct
// can be extended to any dimension

しかし、この方程式を使っても、ラインを比較するために何を保存し、何を保存してはいけないのかわかりません。理想的なソリューションでは、Lineタイプの2つのオブジェクト:

  • プログラム的に等しい(operator==)、
  • メモリ内で同じ表現になります。

そのためには何を保存すればよいですか?

5
Morwenn

あなたはあなたのパラメトリック方程式で正しい軌道に乗っていると思います。

あなたが持っているのは、線方程式のベクトル形式です。

L = R + tV

ここで、[〜#〜] r [〜#〜]は[x0、y0、z0]であり、[〜#〜] v [〜#〜]は[a、 b、c]。

方程式を正規化する必要があるだけです。 | [〜#〜] r [〜#〜] |のように[〜#〜] r [〜#〜]の値を見つけることにより、これを実行します。 [〜#〜] r [〜#〜][〜#〜] v [〜#〜]に垂直な場合に発生する最小値、または- RV = 0。

また、tは行を変更せずに任意の値でスケーリングできるので、正規化する必要があります[〜#〜] v [〜#〜]すべての係数を| [〜# 〜] v [〜#〜] |

11
Dancrumb

最低でも、ラインが等しいかどうかを比較するために必要なのは、すでに持っているパラメトリック方程式だけです。

Dancrumbが示唆するように表現されたL、Mが与えられた場合:

L = X + tV
M = Y + tW

次にL == M VとWが平行である場合(またはそれらが単位長といくつかの「正の」方向に正規化されている場合は等しい)、および一部のtについてY = X + tV。

メンバーごとの同等性を得るには、ベクトルの長さと方向を正規化することが最初のステップですが、ポイントを正規化するためのルールも必要です。たとえば、原点に最も近いライン上のポイントを選択し、それを使用できます。

ベクトルとポイントを正規化するための擬似コード:

vec normalize_vec(vec v) {
  // 1. force unit length
  v = v/v.length();
  // 2. force positive direction
  for (int i = 0; i < v.dimension(); ++i) {
    if (v[i] < 0) {
      v = v * -1;
      break;
    }
    if (v[i] > 0)
      break;
    // keep going until the first nonzero element
  }
  return v;
}

point closest(point p, line l) {
  return (a-p).dot(l.vec) * l.vec;
}

line normalize_line(line l) {
  point new_pt = closest(point::Origin, l);
  vec new_vec = normalize(l.vec);
  return line(new_pt, new_vec);
}
5
Useless