|
This tutorial has not yet been done (as of Dec. 19, 2007).
|
What you see below is an eMail that i recently wrote on this topic (with this
tutorial in mind).
Your problem is to connect two points with a Cylinder, right?
I have done a PROTO that can do this and a bit more, but let me first
explain how
this can be done:
First, you build a Cylinder and put it into a Transform:
DEF Trans Transform
{
children Shape
{
geometry Cylinder
{
height 1
radius .2
}
}
} |
Then you write a script that sets the parameters of the Transform.
Let's PosA and PosB be two SFVec3f
describing the positions of the points A and B to
be connected. Then the VrmlScript could look like this:
function Link(Trans, PosA, PosB)
{
Trans.scale= new SFVec3f(1, PosB.subtract(PosA).length(), 1);
Trans.translation= PosA.add(PosB).multiply(.5);
Trans.rotation= new SFRotation(new SFVec3f(0, 1, 0), PosB.subtract(PosA));
}
|
Let me rationalize the calculations:
Scale and translation are quite forward:
The Cylinder has its center at (0, 0, 0). Therefore we need to
specify where the center goes.
This is the point between PosA and PosB.
Mathematically: (PosA + PosB) / 2, and in
VrmlScript: PosA.add(PosB).divide(2).
For the unchanged Cylinder we specified a hight of 1. This will
become the length of
the line we want to show. Therefore we need to calculate the distance
of the two points
and use this as the y of the scale. Mathematically: | PosB
- PosA |, and
in VrmlScript: PosB.subtract(PosA).length().
The x and z of the scale are set to 1 as we
don't want to change the thickness of the line.
(If you want to specify the thickness programmatically, set radius
of the Cylinder node
to 1, and specifiy it for x and z.)
The rotation can be reasoned similar:
The difference of both points, that is PosB - PosA, is a vector
that points from A to B.
The direction of that vector is the direction we want to orient the
cylinder to.
By default, the cylinder points into y direction, i.e. (0, 1, 0).
To get an SFRotation that rotates from one vector to another, we use
the term
new SFRotation(VecA, VecB).
In our case this is new SFRotation(new SFVec3f(0, 1, 0),
PosB.subtract(PosA)).
In order to save some CPU cycles (and a memory allocation), we should
replace the
'new SFVec3f(0, 1, 0)' with a variable that we initialize to
(0, 1, 0).
Two examples TBD: writes something nice here
__.-.__ end of document
|