/// <summary>
 /// Give two points in any order. Will always be ordered so
 /// that q.y > p.y and q.x > p.x if same y value
 /// </summary>
 ///
 public DTSweepConstraint(TriangulationPoint p1, TriangulationPoint p2) // throws DuplicatePointException
 {
     p = p1;
     q = p2;
     if (p1.getY() > p2.getY())
     {
         q = p1;
         p = p2;
     }
     else if (p1.getY() == p2.getY())
     {
         if (p1.getX() > p2.getX())
         {
             q = p1;
             p = p2;
         }
         else if (p1.getX() == p2.getX())
         {
             logger.Info("Failed to create constraint {}={}", p1, p2);
             //                throw new DuplicatePointException( p1 + "=" + p2 );
             //                return;
         }
     }
     q.addEdge(this);
 }
Beispiel #2
0
        /// <summary>
        /// This implementation will use simple node traversal algorithm to find a
        /// point on the front
        /// </summary>
        ///
        /// <param name="point"></param>
        public AdvancingFrontNode locatePoint(TriangulationPoint point)
        {
            double             px   = point.getX();
            AdvancingFrontNode node = findSearchNode(px);
            double             nx   = node.point.getX();

            if (px == nx)
            {
                if (point != node.point)
                {
                    // We might have two nodes with same x value for a short time
                    if (point == node.prev.point)
                    {
                        node = node.prev;
                    }
                    else if (point == node.next.point)
                    {
                        node = node.next;
                    }
                    else
                    {
                        throw new Exception("Failed to find Node for given afront point");
                        //                    node = null;
                    }
                }
            }
            else if (px < nx)
            {
                while ((node = node.prev) != null)
                {
                    if (point == node.point)
                    {
                        break;
                    }
                }
            }
            else
            {
                while ((node = node.next) != null)
                {
                    if (point == node.point)
                    {
                        break;
                    }
                }
            }
            search = node;
            return(node);
        }
Beispiel #3
0
        /// <summary>
        /// Find closes node to the left of the new point and create a new triangle.
        /// If needed new holes and basins will be filled to.
        /// </summary>
        ///
        /// <param name="tcx"></param>
        /// <param name="point"></param>
        ///
        private static AdvancingFrontNode pointEvent(DTSweepContext tcx,
                                                     TriangulationPoint point)
        {
            AdvancingFrontNode node, newNode;

            node = tcx.locateNode(point);
            if (tcx.isDebugEnabled())
            {
                tcx.getDebugContext().setActiveNode(node);
            }
            newNode = newFrontTriangle(tcx, point, node);

            // Only need to check +epsilon since point never have smaller
            // x value than node due to how we fetch nodes from the front
            if (point.getX() <= node.point.getX() + EPSILON)
            {
                fill(tcx, node);
            }
            tcx.addNode(newNode);

            fillAdvancingFront(tcx, newNode);
            return(newNode);
        }
Beispiel #4
0
        /// <summary>
        /// angle
        /// </summary>
        ///
        /// <param name="node">middle node</param>
        /// <returns>the angle between p-a and p-b in range [-pi,pi]</returns>
        ///
        private static double angle(TriangulationPoint p,
                                    TriangulationPoint a,
                                    TriangulationPoint b)
        {
            // XXX: do we really need a signed angle for holeAngle?
            //      could possible save some cycles here

            /* Complex plane
             * ab = cosA +i*sinA
             * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
             * atan2(y,x) computes the principal value of the argument function
             * applied to the complex number x+iy
             * Where x = ax*bx + ay*by
             *       y = ax*by - ay*bx
             */
            double px = p.getX();
            double py = p.getY();
            double ax = a.getX() - px;
            double ay = a.getY() - py;
            double bx = b.getX() - px;
            double by = b.getY() - py;

            return(Math.Atan2(ax * by - ay * bx, ax * bx + ay * by));
        }
Beispiel #5
0
 /// <summary>
 /// We use a balancing tree to locate a node smaller or equal to given key
 /// value.
 /// </summary>
 ///
 /// <param name="point"></param>
 public AdvancingFrontNode locateNode(TriangulationPoint point)
 {
     return(locateNode(point.getX()));
 }