Find the intersection of a line with a plane: Difference between revisions

m
→‎{{header|Wren}}: Added libheader.
m (→‎{{header|Wren}}: Added libheader.)
 
(8 intermediate revisions by 6 users not shown)
Line 591:
{{out}}
<pre>The ray intersects the plane at (0.000000,-5.000000,5.000000)</pre>
 
=={{header|EasyLang}}==
{{trans|Lua}}
<syntaxhighlight lang=easylang>
proc minus . l[] r[] res[] .
len res[] 3
for i to 3
res[i] = l[i] - r[i]
.
.
func dot l[] r[] .
for i to 3
res += l[i] * r[i]
.
return res
.
proc scale f . l[] .
for i to 3
l[i] = l[i] * f
.
.
proc inter_point rv[] rp[] pn[] pp[] . res[] .
minus rp[] pp[] dif[]
prd1 = dot dif[] pn[]
prd2 = dot rv[] pn[]
scale (prd1 / prd2) rv[]
minus rp[] rv[] res[]
.
rv[] = [ 0.0 -1.0 -1.0 ]
rp[] = [ 0.0 0.0 10.0 ]
pn[] = [ 0.0 0.0 1.0 ]
pp[] = [ 0.0 0.0 5.0 ]
inter_point rv[] rp[] pn[] pp[] res[]
print res[]
</syntaxhighlight>
 
=={{header|Evaldraw}}==
{{trans|C}}
 
Makes use of the intersectionPoint function to intersect 9 lines with 1 moving plane in a realtime demo.
[[File:Evaldraw line vs plane.png|thumb|alt=Grid of 3x3 3d points intersecting a 3D plane|Shows 3x3 grid of lines intersecting a plane. Gridlines drawn between intersection points. Intersection "time" value projected from 3d intersection point to 2d screen rendering.]]
<syntaxhighlight lang="c">
struct vec{x,y,z;};
enum{GRIDRES=3} // Keep a NxN grid of intersection results.
static vec intersections[GRIDRES][GRIDRES];
static vec ipos = {0,5,-15};
static vec ileft = {-1,0,0};
static vec iup = {0,-1,0};
static vec ifor = {0,0,1};
()
{
cls(0); clz(1e32);
setcam( ipos.x, ipos.y, ipos.z,
ileft.x, ileft.y, ileft.z, // flip right basis to left
iup.x, iup.y, iup.z, // flip down basis to up
ifor.x, ifor.y, ifor.z);
t=klock(0);
vec planePoint = {0,5,0}; // Plane Position
vec pN = {cos(t),1,sin(t)}; // PlaneNormal, un-normalized
normalize(pN);
 
for(x=0; x<GRIDRES; x++)
for(z=0; z<GRIDRES; z++)
{
scale = 4.5; halfgrid = scale*(GRIDRES-1)/2;
vec lineVector = {0,1,0}; // Direction of line
vec linePoint ={-halfgrid+scale*x, 5, -halfgrid+scale*z};
if (vecdot( lineVector, pN ) == 0 )
{
moveto(0,0); printf("Line and Plane dont intersect.");
} else {
vec isect;
isect_time = intersectionPoint(lineVector, linePoint, pN, planePoint, isect);
intersections[x][z] = isect; // Store for drawing grid
//setcol(255,255,0); drawsph(isect.x, isect.y, isect.z, .1);
setcol(255,0,0); line(linePoint, isect);
unproject(isect);
setfont(8,12); setcol(255,255,255); printf("t=%2.1f", isect_time);
}
}
// drawgridPlane
setcol(255,0,255);
for(i=0; i<GRIDRES; i++)
for(j=0; j<GRIDRES; j++) {
vec p00 = intersections[i][j];
vec p10 = intersections[(i+1)%GRIDRES][j];
vec p01 = intersections[i][(j+1)%GRIDRES]; // oob wraps to 0 anyhow
line(p00,p10);
line(p00,p01);
}
setcol(192,192,192); moveto(0,0); printf("Line vs Plane intersection");
}
intersectionPoint(vec lineVector, vec linePoint, vec planeNormal, vec planePoint, vec isect){
vec diff; vecsub(diff,linePoint,planePoint);
vec pd; vecadd(pd, diff,planePoint);
t = -vecdot(diff,planeNormal) / vecdot(lineVector,planeNormal);
vec scaledVec; vecscalar(scaledVec, lineVector, t);
vecadd(isect, pd, scaledVec);
return t;
}
line(vec a, vec b) { moveto(a.x,a.y,a.z); lineto(b.x,b.y,b.z); }
// -------------------------------------- VECTOR MATH
vecScalar( vec out, vec a, s ) {
out.x = a.x * s;
out.y = a.y * s;
out.z = a.z * s;
}
vecAdd( vec out, vec a, vec b) {
out.x = a.x + b.x;
out.y = a.y + b.y;
out.z = a.z + b.z;
}
vecAdd( vec out, vec b) {
out.x += b.x;
out.y += b.y;
out.z += b.z;
}
vecSub( vec out, vec a, vec b) {
out.x = a.x - b.x;
out.y = a.y - b.y;
out.z = a.z - b.z;
}
vecCross( vec out, vec a, vec b) {
out.x = a.y*b.z - a.z*b.y;
out.y = a.z*b.x - a.x*b.z;
out.z = a.x*b.y - a.y*b.x;
}
vecDot( vec a, vec b) {
return a.x*b.x + a.y*b.y + a.z*b.z;
}
length( vec v ) {
return sqrt( vecdot(v,v) );
}
normalize( vec v ) {
len = length(v);
if ( len ) { v.x /= len; v.y /= len; v.z /= len; }
}
unproject(vec pt) { // unproject a 3D screenpoint
vec from_eye; vecsub(from_eye, pt, ipos);
nx = vecdot(from_eye, ileft);
ny = vecdot(from_eye, iup);
nz = vecdot(from_eye, ifor);
if (nz <= 0.5) return; // behind eye
f = xres/2/nz; // 90 degree projection
moveto(nx*f + xres/2, ny*f + yres/2 );
}</syntaxhighlight>
 
=={{header|F Sharp|F#}}==
Line 1,491 ⟶ 1,641:
See task [[geometric algebra]]
 
<syntaxhighlight lang=raku>use Clifford:ver<6.2.1>;
 
# We pick a (non-degenerate) projective basis and we compute
# we define the dual and meet operators.
# the pseudo-scalar along with its square
my $I = [∧] my ($i, $j, $k, $l) = @e;
sub prefix:<∗>($M) { $M/$I }
my $I2 = ($I**2).narrow;
sub infix:<∨>($A, $B) { ∗((∗$B)∧(∗$A)) }
 
my $direction = -$j - $k;
$direction /= sqrt($direction**2);
 
# Homogeneous coordinates of (X, Y, Z) are (X, Y, Z, 1)
my $point = 10*$k + $l;
 
# A projective line is a bivector
my $line = $direction ∧ $point;
 
# A projective plane is a trivector
my $plane = (5*$k + $l) ∧ ($k*-($i∧$j∧$k));
 
# The intersection is the meet, and
my $m = $line ∨ $plane;
# according to the De Morgan Law,
# the meet is the dual of the join of the duals.
my $LINE = $line*$I/$I2;
my $PLANE = $plane*$I/$I2;
my $M = $LINE∧$PLANE;
my $m = $M*$I/$I2;
 
# Affine coordinates of (X, Y, Z, W) are (X/W, Y/W, Z/W)
say $m/($m·$l).narrow X· ($i, $j, $k);</syntaxhighlight>
{{out}}
<pre>(0 -5 5)</pre>
Line 1,679 ⟶ 1,824:
Line definition: x=3*t ; y=2+2*t ; z=4+t
Intersection: P(0.6,2.4,4.2)</pre>
 
=={{header|RPL}}==
≪ → rd rp pn pp
≪ rd rp pp - pn DOT * rd pn DOT /
≫ ≫ '<span style="color:blue">INTLP</span>' STO
 
[ 0 -1 -1 ] [ 0 0 0 ] [ 0 0 1 ] [ 0 0 5 ] <span style="color:blue">INTLP</span>
{{out}}
<pre>
1: [ 0 -5 -5 ]
</pre>
 
=={{header|Ruby}}==
Line 1,932 ⟶ 2,088:
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-vector}}
<syntaxhighlight lang="ecmascript">class Vector3D {
<syntaxhighlight lang="wren">import "./vector" for Vector3
construct new(x, y, z) {
_x = x
_y = y
_z = z
}
 
x { _x }
y { _y }
z { _z }
 
+(v) { Vector3D.new(_x + v.x, _y + v.y, _z + v.z) }
 
-(v) { Vector3D.new(_x - v.x, _y - v.y, _z - v.z) }
 
*(s) { Vector3D.new(s * _x, s * _y, s * _z) }
 
dot(v) { _x * v.x + _y * v.y + _z * v.z }
 
toString { "(%(_x), %(_y), %(_z))" }
}
 
var intersectPoint = Fn.new { |rayVector, rayPoint, planeNormal, planePoint|
Line 1,962 ⟶ 2,099:
}
 
var rv = Vector3DVector3.new(0, -1, -1)
var rp = Vector3DVector3.new(0, 0, 10)
var pn = Vector3DVector3.new(0, 0, 1)
var pp = Vector3DVector3.new(0, 0, 5)
var ip = intersectPoint.call(rv, rp, pn, pp)
System.print("The ray intersects the plane at %(ip).")</syntaxhighlight>
Line 1,972 ⟶ 2,109:
<pre>
The ray intersects the plane at (0, -5, 5).
</pre>
 
=={{header|XPL0}}==
{{trans|Wren}}
<syntaxhighlight lang "XPL0">include xpllib;
 
func real IntersectPoint; real RayVector, RayPoint, PlaneNormal, PlanePoint;
real Diff(3), Prod1, Prod2, Prod3, Prod(3);
[VSub(Diff, RayPoint, PlanePoint);
Prod1:= VDot(Diff, PlaneNormal);
Prod2:= VDot(RayVector, PlaneNormal);
Prod3:= Prod1 / Prod2;
return VSub(Diff, RayPoint, VMul(Prod, RayVector, Prod3));
];
 
real RV, RP, PN, PP, IP;
[RV:= [0., -1., -1.];
RP:= [0., 0., 10.];
PN:= [0., 0., 1.];
PP:= [0., 0., 5.];
IP:= IntersectPoint(RV, RP, PN, PP);
Print("The ray intersects the plane at %1.1f, %1.1f, %1.1f\n", IP(0), IP(1), IP(2));
]</syntaxhighlight>
{{out}}
<pre>
The ray intersects the plane at 0.0, -5.0, 5.0
</pre>
 
9,476

edits