Home

hersto:  Connecting Two Points with a Cylinder Node

 

Rant to the author:

    

Check for a response

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