4
\$\begingroup\$

Given a ray with a point and a vector and a plane with a point and a normal vector to the plane. You have to find the intersection point of the plane and the ray..

So your job if you choose to accept is to write a shortest function that will do the job.

RULES:
The submission must be a complete program
And that's all

INPUT FORMAT:
x y z rx ry rz //gives the ray point and the ray vectors
x y z px py pz //gives the point on the plane and the vector normal to plane

OUTPUT FORMAT:
(x,y,z) //intersection point

Test Case:
2 3 4 0.577 0.577 0.577
7 1 3 1 0 0
(7,8,9)

The shortest codes in bytes win.

References: https://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm thanks orlp for the reference

\$\endgroup\$
14
  • \$\begingroup\$ then i think i should remove it. \$\endgroup\$ Oct 2 '16 at 15:20
  • \$\begingroup\$ Any specifications as to required precision? Say 3 decimal figures for example? \$\endgroup\$
    – Luis Mendo
    Oct 2 '16 at 15:37
  • 2
    \$\begingroup\$ Some test cases would be nice. Also, relevant. \$\endgroup\$
    – orlp
    Oct 3 '16 at 10:04
  • 1
    \$\begingroup\$ It will be very helpful if the formulae involved are included in the question, else programmers will have to search for them. \$\endgroup\$
    – rnso
    Oct 3 '16 at 13:40
  • 2
    \$\begingroup\$ I would strongly advice to stop enforcing your very specific input/output rules. They really don't add anything to the challenge. \$\endgroup\$
    – Sanchises
    Oct 4 '16 at 16:32
3
\$\begingroup\$

Mathematica, 20 bytes

Takes 4 lists as input. The dot product operator . has precedence over multiplication and division, so no more parentheses are needed.

#+#2(#3-#).#4/#2.#4&

Readable version:

x + v (r - x).n / v.n

where the arguments in order are x (ray point), v (ray direction), r (plane point), n (plane normal).

\$\endgroup\$
3
  • \$\begingroup\$ does it give output in desired format? \$\endgroup\$ Oct 4 '16 at 13:46
  • \$\begingroup\$ @KishanKumar If by desired format you mean with parentheses, then no. Neither is the input a bunch of numbers separated by spaces. Mathematica works in lists, which are enclosed by {} and separated by ,. \$\endgroup\$
    – user58632
    Oct 4 '16 at 13:59
  • \$\begingroup\$ No other answer shorter than this.. So, i have accepted this answer. \$\endgroup\$ Nov 5 '17 at 12:05
3
\$\begingroup\$

Perl, 107 bytes

Tested for all test cases (i.e. not tested at all) Run with each input number on its own line on STDIN

perl -M5.010 plane.pl
0
1
0
0
0
1
3
3
1
0
0
1
^D

plane.pl:

#!/usr/bin/perl
$$_=<>for a..l;say$a+($t=($j*($g-$a)+$k*($h-$b)+$l*($i-$c))/($j*$d+$k*$e+$l*$f))*$d,$",$b+$t*$e,$",$c+$t*$f

This kind of problem is absolutely not a good match for perlgolf. Perl lacks vector operations and uses too many $s

\$\endgroup\$
3
  • 3
    \$\begingroup\$ +1 for "for all test cases". \$\endgroup\$
    – Steven H.
    Oct 3 '16 at 19:30
  • \$\begingroup\$ does it give output in desired format? \$\endgroup\$ Oct 4 '16 at 14:09
  • \$\begingroup\$ It prints the 3 coordinates on one line separated by spaces without (). Adding the (,,) takes 10 trivial bytes (just add the extra characters to the say) \$\endgroup\$
    – Ton Hospel
    Oct 4 '16 at 14:46
1
\$\begingroup\$

Haskell, 137 157/102 bytes

Follows both input and output pattern. Program reads input from stdin. 157 bytes.

z=zipWith
main=do
[(p,r),(l,n)]<-map(splitAt 3.map read.words).lines<$>getContents
print$(\[a,b,c]->(a,b,c))$z(+)p$map(*(sum(z(*)n(z(-)l p))/sum(z(*)n r)))r

With an input file that has format [[x,y,z],[rx,ry,rz],[x,y,z],[px,py,pz]] and output of format [x,y,z] (102 bytes):

z=zipWith
main=do
[p,r,l,n]<-read<$>getContents
print$z(+)p$map(*(sum(z(*)n(z(-)l p))/sum(z(*)n r)))r
\$\endgroup\$
5
  • \$\begingroup\$ does it follow both output and input pattern... \$\endgroup\$ Oct 4 '16 at 14:08
  • \$\begingroup\$ The optional version did. I changed it to do it anyway, at the cost of 20 bytes. \$\endgroup\$
    – Angs
    Oct 4 '16 at 16:15
  • \$\begingroup\$ well, remove the extra 20 bytes. no need to comply with my input pattern \$\endgroup\$ Oct 4 '16 at 17:36
  • \$\begingroup\$ It always complied with the input pattern - the output had different parentheses. I'll add an option that follows neither format. \$\endgroup\$
    – Angs
    Oct 4 '16 at 20:26
  • \$\begingroup\$ Do the one that saves you most bytes.. \$\endgroup\$ Oct 5 '16 at 3:19
1
\$\begingroup\$

R, 88 bytes

x=scan()
v=scan()
r=scan()
n=scan()
C=cat
C("(");C(x+v*sum((r-x)*n)/sum(v*n),sep=", ");C(")")

Adapted from the Mathematica answer. Takes the following values from stdin, x (ray point), v (ray direction), r (plane point), n (plane normal). Outputs (7, 8, 9) for the test case.

\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 157 bytes

This could probably be shorter. The test case is subject to rounding errors, but otherwise it respects the challenge.

P=prompt;[a,b,c,d,e,f,g,h,i,j,k,l]=(P()+' '+P()).split` `.map(e=>+e);alert('('+(a+(t=(j*(g-a)+k*(h-b)+l*(i-c))/(j*d+k*e+l*f))*d)+','+(b+t*e)+','+(c+t*f)+')')
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 93 bytes

(a,b,c,A,B,C,x,y,z,X,Y,Z)=>`(${t=X*(x-a)+Y*(y-b)+Z*(z-c)/(X*A+Y*B+Z*C),[a+t*A,b+t*B,c+t*C]})`

f=
(a,b,c,A,B,C,x,y,z,X,Y,Z)=>`(${t=X*(x-a)+Y*(y-b)+Z*(z-c)/(X*A+Y*B+Z*C),[a+t*A,b+t*B,c+t*C]})`

console.log(f(2, 3, 4, 0.577350269, 0.577350269, 0.577350269, 7, 1, 3, 1, 0, 0))

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.