View Full Version : How to align an object to a normal vector of a face?
MrSparkle 03282006, 05:09 PM Hi,
I want to use to normal direction which is returned by the intersectRay function to align an object. The object's zaxis should point to the normal direction.
I tried to directly manipulate the object's transform matrix but it failed:
p2 = intersectRay $ p1
$.transform = matrix3 (normalize (cross p2.dir [0,1,0])) [0,1,0] (normalize p2.dir) p2.pos
Thanks,
Christian


This might help (taken from maxscript help)
The following code implements the "Normal Align" feature of the UVW_Map modifier. The "Normal Align" button is not directly accessible to MAXScript. This function can be used as a replacement, and might help you understand the usefulness of the Vector Cross Product.
Script:
fn alignUVGizmo theObj theFace =
(
First get the face normal vector.
It is shown in BLUE on the image
faceNormal = incoordsys theObj (getFaceNormal theObj theFace)
This is the desired up vector in world space
It is shown in YELLOW on the image
worldUpVector = [0,0,1]
Now get the crossproduct of the face normal and the up vector.
This will give you a vector that is perpendicular to the plane defined
by the normal and the up vector. Normalize it to get a normal vector
pointing to the right.
It is shown in RED on the image
rightVector = normalize (cross worldUpVector faceNormal)
Now using the face normal and the new vector,
get a vector that is perpendicular to the plane defined by the two.
This is the "local up vector", the vector that is the projection of
the world up vector on the face you selected. This one is perpendicular
to both the face normal and the right vector, and you have 3 normals now
that define the X, Y and Z of your new orthogonal coordinate system
for the UVW gizmo!
Note that this new vector can be seen as the SHADOW of the World Up vector
on the face of the object in the above image.
 It is now displayed in green in the image below:
upVector = normalize ( cross rightVector faceNormal )
Using the 3 vectors, define a matrix3 value which represents the
coordinate system of the gizmo. The face normal is the Z axis,
the right vector is the X axis, and the local up vector is the Y axis:
theMatrix = matrix3 rightVector upVector faceNormal [0,0,0]
theMap = Uvwmap()
modPanel.addModToSelection theMap ui:on
theMap.gizmo.transform = theMatrix
)
MrSparkle
03282006, 05:30 PM
Thank you for your quick reply! This helped me very much.
Hi,
I want to use to normal direction which is returned by the intersectRay function to align an object. The object's zaxis should point to the normal direction.
I tried to directly manipulate the object's transform matrix but it failed:
p2 = intersectRay $ p1
$.transform = matrix3 (normalize (cross p2.dir [0,1,0])) [0,1,0] (normalize p2.dir) p2.pos
Thanks,
Christian
Every Node in Max has a .DIR property which represent its Z axis. So in order to align an object to a normal, in the simplest case when you don't care about the rest of the axes, you can just assign the vector to that property.
(
s = sphere pos:[10,20,30]
t = teapot radius:5
theMesh = snapshotasmesh s
for f = 1 to theMesh.numfaces do
(
theClone = instance t
theClone.dir = getFaceNormal theMesh f
theClone.pos = meshop.getFaceCenter theMesh f
)
)
The other way would be to use MatrixFromNormal, set the .row4 to the position of the object and assign to the .transform property.
(
s = sphere pos:[10,20,30]
t = teapot radius:5
theMesh = snapshotasmesh s
for f = 1 to theMesh.numfaces do
(
theClone = instance t
theClone.transform = matrixFromNormal (getFaceNormal theMesh f)
theClone.pos = meshop.getFaceCenter theMesh f
ALTERNATIVE:
 theTM = matrixFromNormal (getFaceNormal theMesh f)
 theTM.row4 = meshop.getFaceCenter theMesh f
 theClone.transform = theTM
)
)
Of course, the example from the Online Help takes the UP vector into account, so it is much more general and advanced.
Finally, shameless plug, you could buy my new DVD to learn more... ;)
MrSparkle
03292006, 12:49 AM
Thanks, Bobo. This is even easier and need less code  and it works, too.
CGTalk Moderation
03292006, 12:49 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.