39

線(ベクトルまたは線上の2つの点で表される)が与えられた場合、線が平面と交差する点を見つけるにはどうすればよいですか?私はこれについてたくさんのリソースを見つけましたが、そこでの方程式を理解することはできません(それらは標準的な代数ではないようです)。標準のプログラミング言語(Javaを使用しています)で解釈できる方程式(どれだけ長くても)が欲しいのですが。

4

8 に答える 8

27

これは、直線と平面の交点を見つける Java のメソッドです。含まれていないベクトル メソッドがありますが、それらの機能は一目瞭然です。

/**
 * Determines the point of intersection between a plane defined by a point and a normal vector and a line defined by a point and a direction vector.
 *
 * @param planePoint    A point on the plane.
 * @param planeNormal   The normal vector of the plane.
 * @param linePoint     A point on the line.
 * @param lineDirection The direction vector of the line.
 * @return The point of intersection between the line and the plane, null if the line is parallel to the plane.
 */
public static Vector lineIntersection(Vector planePoint, Vector planeNormal, Vector linePoint, Vector lineDirection) {
    if (planeNormal.dot(lineDirection.normalize()) == 0) {
        return null;
    }

    double t = (planeNormal.dot(planePoint) - planeNormal.dot(linePoint)) / planeNormal.dot(lineDirection.normalize());
    return linePoint.plus(lineDirection.normalize().scale(t));
}
于 2018-10-08T23:23:10.147 に答える
19

次の 3 つのケースを考慮する必要があります。

  • 平面は線に平行で、線は平面内にありません (交差なし)
  • 平面が直線と平行ではありません (1 つの交点)
  • 平面には線が含まれます (線はその上のすべての点で交差します)

次のように、行をパラメーター化された形式で表現できます。

http://answers.yahoo.com/question/index?qid=20080830195656AA3aEBr

この講義の最初の数ページでは、平面について同じことを行います。

http://math.mit.edu/classes/18.02/notes/lecture5compl-09.pdf

平面の法線が線に沿った方向に垂直である場合は、エッジ ケースがあり、まったく交差しているか、平面内にあるかを確認する必要があります。

それ以外の場合は、交点が 1 つあり、それを解くことができます。

これがコードではないことはわかっていますが、堅牢なソリューションを得るには、おそらくこれをアプリケーションのコンテキストに入れたいと思うでしょう。

編集:交点が 1 つだけある例を次に示します。最初のリンクのパラメーター化された方程式から始めるとします。

x = 5 - 13t
y = 5 - 11t
z = 5 - 8t

パラメータtは何でもかまいません。(x, y, z)これらの方程式を満たすすべての (無限の) セットが直線を構成します。次に、平面の方程式がある場合は、次のように言います。

x + 2y + 2z = 5

(ここxから取得) 、y、および上記の方程式を平面の方程式に置き換えることができます。zこれは現在、パラメーター のみにありますt。を解きtます。tこれは、平面上にある線の特定の値です。次に、直線方程式に戻って代入することによりx、 、y、およびを解くことができます。zt

于 2011-04-14T16:38:24.437 に答える
16

Using numpy and python:

#Based on http://geomalgorithms.com/a05-_intersect-1.html
from __future__ import print_function
import numpy as np

epsilon=1e-6

#Define plane
planeNormal = np.array([0, 0, 1])
planePoint = np.array([0, 0, 5]) #Any point on the plane

#Define ray
rayDirection = np.array([0, -1, -1])
rayPoint = np.array([0, 0, 10]) #Any point along the ray

ndotu = planeNormal.dot(rayDirection) 

if abs(ndotu) < epsilon:
    print ("no intersection or line is within plane")

w = rayPoint - planePoint
si = -planeNormal.dot(w) / ndotu
Psi = w + si * rayDirection + planePoint

print ("intersection at", Psi)
于 2016-09-10T08:29:34.367 に答える
0

ZGorlockの答えを拡張するために、3Dベクトルの内積、加算、およびスケーリングを行いました。これらの計算の参照は、Dot ProductAdd two 3D vector、およびScalingです。注: Vec3D は、点 x、y、z を持つ単なるカスタム クラスです。

/**
 * Determines the point of intersection between a plane defined by a point and a normal vector and a line defined by a point and a direction vector.
 *
 * @param planePoint    A point on the plane.
 * @param planeNormal   The normal vector of the plane.
 * @param linePoint     A point on the line.
 * @param lineDirection The direction vector of the line.
 * @return The point of intersection between the line and the plane, null if the line is parallel to the plane.
 */
public static Vec3D lineIntersection(Vec3D planePoint, Vec3D planeNormal, Vec3D linePoint, Vec3D lineDirection) {
    //ax × bx + ay × by
    int dot = (int) (planeNormal.x * lineDirection.x + planeNormal.y * lineDirection.y);
    if (dot == 0) {
        return null;
    }

    // Ref for dot product calculation: https://www.mathsisfun.com/algebra/vectors-dot-product.html
    int dot2 = (int) (planeNormal.x * planePoint.x + planeNormal.y * planePoint.y);
    int dot3 = (int) (planeNormal.x * linePoint.x + planeNormal.y * linePoint.y);
    int dot4 = (int) (planeNormal.x * lineDirection.x + planeNormal.y * lineDirection.y);

    double t = (dot2 - dot3) / dot4;

    float xs = (float) (lineDirection.x * t);
    float ys = (float) (lineDirection.y * t);
    float zs = (float) (lineDirection.z * t);
    Vec3D lineDirectionScale = new Vec3D( xs, ys, zs);

    float xa = (linePoint.x + lineDirectionScale.x);
    float ya = (linePoint.y + lineDirectionScale.y);
    float za = (linePoint.z + lineDirectionScale.z);

    return new Vec3D(xa, ya, za);
}
于 2018-11-13T13:35:02.143 に答える