mathematical functions for scripting in LDCad


mathematical functions for scripting in LDCad
#1
Hi

Is there any overview on the mathematical functions included in the scripting language of LDCad? Does it include algebraic operations (Matrices)? Is it possible to add such libraries?

Regards
Joscha
Reply
RE: mathematical functions for scripting in LDCad
#2
According to Scripting API documentation. LDCad have module match included described here http://lua-users.org/wiki/MathLibraryTutorial.
Lego isn't just a brand of plastic bricks. It's a lifestyle; and artistic medium.
Reply
RE: mathematical functions for scripting in LDCad
#3
(2018-03-14, 9:07)Jarema Wrote: According to Scripting API documentation. LDCad have module match included described here http://lua-users.org/wiki/MathLibraryTutorial.


Hi Jarema

Thank you for yor quick answer and sorry for being blind. It is quite obvious on the LDCad homepage.

It doesn't seem to support algebraic functions.
Reply
RE: mathematical functions for scripting in LDCad
#4
(2018-03-14, 16:57)Joscha Wrote: It doesn't seem to support algebraic functions.

The default lua math library is very limited, but the beauty of a scripting language is you can extend it with the things you need. Ether by using a thirdparty library or by writing one your self.

If all you need is matrix and vector math I did add support for that through the ldc module as LDraw is heavily depended on matrix math.

But the ldc matrix math is highly targeted on LDraw usage, so if you need more complicated things you might need to use something like:
https://github.com/anaef/lua-linear

But this would require you to compile a .dll (window) or .so (Linux). There might also be a pure lua module for this out there, but I couldn't find it during a quick web search.

If you go the compile route be sure to match the main executable 32 or 64 bit wise. And use the lua 5.3 headers.
Reply
RE: mathematical functions for scripting in LDCad
#5
(2018-03-14, 18:33)Roland Melkert Wrote: If all you need is matrix and vector math I did add support for that through the ldc module as LDraw is heavily depended on matrix math.

But the ldc matrix math is highly targeted on LDraw usage, so if you need more complicated things you might need to use something like:
https://github.com/anaef/lua-linear

Hi Roland

Yes, all I need is vector and matrix math. My problem is, I would like to rotate a part and I would like to know (or use it in the script) the new position of a specific point of this part. This would usually be a simple coordinate system rotation multiplying a vector with the rotation matrix. The most suitable command seems to be 'transform'. Only somehow it does not behave fully like this. It seems to flip my part by 180°.

Furthermore, is there any way to access the location of the parts center? I mean the rotation matrix always rotates a part around its center. If I like to rotate it around another center during a script I would have to rotate and translate it. This seems to be confusing.
Reply
RE: mathematical functions for scripting in LDCad
#6
(2018-03-14, 22:15)Joscha Wrote: Hi Roland

Yes, all I need is vector and matrix math. My problem is, I would like to rotate a part and I would like to know (or use it in the script) the new position of a specific point of this part. This would usually be a simple coordinate system rotation multiplying a vector with the rotation matrix. The most suitable command seems to be 'transform'. Only somehow it does not behave fully like this. It seems to flip my part by 180°.

Furthermore, is there any way to access the location of the parts center? I mean the rotation matrix always rotates a part around its center. If I like to rotate it around another center during a script I would have to rotate and translate it. This seems to be confusing.

Keep in mind the LDraw coordinate system uses a negative Y while OpenGL does not. I correct for this by using a base model view rotation of 180 degrees.

To rotate around another center you do indeed need to apply a translate, like so:

Code:
local center=ldc.vector(10, 0, 10) --some alternative center.
local rotation=ldc.matrix()
rotation:setRotate(45, 0, 1, 0) --e.g 45 deg rotate around y

--build transformation matrix
local matrix=ldc.matrix()
matrix:setTranslate(center:getInverted())
matrix:mulAB(rotation)
matrix:mulAB(center)

--Apply it to brick(s), e.g the first one in the model
local ref=ldc.subfile():getRef(1)
local refMatrix=ref:getPosOri()
refMatrix:mulAB(matrix)
ref:setPosOri(refMatrix)

I know it's not very efficient but, if it would need to be really fast you wouldn't be using script Smile
You could wrap the matrix construction in a function if you worried about readability etc.

To find the abs position of point in the part you need to use
Code:
someVectorWithPositionRelativeToBrickRefIsLinkedTo:transform(refMatrix)
Reply
RE: mathematical functions for scripting in LDCad
#7
I figured out why I experienced the 180° flip. I just applied the rotation to the wrong orientation matrix.

But basically I learned now that everything I need is already packed inside the scripting API. Thank you!

Coming back to the matrix type. You describe that it is a 4x4 matrix initialised as identity matrix. But for the location and orientation only 12 elements are used. Do the four remaining elements contain information?
Reply
RE: mathematical functions for scripting in LDCad
#8
(2018-03-15, 14:05)Joscha Wrote: Coming back to the matrix type. You describe that it is a 4x4 matrix initialised as identity matrix. But for the location and orientation only 12 elements are used. Do the four remaining elements contain information?

The 12 elements are what is used in LDraw "type 1" lines. It's a position and 3x3 rotation matrix. Internally this is stored in a 4x4 matrix but one column (or row depending how you look at it) is (or should be) always 0 0 0 1 as it assumes the matrices only contain a rotation and translation.

ps: I noticed an error in my code which works only because of a fluke:
Code:
local matrix=ldc.matrix()
matrix:setTranslate(center:getInverted())
matrix:mulAB(rotation)
matrix:mulAB(center)
should be
Code:
local matrix=ldc.matrix()
matrix:setTranslate(center:getInverted())
matrix:mulAB(rotation)
matrix:mulTranslateAB(center)
mulAB with a matrix using a vector in its constructor acts like a translate as it is basically an alias, but it can be very confusing.
Reply
RE: mathematical functions for scripting in LDCad
#9
As with another pool of questions. Because I have never been strong... in mathematics. I ask how to determine the angle of inclination of a given part with respect to a given axis ?
Lego isn't just a brand of plastic bricks. It's a lifestyle; and artistic medium.
Reply
RE: mathematical functions for scripting in LDCad
#10
(2018-03-15, 18:13)Roland Melkert Wrote:
Code:
local matrix=ldc.matrix()
matrix:setTranslate(center:getInverted())
matrix:mulAB(rotation)
matrix:mulTranslateAB(center)
mulAB with a matrix using a vector in its constructor acts like a translate as it is basically an alias, but it can be very confusing.

Indeed, I thought about why using mulAB once with a matrix once with a vector, but I didn't dare to ask Wink

I just stumbled over the center:getInverted(). In your manual getInverted is for matrices. What does it do with the vector?
Reply
RE: mathematical functions for scripting in LDCad
#11
(2018-03-16, 9:08)Jarema Wrote: As with another pool of questions. Because I have never been strong... in mathematics. I ask how to determine the angle of inclination of a given part with respect to a given axis ?

Do you mean the angle between the orientation of a part/group and any vector? Isn't it 'getAngle'?
Reply
RE: mathematical functions for scripting in LDCad
#12
How calculate the angle of Technic Axle 6 relative to the Y axis.   See attached file.


Attached Files
.jpg   8845-race-car.jpe.jpg (Size: 17.19 KB / Downloads: 155)
Lego isn't just a brand of plastic bricks. It's a lifestyle; and artistic medium.
Reply
RE: mathematical functions for scripting in LDCad
#13
(2018-03-16, 17:15)Jarema Wrote: How calculate the angle of Technic Axle 6 relative to the Y axis.   See attached file.

Axles point into their local X direction, so...

Take a vector of 1 0 0
Transform it by the axles rotation ( :getRef, :getOri)
Take a vector of abs Y (0 -1 0)
Get the angle between the two by
absYVector:getAngle(absAxleXVector)


Hope this get you on the right path.

ps: I'm assuming you need this for scripting, during editing you better off using the selection information feature.
Reply
RE: mathematical functions for scripting in LDCad
#14
(2018-03-16, 9:08)Jarema Wrote: As with another pool of questions. Because I have never been strong... in mathematics. I ask how to determine the angle of inclination of a given part with respect to a given axis ?

Hi Jarema

From the mathematical point of view the angle between two vectors is determined by

angle=acos( vecA*vecB / abs(vecA) / abs(vecB) )

 

Sorry, I wanted to post a formula, but for some reason I couldn't post the image.
Reply
RE: mathematical functions for scripting in LDCad
#15
I discovered Today, that genTools.lua in default\modules have triangleAngle and trianglePlacementAngles. I hope that this module will be regularly enriched with new, stand-alone functions
Lego isn't just a brand of plastic bricks. It's a lifestyle; and artistic medium.
Reply
RE: mathematical functions for scripting in LDCad
#16
(2018-03-17, 17:31)Jarema Wrote: I discovered Today, that genTools.lua in default\modules have triangleAngle and trianglePlacementAngles. I hope that this module will be regularly enriched with new, stand-alone functions

I added those because I needed them in multiple example animations Smile

trianglePlacementAngles basiclly does what the option in the selection information menu does.
Reply
RE: mathematical functions for scripting in LDCad
#17
(2018-03-14, 23:55)Roland Melkert Wrote: To rotate around another center you do indeed need to apply a translate, like so:

Code:
local center=ldc.vector(10, 0, 10) --some alternative center.
local rotation=ldc.matrix()
rotation:setRotate(45, 0, 1, 0) --e.g 45 deg rotate around y

--build transformation matrix
local matrix=ldc.matrix()
matrix:setTranslate(center:getInverted())
matrix:mulAB(rotation)
matrix:mulTranslateAB(center)

--Apply it to brick(s), e.g the first one in the model
local ref=ldc.subfile():getRef(1)
local refMatrix=ref:getPosOri()
refMatrix:mulAB(matrix)
ref:setPosOri(refMatrix)

Roland, I have to come back to your code above. I applied it successfully. Thank you! But I do not understand the getInverted command. How to invert a vector? The command should be only for matrices, shouldn't it?
Reply
RE: mathematical functions for scripting in LDCad
#18
(2018-03-25, 9:12)Joscha Wrote: Roland, I have to come back to your code above. I applied it successfully. Thank you! But I do not understand the getInverted command. How to invert a vector? The command should be only for matrices, shouldn't it?

getInverted only flips the signs of xyz, so e.g. (1,-2,3) returns (-1,2,-3).

I named it inverted as its goal is the same, to "undo" the vectors content (1+ -1 = 0) just as an inverted matrix can be used to get identity back when multiplying with the original.
Reply
RE: mathematical functions for scripting in LDCad
#19
(2018-03-25, 17:31)Roland Melkert Wrote:
(2018-03-25, 9:12)Joscha Wrote: Roland, I have to come back to your code above. I applied it successfully. Thank you! But I do not understand the getInverted command. How to invert a vector? The command should be only for matrices, shouldn't it?

getInverted only flips the signs of xyz, so e.g. (1,-2,3) returns (-1,2,-3).

I named it inverted as its goal is the same, to "undo" the vectors content (1+ -1 = 0) just as an inverted matrix can be used to get identity back when multiplying with the original.


I have a different approach for the rotation around any center which seems to be much shorter:
Code:
local angle=23                     --rotation angle
local centerPart=ref.getPos()             --center of part/group to be rotated
local centerRot=ldc.vector(2,3,4)        --Vector of rotation center
local centerPartRel=centerPart-centerRot     --relative position of part/group center from rotation Center
                
ref:mulRotateAB(angle,1,0,0)            --rotates the part/group itself around the x-axis of his center
centerPartRel.transform(ref.getOri())        --makes a transformation to the relative position with the new orientation
ref:setPos(centerPartRel+centerRot)        --sets the new position as vector-sum of rotation center and transformed relative position vector
Reply
RE: mathematical functions for scripting in LDCad
#20
In my code were small errors. I corrected them and put it into a function for those who are interested in rotating parts around an arbitrary center.

If you perform multiple rotations to one part you should not use the orientation of the reference itself as shown in my last reply:
Code:
centerPartRel.transform(ref.getOri())
Therefore I introduces the 'indipendent orientation'.


So, here is the code:
Code:
function rotaround(refPart,centerRot,indOri,angle,rotVec)
    --refPart: refline object/group
    --centerRot: vector to rotation center
    --indOri: indipendent orientation matrix
    --angle: angle of rotation in degrees
    --rotVec: vector to rotate around
    local centerPartRel=refPart:getPos()-centerRot --relative position of part/group center from rotation Center
    local refPartOri=refPart:getOri()
    refPartOri:mulRotateAB(angle,rotVec) --rotates the part/group itself around the x-axis of his center
    centerPartRel:transform(indOri) --makes a coordinate transformation to the relate Position
    refPart:setPos(centerPartRel+centerRot)    --sets the new position as vector-sum of rotation center and transformed relative position vector
    refPart:setOri(refPartOri)
    return refPart:getPosOri()
end
Reply
« Next Oldest | Next Newest »



Forum Jump:


Users browsing this thread: 11 Guest(s)