MCPcopy Index your code
hub / github.com/processing/processing / parsePathArcto

Method parsePathArcto

core/src/processing/core/PShapeSVG.java:972–1050  ·  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

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