Browse Source

SVGLoader: Improve round rect corners approximation (#22132)

Victor Nakoryakov 4 years ago
parent
commit
5732f1918d
1 changed files with 49 additions and 9 deletions
  1. 49 9
      examples/jsm/loaders/SVGLoader.js

+ 49 - 9
examples/jsm/loaders/SVGLoader.js

@@ -763,25 +763,65 @@ class SVGLoader extends Loader {
 			const w = parseFloatWithUnits( node.getAttribute( 'width' ) );
 			const h = parseFloatWithUnits( node.getAttribute( 'height' ) );
 
+			// Ellipse arc to Bezier approximation Coefficient (Inversed). See:
+			// https://spencermortensen.com/articles/bezier-circle/
+			const bci = 1 - 0.551915024494;
+
 			const path = new ShapePath();
-			path.moveTo( x + 2 * rx, y );
-			path.lineTo( x + w - 2 * rx, y );
-			if ( rx !== 0 || ry !== 0 ) path.bezierCurveTo( x + w, y, x + w, y, x + w, y + 2 * ry );
-			path.lineTo( x + w, y + h - 2 * ry );
-			if ( rx !== 0 || ry !== 0 ) path.bezierCurveTo( x + w, y + h, x + w, y + h, x + w - 2 * rx, y + h );
-			path.lineTo( x + 2 * rx, y + h );
 
+			// top left
+			path.moveTo( x + rx, y );
+
+			// top right
+			path.lineTo( x + w - rx, y );
 			if ( rx !== 0 || ry !== 0 ) {
 
-				path.bezierCurveTo( x, y + h, x, y + h, x, y + h - 2 * ry );
+				path.bezierCurveTo(
+					x + w - rx * bci,
+					y,
+					x + w,
+					y + ry * bci,
+					x + w,
+					y + ry
+				);
 
 			}
 
-			path.lineTo( x, y + 2 * ry );
+			// bottom right
+			path.lineTo( x + w, y + h - ry );
+			if ( rx !== 0 || ry !== 0 ) {
+
+				path.bezierCurveTo(
+					x + w,
+					y + h - ry * bci,
+					x + w - rx * bci,
+					y + h,
+					x + w - rx,
+					y + h
+				);
+
+			}
+
+			// bottom left
+			path.lineTo( x + rx, y + h );
+			if ( rx !== 0 || ry !== 0 ) {
+
+				path.bezierCurveTo(
+					x + rx * bci,
+					y + h,
+					x,
+					y + h - ry * bci,
+					x,
+					y + h - ry
+				);
+
+			}
 
+			// back to top left
+			path.lineTo( x, y + ry );
 			if ( rx !== 0 || ry !== 0 ) {
 
-				path.bezierCurveTo( x, y, x, y, x + 2 * rx, y );
+				path.bezierCurveTo( x, y + ry * bci, x + rx * bci, y, x + rx, y );
 
 			}