DeadlyNightshade

12-10-2012, 02:10 PM

This is the function I use to orient a shell by calculating the angle of a vector (2 UV points) and then rotating the shell accordingly. At the bottom is the function for the arc tangent calculation.

global proc orientEdge()

{

global float $angle;

global float $pointLeft[];

global string $selUVs[];

// Check for valid selection

selCheckUVorEdges();

// Convert selection to UVs in case selection is edges

PolySelectConvert 4;

// Calculate arc tangent in degrees

calcArcTanAngle();

// Reduce arctan angle to 4 decimals only

$angle = `cutDecimals($angle)`;

// Determine rotation type based on arc tangent

// arctan range is -90 deg to +90 deg

global int $invertVal;

if ($angle == 0.0000 || $angle == 90.0000 || $angle == -90.0000)

{

// Type 0 - No rotation

$angle = 0;

} else if ($angle >= -44.9999 && $angle <= 44.9999)

{

// Type A - Invert arctan

$invertVal = 1;

} else if ($angle >= 45.0001 && $angle <= 89.9999)

{

// Type B - Subtract arctan from 90

$angle = 90 - $angle;

$invertVal = 0;

} else if ($angle <= -45.0001 && $angle >= -89.9999)

{

// Type C - Add 45 to arctan

$angle = $angle + 45;

$invertVal = 0;

} else {

// Type D - 45 degrees vector

$angle = 45;

$invertVal = 0;

}

int $invertVal;

if ($invertVal == 1) $angle = -$angle;

// Select the shell and rotate it correctly

SelectUVShell ;

polyEditUV -pivotU $pointLeft[0] -pivotV $pointLeft[1] -angle $angle ;

// Select the original selection

select $selUVs;

}

// Calculate arc tangent angle

// Used for the orientEdge

global proc float calcArcTanAngle()

{

global float $angle;

global float $pointLeft[];

global string $selUVs[];

// Flatten selected UVs

$selUVs = `ls -sl -fl`;

// Get point coordinates

select $selUVs[0];

float $pointA[] = `polyEditUV -q`;

select $selUVs[1];

float $pointB[] = `polyEditUV -q`;

// Get U and V dist

float $uDist, $vDist, $pointLeft[];

// Find left point

if ($pointA[0] >= $pointB[0])

{

$pointLeft = $pointA;

$uDist = ($pointA[0] - $pointB[0]);

$vDist = ($pointA[1] - $pointB[1]);

} else {

$pointLeft = $pointB;

$uDist = ($pointB[0] - $pointA[0]);

$vDist = ($pointB[1] - $pointA[1]);

}

// Calculate arc tangent in degrees

$angle = `atan2d $vDist $uDist`;

return ($angle);

}

But it's not entirely functional. It works most of the time, but I'm having a problem with vectors that go in a SSE to NNW direction (or vice versa). I also sometimes get wrong orientations when the vector is close to 0, 90, -90 or 180

global proc orientEdge()

{

global float $angle;

global float $pointLeft[];

global string $selUVs[];

// Check for valid selection

selCheckUVorEdges();

// Convert selection to UVs in case selection is edges

PolySelectConvert 4;

// Calculate arc tangent in degrees

calcArcTanAngle();

// Reduce arctan angle to 4 decimals only

$angle = `cutDecimals($angle)`;

// Determine rotation type based on arc tangent

// arctan range is -90 deg to +90 deg

global int $invertVal;

if ($angle == 0.0000 || $angle == 90.0000 || $angle == -90.0000)

{

// Type 0 - No rotation

$angle = 0;

} else if ($angle >= -44.9999 && $angle <= 44.9999)

{

// Type A - Invert arctan

$invertVal = 1;

} else if ($angle >= 45.0001 && $angle <= 89.9999)

{

// Type B - Subtract arctan from 90

$angle = 90 - $angle;

$invertVal = 0;

} else if ($angle <= -45.0001 && $angle >= -89.9999)

{

// Type C - Add 45 to arctan

$angle = $angle + 45;

$invertVal = 0;

} else {

// Type D - 45 degrees vector

$angle = 45;

$invertVal = 0;

}

int $invertVal;

if ($invertVal == 1) $angle = -$angle;

// Select the shell and rotate it correctly

SelectUVShell ;

polyEditUV -pivotU $pointLeft[0] -pivotV $pointLeft[1] -angle $angle ;

// Select the original selection

select $selUVs;

}

// Calculate arc tangent angle

// Used for the orientEdge

global proc float calcArcTanAngle()

{

global float $angle;

global float $pointLeft[];

global string $selUVs[];

// Flatten selected UVs

$selUVs = `ls -sl -fl`;

// Get point coordinates

select $selUVs[0];

float $pointA[] = `polyEditUV -q`;

select $selUVs[1];

float $pointB[] = `polyEditUV -q`;

// Get U and V dist

float $uDist, $vDist, $pointLeft[];

// Find left point

if ($pointA[0] >= $pointB[0])

{

$pointLeft = $pointA;

$uDist = ($pointA[0] - $pointB[0]);

$vDist = ($pointA[1] - $pointB[1]);

} else {

$pointLeft = $pointB;

$uDist = ($pointB[0] - $pointA[0]);

$vDist = ($pointB[1] - $pointA[1]);

}

// Calculate arc tangent in degrees

$angle = `atan2d $vDist $uDist`;

return ($angle);

}

But it's not entirely functional. It works most of the time, but I'm having a problem with vectors that go in a SSE to NNW direction (or vice versa). I also sometimes get wrong orientations when the vector is close to 0, 90, -90 or 180