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

m
→‎{{header|Wren}}: Added libheader.
(Added solution for Action!)
m (→‎{{header|Wren}}: Added libheader.)
 
(23 intermediate revisions by 12 users not shown)
Line 11:
=={{header|11l}}==
 
<langsyntaxhighlight lang="11l">F intersection_point(ray_direction, ray_point, plane_normal, plane_point)
R ray_point - ray_direction * dot(ray_point - plane_point, plane_normal) / dot(ray_direction, plane_normal)
 
print(‘The ray intersects the plane at ’intersection_point((0.0, -1.0, -1.0), (0.0, 0.0, 10.0), (0.0, 0.0, 1.0), (0.0, 0.0, 5.0)))</langsyntaxhighlight>
 
{{out}}
Line 23:
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
<langsyntaxhighlight Actionlang="action!">INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
 
DEFINE REALPTR="CARD"
TYPE VectorR=[CARD x,y,z] ;REAL POINTER
TYPE VectorR=[REALPTR x,y,z]
 
PROC PrintVector(VectorR POINTER v)
Line 136 ⟶ 137:
Vector(r5,r1,r0,planePoint)
Test(rayVector,rayPoint,planeNormal,planePoint)
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Find_the_intersection_of_a_line_with_a_plane.png Screenshot from Atari 8-bit computer]
Line 154 ⟶ 155:
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;
 
Line 209 ⟶ 210:
Plane_Normal => (0.0, 0.0, 1.0),
Plane_Point => (0.0, 0.0, 5.0)));
end Intersection;</langsyntaxhighlight>
{{out}}
<pre>( 0.000,-5.000, 5.000)</pre>
 
=={{header|APL}}==
<langsyntaxhighlight APLlang="apl">⍝ Find the intersection of a line with a plane
⍝ The intersection I belongs to a line defined by point L and vector V, translates to:
⍝ A real parameter t exists, that satisfies I = L + tV
Line 232 ⟶ 233:
t ← ((P - L) dot N) ÷ V dot N
I ← L + t × V
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 238 ⟶ 239:
0 ¯5 5
</pre>
 
=={{header|Arturo}}==
{{trans|Nim}}
<syntaxhighlight lang="rebol">define :vector [x, y, z][]
 
addv: function [v1 :vector, v2 :vector]->
to :vector @[v1\x+v2\x, v1\y+v2\y, v1\z+v2\z]
 
subv: function [v1 :vector, v2 :vector]->
to :vector @[v1\x-v2\x, v1\y-v2\y, v1\z-v2\z]
 
mulv: function [v1 :vector, v2 :vector :floating][
if? is? :vector v2
-> return sum @[v1\x*v2\x v1\y*v2\y v1\z*v2\z]
else
-> return to :vector @[v1\x*v2, v1\y*v2, v1\z*v2]
]
 
intersect: function [lV, lP, pV, pP][
tdenom: mulv pV lV
if zero? tdenom -> return to :vector @[∞, ∞, ∞]
t: (mulv pV subv pP lP) / tdenom
return addv mulv lV t lP
]
 
coords: intersect to :vector @[0.0, neg 1.0, neg 1.0]
to :vector @[0.0, 0.0, 10.0]
to :vector @[0.0, 0.0, 1.0]
to :vector @[0.0, 0.0, 5.0]
 
print ["Intersection at:" coords]</syntaxhighlight>
 
{{out}}
 
<pre>Intersection at: [x:0.0 y:-5.0 z:5.0]</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">/*
<lang AutoHotkey>/*
; https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection#Algebraic_form
l = line vector
Line 281 ⟶ 317:
Vector_Dot(v, w){
return v.1*w.1 + v.2*w.2 + v.3*w.3
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">; task
l1 := [0, -1, -1]
lo1 := [0, 0, 10]
Line 310 ⟶ 346:
}
MsgBox % output
return</langsyntaxhighlight>
{{out}}
<pre>0.000000, -5.000000, 5.000000
Line 319 ⟶ 355:
=={{header|C}}==
Straightforward application of the intersection formula, prints usage on incorrect invocation.
<syntaxhighlight lang="c">
<lang C>
#include<stdio.h>
 
Line 372 ⟶ 408:
return 0;
}
</syntaxhighlight>
</lang>
Invocation and output:
<pre>
Line 380 ⟶ 416:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
 
namespace FindIntersection {
Line 431 ⟶ 467:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0.00, -5.00, 5.00)</pre>
Line 437 ⟶ 473:
=={{header|C++}}==
{{trans|Java}}
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <sstream>
 
Line 490 ⟶ 526:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0, -5, 5)</pre>
Line 496 ⟶ 532:
=={{header|D}}==
{{trans|Kotlin}}
<langsyntaxhighlight Dlang="d">import std.stdio;
 
struct Vector3D {
Line 551 ⟶ 587:
auto ip = intersectPoint(rv, rp, pn, pp);
writeln("The ray intersects the plane at ", ip);
}</langsyntaxhighlight>
 
{{out}}
<pre>The ray intersects the plane at (0.000000,-5.000000,5.000000)</pre>
 
=={{header|F#|F sharpEasyLang}}==
{{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#}}==
{{trans|C#}}
<langsyntaxhighlight lang="fsharp">open System
 
type Vector(x : double, y : double, z : double) =
Line 590 ⟶ 776:
Console.WriteLine("The ray intersects the plane at {0}", ip)
 
0 // return an integer exit code</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0.00, -5.00, 5.00)</pre>
Line 596 ⟶ 782:
=={{header|Factor}}==
{{trans|11l}}
<langsyntaxhighlight lang="factor">USING: io locals math.vectors prettyprint ;
 
:: intersection-point ( rdir rpt pnorm ppt -- loc )
Line 602 ⟶ 788:
 
"The ray intersects the plane at " write
{ 0 -1 -1 } { 0 0 10 } { 0 0 1 } { 0 0 5 } intersection-point .</langsyntaxhighlight>
{{out}}
<pre>
Line 609 ⟶ 795:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 11-07-2018
' compile with: fbc -s console
 
Line 675 ⟶ 861:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>line intersects the plane at (0, -5, 5)</pre>
Line 681 ⟶ 867:
=={{header|Go}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 722 ⟶ 908:
ip := intersectPoint(rv, rp, pn, pp)
fmt.Println("The ray intersects the plane at", ip)
}</langsyntaxhighlight>
 
{{out}}
Line 731 ⟶ 917:
=={{header|Groovy}}==
{{trans|Java}}
<langsyntaxhighlight lang="groovy">class LinePlaneIntersection {
private static class Vector3D {
private double x, y, z
Line 779 ⟶ 965:
println("The ray intersects the plane at $ip")
}
}</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0.0, -5.0, 5.0)</pre>
Line 786 ⟶ 972:
{{trans|Kotlin}}
Note that V3 is implemented similarly in the external library [https://hackage.haskell.org/package/linear-1.20.7/docs/Linear-V3.html linear].
<langsyntaxhighlight Haskelllang="haskell">import Control.Applicative (liftA2)
import Text.Printf (printf)
 
Line 828 ⟶ 1,014:
rp = V3 0 0 10
pn = V3 0 0 1
pp = V3 0 0 5</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0.0, -5.0, 5.0)</pre>
Line 834 ⟶ 1,020:
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">mp=: +/ .* NB. matrix product
p=: mp&{: %~ -~&{. mp {:@] NB. solve
intersectLinePlane=: [ +/@:* 1 , p NB. substitute</langsyntaxhighlight>
'''Example Usage:'''
<langsyntaxhighlight lang="j"> Line=: 0 0 10 ,: 0 _1 _1 NB. Point, Ray
Plane=: 0 0 5 ,: 0 0 1 NB. Point, Normal
Line intersectLinePlane Plane
0 _5 5</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Kotlin}}
<langsyntaxhighlight Javalang="java">public class LinePlaneIntersection {
private static class Vector3D {
private double x, y, z;
Line 893 ⟶ 1,079:
System.out.println("The ray intersects the plane at " + ip);
}
}</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0.000000, -5.000000, 5.000000)</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
In the following, a 3d vector is represented by a JSON array: [x, y, z]
<syntaxhighlight lang="jq"># add as many as you please
def addVector:
transpose | add;
 
# . - y
def minusVector(y):
[.[0] - y[0], .[1] - y[1], .[2] - y[2]];
 
# scalar multiplication: . * s
def multVector(s):
map(. * s);
 
def dot(y):
.[0] * y[0] + .[1] * y[1] + .[2] * y[2];
 
def intersectPoint($rayVector; $rayPoint; $planeNormal; $planePoint):
($rayPoint | minusVector($planePoint)) as $diff
| ($diff|dot($planeNormal)) as $prod1
| ($rayVector|dot($planeNormal)) as $prod2
| $rayPoint | minusVector($rayVector | multVector(($prod1 / $prod2) )) ;
 
def rv : [0, -1, -1];
def rp : [0, 0, 10];
def pn : [0, 0, 1];
def pp : [0, 0, 5];
 
"The ray intersects the plane at:",
intersectPoint(rv; rp; pn; pp)</syntaxhighlight>
{{out}}
<pre>
The ray intersects the plane at:
[0,-5,5]
</pre>
 
 
=={{header|Julia}}==
Line 901 ⟶ 1,128:
{{trans|Python}}
 
<langsyntaxhighlight lang="julia">function lineplanecollision(planenorm::Vector, planepnt::Vector, raydir::Vector, raypnt::Vector)
ndotu = dot(planenorm, raydir)
if ndotu ≈ 0 error("no intersection or line is within plane") end
Line 920 ⟶ 1,147:
 
ψ = lineplanecollision(planenorm, planepnt, raydir, raypnt)
println("Intersection at $ψ")</langsyntaxhighlight>
 
{{out}}
Line 926 ⟶ 1,153:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.51
 
class Vector3D(val x: Double, val y: Double, val z: Double) {
Line 961 ⟶ 1,188:
val ip = intersectPoint(rv, rp, pn, pp)
println("The ray intersects the plane at $ip")
}</langsyntaxhighlight>
 
{{out}}
Line 969 ⟶ 1,196:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function make(xval, yval, zval)
return {x=xval, y=yval, z=zval}
end
Line 1,006 ⟶ 1,233:
pp = make(0.0, 0.0, 5.0)
ip = intersectPoint(rv, rp, pn, pp)
print("The ray intersects the plane at " .. tostr(ip))</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0, -5, 5)</pre>
 
=={{header|Maple}}==
<langsyntaxhighlight Maplelang="maple">geom3d:-plane(P, [geom3d:-point(p1,0,0,5), [0,0,1]]);
geom3d:-line(L, [geom3d:-point(p2,0,0,10), [0,-1,-1]]);
geom3d:-intersection(px,L,P);
geom3d:-detail(px);</langsyntaxhighlight>
{{Out}}
<pre>[["name of the object",px],["form of the object",point3d],["coordinates of the point",[0,-5,5]]]</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">RegionIntersection[InfiniteLine[{0, 0, 10}, {0, -1, -1}], InfinitePlane[{0, 0, 5}, {{0, 1, 0}, {1, 0, 0}}]]</langsyntaxhighlight>
{{out}}
<pre>Point[{0, -5, 5}]</pre>
Line 1,026 ⟶ 1,253:
=={{header|MATLAB}}==
{{trans|Kotlin}}
<langsyntaxhighlight MATLABlang="matlab">function point = intersectPoint(rayVector, rayPoint, planeNormal, planePoint)
 
pdiff = rayPoint - planePoint;
Line 1,033 ⟶ 1,260:
prod3 = prod1 / prod2;
 
point = rayPoint - rayVector * prod3;</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight MATLABlang="matlab">>> intersectPoint([0 -1 -1], [0 0 10], [0 0 1], [0 0 5])
 
ans =
 
0 -5 5
</syntaxhighlight>
</lang>
 
=={{header|Modula-2}}==
<langsyntaxhighlight lang="modula2">MODULE LinePlane;
FROM RealStr IMPORT RealToStr;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
Line 1,104 ⟶ 1,331:
 
ReadChar;
END LinePlane.</langsyntaxhighlight>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">
<lang Nim>
type Vector = tuple[x, y, z: float]
 
Line 1,141 ⟶ 1,368:
planeVector = (0.0, 0.0, 1.0),
planePoint = (0.0, 0.0, 5.0))
echo "Intersection at ", coords</langsyntaxhighlight>
 
{{out}}
Line 1,148 ⟶ 1,375:
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">package Line; sub new { my ($c, $a) = @_; my $self = { P0 => $a->{P0}, u => $a->{u} } } # point / ray
package Plane; sub new { my ($c, $a) = @_; my $self = { V0 => $a->{V0}, n => $a->{n} } } # point / normal
 
Line 1,175 ⟶ 1,402:
my $P = Plane->new({ V0=>[0,0,5 ], n=>[0, 0, 1]});
print 'Intersection at point: ', join(' ', line_plane_intersection($L, $P)) . "\n";
</syntaxhighlight>
</lang>
{{out}}
<pre>Intersection at point: 0 -5 5</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function dot(sequence a, b) return sum(sq_mul(a,b)) end function
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #008080;">function</span> <span style="color: #000000;">dot</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function intersection_point(sequence line_vector,line_point,plane_normal,plane_point)
atom a = dot(line_vector,plane_normal)
<span style="color: #008080;">function</span> <span style="color: #000000;">intersection_point</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">line_vector</span><span style="color: #0000FF;">,</span><span style="color: #000000;">line_point</span><span style="color: #0000FF;">,</span><span style="color: #000000;">plane_normal</span><span style="color: #0000FF;">,</span><span style="color: #000000;">plane_point</span><span style="color: #0000FF;">)</span>
if a=0 then return "no intersection" end if
<span style="color: #004080;">atom</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dot</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line_vector</span><span style="color: #0000FF;">,</span><span style="color: #000000;">plane_normal</span><span style="color: #0000FF;">)</span>
sequence diff = sq_sub(line_point,plane_point)
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008000;">"no intersection"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return sq_add(sq_add(diff,plane_point),sq_mul(-dot(diff,plane_normal)/a,line_vector))
<span style="color: #004080;">sequence</span> <span style="color: #000000;">diff</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line_point</span><span style="color: #0000FF;">,</span><span style="color: #000000;">plane_point</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">diff</span><span style="color: #0000FF;">,</span><span style="color: #000000;">plane_point</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">dot</span><span style="color: #0000FF;">(</span><span style="color: #000000;">diff</span><span style="color: #0000FF;">,</span><span style="color: #000000;">plane_normal</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">line_vector</span><span style="color: #0000FF;">))</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
?intersection_point({0,-1,-1},{0,0,10},{0,0,1},{0,0,5})
?intersection_point({3,2,1},{0,2,4},{1,2,3},{3,3,3})
<span style="color: #0000FF;">?</span><span style="color: #000000;">intersection_point</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span>
?intersection_point({1,1,0},{0,0,1},{0,0,3},{0,0,0}) -- (parallel to plane)
<span style="color: #0000FF;">?</span><span style="color: #000000;">intersection_point</span><span style="color: #0000FF;">({</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})</span>
?intersection_point({1,1,0},{1,1,0},{0,0,3},{0,0,0}) -- (line within plane)</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">intersection_point</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- (parallel to plane)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">intersection_point</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- (line within plane)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,199 ⟶ 1,429:
"no intersection"
"no intersection"
</pre>
 
=={{header|Picat}}==
{{trans|Java}}
{{works with|Picat}}
<syntaxhighlight lang="picat">
plus(U, V) = {U[1] + V[1], U[2] + V[2], U[3] + V[3]}.
 
minus(U, V) = {U[1] - V[1], U[2] - V[2], U[3] - V[3]}.
 
times(U, S) = {U[1] * S, U[2] * S, U[3] * S}.
 
dot(U, V) = U[1] * V[1] + U[2] * V[2] + U[3] * V[3].
 
intersect_point(RayVector, RayPoint, PlaneNormal, PlanePoint) = IntersectPoint =>
Diff = minus(RayPoint, PlanePoint),
Prod1 = dot(Diff, PlaneNormal),
Prod2 = dot(RayVector, PlaneNormal),
Prod3 = Prod1 / Prod2,
IntersectPoint = minus(RayPoint, times(RayVector, Prod3)).
 
main =>
RayVector = {0.0, -1.0, -1.0},
RayPoint = {0.0, 0.0, 10.0},
PlaneNormal = {0.0, 0.0, 1.0},
PlanePoint = {0.0, 0.0, 5.0},
IntersectPoint = intersect_point(RayVector, RayPoint, PlaneNormal, PlanePoint),
printf("The ray intersects the plane at (%f, %f, %f)\n",
IntersectPoint[1],
IntersectPoint[2],
IntersectPoint[3]
).
</syntaxhighlight>
{{out}}
<pre>
The ray intersects the plane at (0.000000, -5.000000, 5.000000)
</pre>
 
 
=={{header|Prolog}}==
{{trans|Picat}}
{{works with|GNU Prolog}}
{{works with|SWI Prolog}}
<syntaxhighlight lang="prolog">
:- initialization(main).
 
vector_plus(U, V, W) :-
U = p(X1, Y1, Z1),
V = p(X2, Y2, Z2),
X3 is X1 + X2,
Y3 is Y1 + Y2,
Z3 is Z1 + Z2,
W = p(X3, Y3, Z3).
 
vector_minus(U, V, W) :-
U = p(X1, Y1, Z1),
V = p(X2, Y2, Z2),
X3 is X1 - X2,
Y3 is Y1 - Y2,
Z3 is Z1 - Z2,
W = p(X3, Y3, Z3).
 
vector_times(U, S, V) :-
U = p(X1, Y1, Z1),
X2 is X1 * S,
Y2 is Y1 * S,
Z2 is Z1 * S,
V = p(X2, Y2, Z2).
 
vector_dot(U, V, S) :-
U = p(X1, Y1, Z1),
V = p(X2, Y2, Z2),
S is X1 * X2 + Y1 * Y2 + Z1 * Z2.
 
intersect_point(RayVector, RayPoint, PlaneNormal, PlanePoint, IntersectPoint) :-
vector_minus(RayPoint, PlanePoint, Diff),
vector_dot(Diff, PlaneNormal, Prod1),
vector_dot(RayVector, PlaneNormal, Prod2),
Prod3 is Prod1 / Prod2,
vector_times(RayVector, Prod3, Times),
vector_minus(RayPoint, Times, IntersectPoint).
 
main :-
RayVector = p(0.0, -1.0, -1.0),
RayPoint = p(0.0, 0.0, 10.0),
PlaneNormal = p(0.0, 0.0, 1.0),
PlanePoint = p(0.0, 0.0, 5.0),
intersect_point(RayVector, RayPoint, PlaneNormal, PlanePoint, p(X, Y, Z)),
format("The ray intersects the plane at (~f, ~f, ~f)\n", [X, Y, Z]).
</syntaxhighlight>
{{out}}
<pre>
 
The ray intersects the plane at (0.000000, -5.000000, 5.000000)
</pre>
 
Line 1,204 ⟶ 1,528:
Based on the approach at geomalgorithms.com<ref>http://geomalgorithms.com/a05-_intersect-1.html</ref>
 
<langsyntaxhighlight lang="python">#!/bin/python
from __future__ import print_function
import numpy as np
Line 1,230 ⟶ 1,554:
 
Psi = LinePlaneCollision(planeNormal, planePoint, rayDirection, rayPoint)
print ("intersection at", Psi)</langsyntaxhighlight>
 
{{out}}
Line 1,237 ⟶ 1,561:
=={{header|R}}==
{{trans|MATLAB}}
<langsyntaxhighlight Rlang="r">intersect_point <- function(ray_vec, ray_point, plane_normal, plane_point) {
 
pdiff <- ray_point - plane_point
Line 1,246 ⟶ 1,570:
 
return(point)
}</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight Rlang="r">>>intersect_point(c(0, -1, -1), c(0, 0, 10), c(0, 0, 1), c(0, 0, 5))
[1] 0 -5 5</langsyntaxhighlight>
 
=={{header|Racket}}==
{{trans|Sidef}}
<langsyntaxhighlight lang="racket">#lang racket
;; {{trans|Sidef}}
;; vectors are represented by lists
Line 1,276 ⟶ 1,600:
(line-plane-intersection (Line '(0 0 10) '(0 -1 -1))
(Plane '(0 0 5) '(0 0 1)))
'(0 -5 5)))</langsyntaxhighlight>
 
{{out}}
Line 1,286 ⟶ 1,610:
{{trans|Python}}
 
<syntaxhighlight lang="raku" perl6line>class Line {
has $.P0; # point
has $.u⃗; # ray
Line 1,309 ⟶ 1,633:
Line.new( :P0(0,0,10), :u⃗(0,-1,-1) ),
Plane.new( :V0(0,0, 5), :n⃗(0, 0, 1) )
);</langsyntaxhighlight>
{{out}}
<pre>Intersection at point: (0 -5 5)</pre>
 
===With a geometric algebra library===
 
See task [[geometric algebra]]
 
<syntaxhighlight lang=raku>use Clifford:ver<6.2.1>;
 
# We pick a (non-degenerate) projective basis and
# we define the dual and meet operators.
my $I = [∧] my ($i, $j, $k, $l) = @e;
sub prefix:<∗>($M) { $M/$I }
sub infix:<∨>($A, $B) { ∗((∗$B)∧(∗$A)) }
 
my $direction = -$j - $k;
 
# 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
my $m = $line ∨ $plane;
 
# Affine coordinates of (X, Y, Z, W) are (X/W, Y/W, Z/W)
say $m/($m·$l) X· ($i, $j, $k);</syntaxhighlight>
{{out}}
<pre>(0 -5 5)</pre>
 
=={{header|REXX}}==
===version 1===
This program does NOT handle the case when the line is parallel to or within the plane.
<langsyntaxhighlight lang="rexx">/* REXX */
Parse Value '0 0 1' With n.1 n.2 n.3 /* Normal Vector of the plane */
Parse Value '0 0 5' With p.1 p.2 p.3 /* Point in the plane */
Line 1,334 ⟶ 1,689:
z=a.3+t*v.3
 
Say 'Intersection: P('||x','y','z')'</langsyntaxhighlight>
 
{{out}}
Line 1,342 ⟶ 1,697:
===version 2===
handle the case that the line is parallel to the plane or lies within it.
<langsyntaxhighlight lang="rexx">/*REXX*/
Parse Value '1 2 3' With n.1 n.2 n.3
Parse Value '3 3 3' With p.1 p.2 p.3
Line 1,464 ⟶ 1,819:
End
End
Return res </langsyntaxhighlight>
{{out}}
<pre>Plane definition: x+2*y+3*z=18
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}}==
{{trans|C#}}
<langsyntaxhighlight lang="ruby">require "matrix"
 
def intersectPoint(rayVector, rayPoint, planeNormal, planePoint)
Line 1,491 ⟶ 1,857:
end
 
main()</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at Vector[0.0, -5.0, 5.0]</pre>
Line 1,498 ⟶ 1,864:
{{trans|Kotlin}}
 
<langsyntaxhighlight Rustlang="rust">use std::ops::{Add, Div, Mul, Sub};
 
#[derive(Copy, Clone, Debug, PartialEq)]
Line 1,603 ⟶ 1,969:
println!("{:?}", intersect(rv, rp, pn, pp));
}
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">object LinePLaneIntersection extends App {
val (rv, rp, pn, pp) =
(Vector3D(0.0, -1.0, -1.0), Vector3D(0.0, 0.0, 10.0), Vector3D(0.0, 0.0, 1.0), Vector3D(0.0, 0.0, 5.0))
Line 1,631 ⟶ 1,997:
println(s"The ray intersects the plane at $ip")
}</langsyntaxhighlight>
{{Out}}See it in running in your browser by [https://scalafiddle.io/sf/oLTlNZk/0 ScalaFiddle (JavaScript)].
 
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">struct Line {
P0, # point
u⃗, # ray
Line 1,659 ⟶ 2,025:
Line(P0: [0,0,10], u⃗: [0,-1,-1]),
Plane(V0: [0,0, 5], n⃗: [0, 0, 1]),
))</langsyntaxhighlight>
{{out}}
<pre>Intersection at point: [0, -5, 5]</pre>
Line 1,665 ⟶ 2,031:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Module Module1
 
Class Vector3D
Line 1,716 ⟶ 2,082:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}
<pre>The ray intersects the plane at (0.00, -5.00, 5.00)</pre>
Line 1,722 ⟶ 2,088:
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-vector}}
<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,752 ⟶ 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).")</langsyntaxhighlight>
 
{{out}}
<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>
 
=={{header|zkl}}==
{{trans|Raku}}{{trans|Python}}
<langsyntaxhighlight lang="zkl">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; } }
 
Line 1,779 ⟶ 2,152:
//w.zipWith('+,line.ray.apply('*,si)).zipWith('+,plane.pt); // or
w.zipWith('wrap(w,r,pt){ w + r*si + pt },line.ray,plane.pt);
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">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) ))
);</langsyntaxhighlight>
{{out}}
<pre>
9,479

edits