POV-Ray : Newsgroups : povray.advanced-users : On Bezier splines Server Time
2 Nov 2024 03:14:59 EDT (-0400)
  On Bezier splines (Message 1 to 10 of 10)  
From: Peter Popov
Subject: On Bezier splines
Date: 25 Apr 2000 20:06:49
Message: <27ccgsoh995bp5kkjdis349tgpdkuc9a2n@4ax.com>
A problem arised which requires approximating a Bezier spline with
linear segments and circle (not ellipse!) arcs. The controlling
parameters would be maximum number of elements (I know I can
approximate it with a gazillion segments but I don't want to :) ),
maximum cusp angle and maximum distance between real and interpolated
curves. Any math, ideas, headers or urls? Thanks in advance.


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] usanet
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: On Bezier splines
Date: 2 May 2000 18:09:58
Message: <390F5219.A9E9DC7F@online.no>
Peter Popov wrote:

> A problem arised which requires approximating a Bezier spline with
> linear segments and circle (not ellipse!) arcs. The controlling
> parameters would be maximum number of elements (I know I can
> approximate it with a gazillion segments but I don't want to :) ),
> maximum cusp angle and maximum distance between real and interpolated
> curves. Any math, ideas, headers or urls? Thanks in advance.

Some of my thoughts:

First I think that for optimal results this problem would have to be
solved iteratively.

But if I was to do this in only one pass, then here is my suggestion:

First I would create an array of co-ordinates for several (many)
points along the spline.

I would then "move" along this string of points and for every point
I would calculate how many points "behind" and "in front" of this point
a circle segment could be used for interpolation (within the given
"error" limit).

(The problem here would be to find a way to calculate the centre and
plane and radius for this circle segment in such a way that it comes
near enough as many as possible points around the given point.)
The results of this "walk" along the spline could be stored in another
array.

Then I would do calculations on this array to find out which circle
segments to use in each "area" of the spline. Here the algorithm would
have to take into account your other controlling parameters.
(I think these calculations would be the hardest part of the problem.)

And at last my algorithm would have to patch together all the circle
(or torii ?) segments taking care that every two joined circle segments
have their centres in the same plane and that their "joining" also take
place in the same plane.

There is a danger that this last part of the algorithm would have to
change some of the parameters for the circle segments in order to make
them possible to join smoothly, and thereby enforcing new "iterations"
:(

I think that I would use circle segments with large radii instead of
using linear segments.

I'm not sure what math you are looking for. Please specify.

Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: On Bezier splines
Date: 2 May 2000 21:36:50
Message: <390F829F.FAD318D3@online.no>
Forgive me if I have misunderstood your problem.

Here are some more thoughts:

Tor Olav Kristensen wrote:

> ...
> (The problem here would be to find a way to calculate the centre and
> plane and radius for this circle segment in such a way that it comes
> near enough as many as possible points around the given point.)
> The results of this "walk" along the spline could be stored in another
> array.
> ...

I think that maybe a "good" starting point for each of these circle
segments could be calculated by using 1 point on each side of the
given point. This would give 3 points which is could be used to
define a circle that touch each of them (ex-circle ?).

(I have posted an image to p.b.i that shows these circles.
The white spheres the path of the spline and the coloured ones shows
the path of the centres of the ex-circles.)

One could then start to check points further and further away on
each side of the given point and until the "error" limit is reached.
(The middle point could also be adjusted in some way while doing
this.)

And then one could move on to do the same around the next point
in the array of spline points.

> ...
> And at last my algorithm would have to patch together all the circle
> (or torii ?) segments taking care that every two joined circle segments
> have their centres in the same plane and that their "joining" also take
> place in the same plane.
> ...

I have connected some torii segments (to approximate the Bezier path)
to the left in my image, but as you see I have not applied this
correction to them.

Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html


Post a reply to this message

From: Peter Popov
Subject: Re: On Bezier splines
Date: 3 May 2000 18:06:41
Message: <8j81hs8ok8074bke6vnpqqdmbu9jhtedjp@4ax.com>
On Wed, 26 Apr 2000 03:01:35 +0300, Peter Popov <pet### [at] usanet>
wrote:

Thanks a lot, Tor Olav, I'll take a careful look at your idea when
I've had some sleep :) I notice one important thing I have missed to
say. The probles is 2D. No need to fiddle with minimum bounding
spheres, planes, etc.


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] usanet
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

From: Peter Popov
Subject: Re: On Bezier splines
Date: 5 May 2000 08:18:10
Message: <fke5hs4coeqsgp2pkpj98u2kb8pa36e9pa@4ax.com>
On Wed, 03 May 2000 00:09:30 +0200, Tor Olav Kristensen
<tto### [at] onlineno> wrote:

>Some of my thoughts:
>
>First I think that for optimal results this problem would have to be
>solved iteratively.

That's OK as long as I can code it... that's what computers are for :)

>But if I was to do this in only one pass, then here is my suggestion:

>First I would create an array of co-ordinates for several (many)
>points along the spline.

>I would then "move" along this string of points and for every point
>I would calculate how many points "behind" and "in front" of this point
>a circle segment could be used for interpolation (within the given
>"error" limit).

How? I mean, it's trivial for three points, maybe even four, but how
should I proceed with more points?

>Then I would do calculations on this array to find out which circle
>segments to use in each "area" of the spline. Here the algorithm would
>have to take into account your other controlling parameters.
>(I think these calculations would be the hardest part of the problem.)

I don't think so. It would be computationally beneficial if these were
taken into account while calculating the circles in the previous step
of the algorithm.

>There is a danger that this last part of the algorithm would have to
>change some of the parameters for the circle segments in order to make
>them possible to join smoothly, and thereby enforcing new "iterations"
>:(

Smoothness is not obligatory as long as cusp angles are kept withing a
certain limit.

>I think that I would use circle segments with large radii instead of
>using linear segments.

Linear segments are preferable where possible.

>I'm not sure what math you are looking for. Please specify.

For example, how does one find the distance to the closest point on a
Bezier spline? Or the maximum distance between a circular arc and a
Bezier spline? I can handle most of the math involved in this problem
but the distances part scares the s*&^ out of me.


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] usanet
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: On Bezier splines
Date: 9 May 2000 07:59:01
Message: <3917FD7C.2F70E8E4@online.no>
Peter Popov wrote:

> >I would then "move" along this string of points and for every point
> >I would calculate how many points "behind" and "in front" of this point
> >a circle segment could be used for interpolation (within the given
> >"error" limit).
>
> How? I mean, it's trivial for three points, maybe even four, but how
> should I proceed with more points?

I have done some coding trying to find a way to estimate the centre
of a circle for several points.

What I have come up with so far is just a "dirty" way to find it.
It's quite time consuming to parse, so later today I will implement
some macros that does a numerical search for "good" centre points.

I have posted another  image to p.b.i that shows a "height field"
above a plane with 6 points. This the lowest point in this height
field shows where the "best" centre point is for a circle that comes
close to the given points.

The "height field" can be considered as an "error field".
The height above "ground" gives the least "error" generated if
placing the circle below.

The code generating this image also estimates which radius to use
for the circle. And the code can also be used with more or less
points.

Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html


Post a reply to this message

From: Peter Popov
Subject: Re: On Bezier splines
Date: 9 May 2000 16:28:37
Message: <soqghsssd88tap7n124e7r2askalqh5c35@4ax.com>
On Tue, 09 May 2000 13:58:53 +0200, Tor Olav Kristensen
<tto### [at] onlineno> wrote:

>I have done some coding trying to find a way to estimate the centre
>of a circle for several points.

>What I have come up with so far is just a "dirty" way to find it.
>It's quite time consuming to parse, so later today I will implement
>some macros that does a numerical search for "good" centre points.

Parse time won't be a problem since I'll write the program in C.

>I have posted another  image to p.b.i that shows a "height field"
>above a plane with 6 points. This the lowest point in this height
>field shows where the "best" centre point is for a circle that comes
>close to the given points.

Very illustrative, thanks!

>The "height field" can be considered as an "error field".
>The height above "ground" gives the least "error" generated if
>placing the circle below.

So basically you find the standard error of the distances between the
points and the circle? Nifty :)

>The code generating this image also estimates which radius to use
>for the circle. And the code can also be used with more or less
>points.

Interesting, how do you do that, by sampling?


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] usanet
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: On Bezier splines
Date: 9 May 2000 17:18:45
Message: <391880AD.47C6B558@online.no>
Peter Popov wrote:

> >I have posted another  image to p.b.i that shows a "height field"
> >above a plane with 6 points. This the lowest point in this height
> >field shows where the "best" centre point is for a circle that comes
> >close to the given points.
>
> Very illustrative, thanks!

You're welcome. Interesting problem btw.

> >The "height field" can be considered as an "error field".
> >The height above "ground" gives the least "error" generated if
> >placing the circle below.
>
> So basically you find the standard error of the distances between the
> points and the circle? Nifty :)

;)

First I  thought about doing linear regression analysis on the points
to get a vector for a tangent line of the circle. Then one could
construct
a normal vector to a tangent line of the circle. This vector could then
be used as a direction vector for a line to place the circle centre on.

But then I realized that it could be difficult to place the line and
thereafter to place the circle centre on it.

The linear regression gave birth to the idea of using the sum of
squares of  the errors as a measure of how suitable a certain
point would be for the circle centre.


> >The code generating this image also estimates which radius to use
> >for the circle. And the code can also be used with more or less
> >points.
>
> Interesting, how do you do that, by sampling?

Mean distance from the point in question to the other points.

(See code below.)

The problem with this code is that one has to know which region
to do the search. This could be frustrating if many of the points
lies close to a straight line. That would cause the region to
expand very much because the centre would approach infinity.

Therefore I'm working on macros to implement the Nelder-
Mead simplex method to locate the minima of the "error field".

Tor Olav
--
mailto:tor### [at] hotmailcom
http://www.crosswinds.net/~tok/tokrays.html

#version 3.1;

global_settings {
  #max_trace_level 1
  ambient_light 2
}

#include "colors.inc"


#macro SumSqdErrors(Point, PointArray, Radius)

  #local NrOfPoints = dimension_size(PointArray, 1);
  #local ErrorSum = 0;

  #local PtCnt = 0;
  #while(PtCnt < NrOfPoints)
    #local ErrorSum = ErrorSum +
           pow(vlength(Point - PointArray[PtCnt]) - Radius, 2);
    #local PtCnt = PtCnt + 1;
  #end // while

  ErrorSum

#end // macro SumSqdErrors


#macro MeanDist(Point, PointArray)

  #local NrOfPoints = dimension_size(PointArray, 1);
  #local DistSum = 0;

  #local PtCnt = 0;
  #while(PtCnt < NrOfPoints)
    #local ThisDist = vlength(Point - PointArray[PtCnt]);
    #local DistSum = DistSum + ThisDist;
    #local PtCnt = PtCnt + 1;
  #end // while

  (DistSum/NrOfPoints)

#end // macro MeanDist


#macro StoreErrors(PointArray, ErrorArray, RadiusArray, xMin, xMax, zMin,
zMax)

  #local xNr = dimension_size(ErrorArray, 1);
  #local zNr = dimension_size(ErrorArray, 2);

  #local dx = (xMax - xMin)/xNr;
  #local dz = (zMax - zMin)/zNr;

  #local xPos = xMin;
  #local xCnt = 0;
  #while(xCnt < xNr)
    #local zPos = zMin;
    #local zCnt = 0;
    #while(zCnt < zNr)
      #local Point = <xPos, 0, zPos>;
      #local BestRadius = MeanDist(Point, PointArray);
      #local MinimumError = SumSqdErrors(Point, PointArray, BestRadius);
      #declare RadiusArray[xCnt][zCnt] = BestRadius;
      #declare ErrorArray[xCnt][zCnt] = Point + y*MinimumError;
      #local zCnt = zCnt + 1;
      #local zPos = zPos + dz;
    #end // while
    #local xCnt = xCnt + 1;
    #local xPos = xPos + dx;
  #end // while

#end // macro StoreErrors


#macro LocateBest(ErrorArray, RadiusArray, xBest, zBest)

  #local xNr = dimension_size(ErrorArray, 1);
  #local zNr = dimension_size(ErrorArray, 2);
  #declare xBest = 0;
  #declare zBest = 0;
  #local LeastError = ErrorArray[0][0].y;

  #local xCnt = 0;
  #while(xCnt < xNr)
    #local zCnt = 0;
    #while(zCnt < zNr)
      #local CurrentError = ErrorArray[xCnt][zCnt].y;
      #if(CurrentError < LeastError)
        #local LeastError = CurrentError;
        #declare xBest = xCnt;
        #declare zBest = zCnt;
      #end // if
      #local zCnt = zCnt + 1;
    #end // while
    #local xCnt = xCnt + 1;
  #end // while

#end // macro LocateBest


#macro PlotErrors(ErrorArray, SphereRadius)

  #local xNr = dimension_size(ErrorArray, 1);
  #local zNr = dimension_size(ErrorArray, 2);

  union {
    #local xCnt = 0;
    #while(xCnt < xNr)
      #local zCnt = 0;
      #while(zCnt < zNr)
        sphere { ErrorArray[xCnt][zCnt], SphereRadius }
        #local zCnt = zCnt + 1;
      #end // while
      #local xCnt = xCnt + 1;
    #end // while
  }

#end // macro PlotErrors


#macro PtPlot(PointArray, SphereRadius)

  #local NrOfPoints = dimension_size(PointArray, 1);

  union {
    #local PtCnt = 0;
    #while(PtCnt < NrOfPoints)
      sphere { PointArray[PtCnt], SphereRadius }
      #local PtCnt = PtCnt + 1;
    #end // while
  }

#end // macro PtPlot


#declare SplinePts =
array[6] {
  <1.0, 0, 1.9>,
  <2.0, 0, 1.1>,
  <1.7, 0, 1.5>,
  <2.9, 0, 1.7>,
  <3.1, 0, 3.0>,
  <3.1, 0, 3.4>
}


#declare xCount = 80;
#declare zCount = 80;

#declare ErrArray = array[xCount][zCount]
#declare RadArray = array[xCount][zCount]

#declare xMin = -1;
#declare xMax =  5;
#declare zMin = -1;
#declare zMax =  5;

StoreErrors(SplinePts, ErrArray, RadArray, xMin, xMax, zMin, zMax)

#declare xBest = 0;
#declare zBest = 0;

LocateBest(ErrArray, RadArray, xBest, zBest)

#declare BestPoint = ErrArray[xBest][zBest];


object {
  PtPlot(SplinePts, 0.06)
  pigment { color Red*3 }
}

sphere {
  BestPoint, 0.06
  pigment { color Green }
}

torus {
  RadArray[xBest][zBest], 0.02
  translate (x + z)*BestPoint
  pigment { color White*2 }
}

object {
  PlotErrors(ErrArray, 0.03*1.2)
  pigment { color Yellow }
  scale <1, 1/3.5, 1>
}


camera {
//  location <-3, 0.7, 7>
//  location <4.5, 0.8, 9>
  location <-1.5, 4.5*1.3, 9>*0.85
//  location BestPoint + 7*y
  look_at BestPoint
}

background { color Blue/2 }

light_source { <10,  100, 10>, 1 }
light_source { <10, -100, 10>, 1 }


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: On Bezier splines
Date: 12 May 2000 20:01:12
Message: <391C9B3B.C63B6FC1@online.no>
Tor Olav Kristensen wrote:

> Therefore I'm working on macros to implement the Nelder-
> Mead simplex method to locate the minima of the "error field".

And here they are.

I'll try to explain later (if its necessary).

Tor Olav

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Copyright 2000 by Tor Olav Kristensen
// mailto:tor### [at] hotmailcom
// http://www.crosswinds.net/~tok/tokrays.html
// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.1;

global_settings {
  #max_trace_level 1
  ambient_light 2
}

#include "colors.inc"

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// The spline points to put a circle around

#declare SplinePts =
array[6] {
  <1.0, 0, 1.9>,
  <2.0, 0, 1.1>,
  <1.7, 0, 1.5>,
  <2.9, 0, 1.7>,
  <3.1, 0, 3.0>,
  <3.1, 0, 3.4>
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Just to show the spline points

#macro PrintVector(Vector)

  #debug "< "
  #debug str(Vector.x, 0, -1)
  #debug ", "
  #debug str(Vector.y, 0, -1)
  #debug ", "
  #debug str(Vector.z, 0, -1)
  #debug " >"

#end // macro PrintVector

#macro PtPlot(PointArray, SphereRadius)

  #local NrOfPoints = dimension_size(PointArray, 1);

  union {
    #local PtCnt = 0;
    #while(PtCnt < NrOfPoints)
      sphere { PointArray[PtCnt], SphereRadius }
      #local PtCnt = PtCnt + 1;
    #end // while
  }

#end // macro PtPlot


object {
  PtPlot(SplinePts, 0.06)
  pigment { color Cyan*2 }
}

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Functions used to evalute fitness of a point

#macro SumSqdErrors(Point, PointArray, Radius)

  #local NrOfPoints = dimension_size(PointArray, 1);
  #local ErrorSum = 0;

  #local PtCnt = 0;
  #while(PtCnt < NrOfPoints)
    #local ErrorSum = ErrorSum +
           pow(vlength(Point - PointArray[PtCnt]) - Radius, 2);
    #local PtCnt = PtCnt + 1;
  #end // while

  ErrorSum

#end // macro SumSqdErrors


#macro MeanDist(Point, PointArray)

  #local NrOfPoints = dimension_size(PointArray, 1);
  #local DistSum = 0;

  #local PtCnt = 0;
  #while(PtCnt < NrOfPoints)
    #local ThisDist = vlength(Point - PointArray[PtCnt]);
    #local DistSum = DistSum + ThisDist;
    #local PtCnt = PtCnt + 1;
  #end // while

  (DistSum/NrOfPoints)

#end // macro MeanDist


#macro UserFunction(Point)

  #local BestRadius = MeanDist(Point, SplinePts);
  #local MinimumError = SumSqdErrors(Point, SplinePts, BestRadius);

  MinimumError

#end // macro UserFunction

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Nelder-Mead simplex method macros
// Made to work for several dimensions
// (as many as POV-Ray can handle in standard vectors: 4 or 5?)
// but I have only tested them for 2D points/vectors

#macro RankVertices(SimplexArray,
                    BestIndex, BestValue,
                    NextWorstIndex, NextWorstValue,
                    WorstIndex, WorstValue)

  #local NrOfVertices = dimension_size(SimplexArray, 1);
  #declare BestIndex      = 0;
  #declare WorstIndex     = 0;
  #declare NextWorstIndex = 0;
  #local FValue = UserFunction(SimplexArray[0]);
  #declare BestValue      = FValue;
  #declare WorstValue     = FValue;
  #declare NextWorstValue = FValue;

  #local IndexCnt = 1;
  #while (IndexCnt < NrOfVertices)
    #local FValue = UserFunction(SimplexArray[IndexCnt]);
    #if (FValue <= BestValue)
      #declare BestIndex = IndexCnt;
      #declare BestValue = FValue;
    #else
      #if (FValue >= WorstValue)
        #declare WorstIndex = IndexCnt;
        #declare WorstValue = FValue;
      #else
        #if (FValue >= NextWorstValue)
          #declare NextWorstIndex = IndexCnt;
          #declare NextWorstValue = FValue;
        #end // if
      #end // if
    #end // if
    #local IndexCnt = IndexCnt + 1;
  #end // while

#end // macro RankVertices


#macro FindCentroid(SimplexArray, WorstVertex)

  #local Dimensions = dimension_size(SimplexArray, 1) - 1;
  #local Centroid = -WorstVertex;

  #local IndexCnt = 0;
  #while (IndexCnt <= Dimensions)
    #local Centroid = Centroid + SimplexArray[IndexCnt];
    #local IndexCnt = IndexCnt + 1;
  #end // while

  (Centroid/Dimensions)

#end // macro FindCentroid


#macro ProjVertex(Vertex, Centroid, ScaleCoeff)

  #local vDisplace = Centroid - Vertex;

  (Centroid + ScaleCoeff*vDisplace)

#end // macro ProjVertex


#macro ShrinkSimplex(SimplexArray, Vertex)

  #local NrOfVertices = dimension_size(SimplexArray, 1);

  #local IndexCnt = 0;
  #while (IndexCnt < NrOfVertices)
    #declare SimplexArray[IndexCnt] =
             (SimplexArray[IndexCnt] + Vertex)/2;
    #local IndexCnt = IndexCnt + 1;
  #end // while

#end // macro ShrinkSimplex


#macro MoveSimplex(SimplexArray)

  #local BestIndex      = 0;
  #local BestValue      = 0;
  #local WorstIndex     = 0;
  #local WorstValue     = 0;
  #local NextWorstIndex = 0;
  #local NextWorstValue = 0;

  #local Crefl  =  1.0; // Reflection  coefficient
  #local Cexp   =  2.0; // Expansion   coefficient
  #local Ccontr = -0.5; // Contraction coefficient

  RankVertices(SimplexArray,
               BestIndex, BestValue,
               NextWorstIndex, NextWorstValue,
               WorstIndex, WorstValue)

  #local WorstVertex = SimplexArray[WorstIndex];
  #local Centroid = FindCentroid(SimplexArray, WorstVertex);
  #local NextIndex = WorstIndex;
  #local ReflPoint = ProjVertex(WorstVertex, Centroid, Crefl);
  #local ReflValue = UserFunction(ReflPoint);
  #if (ReflValue < BestValue)
    #if (Debug) #debug "Trying Expansion " #end // if
    #local ExpPoint = ProjVertex(WorstVertex, Centroid, Cexp);
    #local ExpValue = UserFunction(ExpPoint);
    #if (ExpValue < BestValue)
      #declare SimplexArray[NextIndex] = ExpPoint;
      #if (Debug) #debug "-> Expansion" #end // if
    #else
      #declare SimplexArray[NextIndex] = ReflPoint;
      #if (Debug) #debug "-> Reflection" #end // if
    #end
  #else
    #if (ReflValue < NextWorstValue)
      #declare SimplexArray[NextIndex] = ReflPoint;
      #if (Debug) #debug "Reflection" #end // if
    #else
      #if (Debug) #debug "Trying Contraction " #end // if
      #local ContrPoint = ProjVertex(WorstVertex, Centroid, Ccontr);
      #local ContrValue = UserFunction(ContrPoint);
      #if (ContrValue < WorstValue)
        #declare SimplexArray[NextIndex] = ContrPoint;
        #if (Debug) #debug "-> Contraction" #end // if
      #else
        #local BestVertex = SimplexArray[BestIndex];
        ShrinkSimplex(SimplexArray, BestVertex)
        #declare NextIndex = BestIndex;
        #if (Debug) #debug "-> Shrinking" #end // if
      #end // if
    #end // if
  #end // if

  NextIndex

#end // macro MoveSimplex


#macro FindMinima(SimplexArray, Epsilon, MaxIterations, Point, F_Value)

  #local LastFvalue = -1;
  #local Converged = false;

  #local IterCnt = 0;
  #while (IterCnt < MaxIterations & !Converged)
    #if (Debug)
      #debug concat("\nIteration: ", str(IterCnt, 0, -1), " ")
    #end // if
    #local PointIndex = MoveSimplex(SimplexArray);
    #declare Point = SimplexArray[PointIndex];
    #declare F_value = UserFunction(Point);
    #if (Debug)
      #debug "\n                                                        "
    #end // if
    #if (Debug) PrintVector(Point + y*F_value) #end // if
    #local Diff = LastFvalue - F_value;
    #if ((Diff >= 0) & (Diff < Epsilon))
      #if (Debug) #debug "\nConverged!\n" #end // if
      #local Converged = true;
    #end // if
    #local LastFvalue = F_value;
    #local IterCnt = IterCnt + 1;
  #end // while
  #if (Debug) #debug "\n" #end // if

  Converged

#end // macro FindMinima

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7
// Use of Nelder-Mead simplex method macros in 2D

#macro PointsCombine2D(PointArray, Epsilon, MaxIterations)

  #local NrOfPts = dimension_size(PointArray, 1);
  #local BestPoint = PointArray[0];
  #local LeastValue = UserFunction(PointArray[0]);

  #local Dimensions = 2;
  #local SimplexArray = array[Dimensions + 1]
  #local PtCnt1 = 0;
  #while (PtCnt1 < NrOfPts)
    #local SimplexArray[0] = PointArray[PtCnt1];
    #local PtCnt2 = PtCnt1 + 1;
    #while (PtCnt2 < NrOfPts)
    #local SimplexArray[1] = PointArray[PtCnt2];
      #local PtCnt3 = PtCnt2 + 1;
      #while (PtCnt3 < NrOfPts)
        #local SimplexArray[2] = PointArray[PtCnt3];
        #local GoodPoint = BestPoint; // Just to init it
        #local SmallValue = 0; // Just to init it
        #if (FindMinima(SimplexArray, Epsilon, MaxIterations,
                        GoodPoint, SmallValue))
          #local SmallValue = UserFunction(GoodPoint);
          // The above line should not be necessary (bug?)
        #end // if
          #if (Debug)
            #debug "                           "
            #debug "                           "
            PrintVector(GoodPoint)
            #debug "\n"
          #end // if
          #if (SmallValue < LeastValue)
            #local BestPoint = GoodPoint;
            #local LeastValue = SmallValue;
            #if (Debug)
              #debug "> ==== > ==== > ==== > ===="
              #debug "> ==== > ==== > ==== >     "
              #debug "Found a better point!\n"
            #end // if
          #end // if
        #local PtCnt3 = PtCnt3 + 1;
      #end // while
      #local PtCnt2 = PtCnt2 + 1;
    #end // while
    #local PtCnt1 = PtCnt1 + 1;
  #end // while
  #if (Debug) #debug "\n" #end // if

  BestPoint

#end // macro PointsCombine2D

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#declare Debug = false;

#declare PerfectPoint = PointsCombine2D(SplinePts, 0.0001, 50);
sphere { PerfectPoint, 0.2 pigment { color Red*2 } }

camera {
  location PerfectPoint + 4*y
  look_at PerfectPoint
}

background { color Blue/2 }

light_source { <10,  100, 10>, 1 }
light_source { <10, -100, 10>, 1 }

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7


Post a reply to this message

From: Peter Popov
Subject: Re: On Bezier splines
Date: 13 May 2000 15:46:02
Message: <i4crhsomu1v8s46k6duggi922d8l6ik0nu@4ax.com>
On Sat, 13 May 2000 02:01:00 +0200, Tor Olav Kristensen
<tto### [at] onlineno> wrote:

>
>Tor Olav Kristensen wrote:
>
>> Therefore I'm working on macros to implement the Nelder-
>> Mead simplex method to locate the minima of the "error field".
>
>And here they are.
>
>I'll try to explain later (if its necessary).

Thanks, man! I'll try to figure them out some time tomorrow and will
cry for help if necessary.


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] usanet
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

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