MCPcopy Index your code
hub / github.com/benfry/processing4 / parsePathArcto

Method parsePathArcto

core/src/processing/core/PShapeSVG.java:979–1057  ·  view source on GitHub ↗
(float x1,    float y1,
                              float rx,    float ry,
                              float angle,
                              boolean fa,  boolean fs,
                              float x2,    float y2)

Source from the content-addressed store, hash-verified

977 // Based on arc to bezier curve equations from:
978 // http://www.spaceroots.org/documents/ellipse/node22.html
979 private void parsePathArcto(float x1, float y1,
980 float rx, float ry,
981 float angle,
982 boolean fa, boolean fs,
983 float x2, float y2) {
984 if (x1 == x2 && y1 == y2) return;
985 if (rx == 0 || ry == 0) { parsePathLineto(x2, y2); return; }
986
987 rx = PApplet.abs(rx); ry = PApplet.abs(ry);
988
989 float phi = PApplet.radians(((angle % 360) + 360) % 360);
990 float cosPhi = PApplet.cos(phi), sinPhi = PApplet.sin(phi);
991
992 float x1r = ( cosPhi * (x1 - x2) + sinPhi * (y1 - y2)) / 2;
993 float y1r = (-sinPhi * (x1 - x2) + cosPhi * (y1 - y2)) / 2;
994
995 float cxr, cyr;
996 {
997 float A = (x1r*x1r) / (rx*rx) + (y1r*y1r) / (ry*ry);
998 if (A > 1) {
999 // No solution, scale ellipse up according to SVG standard
1000 float sqrtA = PApplet.sqrt(A);
1001 rx *= sqrtA; cxr = 0;
1002 ry *= sqrtA; cyr = 0;
1003 } else {
1004 float k = ((fa == fs) ? -1f : 1f) *
1005 PApplet.sqrt((rx*rx * ry*ry) / ((rx*rx * y1r*y1r) + (ry*ry * x1r*x1r)) - 1f);
1006 cxr = k * rx * y1r / ry;
1007 cyr = -k * ry * x1r / rx;
1008 }
1009 }
1010
1011 float cx = cosPhi * cxr - sinPhi * cyr + (x1 + x2) / 2;
1012 float cy = sinPhi * cxr + cosPhi * cyr + (y1 + y2) / 2;
1013
1014 float phi1, phiDelta;
1015 {
1016 float sx = ( x1r - cxr) / rx, sy = ( y1r - cyr) / ry;
1017 float tx = (-x1r - cxr) / rx, ty = (-y1r - cyr) / ry;
1018 phi1 = PApplet.atan2(sy, sx);
1019 phiDelta = (((PApplet.atan2(ty, tx) - phi1) % TWO_PI) + TWO_PI) % TWO_PI;
1020 if (!fs) phiDelta -= TWO_PI;
1021 }
1022
1023 // One segment can not cover more that PI, less than PI/2 is
1024 // recommended to avoid visible inaccuracies caused by rounding errors
1025 int segmentCount = PApplet.ceil(PApplet.abs(phiDelta) / TWO_PI * 4);
1026
1027 float inc = phiDelta / segmentCount;
1028 float a = PApplet.sin(inc) *
1029 (PApplet.sqrt(4 + 3 * PApplet.sq(PApplet.tan(inc / 2))) - 1) / 3;
1030
1031 float sinPhi1 = PApplet.sin(phi1), cosPhi1 = PApplet.cos(phi1);
1032
1033 float p1x = x1;
1034 float p1y = y1;
1035 float relq1x = a * (-rx * cosPhi * sinPhi1 - ry * sinPhi * cosPhi1);
1036 float relq1y = a * (-rx * sinPhi * sinPhi1 + ry * cosPhi * cosPhi1);

Callers 1

parsePathMethod · 0.95

Calls 12

parsePathLinetoMethod · 0.95
absMethod · 0.95
radiansMethod · 0.95
cosMethod · 0.95
sinMethod · 0.95
sqrtMethod · 0.95
atan2Method · 0.95
ceilMethod · 0.95
sqMethod · 0.95
tanMethod · 0.95
parsePathCodeMethod · 0.95
parsePathVertexMethod · 0.95

Tested by

no test coverage detected