Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active November 12, 2015 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbostock/2ff125ac774e5fb5764c to your computer and use it in GitHub Desktop.
Save mbostock/2ff125ac774e5fb5764c to your computer and use it in GitHub Desktop.
Arc Test
!function(t,h){"object"==typeof exports&&"undefined"!=typeof module?h(exports):"function"==typeof define&&define.amd?define("d3-path",["exports"],h):h(t.d3_path={})}(this,function(t){"use strict";function h(){this.beginPath()}function i(){return new h}var s=Math.PI,_=2*s,n=1e-6;h.prototype=i.prototype={beginPath:function(){this._x0=this._y0=this._x1=this._y1=null,this._=[]},moveTo:function(t,h){this._.push("M",this._x0=this._x1=+t,",",this._y0=this._y1=+h)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._.push("Z"))},lineTo:function(t,h){this._.push("L",this._x1=+t,",",this._y1=+h)},quadraticCurveTo:function(t,h,i,s){this._.push("Q",+t,",",+h,",",this._x1=+i,",",this._y1=+s)},bezierCurveTo:function(t,h,i,s,_,n){this._.push("C",+t,",",+h,",",+i,",",+s,",",this._x1=+_,",",this._y1=+n)},arcTo:function(t,h,i,s,_){t=+t,h=+h,i=+i,s=+s,_=+_;var e=this._x1,o=this._y1,u=i-t,a=s-h,r=e-t,f=o-h,p=r*r+f*f;if(0>_)throw new Error("negative radius: "+_);if(null===this._x1)this._.push("M",this._x1=t,",",this._y1=h);else if(p>n)if(Math.abs(f*u-a*r)>n&&_){var c=i-e,x=s-o,y=u*u+a*a,M=c*c+x*x,l=Math.sqrt(y),d=Math.sqrt(p),v=_*Math.tan((Math.PI-Math.acos((y+p-M)/(2*l*d)))/2),b=v/d,g=v/l;Math.abs(b-1)>n&&this._.push("L",t+b*r,",",h+b*f),this._.push("A",_,",",_,",0,0,",+(f*c>r*x),",",this._x1=t+g*u,",",this._y1=h+g*a)}else this._.push("L",this._x1=t,",",this._y1=h);else;},arc:function(t,h,i,e,o){t=+t,h=+h,i=+i;var u=i*Math.cos(e),a=i*Math.sin(e),r=t+u,f=h+a,p=Math.abs(o-e);if(0>i)throw new Error("negative radius: "+i);null===this._x1?this._.push("M",r,",",f):(Math.abs(this._x1-r)>n||Math.abs(this._y1-f)>n)&&this._.push("L",r,",",f),p>=_-n?this._.push("A",i,",",i,",0,1,1,",t-u,",",h-a,"A",i,",",i,",0,1,1,",this._x1=r,",",this._y1=f):this._.push("A",i,",",i,",0,",+(p>=s),",1,",this._x1=t+i*Math.cos(o),",",this._y1=h+i*Math.sin(o))},rect:function(t,h,i,s){this._.push("M",this._x0=this._x1=+t,",",this._y0=this._y1=+h,"h",+i,"v",+s,"h",-i,"Z")},toString:function(){return this._.join("")}};var e="0.0.2";t.version=e,t.path=i});
<!DOCTYPE html>
<meta charset="utf-8">
<style>
canvas,
svg {
margin: 10px;
border: solid 1px #000;
}
svg {
border-color: red;
}
canvas {
border-color: blue;
}
</style>
<body>
<script src="d3-path.min.js"></script>
<script>
test(null, null, 100, 20, 100, 100, 0); // empty path
test(20, 20, 20, 20, 100, 60, 50); // (x0,y0) coincident with (x1,y1)
test(20, 20, 60, 60, 100, 100, 50); // (x0,y0), (x1,y1), and (x2,y2) collinear
test(20, 20, 100, 60, 100, 60, 50); // (x1,y1) coincident with (x2,y2)
test(20, 20, 100, 20, 100, 100, 0); // zero radius
test(20, 20, 100, 20, 100, 100, NaN); // NaN radius treated as zero
// test(20, 20, 100, 20, 100, 100, -10); // negative radius (throws error)
test(20, 20, 100, 20, 100, 120, 80); // start tangent coincident with (x0,y0)
test(0, 20, 100, 20, 100, 100, 80); // end tangent coincident with (x2,y2)
function test(x0, y0, x1, y1, x2, y2, radius) {
var test = document.createElement("div"),
canvas = document.createElement("canvas"),
canvasContext,
svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"),
svgContext,
dotRadius = 3.5;
function path(context) {
if (x0 !== null) context.moveTo(x0, y0);
context.arcTo(x1, y1, x2, y2, radius);
context.lineTo(200, 160);
}
canvas.width = 200;
canvas.height = 160;
canvasContext = canvas.getContext("2d");
path(canvasContext);
svg.setAttribute("width", 200);
svg.setAttribute("height", 160);
svgContext = d3_path.path();
path(svgContext);
var svgPath = document.createElementNS("http://www.w3.org/2000/svg", "path");
svgPath.setAttribute("d", svgContext.toString());
svgPath.setAttribute("fill", "none");
svgPath.setAttribute("stroke", "#999");
svgPath.setAttribute("stroke-width", "3");
svg.appendChild(svgPath);
canvasContext.lineWidth = 3;
canvasContext.strokeStyle = "#999";
canvasContext.stroke();
if (x0 !== null) {
var circle0 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle0.setAttribute("cx", x0);
circle0.setAttribute("cy", y0);
circle0.setAttribute("r", dotRadius);
svg.appendChild(circle0);
canvasContext.beginPath();
canvasContext.moveTo(x0 + dotRadius, y0);
canvasContext.arc(x0, y0, dotRadius, 0, 2 * Math.PI);
canvasContext.fill();
}
var circle1 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle1.setAttribute("cx", x1);
circle1.setAttribute("cy", y1);
circle1.setAttribute("r", dotRadius);
svg.appendChild(circle1);
canvasContext.beginPath();
canvasContext.moveTo(x1 + dotRadius, y1);
canvasContext.arc(x1, y1, dotRadius, 0, 2 * Math.PI);
canvasContext.fill();
var circle2 = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle2.setAttribute("cx", x2);
circle2.setAttribute("cy", y2);
circle2.setAttribute("r", dotRadius);
svg.appendChild(circle2);
canvasContext.beginPath();
canvasContext.moveTo(x2 + dotRadius, y2);
canvasContext.arc(x2, y2, dotRadius, 0, 2 * Math.PI);
canvasContext.fill();
test.setAttribute("class", "test");
test.appendChild(svg);
test.appendChild(canvas);
document.body.appendChild(test);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment