POV-Ray : Newsgroups : povray.advanced-users : Q: smooth union of bezier patches Server Time
2 Nov 2024 15:25:22 EDT (-0400)
  Q: smooth union of bezier patches (Message 1 to 10 of 13)  
Goto Latest 10 Messages Next 3 Messages >>>
From: ingo
Subject: Q: smooth union of bezier patches
Date: 23 Apr 1999 16:48:19
Message: <3720ce83.0@news.povray.org>
While exploring the bezier patches, I can not find a way to attatch two, non
flat, patches without a seam. To get an idea of what I'm trying run the included
scene.

Have been looking at the output of sPatch, but I'm still clueless.

ingo
--
Met dank aan de muze met het glazen oog.

#version 3.1;
global_settings{assumed_gamma 1.0}
light_source{<500,500,-500> rgb 1}
camera{
   location<0.0,3.5,-5.0>
   look_at<0.0,1.0, 0.0>
}
#macro GetRadius(R)
   #local Range=R*0.1;
   #local Variation=Range+((-Range)-Range)*rand(S);
   #declare Rr=R+Variation;
#end

#macro BuildArray(H,R,NrBPH,NrBPC)
// H= height; R= radius
// NrBPH= number of patches in height
// NrBPC= number of patches in circumference
   #local PH=((NrBPH*4)-NrBPH)+1;
   #local PC=((NrBPC*4)-NrBPC)+1;
   #local Ystep=H/PH;
   #local BP_arr=array[PH][PC]
   #local Ypos=0;
   #local I=0;
   #local J=0;
   #while (I<PH)
      #while (J<PC-1)
         #local Phi=J*(360/PC);
         GetRadius (R)
         #declare BP_arr[I][J]=vrotate(<Rr,Ypos,0>,<0,Phi,0>);
         #local J=J+1;
      #end
// closed shape so last point is first point.
      #local BP_arr[I][J]= BP_arr[I][0];
      #local J=0;
      #local Ypos=Ypos+Ystep;
      #local I=I+1;
   #end
   #declare OutArray= BP_arr
#end

#macro BuildPatch(InArray)
   #local PH= dimension_size (InArray,1);
   #local PC= dimension_size (InArray,2);
   #local I= 0;
   #local J= 0;
   #while (I<PH-1)
      #while (J<PC-1)
         bicubic_patch {
            type 1
            u_steps 4
            v_steps 4,
InArray[I][J],InArray[I][J+1],InArray[I][J+2],InArray[I][J+3],
InArray[I+1][J],InArray[I+1][J+1],InArray[I+1][J+2],InArray[I+1][J+3],
InArray[I+2][J],InArray[I+2][J+1],InArray[I+2][J+2],InArray[I+2][J+3],
InArray[I+3][J],InArray[I+3][J+1],InArray[I+3][J+2],InArray[I+3][J+3]
            pigment {rgb 1}
         }
         #local J=J+3;
      #end
      #local J=0;
      #local I=I+3;
   #end
#end

#declare S=seed(7);
BuildArray(3,2,5,10)
BuildPatch(OutArray)


Post a reply to this message

From: Ron Parker
Subject: Re: Q: smooth union of bezier patches
Date: 23 Apr 1999 17:24:15
Message: <3720d6ef.0@news.povray.org>
On Fri, 23 Apr 1999 21:48:09 +0200, ingo <ing### [at] ingodemonnl> wrote:
>While exploring the bezier patches, I can not find a way to attatch two, non
>flat, patches without a seam. To get an idea of what I'm trying run the included
>scene.

If you look at my IRTC entry for the january-february stills round, you'll 
find my bedsheet object, which is made out of a couple of hundred patches 
that are all joined smoothly.  Read the code and you might be able to get 
a feel for what needs to happen for it to work.  There's also a preview 
mode built-in to that .inc file that can show you the control mesh for all 
of the patches, which may help you follow along with the explanation I'm 
about to try to give.

First, let me try an appeal to 2d thinking.  If you've ever used a drawing
tool like Corel Draw or Illustrator or Photoshop's paths, you've probably
seen the 'barbells' that one uses to edit a node.  When the two arms of the
barbell form a straight line, the node is smooth.  "Break" the barbell, and
you get a point at that node.  Mathematically, the angle of the barbell 
represents the tangent to the curve at that point.  The length of the barbell
represents the "tension." If the tangents align, the curve is smooth (C1).
If the lengths are also the same, you have higher-order continuity (which 
may be important for certain lighting calculations.)

Okay, now for the ugly ASCII graphics.  If you're not reading this in a 
real newsreader, you may have to switch to a monospaced font now.

     X    #    #    X

X    O----X----X----O    X
     |    |    |    |
#    X----#----#----X    #
     |    |    |    |
#    X----#----#----X    #
     |    |    |    |
X    O----X----X----O    X

     X    #    #    X

That thing is supposed to be a single bicubic patch.  The unconnected 
symbols to all sides are supposed to be the points on adjacent patches.
Now, I'm going to ask you to change how you visualize a bicubic patch.  
Instead of looking at all those points as having equal stature, think 
of them as three different kinds of points. 

First, there are the points marked O.  These are the corners of the 
patches, and they're the only points you can absolutely guarantee the 
patch will intersect.  They are like the node points on your 2D spline 
curve.

Second, there are the points marked X.  You should look at the line
between an X and an O as a barbell, like the ones in your 2d drawing
program.  If each of the two barbells through an O is straight, the 
surface will be smooth at the point represented by the O.  If one or 
both of them is bent, you will have a seam at that point.

Finally, there are the points marked #.  The line between a # and an
X should also be looked at as a barbell, but you need to realize that
the patch doesn't necessarily pass through the point marked X at all.
Nevertheless, if the barbell through an X is not straight, there will 
be a seam along that edge of the patch.

So, in order to have smoothly-joined patches, you need only ensure 
that the overall control mesh doesn't bend at the patch edges.  If 
you look at the control mesh in my bedsheet code, you should see a
lot of straight lines, particularly around the bottom edges of the 
sheet.  You should also see that the point at the center of each of 
those lines is on the edge between two patches (edges are drawn in
a different color.)


Post a reply to this message

From: Ron Parker
Subject: Re: Q: smooth union of bezier patches
Date: 23 Apr 1999 17:40:59
Message: <3720dadb.0@news.povray.org>
On Fri, 23 Apr 1999 21:48:09 +0200, ingo <ing### [at] ingodemonnl> wrote:
>To get an idea of what I'm trying run the included

Okay, so now I'm assuming you've just read my tutorial on patches.
Here's the result of the tutorial as applied to your scene.  Take
note of the comments I've added.

#version 3.1;
global_settings{assumed_gamma 1.0}
light_source{<500,500,-500> rgb 1}
camera{
   location<0.0,3.5,-5.0>
   look_at<0.0,1.0, 0.0>
}
#macro GetRadius(R)
   #local Range=R*0.1;
   #local Variation=Range+((-Range)-Range)*rand(S);
   #declare Rr=R+Variation;
#end

#macro BuildArray(H,R,NrBPH,NrBPC)
// H= height; R= radius
// NrBPH= number of patches in height
// NrBPC= number of patches in circumference
   #local PH=((NrBPH*4)-NrBPH)+1;
   #local PC=((NrBPC*4)-NrBPC)+1;
   #local Ystep=H/PH;
// need one extra element in the array for C1 continuity.
   #local BP_arr=array[PH+1][PC+1]
   #local Ypos=0;
   #local I=0;
   #local J=0;
   #while (I<PH+1)
      #while (J<PC-1)
         #local Phi=J*(360/PC);
         GetRadius (R)
         #declare BP_arr[I][J]=vrotate(<Rr,Ypos,0>,<0,Phi,0>);
         #local J=J+1;
      #end
// closed shape so last point is first point.
      #local BP_arr[I][J]= BP_arr[I][0];
// the last-plus-one point must be the same as the second point, too.
      #local BP_arr[I][J+1]= BP_arr[I][1];
      #local J=0;
      #local Ypos=Ypos+Ystep;
      #local I=I+1;
   #end
   #declare OutArray= BP_arr
#end

#macro BuildPatch(InArray)
// the arrays were made an element larger, so here we must compensate.
   #local PH= dimension_size (InArray,1)-1;
   #local PC= dimension_size (InArray,2)-1;
   #local I= 0;
   #local J= 0;
   #while (I<PH-1)
      #while (J<PC-1)
         bicubic_patch {
            type 1
            u_steps 4
            v_steps 4,
InArray[I][J],InArray[I][J+1],
// notice that the third point in each row is constrained such
// that it, the last point in the row, and the second point
// in the equivalent row in the next patch are in a straight line.
2*InArray[I][J+3]-InArray[I][J+4],InArray[I][J+3],

InArray[I+1][J],InArray[I+1][J+1],
2*InArray[I+1][J+3]-InArray[I+1][J+4],InArray[I+1][J+3],

// notice, too, that each point in the entire third row is 
// constrained in this way with respect to the last row and 
// to the second row of the next patch.  Note the lack of any 
// +2 terms in the whole patch definition.  We calculated them 
// above, but we never use them because we no longer have as 
// much freedom as we did before we wanted smoothness.

2*InArray[I+3][J]-InArray[I+4][J],
2*InArray[I+3][J+1]-InArray[I+4][J+1],
2*(2*InArray[I+3][J+3]-InArray[I+4][J+3])-
  (2*InArray[I+3][J+4]-InArray[I+4][J+4]),
2*InArray[I+3][J+3]-InArray[I+4][J+3],

InArray[I+3][J],InArray[I+3][J+1],
2*InArray[I+3][J+3]-InArray[I+3][J+4],InArray[I+3][J+3]

            pigment {rgb 1}
         }
         #local J=J+3;
      #end
      #local J=0;
      #local I=I+3;
   #end
#end

#declare S=seed(7);
BuildArray(3,2,5,10)
BuildPatch(OutArray)


Post a reply to this message

From: ingo
Subject: Re: Q: smooth union of bezier patches
Date: 23 Apr 1999 18:39:28
Message: <3720e890.0@news.povray.org>
Thanks Ron, this clarifys a lot.
Let me recapitulate to be sure I understood. Instead of imagining a Bpatch as a
set of triangles, it can be seen as a grid of bezier-splines. To stitch two
patches together you have to make sure that the controllpoints on each side of a
node are in one line (like making a smooth prism object with bezier spline).

So to make my object, I have to generate a few smooth "circular" bezier splines
and a set of smooth splines "standing upright". Make a cylindrical grid with
these splines in sutch a way that the endpoints of the spline segements
intersect (the O's in your ascii art). And so on for the X's and #'s. I'll have
a look at your inc file later tonight (bad connection:(

ingo
--
Met dank aan de muze met het glazen oog.

Ron Parker heeft geschreven in bericht <3720d6ef.0@news.povray.org>...
>......


Post a reply to this message

From: ingo
Subject: Re: Q: smooth union of bezier patches
Date: 23 Apr 1999 18:55:21
Message: <3720ec49.0@news.povray.org>
Wow, it looks so easy, but sure gives me something to think about and play with
this weekend.

Thank you Ron, have a nice weekend,

ingo

--
Met dank aan de muze met het glazen oog.

Ron Parker heeft geschreven in bericht <3720dadb.0@news.povray.org>...
>On Fri, 23 Apr 1999 21:48:09 +0200, ingo <ing### [at] ingodemonnl> wrote:
>>To get an idea of what I'm trying run the included
>
>Okay, so now I'm assuming you've just read my tutorial on patches.
>Here's the result of the tutorial as applied to your scene.  Take
>note of the comments I've added.
>.........


Post a reply to this message

From: Phil Clute
Subject: Re: Q: smooth union of bezier patches
Date: 28 Apr 1999 14:32:00
Message: <3727477B.BAF70117@tiac.net>
I posted a similar question in the newusers group and Ken
directed me over here(thanks Ken). I don't usually view the
advanced group, as I am not a jedi yet. But I'm working on it.

Anyhow my question is: What is the math behind keeping those
seams together, and from causing cracks in the patch?

The reason I ask is because I wanted to try animating the patches.
The ultimate goal is to make a face that can change expressions etc.
But I'll settle for just a couple patches working in harmony for
now.

Note: I originally posted this question in newusers because I'm
slightly math impared. So go easy on me...<he he>
-- 
...coffee?...yes please! extra sugar,extra cream...Thank you.


Post a reply to this message

From: Nieminen Mika
Subject: Re: Q: smooth union of bezier patches
Date: 28 Apr 1999 15:17:14
Message: <372750aa.0@news.povray.org>
Just a side note:
  Morphing from one patch(group) to another might be possible with a (near)
future version of the Colefax's PCM macro. He is working on it.

-- 
main(i,_){for(_?--i,main(i+2,"FhhQHFIJD|FQTITFN]zRFHhhTBFHhhTBFysdB"[i]
):5;i&&_>1;printf("%s",_-70?_&1?"[]":" ":(_=0,"\n")),_/=2);} /*- Warp -*/


Post a reply to this message

From: Ron Parker
Subject: Re: Q: smooth union of bezier patches
Date: 28 Apr 1999 15:36:42
Message: <3727553a.0@news.povray.org>
On Wed, 28 Apr 1999 13:38:03 -0400, Phil Clute <plc### [at] tiacnet> wrote:
>Anyhow my question is: What is the math behind keeping those
>seams together, and from causing cracks in the patch?

I find that it helps to look at a collection of connected patches as
a solid mesh composed of quadrilateral (four-sided) elements, rather
than as a bunch of independent patches.  In my bedsheet code, I used
a whopping big array to store the control points for all of the 
patches.  

If you look at that code, you'll see a lot of 3's but not very many 
4's.  This might seem strange: after all, patches have a 4 x 4 array 
of control points, right?  So if you were going to have an n x n mesh
of patches, you would need a 4n x 4n array, right?  No.  You need a 
(3n+1) x (3n+1) array.  Why?  Because to keep from having cracks in
your mesh, you must ensure that all of the points (four altogether)
on the boundary between two patches are the same for both patches.

Here's an ugly ASCII-art representation of a 2 x 1 mesh of patches:

    0   1   2   3   4   5   6 

0   O---O---O---O---O---O---O
    |           |           |
    |           |           |
1   O   O   O   O   O   O   O
    |           |           |
    |           |           |
2   O   O   O   O   O   O   O
    |           |           |
    |           |           |
3   O---O---O---O---O---O---O

         (figure 1)

The lines mark patch boundaries.  The O's are control points.  The
numbers above and to the side are the indices of the points in the 
array.  Notice how every control point in column 3 is in both patches.  
As long as you adhere to this model, you can never have a crack in 
your patch mesh.

Now, let's draw that picture again, but with a 2 x 2 mesh:

    A###B...B###A###B...B###A
    #   |   |   #   |   |   #
    #   |   |   #   |   |   #
    B---C   C---B---C   C---B
    .           .           .
    .           .           .
    B---C   C---B---C   C---B
    #   |   |   #   |   |   #
    #   |   |   #   |   |   #
    A###B...B###A###B...B###A
    #   |   |   #   |   |   #
    #   |   |   #   |   |   #
    B---C   C---B---C   C---B
    .           .           .
    .           .           .
    B---C   C---B---C   C---B
    #   |   |   #   |   |   #
    #   |   |   #   |   |   #
    A###B...B###A###B...B###A

         (figure 2)

This is a little more complicated, because it's trying to get across
a more complicated point (I should really write this thing up as a web
page and put fancy graphics on it!)

The # signs are patch boundaries.  So are the dots.  The A's, B's,
and C's are control points.  The other lines mean something else.

A points are the corners.  It's already been noted that a patch will 
always intersect its corner points.  B points are the remaining edge
points.  They exert an influence on the slope of the patch at the
adjacent A point.  For the sake of discussion, these 'lines of 
influence' are represented by the # signs.  The dots are just there 
to show the patch boundaries.

C points are the interior points.  Each of them exerts an influence on 
the slope of the patch at two undetermined points along the edge of the
patch, roughly corresponding to the adjacent B points.

Now, the payoff: if you want your patches to abut smoothly, without a
visible crease at the edges, all you have to do is make sure that 
anywhere you see three control points joined by a straight line, 
which is to say a line of #'s, -'s, or |'s but not a line of dots,
all of those control points must be in a straight line in 3D space.  
This means that if you drew lines between their locations in 3D space,
you would not get a triangle but a straight line.

So, reverse your thinking about patches.  They're not a 4 x 4 mesh of
control points, or even a 3 x 3 mesh of 'grid squares'.  A patch mesh
consists of a grid of vertex points, represented by the points marked 
'A' in figure 2.  Each vertex point in the grid is surrounded by a 
cloud of up to eight control points that determine the shape of the 
surface at that point.  The points marked 'B' in figure 2 directly
determine the normal of the surface at the vertex, while the points
marked 'C' have a more indirect effect, specifying the evolution of
the surface as you move away from the vertex point in each direction.

There's something I haven't addressed in this discussion.  How do
you deal with a situation where your patches are not in a regular 
grid, as shown below:


      +----------+----------+
      |          #          |
      |          #    B     |
      |          #          |
      |    A     *----------+
      |          #          |
      |          #    C     |
      |          #          |
      +----------+----------+

My simplistic answer is "Don't do that!"  It might be possible to 
figure out the correct control points for patch A to make it pass
through the vertex marked *, but it'll be really hard to keep from
having a crack somewhere along the joint indicated with # signs.
Yes, it can be done.  It will put severe constraints on the edges
of the B and C patches that abut the A patch.  But the math is 
almost certainly quite nasty, and you'd probably be better off just 
splitting patch A in half.  If someone has some foolproof math for
this case, I'd like to see it too.


Post a reply to this message

From: Jerry Anning
Subject: Re: Q: smooth union of bezier patches
Date: 28 Apr 1999 17:41:19
Message: <37276c7c.7555182@news.povray.org>
On Wed, 28 Apr 1999 13:38:03 -0400, Phil Clute <plc### [at] tiacnet>
wrote:

>Anyhow my question is: What is the math behind keeping those
>seams together, and from causing cracks in the patch?
>
>The reason I ask is because I wanted to try animating the patches.
>The ultimate goal is to make a face that can change expressions etc.
>But I'll settle for just a couple patches working in harmony for
>now.

Just to amplify a bit or Ron Parker's answer.
Suppose that the edge in question and the adjacent control points in
each patch are as follows:

--a-----e     e-----i--
   |        |      |       |
   |        |      |       |
--b-----f      f------j--
   |        |      |       |
   |        |      |       |
--c-----g     g-----k--
   |        |      |       |
   |        |      |       |
--d-----h     h-----l--

Then a, e and i must be collinear.  So must b, f and j, c, g and k,
and d, g and ii.  This can sometimes constrain a surface too much, so
there is an alternative method of guaranteeing some continuity.  In
this case, the constraints are that a, e, i and f must be coplanar and
d, h, l and g must be coplanar and in this case b, c, j and k need not
be collinear with anything.

For what you describe yourself as wanting to do, you might want to
look into hierarchical b-splines, also known as h-splines.  As b
splines, the interpatch continuity is automatic.  B splines can also
be converted to beziers (so-called bicubic patches) with some
appropriate matrix math, but the process would probably not be
practical for speed and memory reasons without an external converter
or a patched pov that supports them directly.  

If you want to see some examples of h spline techniques, check out the
Dragon Wing at:
http://www.cs.ubc.ca/nest/imager/contributions/forsey/dragon/top.html

Jerry Anning
clem "at" dhol "dot" com


Post a reply to this message

From: Phil Clute
Subject: Re: Q: smooth union of bezier patches
Date: 29 Apr 1999 02:40:58
Message: <3727F251.FDBE6926@tiac.net>
Thanks for the help!
I can see I'm in over my head a bit though...
if nothing else I've learned something for future
attempts.

Jerry Anning posted(in this thread)a pretty cool
link about hierarchical b-splines. I wandered around
there for a long time. The face animations are worth
the short download.

-- 
...coffee?...yes please! extra sugar,extra cream...Thank you.


Post a reply to this message

Goto Latest 10 Messages Next 3 Messages >>>

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