POV-Ray : Newsgroups : povray.advanced-users : Curve calculation Server Time
2 Nov 2024 17:20:06 EDT (-0400)
  Curve calculation (Message 1 to 10 of 11)  
Goto Latest 10 Messages Next 1 Messages >>>
From: Lewis
Subject: Curve calculation
Date: 23 May 1999 09:54:34
Message: <3747FA77.D1F9248B@netvision.net.il>
I'm starting to work on a nice little macro project (you'll see when
it's done). I need to be able to calculate a path using only several
points on it. For example, I get the coordinates of points A, B and C. I
want to calculate a position on a path that goes through A, B and C,
that is SMOOTH. That is, the path bends smoothly from A to C, going
through B, without sudden turns. I should be able to specify what level
of "bendness" I want, that is how smooth the path will be. It isn't as
easy as I thought in the beggining.

This can be very useful for the macro I'm going to write (it's just a
part), and will be totally cool if possible.

Any ideas?


Post a reply to this message

From: Ph Gibone
Subject: Re: Curve calculation
Date: 23 May 1999 10:43:45
Message: <37480611.0@news.povray.org>
Hi Lewis

Give a look to B-spline, Beziers, TorePatch etc.
It is very easy to find a curve going from A to C, smoothly through B, the
point is there are to many such curves so you have to give more informations
about the curve you want (tangent at the starting point degree of the
smoothness (continuous function (not smooth), function with a continuous
derivative (usually smooth enough) or even more..)

If you have Moray you can try the trans and rotat primitives and play with
the spline type!

HTH
Philippe


>I'm starting to work on a nice little macro project (you'll see when
>it's done). I need to be able to calculate a path using only several
>points on it. For example, I get the coordinates of points A, B and C. I
>want to calculate a position on a path that goes through A, B and C,
>that is SMOOTH. That is, the path bends smoothly from A to C, going
>through B, without sudden turns. I should be able to specify what level
>of "bendness" I want, that is how smooth the path will be. It isn't as
>easy as I thought in the beggining.
>
>This can be very useful for the macro I'm going to write (it's just a
>part), and will be totally cool if possible.
>
>Any ideas?


Post a reply to this message

From: Lewis
Subject: Re: Curve calculation
Date: 23 May 1999 13:46:53
Message: <374830EA.DB46C62E@netvision.net.il>
This doesn't help me much I need to know how to actually do it. The path
itself is what I need not an surface following it. Thanks anyway.


Post a reply to this message

From: Jerry Anning
Subject: Re: Curve calculation
Date: 23 May 1999 14:13:06
Message: <37483454.2444563@news.povray.org>
On Sun, 23 May 1999 15:54:15 +0300, Lewis <nle### [at] netvisionnetil>
wrote:

>I'm starting to work on a nice little macro project (you'll see when
>it's done). I need to be able to calculate a path using only several
>points on it. For example, I get the coordinates of points A, B and C. I
>want to calculate a position on a path that goes through A, B and C,
>that is SMOOTH. That is, the path bends smoothly from A to C, going
>through B, without sudden turns. I should be able to specify what level
>of "bendness" I want, that is how smooth the path will be. It isn't as
>easy as I thought in the beggining.

I wrote a little tutorial once on the subject, but I can't find it.
In the meantime, here is an old project that may put you on the right
track.  It plays with several spline types.  It has bugs - in
particular, the Kochanek-Bartels part doesn't work - but the other
spline types you would want for this project are fine.  If you have to
pass through every given point, use the Cardinal spline and adjust
tension to control smoothness or the Tau spline, where you can also
adjust bias to control how close to which end of the segment the max
curvature is.  Play with it.  You can get better smoothness at the
cost of passing near, not through some points, by using the tensed B
spline or the Beta (tensed and biased B) spline.  You should be able
to extract the ideas you need from this.

// Begin POV code

// Loop.pov - Produces a reference image of the given point set

#version 3.1;

// Do not touch these declares
#declare Crosseye = 2 / 3;
#declare  Regular = 4 / 3;
#declare Square = 1;
#declare Crosssquare = 1 / 2;
#declare Straight = <  0,  0, 0>;
#declare   Crossl = <  0,  1, 0>;
#declare   Crossr = <  0, -1, 0>;

// Use these declares to change the image
#declare Method = 0;
  // 0 for ordinary image or crosseye video
  // 1 for blue-red image
#declare Aspect = Regular;
  // Regular for 800x600 plain or blue-red image
  // Crosseye for 800x600 crosseye video
  // Square for 600x600 plain or blue-red image
  // Crosssquare for 600x600 crosseye video
#declare Angle = Straight;
  // Straight for plain or blue-red image
  // Crossl for left half of crosseye video image
  // Crossr for right half of crosseye video image
#declare File = "Goofy.pts"
  // Name of file containing points (in quotes)
#declare Fine = 10;
  // How smooth image should be.  10 is fairly rough, 50 is very
smooth (but slow)
#declare Width = 2;
  // How thick loop should be
#declare Tens = .25;
  // Tension for Cardinal, Tau, Beta, Tensed B-spline or
Kochanek-Bartels spline
#declare Bias = .75;
  // Bias for Tau, Beta or Kochanek-Bartels spline
#declare Cont = 0;
	// Continuity for Kochanek-Bartels spline
#declare Type = "Kochbar"
  // (should be in quotes)
  // Catmull for Catmull-Rom spline
  // Cardinal for Cardinal spline
  // Tau for Tau spline
  // Bezier for Bezier spline
  // Bspline for B-spline
  // Beta for Beta spline
  // Tbspline for Tensed b-spline
  // Kochbar for Kochanek-Bartels spline
#declare Elev = 0;
  // Elevation (in degrees)
#declare Azim = 0;
  // Azimuth (in degrees)
#declare Close = 1;
	// 0 means "do not close the loop"
	// 1 means "close the loop
#declare Show = 1;
  // 1 means "show control points"
  // 0 means "do not show control points"

// Do not touch declares past this point
#declare White = color rgb <1, 1, 1>;
#declare Black = color rgb <0, 0, 0>;
#declare Red = color rgbt <1, 0, 0, .9>;
#declare Blue = color rgbt <0, 0, 1, .9>;

#declare Shine =
finish
  {
      specular 1.000
     roughness 0.030
       ambient 0.000
       diffuse 1.000
  }
  
#declare Curvtex =
texture
  {
    pigment { color Black }
    finish { Shine }
  }
  
#declare Curvtexr =
texture
  {
    pigment { color Red }
  }
  
#declare Curvtexb =
texture
  {
    pigment { color Blue }
  }

global_settings { assumed_gamma 1.0 } 

camera { up <0, 1, 0> right <Aspect, 0, 0> 
  location <0, 0, -50> look_at <0, 0, 0> rotate Angle}

light_source { <0, 0, -20> color White * 3 }

sky_sphere { pigment { color White } }

#fopen Ptlist File read

#read(Ptlist, Dim)

#declare Ptemp = array[Dim]

#declare Iter = 0;
#while(Iter < Dim)
  #read(Ptlist, Temp)
  #declare Ptemp[Iter] = Temp;
  #undef Temp
  #declare Iter = Iter + 1;
#end

#fclose Ptlist

#declare Points = array[Dim + 2 * (Close + 1)]

#declare Points[0] = ((Close = 0) ? Ptemp[Dim -1] : Ptemp[Dim - 2]);
#if(Close = 1)
	#declare Points[1] = Ptemp[Dim - 1];
#end
#declare Points[Dim + (Close + 1)] = Ptemp[0];
#if(Close = 1)
	#declare Points[Dim + 3] = Ptemp[1];
#end

#declare Iter = 0;
#while(Iter < Dim)
  #declare Points[Iter + (Close + 1)] = Ptemp[Iter];
  #declare Iter = Iter + 1;
#end

#undef Ptemp

#declare Sum = <0, 0, 0>;
#declare Iter = Close + 1;
#while(Iter < Dim + (Close + 1))
  #declare Sum = Sum + Points[Iter];
  #declare Iter = Iter + 1;
#end

#declare Centroid = Sum / Dim;

#macro Mxv(In, Mx)
  <max(In.x, Mx.x), max(In.y, Mx.y), max(In.z, Mx.z)>
#end

#macro Mnv(In, Mn)
  <min(In.x, Mn.x), min(In.y, Mn.y), min(In.z, Mn.z)>
#end

#declare Iter = 0;
#while(Iter < Dim + 2 * (Close + 1))
  #declare Points[Iter] = Points[Iter] - Centroid;
  #declare Points[Iter] = vrotate(Points[Iter], <0, Elev, 0>);
  #declare Points[Iter] = vrotate(Points[Iter], <-Azim, 0, 0>);
  #declare Points[Iter] = Points[Iter] + Centroid;
  #declare Iter = Iter + 1;
#end

#declare Sum = <0, 0, 0>;
#declare Min = <1, 1, 1>;
#declare Max = <0, 0, 0>;

#declare Iter = Close +1;
#while(Iter < Dim + (Close + 1))
  #declare Sum = Sum + Points[Iter];
  #declare Min = Mnv(Min, Points[Iter]);
  #declare Max = Mxv(Max, Points[Iter]);
  #declare Iter = Iter + 1;
#end

#declare Centroid = Sum / Dim;
#declare Centroid = <Centroid.x, Centroid.y, 0>;
#declare Diff = Max - Min;
#declare Iter = 0;
#while(Iter < Dim + 2 * (Close + 1))
  #declare Points[Iter] = Mxv(Mnv((Points[Iter] * <42 * Aspect, 42,
21> / Diff - 
                          (1 + Centroid) * <21 * Aspect, 21, 0>),
                          <21 * Aspect, 21, 21>), <-21 * Aspect, -21,
0>);
  #if(Show = 1)
    sphere { Points[Iter], Width * 1.2 texture { pigment { color rgb
             ((Iter = Close + 1) ? <1, 1, 0> : <0, 1, 0>) } }
             scale ((Iter = Close + 1) ? 1.2 : 1) }
  #end
  #declare Iter = Iter + 1;
#end

#declare Cat = array[4][4]
  {
    { -0.5,  1.5, -1.5,  0.5 },
    {  1.0, -2.5,  2.0, -0.5 },
    { -0.5,  0.0,  0.5,  0.0 },
    {  0.0,  1.0,  0.0,  0.0 }
  }

#declare Car = array[4][4]
  {
    { -Tens, 2 - Tens, Tens - 2, Tens },
    { 2 * Tens, Tens - 3, 3 - 2 * Tens, -Tens },
    { -Tens, 0, Tens, 0 }
    { 0, 1, 0, 0 }
  }
  
#declare Bsp = array[4][4]
  {
    { -1 / 6, 1 / 2, -1 / 2, 1 / 6 },
    { 1 / 2, -1, 1 / 2, 0 },
    { -1 / 2, 0, 1 / 2, 0 },
    { 1 / 6, 2 / 3, 1 / 6, 0 }
  }
  
#declare Tbs = array[4][4]
  {
    { -Tens / 6, 2 - 1.5 * Tens, 1.5 * Tens - 2, Tens / 6 },
    { Tens / 2, 2 * Tens - 3, 3 - 2.5 * Tens, 0 },
    { -Tens / 2, 0, Tens / 2, 0 },
    { Tens / 6, 1 - Tens / 3, Tens / 6, 0 }
  }
  
#declare Bez = array[4][4]
  {
    { -1, 3, -3, 1 },
    { 3, -6, 3, 0 },
    { -3, 3, 0, 0 },
    { 1, 0, 0, 0 }
  }
  
#declare Tau = array[4][4]
  {
    { (Bias - 1) * Tens, 2 - Bias * Tens, (1 - Bias) * Tens - 2, Bias
* Tens },
    { 2 * (1 - Bias) * Tens, (3 * Bias - 1) * Tens - 3, 3 - Tens,
-Bias * Tens },
    { (Bias - 1) * Tens, (1 - 2 * Bias) * Tens, Bias * Tens, 0 },
    { 0, 1, 0, 0 }
  }
  
#declare Divi = Tens + 2 * (Bias * (Bias * (Bias + 2) + 2) + 1);

#declare Bet = array[4][4]
  {
    { -2 * Bias * Bias * Bias / Divi,
    		 2 * (Tens + (Bias * (Bias * (Bias + 1) + 1))) / Divi,
      -2 * (Tens + Bias * (Bias + 1) +1) / Divi, 2 / Divi },
    { 6 * Bias * Bias * Bias / Divi,
    		-3 * (Tens + 2 *(Bias * Bias * (Bias + 1))) / Divi,
      3 * (Tens + 2 * Bias * Bias) / Divi, 0 },
    { -6 * Bias * Bias * Bias / Divi,
    		6 * Bias * (Bias * Bias - 1) / Divi, 6 * Bias / Divi, 0 },
    { 2 * Bias * Bias * Bias / Divi, (Tens + 4 * Bias * (Bias + 1)) /
Divi,
    	  2 / Divi, 0 }
  }
  
#undef Divi
  
#declare Mult = (1 - Tens) / 2;

#declare Alpha = Mult * (1 - Bias) * (1 - Cont);
#declare Beta = Mult * (1 + Bias) * (1 + Cont);
#declare Gamma = Mult * (1 - Bias) * (1 + Cont);
#declare Delta = Mult * (1 + Bias) * (1 - Cont);

#undef Mult

#declare Kbs = array[4][4]
	{
		{ -Beta, -Alpha + Beta -Delta + 2, Alpha -Gamma + Delta -2, Gamma
},
		{ 2 * Beta, 2 * (Alpha - Beta) + Delta + 3, -2 * Alpha + Gamma -
Delta + 3,
			-Gamma },
		{ -Beta, -Alpha + Beta, Alpha, 0 },
		{ 0, 1, 0, 0 }
	}
	
#undef Alpha
#undef Beta
#undef Gamma
#undef Delta
  
#if(strcmp(Type, "Cardinal") = 0)
  #declare Use = Car
#else
  #if(strcmp(Type, "Bspline") = 0)
    #declare Use = Bsp
  #else
    #if(strcmp(Type, "Tbspline") = 0)
      #declare Use = Tbs
    #else
      #if(strcmp(Type, "Bezier") = 0)
        #declare Use = Bez
      #else
        #if(strcmp(Type, "Tau") = 0)
          #declare Use = Tau
        #else
          #if(strcmp(Type, "Beta") = 0)
            #declare Use = Bet
          #else
          		#if(strcmp(Type, "Kochbar") = 0)
          			#declare Use = Kbs
          		#else
            		#declare Use = Cat
            	#end
          #end
        #end
      #end
    #end
  #end
#end

#declare T = 0;

#macro Horn(Row, Pt)
  (T * ( T * (T * Use[0][Row] + Use[1][Row]) + Use[2][Row]) +
Use[3][Row]) * Pt
#end

#macro Cerp(Pf)
  Horn(0, Points[Pf - 1]) + Horn(1, Points[Pf]) +
  Horn(2, Points[Pf + 1]) + Horn(3, Points[Pf + 2])
#end

#declare Loop =
union
  {
    #declare Iter = 1;
    #while(Iter < Dim + 2 * Close)
      #declare Count = max(1, int(Fine * vlength(Points[Iter + 1] -
Points[Iter])));
      #declare Incr = 1 / Count;
      #declare T = 0;
      #while(T < 1)
        #declare Start = Mxv(Mnv(Cerp(Iter), <24 * Aspect, 24, 24>),
                         <-24 * Aspect, -24, 0>);
        #declare T = T + Incr;
        #declare End = Mxv(Mnv(Cerp(Iter), <24 * Aspect, 24, 24>),
                       <-24 * Aspect, -24, 0>);
        #declare End = ((End.x = Start.x) ? End + <.001, 0, 0> : End);
        sphere { Start, Width }
        cylinder { Start, End, Width }

      #end
      #declare Iter = Iter + ((strcmp(Type, "Bezier") = 0) ? 3 :
                             ((strcmp(Type, "Kochbar") = 0) ? 3 : 1
));
    #end
  }
  
#if (Method = 1)
  object { Loop texture { Curvtexr } }
#else
  object { Loop texture { Curvtex } }
#end

#if (Method = 1)
  object { Loop texture { Curvtexb } translate <.75 * Width, 0, -.001>
} 
#end

// End POV Code

// Begin sample point file

8,
<.25, .25, .25>,
<.33, .25, .25>,
<.66, .75, .75>,
<.75, .75, .75>,
<.75, .66, .66>,
<.25, .33, .33>,
<.10, .10, .10>,
<.5, .5, .5>

// End sample point file


Jerry Anning
clem "at" dhol "dot" com


Post a reply to this message

From: Lewis
Subject: Re: Curve calculation
Date: 23 May 1999 14:17:21
Message: <3748380E.1A03E0CC@netvision.net.il>
Thanks!


Post a reply to this message

From: Lewis
Subject: Re: Curve calculation
Date: 23 May 1999 14:27:52
Message: <37483A85.84A1AFE2@netvision.net.il>
Sorry, I just realized this doesn't really help me.
If you can explain how to calculate a curve, it would help. I
specifically need one that goes through the certain specified points, so
just choose any and if you don't mind, tell me how its done,
mathematically.


Post a reply to this message

From: Anders Haglund
Subject: RE: Curve calculation
Date: 23 May 1999 17:48:35
Message: <374869a3.0@news.povray.org>
Lewis <nle### [at] netvisionnetil> wrote:
> Sorry, I just realized this doesn't really help me.
> If you can explain how to calculate a curve, it would help. I
> specifically need one that goes through the certain specified points, so
> just choose any and if you don't mind, tell me how its done,
> mathematically.

Check out Paul Bourke's explanation on bezier curves and spline curves:
http://www.mhri.edu.au/~pdb/geometry/bezier/
http://www.mhri.edu.au/~pdb/geometry/spline/
I did a pov macro of the bezier curve the other day, I can post the code if
your to lazy :)

/Anders


Post a reply to this message

From: Ph Gibone
Subject: Re: Curve calculation
Date: 23 May 1999 18:03:53
Message: <37486d39.0@news.povray.org>
If you want one solution no matter which one, you can consider your curve
equation to be

x = f(u), y= g(u), z = h(u) (f,g,h being 2 nd degree polynomials (for
instance))

Where u belongs to [0 ; 1]

Let A=(x0, y0, z0), B = (x1, y1, z1), C=(x2, y2,z2) and the curve being in A
for u = 0, in B for u = 1/2, in C for u = 1

so you get the equations :

x = a + b*u + c*u*u

u= 0 ==> x0 = a
u=1/2 ==> x1 = a +b/2 + c/4
u = 1 ==> x2 = a + b +c

and so on for the y's and the z's
a very easy set of equations to solve

This is a stupid way to get  what you want, may be you should consider some
more constraints

Philippe




>This doesn't help me much I need to know how to actually do it. The path
>itself is what I need not an surface following it. Thanks anyway.


Post a reply to this message

From: Ken
Subject: Re: Curve calculation
Date: 23 May 1999 18:56:13
Message: <3748792B.CBFF3F8B@pacbell.net>
Anders Haglund wrote:
> 
> Lewis <nle### [at] netvisionnetil> wrote:
> > Sorry, I just realized this doesn't really help me.
> > If you can explain how to calculate a curve, it would help. I
> > specifically need one that goes through the certain specified points, so
> > just choose any and if you don't mind, tell me how its done,
> > mathematically.
> 
> Check out Paul Bourke's explanation on bezier curves and spline curves:
> http://www.mhri.edu.au/~pdb/geometry/bezier/
> http://www.mhri.edu.au/~pdb/geometry/spline/
> I did a pov macro of the bezier curve the other day, I can post the code if
> your to lazy :)
> 
> /Anders

 And if that does not help there is an include file already available from
Chris Colefax that creates spline paths from a set of control points. You
might make it easier to just use his system as a call from yours and save
a lot of extra work. Either that look at the file and see how the master
goes about solving the problems.

http://www.geocities.com/SiliconValley/Lakes/1434/

-- 
Ken Tyler

mailto://tylereng@pacbell.net


Post a reply to this message

From: Jerry Anning
Subject: Re: Curve calculation
Date: 23 May 1999 19:47:57
Message: <374884f0.11271740@news.povray.org>
On Sun, 23 May 1999 20:27:33 +0300, Lewis <nle### [at] netvisionnetil>
wrote:

>Sorry, I just realized this doesn't really help me.
>If you can explain how to calculate a curve, it would help. I
>specifically need one that goes through the certain specified points, so
>just choose any and if you don't mind, tell me how its done,
>mathematically.

Here is an excerpt from a letter I wrote once, modified to use the Tau
spline that I recommend.  There are more efficient ways, but this is
good enough.  If you need more, let me know.

To generate your starting points, you need to explicitly do the
Tau spline calculations.  First
set up an array containing the control points for your object. 
Then set up an array as the Tau basis matrix.  This array is as
follows:

#declare Basis = array[4][4]
  {
    { (Bias - 1) * Tens, 2 - Bias * Tens, (1 - Bias) * Tens - 2, Bias
* Tens },
    { 2 * (1 - Bias) * Tens, (3 * Bias - 1) * Tens - 3, 3 - Tens,
-Bias * Tens },
    { (Bias - 1) * Tens, (1 - 2 * Bias) * Tens, Bias * Tens, 0 },
    { 0, 1, 0, 0 }
  }

(You can use any uniform cubic spline basis you like with minimal
changes to the code, but the shape you get will vary.)  Next, set up
macros to carry out the spline calculation.  I use a simple macro to
do
the basic multiplications with Horner's Rule:
(Param *(Param * (Param * Basis[0][Row] + Basis[1][Row]) +
Basis[2][Row]) + Basis[3][Row]) * Point

Then I set up another simple macro to use the Horner macro for cubic
interpolation:
Horner(T, 0, Points[This - 1]) + Horner(T, 1, Points[This]) +
Horner(T,
2, Points[This + 1]) + Horner[T, 3, Points[This + 2])

Then I would use a loop to generate the actual points along the 
spline from the control points with pseudocode something like this:

Increment = .2 (or more or less, depending on the detail of the
object)
Index = 0
This = 1
while (This < sizeof[Points])
T = 0
while (T < 1)
Actualpoint[Index] = Cubic_interpolate(T, This)
T = T + Incr
Index =Index + 1
endwhile
This = This + 1
endwhile

Jerry Anning
clem "at" dhol "dot" com


Post a reply to this message

Goto Latest 10 Messages Next 1 Messages >>>

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