POV-Ray : Newsgroups : povray.binaries.images : Beautiful maths : Beautiful maths Server Time
5 Nov 2024 06:17:35 EST (-0500)
  Beautiful maths  
From: Manuel Mata
Date: 16 Oct 2005 12:50:01
Message: <web.43528407e4ceb5f9bca0c7c30@news.povray.org>
Hi all. I know u probably dont like maths, but some times they are useful.

Here is a #macro to know if a point is inside a polygon. I hope it is useful
for you. I only translated the algorithm found in the web related in the
code to Pov-Ray, so if u find bugs report here. I think the code is well
commented ...

See ya. Here is the code.



// Persistence of Vision Ray Tracer Scene Description File
// File: pointinpolygon.pov
// Vers: 3.6
// Desc: Basic Scene Example
// Date: 16/10/2005
// Auth: Manuel Mata Rueda - http://www.mmata.org

#version 3.6;

#include "colors.inc"

#default{finish{ambient 1}}

camera{orthographic location <0,10,0> look_at <0,0,0>}

plane {y, 0 pigment { checker White,Gray80 }}
cylinder{0 z*10 0.05 pigment{Blue}}
cylinder{0 x*10 0.05 pigment{Red}}



//A macro to draw the spline
//--------------------------
//s spline
//i first point to draw
//j last point to draw
//step increment
//o object to put. A sphere in most cases
//c color
#macro drawSpline(s,i,j,step,o,c)
   union{
   #local counter=i;
   #while(counter<=j)
      object{o translate s(counter) pigment{c}}
      #local counter=counter+step;
   #end
   }
#end



/*

The algorithm is from http://www.alienryderflex.com/polygon/


// Globals which should be set before calling this function:
//
// int    polySides  =  how many corners the polygon has
// float  polyX[]    =  horizontal coordinates of corners
// float  polyY[]    =  vertical coordinates of corners
// float  x, y       =  point to be tested
//
// (Globals are used in this example for purposes of speed.
// Change as desired.)
//
// The function will return TRUE if the point x,y is inside the
// polygon, or FALSE if it is not. If the point x,y is exactly on
// the edge of the polygon, then the function may return TRUE or
// FALSE.
//
// Note that division by zero is avoided because the division is
// protected by the "if" clause which surrounds it.

boolean pointInPolygon() {

  int      i, j=0         ;
  boolean  oddNODES=FALSE ;

  for (i=0; i<polySides; i++) {
    j++;
    if (j==polySides) j=0;
    if (polyY[i]<y && polyY[j]>=y || polyY[j]<y && polyY[i]>=y) {
      if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x) {
        oddNODES=!oddNODES;
      }
    }
  }

  return oddNODES;
}
*/

#macro pointInPolygon(s,p,n)
  #local polySides=n;
  #local i=0;
  #local j=0;
  #local oddNodes=false;
  #while(i<polySides)
    #local j=j+1;
    #if(j=polySides) #local j=0; #end
    #if((s(i/polySides).z<p.z & s(j/polySides).z>=p.z) |
(s(j/polySides).z<p.z & s(i/polySides).z>=p.z))

#if(s(i/polySides).x+(p.z-s(i/polySides).z)/(s(j/polySides).z-s(i/polySides).z)*(s(j/polySides).x-s(i/polySides).x)<p.x
)
        #local oddNodes=!oddNodes;
      #end
    #end
    #local i=i+1;
  #end
  oddNodes;
#end



//Lets declare some splines
//-------------------------

#declare s1_firstPoint=<3,0,-2>;
#declare s1_nPoints=4;
#declare s1=spline{
linear_spline
 0    s1_firstPoint
,0.25 <3,0,3>
,0.5  <-2,0,1>
,0.75 <-1,0,-3>
,1    s1_firstPoint
}

#declare s2_firstPoint=<-3,0,-3>;
#declare s2_nPoints=5;
#declare s2=spline{
linear_spline
 0   s2_firstPoint
,0.2 <3,0,-1>
,0.4 <4,0,3>
,0.6 <-1,0,-1>
,0.8 <-3,0,2>
,1   s2_firstPoint
}





// What spline we use ?
//---------------------
#declare splineToUse=s2;
#declare nPoints=s2_nPoints;


// Ok lets work with that spline then
//-----------------------------------
object{drawSpline(splineToUse,0,1,0.001,sphere{0 0.05},rgb <0,0,0>)}



// Lets place a lot of points
// and see if are into the polygon
//--------------------------------
#local rangeLeftX=-4;
#local rangeLeftZ=-4;
#local rangeRightX=4;
#local rangeRightZ=4;
#local step=0.25;
#local i=rangeLeftX;
#local j=rangeLeftZ;
#while (i<=rangeRightX)
  #while (j<=rangeRightZ)
        object{
          sphere{0 0.1}
          #local isInside=pointInPolygon(splineToUse,<i,0.5,j>,nPoints);
          #if (isInside) pigment{Yellow}
          #else pigment{Pink}
          #end
          translate <i,0,j>
        }
    #local j=j+step;
  #end
  #local j=rangeLeftZ;
  #local i=i+step;
#end


Post a reply to this message


Attachments:
Download 'pointinpolygon00.png' (75 KB)

Preview of image 'pointinpolygon00.png'
pointinpolygon00.png


 

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