10

I have problem or well, I do not know how to transform 3d point with x,y,z values to 2d point, I have to draw projection, where I do have x,y,z values for points but I don't know how to transform them into 2d so I can move them onto my axis.

enter image description here

I have been looking around wiki and google, howevever I'm not quite sure which matrix transformations should I use to get wanted result.

user2141889
  • 2,255
  • 5
  • 23
  • 25
  • do you know what plane you want to project them onto? how would this plane be given (in what form)? – Bitwise Apr 05 '13 at 21:46
  • Well, tbh I don't know about the plane, however I do have function so I calculate z point taking x y from min max, and then I have to set those points on the axis, that I have painted above and I have no idea how to even start doing this, I've been watching several movies about plotting points however I do have to plot function, so I have to somehow connect the points, I have found that it has to do something with matrix, but well, not sure what matrix transformation should I apply – user2141889 Apr 05 '13 at 22:08
  • You may find useful: http://en.wikipedia.org/wiki/3D_projection and anything related to it –  Apr 09 '13 at 14:40

5 Answers5

14

Let's first assume the camera looking at your scene is centered at the origin, and looking at the -z direction. Then:

  • a perspective projection is given by:
    x' = x/z
    y' = y/z

  • an orthographic projection is given by:
    x' = x
    y' = y
    (i.e., just discard the z component)

Now that you have applied the step above, you might obtain a point that is at (x',y') = (-28.4, +134.5). You now need to scale and center them based on your screen resolution and camera "zoom factor" and aspect ratio : for instance, you might want to multiply by Zoom and add screen_center to both your x and y components (beware: most graphics rendering systems have the y direction pointing down, so you might need to swap signs for the y component). You might still end up with pixels with negative coordinates or whose coordinates are greater than your canvas size. Just discard them : it means that they are outside of your view frustum.

Finally, you might wonder what to do if your camera is not pointing toward -z or not centered at the origin. For the later, it is simple: just subtract the camera coordinates to the component of all your 3D points prior to doing anything else. For the camera rotation, it is also actually quite easy : you just need to rotate your points in the inverse way your camera is rotated prior to doing anything else as well. That just means that you need to multiply all your 3D coordinates by the transpose of the camera rotation matrix. The idea behind this step is that moving the camera around is exactly the same as moving your points in the reverse direction (and it happen that the inverse of a rotation matrix is the transpose of that same matrix).

nbonneel
  • 3,286
  • 4
  • 29
  • 39
3

I would highly recommend using an existing graphics package to do this rather trying to write your own libraries. I don't know what language you are working in but OpenGL is an open source graphics engine that can be used for 3D rendering and has cross-language comparability so it might be the place to start.

If you insist on doing it by hand there is very good example code in the answer to this question.

Community
  • 1
  • 1
Aaron Levenstein
  • 385
  • 2
  • 12
3

You only need to take camera angle into account if you intend to rotate your shape in 3 dimensions. If you have a firm understanding of linear algebra and trigonometry, it's worth the extra effort since it makes your program more flexible, but if your not too string in mathematics I would recommend the following solution.

What you need to be able to do to project a 3D image into a 2D plain is create and equation that will map.

(x,y,z) -> (x',y')

You can do this by defining three mappings form a 3D point to a 2D point.

(1,0,0) -> (  1,  0)
(0,1,0) -> (  0,  1)
(0,0,1) -> (-.7,-.7)

I used (-.7,-.7) for the z access because that point is approximately 1 unit from the origin and half way between the x and y access.

After you have these three points you have enough information to calculate any arbitrary point x,y,z.

(x,y,z) -> (1*x - .7*z, 1*y - .7*z)

In computer graphics the origin of a grid is not in the center of the screen but instead in the top left hand corner. In order use the equation we just generated in our program we must define an offset to move the origin to the center of the screen. We will call this offset point(Ox, Oy).

With the offset our equation becomes the following.

(x,y,z) -> (Ox + 1*x - .7*z, Oy + 1*y - .7*z)
Aaron Levenstein
  • 385
  • 2
  • 12
2

I've found a way to project 3D into Isometric 2D.

I Supposed a angle for Isometric View and of course, a 3D point to project like

Dim IsometricViewAngle As Integer = 30
Dim RowPoint As New Point3D(dx,dy,dz)

which dx, dy and dz are your custom values. then I had to calculate a Delta Value for X and Y Increments and Decrements like

Dim XDelta = Math.Cos(IsometricViewAngle * Math.PI / 180)
Dim YDelta = Math.Sin(IsometricViewAngle * Math.PI / 180)
Dim ZDelta = 0.5

OK, that it, now I'm going to Project 3D points into 2D point:

Dim X As Double = (RowPoint.X * XDelta) + (RowPoint.Y * YDelta)
Dim Y As Double = (RowPoint.X * XDelta) + (RowPoint.Z * ZDelta)
Dim ProjectedPoint As New Point(X,Y)

and the final result works best in RadDiagram. Regards/

Hamed Zakery Miab
  • 738
  • 2
  • 12
  • 34
2

This works for me: (it's in vb). f_nodes are the flat nodes, a_nodes are the 3d nodes after transformation about alpha, beta and gamma. (x,y,z) is a point. There are more sophisticated ones about.

    ca = Cos(alpha)
    sa = Sin(alpha)
    cb = Cos(beta)
    sb = Sin(beta)
    cg = Cos(gamma)
    sg = Sin(gamma)
    q(1) = cg * (cb * X - sb * (sa * Y + ca * z)) - sg * (ca * Y - sa * z)
    q(2) = sg * (cb * X - sb * (sa * Y + ca * z)) + cg * (ca * Y - sa * z)
    q(3) = sb * X + cb * (sa * Y + ca * z)

    f_nodes(i, 1) = q(1)
    f_nodes(i, 2) = q(2)

    a_nodes(i, 1) = q(1)
    a_nodes(i, 2) = q(2)
    a_nodes(i, 3) = q(3)
Chris
  • 21
  • 4