discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

module for rotating an object around any axis is required

SP
Sanjeev Prabhakar
Thu, Mar 23, 2023 2:44 AM

I would propose if a module can be developed to rotate an object around an
axis.

e.g. for any sequence of rotations an equivalent axis and angle can be
found from the functions written below

function cvar(a)=
let(
text=a[0],
b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]:
search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]:
search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]],
n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]],
l=len(b),
c=[for(i=[0:l-1])each search(b[i],n)],
d=[for(i=[0:len(c)-1])10^(l-i-1)],
e=cd,
f=search(".",a)!=[]&&search("-",a)!=[]?e
10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e10^-(l-(search(".",a)[0]-1)):e,
g=search("-",a)!=[]?f
-1:f
)[text,g];

//function to rotate a point around a vector(axis) with angle theta

function q(vector=[1,0,0],point=[0,5,0],theta=0)=

let(t=theta,
v=vector/norm(vector),
p=[cos(t/2),vsin(t/2)],
p1=[p.x,-p.y],
q=[0,len(point)==2?[point.x,point.y,0]:point],
pq=[p.x
q.x-p.yq.y,p.xq.y+p.yq.x+cross(p.y,q.y)],
pqp1=[pq.x
p1.x-pq.yp1.y,pq.xp1.y+pq.y*p1.x+cross(pq.y,p1.y)],
transformation=pqp1.y
)

transformation
;
// function is input to another function q_rot
function qmr1(s,r,pl,n=0)= n==len(s)?pl:
qmr1(s,r,
let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(p=pl)q(v1,p,r1)],n+1);
//function is input to another function q_rot
function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1);

//function to rotate a group of points "pl" around a series of axis with
defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will
rotate the line first around z axis by 20 deg then around x axis by 40
degrees and then around y axis by 80 degrees.
function q_rot(s,pl)=
is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl);

// sequence of rotation defined by r1
r1=["x30","y40","z100"];
vz=[0,0,1];
v1=q_rot(r1,[vz])[0];

v2=cross(vz,v1);
theta=acos(vz*v1/norm(v1));

// equivalent rotation axis and angle of rotation w.r.t vector vz
echo(v2,theta);

I would propose if a module can be developed to rotate an object around an axis. e.g. for any sequence of rotations an equivalent axis and angle can be found from the functions written below function cvar(a)= let( text=a[0], b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]: search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]: search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]], n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]], l=len(b), c=[for(i=[0:l-1])each search(b[i],n)], d=[for(i=[0:len(c)-1])10^(l-i-1)], e=c*d, f=search(".",a)!=[]&&search("-",a)!=[]?e*10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e*10^-(l-(search(".",a)[0]-1)):e, g=search("-",a)!=[]?f*-1:f )[text,g]; //function to rotate a point around a vector(axis) with angle theta function q(vector=[1,0,0],point=[0,5,0],theta=0)= let(t=theta, v=vector/norm(vector), p=[cos(t/2),v*sin(t/2)], p1=[p.x,-p.y], q=[0,len(point)==2?[point.x,point.y,0]:point], pq=[p.x*q.x-p.y*q.y,p.x*q.y+p.y*q.x+cross(p.y,q.y)], pqp1=[pq.x*p1.x-pq.y*p1.y,pq.x*p1.y+pq.y*p1.x+cross(pq.y,p1.y)], transformation=pqp1.y ) transformation ; // function is input to another function q_rot function qmr1(s,r,pl,n=0)= n==len(s)?pl: qmr1(s,r, let( v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], r1=r[n]==undef?0:r[n]) [for(p=pl)q(v1,p,r1)],n+1); //function is input to another function q_rot function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let( v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], r1=r[n]==undef?0:r[n]) [for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1); //function to rotate a group of points "pl" around a series of axis with defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will rotate the line first around z axis by 20 deg then around x axis by 40 degrees and then around y axis by 80 degrees. function q_rot(s,pl)= is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl); // sequence of rotation defined by r1 r1=["x30","y40","z100"]; vz=[0,0,1]; v1=q_rot(r1,[vz])[0]; v2=cross(vz,v1); theta=acos(vz*v1/norm(v1)); // equivalent rotation axis and angle of rotation w.r.t vector vz echo(v2,theta);
KT
Kevin Toppenberg
Fri, Mar 24, 2023 9:23 PM

The math is too dense for me to pick apart, but it seems that when I worked
on this in a different engine, that the math involves quaternions.

Does this solution use quaternions?

Kevin

On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I would propose if a module can be developed to rotate an object around an
axis.

e.g. for any sequence of rotations an equivalent axis and angle can be
found from the functions written below

function cvar(a)=
let(
text=a[0],

b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]:
search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]:

search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]],
n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]],
l=len(b),
c=[for(i=[0:l-1])each search(b[i],n)],
d=[for(i=[0:len(c)-1])10^(l-i-1)],
e=c*d,

f=search(".",a)!=[]&&search("-",a)!=[]?e10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e10^-(l-(search(".",a)[0]-1)):e,
g=search("-",a)!=[]?f*-1:f
)[text,g];

//function to rotate a point around a vector(axis) with angle theta

function q(vector=[1,0,0],point=[0,5,0],theta=0)=

let(t=theta,
v=vector/norm(vector),
p=[cos(t/2),vsin(t/2)],
p1=[p.x,-p.y],
q=[0,len(point)==2?[point.x,point.y,0]:point],
pq=[p.x
q.x-p.yq.y,p.xq.y+p.yq.x+cross(p.y,q.y)],
pqp1=[pq.x
p1.x-pq.yp1.y,pq.xp1.y+pq.y*p1.x+cross(pq.y,p1.y)],
transformation=pqp1.y
)

transformation
;
// function is input to another function q_rot
function qmr1(s,r,pl,n=0)= n==len(s)?pl:
qmr1(s,r,
let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(p=pl)q(v1,p,r1)],n+1);
//function is input to another function q_rot
function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1);

//function to rotate a group of points "pl" around a series of axis with
defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will
rotate the line first around z axis by 20 deg then around x axis by 40
degrees and then around y axis by 80 degrees.
function q_rot(s,pl)=
is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl);

// sequence of rotation defined by r1
r1=["x30","y40","z100"];
vz=[0,0,1];
v1=q_rot(r1,[vz])[0];

v2=cross(vz,v1);
theta=acos(vz*v1/norm(v1));

// equivalent rotation axis and angle of rotation w.r.t vector vz
echo(v2,theta);


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

The math is too dense for me to pick apart, but it seems that when I worked on this in a different engine, that the math involves quaternions. Does this solution use quaternions? Kevin On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > I would propose if a module can be developed to rotate an object around an > axis. > > e.g. for any sequence of rotations an equivalent axis and angle can be > found from the functions written below > > function cvar(a)= > let( > text=a[0], > > b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]: > search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]: > > search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]], > n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]], > l=len(b), > c=[for(i=[0:l-1])each search(b[i],n)], > d=[for(i=[0:len(c)-1])10^(l-i-1)], > e=c*d, > > f=search(".",a)!=[]&&search("-",a)!=[]?e*10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e*10^-(l-(search(".",a)[0]-1)):e, > g=search("-",a)!=[]?f*-1:f > )[text,g]; > > //function to rotate a point around a vector(axis) with angle theta > > function q(vector=[1,0,0],point=[0,5,0],theta=0)= > > let(t=theta, > v=vector/norm(vector), > p=[cos(t/2),v*sin(t/2)], > p1=[p.x,-p.y], > q=[0,len(point)==2?[point.x,point.y,0]:point], > pq=[p.x*q.x-p.y*q.y,p.x*q.y+p.y*q.x+cross(p.y,q.y)], > pqp1=[pq.x*p1.x-pq.y*p1.y,pq.x*p1.y+pq.y*p1.x+cross(pq.y,p1.y)], > transformation=pqp1.y > ) > > transformation > ; > // function is input to another function q_rot > function qmr1(s,r,pl,n=0)= n==len(s)?pl: > qmr1(s,r, > let( > v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], > r1=r[n]==undef?0:r[n]) > [for(p=pl)q(v1,p,r1)],n+1); > //function is input to another function q_rot > function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let( > v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], > r1=r[n]==undef?0:r[n]) > [for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1); > > //function to rotate a group of points "pl" around a series of axis with > defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will > rotate the line first around z axis by 20 deg then around x axis by 40 > degrees and then around y axis by 80 degrees. > function q_rot(s,pl)= > is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl); > > // sequence of rotation defined by r1 > r1=["x30","y40","z100"]; > vz=[0,0,1]; > v1=q_rot(r1,[vz])[0]; > > v2=cross(vz,v1); > theta=acos(vz*v1/norm(v1)); > > // equivalent rotation axis and angle of rotation w.r.t vector vz > echo(v2,theta); > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Fri, Mar 24, 2023 9:31 PM

Of course a module can be developed to rotate around an arbitrary axis: the
native rotate in fact already does this with the v= argument.

On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I would propose if a module can be developed to rotate an object around an
axis.

e.g. for any sequence of rotations an equivalent axis and angle can be
found from the functions written below

function cvar(a)=
let(
text=a[0],

b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]:
search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]:

search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]],
n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]],
l=len(b),
c=[for(i=[0:l-1])each search(b[i],n)],
d=[for(i=[0:len(c)-1])10^(l-i-1)],
e=c*d,

f=search(".",a)!=[]&&search("-",a)!=[]?e10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e10^-(l-(search(".",a)[0]-1)):e,
g=search("-",a)!=[]?f*-1:f
)[text,g];

//function to rotate a point around a vector(axis) with angle theta

function q(vector=[1,0,0],point=[0,5,0],theta=0)=

let(t=theta,
v=vector/norm(vector),
p=[cos(t/2),vsin(t/2)],
p1=[p.x,-p.y],
q=[0,len(point)==2?[point.x,point.y,0]:point],
pq=[p.x
q.x-p.yq.y,p.xq.y+p.yq.x+cross(p.y,q.y)],
pqp1=[pq.x
p1.x-pq.yp1.y,pq.xp1.y+pq.y*p1.x+cross(pq.y,p1.y)],
transformation=pqp1.y
)

transformation
;
// function is input to another function q_rot
function qmr1(s,r,pl,n=0)= n==len(s)?pl:
qmr1(s,r,
let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(p=pl)q(v1,p,r1)],n+1);
//function is input to another function q_rot
function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1);

//function to rotate a group of points "pl" around a series of axis with
defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will
rotate the line first around z axis by 20 deg then around x axis by 40
degrees and then around y axis by 80 degrees.
function q_rot(s,pl)=
is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl);

// sequence of rotation defined by r1
r1=["x30","y40","z100"];
vz=[0,0,1];
v1=q_rot(r1,[vz])[0];

v2=cross(vz,v1);
theta=acos(vz*v1/norm(v1));

// equivalent rotation axis and angle of rotation w.r.t vector vz
echo(v2,theta);


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Of course a module can be developed to rotate around an arbitrary axis: the native rotate in fact already does this with the v= argument. On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > I would propose if a module can be developed to rotate an object around an > axis. > > e.g. for any sequence of rotations an equivalent axis and angle can be > found from the functions written below > > function cvar(a)= > let( > text=a[0], > > b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]: > search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]: > > search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]], > n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]], > l=len(b), > c=[for(i=[0:l-1])each search(b[i],n)], > d=[for(i=[0:len(c)-1])10^(l-i-1)], > e=c*d, > > f=search(".",a)!=[]&&search("-",a)!=[]?e*10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e*10^-(l-(search(".",a)[0]-1)):e, > g=search("-",a)!=[]?f*-1:f > )[text,g]; > > //function to rotate a point around a vector(axis) with angle theta > > function q(vector=[1,0,0],point=[0,5,0],theta=0)= > > let(t=theta, > v=vector/norm(vector), > p=[cos(t/2),v*sin(t/2)], > p1=[p.x,-p.y], > q=[0,len(point)==2?[point.x,point.y,0]:point], > pq=[p.x*q.x-p.y*q.y,p.x*q.y+p.y*q.x+cross(p.y,q.y)], > pqp1=[pq.x*p1.x-pq.y*p1.y,pq.x*p1.y+pq.y*p1.x+cross(pq.y,p1.y)], > transformation=pqp1.y > ) > > transformation > ; > // function is input to another function q_rot > function qmr1(s,r,pl,n=0)= n==len(s)?pl: > qmr1(s,r, > let( > v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], > r1=r[n]==undef?0:r[n]) > [for(p=pl)q(v1,p,r1)],n+1); > //function is input to another function q_rot > function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let( > v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], > r1=r[n]==undef?0:r[n]) > [for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1); > > //function to rotate a group of points "pl" around a series of axis with > defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will > rotate the line first around z axis by 20 deg then around x axis by 40 > degrees and then around y axis by 80 degrees. > function q_rot(s,pl)= > is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl); > > // sequence of rotation defined by r1 > r1=["x30","y40","z100"]; > vz=[0,0,1]; > v1=q_rot(r1,[vz])[0]; > > v2=cross(vz,v1); > theta=acos(vz*v1/norm(v1)); > > // equivalent rotation axis and angle of rotation w.r.t vector vz > echo(v2,theta); > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Fri, Mar 24, 2023 11:38 PM

Yes the function q() is quaternion rotation

Rest of it is mainly to rotate a vector to a sequence.

You can give any length of sequence in any order e.g.
"x30","z90","y73","z50","x43" etc.

On Sat, 25 Mar, 2023, 2:54 am Kevin Toppenberg, kdtop3@gmail.com wrote:

The math is too dense for me to pick apart, but it seems that when I
worked on this in a different engine, that the math involves quaternions.

Does this solution use quaternions?

Kevin

On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I would propose if a module can be developed to rotate an object around
an axis.

e.g. for any sequence of rotations an equivalent axis and angle can be
found from the functions written below

function cvar(a)=
let(
text=a[0],

b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]:
search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]:

search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]],
n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]],
l=len(b),
c=[for(i=[0:l-1])each search(b[i],n)],
d=[for(i=[0:len(c)-1])10^(l-i-1)],
e=c*d,

f=search(".",a)!=[]&&search("-",a)!=[]?e10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e10^-(l-(search(".",a)[0]-1)):e,
g=search("-",a)!=[]?f*-1:f
)[text,g];

//function to rotate a point around a vector(axis) with angle theta

function q(vector=[1,0,0],point=[0,5,0],theta=0)=

let(t=theta,
v=vector/norm(vector),
p=[cos(t/2),vsin(t/2)],
p1=[p.x,-p.y],
q=[0,len(point)==2?[point.x,point.y,0]:point],
pq=[p.x
q.x-p.yq.y,p.xq.y+p.yq.x+cross(p.y,q.y)],
pqp1=[pq.x
p1.x-pq.yp1.y,pq.xp1.y+pq.y*p1.x+cross(pq.y,p1.y)],
transformation=pqp1.y
)

transformation
;
// function is input to another function q_rot
function qmr1(s,r,pl,n=0)= n==len(s)?pl:
qmr1(s,r,
let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(p=pl)q(v1,p,r1)],n+1);
//function is input to another function q_rot
function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1);

//function to rotate a group of points "pl" around a series of axis with
defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will
rotate the line first around z axis by 20 deg then around x axis by 40
degrees and then around y axis by 80 degrees.
function q_rot(s,pl)=
is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl);

// sequence of rotation defined by r1
r1=["x30","y40","z100"];
vz=[0,0,1];
v1=q_rot(r1,[vz])[0];

v2=cross(vz,v1);
theta=acos(vz*v1/norm(v1));

// equivalent rotation axis and angle of rotation w.r.t vector vz
echo(v2,theta);


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Yes the function q() is quaternion rotation Rest of it is mainly to rotate a vector to a sequence. You can give any length of sequence in any order e.g. "x30","z90","y73","z50","x43" etc. On Sat, 25 Mar, 2023, 2:54 am Kevin Toppenberg, <kdtop3@gmail.com> wrote: > The math is too dense for me to pick apart, but it seems that when I > worked on this in a different engine, that the math involves quaternions. > > Does this solution use quaternions? > > Kevin > > On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar < > sprabhakar2006@gmail.com> wrote: > >> I would propose if a module can be developed to rotate an object around >> an axis. >> >> e.g. for any sequence of rotations an equivalent axis and angle can be >> found from the functions written below >> >> function cvar(a)= >> let( >> text=a[0], >> >> b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]: >> search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]: >> >> search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]], >> n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]], >> l=len(b), >> c=[for(i=[0:l-1])each search(b[i],n)], >> d=[for(i=[0:len(c)-1])10^(l-i-1)], >> e=c*d, >> >> f=search(".",a)!=[]&&search("-",a)!=[]?e*10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e*10^-(l-(search(".",a)[0]-1)):e, >> g=search("-",a)!=[]?f*-1:f >> )[text,g]; >> >> //function to rotate a point around a vector(axis) with angle theta >> >> function q(vector=[1,0,0],point=[0,5,0],theta=0)= >> >> let(t=theta, >> v=vector/norm(vector), >> p=[cos(t/2),v*sin(t/2)], >> p1=[p.x,-p.y], >> q=[0,len(point)==2?[point.x,point.y,0]:point], >> pq=[p.x*q.x-p.y*q.y,p.x*q.y+p.y*q.x+cross(p.y,q.y)], >> pqp1=[pq.x*p1.x-pq.y*p1.y,pq.x*p1.y+pq.y*p1.x+cross(pq.y,p1.y)], >> transformation=pqp1.y >> ) >> >> transformation >> ; >> // function is input to another function q_rot >> function qmr1(s,r,pl,n=0)= n==len(s)?pl: >> qmr1(s,r, >> let( >> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >> r1=r[n]==undef?0:r[n]) >> [for(p=pl)q(v1,p,r1)],n+1); >> //function is input to another function q_rot >> function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let( >> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >> r1=r[n]==undef?0:r[n]) >> [for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1); >> >> //function to rotate a group of points "pl" around a series of axis with >> defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will >> rotate the line first around z axis by 20 deg then around x axis by 40 >> degrees and then around y axis by 80 degrees. >> function q_rot(s,pl)= >> is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl); >> >> // sequence of rotation defined by r1 >> r1=["x30","y40","z100"]; >> vz=[0,0,1]; >> v1=q_rot(r1,[vz])[0]; >> >> v2=cross(vz,v1); >> theta=acos(vz*v1/norm(v1)); >> >> // equivalent rotation axis and angle of rotation w.r.t vector vz >> echo(v2,theta); >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Fri, Mar 24, 2023 11:46 PM

I mean for 3d models without the points list.

This can make the rotations easier to write in my opinion and would request
openscad developers to make a module which rotates the object around an
arbitrary axis, rather than only x,y and z

For the models which I develop with the points list, I have written a
function which does this.

On Sat, 25 Mar, 2023, 3:01 am Adrian Mariano, avm4@cornell.edu wrote:

Of course a module can be developed to rotate around an arbitrary axis:
the native rotate in fact already does this with the v= argument.

On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I would propose if a module can be developed to rotate an object around
an axis.

e.g. for any sequence of rotations an equivalent axis and angle can be
found from the functions written below

function cvar(a)=
let(
text=a[0],

b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]:
search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]:

search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]],
n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]],
l=len(b),
c=[for(i=[0:l-1])each search(b[i],n)],
d=[for(i=[0:len(c)-1])10^(l-i-1)],
e=c*d,

f=search(".",a)!=[]&&search("-",a)!=[]?e10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e10^-(l-(search(".",a)[0]-1)):e,
g=search("-",a)!=[]?f*-1:f
)[text,g];

//function to rotate a point around a vector(axis) with angle theta

function q(vector=[1,0,0],point=[0,5,0],theta=0)=

let(t=theta,
v=vector/norm(vector),
p=[cos(t/2),vsin(t/2)],
p1=[p.x,-p.y],
q=[0,len(point)==2?[point.x,point.y,0]:point],
pq=[p.x
q.x-p.yq.y,p.xq.y+p.yq.x+cross(p.y,q.y)],
pqp1=[pq.x
p1.x-pq.yp1.y,pq.xp1.y+pq.y*p1.x+cross(pq.y,p1.y)],
transformation=pqp1.y
)

transformation
;
// function is input to another function q_rot
function qmr1(s,r,pl,n=0)= n==len(s)?pl:
qmr1(s,r,
let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(p=pl)q(v1,p,r1)],n+1);
//function is input to another function q_rot
function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1);

//function to rotate a group of points "pl" around a series of axis with
defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will
rotate the line first around z axis by 20 deg then around x axis by 40
degrees and then around y axis by 80 degrees.
function q_rot(s,pl)=
is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl);

// sequence of rotation defined by r1
r1=["x30","y40","z100"];
vz=[0,0,1];
v1=q_rot(r1,[vz])[0];

v2=cross(vz,v1);
theta=acos(vz*v1/norm(v1));

// equivalent rotation axis and angle of rotation w.r.t vector vz
echo(v2,theta);


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I mean for 3d models without the points list. This can make the rotations easier to write in my opinion and would request openscad developers to make a module which rotates the object around an arbitrary axis, rather than only x,y and z For the models which I develop with the points list, I have written a function which does this. On Sat, 25 Mar, 2023, 3:01 am Adrian Mariano, <avm4@cornell.edu> wrote: > Of course a module can be developed to rotate around an arbitrary axis: > the native rotate in fact already does this with the v= argument. > > > On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar < > sprabhakar2006@gmail.com> wrote: > >> I would propose if a module can be developed to rotate an object around >> an axis. >> >> e.g. for any sequence of rotations an equivalent axis and angle can be >> found from the functions written below >> >> function cvar(a)= >> let( >> text=a[0], >> >> b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]: >> search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]: >> >> search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]], >> n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]], >> l=len(b), >> c=[for(i=[0:l-1])each search(b[i],n)], >> d=[for(i=[0:len(c)-1])10^(l-i-1)], >> e=c*d, >> >> f=search(".",a)!=[]&&search("-",a)!=[]?e*10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e*10^-(l-(search(".",a)[0]-1)):e, >> g=search("-",a)!=[]?f*-1:f >> )[text,g]; >> >> //function to rotate a point around a vector(axis) with angle theta >> >> function q(vector=[1,0,0],point=[0,5,0],theta=0)= >> >> let(t=theta, >> v=vector/norm(vector), >> p=[cos(t/2),v*sin(t/2)], >> p1=[p.x,-p.y], >> q=[0,len(point)==2?[point.x,point.y,0]:point], >> pq=[p.x*q.x-p.y*q.y,p.x*q.y+p.y*q.x+cross(p.y,q.y)], >> pqp1=[pq.x*p1.x-pq.y*p1.y,pq.x*p1.y+pq.y*p1.x+cross(pq.y,p1.y)], >> transformation=pqp1.y >> ) >> >> transformation >> ; >> // function is input to another function q_rot >> function qmr1(s,r,pl,n=0)= n==len(s)?pl: >> qmr1(s,r, >> let( >> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >> r1=r[n]==undef?0:r[n]) >> [for(p=pl)q(v1,p,r1)],n+1); >> //function is input to another function q_rot >> function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let( >> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >> r1=r[n]==undef?0:r[n]) >> [for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1); >> >> //function to rotate a group of points "pl" around a series of axis with >> defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will >> rotate the line first around z axis by 20 deg then around x axis by 40 >> degrees and then around y axis by 80 degrees. >> function q_rot(s,pl)= >> is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl); >> >> // sequence of rotation defined by r1 >> r1=["x30","y40","z100"]; >> vz=[0,0,1]; >> v1=q_rot(r1,[vz])[0]; >> >> v2=cross(vz,v1); >> theta=acos(vz*v1/norm(v1)); >> >> // equivalent rotation axis and angle of rotation w.r.t vector vz >> echo(v2,theta); >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Sat, Mar 25, 2023 12:01 AM

Yes, for 3d geometry, not point lists, the already existing OpenSCAD
rotate() module will rotate angle a around an arbitrary axis v.  I don't
find this to be a particularly useful operation in general, though.  Must
more useful is rotating one vector onto another. We asked at one point for
them to add rotation that maps vector v onto vector w and they said this
was not suitable to be native and should be done in user space.  Of course,
BOSL2 can produce rotation matrices or apply rotations to point lists.

On Fri, Mar 24, 2023 at 7:48 PM Sanjeev Prabhakar sprabhakar2006@gmail.com
wrote:

I mean for 3d models without the points list.

This can make the rotations easier to write in my opinion and would
request openscad developers to make a module which rotates the object
around an arbitrary axis, rather than only x,y and z

For the models which I develop with the points list, I have written a
function which does this.

On Sat, 25 Mar, 2023, 3:01 am Adrian Mariano, avm4@cornell.edu wrote:

Of course a module can be developed to rotate around an arbitrary axis:
the native rotate in fact already does this with the v= argument.

On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I would propose if a module can be developed to rotate an object around
an axis.

e.g. for any sequence of rotations an equivalent axis and angle can be
found from the functions written below

function cvar(a)=
let(
text=a[0],

b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]:
search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]:

search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]],
n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]],
l=len(b),
c=[for(i=[0:l-1])each search(b[i],n)],
d=[for(i=[0:len(c)-1])10^(l-i-1)],
e=c*d,

f=search(".",a)!=[]&&search("-",a)!=[]?e10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e10^-(l-(search(".",a)[0]-1)):e,
g=search("-",a)!=[]?f*-1:f
)[text,g];

//function to rotate a point around a vector(axis) with angle theta

function q(vector=[1,0,0],point=[0,5,0],theta=0)=

let(t=theta,
v=vector/norm(vector),
p=[cos(t/2),vsin(t/2)],
p1=[p.x,-p.y],
q=[0,len(point)==2?[point.x,point.y,0]:point],
pq=[p.x
q.x-p.yq.y,p.xq.y+p.yq.x+cross(p.y,q.y)],
pqp1=[pq.x
p1.x-pq.yp1.y,pq.xp1.y+pq.y*p1.x+cross(pq.y,p1.y)],
transformation=pqp1.y
)

transformation
;
// function is input to another function q_rot
function qmr1(s,r,pl,n=0)= n==len(s)?pl:
qmr1(s,r,
let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(p=pl)q(v1,p,r1)],n+1);
//function is input to another function q_rot
function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1);

//function to rotate a group of points "pl" around a series of axis with
defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will
rotate the line first around z axis by 20 deg then around x axis by 40
degrees and then around y axis by 80 degrees.
function q_rot(s,pl)=
is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl);

// sequence of rotation defined by r1
r1=["x30","y40","z100"];
vz=[0,0,1];
v1=q_rot(r1,[vz])[0];

v2=cross(vz,v1);
theta=acos(vz*v1/norm(v1));

// equivalent rotation axis and angle of rotation w.r.t vector vz
echo(v2,theta);


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Yes, for 3d geometry, not point lists, the already existing OpenSCAD rotate() module will rotate angle a around an arbitrary axis v. I don't find this to be a particularly useful operation in general, though. Must more useful is rotating one vector onto another. We asked at one point for them to add rotation that maps vector v onto vector w and they said this was not suitable to be native and should be done in user space. Of course, BOSL2 can produce rotation matrices or apply rotations to point lists. On Fri, Mar 24, 2023 at 7:48 PM Sanjeev Prabhakar <sprabhakar2006@gmail.com> wrote: > I mean for 3d models without the points list. > > This can make the rotations easier to write in my opinion and would > request openscad developers to make a module which rotates the object > around an arbitrary axis, rather than only x,y and z > > For the models which I develop with the points list, I have written a > function which does this. > > On Sat, 25 Mar, 2023, 3:01 am Adrian Mariano, <avm4@cornell.edu> wrote: > >> Of course a module can be developed to rotate around an arbitrary axis: >> the native rotate in fact already does this with the v= argument. >> >> >> On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar < >> sprabhakar2006@gmail.com> wrote: >> >>> I would propose if a module can be developed to rotate an object around >>> an axis. >>> >>> e.g. for any sequence of rotations an equivalent axis and angle can be >>> found from the functions written below >>> >>> function cvar(a)= >>> let( >>> text=a[0], >>> >>> b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]: >>> search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]: >>> >>> search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]], >>> n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]], >>> l=len(b), >>> c=[for(i=[0:l-1])each search(b[i],n)], >>> d=[for(i=[0:len(c)-1])10^(l-i-1)], >>> e=c*d, >>> >>> f=search(".",a)!=[]&&search("-",a)!=[]?e*10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e*10^-(l-(search(".",a)[0]-1)):e, >>> g=search("-",a)!=[]?f*-1:f >>> )[text,g]; >>> >>> //function to rotate a point around a vector(axis) with angle theta >>> >>> function q(vector=[1,0,0],point=[0,5,0],theta=0)= >>> >>> let(t=theta, >>> v=vector/norm(vector), >>> p=[cos(t/2),v*sin(t/2)], >>> p1=[p.x,-p.y], >>> q=[0,len(point)==2?[point.x,point.y,0]:point], >>> pq=[p.x*q.x-p.y*q.y,p.x*q.y+p.y*q.x+cross(p.y,q.y)], >>> pqp1=[pq.x*p1.x-pq.y*p1.y,pq.x*p1.y+pq.y*p1.x+cross(pq.y,p1.y)], >>> transformation=pqp1.y >>> ) >>> >>> transformation >>> ; >>> // function is input to another function q_rot >>> function qmr1(s,r,pl,n=0)= n==len(s)?pl: >>> qmr1(s,r, >>> let( >>> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >>> r1=r[n]==undef?0:r[n]) >>> [for(p=pl)q(v1,p,r1)],n+1); >>> //function is input to another function q_rot >>> function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let( >>> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >>> r1=r[n]==undef?0:r[n]) >>> [for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1); >>> >>> //function to rotate a group of points "pl" around a series of axis with >>> defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> will >>> rotate the line first around z axis by 20 deg then around x axis by 40 >>> degrees and then around y axis by 80 degrees. >>> function q_rot(s,pl)= >>> is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl); >>> >>> // sequence of rotation defined by r1 >>> r1=["x30","y40","z100"]; >>> vz=[0,0,1]; >>> v1=q_rot(r1,[vz])[0]; >>> >>> v2=cross(vz,v1); >>> theta=acos(vz*v1/norm(v1)); >>> >>> // equivalent rotation axis and angle of rotation w.r.t vector vz >>> echo(v2,theta); >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Sat, Mar 25, 2023 12:15 AM

On 3/24/2023 4:38 PM, Sanjeev Prabhakar wrote:

You can give any length of sequence in any order e.g.
"x30","z90","y73","z50","x43" etc.

For a function like that, I'd recommend pairs of operation and value - [
"x", 30, "z", 90, "y", 73, "x", 43 ].

That's both a lot easier to process - no parsing strings to extract
numbers - and more easily allows for the values being variables.

On 3/24/2023 4:38 PM, Sanjeev Prabhakar wrote: > You can give any length of sequence in any order e.g. > "x30","z90","y73","z50","x43" etc. For a function like that, I'd recommend pairs of operation and value - [ "x", 30, "z", 90, "y", 73, "x", 43 ]. That's both a lot easier to process - no parsing strings to extract numbers - and more easily allows for the values being variables.
SP
Sanjeev Prabhakar
Sat, Mar 25, 2023 12:21 AM

Oh, I didn't know this
Will check once I have access to my computer
Thanks

On Sat, 25 Mar 2023, 05:32 Adrian Mariano, avm4@cornell.edu wrote:

Yes, for 3d geometry, not point lists, the already existing OpenSCAD
rotate() module will rotate angle a around an arbitrary axis v.  I don't
find this to be a particularly useful operation in general, though.  Must
more useful is rotating one vector onto another. We asked at one point for
them to add rotation that maps vector v onto vector w and they said this
was not suitable to be native and should be done in user space.  Of course,
BOSL2 can produce rotation matrices or apply rotations to point lists.

On Fri, Mar 24, 2023 at 7:48 PM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I mean for 3d models without the points list.

This can make the rotations easier to write in my opinion and would
request openscad developers to make a module which rotates the object
around an arbitrary axis, rather than only x,y and z

For the models which I develop with the points list, I have written a
function which does this.

On Sat, 25 Mar, 2023, 3:01 am Adrian Mariano, avm4@cornell.edu wrote:

Of course a module can be developed to rotate around an arbitrary axis:
the native rotate in fact already does this with the v= argument.

On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar <
sprabhakar2006@gmail.com> wrote:

I would propose if a module can be developed to rotate an object around
an axis.

e.g. for any sequence of rotations an equivalent axis and angle can be
found from the functions written below

function cvar(a)=
let(
text=a[0],

b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]:
search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]:

search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]],
n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]],
l=len(b),
c=[for(i=[0:l-1])each search(b[i],n)],
d=[for(i=[0:len(c)-1])10^(l-i-1)],
e=c*d,

f=search(".",a)!=[]&&search("-",a)!=[]?e10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e10^-(l-(search(".",a)[0]-1)):e,
g=search("-",a)!=[]?f*-1:f
)[text,g];

//function to rotate a point around a vector(axis) with angle theta

function q(vector=[1,0,0],point=[0,5,0],theta=0)=

let(t=theta,
v=vector/norm(vector),
p=[cos(t/2),vsin(t/2)],
p1=[p.x,-p.y],
q=[0,len(point)==2?[point.x,point.y,0]:point],
pq=[p.x
q.x-p.yq.y,p.xq.y+p.yq.x+cross(p.y,q.y)],
pqp1=[pq.x
p1.x-pq.yp1.y,pq.xp1.y+pq.y*p1.x+cross(pq.y,p1.y)],
transformation=pqp1.y
)

transformation
;
// function is input to another function q_rot
function qmr1(s,r,pl,n=0)= n==len(s)?pl:
qmr1(s,r,
let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(p=pl)q(v1,p,r1)],n+1);
//function is input to another function q_rot
function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let(
v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1],
r1=r[n]==undef?0:r[n])
[for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1);

//function to rotate a group of points "pl" around a series of axis
with defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=>
will rotate the line first around z axis by 20 deg then around x axis by 40
degrees and then around y axis by 80 degrees.
function q_rot(s,pl)=
is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl);

// sequence of rotation defined by r1
r1=["x30","y40","z100"];
vz=[0,0,1];
v1=q_rot(r1,[vz])[0];

v2=cross(vz,v1);
theta=acos(vz*v1/norm(v1));

// equivalent rotation axis and angle of rotation w.r.t vector vz
echo(v2,theta);


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Oh, I didn't know this Will check once I have access to my computer Thanks On Sat, 25 Mar 2023, 05:32 Adrian Mariano, <avm4@cornell.edu> wrote: > Yes, for 3d geometry, not point lists, the already existing OpenSCAD > rotate() module will rotate angle a around an arbitrary axis v. I don't > find this to be a particularly useful operation in general, though. Must > more useful is rotating one vector onto another. We asked at one point for > them to add rotation that maps vector v onto vector w and they said this > was not suitable to be native and should be done in user space. Of course, > BOSL2 can produce rotation matrices or apply rotations to point lists. > > On Fri, Mar 24, 2023 at 7:48 PM Sanjeev Prabhakar < > sprabhakar2006@gmail.com> wrote: > >> I mean for 3d models without the points list. >> >> This can make the rotations easier to write in my opinion and would >> request openscad developers to make a module which rotates the object >> around an arbitrary axis, rather than only x,y and z >> >> For the models which I develop with the points list, I have written a >> function which does this. >> >> On Sat, 25 Mar, 2023, 3:01 am Adrian Mariano, <avm4@cornell.edu> wrote: >> >>> Of course a module can be developed to rotate around an arbitrary axis: >>> the native rotate in fact already does this with the v= argument. >>> >>> >>> On Wed, Mar 22, 2023 at 10:45 PM Sanjeev Prabhakar < >>> sprabhakar2006@gmail.com> wrote: >>> >>>> I would propose if a module can be developed to rotate an object around >>>> an axis. >>>> >>>> e.g. for any sequence of rotations an equivalent axis and angle can be >>>> found from the functions written below >>>> >>>> function cvar(a)= >>>> let( >>>> text=a[0], >>>> >>>> b=search("-",a)!=[]&&search(".",a)!=[]?[for(i=[2:len(a)-1])if(a[i]!=".")a[i]]: >>>> search("-",a)!=[]&&search(".",a)==[]?[for(i=[2:len(a)-1])a[i]]: >>>> >>>> search("-",a)==[]&&search(".",a)!=[]?[for(i=[1:len(a)-1])if(a[i]!=".")a[i]]:[for(i=[1:len(a)-1])a[i]], >>>> n=[["0"],["1"],["2"],["3"],["4"],["5"],["6"],["7"],["8"],["9"]], >>>> l=len(b), >>>> c=[for(i=[0:l-1])each search(b[i],n)], >>>> d=[for(i=[0:len(c)-1])10^(l-i-1)], >>>> e=c*d, >>>> >>>> f=search(".",a)!=[]&&search("-",a)!=[]?e*10^-(l-(search(".",a)[0]-2)):search(".",a)!=[]&&search("-",a)==[]?e*10^-(l-(search(".",a)[0]-1)):e, >>>> g=search("-",a)!=[]?f*-1:f >>>> )[text,g]; >>>> >>>> //function to rotate a point around a vector(axis) with angle theta >>>> >>>> function q(vector=[1,0,0],point=[0,5,0],theta=0)= >>>> >>>> let(t=theta, >>>> v=vector/norm(vector), >>>> p=[cos(t/2),v*sin(t/2)], >>>> p1=[p.x,-p.y], >>>> q=[0,len(point)==2?[point.x,point.y,0]:point], >>>> pq=[p.x*q.x-p.y*q.y,p.x*q.y+p.y*q.x+cross(p.y,q.y)], >>>> pqp1=[pq.x*p1.x-pq.y*p1.y,pq.x*p1.y+pq.y*p1.x+cross(pq.y,p1.y)], >>>> transformation=pqp1.y >>>> ) >>>> >>>> transformation >>>> ; >>>> // function is input to another function q_rot >>>> function qmr1(s,r,pl,n=0)= n==len(s)?pl: >>>> qmr1(s,r, >>>> let( >>>> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >>>> r1=r[n]==undef?0:r[n]) >>>> [for(p=pl)q(v1,p,r1)],n+1); >>>> //function is input to another function q_rot >>>> function qmr2(s,r,pl,n=0)= n==len(s)?pl:qmr2(s,r,let( >>>> v1=s[n]=="x"?[1,0,0]:s[n]=="y"?[0,1,0]:[0,0,1], >>>> r1=r[n]==undef?0:r[n]) >>>> [for(i=[0:len(pl)-1])[for(p=pl[i])q(v1,p,r1)]],n+1); >>>> >>>> //function to rotate a group of points "pl" around a series of axis >>>> with defined angles e.g q_rot(s=["z20","x40","y80"],pl=[[2,0],[10,2]])=> >>>> will rotate the line first around z axis by 20 deg then around x axis by 40 >>>> degrees and then around y axis by 80 degrees. >>>> function q_rot(s,pl)= >>>> is_num(pl[0][0])?qmr1([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl):qmr2([for(p=s)cvar(p)[0]],[for(p=s)cvar(p)[1]],pl); >>>> >>>> // sequence of rotation defined by r1 >>>> r1=["x30","y40","z100"]; >>>> vz=[0,0,1]; >>>> v1=q_rot(r1,[vz])[0]; >>>> >>>> v2=cross(vz,v1); >>>> theta=acos(vz*v1/norm(v1)); >>>> >>>> // equivalent rotation axis and angle of rotation w.r.t vector vz >>>> echo(v2,theta); >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
SP
Sanjeev Prabhakar
Sat, Mar 25, 2023 12:23 AM

You are right
It is easier but you need to write a little extra

On Sat, 25 Mar 2023, 05:46 Jordan Brown, openscad@jordan.maileater.net
wrote:

On 3/24/2023 4:38 PM, Sanjeev Prabhakar wrote:

You can give any length of sequence in any order e.g.
"x30","z90","y73","z50","x43" etc.

For a function like that, I'd recommend pairs of operation and value - [
"x", 30, "z", 90, "y", 73, "x", 43 ].

That's both a lot easier to process - no parsing strings to extract
numbers - and more easily allows for the values being variables.

You are right It is easier but you need to write a little extra On Sat, 25 Mar 2023, 05:46 Jordan Brown, <openscad@jordan.maileater.net> wrote: > On 3/24/2023 4:38 PM, Sanjeev Prabhakar wrote: > > You can give any length of sequence in any order e.g. > "x30","z90","y73","z50","x43" etc. > > > For a function like that, I'd recommend pairs of operation and value - [ > "x", 30, "z", 90, "y", 73, "x", 43 ]. > > That's both a lot easier to process - no parsing strings to extract > numbers - and more easily allows for the values being variables. > >
SP
Sanjeev Prabhakar
Sat, Mar 25, 2023 1:46 AM

//rotated cylinder
color("magenta")
rotate([0,45,0])
rotate([70,0,0])
rotate([0,10,0])
rotate([30,40,100])
cylinder(r=1,h=50,$fn=30);

//reverse rotation based on equivalent axis of rotation and angle
theta=78.09373872704292;
v=[0.33215577139188024, 0.9203587619795575, -0.0];
color("green")
rotate(-theta,v)
rotate(theta,v)
cylinder(r=1,h=50,$fn=30);

On Sat, 25 Mar 2023, 05:53 Sanjeev Prabhakar, sprabhakar2006@gmail.com
wrote:

You are right
It is easier but you need to write a little extra

On Sat, 25 Mar 2023, 05:46 Jordan Brown, openscad@jordan.maileater.net
wrote:

On 3/24/2023 4:38 PM, Sanjeev Prabhakar wrote:

You can give any length of sequence in any order e.g.
"x30","z90","y73","z50","x43" etc.

For a function like that, I'd recommend pairs of operation and value - [
"x", 30, "z", 90, "y", 73, "x", 43 ].

That's both a lot easier to process - no parsing strings to extract
numbers - and more easily allows for the values being variables.

//rotated cylinder color("magenta") rotate([0,45,0]) rotate([70,0,0]) rotate([0,10,0]) rotate([30,40,100]) cylinder(r=1,h=50,$fn=30); //reverse rotation based on equivalent axis of rotation and angle theta=78.09373872704292; v=[0.33215577139188024, 0.9203587619795575, -0.0]; color("green") rotate(-theta,v) rotate(theta,v) cylinder(r=1,h=50,$fn=30); On Sat, 25 Mar 2023, 05:53 Sanjeev Prabhakar, <sprabhakar2006@gmail.com> wrote: > You are right > It is easier but you need to write a little extra > > > On Sat, 25 Mar 2023, 05:46 Jordan Brown, <openscad@jordan.maileater.net> > wrote: > >> On 3/24/2023 4:38 PM, Sanjeev Prabhakar wrote: >> >> You can give any length of sequence in any order e.g. >> "x30","z90","y73","z50","x43" etc. >> >> >> For a function like that, I'd recommend pairs of operation and value - [ >> "x", 30, "z", 90, "y", 73, "x", 43 ]. >> >> That's both a lot easier to process - no parsing strings to extract >> numbers - and more easily allows for the values being variables. >> >>