},
clone : function clone(){
- return new Vec(this.x, this.y);
+ return new math.Vec(this.x, this.y);
},
scale : function scale(s){
Y.extend(math.Vec, {
sum : function sum(a, b) {
- return new Vec(a.x+b.x, a.y+b.y);
+ return new math.Vec(a.x+b.x, a.y+b.y);
},
difference : function difference(a, b) {
- return new Vec(a.x-b.x, a.y-b.y);
+ return new math.Vec(a.x-b.x, a.y-b.y);
},
dot : function dot(a, b) {
},
lerp : function lerp(x, a, b) {
- return new Vec( math.lerp(a.x, b.x, x),
+ return new math.Vec( math.lerp(a.x, b.x, x),
math.lerp(a.y, b.y, x) );
},
reflect : function reflect(v, line){
+ var dot = math.Vec.dot
+ , basev = math.Vec.difference(v, line.p1);
return line.clone()
- .scale(2 * v.dot(line) / line.dot(line))
- .subtract(v);
+ .scale(2 * dot(basev,line) / dot(line,line))
+ .subtract(basev)
+ .add(line.p1);
}
});
grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; //
grid.draw();
+// Draw axes
+ctx = grid.ctx;
+drawLine(-w,-h2, w,-h2, '#CCCCCC', 2.0);
+drawLine(w2,-h, w2,h, '#CCCCCC', 2.0);
+
+
+
P = new Layer()
.width(w).height(h)
.appendTo(grid);
ctx.translate(w2, h2);
ctx.scale(PPU, PPU);
-// Draw axes
-drawLine(-W2,0, W2,0, '#CCCCCC');
-drawLine(0,-H2, 0,H2, '#CCCCCC');
+points = Y([]);
+line = mkLine(-3,2, 4,7);
+addPoint(-5,2);
-testLine(1,2, 4,7, 'rgba(231,48,117, 0.5)', 'rgba(69,150,255, 1)');
-// testLine(-4,-2, 7,13, 'rgba(131,187,50, 0.75)', 'rgba(69,150,255, 1)');
+dragging = false;
+P.layer.bind('click', function(evt){
+ if (!dragging) {
+ var v = convertLoc(evt);
+ addPoint(v.x,v.y);
+ }
+ return false;
+});
});
-function testLine(x1,y1, x2,y2, color, pcolor){
- var t,p, line = new math.Line(x1,y1, x2,y2, 10);
+function convertLoc(evt){
+ var off = P.layer.offset()
+ , x = (evt.pageX - off.left - w2)/(PPU)
+ , y = (evt.pageY - off.top - h2)/PPU * -1;
+ return new math.Vec(x,y);
+}
+
+function clear(){
+ ctx.clearRect(-2*w,-2*h, 4*w,4*h);
+ points.forEach(removePoint);
+ p1.remove(); p2.remove();
+}
+
+function mvLine(pn, x,y){
+ var x1 = (pn === 1 ? x : line.x1)
+ , y1 = (pn === 1 ? y : line.y1)
+ , x2 = (pn === 2 ? x : line.x2)
+ , y2 = (pn === 2 ? y : line.y2)
+ ;
+ mkLine(x1,y1, x2,y2);
+ redraw();
+}
+
+function redraw(color){
+ color = color || 'rgba(231,48,117, 0.5)';
+ var pts = points.clone();
+ clear();
drawLine(-W/2, line.calcY(-W2), line.calcX(H2), H2, color);
- drawPoint(line.x1, line.y1);
- drawPoint(line.x2, line.y2);
-
- drawPoint(0, 0, pcolor);
+ P.append(p1, p2);
+ pts.forEach(addPoint);
+}
+
+function removePoint(c){
+ if (c.reflected) c.reflected.remove();
+ points.remove(c);
+ c.remove();
+}
+
+function addPoint(x,y){
+ if (x instanceof Shape) {
+ var c = x;
+ removePoint(c);
+ P.append(x);
+ } else {
+ var v = new math.Vec(x,y)
+ , c = drawPoint(v, null, '#552F74');
+ }
- t = 0;
- p = line.pcalc(t);
- drawPoint(p.x, p.y, pcolor);
+ var rv = math.Vec.reflect(c.vec,line)
+ , rc = c.reflected = drawPoint(rv, null, '#F25522');
+ points.push(c);
+}
+
+function mkLine(x1,y1, x2,y2, color, pcolor){
+ if (window.p1) p1.remove();
+ if (window.p2) p2.remove();
- t = 1;
- p = line.pcalc(t);
- drawPoint(p.x, p.y, pcolor);
+ color = color || 'rgba(231,48,117, 0.5)';
+ pcolor = pcolor || 'rgba(69,150,255, 1)';
+ var line = new math.Line(x1,y1, x2,y2, 10);
+ drawLine(-W/2, line.calcY(-W2), line.calcX(H2), H2, color);
- t = -1;
- p = line.pcalc(t);
- drawPoint(p.x, p.y, pcolor);
+ p1 = drawPoint(line.x1, line.y1, pcolor);
+ p1.layer.bind('mousedown', function(){
+ dragging = true;
+ function onMove(evt){
+ var r = 3.75, v = convertLoc(evt);
+ mvLine(1, v.x,v.y);
+
+ // _p1.appendTo(P);
+ // p1.position(w2-r + v.x*PPU, h2-r - v.y*PPU)
+
+ return false;
+ }
+ P.layer.bind('mousemove', onMove);
+ P.layer.bind('mouseup', function(evt){
+ dragging = false;
+ P.layer.unbind('mousemove', onMove);
+ P.layer.unbind('mouseup', arguments.callee);
+ // _p1.remove();
+ return false;
+ });
+ return false;
+ });
- return line;
+ p2 = drawPoint(line.x2, line.y2, pcolor);
+ return (window.line = line);
}
-
function drawLine(x1,y1, x2,y2, color, width){
ctx.beginPath();
ctx.lineWidth = width || PX;
function drawPoint(x,y, color, r){
r = r || 3.75;
+ if (x instanceof math.Vec) {
+ var v = x;
+ x = v.x;
+ y = v.y;
+ } else
+ var v = new math.Vec(x,y);
+
var c = new Circle(r)
.position(w2-r + x*PPU, h2-r - y*PPU)
.attr({ 'fillStyle': color || 'rgba(0,0,0,0.5)' })
.appendTo(P)
.draw();
+ c.vec = v;
c.layer.attr('title', '('+x+','+y+')');
return c;
}