planetri.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 
62 #include "planetri.h"
63 
64 namespace ConvexDecomposition
65 {
66 
67 
68 static inline double DistToPt(const double *p,const double *plane)
69 {
70  double x = p[0];
71  double y = p[1];
72  double z = p[2];
73  double d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3];
74  return d;
75 }
76 
77 
78 static PlaneTriResult getSidePlane(const double *p,const double *plane,double epsilon)
79 {
80 
81  double d = DistToPt(p,plane);
82 
83  if ( (d+epsilon) > 0 )
84  return PTR_FRONT; // it is 'in front' within the provided epsilon value.
85 
86  return PTR_BACK;
87 }
88 
89 static void add(const double *p,double *dest,unsigned int tstride,unsigned int &pcount)
90 {
91  char *d = (char *) dest;
92  d = d + pcount*tstride;
93  dest = (double *) d;
94  dest[0] = p[0];
95  dest[1] = p[1];
96  dest[2] = p[2];
97  pcount++;
98  assert( pcount <= 4 );
99 }
100 
101 
102 // assumes that the points are on opposite sides of the plane!
103 static void intersect(const double *p1,const double *p2,double *split,const double *plane)
104 {
105 
106  double dp1 = DistToPt(p1,plane);
107  double dp2 = DistToPt(p2,plane);
108 
109  double dir[3];
110 
111  dir[0] = p2[0] - p1[0];
112  dir[1] = p2[1] - p1[1];
113  dir[2] = p2[2] - p1[2];
114 
115  double dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2];
116  double dot2 = dp1 - plane[3];
117 
118  double t = -(plane[3] + dot2 ) / dot1;
119 
120  split[0] = (dir[0]*t)+p1[0];
121  split[1] = (dir[1]*t)+p1[1];
122  split[2] = (dir[2]*t)+p1[2];
123 
124 }
125 
126 #define MAXPTS 256
127 
128 class point
129 {
130 public:
131 
132  void set(const double *p)
133  {
134  x = p[0];
135  y = p[1];
136  z = p[2];
137  }
138 
139  double x;
140  double y;
141  double z;
142 };
143 class polygon
144 {
145 public:
146  polygon(void)
147  {
148  mVcount = 0;
149  }
150 
151  polygon(const double *p1,const double *p2,const double *p3)
152  {
153  mVcount = 3;
154  mVertices[0].set(p1);
155  mVertices[1].set(p2);
156  mVertices[2].set(p3);
157  }
158 
159 
160  int NumVertices(void) const { return mVcount; };
161 
162  const point& Vertex(int index)
163  {
164  if ( index < 0 ) index+=mVcount;
165  return mVertices[index];
166  };
167 
168 
169  void set(const point *pts,int count)
170  {
171  for (int i=0; i<count; i++)
172  {
173  mVertices[i] = pts[i];
174  }
175  mVcount = count;
176  }
177 
178  int mVcount;
180 };
181 
182 class plane
183 {
184 public:
185  plane(const double *p)
186  {
187  normal.x = p[0];
188  normal.y = p[1];
189  normal.z = p[2];
190  D = p[3];
191  }
192 
193  double Classify_Point(const point &p)
194  {
195  return p.x*normal.x + p.y*normal.y + p.z*normal.z + D;
196  }
197 
199  double D;
200 };
201 
202 void Split_Polygon(polygon *poly, plane *part, polygon &front, polygon &back)
203 {
204  int count = poly->NumVertices ();
205  int out_c = 0, in_c = 0;
206  point ptA, ptB,outpts[MAXPTS],inpts[MAXPTS];
207  double sideA, sideB;
208  ptA = poly->Vertex (count - 1);
209  sideA = part->Classify_Point (ptA);
210  for (int i = -1; ++i < count;)
211  {
212  ptB = poly->Vertex(i);
213  sideB = part->Classify_Point(ptB);
214  if (sideB > 0)
215  {
216  if (sideA < 0)
217  {
218  point v;
219  intersect(&ptB.x, &ptA.x, &v.x, &part->normal.x );
220  outpts[out_c++] = inpts[in_c++] = v;
221  }
222  outpts[out_c++] = ptB;
223  }
224  else if (sideB < 0)
225  {
226  if (sideA > 0)
227  {
228  point v;
229  intersect(&ptB.x, &ptA.x, &v.x, &part->normal.x );
230  outpts[out_c++] = inpts[in_c++] = v;
231  }
232  inpts[in_c++] = ptB;
233  }
234  else
235  outpts[out_c++] = inpts[in_c++] = ptB;
236  ptA = ptB;
237  sideA = sideB;
238  }
239 
240  front.set(&outpts[0], out_c);
241  back.set(&inpts[0], in_c);
242 }
243 
244 PlaneTriResult planeTriIntersection(const double *_plane, // the plane equation in Ax+By+Cz+D format
245  const double *triangle, // the source triangle.
246  unsigned int tstride, // stride in bytes of the input and output *vertices*
247  double epsilon, // the co-planer epsilon value.
248  double *front, // the triangle in front of the
249  unsigned int &fcount, // number of vertices in the 'front' triangle
250  double *back, // the triangle in back of the plane
251  unsigned int &bcount) // the number of vertices in the 'back' triangle.
252 {
253 
254  fcount = 0;
255  bcount = 0;
256 
257  const char *tsource = (const char *) triangle;
258 
259  // get the three vertices of the triangle.
260  const double *p1 = (const double *) (tsource);
261  const double *p2 = (const double *) (tsource+tstride);
262  const double *p3 = (const double *) (tsource+tstride*2);
263 
264 
265  PlaneTriResult r1 = getSidePlane(p1,_plane,epsilon); // compute the side of the plane each vertex is on
266  PlaneTriResult r2 = getSidePlane(p2,_plane,epsilon);
267  PlaneTriResult r3 = getSidePlane(p3,_plane,epsilon);
268 
269  if ( r1 == r2 && r1 == r3 ) // if all three vertices are on the same side of the plane.
270  {
271  if ( r1 == PTR_FRONT ) // if all three are in front of the plane, then copy to the 'front' output triangle.
272  {
273  add(p1,front,tstride,fcount);
274  add(p2,front,tstride,fcount);
275  add(p3,front,tstride,fcount);
276  }
277  else
278  {
279  add(p1,back,tstride,bcount); // if all three are in 'back' then copy to the 'back' output triangle.
280  add(p2,back,tstride,bcount);
281  add(p3,back,tstride,bcount);
282  }
283  return r1; // if all three points are on the same side of the plane return result
284  }
285 
286 
287  polygon pi(p1,p2,p3);
288  polygon pfront,pback;
289 
290  plane part(_plane);
291  Split_Polygon(&pi,&part,pfront,pback);
292 
293  for (int i=0; i<pfront.mVcount; i++)
294  {
295  add( &pfront.mVertices[i].x, front, tstride, fcount );
296  }
297 
298  for (int i=0; i<pback.mVcount; i++)
299  {
300  add( &pback.mVertices[i].x, back, tstride, bcount );
301  }
302 
304 
305  if ( fcount == 0 && bcount )
306  ret = PTR_BACK;
307 
308  if ( bcount == 0 && fcount )
309  ret = PTR_FRONT;
310 
311  return ret;
312 }
313 
314 };
ConvexDecomposition::plane::Classify_Point
double Classify_Point(const point &p)
Definition: planetri.cpp:193
ConvexDecomposition::plane::normal
point normal
Definition: planetri.cpp:198
ConvexDecomposition::polygon::set
void set(const point *pts, int count)
Definition: planetri.cpp:169
ConvexDecomposition::polygon::polygon
polygon(void)
Definition: planetri.cpp:146
ConvexDecomposition::PTR_SPLIT
@ PTR_SPLIT
Definition: planetri.h:67
ConvexDecomposition::polygon
Definition: planetri.cpp:143
ConvexDecomposition::polygon::mVertices
point mVertices[MAXPTS]
Definition: planetri.cpp:179
ConvexDecomposition::polygon::NumVertices
int NumVertices(void) const
Definition: planetri.cpp:160
planetri.h
ConvexDecomposition::polygon::mVcount
int mVcount
Definition: planetri.cpp:178
ConvexDecomposition::point::set
void set(const double *p)
Definition: planetri.cpp:132
ConvexDecomposition::plane::plane
plane(const double *p)
Definition: planetri.cpp:185
ConvexDecomposition::point::x
double x
Definition: planetri.cpp:139
ConvexDecomposition::Split_Polygon
void Split_Polygon(polygon *poly, plane *part, polygon &front, polygon &back)
Definition: planetri.cpp:202
ConvexDecomposition
Definition: bestfit.cpp:75
ConvexDecomposition::intersect
static void intersect(const double *p1, const double *p2, double *split, const double *plane)
Definition: concavity.cpp:134
ConvexDecomposition::polygon::Vertex
const point & Vertex(int index)
Definition: planetri.cpp:162
ConvexDecomposition::point::y
double y
Definition: planetri.cpp:140
ConvexDecomposition::PlaneTriResult
PlaneTriResult
Definition: planetri.h:63
ConvexDecomposition::PTR_FRONT
@ PTR_FRONT
Definition: planetri.h:65
MAXPTS
#define MAXPTS
Definition: planetri.cpp:126
ConvexDecomposition::plane::D
double D
Definition: planetri.cpp:199
ConvexDecomposition::PTR_BACK
@ PTR_BACK
Definition: planetri.h:66
ConvexDecomposition::plane
Definition: planetri.cpp:182
ConvexDecomposition::polygon::polygon
polygon(const double *p1, const double *p2, const double *p3)
Definition: planetri.cpp:151
ConvexDecomposition::point::z
double z
Definition: planetri.cpp:141
ConvexDecomposition::point
Definition: planetri.cpp:128
ConvexDecomposition::DistToPt
static double DistToPt(const double *p, const double *plane)
Definition: concavity.cpp:124
ConvexDecomposition::planeTriIntersection
PlaneTriResult planeTriIntersection(const double *_plane, const double *triangle, unsigned int tstride, double epsilon, double *front, unsigned int &fcount, double *back, unsigned int &bcount)
Definition: planetri.cpp:244
ConvexDecomposition::getSidePlane
static PlaneTriResult getSidePlane(const double *p, const double *plane, double epsilon)
Definition: planetri.cpp:78
ConvexDecomposition::add
static void add(const double *p, double *dest, unsigned int tstride, unsigned int &pcount)
Definition: planetri.cpp:89


convex_decomposition
Author(s): John W. Ratcliff
autogenerated on Wed Mar 2 2022 00:04:59