Notifications
Clear all

[Closed] rounding off normal values

Hi,

I’m trying to compare face normals of an object but I keep getting different normalvalues though the normals should be the same.

If I make a box and copy it as element a few times. Not all of the normals (of the faces facing the same way) are the same.

If I test the normalvalues of two faces that should be the same I get:
[0.84133,0.540523,0]
[0.841329,0.540523,0]

Why is that?
If it’s just the way max is. Is there a way to round it up or remove the last two digits? The only I found to round numbers off is with ceil and floor.

Thanks

7 Replies

If you’re in a late enough version of MXS, have a look at the close_enough method.

P.S. does anybody know exactly what the third (range) parameter to close_enough actually measures, arithmetically?

@drdubosc,

Thansk for your reply. I have looked at close_enough… But I can’t get the “threshold” to work properly. Either it doesn’t do anything or else it jumps too far away from the number.

Hi Jacob,
different values in seemingly identical objects should be given by Max internal approximation.

When I need to compare two normal vectors, I usually check the angle between them and set the result as threshold. Say the angle is less than 0.01 degs, they’re considered the same.

The general formula to get the angle between two vectors is:


function getAngleVect p3Vect01 p3Vect02 p3Origin =
(
	return (acos(dot (normalize(p3Vect01 - p3Origin)) (normalize(p3Vect02 - p3Origin))))
)

When dealing with normals it can be simplified to:


function getAngleNorm p3Norm01 p3Norm02 =
(
	return (acos(dot p3Norm01 p3Norm02))
)

Angle values are unsigned, always positive.

I hope this helps.

  • Enrico

thanks syncviews. I got it working with floor(acos(dot newfacenormal facenm)).

You could take the DotNet approach –

doubleval = dotnetobject "system.double" 0.84133
decimalplaces = 3
roundedoutput = ((dotnetclass "system.math").round doubleval decimalplaces) as float
print roundedoutput

I could never figure out how to use close_enough properly, although it should be a really straight forward operation. Just take the absolute difference between two numbers and see if the result is less than a certain threshold.

fn isCloseEnough_float num1 num2 thresh =
  (
  	if abs (num1 - num2) <= thresh then true else false
  )

isCloseEnough_float 0.84133 0.841329 .00001

true

And since normal values are just Point3’s, equivalent to points in space, you can use the distance method to compare them.

fn isCloseEnough_p3 num1 num2 thresh =
  (
  	if distance num1 num2 <= thresh then true else false
  )

isCloseEnough_p3 [0.84133,0.540523,0] [0.841329,0.540523,0] .00001

true

To get the difference between two normals, you could also use dot() Might be slower, but depending on your needs may be more appropriate