POV-Ray : Newsgroups : povray.general : Feature request - spliney cylinders - or howto model pipes : Re: Feature request - spliney cylinders - or howto model pipes Server Time
16 Nov 2024 07:13:42 EST (-0500)
  Re: Feature request - spliney cylinders - or howto model pipes  
From: Gilles Tran
Date: 23 Sep 1998 13:19:32
Message: <36091FDF.1869F5AC@inapg.inra.fr>
Hi
Here a little bit of povray 3.1 code that could do the trick. Actually I
made it to model a fantasy tree trunk but it could be used (and largely
simplified and improved) for a lot of other purposes, including making
pipes. It takes a shape defined in the x-z plane and extrude it according to
a path defined by three macros (fx(j), fy(j),fz(j), j=0 to 1). You obtain a
triangle mesh (non-smoothed). Actually, it's more than extrusion because the
shape itself is modified along the path (I wanted the shape to be corrugated
and to be larger at the base) so macros are used  too to define the shape
according the current position in the path.

You can change the macros and obtain a different mesh. For a pipe, this
could be overkill, but since the resulting object is a mesh many copies of
it can be used in a scene without eating too much memory (and they render
fast). Use small step sizes for trial and large for final render (parsing
may be long).

This code could be enhanced by having a spline for the path and another
spline for the shape (volunteers ???). And triangle smoothing...

The final rendering is here http://www.inapg.inra.fr/dsa/essai/foret6.jpg

I hope this helps.

Gilles Tran
The Book of Beginnings - Povray Gallery
 http://www.ina.fr/Artichaud/Tran/gtran.en.html

===============================
#macro fx(j) // macro that defines the x path
(-10*j*j*j*j -22*j*j*j +21*j*j)/2
#end

#macro fy(j) // macro that defines the y path
j*40
#end

#macro fz(j) // macro that defines the z path
(-10*j*j*j*j -22*j*j*j +21*j*j)/2
#end

#macro fray(j) //macro that changes the radius (large at the base, near 3 at
the end)
exp(-16*j +3.7) + 2.7
#end

#macro fxSeg(j,r) //macro that defines the shape on the x axis
r*(sin(2*pi*j)*(1+(cos(2*pi*j*15)/30)))
#end

#macro fzSeg(j,r) //macro that defines the shape on the z axis
r*(cos(2*pi*j)*(1+(sin(2*pi*j*15)/30)))
#end

#declare iStep=0.01; // step size for the path hi-res
#declare iSegStep=0.002; // step size for the shape hi-res

//#declare iStep=0.03; // step size for the path low-res
//#declare iSegStep=0.03; // step size for the path low-res


#declare Arbre=mesh{
#declare iPath=0;
#while (iPath<1) // loop on path
#declare iPath2=iPath+iStep;
#declare iPath3=iPath2+iStep;

#declare r1=fray(iPath);
#declare r2=fray(iPath2);

#declare xP1=fx(iPath); // present point on the path
#declare yP1=fy(iPath);
#declare zP1=fz(iPath);

#declare xP2=fx(iPath2); // next point on the path
#declare yP2=fy(iPath2);
#declare zP2=fz(iPath2);

#declare xP3=fx(iPath3); // next next point on the path
#declare yP3=fy(iPath3);
#declare zP3=fz(iPath3);

#declare P1=<xP1,yP1,zP1>;
#declare P2=<xP2,yP2,zP2>;
#declare P3=<xP3,yP3,zP3>;

// vector calculation to rotate the shape along the P2-P1 vector (thanks
John Van Sickle !)
#declare yV1=vnormalize(P2-P1);
#declare xV1=vnormalize(vcross(yV1,z));
#declare zV1=vcross(xV1,yV1);

// vector calculation to rotate the shape along the P3-P2 vector
#declare yV2=vnormalize(P3-P2);
#declare xV2=vnormalize(vcross(yV2,z));
#declare zV2=vcross(xV2,yV2);

// shape definition
#declare iSeg=0;
#while (iSeg<1)
#declare iSeg2=iSeg+iSegStep;
#declare x1=fxSeg(iSeg,r1);
#declare y1=0;
#declare z1=fzSeg(iSeg,r1);

#declare x1s=fxSeg(iSeg2,r1);
#declare y1s=0;
#declare z1s=fzSeg(iSeg2,r1);

#declare x2=fxSeg(iSeg,r2);
#declare y2=0;
#declare z2=fzSeg(iSeg,r2);

#declare x2s=fxSeg(iSeg2,r2);
#declare y2s=0;
#declare z2s=fzSeg(iSeg2,r2);

// rotates the 4 points that will make the 2 triangles
#declare posV1=<x1*xV1.x + y1*yV1.x + z1*zV1.x + P1.x, x1*xV1.y + y1*yV1.y +
z1*zV1.y + P1.y, x1*xV1.z + y1*yV1.z + z1*zV1.z + P1.z>;
#declare posV2=<x2*xV2.x + y2*yV2.x + z2*zV2.x + P2.x, x2*xV2.y + y2*yV2.y +
z2*zV2.y + P2.y, x2*xV2.z + y2*yV2.z + z2*zV2.z + P2.z>;
#declare posV1s=<x1s*xV1.x + y1s*yV1.x + z1s*zV1.x + P1.x,x1s*xV1.y +
y1s*yV1.y + z1s*zV1.y + P1.y, x1s*xV1.z + y1s*yV1.z + z1s*zV1.z + P1.z>;
#declare posV2s=<x2s*xV2.x + y2s*yV2.x + z2s*zV2.x + P2.x, x2s*xV2.y +
y2s*yV2.y + z2s*zV2.y + P2.y, x2s*xV2.z + y2s*yV2.z + z2s*zV2.z + P2.z>;

triangle{posV1,posV2,posV1s}
triangle{posV1s,posV2,posV2s}

#declare iSeg= iSeg + iSegStep; // next point on the shape
#end

#declare iPath=iPath2; // next point on the path
#end
}


David Greaves wrote:

> Hi
>
> This started with "How can I model a bendy pipe?"
>
> I got sPatch, created a line with 10 points, lathed it (6 sides) and
> then moved/rotated the hexagonal groups of points. The problem is that
> this doesn't retain the pipe walls equidistant to the pipe's axis :(
>
> I kinda fixed this by using three groups of hexagons around a bend so
> the 'straight' bits were cylindrical but thats quite fiddly and not
> accurate.
>
> Then, some reading later I thought:
> Wouldn't it be nice to have a spline that had thickness?
> Maybe a blob spline? (but that would be too thick at the bends)
> Maybe have a 'map' function to determine radius wrt distance along the
> spline (assuming you can calculate the distance travelled along a spline
> - my maths is not that good)
> A function of '1' would then produce a bent cylinder - more interesting
> functions would produce eg, a string of pearls....
>
> Any other ideas for bendy pipes?
>
> David


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.