void calc_miter(IVertexDest vc,
VertexWithDistance v0,
VertexWithDistance v1,
VertexWithDistance v2,
double dx1, double dy1,
double dx2, double dy2,
line_join_e lj,
double mlimit,
double dbevel)
{
double xi = v1.x;
double yi = v1.y;
double di = 1;
double lim = m_width_abs * mlimit;
bool miter_limit_exceeded = true; // Assume the worst
bool intersection_failed = true; // Assume the worst
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 xi, out yi))
{
// Calculation of the intersection succeeded
//---------------------
di = agg_math.calc_distance(v1.x, v1.y, xi, yi);
if (di <= lim)
{
// Inside the miter limit
//---------------------
add_vertex(vc, xi, yi);
miter_limit_exceeded = false;
}
intersection_failed = false;
}
else
{
// Calculation of the intersection failed, most probably
// the three points lie one straight line.
// First check if v0 and v2 lie on the opposite sides of vector:
// (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
// to the line determined by vertices v0 and v1.
// This condition determines whether the next line segments continues
// the previous one or goes back.
//----------------
double x2 = v1.x + dx1;
double y2 = v1.y - dy1;
if ((agg_math.cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) ==
(agg_math.cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
{
// This case means that the next segment continues
// the previous one (straight line)
//-----------------
add_vertex(vc, v1.x + dx1, v1.y - dy1);
miter_limit_exceeded = false;
}
}
if (miter_limit_exceeded)
{
// Miter limit exceeded
//------------------------
switch (lj)
{
case line_join_e.miter_join_revert:
// For the compatibility with SVG, PDF, etc,
// we use a simple bevel join instead of
// "smart" bevel
//-------------------
add_vertex(vc, v1.x + dx1, v1.y - dy1);
add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
case line_join_e.miter_join_round:
calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
break;
default:
// If no miter-revert, calculate new dx1, dy1, dx2, dy2
//----------------
if (intersection_failed)
{
mlimit *= m_width_sign;
add_vertex(vc, v1.x + dx1 + dy1 * mlimit,
v1.y - dy1 + dx1 * mlimit);
add_vertex(vc, v1.x + dx2 - dy2 * mlimit,
v1.y - dy2 - dx2 * mlimit);
}
else
{
double x1 = v1.x + dx1;
double y1 = v1.y - dy1;
double x2 = v1.x + dx2;
double y2 = v1.y - dy2;
di = (lim - dbevel) / (di - dbevel);
add_vertex(vc, x1 + (xi - x1) * di,
y1 + (yi - y1) * di);
add_vertex(vc, x2 + (xi - x2) * di,
y2 + (yi - y2) * di);
}
break;
}
}
}
}