19

I would like to distort or map a given JPEG so that it looks 3D when viewed from certain angle, as in this YouTube video. The most interesting part of the video:

perspective

I usually use conformal mapping (a complex function) to do my distortions. Can you help me with figuring out which function to use for this?

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
Dr. Parasolian
  • 199
  • 1
  • 3

1 Answers1

29
lin[cam_, obj_][t_] := cam  t + (1 - t) obj
s[cam_, obj_] := First@Solve[lin[cam, obj][t][[3]] == 0, t];
tr[cam_, obj_] := lin[cam, obj][t] /. s[cam, obj] // FullSimplify

And that's it: tr[ ] is your transformation function. Let's test it with a Rubik's cube, simulating the video you linked. The following boring part is building the cube. We will make only three faces, since the rest aren't visible.

(*The following is a face with random colors*)
d = .05; col := RandomChoice[{Red, Orange, Green, White, Yellow, Blue}];
face := Table[{col, EdgeForm[Black], Polygon[{{i + d, j + d, 0}, {i + 1 - d, j + d, 0}, 
                                              {i + 1 - d, j + 1 - d, 0}, {i + d, j + 1 - d, 0}}]}, 
             {i, 0, 2}, {j, 0, 2}]

(*Now we build a "3-faced-cube"*)
m = RotationTransform[Pi, {0, 1, 0}, 3/2 {1, 0, 1}];
cube = Table[(face /. Polygon[x_] :> Polygon[m /@ (RotateLeft[#, i] & /@ x)]), {i, 0, 2}];
Graphics3D[cube, Axes -> True, Lighting -> {{"Ambient", White}}]

Mathematica graphics

And now (surprise!) we project the cube onto a sheet of paper using the function defined at the top. Let's see two views. First, the one faking a 3D view made by selecting the appropriate ViewPoint and ViewVector (meaning the camera position and direction):

Graphics3D[cube /. Polygon[x_] :> Polygon[tr[{10, -10, 10}, #] & /@ x], 
           Lighting -> "Neutral", ViewVector -> {{10, -10, 10}, {0, 3, 0}}, Boxed -> True]

Mathematica graphics

And now the "real" paper sheet for you to print it and make your own video :)

Framed@Graphics[cube /. (Polygon[x_] :> Polygon[tr[{10, -10, 10}, #] & /@ x]) /. 
                Polygon[x_] :> Polygon[Most /@ x]]

Mathematica graphics

Edit:

Raising and then lowering the camera:

enter image description here .

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
  • What are we looking at? How does it relate to what we see in the video? – C. E. Dec 06 '13 at 20:51
  • 2
    @C. E. The dots on the z==0 plane are the 2-d projection for the front face and top face of the cube as you should draw them to fake the appearance for the camera at a certain position (cam in my code) – Dr. belisarius Dec 06 '13 at 20:54
  • @Anon Perhaps it's clear now :) – Dr. belisarius Dec 07 '13 at 06:28
  • Much better! Very nice. – C. E. Dec 07 '13 at 11:05
  • Love the simplicity of this answer. A published a related demonstration some time ago http://demonstrations.wolfram.com/Anamorphic2DImagesThatLookThreeDimensionalFromAParticularVie/ hth – MaTECmatica Dec 09 '13 at 09:31
  • Of course, if you are depicting a 'real' Rubik's cube, orange tiles should not occur on two orthogonal faces of any cube segment. Nor, for that matter, should red be adjacent to orange, blue to green etc :) – geordie Feb 06 '17 at 02:11