Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

(MEL) How Does one get the Angle between 2 adjacent Faces?

absoluteKelvin
Collaborator

(MEL) How Does one get the Angle between 2 adjacent Faces?

absoluteKelvin
Collaborator
Collaborator

timelapse1147.png

I know how to get the normal vector. But im unsure how to get the angle of the 2 adjacent faces as shown in the image. 

https://www.artstation.com/kelvintam
0 Likes
Reply
Accepted solutions (2)
1,400 Views
9 Replies
Replies (9)

Kahylan
Advisor
Advisor

Hi!

 

If you have the two normal vectors, you can just use the angle command to get the angle between them in radian.

 

https://help.autodesk.com/cloudhelp/2022/ENU/Maya-Tech-Docs/Commands/show.html?angle.html&cat=Langua...

 

and if you need it in degrees you can then use the rad_to_deg command to get that

 

https://help.autodesk.com/cloudhelp/2022/ENU/Maya-Tech-Docs/Commands/show.html?rad_to_deg.html&cat=L...

 

I hope it helps!

 

absoluteKelvin
Collaborator
Collaborator

thanks. unfortunately I need the vectors to be pointing in the direction where I drew the arrow. Thats the main part i have trouble wrapping my head around.

https://www.artstation.com/kelvintam
0 Likes

absoluteKelvin
Collaborator
Collaborator

or maybe im mis-understanding how the angle command works.

https://www.artstation.com/kelvintam
0 Likes

mcw0
Advisor
Advisor
Accepted solution

The arrows you drew are tangents, not normals of the faces.  So add 180 to the angle value.

absoluteKelvin
Collaborator
Collaborator

thanks mcw0. that make more sense now.  But now im running another problem is rad_to_deg(`angle($vector1, $vector2)`) is unable to determine the correct angle when it gets close to 180 degrees.

 

global proc vector getFaceNormal( string $pFaceName ) {

	string $polyInfoResult[] = `polyInfo -fn $pFaceName`;
	string $stringToParse = $polyInfoResult[0];
	
	string $items[];
	int $numTokens = `tokenize $stringToParse " " $items`;
	
	float $x = ($items[2]);
	float $y = ($items[3]);
	float $z = ($items[4]);
	
	vector $normal = << $x, $y, $z >>;
	
	string $parentShape[] = `listRelatives -parent -path $pFaceName`;
	string $parentTransform[] = `listRelatives -parent -path $parentShape[0]`;
	
	float $transformMatrix[] = `xform -q -m -ws $parentTransform[0]`;
	
	vector $worldNormal = `pointMatrixMult $normal $transformMatrix`;
	
	vector $unitWorldNormal = unit( $worldNormal );
	
	return $unitWorldNormal;

}

{
    vector $fnormals[];
    string $faces[] = `ls -sl -fl`;
    for($face in $faces){
       $fnormals[`size($fnormals)`] = `getFaceNormal($face)`;
    }

    int $degree = rad_to_deg(`angle $fnormals[0] $fnormals[1]`);
    select -r $faces;
    print ($degree + "\n");
    //print ($degree + 180);
}

 

maya_Q1nR2NX2ip.png

in both cases i get the same results 12 degrees. what should i do to ensure i get the correct angles in degrees?

https://www.artstation.com/kelvintam

absoluteKelvin
Collaborator
Collaborator

So I came across a math formula to calculate the angle of 2 adjacent planes. cos θ = |(n1 . n2)/|(|n1|.|n2|) 

heres my attempt to write the same formula in maya

 

$o = acos((dot($n1,$n2)) / sqrt(((pow($n1.x) 2) + (pow($n1.y) 2) + (pow($n1.z) 2)) * ((pow($n2.x) 2) + (pow($n2.y) 2) + (pow($n2.z) 2)));

 

 

however im getting syntax error. does anyone know how to translate the above formula?

https://www.artstation.com/kelvintam
0 Likes

mcw0
Advisor
Advisor

I think you just need one more parentheses at the end.

0 Likes

mcw0
Advisor
Advisor

Your 12 degrees is the absolute angle of the faces.  If you want to determine if it should be a negative value, then you have to use a cross product.  Your 2 vectors will return a cross product vector.  You take this cross product vector and do a dot product against a vector that you determine represents the positive axis.  If the dot value is positive, then your angle is positive.  If negative, then your angle is negative and should then be 180 - 12 = 168.  Hope that helps.

absoluteKelvin
Collaborator
Collaborator
Accepted solution

thanks mcw. I ended up following this.

dotbetweenfaces.gif

not sure if thats the same idea as what you suggested. I wish I studied more trigonometry back in school.

the code I ended up with thats working.

 

global proc vector getFaceNormal( string $pFaceName ) {

	string $polyInfoResult[] = `polyInfo -fn $pFaceName`;
	string $stringToParse = $polyInfoResult[0];
	
	string $items[];
	int $numTokens = `tokenize $stringToParse " " $items`;
	
	float $x = ($items[2]);
	float $y = ($items[3]);
	float $z = ($items[4]);
	
	vector $normal = << $x, $y, $z >>;
	
	string $parentShape[] = `listRelatives -parent -path $pFaceName`;
	string $parentTransform[] = `listRelatives -parent -path $parentShape[0]`;
	
	float $transformMatrix[] = `xform -q -m -ws $parentTransform[0]`;
	
	vector $worldNormal = `pointMatrixMult $normal $transformMatrix`;
	
	vector $unitWorldNormal = unit( $worldNormal );
	
	return $unitWorldNormal;
    
}

global proc float getAdjacentFaceAngle(string $inFaces[])
{
    vector $fnormals[];
    //string $faces[] = `ls -sl -fl`;
    vector $fPos[];
    for($face in $inFaces){
       $fnormals[`size($fnormals)`] = `getFaceNormal($face)`;
       setToolTo Move;
       select -r $face;
       float $faceCenter[] = `manipMoveContext -q -p Move`;
       $fPos[`size $fPos`] = <<$faceCenter[0], $faceCenter[1], $faceCenter[2]>> ;
    }
    float $upDown = dot($fnormals[0], ($fPos[1] - $fPos[0]));
    //dotProduct = Mathutils.DotVecs(face1.no, (face2.cent - face1.cent))
    //print ("upDown: "+ $upDown + "\n");
    int $degree = rad_to_deg(`angle $fnormals[0] $fnormals[1]`);
    select -r $infaces;
    float $dotProduct = dotProduct($fnormals[0],$fnormals[1],0);
    int $finalAngle;
    //print ("dotProduct: " + $dotProduct + "\n");
    
    if($upDown > 0){
        $finalAngle = 180 - $degree;
    }
    else if($upDown < 0){
        $finalAngle = 180 + $degree;
    }
    else if($upDown == 0){
        if ($dotProduct == 1){
            $finalAngle = 180;
        }
        else if($dotProduct == -1){
            $finalAngle = 360;
        }
    }
    
    //print ($finalAngle + "\n");
    //print $degree;
	return $finalAngle;
}

 

https://www.artstation.com/kelvintam