|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
is it possible to use a matrix to force an object at point <x1,y1,z1> to
"track" a point <x2,y2,z2> without having to use complex trig functions.
ie: imagine a gun following a moving target (whose position is given by
a spline), how would i point the barrel? I tried the reorient macro, but
I must admit, I don't understand the matrix command very well.
thanks
paul
--
-------------------------------------------#
Paul Daniel Jones
120 Chandlee Laboratory
Penn State University
814-865-2090
pdj### [at] psuedu
http://research.chem.psu.edu/glassgrp/paul
--------------------------------------------#
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Paul Daniel Jones wrote:
>
> is it possible to use a matrix to force an object at point <x1,y1,z1> to
> "track" a point <x2,y2,z2> without having to use complex trig functions.
> ie: imagine a gun following a moving target (whose position is given by
> a spline), how would i point the barrel? I tried the reorient macro, but
> I must admit, I don't understand the matrix command very well.
>
The Reorient macro should do exactly what you need, and there should be no need
to understand the inner workings of the matrix command. Doesn't it work for you,
and if so, why?
Or perhaps this will help: these macros work as a vector equivalet of Reorient
(you need to call v_reorient, the second is used internally to catch ambiguous
cases)
//give 0 if not parallel, 1 if parallel, -1 if anti-parallel
#macro v_parallel(V1i,V2i)
#local V1=vnormalize(V1i+<0,0,0>);
#local V2=vnormalize(V2i+<0,0,0>);
#local Vt=(vlength(V1+V2)-1);
#if(Vt=1|Vt=-1) Vt
#else 0
#end
#end
//Vector equivalent of John VanSickle's Reorient macro
//V - vector to be reoriented
//RefA - original orientation
//RefB - target orientation
#macro v_reorient(V,RefA,RefB)
(#if((v_parallel(RefA,RefB))=0)
vaxis_rotate(
V,
vcross(vnormalize(RefA),vnormalize(RefB)),
degrees(atan2(vlength(vcross(vnormalize(RefA),vnormalize(RefB))),
vdot(vnormalize(RefA),vnormalize(RefB)))))
#else
((v_parallel(RefA,RefB))*V)
#end)
#end
--
Margus Ramst
Personal e-mail: mar### [at] peakeduee
TAG (Team Assistance Group) e-mail: mar### [at] tagpovrayorg
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Margus Ramst wrote:
> The Reorient macro should do exactly what you need, and there should be no need
> to understand the inner workings of the matrix command. Doesn't it work for you,
> and if so, why?
John's macro should do what you want. The only problem I think would be the axial
rotation changing, but if your gun stays pointing on the x-z plane with y up it
shouldn't matter I think. I've written one aimilar to keep axial rotation the same
(perpendicular vector intersecting y axis still intersects y axis). It's a lot
messier than John's though.
Scales according to vector length ratios, comment out scale if u don't want it.
#macro reposition(vec1,vec2)
#if (vlength(vec1)=0)
#render "Warning: reposition initial vector length is zero.\n"
#end
#if (vec1.x=0 & vec1.z=0)
#local RotY=0;
#else
#local RotY=atan2(vec1.x,vec1.z)*180/pi;
#end
#local RotX=asin((vec1.y)/vlength(vec1))*180/pi;
rotate -RotY*y
rotate RotX*x
scale vlength(vec2)/vlength(vec1)
#if (vlength(vec2)=0)
#render "Warning: reposition final vector length is zero.\n"
#end
#if (vec2.x=0 & vec2.z=0)
#local RotY=0;
#else
#local RotY=atan2(vec2.x,vec2.z)*180/pi;
#end
#local RotX=asin((vec2.y)/vlength(vec2))*180/pi;
rotate <-RotX,RotY,0>
#end
--
David Fontaine <dav### [at] faricynet> ICQ 55354965
Please visit my website: http://davidf.faricy.net/
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
the reorient actually does work, I apparently can write POV code properly
:-) (getting variables confused etc....)
Thanks for the help. I still don't quite understand how the reorient macro
works, but for now at least it does.... ;-)
-p
Paul Daniel Jones wrote:
> is it possible to use a matrix to force an object at point <x1,y1,z1> to
> "track" a point <x2,y2,z2> without having to use complex trig functions.
> ie: imagine a gun following a moving target (whose position is given by
> a spline), how would i point the barrel? I tried the reorient macro, but
> I must admit, I don't understand the matrix command very well.
>
> thanks
>
> paul
>
> --
> -------------------------------------------#
> Paul Daniel Jones
> 120 Chandlee Laboratory
> Penn State University
> 814-865-2090
> pdj### [at] psuedu
>
> http://research.chem.psu.edu/glassgrp/paul
> --------------------------------------------#
--
-------------------------------------------#
Paul Daniel Jones
120 Chandlee Laboratory
Penn State University
814-865-2090
pdj### [at] psuedu
http://research.chem.psu.edu/glassgrp/paul
--------------------------------------------#
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
J Charter wrote:
> Yikes! This is great! So I put together concepts from Margus and David and come up
> with the following. And it seems to solve a problem I've been chasing for some
> time,...how to orient an arbitrary set of points from a shape ( the processes of a
> vertabrae ) along a spline ( forming the axial structure of an animal's turning neck
)
> and know what the new point locations are ( in order to attach muscles at their
> insertion points ). Mild testing seems to indicate this works! Can anyone who
knows
> vet this? Is this really a solution? Is there a cleaner way?
Oh, you wanted to apply it to an input vector? Well I wrote something for that too!
:))
Looks right. The last two lines that modify pt can be comnbined: vrotate ( pt,
<-RotX,RotY,0> )
Basically the more control and more errorproofing you want the more sloppy code you'll
have to write. Basically my macro finds the rotation values (spherical vector) of the
vectors and undoes the first one and applies the second.
--
David Fontaine <dav### [at] faricynet> ICQ 55354965
Please visit my website: http://davidf.faricy.net/
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
David Fontaine wrote:
>
> John's macro should do what you want. The only problem I think would be the axial
> rotation changing, but if your gun stays pointing on the x-z plane with y up it
> shouldn't matter I think. I've written one aimilar to keep axial rotation the same
> (perpendicular vector intersecting y axis still intersects y axis). It's a lot
> messier than John's though.
The Reorient vector tilts as if the joint were a ball-and-socket joint. If you
want to tilt in the way the POV camera tilts when the look_at parameter is
specified, here is some tighter, neater, and more flexible code.
Specifically, it allows you to begin from any direction; this is useful because
sometimes I model with x=forward, and sometimes with z=forward. The "up"
direction of your scene can also be specified, so this can be used by people
who use up=y or up=z (or up=<3,4,12>/13, if you want to be strange).
I should probably add this to the Thoroughly Useful Macros file...
Hope this helps,
John
// macro code follows
#macro PointAlong(OldDirection,NewDirection,Up)
// OldDirection is the direction in which the object is currently pointed
// NewDirection is the direction in which you want it to point
// Up is the vector that is considered to be up
#if(vlength(OldDirection)=0)
#error "Zero-length vector supplied as old direction.\n"
#end
#if(vlength(NewDirection)=0)
#error "Zero-length vector supplied as new direction.\n"
#end
#if(vlength(Up)=0)
#error "Zero-length vector supplied as up vector.\n"
#end
#local vOD=vnormalize(OldDirection);
#local vOR=vcross(Up,OldDirection);
#if(vlength(vOR)=0)
#debug "Old direction vector is parallel to up vector.\n"
#local vOR=vcross(vOD,<vOD.z,vOD.x,-vOD.y>);
#end
#local vOR=vnormalize(vOR);
#local vOU=vnormalize(vcross(OldDirection,vOR));
#local vND=vnormalize(NewDirection);
#local vNR=vcross(Up,NewDirection);
#if(vlength(vNR)=0)
#debug "New direction vector is parallel to up vector.\n"
#local vNR=vcross(vND,<vND.z,vND.x,-vND.y>);
#end
#local vNR=vnormalize(vNR);
#local vNU=vnormalize(vcross(NewDirection,vOR));
matrix <vOR.x,vOU.x,vOD.x, vOR.y,vOU.y,vOD.y, vOR.z,vOU.z,vOD.z, 0,0,0>
matrix <vOR.x,vOR.y,vOR.z, vOU.x,vOU.y,vOU.z, vOD.x,vOD.y,vOD.z, 0,0,0>
#end
// end of macro code
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Does this assume that your object is not located somewhere else other
than the origin? (<0,0,0>) What if I have a gun turret that is located
at <5,0,5> (ie: it rotates around the line defined by <5,y,5>), would
this macro take that in to account? or would another parameter
_location_ be required?
-paul
John VanSickle wrote:
>
> David Fontaine wrote:
> >
> > John's macro should do what you want. The only problem I think would be the axial
> > rotation changing, but if your gun stays pointing on the x-z plane with y up it
> > shouldn't matter I think. I've written one aimilar to keep axial rotation the same
> > (perpendicular vector intersecting y axis still intersects y axis). It's a lot
> > messier than John's though.
>
> The Reorient vector tilts as if the joint were a ball-and-socket joint. If you
> want to tilt in the way the POV camera tilts when the look_at parameter is
> specified, here is some tighter, neater, and more flexible code.
>
> Specifically, it allows you to begin from any direction; this is useful because
> sometimes I model with x=forward, and sometimes with z=forward. The "up"
> direction of your scene can also be specified, so this can be used by people
> who use up=y or up=z (or up=<3,4,12>/13, if you want to be strange).
>
> I should probably add this to the Thoroughly Useful Macros file...
>
> Hope this helps,
> John
>
> // macro code follows
>
> #macro PointAlong(OldDirection,NewDirection,Up)
> // OldDirection is the direction in which the object is currently pointed
> // NewDirection is the direction in which you want it to point
> // Up is the vector that is considered to be up
>
> #if(vlength(OldDirection)=0)
> #error "Zero-length vector supplied as old direction.\n"
> #end
> #if(vlength(NewDirection)=0)
> #error "Zero-length vector supplied as new direction.\n"
> #end
> #if(vlength(Up)=0)
> #error "Zero-length vector supplied as up vector.\n"
> #end
>
> #local vOD=vnormalize(OldDirection);
> #local vOR=vcross(Up,OldDirection);
> #if(vlength(vOR)=0)
> #debug "Old direction vector is parallel to up vector.\n"
> #local vOR=vcross(vOD,<vOD.z,vOD.x,-vOD.y>);
> #end
> #local vOR=vnormalize(vOR);
> #local vOU=vnormalize(vcross(OldDirection,vOR));
>
> #local vND=vnormalize(NewDirection);
> #local vNR=vcross(Up,NewDirection);
> #if(vlength(vNR)=0)
> #debug "New direction vector is parallel to up vector.\n"
> #local vNR=vcross(vND,<vND.z,vND.x,-vND.y>);
> #end
> #local vNR=vnormalize(vNR);
> #local vNU=vnormalize(vcross(NewDirection,vOR));
>
> matrix <vOR.x,vOU.x,vOD.x, vOR.y,vOU.y,vOD.y, vOR.z,vOU.z,vOD.z, 0,0,0>
> matrix <vOR.x,vOR.y,vOR.z, vOU.x,vOU.y,vOU.z, vOD.x,vOD.y,vOD.z, 0,0,0>
>
> #end
> // end of macro code
--
--------------------------------------------------}
Paul Daniel Jones
The Pennslyvania State University
pdj### [at] psuedu
http://research.chem.psu.edu/glassgrp/paul
C The way is near, but men
// \ seek it afar. It is in the
N N easy things, but men seek it
| || in the difficult things.
C C -Menicius
\\ /
C
--------------------------------------------------}
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Margus Ramst wrote:
> ... 8< Snip ...
> #macro v_parallel(V1i,V2i)
> #local V1=vnormalize(V1i+<0,0,0>);
> #local V2=vnormalize(V2i+<0,0,0>);
> #local Vt=(vlength(V1+V2)-1);
> #if(Vt=1|Vt=-1) Vt
> #else 0
> #end
> #end
> ...
> #macro v_reorient(V,RefA,RefB)
> (#if((v_parallel(RefA,RefB))=0)
> vaxis_rotate(
> V,
> vcross(vnormalize(RefA),vnormalize(RefB)),
> degrees(atan2(vlength(vcross(vnormalize(RefA),vnormalize(RefB))),
> vdot(vnormalize(RefA),vnormalize(RefB)))))
> #else
> ((v_parallel(RefA,RefB))*V)
> #end)
> #end
> ...
I like the way you're finding if the two vectors are parallel in the first
macro and how the result is used to make a decision, and later to scale
the "incoming" vector if the other two are parallel.
BUT: From what I can see you're calculating the same things several times.
Wouldn't it be better to store calculated values in variables and use them
up again when needed ?
(Or is there too much overhead for POV to make these new variables ?)
Below are my suggestions of how the same thing could be done with only
one macro. (At least they seem to work the same way :)
Regards,
Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html
// First using your parallel-method:
#macro vReorient(vI,vRefA,vRefB)
#local vA=vnormalize(vRefA+<0,0,0>);
#local vB=vnormalize(vRefB+<0,0,0>);
#local vC=vcross(vA,vB);
#local vD=vdot(vA,vB);
#local SS=vlength(vA+vB)-1;
(SS=-1|SS=1?SS*vI:vaxis_rotate(vI,vC,degrees(atan2(vlength(vC),vD))))
#end
// Then with information about parallelism from vdot:
#macro vReorient2(vI,vRefA,vRefB)
#local vA=vnormalize(vRefA+<0,0,0>);
#local vB=vnormalize(vRefB+<0,0,0>);
#local vC=vcross(vA,vB);
#local vD=vdot(vA,vB);
(abs(vD)=1?vD*vI:vaxis_rotate(vI,vC,degrees(atan2(vlength(vC),vD))))
#end
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
J Charter wrote:
> Yikes! This is great! So I put together concepts from Margus and David and come up
> with the following. And it seems to solve a problem I've been chasing for some
> time,...how to orient an arbitrary set of points from a shape ( the processes of a
> vertabrae ) along a spline ( forming the axial structure of an animal's turning neck
)
> and know what the new point locations are ( in order to attach muscles at their
> insertion points ). Mild testing seems to indicate this works! Can anyone who
knows
> vet this? Is this really a solution? Is there a cleaner way?
>
> #macro repoint(pt,vec1,vec2)
>
> #if (vlength(vec1)=0)
> #render "Warning: reposition initial vector length is zero.\n"
> #end
> #if (vec1.x=0 & vec1.z=0)
> #local RotY=0;
> #else
> #local RotY=atan2(vec1.x,vec1.z)*180/pi;
> #end
> #local RotX=asin((vec1.y)/vlength(vec1))*180/pi;
>
> #local pt = vrotate ( pt, <0,-RotY,0> )
> #local pt = vrotate ( pt, <RotX,0,0> )
>
> ... 8< Snip ...
May I suggest using degrees() instead of
multiplying with 180/pi ?
E.g.: RotY=degrees(atan2(vec1.x,vec1.z));
You can also write asin(vnormalize(vec1).y)
instead of asin((vec1.y)/vlength(vec1))
Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Tor Olav Kristensen wrote:
> > #macro repoint(pt,vec1,vec2)
> >
> > #if (vlength(vec1)=0)
> > #render "Warning: reposition initial vector length is zero.\n"
> > #end
> > #if (vec1.x=0 & vec1.z=0)
> > #local RotY=0;
> > #else
> > #local RotY=atan2(vec1.x,vec1.z)*180/pi;
> > #end
> > #local RotX=asin((vec1.y)/vlength(vec1))*180/pi;
> >
> > #local pt = vrotate ( pt, <0,-RotY,0> )
> > #local pt = vrotate ( pt, <RotX,0,0> )
> >
> > ... 8< Snip ...
>
> May I suggest using degrees() instead of
> multiplying with 180/pi ?
> E.g.: RotY=degrees(atan2(vec1.x,vec1.z));
>
> You can also write asin(vnormalize(vec1).y)
> instead of asin((vec1.y)/vlength(vec1))
Ah, will do. New version will go up when I update my site.
--
David Fontaine <dav### [at] faricynet> ICQ 55354965
Please visit my website: http://davidf.faricy.net/
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|