Parameter Wireing with Expressions - Rotation scales different boxes

Parameter Wireing with Expressions - Rotation scales different boxes

info
Explorer Explorer
1,160 Views
14 Replies
Message 1 of 15

Parameter Wireing with Expressions - Rotation scales different boxes

info
Explorer
Explorer

Dear Scripters I need your help, please.
I become crazy.. since a couple of day´s (or better week´s) I try to get this work.
on 4:20 on this video you see some arrows:

https://youtu.be/AQqyGNOP_3o
The arrows are linked with the rotor of the induction motor.
The Length of the arrows depend´s on the magnetic N and S field.
Every time N or S hit the arrow it should became 150% on N and -150% on S
Between the pole´s I need the scale value 0
My animation is a simple out of range animation controlled by an ease curve.

At first glance, it seemed easy to write an expression for it, even as a beginner.
But as an neeby in scripting I struggle with the syntax und much more with formula´s.
My first stumbling block was that the value of X_Rotation is in Rad, so it take some time to find out, I have to multiplicate with 57,295779513 to get Grad.🙄

But now I use
MyPfeil = getNodeByName "Pfeil007"
MyDummy = getNodeByName "Dummy001"
X_Rotation = coordsys gimbal MyDummy.rotation.x
RotAngle = atan2 (coordsys world MyPfeil.pos.Z - MyDummy.Pos.Z) (MyPfeil.Pos.Y - MyDummy.Pos.Y)
to get the Grad Value and to find out the angle between my Dummy and the Arrow(´s).

Because of the "out of range" rotation I get very high rotation angles, which i clean up by integer:
DrehA = int (X_Rotation/360)
DrehB = X_Rotation - (DrehA*360)

As you can see in the video from 4:20 the arrows length depend on the angle of the magnetic field (N/S) but the rotation is linked at the rotor.

I made two scripts to play around, but often I get unexpected results.
Most I find out, so like RotAngle was 90° ((150/90)*RotAngle)/100 where I expect 1.5
and get 0.9, because of an integer data type..
Typical beginner error I guess
Whenever I'm close to it and think "now I've got it" it slips back into the distance

Please help me to keep mental health😄

Thank you in Advance!
Josef

 

Script1
MyPfeil = getNodeByName "Pfeil006" --Scale object
MyDummy = getNodeByName "Dummy001"
MyRotorDummy = getNodeByName "Dummy002" --Rotation of the rotor
X_Rotation = coordsys gimbal MyRotorDummy.rotation.x
DrehA = int (X_Rotation/360)
DrehB = X_Rotation - (DrehA*360)
RotAngle = atan2 (coordsys world MyPfeil.pos.Z - MyDummy.Pos.Z) (MyPfeil.Pos.Y - MyDummy.Pos.Y)-- get vector
Dreh = RotAngle --+ DrehB
if (Dreh == 0 or Dreh == 180 or Dreh == -180) then ScaleA = 0 else
if (Dreh == 45) or (Dreh == 135) then ScaleA = 0.75 else
if (Dreh == -45) or (Dreh == -135) then ScaleA = -0.75 else
if (Dreh == 90) then ScaleA = 1.5 else
if (Dreh == -90) then ScaleA = -1.5
print ScaleA

Script2
MyPfeil = getNodeByName "Pfeil006" --Scale object
MyDummy = getNodeByName "Dummy001" --Rotate dummy to get vectors (probably not necessary)
MyRotorDummy = getNodeByName "Dummy002" --Rotation of the rotor
X_Rotation = coordsys gimbal MyDummy.rotation.x
DrehA = int (X_Rotation/360) --the integer cut decimal
DrehB = X_Rotation - (DrehA*360) --cleaned angle, because of the out of range
RotAngle = atan2 (coordsys world MyPfeil.pos.Z - MyDummy.Pos.Z) (MyPfeil.Pos.Y - MyDummy.Pos.Y) --get vector
Dreh = RotAngle + DrehB --not used in this first step
if (RotAngle > 0) and (RotAngle <= 90) then ScaleA = ((150.0/90.0)*RotAngle)/100.0 else
if (RotAngle > 90) and (RotAngle <= 180) then ScaleA = (150.0/90.0)*(RotAngle-90.0)/100.0 else
if (RotAngle <= 0) and (RotAngle >= -90) then ScaleA = ((150.0/90.0)*RotAngle)/100.0 else
if (RotAngle < -90) and (RotAngle > -179.9) then ScaleA = (150.0/90.0)*(RotAngle+90.0)/100.0

 

 

0 Likes
1,161 Views
14 Replies
Replies (14)
Message 2 of 15

leeminardi
Mentor
Mentor

Does this do what you want?

 

I've removed the wire parameter of arrow Pfeil003 and added a transform script to the object.

m = matrix3 [1,0,0] [0,1,0] [0,0, 1] [-1.66893e-06,21.2132,-21.2132]
quat_ang = dum2T.rotation
angx = (quatToEuler2 quat_ang).x
s = sin(angx)
m.row1 = s * m.row1
m

Here, dum2T is the transform for dummy002.  angx is the x axis rotation of dummy2.  The other arrows would require you to add a phase angle to angx with multiples of 45 as I did with arrow Pfeil004.  The original value for m are provided when you initiate the creation of the script but the first 3 vectors should be non zero or [1,0,0][0,1,0][0,0,1].  Row1 is the x axis vector of the arrow.

leeminardi_1-1692122474657.png

 

 

 

lee.minardi
0 Likes
Message 3 of 15

denisT.MaxDoctor
Advisor
Advisor

here is my version:

nums = 12
radius = 5
frequency = 1

with redraw off
(
	max create mode
	
	global gear = Ngon name:#gear scribe:1 radius:radius nsides:nums rotation:(eulerangles 0 90 0) wirecolor:orange  
	a0 = Cylinder name:#arrow radius:0.4 height:10 sides:6 rotation:(eulerangles 0 90 0) smooth:off
	a1 = Cone name:#head radius1:1 radius2:0 height:-2 heightsegs:1 sides:6 rotation:(eulerangles 0 90 0) smooth:off

	resetxform gear
	collapsestack gear

	arrow = converttomesh a0 
	meshop.attach arrow a1
	centerpivot arrow


	global rot = gear.rotation.controller = createinstance euler_xyz

	lockedtracksman.setlocks on rot[2] undefined -1 off 
	lockedtracksman.setlocks on rot[3] undefined -1 off 

	global ars = for k=1 to nums collect 
	(
		a = instance arrow parent:gear
		a.wirecolor = if k == 1 then red else green
			
		offset = 360.0/nums * (k-1)
		tm = rotatex (translate (transmatrix gear.pos) [0,0, radius]) offset
		a.pos = tm.pos
			
		c = a.scale.controller = scale_expression()
		c.AddScalarConstant #freq frequency
		c.AddScalarConstant #offset offset
		c.AddScalarTarget #rol rot[1]
			
		c.setexpression "[1, 1, cos (radToDeg((rol + offset)*freq)) + 0.00001]"	
			
		a	
	)
	delete arrow
	select gear
	
	max modify mode
)

 

Run the script, and it will create a scene and rig for you.

Use #nums and #frequency to control the mechanics.

 

SPIN THE WHEEL !

  

0 Likes
Message 4 of 15

info
Explorer
Explorer

Thank you leeminardi and denisT.MaxDoctor for your help!

Sorry for answering so late, but I became ill and have to stay in bed..

Sadly leeminardi script make an error, perhaps because I ´m using 3dsmax 2016, ähem..

 

denisT.MaxDoctor works, but the direction of the arrows have to follow the magnetic field,

so I have continued to work on my own spript what work now, thank god.

A difficult way on the test scene and much more complex on the correct scene.

Thats my working script whit comments that works

/*Get values from objects*/
MyPfeil = getNodeByName "Pfeil000"
MyRotorDummy = getNodeByName "RotorDummy"
MyMagDummy = getNodeByName "MagnetfeldDummy"

/*Scale from -150% to +150% by turning 180°*/
Dreh2ScaleStep = 300.0/180.0

/*Clean up rotation magnet*/
X_RotMagnet = coordsys gimbal MyMagDummy.rotation.x
DrehInt = int (X_RotMagnet/360)
DrehBerMagnet = (X_RotMagnet - (DrehInt*360.0))

/*Clean up rotation rotor*/
/*X_RotRotor = coordsys gimbal MyRotorDummy.rotation.x
DrehInt = int (X_RotRotor/360)
DrehBerRotor = (X_RotRotor - (DrehInt*360.0))*/

/*Get vectors from objects "Pfeil" */
PfeilVektorAkt = atan2 (coordsys world MyPfeil.pos.Z - MyRotorDummy.Pos.Z) (MyPfeil.Pos.Y - MyRotorDummy.Pos.Y)

/*exit value if then*/
DiffRot = DrehBerMagnet-PfeilVektorAkt

/*Clean up vectors*/
--PfeilVektorBer = PfeilVektorAkt-DrehBerRotor

if (DiffRot >=0.0 and DiffRot <=360.0) then
(
Dreh2Scale = DrehBerMagnet-PfeilVektorAkt
"Vektor 0 - +360"
)
else
if (DiffRot <0.0 and DiffRot >=-360.0) then
(
Dreh2Scale = DrehBerMagnet-PfeilVektorAkt
"Vektor 0 - -360"
)
else
(
Dreh2Scale = PfeilVektorAkt-(DrehBerMagnet-180.0)
"Vektor ueber 360"
)


if (Dreh2Scale >= 0.0 and Dreh2Scale < 180.0) then
(
ScaleA = Dreh2ScaleStep*-(Dreh2Scale-90.0)/100.0
"0 - +180°"
)
else
if (Dreh2Scale < 0.0 and Dreh2Scale > -180.0) then
(
ScaleA = Dreh2ScaleStep*(90.0+Dreh2Scale)/100.0
"0 - -180°"
)
else
if (Dreh2Scale >= 180.0 and Dreh2Scale <= 360.0) then
(
ScaleA = Dreh2ScaleStep*(-90.0+Dreh2Scale-180.0)/100.0
"180° - 360°"
)
else
if (Dreh2Scale <= -180.0 and Dreh2Scale >= -360.0) then
(
ScaleA = Dreh2ScaleStep*-(-90.0-Dreh2Scale-180.0)/100.0
"-180° - -360°"
)
MyPfeil.scale.x = ScaleA

 

Thak you again for help

Josef

0 Likes
Message 5 of 15

leeminardi
Mentor
Mentor

I've added a transform script to each of the eight arrows.  Each has a different phase angle.  I think the results are what you want.

 

Click Play in the attached file.

leeminardi_0-1693073547333.png

 

lee.minardi
0 Likes
Message 6 of 15

info
Explorer
Explorer

Thank you again leeminardi for making so much work!

Sorry for being late again, but I was in vacation for two weeks.

 

Sadly my max is to old to open that file, my newest max is 2019.

do you have the possibility to save in this version, or is you 3dsmax to new?

 

Josef

0 Likes
Message 7 of 15

leeminardi
Mentor
Mentor

The oldest option for saving Max files on my system is 2020.  Attached is the file in 2020 format.

 

Here's an example of the transform controller script for arrow Pfeil000. Dum2T is the transform for dummy002.

leeminardi_0-1694525053546.png

... and for arrow Pfeil001.  Note the difference for the phase angle, 45 vs. 90 degrees. The other arrows have appropriate phase angle adjustments.

leeminardi_1-1694525126137.png

 

 

lee.minardi
0 Likes
Message 8 of 15

info
Explorer
Explorer

Thank you lee.minardi!

 

I try to copy your work, but get it done..

My setup is

Pfeil000 XScale: Float Script as Controller

Variable Dum2T with your script assigned with

turning dummy (MagnetfeldDummy)  Transform: Position/Rotation/Scale

On Evaluate I get error message

--Unable to convert: (matrix3 [1,0,0] [0,1,0] [0,0, 1] [0,0, 30])

to type: Float

What I´m doing wrong?

Josef

 

 

0 Likes
Message 9 of 15

info
Explorer
Explorer

Dear Community,

Would anyone be so kind to save me lee.minardi´s file at least on version deeper than 20 please.

 

Thank you in Advance!

Josef

0 Likes
Message 10 of 15

leeminardi
Mentor
Mentor

Can you post your Max file? It will let me see more fully what you are doing.

lee.minardi
0 Likes
Message 11 of 15

info
Explorer
Explorer

Of course, thank you for help

0 Likes
Message 12 of 15

leeminardi
Mentor
Mentor

The transform script for Pfeil000 should be assigned to the object.

leeminardi_0-1694719521136.png

If you are not familiar with how to do this go to about 2:20 in this tutorial  for the process of assigning a transform script to an object.

 

 

 

lee.minardi
0 Likes
Message 13 of 15

info
Explorer
Explorer

Of course I know this amazing tutorial and have watched it sometimes in the beginning of my way,

just like your Scissor Mechanism tutorial.

I´ve decided that it´s to complicated for the beginning and so I take Wire Parameters and Script.

But now I see, I betting on the wrong horse..

I get it work in my way perfectly, BUT on reopening my scene the Wire Parameter dialog display a couple of errors.

Strangely not all of that and if I press Update all works perfectly again.

Second BUT..  I can´t render images at all, because of the same error messages.

Only individual images are rendering?!

I can´t find out what error happens here so I´m afraid I have to give up this way and set all my hope in your way🙂

 

Long speech short sense, the first Level of your script works perfect in my test scene! Thank you!

I hope I don´t bother you to much..

But would you be so kind to help me again.

Now the X-scale works in turning the "MagnetfeldDummy".

The arrows should change also the scale if the "RotorDummy" rotate, they have to interact together.

But I have no idea, how to adjust your script to get it work..

So... Heeelp! 🙂

 

Josef

0 Likes
Message 14 of 15

leeminardi
Mentor
Mentor

@info 

  1.  I think you should make a post with the subject "please convert a Max 2020 file to 2019" so that you can examine my files or, upgrade your version of Max.
  2.  I arbitrarily set a scale factor of 2 in the transform scripts.  To make it a function of the x rotation of RotoDummy just substitute  sin(dumRoto) for the 2 in the statement defining "s" (the scale factor).  Here, I associated dumRoto for the x rotation of RotoDummy  (see below),

    HOWEVER, since Cylinder001 to 008, and Pfeil000 to 007 are linked to RotorDummy you cannot rotate RotoDummy independently of MagnetfeldDummy.  Therefore you should unlink these 16 objects from RotoDummy and link them to MagnetfeldDummy.  

  3. To rotate everything rotate MagnetfeldDummy.
  4. To adjust the scale factor rotate RotoDummy.  Note, I only changed the script for Pfeil000 in the attached file.
    leeminardi_1-1694784271049.png

     

lee.minardi
0 Likes
Message 15 of 15

info
Explorer
Explorer

Hi leeminardi 

I got all your tips working, but...

ouch, sadly interact between that both is absolutly necessary.

 

Whith view changes my script works now without error messages by rendering,

but other strange things happens..

You remember, I´ve wired the arrow with the magnetic dummy and this works.

But after reopening the scene the links of the wire parameter are gone, but the script works anyway..

Not more to find by the different ways to open the Wire Parameter Dialog, also in the Schematic editor.

Of course the button show wire is enabled..

Thank you max for puzzle me😄

 

Thank you leeminardi for all your help!

Josef

0 Likes