Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created July 31, 2013 06:24
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 enjalot/6119774 to your computer and use it in GitHub Desktop.
Save enjalot/6119774 to your computer and use it in GitHub Desktop.
constraints
{"description":"constraints","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":true,"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,"thumbnail":"http://i.imgur.com/puo2a6F.png"}
var svg = d3.select("svg");
var bg = svg.append("rect")
.attr({
width: "100%",
height: "100%",
fill: "#187575"
})
var radius = 11;
var init1 = {x:100, y:100, i: 0, lines: []};
var init2 = {x: 400, y: 300, i: 1, lines: []};
var init3 = {x: 200, y: 300, i: 2, lines: []};
var points = [init1, init2, init3];
var lines = [[init1,init2], [init2, init3]];
var currentPoint;
init1.lines = [lines[0]]
init2.lines = [lines[0], lines[1]]
init3.lines = [lines[1]]
/*
svg .append("circle")
.attr({
cx: init2.x + vector(init2, init1).x * 1,
cy: init2.y + vector(init2, init1).y * 1.12,
r: 8
})*/
var colors = d3.scale.category20b();
bg.on("click", function() {
var mouse = d3.mouse(this);
var newPoint = {x: mouse[0], y: mouse[1], i: points.length, lines: [] };
points.push(newPoint);
if(currentPoint) {
//create a new line
var newLine = [currentPoint, newPoint];
lines.push(newLine);
newPoint.lines.push(newLine);
currentPoint.lines.push(newLine);
currentPoint = null;
} else {
currentPoint = newPoint;
}
update();
})
function getAngle(line0, line1) {
var omega = Math.atan2(mx - cx, my - cy);
}
function distance(p0, p1) {
return Math.sqrt((p0.x-p1.x)*(p0.x-p1.x) + (p0.y-p1.y)*(p0.y-p1.y))
}
function vector(p0, p1) {
return {
x: p1.x - p0.x,
y: p1.y - p0.y
}
}
function angle(v0, v1) {
dotprod = v0.x*v1.x + v0.y*v1.y
mag0 = Math.sqrt(v0.x*v0.x + v0.y*v0.y);
mag1 = Math.sqrt(v1.x*v1.x + v1.y*v1.y);
return Math.acos(dotprod / (mag0 * mag1));
}
function rotate(vec, c, theta) {
//TODO implement this (rotate vec about c by theta)
var x = x * Math.cos(theta) - y * Math.sin(theta);
var y = x * Math.sin(theta) + y * Math.cos(theta);
}
var target = Math.PI;
var tension = 0.041*Math.PI;
var velocity = .001;
constrainLines();
update();
tributary.run = function(g,t) {
//collide();
constrainLines();
bounds();
update();
}
function constrainLines() {
//do the constraints for each line
lines.forEach(function(line) {
console.log("line", line)
// each line should look at the lines attached to it's points
// and rotate itself to meet constrains
var p0 = line[0];
var p1 = line[1];
var dist = distance(p0, p1);
var vec = vector(p0, p1);
// console.log("dist", dist);
p0.lines.forEach(function(oline) {
if(line === oline) return
console.log("p0 line");
constrainLine(p0, p1, vec, dist, oline);
});
p1.lines.forEach(function(oline) {
if(line === oline) return
console.log("p1 line");
constrainLine(p1, p0, vec, dist, oline);
});
//p.lines
})
}
function bounds() {
//TODO implement as constraints
points.forEach(function(p) {
if(p.x < radius) p.x = +radius;
if(p.x > tributary.sw-radius) p.x = tributary.sw - radius;
if(p.y < radius) p.y = +radius;
if(p.y > tributary.sh-radius) p.y = tributary.sh - radius;
});
}
function constrainLine(p0, p1, vec, dist, oline) {
//the point in l0 that is not p0 (only works because 2 points in a line
var op = oline[+!oline.indexOf(p0)];
//console.log("op", op)
var ovec = vector(p0, op);
//console.log("ovec", ovec)
var theta = angle(vec, ovec);
//console.log("theta", theta);
//rotate p1 towards constraint
var omega = (target - theta) * tension;
//console.log("omega", omega);
//TODO this constraint is nonsense;
//should actually rotate the vector
var nx = dist * Math.cos(omega);
var ny = dist * Math.sin(omega);
console.log("p1.x,p1.y", p1.x, p1.y)
console.log("nx,ny", nx, ny)
p0.x += (nx - p0.x) * velocity;
p0.y += (ny - p0.y) * velocity;
}
function update() {
var pointSel = svg.selectAll("circle.point")
.data(points, function(d) { return d.i });
var pointDrag = d3.behavior.drag()
.on("drag", function(d) {
d.x += d3.event.dx;
d.y += d3.event.dy;
console.log("hey", d)
update();
})
pointSel.enter()
.append("circle").classed("point", true)
.call(pointDrag)
.on("click", function(d) {
if(currentPoint) {
points.push(d);
//create a new line
var newLine = [currentPoint, d];
lines.push(newLine);
d.lines.push(newLine);
currentPoint.lines.push(newLine);
currentPoint = null;
update();
} else {
currentPoint = d;
}
})
pointSel.attr({
cx: function(d) { return d.x },
cy: function(d) { return d.y },
r: radius,
fill: "#E28D0E"
})
var lineSel = svg.selectAll("line.line")
.data(lines);
lineSel.enter()
.append("line").classed("line", true);
lineSel.attr({
x1: function(d) { return d[0].x },
y1: function(d) { return d[0].y },
x2: function(d) { return d[1].x },
y2: function(d) { return d[1].y },
stroke: "#E28D0E"
})
}
.line {
pointer-events: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment