Revision: 54530
          http://brlcad.svn.sourceforge.net/brlcad/?rev=54530&view=rev
Author:   indianlarry
Date:     2013-03-05 11:25:15 +0000 (Tue, 05 Mar 2013)
Log Message:
-----------
Determine circumcircle during sweep adding event to close points when height of 
circumcircle is reached.  Current methodology was solely using angles between 
neighbors on the advancing front occasionally causing non-conforming triangles 
to be formed.

Modified Paths:
--------------
    brlcad/trunk/src/other/poly2tri/poly2tri/sweep/advancing_front.h
    brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.cc
    brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.h

Modified: brlcad/trunk/src/other/poly2tri/poly2tri/sweep/advancing_front.h
===================================================================
--- brlcad/trunk/src/other/poly2tri/poly2tri/sweep/advancing_front.h    
2013-03-04 22:30:23 UTC (rev 54529)
+++ brlcad/trunk/src/other/poly2tri/poly2tri/sweep/advancing_front.h    
2013-03-05 11:25:15 UTC (rev 54530)
@@ -47,12 +47,15 @@
   Node* prev;
 
   double value;
+  double angle;
+  bool circum;
+  double circumheight;
 
-  Node(Point& p) : point(&p), triangle(NULL), next(NULL), prev(NULL), 
value(p.x)
+  Node(Point& p) : point(&p), triangle(NULL), next(NULL), prev(NULL), 
value(p.x), circum(false)
   {
   }
 
-  Node(Point& p, Triangle& t) : point(&p), triangle(&t), next(NULL), 
prev(NULL), value(p.x)
+  Node(Point& p, Triangle& t) : point(&p), triangle(&t), next(NULL), 
prev(NULL), value(p.x), circum(false)
   {
   }
 

Modified: brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.cc
===================================================================
--- brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.cc     2013-03-04 
22:30:23 UTC (rev 54529)
+++ brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.cc     2013-03-05 
11:25:15 UTC (rev 54530)
@@ -28,6 +28,7 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+#include <float.h>
 #include <stdexcept>
 #include "sweep.h"
 #include "sweep_context.h"
@@ -51,8 +52,13 @@
 
 void Sweep::SweepPoints(SweepContext& tcx, int num_points)
 {
-  for (size_t i = 1; i < tcx.point_count(); i++) {
+  double currentheight = tcx.GetPoint(0)->y;
+  for (size_t i = 1; (i < tcx.point_count()) && (i <= num_points); i++) {
     Point& point = *tcx.GetPoint(i);
+    if (point.y > currentheight) {
+      CheckCircleEvent(tcx,point.y);
+      currentheight = point.y;
+    }
     Node* node = &PointEvent(tcx, point);
     for (size_t j = 0; j < point.edge_list.size(); j++) {
       EdgeEvent(tcx, point.edge_list[j], node);
@@ -213,6 +219,14 @@
   node.next->prev = new_node;
   node.next = new_node;
 
+  if (new_node->next)
+    UpdateNodeAngleCircum(*new_node->next);
+    
+  UpdateNodeAngleCircum(*new_node);
+  
+  if (new_node->prev)
+    UpdateNodeAngleCircum(*new_node->prev);
+
   if (!Legalize(tcx, *triangle)) {
     tcx.MapTriangleToNodes(*triangle);
   }
@@ -220,6 +234,25 @@
   return *new_node;
 }
 
+void Sweep::UpdateNodeAngleCircum(Node& n)
+{
+  if (n.next && n.prev) {
+    Point* nextPoint = n.next->point;
+    Point* prevPoint = n.prev->point;
+
+    n.angle = Angle(*n.point, *nextPoint, *prevPoint);
+
+    if ((n.angle > 0) && (n.angle < M_PI)) {
+      Point center;
+      double radius;
+      n.circum = Circumcircle(*n.point, *nextPoint, *prevPoint, center, 
radius);
+      if (n.circum) {
+        n.circumheight = center.y + radius;
+      }
+    }
+  }
+}
+
 void Sweep::Fill(SweepContext& tcx, Node& node)
 {
   Triangle* triangle = new Triangle(*node.prev->point, *node.point, 
*node.next->point);
@@ -234,6 +267,11 @@
   // Update the advancing front
   node.prev->next = node.next;
   node.next->prev = node.prev;
+  if (node.next)
+    UpdateNodeAngleCircum(*node.next);
+    
+  if (node.prev)
+    UpdateNodeAngleCircum(*node.prev);
 
   // If it was legalized the triangle has already been mapped
   if (!Legalize(tcx, *triangle)) {
@@ -242,11 +280,27 @@
 
 }
 
+void Sweep::CheckCircleEvent(SweepContext& tcx, double currentheight)
+{
+  Node *node = tcx.front()->head();
+
+  while (node->next) {
+    // if HoleAngle exceeds 90 degrees then break.
+    if (node->circum && (node->circumheight < currentheight)) {
+      Fill(tcx, *node);
+      node = node->prev;
+    } else {
+      node = node->next;
+    }
+  }
+}
+
 void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
 {
 
   // Fill right holes
   Node* node = n.next;
+  Node* leftboundnode = NULL;
 
   while (node->next) {
     // if HoleAngle exceeds 90 degrees then break.
@@ -265,6 +319,25 @@
     node = node->prev;
   }
 
+  node = n.prev;
+  if (node->point->x < n.point->x) {
+    node = node->prev;
+    while (node) {
+      // if HoleAngle exceeds 90 degrees then break.
+      if (node->point->x >= n.point->x) {
+        leftboundnode = node;
+      }
+      node = node->prev;
+    }
+    if (leftboundnode) {
+      node = n.prev;
+      while (node != leftboundnode) {
+        Fill(tcx, *node);
+        node = node->prev;
+      }
+    }
+  }
+
   // Fill right basins
   if (n.next && n.next->next) {
     double angle = BasinAngle(n);
@@ -279,7 +352,7 @@
 
   Node* nextNode = node->next;
   Node* prevNode = node->prev;
-  if (!AngleExceeds90Degrees(node->point, nextNode->point, prevNode->point))
+  if (!AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, 
prevNode->point))
           return false;
 
   // Check additional points on front.
@@ -414,6 +487,32 @@
   return false;
 }
 
+bool Sweep::Circumcircle(const Point& a, const Point& b, const Point& c, 
Point& center, double &radius)
+{
+  double cross_product = Cross(a - b,b - c);
+
+  if (cross_product > DBL_MIN) {
+    double cp2 = cross_product * cross_product;
+    double dotp_a = Dot(a - b,a - c);
+    double dotp_b = Dot(b - a,b - c);
+    double dotp_c = Dot(c - a,c - b);
+    double ablen = (a -b).Length();
+    double bclen = (b-c).Length();
+    double calen = (c-a).Length();
+
+    radius = ablen * bclen * calen / (2.0 * cross_product);
+
+    double alpha = bclen * bclen * dotp_a / (2.0 * cp2);
+    double beta = calen * calen * dotp_b / (2.0 * cp2);
+    double gamma = ablen * ablen * dotp_c / (2.0 * cp2);
+
+    center = alpha * a + beta * b + gamma * c;
+  } else {
+    return  false;
+  }
+  return true;
+}
+
 bool Sweep::Incircle(Point& pa, Point& pb, Point& pc, Point& pd)
 {
   double adx = pa.x - pd.x;

Modified: brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.h
===================================================================
--- brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.h      2013-03-04 
22:30:23 UTC (rev 54529)
+++ brlcad/trunk/src/other/poly2tri/poly2tri/sweep/sweep.h      2013-03-05 
11:25:15 UTC (rev 54530)
@@ -105,7 +105,7 @@
    * @return
    */
   Node& NewFrontTriangle(SweepContext& tcx, Point& point, Node& node);
-
+  void UpdateNodeAngleCircum(Node& n);
   /**
    * Adds a triangle to the advancing front to fill a hole.
    * @param tcx
@@ -143,6 +143,7 @@
    * @return true if d is inside circle, false if on circle edge
    */
   bool Incircle(Point& pa, Point& pb, Point& pc, Point& pd);
+  bool Circumcircle(const Point& pa, const Point& pb, const Point& pc, Point& 
center, double& radius);
 
   /**
    * Rotates a triangle pair one vertex CW
@@ -167,6 +168,7 @@
    * @param tcx
    * @param n
    */
+  void CheckCircleEvent(SweepContext& tcx, double currentheight);
   void FillAdvancingFront(SweepContext& tcx, Node& n);
 
   // Decision-making about when to Fill hole.

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to