From comp.graphics.raytracing Sun Aug 28 18:30:40 1994 Path: uniol!zib-berlin.de!news.th-darmstadt.de!terra.wiwi.uni-frankfurt.de!zeus.rbi.informatik.uni-frankfurt.de!news.dfn.de!darwin.sura.net!howland.reston.ans.net!agate!msuinfo!harbinger.cc.monash.edu.au!news.uwa.edu.au!uniwa.uwa.edu.au!povray From: povray@uwa.edu.au (POVRAY account) Newsgroups: comp.graphics.raytracing Subject: POV-Ray and Moray : Handedness explained Date: 25 Aug 1994 14:53:50 GMT Organization: The University of Western Australia Lines: 266 Message-ID: <33ib9u$25u@styx.uwa.edu.au> NNTP-Posting-Host: uniwa.uwa.edu.au Summary: A document from the POV-Team leader about LHC vs RHC Keywords: LHC RHC POV-RAY MORAY YOUNG X-Newsreader: TIN [version 1.2 PL2] Left and Right Handed Coordinate Systems in POV-Ray and Moray An Opinionated Essay by Chris Young There has been much debate and concern and frustration over the use of Left Handed Coordinates (LHC) and Right Handed Coordinates (RHC) in POV-Ray, Moray and other rendering utilities. This essay is my attempt to share what I think, what I know, and what I think I know on this subject. The question that bothers everyone is "How do I convert Moray's RHC to POV- Ray's LHC?" In an attempt to grab your attention and get the controversy out of the way early on... Moray already converts its RHC to POV-Ray's LHC when it exports its .POV files. Actually it sorta tricks POV-Ray into creating a RHC image using POV-Ray's LHC. Furthermore Lutz does a better job of it in Moray than POV-Ray's own method of doing RHC. All of the confusion has come from those who attempt to convert Moray's RHC into LHC when in fact its already converted. Here is the default Moray camera as sent to me in a message from Lutz... camera { // Camera STDCAM location direction <0.0, 0.0, dirZ> sky <0.0, 0.0, 1.0> // Use right handed-system! up <0.0, 0.0, 1.0> // Where Z is up right <1.3333, 0.0, 0.0> look_at } // where dirZ is calculated according to the aperture the user defines. Notice that the default Moray camera statement, the "right" vector has a positive value. This instruction tells POV-Ray to use a LHC. All .POV files created by Moray use POV-Ray's LHC as is. Although POV-Ray is by default a LHC renderer, it claims to be capable of doing RHC if you want it to. Later on I'll tell you why it is not really capable of doing true RHC despite the fact that I've co-authored 3 books that says it does! If the camera had a negative "right" vector, this tells POV-Ray to use a RHC system. However Moray doesn't use a negative "right". (Probably because it doesn't work) Therefore Moray is doing the conversion for you. If you want to see this for yourself try this example... Load Moray and create a cone. You'll see a unit cone with the point at the origin and the rim at Z = +1. Instruct Moray to rotate it 90 degrees about the Y axis. The cone will point to the right in the direction of the +X axis. The little box on the screen says "90.0000" but when you export this to a .POV file it looks like this... cone { // Cone001 <0,0,0>, 0 <0,0,1>, 1 rotate <-0.000000, -90.000000, -0.000000> } Moray has reversed all the signs on the rotations. So this is how Moray does it. It tells POV-Ray to use its default LHC and it reverses its rotations to compensate. Note: I have no idea why this works but apearently it does. There is a strong possibility that it shouldn't. It may be a bug in POV-Ray. The reason that coordinate systems are called "Right" or "Left" handed is because you can use your hands as a universal standard and mnemonic device for defining the two non-homogeneous ways of specifying 3D coordinates. Do the following... Hold out both hands in front of you. Turn your palms facing each other. Stick your thumbs up. Point your first finger away from you. Bend your middle finger and/or other fingers 90 degrees from your palm so that they point at the facing palm. In this configuration your thumbs point in the +Y direction, your first finger points +Z and your remaining fingers point +X in the coordinate systems named for those hands. Always label the fingers and thumb the same in either RHC or LHC but use the corresponding hand. Note that no amount of twisting or turning of your wrists can make a your right hand fingers point exactly like your left hand even if you cut your hand off. However if twist your right hand around the proper way (or cut it off ) you can get your right hand to point in the directions or Moray's axes with your thumb (+Y) to point away from you, your index finger (+Z) to point up, and your remaining fingers (+X) to point to the right. So therefore Moray uses Right Handed Coordinates. But it uses Left Handed Rotations! Right and left hands are also used to specify the direction of rotation. The rule says to close your fist and extend your thumb in a traditional "thumbs up" gesture. Then rotate your wrist so that your thumb is pointing in the same direction as the positive axis about which you are rotating. This makes your fingers curl in the positive rotation direction. Note that if you use your right or left hand it makes a difference. Moray positions its axes in a standard RHC orientation but it uses Left Handed Rotation! Note the cone example earlier. I rotated the cone +90 about the Y axis. In RHR the cone would have ended up with its base moving from Z=+1 to X=+1 but it ends up at X=-1. Point your thumbs in the +Y direction while looking at the Moray screen to see that Moray is doing a LHR. My experience is limited in this area. It may be that all "Right Handed" modelers use Right Handed Coordinates with Left Handed Rotations. I just don't know. If other RHC systems use RHR then Moray's RHC with LHR may be part of the confusion. For the record, POV-Ray uses LHC and LHR. So now you're asking... if Moray creates .POV files that use POV-Ray's LHC then why is it hard to mix Moray objects with non-Moray objects? Part of it is the rotational differences but part of it has to do with which way is "up". Let me explain my own confusion with RHC vs LHC because it centers mostly on the "up" issue. When I was in high school and took algebra and geometry, we used a RHC for 3D graphs. I don't recall if they called it RH but it was. They explained it by saying it was an extension of the 2D X,Y Cartesian coordinates we had been using. In turn, that was an extension of the "real number line" which was used to teach about positive and negative real numbers. The X axis was a real number line which extended the across the page left to right with positive numbers increasing to the right. The Y axis was perpendicular to this on the 2D page with positive Y values extending towards the top of the page. All this seems quite intuitive and natural so far. The problem arises with different conventions about what to do with the Z axis. My HS textbook illustrated the +Z axis as though it was coming out of the page towards you. It was an isometric projection with the X and Y axis still perpendicular in their usual positions and the +Z axis extending downward and to the left. Although this was not a true perspective view of the axes, it left you with the impression that you were viewing the axes from a location of about <5,5,10>. Note these are all positive values. Another way that my teachers illustrated it was to instruct us to stand our pencil up on its eraser on a page with an X,Y coordinate system on it. The point of the pencil pointed in the +Z direction. When looking at your desk with the pencil sticking up, your location is more like <5,-10,5>. That is that you are in the -Y space, +X is to the right and +Z is up off the page. This is virtually the same as Moray's default RHC except the default location is slightly -X. You can easily move the camera to the right (+X) to get the same pencil-on-the-desktop view with the pencil playing the role of the Z axis. Note however that the isometric view from <5,5,10> and the desktop view from <5,-10,5> are both RHC systems but our opinions about what is "up" may vary. When looking at a printed page or better yet at the classroom blackboard, it seems that +Y is up. But when looking at your pencil standing on your desk it seems clear that +Z is up. The truth is that "up" is a pretty meaningless term when drawing 3D graphs or plotting spaceship travel so it wasn't important as long as you knew the relative relationship between X, Y, and Z. When ray tracing a real world scene, the concept of "up" is more important. When determining the camera orientation (even in an outer space scene) "up" has meaning to a camera. Note however that every RHC that I ever saw (including Moray) used +Z up. A friend of mine went to a different school system that used different textbooks that used a LHC system. His book drew X and Y the same as mine but they labeled the +Z axis into the page away from you and -Z out of the page towards you. He never stood a pencil on its eraser. The teachers told him to imagine himself traveling along the Z axis. Positive travel was forwards into the book and reverse gear took you in the -Z direction. In this system he never debated which way was "up" because it was ALWAYS +Y no matter where you sat. As an alternative they told him that the numbered pages of his text book increased as he went deeper into the book. This was why +Z went into the page for him but +Z went out of the page for me. This system my friend learned is identical to the LHC that is the default for POV-Ray. The typical POV-Ray camera is at a location like <5,5,-10>. The +Y axis is up, +X to the right, +Z into the screen. I grew up using RHC and +Z up so POV-Ray was difficult for me to understand at first. I finally began to think of my monitor as a blackboard with +Y up and +X to the right. I still get my +/- backwards sometimes on Z however my friend's comments about +Z being straight ahead and pages in a book have sure helped me a lot. Another topic... This is stuff that I just discovered while writing this essay. I said that a POV-Ray camera vector with a negative value like "right <-1.333,0,0>" causes POV-Ray to use RHC. I am sure that this is not totally true. It may be a bug or design limitation in POV-Ray! The logic behind POV-Ray's "right" vector is that the "right" points to the right side of the screen. Hold up both hands in the coordinate positions described earlier. Your middle fingers point +X on either hand. On your right hand, the +X fingers point to the left side of your screen and therefore the "right" side is -X. You're telling POV-Ray to define "right" as a -X value. The way POV-Ray implements this is it cheats. David Buck or whomever, noticed that your right hand is the mirror image of your left. The calculations in our routine Create_Ray in module RENDER.C control the aspect ratio by multiplying the pixel column number by the length of the "right" vector. If that is a negative number then in fact POV-Ray is tracing rows right-to-left but plotting pixels left-to-right! All it is doing is making a mirror image of the scene. Now as long as "up" is +Y and forward is +Z then indeed, the quickest way to make POV-Ray use RHC is to reverse it in a mirror. But traditional RHC like Moray and my HS textbook use +Z up, and +Y forward and +X to the right. It seems that all of POV-Ray expects +Y to be up, +X right etc. If you specify other values you'll get weired results. Note the Moray cone example above rotates -90*y but the resulting object rotates +90*y when rendered. The different use of "up" makes POV-Ray rotate the wrong way! If you attempt to specify "up z*NNN" and "direction y*MMM" but use a value of "right -x*LLL" then you don't get what you'd expect. You'd want a statement like "translate x*5" to move the object to the right side of the screen like Moray does. But POV-Ray doesn't do that. It blindly moves the object left. So it seems that Lutz's method of getting POV-Ray to accurately reproduce RHC is better than POV-Ray's and that people who use negative right vectors to try to import RH data from other sources are going to get wrong results. At this point I'm amazed POV-Ray works at all. Final topic... There is a mistake in Moray's default camera that doesn't hurt anything but it will confuse some people. Moray defines the camera "direction" vector as a +Z value and "up" and "sky" as +Z values too. Theoretically "direction" should be perpendicular to both "right" and "up". Here's the details why... POV-Ray and DKB define their camera using just 4 basic vectors: up, right, location, and direction. Lets call them U, D, R, and L. The rendering engine must have these 4 vectors to work properly. The sky and look_at vectors (S and LA) aren't part of the rendering itself. In fact LA doesn't get stored and S is only used in the LA calculations. The LA vector is actually a type of rotate command that instructs POV-Ray how to turn to look at the specified point. Its job is to modify U, D & R relative to the current L at the time that LA is parsed. If any vector is changed after a LA, then chances are that the camera no longer looks at the specified point. The D vector describes the distance and direction that view plane from is from L. The U and R vectors specify the size and orientation of the view screen. Unless you want really weird special effects or distortion, these three vectors must be mutually perpendicular to each other. The LA modifies U, D & R as follows... Store the length of D. Create a new D that is LA-L. That is, draw a line between the location point and the look_at point. Normalize this new D to length 1, then scale it to the length of the old D. This makes D the same length as it originally was but it now points a different direction. The original direction of D is totally unimportant when look_at is used. Only its length matters. That's why Moray's "direction z*NNN" doesn't hurt anything. Now we're aimed the right direction but which way is up? The actual direction of U doesn't matter when LA is used. Only its length matters. Because the LA may have tilted up or down some, we can no longer say that "up" is exactly +Y. Thats where sky comes in. Take the cross-product of D and S. This gives you a vector perpendicular to both D and S that is the direction of the new R vector. Normalize it and scale it by the length of the old R vector. This results in the new R vector. Now take new R cross new D and scale it to the length of the old U. Make this the new U. So as long as you use LA, the actual direction of U, D, & R don't matter... only their length matters. If you delete the LA vector from a camera then directions of U, D, & R do matter. So in my opinion Lutz should change the Moray camera to use a Y valued "direction" vector in case somebody deletes the "look_at". Well that's all I know. I've not solved any problems on how to convert RHC to/from LHC and I've raised a zillion new questions but perhaps the quality of the debate is better. Chris Young, POV-Ray Team Coordinator 23-August-1994 CIS: 76702,1655 Internet: 76702.1655 Distribute freely. Comments welcome.