線(ベクトルまたは線上の2つの点で表される)が与えられた場合、線が平面と交差する点を見つけるにはどうすればよいですか?私はこれについてたくさんのリソースを見つけましたが、そこでの方程式を理解することはできません(それらは標準的な代数ではないようです)。標準のプログラミング言語(Javaを使用しています)で解釈できる方程式(どれだけ長くても)が欲しいのですが。
8 に答える
これは、直線と平面の交点を見つける 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));
}
次の 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
、およびを解くことができます。z
t
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)
ZGorlockの答えを拡張するために、3Dベクトルの内積、加算、およびスケーリングを行いました。これらの計算の参照は、Dot Product、Add 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);
}