[vtkusers] positioning a cylinder

Marc Cotran marc at cotran.ca
Sat Mar 31 01:58:13 EDT 2007


Hi Mark,

I have a 'hard' way of doing what you are asking. The easiest way is 
what Amy proposes, but if you definitely want a cylinder that can update 
quickly with changes to the endpoints...

- useablePt1 and 2 are classes (Coord) with 3 variables (x, y, z) for 
coordinates. Although we implemented some convenience methods in Coord, 
you could do it all with vtkMath.

- this->transform corresponds to that of the actor made from the 
cylinderSource

//////////////////////////////

    this->cylinderSource = vtkCylinderSource::New();
    this->cylinderSource->SetCapping(1);
    this->cylinderSource->SetResolution(5);

    // find out halfway point
    Coord halfwayPt(
        (useablePt1.x() + useablePt2.x()) / 2,
        (useablePt1.y() + useablePt2.y()) / 2,
        (useablePt1.z() + useablePt2.z()) / 2);

    double pos[4];
    double res[4];

    pos[0] = halfwayPt.x();
    pos[1] = halfwayPt.y();
    pos[2] = halfwayPt.z();
    pos[3] = 1;

    this->transform.getTransform()->MultiplyPoint(pos, res);

    // we found the center point

    Coord diff(this->pt2 - this->pt1);
    Coord normalized(diff.normalize());

    double norm = diff.norm();

    this->cachedActor->SetScale(this->radius, norm, this->radius);

    // get cross product
    double cross[3];
    double input[3];
    double output[3];

    input[0] = 0;
    input[1] = 1;
    input[2] = 0;

    output[0] = normalized.x();
    output[1] = normalized.y();
    output[2] = normalized.z();

    vtkMath::Cross(input, output, cross);

    // get the angle
    double angle = HelperClass::getAngle(Coord(0,1,0), Coord(), normalized);

    // start with no rotation so they don't accumulate
    this->cachedActor->SetOrientation(0,0,0);

    this->cachedActor->RotateWXYZ(angle, cross[0], cross[1], cross[2]);

    this->cachedActor->SetPosition(
        res[0] / res[3],
        res[1] / res[3],
        res[2] / res[3]);

//////////////////////////////

It is quite possible that the code can be optimized (or at least made 
shorter). The only advantage to this method is that you don't have to 
remap the actor when you change one or both of the endpoints. If you 
don't care about updates, I strongly recommend the lineSource/TubeFilter 
method (it's much simpler!!!)

Marc


Mark Wyszomierski wrote:
> Hi,
>
> I have two points in VTK space, is there an easy way to construct a
> cylinder so that its two endpoints touch the two points? Something
> like:
>
> cylinder->SetEndpoint1(x,y,z);
> cylinder->SetEndpoint2(x,y,z);
>
> Thanks,
> Mark
> _______________________________________________
> This is the private VTK discussion list. Please keep messages 
> on-topic. Check the FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers



More information about the vtkusers mailing list