





 
 




 
 


Thomas de Groot <tho### [at] degrootorg> wrote:
> 2) Point 1 is crucial to define/calculate the target triangle. It is
> *not* defined from the origin but from the initial triangle.
>
> 3) All apices from the triangle have to be translated by an identical
> vector value. If not, you may have interesting surprises, mostly
> additional rotations to the object. However, those are difficult to
> control from the onset if used on purpose.
Right. The macro takes your exact triangle, and moves it from right where it
is, to exactly where it would be if you moved it there with some unknown
combinations of rotations and translations.
I did wonder what would happen if I jimmied some of the target triangle
coordinates, and yes, the triangles got moved  but I have yet to quantify
exactly how.
 BW
Post a reply to this message


 
 




 
 


The other thing that might not be immediately obvious, but will help in the
overall understanding of the macro's general use is that you only need to
identify 3 points in/on an object in order to line it up with another
instantiation of itself.
Anything. Triangles, cubes, meshes, parametrics, splines, point clouds, or even
entire included scenes.
Let's say you're modeling something in pieces, and you have a spot on a CSG
object where you need to place the next piece. It needs to fit in some specific
alignment, but it's always easier to model things near the origin, lying flat on
a plane, etc.
What you can do is take the points on the csg object that you modeled, and
concatenate all of the transforms that you used to put the object containing
that point where it currently is. Apply that transform to an <x, y, z> vector
using vtransform, and you have the exact coordinates of those points.
Now you can take one of those points and place it on the origin, and either with
math or macros arrange the other two points to lie flat on the plane. Get those
3 coordinates.
Knowing that the triangle on the plane will now fit perfectly into/onto your csg
object, you can model your piece, and then use Reorient_Triangle to just move it
where it needs to go.
Likely we could use a macro that will just grab that csg triangle and move it to
the plane at the origin and return the 3 coordinates as a tuple.
 BW
Post a reply to this message
Attachments:
Download 'pointcloudregistration.png' (48 KB)
Preview of image 'pointcloudregistration.png'


 
 




 
 


Hi(gh)!
On 01.02.24 13:42, Bald Eagle wrote:
> I always find these ritual/religious explanations tiresome  Look around the
> modern world, and try to even count the number of knickknacks, baubles,
> bricabrac, curios, ornaments, souvenirs, and trinkets people buy and
> accumulate  all of which have zero ritualistic or religious purpose or meaning.
In Germany, some call these things "Hinstellchen und Verstaubchen"
(placelets and little dust collectors), or, if of the larger kind,
"RumstehoMaten" (standaroundomatons)... at least they have not taken
over Khyberspace Ground Control yet! Except for a small plastic PEZ
sweets dispenser in the shape of Jason Momoa in "Aquaman"... sorry, but
I simply dig longhaired and bearded men! And lynxes... but it's hard to
find a naturalistic lifesized sitting wooden lynx for the top of my
eorgan! Or perhaps better a Vangelis bust?
>
> It could have been a _designer_ dodecahedron that was very trendy, and only the
> wealthiest could afford then, to flaunt their status.
...then most likely not made by Fortis, the oil lamp manufacture!
See you in Khyberspace!
Yadgar
Now playing: Total Eclipse Of The Heart (Bonnie Tyler)

VBI BENE, IBI BACTRIA!
Post a reply to this message


 
 




 
 


Op 922024 om 13:33 schreef Bald Eagle:
> Thomas de Groot <tho### [at] degrootorg> wrote:
>
>> 2) Point 1 is crucial to define/calculate the target triangle. It is
>> *not* defined from the origin but from the initial triangle.
>>
>> 3) All apices from the triangle have to be translated by an identical
>> vector value. If not, you may have interesting surprises, mostly
>> additional rotations to the object. However, those are difficult to
>> control from the onset if used on purpose.
>
> Right. The macro takes your exact triangle, and moves it from right where it
> is, to exactly where it would be if you moved it there with some unknown
> combinations of rotations and translations.
>
Yes, that works very straightforward indeed.
> I did wonder what would happen if I jimmied some of the target triangle
> coordinates, and yes, the triangles got moved  but I have yet to quantify
> exactly how.
>
There are some unknown (to me) issues there which I want to delve deeper
into, as for instance those making the object rotate around one or more
axis, as I wrote earlier, under comment 3. It might be a powerful,
additional, feature if we understand how and under what conditions, it
can be used in a controlled way.

Thomas
Post a reply to this message


 
 




 
 


Op 922024 om 14:24 schreef Bald Eagle:
> The other thing that might not be immediately obvious, but will help in the
> overall understanding of the macro's general use is that you only need to
> identify 3 points in/on an object in order to line it up with another
> instantiation of itself.
>
> Anything. Triangles, cubes, meshes, parametrics, splines, point clouds, or even
> entire included scenes.
>
Yes, that is the fantastical approach of the macro. And it is so easy in
use!
> Let's say you're modeling something in pieces, and you have a spot on a CSG
> object where you need to place the next piece. It needs to fit in some specific
> alignment, but it's always easier to model things near the origin, lying flat on
> a plane, etc.
>
> What you can do is take the points on the csg object that you modeled, and
> concatenate all of the transforms that you used to put the object containing
> that point where it currently is. Apply that transform to an <x, y, z> vector
> using vtransform, and you have the exact coordinates of those points.
>
> Now you can take one of those points and place it on the origin, and either with
> math or macros arrange the other two points to lie flat on the plane. Get those
> 3 coordinates.
>
> Knowing that the triangle on the plane will now fit perfectly into/onto your csg
> object, you can model your piece, and then use Reorient_Triangle to just move it
> where it needs to go.
>
> Likely we could use a macro that will just grab that csg triangle and move it to
> the plane at the origin and return the 3 coordinates as a tuple.
>
I had not yet thought that far, but that would be a logical use of the
macro. Something to experiment with. It might solve some issues I was
struggling with in my LogoPlanet scene recently.

Thomas
Post a reply to this message


 
 




 
 


Op 722024 om 17:35 schreef Bald Eagle:
> Thomas de Groot <tho### [at] degrootorg> wrote:
>
>> I dimly remembered an old post about Euler matrix rotations:
>>
>
> Very nice. I'll hopefully get a chance to take a look at that code and what it
> does in the coming week.
>
Good.
> In preparation for that, I wrote a little transform visualization playground
> that compares the transformed world coordinates (basis vectors) to the camera
> basis vectors.
> (I phrase it that way, since if you apply a transform to the camera, you'll get
> the effect of transforming all of POVspace with that transform)
>
> It's also difficult for most people to grasp and clearly understand what's going
> on with a matrix transform, and keep track of how the basis vectors get
> processed, and what the values in the matrix < > (matrix vector) directive
> represent.
>
Very useful! And yes, meddling with matrix feels like (black) magic... ;)
> So the first transform I rendered is the Shear_Trans (), since it's a straight
> conversion of the basis vector space to what's specified in the matrix vector.
> There's really no "shear" unless you specify one.
> Shear_Trans () really does nothing except apply a straight transform {matrix
> <>}.
> You can use it to shear, scale, or rotate, or all 3, depending on what values
> you put in for the arguments. You can't do translations with it, since that
> last row vector is hardcoded in the macro to 0, 0, 0.
>
Excellent initiative! Going to put that into my HowTo folder, and play
with it as soon as I can find a few free seconds of time.

Thomas
Post a reply to this message


 
 




 
 


Op 922024 om 22:00 schreef Jörg "Yadgar" Bleimann:
> Hi(gh)!
>
> VBI BENE, IBI BACTRIA
Of course! I almost forgot /who/ wrote the message. :)

Thomas
Post a reply to this message


 
 




 
 


"Bald Eagle" <cre### [at] netscapenet> wrote:
>...
> Identify any three points on your original object (A, B, C), and where those
> three points end up (A2, B2, C2)
>
> Apply the macro like so:
> #declare MyTransform = Reorient_Triangle (A, B, C, A2, B2, C2)
> object {MyObject transform {MyTransform}}
>
> Please try this out with a large assortment of objects in various orientations
> to see if I missed anything. The only thing not included is a sanity check for
> plugging in a second set of coordinates that are identical to the first.
>
> #macro Reorient_Triangle (A, B, C, A2, B2, C2)
> // Bill Walker "Bald Eagle" February 2024
> #ifndef(TRANSFORMS_INC_TEMP)
> #include "transforms.inc"
> #end
> #local Translate1 = transform {translate A}
> #local Vector1 = B  A;
> #local Vector2 = B2  A2;
> // Align Vector1 to Vector2
> #local FirstTransform = transform {Reorient_Trans (Vector1, Vector2)};
> #local A1 = vtransform (AA, FirstTransform)+A;
> #local B1 = vtransform (BA, FirstTransform)+A;
> #local C1 = vtransform (CA, FirstTransform)+A;
> // Find the vector to C1 that is perpendicular to Vector2
> #local T1 = vdot (B1A1, C1A1) / vdot (B1A1, B1A1);
> #local D = A1 + T1 * (B1A1);
> #local Vector3 = C1  D;
> // Find the vector to C2 that is perpendicular to Vector2
> #local T2 = vdot (B2A2, C2A2) / vdot (B2A2, B2A2);
> #local D2 = A2 + T2 * (B2A2);
> #local Vector4 = C2  D2;
> // Rotate everything around Vector2 so that the perpendicular vectors match
> #local SecondTransform = transform {Reorient_Trans (Vector3, Vector4)};
> // Now everything is similarly aligned with 3 sequential transforms
> // and translating a final time puts the object at the destination
> #local Translate2 = transform {translate A2}
> #local T = transform { transform {Translate1} transform {FirstTransform}
> transform {SecondTransform} transform {Translate2} }
>
> T
>
> #end
>...
Hi Bill
To simplify your macro, you could first simplify the problem, like this:
You can start with two triangles A, B, C and A2, B2, C2, which have their A and
A2 points at origo.
This means the translate A and translate A2 transformations will not lead to
any changes, so they can be removed.
Your A1 point will now also end up at origo, since the reorient transformation
does not result in any translations, only a rotation.
So now you can remove A, A1 and A2 from all expressions in your macro.
You will then get some variables whose values are only copies of other
variables' values. You can eliminate these by using those other variables
instead.
Parts of your expressions for T1/D and T2/D2 can be replaced with a call to the
VProject_Plane() macro from math.inc or VectorProject() from my vectors.inc.
To "unsimplify" the problem again, in order to deal with triangles which does
not have their A and A2 points at origo, you can just reintroduce the translate
A and translate A2 transformations in the resulting composite transform
expression.
P.S.: You don't have to wrap the Reorient_Trans macro calls into transform { }
statements, because this is already done by the Reorient_Trans macro itself.
P.P.S. That also goes for the transformations within the final transform { }
statement. You can write it like this: transform { Translate1 FirstTransform
SecondTransform Translate2 }  and you don't have to put it into a variable (T)
before you return it.

Tor Olav
http://subcube.com
https://github.com/tok
Post a reply to this message


 
 




 
 


"Tor Olav Kristensen" <tor### [at] TOBEREMOVEDgmailcom> wrote:
>...
> To "unsimplify" the problem again, in order to deal with triangles which does
> not have their A and A2 points at origo, you can just reintroduce the translate
> A and translate A2 transformations in the resulting composite transform
> expression.
Sorry Bill
What I wrote above is not true. I forgot to uncomment the translations in my
test transform before testing my modifications to your macro.
This macro version works when p0A = <0, 0, 0> and p2A = <0, 0, 0>:
#macro Reorient_Triangle(p0B, p0C, p2B, p2C)
#local FirstTransform = Reorient_Trans(p0B, p2B)
#local p1B = vtransform(p0B, FirstTransform);
#local p1C = vtransform(p0C, FirstTransform);
#local p1D = vdot(p1C, p1B)/vdot(p1B, p1B)*p1B;
#local p2D = vdot(p2C, p2B)/vdot(p2B, p2B)*p2B;
#local v1D1C = p1C  p1D;
#local v2D2C = p2C  p2D;
#local SecondTransform = Reorient_Trans(v1D1C, v2D2C)
transform {
transform { FirstTransform }
transform { SecondTransform }
}
#end // macro Reorient_Triangle
 and this version also works when that is not the case. I.e. It also works when
there are translations within the transformation.
#macro Reorient_Triangle(p0A, p0B, p0C, p2A, p2B, p2C)
#local v0A0B = p0B  p0A;
#local v0A0C = p0C  p0A;
#local v2A2B = p2B  p2A;
#local v2A2C = p2C  p2A;
#local FirstTransform = Reorient_Trans(v0A0B, v2A2B)
#local v0A1B = vtransform(v0A0B, FirstTransform);
#local v0A1C = vtransform(v0A0C, FirstTransform);
#local v1D1C = v0A1C  vdot(v0A1C, v0A1B)/vdot(v0A1B, v0A1B)*v0A1B;
#local v2D2C = v2A2C  vdot(v2A2C, v2A2B)/vdot(v2A2B, v2A2B)*v2A2B;
#local SecondTransform = Reorient_Trans(v1D1C, v2D2C)
transform {
transform { translate p0A }
transform { FirstTransform }
transform { SecondTransform }
transform { translate +p2A }
}
#end // macro Reorient_Triangle

Tor Olav
http://subcube.com
https://github.com/tok
Post a reply to this message


 
 




 
 


"Tor Olav Kristensen" <tor### [at] TOBEREMOVEDgmailcom> wrote:
>...
>  and this version also works when that is not the case. I.e. It also works when
> there are translations within the transformation.
>
> #macro Reorient_Triangle(p0A, p0B, p0C, p2A, p2B, p2C)
>
> #local v0A0B = p0B  p0A;
> #local v0A0C = p0C  p0A;
> #local v2A2B = p2B  p2A;
> #local v2A2C = p2C  p2A;
> #local FirstTransform = Reorient_Trans(v0A0B, v2A2B)
> #local v0A1B = vtransform(v0A0B, FirstTransform);
> #local v0A1C = vtransform(v0A0C, FirstTransform);
> #local v1D1C = v0A1C  vdot(v0A1C, v0A1B)/vdot(v0A1B, v0A1B)*v0A1B;
> #local v2D2C = v2A2C  vdot(v2A2C, v2A2B)/vdot(v2A2B, v2A2B)*v2A2B;
> #local SecondTransform = Reorient_Trans(v1D1C, v2D2C)
>
> transform {
> transform { translate p0A }
> transform { FirstTransform }
> transform { SecondTransform }
> transform { translate +p2A }
> }
>
> #end // macro Reorient_Triangle
In the macro above v1D1C is perpendicular to v0A1B and v2D2C is perpendicular to
v2A2B. I.e vdot(v1D1C, v0A1B) = 0 and vdot(v2D2C, v2A2B) = 0.
It is also possible to find another vector; v1 that is perpendicular to v0A1B0
and another vector; v2 that is perpendicular to v2A2B by calculating two cross
products, like this:
v1 = vcross(v0A1B, v0A1C)
v2 = vcross(v2A2B, v2A2C)
Then the macro can be rewritten like this:
#macro Reorient_Triangle(p0A, p0B, p0C, p2A, p2B, p2C)
#local v0A0B = p0B  p0A;
#local v0A0C = p0C  p0A;
#local v2A2B = p2B  p2A;
#local v2A2C = p2C  p2A;
#local FirstTransform = Reorient_Trans(v0A0B, v2A2B)
#local v0A1B = vtransform(v0A0B, FirstTransform);
#local v0A1C = vtransform(v0A0C, FirstTransform);
#local v1 = vcross(v0A1B, v0A1C);
#local v2 = vcross(v2A2B, v2A2C);
#local SecondTransform = Reorient_Trans(v1, v2)
transform {
translate p0A
FirstTransform
SecondTransform
translate +p2A
}
#end // macro Reorient_Triangle
 which can be simplified a little bit, like e.g. this:
#macro Reorient_Triangle(p0A, p0B, p0C, p2A, p2B, p2C)
#local v0A0B = p0B  p0A;
#local v0A0C = p0C  p0A;
#local v2A2B = p2B  p2A;
#local v2A2C = p2C  p2A;
#local Transform = Reorient_Trans(v0A0B, v2A2B)
transform {
translate p0A
Transform
Reorient_Trans(
vtransform(
vcross(v0A0B, v0A0C),
Transform
),
vcross(v2A2B, v2A2C)
)
translate +p2A
}
#end // macro Reorient_Triangle
 but imho it does now look a bit ugly.

Tor Olav
http://subcube.com
https://github.com/tok
Post a reply to this message


 
 




 

