POV-Ray : Newsgroups : povray.general : Surface from XYZ data Server Time
30 Jul 2024 20:25:37 EDT (-0400)
  Surface from XYZ data (Message 5 to 14 of 14)  
<<< Previous 4 Messages Goto Initial 10 Messages
From: Chris B
Subject: Re: Surface from XYZ data
Date: 14 Oct 2008 17:48:21
Message: <48f513a5$1@news.povray.org>
"New2Povray" <nomail@nomail> wrote in message 
news:web.48f4e301fc37f40429569840@news.povray.org...
> Hi all
>
> I am new to povray and have been trying to render a surface without much
> success,

Hi and Welcome.

> the surface could not be mathematically represented (will at least not
> in one piece) as a function,

I'll take your word for it :o)

The example pasted in below my signature illustrates one approach that you 
could quite easily use. I transformed your data into POV-Ray arrays, then 
used those arrays to build a POV-Ray mesh2 object. Transforming your data in 
this way is quite simple using an editor that supports columnar editing, 
such as the POV-Ray Windows editor. ie. to insert the commas you can click 
in the gap between two numbers in the top line, ctrl-shift-click in the 
corresponding position on the bottom line and type a comma. (repeat 7 times, 
once for each gap).

This example isn't smoothed and smoothing would require an extra chunk of 
code to calculate the mesh normals.

Alternatively you may wish to take a look at Mike Williams' excellent 
isosurface tutorial which provides a number of ways of combining functions 
(see http://www.econym.demon.co.uk/isotut/). You may find that you can 
programmatically 'chop' your different functions together.

If your full dataset follows a grid in the way this data does, you might 
want to consider writing the z values as a bitmap then using the image as a 
height field.

Regards,
Chris B.

// Example...

camera {location <0,0,-5> look_at 0}
light_source {<-10,20,-50>, rgb 1}

#declare GridSize = 7;
#declare PointCount = pow(GridSize,2);
#declare NumberOfFaces = 2*pow(GridSize-1,2);

#declare XCoord = array[PointCount] {

   -1.5000 , -1.0000 , -0.5000 ,       0  ,  0.5000 ,   1.0000  ,  1.5000 ,
   -1.5000 , -1.0000 , -0.5000 ,       0  ,  0.5000 ,   1.0000  ,  1.5000 ,
   -1.5000 , -1.0000 , -0.5000 ,       0  ,  0.5000 ,   1.0000  ,  1.5000 ,
   -1.5000 , -1.0000 , -0.5000 ,       0  ,  0.5000 ,   1.0000  ,  1.5000 ,
   -1.5000 , -1.0000 , -0.5000 ,       0  ,  0.5000 ,   1.0000  ,  1.5000 ,
   -1.5000 , -1.0000 , -0.5000 ,       0  ,  0.5000 ,   1.0000  ,  1.5000 ,
   -1.5000 , -1.0000 , -0.5000 ,       0  ,  0.5000 ,   1.0000  ,  1.5000 }

#declare YCoord = array[PointCount] {
   -1.5000 , -1.5000 , -1.5000 , -1.5000  , -1.5000 ,  -1.5000  , -1.5000 ,
   -1.0000 , -1.0000 , -1.0000 , -1.0000  , -1.0000 ,  -1.0000  , -1.0000 ,
   -0.5000 , -0.5000 , -0.5000 , -0.5000  , -0.5000 ,  -0.5000  , -0.5000 ,
         0 ,       0 ,       0 ,       0  ,       0 ,        0  ,       0 ,
    0.5000 ,  0.5000 ,  0.5000 ,  0.5000  ,  0.5000 ,   0.5000  ,  0.5000 ,
    1.0000 ,  1.0000 ,  1.0000 ,  1.0000  ,  1.0000 ,   1.0000  ,  1.0000 ,
    1.5000 ,  1.5000 ,  1.5000 ,  1.5000  ,  1.5000 ,   1.5000  ,  1.5000 }

#declare ZCoord = array[PointCount] {
    0.7781 ,  0.9975 ,  0.6816 ,       0  , -0.6816 ,  -0.9975  , -0.7781 ,
    0.9975 ,  0.8415 ,  0.4794 ,       0  , -0.4794 ,  -0.8415  , -0.9975 ,
    0.6816 ,  0.4794 ,  0.2474 ,       0  , -0.2474 ,  -0.4794  , -0.6816 ,
         0 ,       0 ,       0 ,       0  ,       0 ,        0  ,       0 ,
   -0.6816 , -0.4794 , -0.2474 ,       0  ,  0.2474 ,   0.4794  ,  0.6816 ,
   -0.9975 , -0.8415 , -0.4794 ,       0  ,  0.4794 ,   0.8415  ,  0.9975 ,
   -0.7781 , -0.9975 , -0.6816 ,       0  ,  0.6816 ,   0.9975  ,  0.7781 }

mesh2 {
  vertex_vectors {
    PointCount,
    #local I = 0;
    #while (I<PointCount)
      #if (I!=PointCount-1)
        <XCoord[I],YCoord[I],ZCoord[I]>,
      #else
        <XCoord[I],YCoord[I],ZCoord[I]>
      #end
      #local I = I + 1;
    #end
  }
  face_indices {
    NumberOfFaces
    #local I = 0;
    #while (I<GridSize-1)
      #local J = 0;
      #while (J<GridSize-1)
        #local K = I*(GridSize)+J;
        <K,K+1,K+GridSize>,
        #if (K!=NumberOfFaces-1)
          <K+1,K+GridSize+1,K+GridSize>,
        #else
          <K+1,K+GridSize+1,K+GridSize>
        #end
        #local J = J + 1;
      #end
      #local I = I + 1;
    #end
  }
  pigment {rgb 1}
}


Post a reply to this message

From: New2Povray
Subject: Re: Surface from XYZ data
Date: 14 Oct 2008 18:05:00
Message: <web.48f516cf825a59e12d75b4a20@news.povray.org>
Dear Christian

Thankyou for your help. The Z=sin(X*Y) function is for illustrative purposes
only and is not what I would like to plot. I can't fit a function to my
experimental data because of the noise - it can be approximated by a series of
Bessel functions of the second kind, but I would like to render the original
unaltered data only. I guess a way to do this as you hinted - is to output the
data as an image file from another program and use the pixel height to render
the surface. Though I would still like to know if there is another straight
forward way to render surfaces!

Cheers





Christian Froeschlin <chr### [at] chrfrde> wrote:
> > success, the surface could not be mathematically represented
>
> > Z=sin(X*Y).
>
> Looks like a mathematical representation to me. If your
> surface is of the form z=f(x,y) it can be rendered as an
> height_field object. Note that the function must be
> scaled such that z is in the range from 0.0 to 1.0.
>
> height_field
> {
>    function 512, 512 {0.5+0.5*sin(1.5*x*y)}
>    pigment {color White}
>    translate -0.5*x
> }


Post a reply to this message

From: New2Povray
Subject: Re: Surface from XYZ data
Date: 14 Oct 2008 19:00:00
Message: <web.48f52341825a59e16cefaa570@news.povray.org>
Hi Tim and Chris (and everyone else)

A massive thank you for everyone's help! I didn't notice there was a delay
between posting and messages appearing so I double posted, another true newbie
mistake. All solutions worked perfectly.

I have to admit, Povray is pretty addictive even after using it only for a day.


Post a reply to this message

From: Dan Connelly
Subject: Re: Surface from XYZ data
Date: 15 Oct 2008 09:19:45
Message: <48f5edf1@news.povray.org>
Chris B wrote:

> The example pasted in below my signature illustrates one approach that 
> you could quite easily use. I transformed your data into POV-Ray arrays, 
> then used those arrays to build a POV-Ray mesh2 object. Transforming 
> your data in this way is quite simple using an editor that supports 
> columnar editing, such as the POV-Ray Windows editor. ie. to insert the 
> commas you can click in the gap between two numbers in the top line, 
> ctrl-shift-click in the corresponding position on the bottom line and 
> type a comma. (repeat 7 times, once for each gap).
> 
> This example isn't smoothed and smoothing would require an extra chunk 
> of code to calculate the mesh normals.
> 

Very nice!

Couldn't one also use bicupic patches to attain smoothness?  I've not had luck with
them yet.  If I get time, I'll put together an example of where I have had trouble.

Dan


Post a reply to this message

From: Chris B
Subject: Re: Surface from XYZ data
Date: 15 Oct 2008 11:26:32
Message: <48f60ba8$1@news.povray.org>
"Dan Connelly" <djc### [at] yahoocom> wrote in message 
news:48f5edf1@news.povray.org...
> Chris B wrote:
>
>> The example pasted in below my signature illustrates one approach that 
>> you could quite easily use. I transformed your data into POV-Ray arrays, 
>> then used those arrays to build a POV-Ray mesh2 object.
>
> Couldn't one also use bicupic patches to attain smoothness?  I've not had 
> luck with them yet.  If I get time, I'll put together an example of where 
> I have had trouble.
>

I might be wrong (I've never used bicubic patches), but the documentation 
says that POV-Ray supports Bezier patches which, I think, means that you'd 
have to calculate a large number of Bezier control points that don't sit on 
the original curved surface. I'd guess that this would be quite tricky.

Regards,
Chris B.


Post a reply to this message

From: Warp
Subject: Re: Surface from XYZ data
Date: 15 Oct 2008 12:08:56
Message: <48f61598@news.povray.org>
Chris B <nom### [at] nomailcom> wrote:
> I might be wrong (I've never used bicubic patches), but the documentation 
> says that POV-Ray supports Bezier patches which, I think, means that you'd 
> have to calculate a large number of Bezier control points that don't sit on 
> the original curved surface. I'd guess that this would be quite tricky.

  Creating a bicubic patch which follows a given surface is not that hard.
The principle is rather simple:

- The four corner points sit on the original surface.

- Each corner point and an adjacent edge point of the bicubic patch define
  a line which is tangential to the surface at the location of the corner
  point.

- The four middle points work in the same way with their respective edge
  points, ie. they define the tangent vector of the surface at the edge point
  (although the generated surface doesn't necessarily go through this edge
  point).

- The only tricky thing is calculating the proper distance between corner
  points and their respective edge points, and the distance between the edge
  points and their respective center points. If I'm not mistaken, this
  distance is defined by the curvature of the surface at the corner point
  (or edge point in the latter case), ie. its second derivative.

  However, I think that in most cases it's enough to distribute all the
  points at (about) equal distances from each other. The possible error
  introduced by this probably isn't very large.

  This also gives the method for joining bicugic patches smoothly. Since
we know that the edge and center control points define the tangent of the
surface with their respective corner/edge points, adjacent bicubic patces
should have the same tangent direction at the shared control points.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: Surface from XYZ data
Date: 15 Oct 2008 12:12:43
Message: <48f6167b@news.povray.org>
Btw, it would be perfectly possible to create a POV-Ray macro which takes
a 2-dimensional array of 3D points (ie. basically a grid of points) and
which would then generate a smooth surface which goes through all these
points, by creating a bicubic patch for each group of four adjacent points
in the grid. The tangential control points can be easily calculated in such
a way that the resulting group of bicubic patches form a smooth surface
which goes through all the given points.

  I actually once started writing such a macro, but I never finished it.

-- 
                                                          - Warp


Post a reply to this message

From: Dan Connelly
Subject: Re: Surface from XYZ data
Date: 15 Oct 2008 12:25:02
Message: <48f6195e@news.povray.org>
I attempted a calculation of normal vectors for this mesh2 object.
--------------------------------------------
camera {location <0,0,-5> look_at 0}
light_source {<-10,20,-50>, rgb 1}

#declare GridSize = 7;
#declare PointCount = pow(GridSize,2);
#declare NumberOfFaces = 2*pow(GridSize-1,2);
#declare use_normal_vectors = 1;

#declare XCoord =
   array[PointCount] {
     -1.5, -1.0, -0.5, 0,  0.5,   1.0,  1.5,
     -1.5, -1.0, -0.5, 0,  0.5,   1.0,  1.5,
     -1.5, -1.0, -0.5, 0,  0.5,   1.0,  1.5,
     -1.5, -1.0, -0.5, 0,  0.5,   1.0,  1.5,
     -1.5, -1.0, -0.5, 0,  0.5,   1.0,  1.5,
     -1.5, -1.0, -0.5, 0,  0.5,   1.0,  1.5,
     -1.5, -1.0, -0.5, 0,  0.5,   1.0,  1.5
   }

#declare YCoord =
   array[PointCount] {
     -1.5, -1.5, -1.5, -1.5, -1.5,  -1.5, -1.5,
     -1.0, -1.0, -1.0, -1.0, -1.0,  -1.0, -1.0,
     -0.5, -0.5, -0.5, -0.5, -0.5,  -0.5, -0.5,
     0,   0,   0,   0,    0,    0 ,   0,
     0.5,  0.5,  0.5,  0.5,  0.5,   0.5,  0.5,
     1.0,  1.0,  1.0,  1.0,  1.0,   1.0,  1.0,
     1.5,  1.5,  1.5,  1.5,  1.5,   1.5,  1.5
   }

#declare ZCoord =
   array[PointCount] {
     0.7781,  0.9975,  0.6816, 0, -0.6816,  -0.9975, -0.7781,
     0.9975,  0.8415,  0.4794, 0, -0.4794,  -0.8415, -0.9975,
     0.6816,  0.4794,  0.2474, 0, -0.2474,  -0.4794, -0.6816,
     0,       0,       0,      0,       0,  0,       0,
     -0.6816, -0.4794, -0.2474, 0,  0.2474,   0.4794,  0.6816,
     -0.9975, -0.8415, -0.4794, 0,  0.4794,   0.8415,  0.9975,
     -0.7781, -0.9975, -0.6816, 0,  0.6816,   0.9975,   0.7781
   }

mesh2 {
   vertex_vectors {
     PointCount,
     #local I = 0;
     #while (I < PointCount)
       #if (I != PointCount-1)
	<XCoord[I],YCoord[I],ZCoord[I]>,
       #else
	<XCoord[I],YCoord[I],ZCoord[I]>
       #end
       #local I = I + 1;
     #end
   }
   #if (use_normal_vectors)
     normal_vectors {
       PointCount,
       #local I = 0;
       #while (I < GridSize)
	#local I1 = ((I = 0) ? 0 : I - 1);
	#local I2 = ((I = GridSize - 1) ? I : I + 1);

	#local J = 0;
	#while (J < GridSize)
	  #local J1  = ((J = 0) ? 0 : J - 1);
	  #local J2  = ((J = GridSize - 1) ? J : J + 1);

	  #local dx  = XCoord[I2 + J * GridSize] - XCoord[I1 + J * GridSize];
	  #local dy  = YCoord[I + J2 * GridSize] - YCoord[I + J1 * GridSize];
	  #local dzx = ZCoord[I2 + J * GridSize] - ZCoord[I1 + J * GridSize];
	  #local dzy = ZCoord[I + J2 * GridSize] - ZCoord[I + J1 * GridSize];
	  #local vnorm = vnormalize( vcross(<dx, 0, dzx>, <0, dy, dzy>) );
	  #if ((J < GridSize - 1) | (I < GridSize - 1))
	    vnorm,
	  #else
	    vnorm
	  #end
	  #local J = J + 1;
	#end
	#local I = I + 1;
       #end
     }
   #end
   face_indices {
     NumberOfFaces
     #local I = 0;
     #while (I<GridSize-1)
       #local J = 0;
       #while (J<GridSize-1)
	#local K = I*(GridSize)+J;
	<K,K+1,K+GridSize>,
	#if (K!=NumberOfFaces-1)
	  <K+1,K+GridSize+1,K+GridSize>,
	#else
	  <K+1,K+GridSize+1,K+GridSize>
	#end
	#local J = J + 1;
       #end
       #local I = I + 1;
     #end
   }
   pigment {rgb 1}
}


Post a reply to this message

From: Chris B
Subject: Re: Surface from XYZ data
Date: 15 Oct 2008 13:18:06
Message: <48f625ce$1@news.povray.org>
"Dan Connelly" <djc### [at] yahoocom> wrote in message 
news:48f6195e@news.povray.org...
>I attempted a calculation of normal vectors for this mesh2 object.

You just beat me to it :o)

We've both used very similar techniques. I was just investigating some dark 
lines that I get along the edges of the grid and light lines along the 
diagonals of the triangles (I notice you got them too), but I've concluded 
that it's just due to the fact that the z distances are relatively large.

Regards,
Chris B.


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Surface from XYZ data
Date: 15 Oct 2008 19:53:23
Message: <48f68273$1@news.povray.org>
Warp wrote:
>   Btw, it would be perfectly possible to create a POV-Ray macro which takes
> a 2-dimensional array of 3D points (ie. basically a grid of points) and
> which would then generate a smooth surface which goes through all these
> points, by creating a bicubic patch for each group of four adjacent points
> in the grid. The tangential control points can be easily calculated in such
> a way that the resulting group of bicubic patches form a smooth surface
> which goes through all the given points.
> 
>   I actually once started writing such a macro, but I never finished it.

I once made a set of macros that handles this.
Here are some images made with it:

http://home.online.no/~t-o-k/POV-Ray_Images/Bezier_Patches_Torus.jpg
http://home.online.no/~t-o-k/POV-Ray_Images/Bezier_Patches_UV-mapped.jpg
http://home.online.no/~t-o-k/POV-Ray_Images/Bezier_Patchwork.jpg
http://home.online.no/~t-o-k/POV-Ray_Images/Bezier_Patchwork_Ctrl_Grid.jpg
http://home.online.no/~t-o-k/POV-Ray_Images/Bezier_Patchwork_Top_View.jpg
http://home.online.no/~t-o-k/POV-Ray_Images/Bezier_Patches_Stitched.jpg
http://home.online.no/~t-o-k/POV-Ray_Images/Bezier_Patches_Stitched_.jpg

-- 
Tor Olav
http://subcube.com


Post a reply to this message

<<< Previous 4 Messages Goto Initial 10 Messages

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