PDA

View Full Version : programming/math GUI question..


Polimeno
04-05-2011, 11:01 PM
Hey guys,
Iīm doing a simple scripting research about automaticly generates GUI controls for facial rigging. ala Jason Osipa eg. http://vimeo.com/9219973 and http://www.creativecrash.com/system/photos/000/101/013/101013/big/theFacialSetup_web1.JPG?1280295706

Ok, things were going quite well until I hit a wall:

Rather than coding a one/four/two side controller Iīm trying to generate a three side...
Iīm wondering what would you guys go about clamping a control curve transform position XYZ using its parent area, a triangle curve shape ?

Any hints would be highly appreciated.

Thanks in advance

wamo
04-06-2011, 05:42 AM
One idea might be develope a GUI panel which uses a plane mesh behind it and use IntersectRay() to caculate the ray and the mesh intersection when ever it wants to go to be undefined you can restrict the control from movements,

That way you get rid of the Math and you always can do it in different shapes panel ..

Best regards,

elT
04-06-2011, 05:51 AM
Or just use attachment constraint to tie the control to the plane? :shrug:

eek
04-06-2011, 07:13 AM
It's all to do with trig and more specifically the law of sines. Essentially you'd be controlling the limit of the controls z position based on its x.

if we have a regular triangle made up of 3 points 'a', 'b' & 'c' - 'a' being on the far left, 'b' being in the middle (the top of the triangle) and 'c' being the far right.

Now if we have a point 'p0' - at the bottom of the triangle between 'a' and 'c' its essentially on one of the sides based on its position between 'a' and 'c' - i.e if its x position is greater than half the distance (|a-c|) its on the side of 'c' else its on the side of 'a'.

Now for the length i.e its z limit - basically im going to stick with an equilateral triangle i.e made up of 3 angles of 60 degrees. I'll stick with 'p0's position being on the side of 'a' for now.

Law of sines tells us we can get the length of a side from two angles and a length - the angle at 'a' is going to be 60 degrees, the angle at 'b' is going to be '30' as its at the top and split in half (for each side) and seeing as this is basically now a right-angle triangle the last angle will be 90 degrees.Why 90, well were getting the angle between a-p0 and p0 vertically through the ab line.

We first need to get the length between 'a' and the intersection of 'p0' on the 'ab' line - if it were firing a ray straight up.

we get the length between 'p0.x and 'a.x', lets call it pa and multiply it by the sin of 90, then we divide this by the sin of its opposite - in this case 30 degree (i.e the top, halved)

if the p0 distance is say 5.0 our result for the pa line should be 10.0 -

pa = (5.0 * sin (90.0))/(sin 30.0)

Now that we have pa, we can get the missing length i.e how far p0 can travel in z. Its the same equation just with different sides.

z limit = (pa * sin(60.0))/sin(90.0)
z limit = 8.6

If you wanted to use non-equal triangles you can use law of cosine to get the angles.

This is pretty much it - very rough, (worked it out on pen and paper and a calculator at home, will try and test it tomorrow)

Polimeno
04-07-2011, 07:09 AM
One idea might be develope a GUI panel which uses a plane mesh behind it and use IntersectRay() to caculate the ray and the mesh intersection when ever it wants to go to be undefined you can restrict the control from movements,

That way you get rid of the Math and you always can do it in different shapes panel ..

Best regards,

That should work, but Iīm curious about a directly scripted math solution to keep things simple and cleaner.. I really donīt want to add extra nodes/funcitons and so on..
Thanks for your input anyway.

Or just use attachment constraint to tie the control to the plane?

But how we could retrieve the [x,y] normalized barycentric result to feed the spline controlīs float limit controllers ??

Charles
Great explanation, I did understand after reading it 05 times over and over !!
Could you please take a look at my image ??

http://03814152819071495559-a-g.googlegroups.com/attach/8cb3fae8e3ad23b0/triangle_math_problem.jpg?gda=rQhCZ0YAAAA7fxXdL61pxMl0cxX0pRvzGljm1thHIaT7PgH1DCw-k7ow9fBaPcrkkkgeHKxRQRdx40jamwa1UURqDcgHarKEE-Ea7GxYMt0t6nY0uV5FIQ&view=1&part=4

http://mathworld.wolfram.com/EquilateralTriangle.html
Now Iīm doing a equilateral triangle shape for right math values.

I will be glad if someone could input another hints aswell.

theflash
04-07-2011, 12:33 PM
You can find limit on both sides of this middle line of the triangle based on height (distance from top point). You can use an isosceles triangle.

https://lh6.googleusercontent.com/_YaF97CrfShk/TZ2el0yFdyI/AAAAAAAAAig/nu1EAUtI3pE/triangle_control.jpg

So first you can calculate "h" which is the vertical distance of your current point from B.
Then you can calculate "x" based on above formula using the angle /_BAC. Here "x" is horizontal limit on both sides from the point B.

JHN
04-07-2011, 07:01 PM
Here's my not so scientific approach. See max file.
This is a script controller's script.


x = pos.value.x
y = pos.value.y
z = 0

angle = cos 60

if y > 50 then y = 50
if y < 0 then y = 0

if x > (angle * y) then x = (angle * y)
if x < (angle * -y) then x = (angle * -y)

[x,y,z]


So not a perfect 60 * 60 * 60 triangle, but that's something the math guys can probably fix :)
It's max offcourse so you have to figure out how to do it in SI.

-Johan

Polimeno
04-08-2011, 03:52 AM
Here's my not so scientific approach.

x = pos.value.x
y = pos.value.y
z = 0

angle = cos 60

if y > 50 then y = 50
if y < 0 then y = 0

if x > (angle * y) then x = (angle * y)
if x < (angle * -y) then x = (angle * -y)

[x,y,z]

-Johan

Thanks Johan, I liked your approach !! unfortunately two little problems are happening:

1. It gets pretty messy when the box is in the local space of the triangle (parenting).. So basicly it needs an extra-node to maintain the offset.. See max file.

2. Zero Transforms within TransformToZero or assumeSkinPose options didnīt work unless you force by script eg.

<box>.pos.controller[2][2].value = 25.0
<box>.pos.controller[2][1].value = 0.0



So not a perfect 60 * 60 * 60 triangle, but that's something the math guys can probably fix

I guess we could fix that by finding the angle from 2D vectros (http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm) eg.


-- knots
A = (getKnotPoint _triangle 1 2)
B = (getKnotPoint _triangle 1 3)
C = (getKnotPoint _triangle 1 1)

AB = A-B
AC = A-C

-- get angle from 2D vectors
angle = acos( dot (normalize(AB)) (normalize(AC)) )


It isnīt hard to draw one Equilateral Triangle BTW

Star radius1:25.0 radius2:50.0 fillet1:0 fillet2:0 numPoints:3 distort:0 pos:[0,0,0] name:"triangle" wirecolor:yellow


Maulik
Thanks a lot for your input.
How would you go about it inside Maya, expressions or nodes ?? Iīm testing some ICE graph right now..

theflash
04-08-2011, 10:25 AM
Everything can be done with maya nodes, except tan(theta). That I will do it in expression. But the problem in Maya is to limit the transform with dynamic limit values. There are ways to workaround like have two controls, one that moves and one that is restricted. But that is not very user friendly.
Other way you could do is to use transformLimits in the expression, a bit ugly solution.

CGTalk Moderation
04-08-2011, 10:25 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.