NewTOAPIA.Drawing.math_stroke.calc_join C# (CSharp) Method

calc_join() public method

public calc_join ( IVertexDest vc, VertexWithDistance v0, VertexWithDistance v1, VertexWithDistance v2, double len1, double len2 ) : void
vc IVertexDest
v0 VertexWithDistance
v1 VertexWithDistance
v2 VertexWithDistance
len1 double
len2 double
return void
        public void calc_join(IVertexDest vc, VertexWithDistance v0,
                                        VertexWithDistance v1,
                                        VertexWithDistance v2,
                                        double len1,
                                        double len2)
        {
            double dx1 = m_width * (v1.y - v0.y) / len1;
            double dy1 = m_width * (v1.x - v0.x) / len1;
            double dx2 = m_width * (v2.y - v1.y) / len2;
            double dy2 = m_width * (v2.x - v1.x) / len2;

            vc.Clear();

            double cp = agg_math.cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
            if (cp != 0 && (cp > 0) == (m_width > 0))
            {
                // Inner join
                //---------------
                double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
                if (limit < m_inner_miter_limit)
                {
                    limit = m_inner_miter_limit;
                }

                switch (m_inner_join)
                {
                    default: // inner_bevel
                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
                        add_vertex(vc, v1.x + dx2, v1.y - dy2);
                        break;

                    case inner_join_e.inner_miter:
                        calc_miter(vc,
                                   v0, v1, v2, dx1, dy1, dx2, dy2,
                                   line_join_e.miter_join_revert,
                                   limit, 0);
                        break;

                    case inner_join_e.inner_jag:
                    case inner_join_e.inner_round:
                        cp = (dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2);
                        if (cp < len1 * len1 && cp < len2 * len2)
                        {
                            calc_miter(vc,
                                       v0, v1, v2, dx1, dy1, dx2, dy2,
                                       line_join_e.miter_join_revert,
                                       limit, 0);
                        }
                        else
                        {
                            if (m_inner_join == inner_join_e.inner_jag)
                            {
                                add_vertex(vc, v1.x + dx1, v1.y - dy1);
                                add_vertex(vc, v1.x, v1.y);
                                add_vertex(vc, v1.x + dx2, v1.y - dy2);
                            }
                            else
                            {
                                add_vertex(vc, v1.x + dx1, v1.y - dy1);
                                add_vertex(vc, v1.x, v1.y);
                                calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
                                add_vertex(vc, v1.x, v1.y);
                                add_vertex(vc, v1.x + dx2, v1.y - dy2);
                            }
                        }
                        break;
                }
            }
            else
            {
                // Outer join
                //---------------

                // Calculate the distance between v1 and 
                // the central point of the bevel line segment
                //---------------
                double dx = (dx1 + dx2) / 2;
                double dy = (dy1 + dy2) / 2;
                double dbevel = Math.Sqrt(dx * dx + dy * dy);

                if (m_line_join == line_join_e.round_join || m_line_join == line_join_e.bevel_join)
                {
                    // This is an optimization that reduces the number of points 
                    // in cases of almost collinear segments. If there's no
                    // visible difference between bevel and miter joins we'd rather
                    // use miter join because it adds only one point instead of two. 
                    //
                    // Here we calculate the middle point between the bevel points 
                    // and then, the distance between v1 and this middle point. 
                    // At outer joins this distance always less than stroke width, 
                    // because it's actually the height of an isosceles triangle of
                    // v1 and its two bevel points. If the difference between this
                    // width and this value is small (no visible bevel) we can 
                    // add just one point. 
                    //
                    // The constant in the expression makes the result approximately 
                    // the same as in round joins and caps. You can safely comment 
                    // out this entire "if".
                    //-------------------
                    if (m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
                    {
                        if (agg_math.calc_intersection(v0.x + dx1, v0.y - dy1,
                                             v1.x + dx1, v1.y - dy1,
                                             v1.x + dx2, v1.y - dy2,
                                             v2.x + dx2, v2.y - dy2,
                                             out dx, out dy))
                        {
                            add_vertex(vc, dx, dy);
                        }
                        else
                        {
                            add_vertex(vc, v1.x + dx1, v1.y - dy1);
                        }
                        return;
                    }
                }

                switch (m_line_join)
                {
                    case line_join_e.miter_join:
                    case line_join_e.miter_join_revert:
                    case line_join_e.miter_join_round:
                        calc_miter(vc,
                                   v0, v1, v2, dx1, dy1, dx2, dy2,
                                   m_line_join,
                                   m_miter_limit,
                                   dbevel);
                        break;

                    case line_join_e.round_join:
                        calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
                        break;

                    default: // Bevel join
                        add_vertex(vc, v1.x + dx1, v1.y - dy1);
                        add_vertex(vc, v1.x + dx2, v1.y - dy2);
                        break;
                }
            }
        }