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: 3180
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 »

keithsloan52 wrote: Wed Apr 07, 2021 7:51 pm Given a object Obj with Placement Obj.Placement how do I create a Vector that goes through Obj.Base in the same direction as the Placement.Rotation.Axis and has Placement.Rotation.Angle = 0
There's no such thing. Vectors do not have an angle property, rotations do. Once you have a vector in the direction you already specified, the only degree of freedom left is its length.

In CS terms, a rotation is a function that takes a vector as an argument and returns a (rotated) vector. A function is a different animal to its argument. You are trying to ascribed properties of the function to its argument.

What ever you are seeking, it isn't what you are asking for, because there's no such thing.
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: Wed Apr 07, 2021 8:08 pm
There's no such thing. Vectors do not have an angle property, rotations do. Once you have a vector in the direction you already specified, the only degree of freedom left is its length.
Vectors have a direction do they not. So given a Rotation how do I obtain the Axis?

"Once you have a vector in the direction you already specified" I have not specified any direction. I have a Placement that has a Rotation.
One can create a Rotation with an Axis and an Angle, but how do I get the Axis which corresponds to one with angle 0. You really have not grasped the fact that I am being passed some objects on a stack and they have Placements, I am not creating them.
edwilliams16
Veteran
Posts: 3180
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 »

Placement.Base is the translation vector
Placement.Rotation.Axis is the unit vector around which the rotation occurs.
Placement.Rotation.Angle is the angle through which the rotation is made.

I am perfectly aware that is the information you have.

What you ask for is "how do I create a Vector that goes through Obj.Base in the same direction as the Placement.Rotation.Axis and has Placement.Rotation.Angle = 0"

The last clause is nonsensical. There is only one axis, it doesn't depend on the rotation angle. There's only so many ways I can say it.

EDIT
Actually the first clause doesn't work either.
"how do I create a Vector that goes through Obj.Base in the same direction as the Placement.Rotation.Axis and has Placement.Rotation.Angle = 0"

If you think of vectors as having a tip and a tail, the tail of FreeCAD vectors are always at the origin. Think of them as coordinates. So unless it accidentally happened that the Obj.Base vector and Axis vectors were parallel, there is no such vector.
Last edited by edwilliams16 on Wed Apr 07, 2021 10:00 pm, edited 1 time in total.
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 »

Okay think I am there, I found Placement.Rotation has a RawAxis as well as Axis and Angle

So what I needed to test was

Code: Select all

v1 = obj2.Placement.Base.sub(obj1.Placement.Base)
v2 = obj1.Placement.Rotation.RawAxis
if  v2.dot(v1) == 0 :
    ....Action
edwilliams16
Veteran
Posts: 3180
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 »

The only difference between RawAxis and Axis is that the latter is normalized to be a unit vector. Your code would work exactly the same using Axis.

What your code does is to test to see if the (common) rotation axis is perpendicular to the displacement between your two objects. If that's what you want, good. It won't actually work reliably because the cardinal sin of floating point arithmetic is to check equality. Numbers that are theoretically equal aren't necessarily equal because of finite precision arithmetic.

Code: Select all

v1 = obj2.Placement.Base.sub(obj1.Placement.Base)
v2 = obj1.Placement.Rotation.Axis
if  abs(v2.dot(v1)) <= 1e-15*v1.Length :
    ....Action
deals with this issue. 1e-15 is likely appropriate, but it actually depends on the precision of the imported numbers. If they are less precise than FreeCAD's arithmetic, you'll need to make it larger.

One quirk you should deal with is that if Rotation.Angle is zero, the axis is in fact arbitrary. I believe FreeCAD defaults it to (0,0,1) for the sake of definiteness. Then your test makes no sense, so you need to decide what you need to do then.
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: Wed Apr 07, 2021 10:24 pm The only difference between RawAxis and Axis is that the latter is normalized to be a unit vector. Your code would work exactly the same using Axis.
That is a bummer I thought it might give the Axis I require.

Found this on Wikipedia
68F31BED-373B-4C29-B826-B9F8AE9B0514_4_5005_c.jpeg
68F31BED-373B-4C29-B826-B9F8AE9B0514_4_5005_c.jpeg (121.69 KiB) Viewed 944 times
But assume this would be the same as Creating a Placement.Rotation with an Axis and an Angle.
What I need is given an Axis and Angle get the NewAxis that will get me the same Rotation with NewAxis, Angle 0
wmayer
Founder
Posts: 20309
Joined: Thu Feb 19, 2009 10:32 am
Contact:

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

Post by wmayer »

What I need is given an Axis and Angle get the NewAxis that will get me the same Rotation with NewAxis, Angle 0
You have a rotation defined by a given axis and a given angle != 0. Now you want to express the same rotation with a different axis and an angle of 0.

The simple answer is: that's not possible

If you consider a rotation with an arbitrary axis but an angle of 0 is that you get a function where each point is mapped to itself.

From the linked WP article you can easily see this fact:
If the rotation angle theta is 0 then all expressions of cos(theta) are 1 and sin(theta) are 0. So, if you replace all occurrences of cos(theta) with 1 and all sin(theta) with 0 you will end up with the identity matrix -- independent of the coordinates of the axis u.

When you have a rotation with an angle != 0 then cos(theta) and sin(theta) will be in the range [-1, 1]. The rotation matrix always will be different to the identity matrix.
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 »

wmayer wrote: Thu Apr 08, 2021 2:08 pm
The simple answer is: that's not possible

If you consider a rotation with an arbitrary axis but an angle of 0 is that you get a function where each point is mapped to itself.

From the linked WP article you can easily see this fact:
If the rotation angle theta is 0 then all expressions of cos(theta) are 1 and sin(theta) are 0. So, if you replace all occurrences of cos(theta) with 1 and all sin(theta) with 0 you will end up with the identity matrix -- independent of the coordinates of the axis u.

When you have a rotation with an angle != 0 then cos(theta) and sin(theta) will be in the range [-1, 1]. The rotation matrix always will be different to the identity matrix.
Mmmh - Yes I see if theta is zero then then the rotation works out as Identity. I also tried altering some Placement properties and see that if angle = 0 it does not matter what values are entered for axis it does not rotate.

Okay let me explain one example of what I was trying to solve. I am trying to check if I can create a some hull requests without resorting to OpenSCAD meshing. When the hull request gets executed it has a number of objects on the stack. If I find two objects on the stack, let's say two cylinders I can check if their axis are parallel and now want to check if two of the end circular faces are in the same plane. I was trying to use Placement Rotations as I was under the impression that if I try and look at the Shapes Faces, there is no guarantee what order or position the circular ones would be.
edwilliams16
Veteran
Posts: 3180
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 »

keithsloan52 wrote: Sat Apr 10, 2021 8:53 pm Okay let me explain one example of what I was trying to solve. I am trying to check if I can create a some hull requests without resorting to OpenSCAD meshing. When the hull request gets executed it has a number of objects on the stack. If I find two objects on the stack, let's say two cylinders I can check if their axis are parallel and now want to check if two of the end circular faces are in the same plane. I was trying to use Placement Rotations as I was under the impression that if I try and look at the Shapes Faces, there is no guarantee what order or position the circular ones would be.
How about backing up a little. You want to implement a convex hull implementation without meshing and calling OpenSCAD? Can you refer me to the algorithm involved?
OpenSCAD's hull uses CGAL, which in turn implements the quickhull algorithm. This works on a point cloud of vertices, so inherently involves a meshed object.

Is your hull supposed to work just with primitives or with more general objects? If the latter, you can't just write recognizer code for circular faces.

You can obviously check if some pair of faces (not necessarily circular) are parallel by looping over both objects and comparing normals.
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: Sat Apr 10, 2021 10:53 pm

How about backing up a little. You want to implement a convex hull implementation without meshing and calling OpenSCAD? Can you refer me to the algorithm involved?
OpenSCAD's hull uses CGAL, which in turn implements the quickhull algorithm. This works on a point cloud of vertices, so inherently involves a meshed object.
You can obviously check if some pair of faces (not necessarily circular) are parallel by looping over both objects and comparing normals.
If you look at https://github.com/KeithSloan/OpenSCAD_Alt_Import and branch newmayer and the code in OpenSCADHull.py
You will see that it currently handles Two unequal Circles, Two unequal Spheres as Non Mesh i.e for such requests it creates a BREP solution that is equivalent to OpenSCAD CGAL hull mesh, but in a lot less time, will export to STEP better etc etc.

There are a number of very good OpenSCAD projects - Microscope, prosthetics that converting to Mesh just doesn't cut the ice as far as conversion to FreeCAD, might as well stick to OpenSCAD

One will never get to handle all situations in non mesh way but hope is that enough can be handled

For test files try
Two-Circles-Hull.csg
(178 Bytes) Downloaded 18 times
Two-Spheres-Hull.csg
(178 Bytes) Downloaded 14 times
Post Reply