| 3956 | //------------------------------------------------------------------------------ |
| 3957 | |
| 3958 | void ClipperOffset::DoOffset(double delta) |
| 3959 | { |
| 3960 | m_destPolys.clear(); |
| 3961 | m_delta = delta; |
| 3962 | |
| 3963 | //if Zero offset, just copy any CLOSED polygons to m_p and return ... |
| 3964 | if (NEAR_ZERO(delta)) |
| 3965 | { |
| 3966 | m_destPolys.reserve(m_polyNodes.ChildCount()); |
| 3967 | for (int i = 0; i < m_polyNodes.ChildCount(); i++) |
| 3968 | { |
| 3969 | PolyNode& node = *m_polyNodes.Childs[i]; |
| 3970 | if (node.m_endtype == etClosedPolygon) |
| 3971 | m_destPolys.push_back(node.Contour); |
| 3972 | } |
| 3973 | return; |
| 3974 | } |
| 3975 | |
| 3976 | //see offset_triginometry3.svg in the documentation folder ... |
| 3977 | if (MiterLimit > 2) m_miterLim = 2/(MiterLimit * MiterLimit); |
| 3978 | else m_miterLim = 0.5; |
| 3979 | |
| 3980 | double y; |
| 3981 | if (ArcTolerance <= 0.0) y = def_arc_tolerance; |
| 3982 | else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance) |
| 3983 | y = std::fabs(delta) * def_arc_tolerance; |
| 3984 | else y = ArcTolerance; |
| 3985 | //see offset_triginometry2.svg in the documentation folder ... |
| 3986 | double steps = pi / std::acos(1 - y / std::fabs(delta)); |
| 3987 | if (steps > std::fabs(delta) * pi) |
| 3988 | steps = std::fabs(delta) * pi; //ie excessive precision check |
| 3989 | m_sin = std::sin(two_pi / steps); |
| 3990 | m_cos = std::cos(two_pi / steps); |
| 3991 | m_StepsPerRad = steps / two_pi; |
| 3992 | if (delta < 0.0) m_sin = -m_sin; |
| 3993 | |
| 3994 | m_destPolys.reserve(m_polyNodes.ChildCount() * 2); |
| 3995 | for (int i = 0; i < m_polyNodes.ChildCount(); i++) |
| 3996 | { |
| 3997 | PolyNode& node = *m_polyNodes.Childs[i]; |
| 3998 | m_srcPoly = node.Contour; |
| 3999 | |
| 4000 | int len = (int)m_srcPoly.size(); |
| 4001 | if (len == 0 || (delta <= 0 && (len < 3 || node.m_endtype != etClosedPolygon))) |
| 4002 | continue; |
| 4003 | |
| 4004 | m_destPoly.clear(); |
| 4005 | if (len == 1) |
| 4006 | { |
| 4007 | if (node.m_jointype == jtRound) |
| 4008 | { |
| 4009 | double X = 1.0, Y = 0.0; |
| 4010 | for (cInt j = 1; j <= steps; j++) |
| 4011 | { |
| 4012 | m_destPoly.push_back(IntPoint( |
| 4013 | Round(m_srcPoly[0].X + X * delta), |
| 4014 | Round(m_srcPoly[0].Y + Y * delta))); |
| 4015 | double X2 = X; |
nothing calls this directly
no test coverage detected