MCPcopy Create free account
hub / github.com/MyGUI/mygui / addArcApproximate

Function addArcApproximate

MyGUIEngine/src/msdfgen/ext/import-svg.cpp:106–154  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

104}
105
106static void addArcApproximate(Contour &contour, Point2 startPoint, Point2 endPoint, Vector2 radius, double rotation, bool largeArc, bool sweep) {
107 if (endPoint == startPoint)
108 return;
109 if (radius.x == 0 || radius.y == 0)
110 return contour.addEdge(EdgeHolder(startPoint, endPoint));
111
112 radius.x = fabs(radius.x);
113 radius.y = fabs(radius.y);
114 Vector2 axis(cos(rotation), sin(rotation));
115
116 Vector2 rm = rotateVector(.5*(startPoint-endPoint), Vector2(axis.x, -axis.y));
117 Vector2 rm2 = rm*rm;
118 Vector2 radius2 = radius*radius;
119 double radiusGap = rm2.x/radius2.x+rm2.y/radius2.y;
120 if (radiusGap > 1) {
121 radius *= sqrt(radiusGap);
122 radius2 = radius*radius;
123 }
124 double dq = (radius2.x*rm2.y+radius2.y*rm2.x);
125 double pq = radius2.x*radius2.y/dq-1;
126 double q = (largeArc == sweep ? -1 : +1)*sqrt(max(pq, 0.));
127 Vector2 rc(q*radius.x*rm.y/radius.y, -q*radius.y*rm.x/radius.x);
128 Point2 center = .5*(startPoint+endPoint)+rotateVector(rc, axis);
129
130 double angleStart = arcAngle(Vector2(1, 0), (rm-rc)/radius);
131 double angleExtent = arcAngle((rm-rc)/radius, (-rm-rc)/radius);
132 if (!sweep && angleExtent > 0)
133 angleExtent -= 2*M_PI;
134 else if (sweep && angleExtent < 0)
135 angleExtent += 2*M_PI;
136
137 int segments = (int) ceil(ARC_SEGMENTS_PER_PI/M_PI*fabs(angleExtent));
138 double angleIncrement = angleExtent/segments;
139 double cl = 4/3.*sin(.5*angleIncrement)/(1+cos(.5*angleIncrement));
140
141 Point2 prevNode = startPoint;
142 double angle = angleStart;
143 for (int i = 0; i < segments; ++i) {
144 Point2 controlPoint[2];
145 Vector2 d(cos(angle), sin(angle));
146 controlPoint[0] = center+rotateVector(Vector2(d.x-cl*d.y, d.y+cl*d.x)*radius, axis);
147 angle += angleIncrement;
148 d.set(cos(angle), sin(angle));
149 controlPoint[1] = center+rotateVector(Vector2(d.x+cl*d.y, d.y-cl*d.x)*radius, axis);
150 Point2 node = i == segments-1 ? endPoint : center+rotateVector(d*radius, axis);
151 contour.addEdge(EdgeHolder(prevNode, controlPoint[0], controlPoint[1], node));
152 prevNode = node;
153 }
154}
155
156bool buildShapeFromSvgPath(Shape &shape, const char *pathDef, double endpointSnapRange) {
157 char nodeType = '\0';

Callers 1

buildShapeFromSvgPathFunction · 0.85

Calls 7

EdgeHolderClass · 0.85
rotateVectorFunction · 0.85
Vector2Class · 0.85
maxFunction · 0.85
arcAngleFunction · 0.85
addEdgeMethod · 0.45
setMethod · 0.45

Tested by

no test coverage detected