Exemple #1
0
        internal SweepComparator(com.epl.geometry.EditShape shape, double tol, bool bIsSimple)
            : base(true)
        {
            m_shape                   = shape;
            m_sweep_y                 = com.epl.geometry.NumberUtils.TheNaN;
            m_sweep_x                 = 0;
            m_prev_x                  = 0;
            m_prev_y                  = com.epl.geometry.NumberUtils.TheNaN;
            m_tolerance               = tol;
            m_tolerance_10            = 10 * tol;
            m_prevx_2                 = com.epl.geometry.NumberUtils.TheNaN;
            m_prevx_1                 = com.epl.geometry.NumberUtils.TheNaN;
            m_b_intersection_detected = false;
            m_prev_1                  = -1;
            m_prev_2                  = -1;
            m_vertex_1                = -1;
            m_vertex_2                = -1;
            m_current_node            = -1;
            m_b_is_simple             = bIsSimple;
            m_temp_simple_edge_1      = new com.epl.geometry.SweepComparator.SimpleEdge();
            m_temp_simple_edge_2      = new com.epl.geometry.SweepComparator.SimpleEdge();
            int s = System.Math.Min(shape.GetTotalPointCount() * 3 / 2, (int)(67));
            /* SIMPLEDGE_CACHESIZE */
            int cache_size = System.Math.Min((int)7, s);

            // m_simple_edges_buffer.reserve(cache_size);//must be reserved and
            // never grow beyond reserved size
            m_simple_edges_buffer  = new System.Collections.Generic.List <com.epl.geometry.SweepComparator.SimpleEdge>();
            m_simple_edges_recycle = new System.Collections.Generic.List <com.epl.geometry.SweepComparator.SimpleEdge>();
            m_simple_edges_cache   = new System.Collections.Generic.List <com.epl.geometry.SweepComparator.SimpleEdge>();
            for (int i = 0; i < cache_size; i++)
            {
                m_simple_edges_cache.Add(null);
            }
        }
Exemple #2
0
        // The value has not been cached
        // Creates a cached edge. May fail and return NULL.
        internal virtual com.epl.geometry.SweepComparator.SimpleEdge TryCreateCachedEdge_(int value)
        {
            int ind = (value & com.epl.geometry.NumberUtils.IntMax()) % m_simple_edges_cache.Count;

            com.epl.geometry.SweepComparator.SimpleEdge se = m_simple_edges_cache[ind];
            if (se == null)
            {
                if ((m_simple_edges_recycle.Count == 0))
                {
                    // assert(m_simple_edges_buffer.size() <
                    // m_simple_edges_buffer.capacity());//should never happen
                    // assert(m_simple_edges_buffer.size() <
                    // m_simple_edges_cache.size());//should never happen
                    m_simple_edges_buffer.Add(new com.epl.geometry.SweepComparator.SimpleEdge());
                    se = m_simple_edges_buffer[m_simple_edges_buffer.Count - 1];
                }
                else
                {
                    se = m_simple_edges_recycle[m_simple_edges_recycle.Count - 1];
                    m_simple_edges_recycle.RemoveAt(m_simple_edges_recycle.Count - 1);
                }
                se.m_value = value;
                m_simple_edges_cache[ind] = se;
                return(se);
            }
            else
            {
                System.Diagnostics.Debug.Assert((se.m_value != value));
            }
            // do not call TryCreateCachedEdge
            // twice.
            return(null);
        }
Exemple #3
0
        // Removes cached edge from the cache for the given value.
        internal virtual void TryDeleteCachedEdge_(int value)
        {
            int ind = (value & com.epl.geometry.NumberUtils.IntMax()) % m_simple_edges_cache.Count;

            com.epl.geometry.SweepComparator.SimpleEdge se = m_simple_edges_cache[ind];
            if (se != null && se.m_value == value)
            {
                // this value is cached
                m_simple_edges_recycle.Add(se);
                m_simple_edges_cache[ind] = null;
            }
        }
Exemple #4
0
 // Index 1 corresponds to the left segments, index 2 - right, e.g. m_line_1,
 // m_line_2
 // Returns a cached edge for the given value. May return NULL.
 internal virtual com.epl.geometry.SweepComparator.SimpleEdge TryGetCachedEdge_(int value)
 {
     com.epl.geometry.SweepComparator.SimpleEdge se = m_simple_edges_cache[(value & com.epl.geometry.NumberUtils.IntMax()) % m_simple_edges_cache.Count];
     if (se != null)
     {
         if (se.m_value == value)
         {
             return(se);
         }
     }
     // int i = 0;
     // cache collision
     return(null);
 }
Exemple #5
0
 internal virtual void InitSimpleEdge_(com.epl.geometry.SweepComparator.SimpleEdge se, int vertex)
 {
     se.m_segment = m_shape.GetSegment(vertex);
     se.m_b_curve = se.m_segment != null;
     if (!se.m_b_curve)
     {
         m_shape.QueryLineConnector(vertex, se.m_line);
         se.m_segment = se.m_line;
         se.m_env.SetCoordsNoNaN_(se.m_line.GetStartX(), se.m_line.GetEndX());
         se.m_env.vmax += m_tolerance;
         se.m_line.OrientBottomUp_();
         se.m_b_horizontal = se.m_line.GetEndY() == se.m_line.GetStartY();
         if (!se.m_b_horizontal)
         {
             se.m_dxdy = (se.m_line.GetEndX() - se.m_line.GetStartX()) / (se.m_line.GetEndY() - se.m_line.GetStartY());
         }
     }
 }
Exemple #6
0
        internal virtual int CompareNonHorizontal_(com.epl.geometry.SweepComparator.SimpleEdge line_1, com.epl.geometry.SweepComparator.SimpleEdge line_2)
        {
            if (line_1.m_line.GetStartY() == line_2.m_line.GetStartY() && line_1.m_line.GetStartX() == line_2.m_line.GetStartX())
            {
                // connected
                // at
                // the
                // start
                // V
                // shape
                if (line_1.m_line.GetEndY() == line_2.m_line.GetEndY() && line_1.m_line.GetEndX() == line_2.m_line.GetEndX())
                {
                    // connected
                    // at
                    // another
                    // end
                    // also
                    if (m_b_is_simple)
                    {
                        return(ErrorCoincident());
                    }
                    return(0);
                }
                return(CompareNonHorizontalUpperEnd_(line_1, line_2));
            }
            if (line_1.m_line.GetEndY() == line_2.m_line.GetEndY() && line_1.m_line.GetEndX() == line_2.m_line.GetEndX())
            {
                // the case of upside-down V.
                return(CompareNonHorizontalLowerEnd_(line_1, line_2));
            }
            int lower = CompareNonHorizontalLowerEnd_(line_1, line_2);
            int upper = CompareNonHorizontalUpperEnd_(line_1, line_2);

            if (lower < 0 && upper < 0)
            {
                return(-1);
            }
            if (lower > 0 && upper > 0)
            {
                return(1);
            }
            return(ErrorCracking());
        }
Exemple #7
0
        internal virtual int CompareNonHorizontalUpperEnd_(com.epl.geometry.SweepComparator.SimpleEdge line_1, com.epl.geometry.SweepComparator.SimpleEdge line_2)
        {
            int sign = 1;

            if (line_2.m_line.GetEndY() < line_1.m_line.GetEndY())
            {
                sign = -1;
                com.epl.geometry.SweepComparator.SimpleEdge tmp = line_1;
                line_1 = line_2;
                line_2 = tmp;
            }
            com.epl.geometry.Line l1 = line_1.m_line;
            com.epl.geometry.Line l2 = line_2.m_line;
            // Now line_1 has End point lower than line_2 endpoint.
            double x_1 = l1.GetEndX() - l2.GetStartX();
            double x2  = line_2.m_dxdy * (l1.GetEndY() - l2.GetStartY());
            double tol = m_tolerance_10;

            if (x_1 < x2 - tol)
            {
                return(-sign);
            }
            else
            {
                if (x_1 > x2 + tol)
                {
                    return(sign);
                }
                else
                {
                    // Possible problem
                    if (l2._isIntersectingPoint(l1.GetEndXY(), m_tolerance, true))
                    {
                        return(ErrorCracking());
                    }
                    return(x_1 < x2 ? -sign : sign);
                }
            }
        }
Exemple #8
0
        internal virtual int CompareSegments(int leftElm, int left_vertex, int right_elm, int right_vertex)
        {
            com.epl.geometry.SweepComparator.SimpleEdge edgeLeft = TryGetCachedEdge_(leftElm);
            if (edgeLeft == null)
            {
                if (m_vertex_1 == left_vertex)
                {
                    edgeLeft = m_temp_simple_edge_1;
                }
                else
                {
                    m_vertex_1 = left_vertex;
                    edgeLeft   = TryCreateCachedEdge_(leftElm);
                    if (edgeLeft == null)
                    {
                        edgeLeft = m_temp_simple_edge_1;
                        m_temp_simple_edge_1.m_value = leftElm;
                    }
                    InitSimpleEdge_(edgeLeft, left_vertex);
                }
            }
            else
            {
                m_vertex_1 = left_vertex;
            }
            com.epl.geometry.SweepComparator.SimpleEdge edgeRight = TryGetCachedEdge_(right_elm);
            if (edgeRight == null)
            {
                if (m_vertex_2 == right_vertex)
                {
                    edgeRight = m_temp_simple_edge_2;
                }
                else
                {
                    m_vertex_2 = right_vertex;
                    edgeRight  = TryCreateCachedEdge_(right_elm);
                    if (edgeRight == null)
                    {
                        edgeRight = m_temp_simple_edge_2;
                        m_temp_simple_edge_2.m_value = right_elm;
                    }
                    InitSimpleEdge_(edgeRight, right_vertex);
                }
            }
            else
            {
                m_vertex_2 = right_vertex;
            }
            if (edgeLeft.m_b_curve || edgeRight.m_b_curve)
            {
                return(CompareSegments_(left_vertex, right_vertex, edgeLeft, edgeRight));
            }
            // Usually we work with lines, so process them in the fastest way.
            // First check - assume segments are far apart. compare x intervals
            if (edgeLeft.m_env.vmax < edgeRight.m_env.vmin)
            {
                return(-1);
            }
            if (edgeRight.m_env.vmax < edgeLeft.m_env.vmin)
            {
                return(1);
            }
            // compare case by case.
            int kind = edgeLeft.m_b_horizontal ? 1 : 0;

            kind |= edgeRight.m_b_horizontal ? 2 : 0;
            if (kind == 0)
            {
                // both segments are non-horizontal
                return(CompareNonHorizontal_(edgeLeft, edgeRight));
            }
            else
            {
                if (kind == 1)
                {
                    // line_1 horizontal, line_2 is not
                    return(CompareHorizontal1_(edgeLeft.m_line, edgeRight.m_line));
                }
                else
                {
                    if (kind == 2)
                    {
                        // line_2 horizontal, line_1 is not
                        return(CompareHorizontal1_(edgeRight.m_line, edgeLeft.m_line) * -1);
                    }
                    else
                    {
                        // if (kind == 3) //both horizontal
                        return(CompareHorizontal2_(edgeLeft.m_line, edgeRight.m_line));
                    }
                }
            }
        }
Exemple #9
0
        internal virtual int CompareSegments_(int left, int right, com.epl.geometry.SweepComparator.SimpleEdge segLeft, com.epl.geometry.SweepComparator.SimpleEdge segRight)
        {
            if (m_b_intersection_detected)
            {
                return(-1);
            }
            bool   sameY = m_prev_y == m_sweep_y && m_prev_x == m_sweep_x;
            double xleft;

            if (sameY && left == m_prev_1)
            {
                xleft = m_prevx_1;
            }
            else
            {
                xleft    = com.epl.geometry.NumberUtils.NaN();
                m_prev_1 = -1;
            }
            double xright;

            if (sameY && right == m_prev_2)
            {
                xright = m_prevx_2;
            }
            else
            {
                xright   = com.epl.geometry.NumberUtils.NaN();
                m_prev_2 = -1;
            }
            // Quickly compare x projections.
            com.epl.geometry.Envelope1D envLeft  = segLeft.m_segment.QueryInterval(com.epl.geometry.VertexDescription.Semantics.POSITION, 0);
            com.epl.geometry.Envelope1D envRight = segRight.m_segment.QueryInterval(com.epl.geometry.VertexDescription.Semantics.POSITION, 0);
            if (envLeft.vmax < envRight.vmin)
            {
                return(-1);
            }
            if (envRight.vmax < envLeft.vmin)
            {
                return(1);
            }
            m_prev_y = m_sweep_y;
            m_prev_x = m_sweep_x;
            // Now do intersection with the sweep line (it is a line parallel to the
            // axis x.)
            if (com.epl.geometry.NumberUtils.IsNaN(xleft))
            {
                m_prev_1 = left;
                double x = segLeft.m_segment.IntersectionOfYMonotonicWithAxisX(m_sweep_y, m_sweep_x);
                xleft     = x;
                m_prevx_1 = x;
            }
            if (com.epl.geometry.NumberUtils.IsNaN(xright))
            {
                m_prev_2 = right;
                double x = segRight.m_segment.IntersectionOfYMonotonicWithAxisX(m_sweep_y, m_sweep_x);
                xright    = x;
                m_prevx_2 = x;
            }
            if (System.Math.Abs(xleft - xright) <= m_tolerance)
            {
                // special processing as we cannot decide in a simple way.
                return(CompareTwoSegments_(segLeft.m_segment, segRight.m_segment));
            }
            else
            {
                return(xleft <xright ? -1 : xleft> xright ? 1 : 0);
            }
        }