Checking if two Placements are parallel and creating one orthogonal.

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
edwilliams16
Veteran
Posts: 3191
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Checking if two Placements are parallel and creating one orthogonal.

Post by edwilliams16 »

You are asking to check if when looking down the axis of one object, you'll be lined up with the axis of the second?
If so, that is simple enough:

Code: Select all

dv = obj1.Placement.Base - obj2.Placement.Base #displacement
ax1 = obj1.Placement.Rotation.multVec(App.Vector(0,0,1)) #symmetry axis direction of cylinder or cone
ax2 = obj2.Placement.Rotation.multVec(App.Vector(0,0,1))
align1 = dv.cross(ax1).Length <= 1e-15*dv.Length # Axis parallel to displacement?
align2 = dv.cross(ax2).Length <= 1e-15*dv.Length
isAligned = align1 and align2  # both lined up
keithsloan52
Veteran
Posts: 2764
Joined: Mon Feb 27, 2012 5:31 pm

Re: Checking if two Placements are parallel and creating one orthogonal.

Post by keithsloan52 »

edwilliams16 wrote: Mon Apr 12, 2021 11:03 pm You are asking to check if when looking down the axis of one object, you'll be lined up with the axis of the second?
If so, that is simple enough:

Code: Select all

dv = obj1.Placement.Base - obj2.Placement.Base #displacement
ax1 = obj1.Placement.Rotation.multVec(App.Vector(0,0,1)) #symmetry axis direction of cylinder or cone
ax2 = obj2.Placement.Rotation.multVec(App.Vector(0,0,1))
align1 = dv.cross(ax1).Length <= 1e-15*dv.Length # Axis parallel to displacement?
align2 = dv.cross(ax2).Length <= 1e-15*dv.Length
isAligned = align1 and align2  # both lined up
Many thanks now we are going places

So if I go back to my original what I called orthogonal check, can I not check for this situation with

Code: Select all

dv = obj1.Placement.Base - obj2.Placement.Base #displacement vector
rot1 = obj1.Placement.Rotation
rot2 = obj2.Placement.Rotation
Check. if parallel with
if   abs((rot1.multiply(rot2.inverted())).Angle) < 1e-15 # True if rot1 == rot2
     # Check if just displaced 90 degrees to axis of symmetry
     ax1 = rot1.multVec(App.Vector(0,0,1)) #symmetry axis direction of cylinder or cone
     if ax1.dot(dv) <= 1e-15 :
            # action parallel and orthogonally displaced
edwilliams16
Veteran
Posts: 3191
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Checking if two Placements are parallel and creating one orthogonal.

Post by edwilliams16 »

To be consistent, you can use rot1.isSame(rot2, 1e-15) to compare the rotations. However the earlier test also works well.

You should use

Code: Select all

ax1.dot(dv) <= 1e-15*dv.Length
for the orthogonality test, so it does not depend on the magnitude of dv, You can’t just normalize it because it could be zero. ax1 is a unit vector already. The test is True when dv=0 as any vector is both parallel and orthogonal to the zero vector. You can choose which case to use by the order you place the tests.
edwilliams16
Veteran
Posts: 3191
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Checking if two Placements are parallel and creating one orthogonal.

Post by edwilliams16 »

Code: Select all

c1 = Part.Circle(obj1.Placement.Base, obj1.Placement.Rotation.Axis, \
         obj1.Radius.getValueAs('mm'))
    c2 = Part.Circle(obj2.Placement.Base, obj2.Placement.Rotation.Axis, \
         obj2.Radius.getValueAs('mm'))

    # helper circle located at c1
    c3 = Part.Circle()
    #c3.Center = obj1.Center
    c3.Center = obj1.Placement.Base
    c3.Radius = obj1.Radius - obj2.Radius

    # get the mid point of the line from the center of c1 to c2
    #v1 = obj1.Center
    #v2 = obj2.Center
    v1  = obj1.Placement.Base
    v2  = obj2.Placement.Base
    v3  = (v1 + v2) / 2

    # Thales circle that is located in v3 and goes through
    #  the center points of c1 and c2
    c4 = Part.Circle()
    c4.Center = v3
    c4.Radius = (v1 - v2).Length / 2
I didn't touch your coding for the radii of c1, c2 c3 and c4, but I suspect there will be a problem if the units aren't mm. The getValueAs('mm') I believe should be for all or none.
Post Reply