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, 2016 at 15:20
  • \$\begingroup\$ Any specifications as to required precision? Say 3 decimal figures for example? \$\endgroup\$
    – Luis Mendo
    Oct 2, 2016 at 15:37
  • 2
    \$\begingroup\$ Some test cases would be nice. Also, relevant. \$\endgroup\$
    – orlp
    Oct 3, 2016 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, 2016 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, 2016 at 16:32

6 Answers 6

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, 2016 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, 2016 at 13:59
  • \$\begingroup\$ No other answer shorter than this.. So, i have accepted this answer. \$\endgroup\$ Nov 5, 2017 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, 2016 at 19:30
  • \$\begingroup\$ does it give output in desired format? \$\endgroup\$ Oct 4, 2016 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, 2016 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, 2016 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, 2016 at 16:15
  • \$\begingroup\$ well, remove the extra 20 bytes. no need to comply with my input pattern \$\endgroup\$ Oct 4, 2016 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, 2016 at 20:26
  • \$\begingroup\$ Do the one that saves you most bytes.. \$\endgroup\$ Oct 5, 2016 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 and acknowledge you have read our privacy policy.

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