CloudFlare suffered a massive security issue affecting all of its customers, including Rosetta Code. All passwords not changed since February 19th 2017 have been expired, and session cookie longevity will be reduced until late March.--Michael Mol (talk) 05:15, 25 February 2017 (UTC)

Find the intersection of a line with a plane

From Rosetta Code
Find the intersection of a line with a plane is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Finding the intersection of an infinite ray with a plane in 3D is an important topic in collision detection.
Task

Find the point of intersection for the infinite ray with direction (0,-1,-1) passing through position (0, 0, 10) with the infinite plane with a normal vector of (0, 0, 1) and which passes through [0, 0, 5].

Perl 6[edit]

Works with: Rakudo version 2016.11
Translation of: Python
class Line {
has $.P0; # point
has $.u; # ray
}
class Plane {
has $.V0; # point
has $.n; # normal
}
 
sub infix:<> ( @a, @b where +@a == +@b ) { [+] @a «*» @b } # dot product
 
sub line-plane-intersection ($𝑳, $𝑷) {
my $cos = $𝑷.n⃗ ∙ $𝑳.u; # cosine between normal & ray
return 'Vectors are orthoganol; no intersection or line within plane'
if $cos == 0;
my $𝑊 = $𝑳.P0 «-» $𝑷.V0; # difference between P0 and V0
my $S𝐼 = -($𝑷.n⃗ ∙ $𝑊) / $cos; # line segment where it intersets the plane
$𝑊 «+» $S𝐼 «*» $𝑳.u⃗ «+» $𝑷.V0; # point where line intersects the plane
}
 
say 'Intersection at point: ', line-plane-intersection(
Line.new( :P0(0,0,10), :u⃗(0,-1,-1) ),
Plane.new( :V0(0,0, 5), :n⃗(0, 0, 1) )
);
Output:
Intersection at point: (0 -5 5)

Python[edit]

Based on the approach at geomalgorithms.com[1]

#!/bin/python
from __future__ import print_function
import numpy as np
 
def LinePlaneCollision(planeNormal, planePoint, rayDirection, rayPoint, epsilon=1e-6):
 
ndotu = planeNormal.dot(rayDirection)
if abs(ndotu) < epsilon:
raise RuntimeError("no intersection or line is within plane")
 
w = rayPoint - planePoint
si = -planeNormal.dot(w) / ndotu
Psi = w + si * rayDirection + planePoint
return Psi
 
 
if __name__=="__main__":
#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
 
Psi = LinePlaneCollision(planeNormal, planePoint, rayDirection, rayPoint)
print ("intersection at", Psi)
Output:
intersection at [ 0 -5  5]

Sidef[edit]

Translation of: Perl 6
struct Line {
P0, # point
u⃗, # ray
}
 
struct Plane {
V0, # point
n⃗, # normal
}
 
func dot_prod(a, b) { a »*« b -> sum }
 
func line_plane_intersection(𝑳, 𝑷) {
var cos = dot_prod(𝑷.n⃗, 𝑳.u) ->
|| return 'Vectors are orthogonal'
var 𝑊 = (𝑳.P0 »-« 𝑷.V0)
var S𝐼 = -(dot_prod(𝑷.n⃗, 𝑊) / cos)
𝑊 »+« (𝑳.u⃗ »*» S𝐼) »+« 𝑷.V0
}
 
say ('Intersection at point: ', line_plane_intersection(
Line(P0: [0,0,10], u⃗: [0,-1,-1]),
Plane(V0: [0,0, 5], n⃗: [0, 0, 1]),
))
Output:
Intersection at point: [0, -5, 5]

zkl[edit]

Translation of: Perl 6
Translation of: Python
class Line { fcn init(pxyz, ray_xyz)   { var pt=pxyz, ray=ray_xyz;       } }
class Plane{ fcn init(pxyz, normal_xyz){ var pt=pxyz, normal=normal_xyz; } }
 
fcn dotP(a,b){ a.zipWith('*,b).sum(0.0); } # dot product --> x
fcn linePlaneIntersection(line,plane){
cos:=dotP(plane.normal,line.ray); # cosine between normal & ray
_assert_((not cos.closeTo(0,1e-6)),
"Vectors are orthoganol; no intersection or line within plane");
w:=line.pt.zipWith('-,plane.pt); # difference between P0 and V0
si:=-dotP(plane.normal,w)/cos; # line segment where it intersets the plane
# point where line intersects the plane:
//w.zipWith('+,line.ray.apply('*,si)).zipWith('+,plane.pt); // or
w.zipWith('wrap(w,r,pt){ w + r*si + pt },line.ray,plane.pt);
}
println("Intersection at point: ", linePlaneIntersection(
Line( T(0.0, 0.0, 10.0), T(0.0, -1.0, -1.0) ),
Plane(T(0.0, 0.0, 5.0), T(0.0, 0.0, 1.0) ))
);
Output:
Intersection at point: L(0,-5,5)

References[edit]

  1. http://geomalgorithms.com/a05-_intersect-1.html