Find the intersection of a line with a plane: Difference between revisions
(Created page with "Category:Geometry Category:Collision detection {{draft task}}Finding the intersection of an infinite ray with a plane in 3D is an important topic in collision detectio...") |
Thundergnat (talk | contribs) (→{{header|Perl 6}}: Add Perl 6 example) |
||
Line 6: | Line 6: | ||
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]. |
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]. |
||
=={{header|Perl 6}}== |
|||
{{works with|Rakudo|2016.11}} |
|||
{{trans|Python}} |
|||
<lang perl6>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) ) |
|||
);</lang> |
|||
{{out}} |
|||
<pre>Intersection at point: (0 -5 5)</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 21:15, 20 December 2016
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
<lang perl6>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) ) );</lang>
- Output:
Intersection at point: (0 -5 5)
Python
Based on the approach at geomalgorithms.com[1]
<lang python>#!/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)</lang>
- Output:
intersection at [ 0 -5 5]