線が点に当たるかどうかを知る関数を作成したいと思います。そのような機能はありますか?また、3D ポイントのサイズをセンチメートル単位で設定したいのですが、その方法がわかりません。
私はあなたの助けに感謝します。
例えば:
ポイントに半径があり、線が真ん中の点に正確に当たらないと仮定すると、線が点に当たるかどうかを示す関数はありますか?
線が点に当たるかどうかを知る関数を作成したいと思います。そのような機能はありますか?また、3D ポイントのサイズをセンチメートル単位で設定したいのですが、その方法がわかりません。
私はあなたの助けに感謝します。
例えば:
ポイントに半径があり、線が真ん中の点に正確に当たらないと仮定すると、線が点に当たるかどうかを示す関数はありますか?
わかりました、どの次元でも機能する古典的なソリューションがあります。
まず第一に、球と線を取得し、それらの適切なモデルを用意する必要があります。Sphere は簡単で、Vector.center
とがあれば簡単です.diameter
。
class Sphere:
def __init__( sphere, center, diameter ):
sphere.center=Vector(center)
sphere.diameter=float(diameter)
ラインはさまざまな方法で定義できるため、初心者にとってはより問題になる可能性があります。最も有用なのは、パラメトリック方程式から得られます。ベクトルには方向が.direction
あり、いくつかの開始点があり.center
ます。.direction
これは単位長であり.center
、(0,0) からの直線上の最も近い点であると仮定します。ほとんどの場合、線を作成する必要があり、ベクトルをポイントする必要があります。
def line_on_two_points( A, B ):
return Line( direction= Vector(B)-A, center=A )
そのため、コンストラクターでdirection
andを修正する必要があります。単位長にするだけで簡単に修正できます。を見つけるには、スカラー射影が必要です。D へのベクトルは次のとおりです。
center
.direction
.center
.direction
A から B まで、および C から A までの単位長として、次のようにラインをcenter
初期化できます。
class Line:
def __init__( line, direction, center ):
line.direction= Vector(direction) / length(direction)
line.center= center - line.direction*dot(center,line.direction)
線がない場合は、次の 2 つの点だけを実行できます。
#class Sphere:
def colide_line_on_two_points( sphere, A, B ):
line=line_on_two_points( A-sphere.center, B-sphere.center)
return length(line.center) < sphere.diameter
しかし、行がある場合は、次のように最適化しようとします。
#class Sphere:
def colide_line( sphere, line ):
return line.distance_to(sphere.center) < sphere.diameter
関数は.distance_to()
少しトリッキーです:
#class Line:
def vector_to( line, P ):
return line.center + line.direction * dot(line.direction,P) - P
def distance_to( line, P ):
return length( line.center + line.direction * dot(line.direction,P) - P )
def move_to( line, P ):
line.center += line.direction * dot(line.direction,P) - P
最後になりましたが、Vector
タイプです。numpy を試しますが、2D、3D ではかなり遅いです。
from numpy import array as Vector
from numpy import dot
from numpy.linalg import norm as length
あなたが探しているのは、線と球の間の交点を見つけるアルゴリズムです。これは、グラフィックス プログラミングで一般的に見られる問題であり、多くの記事で、おそらく私よりもはるかに詳しく説明されています。http://www.lighthouse3d.com/tutorials/maths/ray-sphere-intersection/にあります。
基本的な考え方は、球を線に射影し、ピタゴラスの定理を使用して、交点、球の中心、および射影された点によって形成される結果の直角三角形 を解くことです。
パストレーシング レンダラーで使用したコードは次のとおりです。
hitdata intersectwith(Sphere sphere)
{
d3Vector projected;
float t = V.dot(sphere.pos.subtract(O));
projected = V.normalize().scalarmultiply(t); //the projected vector
float distnce = (projected.subtract(sphere.pos.subtract(O))).magnitude();
//the length between the center of your sphere and the projected point
hitdata outdata; // a class containing the results of the intersection
outdata.hit = false;
outdata.t = 110;
if(t<=0)
{
return outdata;
}
if(distnce<sphere.r)
{// the line is less distant from the center of the sphere than the surface
outdata.hit = true;
float deltaT = sqrtf((sphere.r*sphere.r)-(distnce*distnce));//Pythagorean theorem
outdata.coord = O.add(V.scalarmultiply(t-deltaT));
//calculating intersection coordinates
outdata.normal = outdata.coord.subtract(sphere.pos);
outdata.normal = outdata.normal.normalize();//calculating surface normals
outdata.material = sphere.material;
outdata.t = t-deltaT;
}
return outdata;
}