[ Launch: circle line ] 5501666 by panamantis
[ Launch: stacked bar ] 5414766 by panamantis
-
-
Save panamantis/5501666 to your computer and use it in GitHub Desktop.
circle line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"editor_editor":{"coffee":false,"vim":false,"emacs":false,"width":528,"height":680,"hide":false},"description":"circle line","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//trying to recreate the effect from here: | |
//www.themaninblue.com/experiment/Blobular/ | |
var a = { | |
x: 250, | |
y: 300, | |
r: 226, | |
}; | |
var b = { | |
x: 770, | |
y: 300, | |
r: 100 | |
}; | |
var join = { | |
r: 119, | |
}; | |
var originDistance = a.r - b.r; | |
a.area = Math.PI * Math.pow(a.r, 2); | |
b.area = Math.PI * Math.pow(b.r, 2); | |
var afterCircleArea = a.area - b.area; | |
a.rmax = a.r; | |
a.rmin = Math.sqrt(afterCircleArea / Math.PI); | |
var distance = calculateDistance(a,b); | |
//var distanceDiff = distance - a.rmax + b.r; | |
var distanceDiff = distance - originDistance; | |
//var distanceDiff = originDistance; | |
if(distanceDiff < 1) { distanceDiff = 1 } | |
var dontdraw = false; | |
if(distance > 2*join.r + a.r + b.r) { | |
console.log("MAY DAY") | |
dontdraw = true; | |
} | |
var angle = calculateAngle(a,b); | |
b.h = 0; | |
b.k = 0 - a.rmax + b.r - distanceDiff; | |
var startY = 0 - a.rmin - join.r * 2 - b.r; | |
var finalY = 0 - a.rmax + b.r - 1; | |
var differenceY = startY - finalY; | |
//console.log("start final", startY, finalY, differenceY) | |
var currDifferenceY = b.k - finalY; | |
var differencePercentage = currDifferenceY / differenceY; | |
//console.log("diff per", differencePercentage) | |
//var differencePercentage = 1.38632; | |
//join.r = join.rmax - (join.rmax - join.rmin) * differencePercentage; | |
//a.r = a.rmax - (a.rmax - a.rmin) * differencePercentage; | |
//console.log(b.k, join.r) | |
var triangleA = a.r + join.r; // Side a | |
var triangleB = b.r + join.r; // Side b | |
var triangleC = Math.abs(b.k - 0); // Side c | |
var triangleP = (triangleA + triangleB + triangleC) / 2; // Triangle half perimeter | |
var triangleArea = Math.sqrt(triangleP * (triangleP - triangleA) * (triangleP - triangleB) * (triangleP - triangleC)); // Triangle area | |
if (triangleC >= triangleA) | |
{ | |
var triangleH = 2 * triangleArea / triangleC; // Triangle height | |
var triangleD = Math.sqrt(Math.pow(triangleA, 2) - Math.pow(triangleH, 2)); // Big circle bisection of triangleC | |
} | |
else | |
{ | |
var triangleH = 2 * triangleArea / triangleA; // Triangle height | |
var triangleD = Math.sqrt(Math.pow(triangleC, 2) - Math.pow(triangleH, 2)); // Small circle bisection of triangleA | |
} | |
a.tan = triangleH / triangleD; | |
a.angle = Math.atan(a.tan); | |
a.sin = Math.sin(a.angle); | |
a.intersectX = a.sin * a.r; | |
a.cos = Math.cos(a.angle); | |
a.intersectY = a.cos * a.r; | |
join.x = 0 + a.sin * (a.r + join.r); | |
join.y = 0 - a.cos * (a.r + join.r); | |
var coord1 = { | |
x: -a.intersectX, | |
y: -a.intersectY | |
}; | |
var coord2 = { | |
x: a.intersectX, | |
y: -a.intersectY | |
} | |
b.tan = (b.k - join.y) / (b.h - join.x); | |
b.angle = Math.atan(b.tan); | |
b.intersectX = join.x - Math.cos(b.angle) * (join.r); | |
b.intersectY = join.y - Math.sin(b.angle) * (join.r); | |
var lavaPathD = "M " + coord1.x + " " + coord1.y + " A " + a.r + " " + a.r + " 0 1 0 " + coord2.x + " " + coord2.y; | |
//console.log("crossover?", join.x - join.r, b.k, join.y, b.k < join.y) | |
if (join.x - join.r <= 0 && b.k < join.y) | |
{ | |
var crossOverY = circleYFromX(join, 0); | |
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 0 " + (join.y + crossOverY); | |
lavaPathD += "m 0 -" + (crossOverY * 2); | |
} | |
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + b.intersectX + " " + b.intersectY; | |
var largeArcFlag = 1; | |
if (join.y < b.k) | |
{ | |
largeArcFlag = 0; | |
} | |
lavaPathD += "a " + b.r + " " + b.r + " 0 " + largeArcFlag + " 0 " + (b.intersectX * -2) + " 0"; | |
if (join.x - join.r <= 0 && b.k < join.y) | |
{ | |
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 0 " + (join.y - crossOverY); | |
lavaPathD += "m 0 " + (crossOverY * 2); | |
} | |
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + coord1.x + " " + coord1.y; | |
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + coord1.x + " " + coord1.y; | |
//console.log(join) | |
var data = [a,b]; | |
var cs = d3.scale.category10(); | |
var svg = d3.select("svg"); | |
svg.selectAll("circle.blob") | |
.data(data) | |
.enter() | |
.append("circle") | |
.classed("blob", true) | |
.attr("cx", function(d) { return d.x }) | |
.attr("cy", function(d) {return d.y }) | |
.attr("r", function(d) { return d.r }) | |
.style("fill", function(d,i) { return cs(i); }) | |
.style("fill-opacity", 0.5) | |
.style("stroke", function(d,i) { return cs(i); }) | |
if(!dontdraw) { | |
var lavaPath = svg.append("path") | |
.classed("lava", true) | |
.attr("transform", function() { | |
var translate = "translate(" + [a.x, a.y] + ")"; | |
var rotate = "rotate(" + [angle, 0, 0] + ")"; | |
return translate + rotate; | |
}) | |
.style("fill", "none") | |
.style("stroke", "#000") | |
.style("stroke-width", 10) | |
// lavaPath.attr("d", lavaPathD) | |
} | |
function calculateDistance(origin, point) { | |
var xx = point.x - origin.x; | |
var yy = point.y - origin.y; | |
return Math.sqrt(xx*xx + yy*yy) | |
} | |
function calculateAngle(origin, point) | |
{ | |
var tan = (point.y - origin.y) / (point.x - origin.x); | |
var angle = Math.atan(tan) / Math.PI * 180 + 90; | |
if (point.x < origin.x) | |
{ | |
angle += 180; | |
} | |
return angle; | |
} | |
function circleYFromX (circle, x) | |
{ | |
return Math.sqrt(Math.pow(circle.r, 2) - Math.pow(x - circle.x, 2)); | |
}; | |
/* | |
var o = { | |
x: 150, | |
y: 0, | |
r: 20 | |
}; | |
var originDistance = calculateDistance(a,o); | |
b.r = a.r - originDistance; | |
*/ | |
//debugging stuff: | |
coord1.r = 10; | |
coord2.r = 10; | |
//join.r = 650; | |
//show helper things | |
var aint = { | |
x: a.intersectX, | |
y: a.intersectY, | |
r: 20 | |
}; | |
var ak = { //a center | |
x: a.h, | |
y: a.k, | |
r: 5 | |
}; | |
var bint = { | |
x: b.intersectX, | |
y: b.intersectY, | |
r: 20 | |
}; | |
var bk = { // center | |
x: b.h, | |
y: b.k, | |
r: 5 | |
}; | |
// Add line | |
var liner={ | |
x1:a.x, | |
y1:a.y, | |
x2:b.x, | |
y2:b.y | |
}; | |
var linerr=[liner]; | |
rect_w=w; | |
radius=rect_w+90;//radius=220; | |
r1=a.r; | |
console.log("Given: "+ "w: "+w+", r1: "+r1+" at ("+a.x+","+a.y+")"); | |
// Control point P1 | |
x1=w; | |
y1=Math.sqrt(Math.pow(r1,2)-Math.pow(w,2)); | |
// reference translate | |
y1=-1*y1; | |
console.log("Place P1 at: ("+x1+","+y1+")"); | |
var p1 = { // center | |
x: x1, | |
y: y1, | |
r: 3 | |
}; | |
// Circle start POINT 2 | |
x2=Math.sqrt(Math.pow(radius,2)-Math.pow(Math.pow(radius,2)/(2*a.r),2)); | |
y2=a.r-Math.pow(radius,2)/(2*a.r); | |
// reference translate | |
y2=-1*y2; | |
var p2 = { // center | |
x: x2, | |
y: y2, | |
r: 10 | |
}; | |
console.log("Place P2 at: ("+x2+","+y2+")"); | |
// Line tangent end POINT 3 | |
x3=x1; | |
d_xy=Math.sqrt(Math.pow((x1-x2),2)+Math.pow((y1-y2),2)); | |
console.log("Distance x1 to x2: "+d_xy+" dx "+d_x+" dy "+d_y); | |
// p3 reference | |
y3=y1-d_xy; | |
var p3 = { // center | |
x: x3, | |
y: y3, | |
r: 10 | |
}; | |
console.log("Place P3 at: ("+x3+","+y3+")"); | |
var helpers = [ bint,bk,aint,ak,p1,p2,p3]; | |
// var helpers = [p1]; | |
var hcs = d3.scale.category20b(); | |
lavaPathE="M "+x2+" "+y2+" Q "+x1+" "+y1+" "+x3+" "+y3; // pt move start | |
m1=-x1; | |
n1=y1; | |
m2=-x2; | |
n2=y2; | |
m3=-x3; | |
n3=y3; | |
lavaPathE+="M "+m2+" "+n2+" Q "+m1+" "+n1+" "+m3+" "+n3; // pt move start | |
console.log("So lava: "+lavaPathE); | |
// lavapathE += "Q "+x2+" "+x2+" "; // pt control | |
// lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + coord1.x + " " + coord1.y; | |
// lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + coord1.x + " " + coord1.y; | |
lavaPath_stoke=10; | |
var lavaPath = svg.append("path") | |
.classed("lava", true) | |
.attr("transform", function() { | |
var translate = "translate(" + [a.x, a.y] + ")"; | |
var rotate = "rotate(" + [angle, 0, 0] + ")"; | |
return translate + rotate; | |
}) | |
.style("fill", "none") | |
.style("stroke", "#000") | |
.style("stroke-width", lavaPath_stoke) | |
lavaPath.attr("d", lavaPathE) | |
svg.selectAll("line.help") | |
.data(linerr) | |
//.data([{r:100}]) | |
.enter() | |
.append("line") | |
// .attr("x1", a.x) | |
// .attr("y1", a.y) | |
// .attr("x2", b.x) | |
// .attr("y2", b.y) | |
.attr("x1", function(d) { return d.x1 }) | |
.attr("y1", function(d) { return d.y1 }) | |
.attr("x2", function(d) { return d.x2 }) | |
.attr("y2", function(d) { return d.y2 }) | |
.style("stroke", function(d,i) { return 1; }) | |
// .style("stroke-width", function(d,i) { return 100; }) ; | |
.style("stroke-width", function(d,i) { return rect_w*2+lavaPath_stoke; }) ; | |
// help circles | |
svg.selectAll("circle.help") | |
.data(helpers) | |
.enter() | |
.append("circle") | |
.classed("help", true) | |
.attr("transform", function() { | |
var translate = "translate(" + [a.x, a.y] + ")"; | |
var rotate = "rotate(" + [angle, 0, 0] + ")"; | |
return translate + rotate; | |
}) | |
.attr("cx", function(d) { return d.x }) | |
.attr("cy", function(d) {return d.y }) | |
.attr("r", function(d) { return Math.abs(d.r) }) | |
.style("fill", function(d,i) { return hcs(i); }) | |
.style("fill-opacity", 0.5) | |
.style("stroke", function(d,i) { return hcs(i); }) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment