Dropped the _new in vector lib, Node and edge creation/modification hookup with openerp
bzr revid: fva@openerp.com-20120222140047-oqpj2axm35wswyei
This commit is contained in:
parent
a444a588cd
commit
9af0dcc56d
|
@ -111,34 +111,16 @@ openerp.web.DiagramView = openerp.web.View.extend({
|
||||||
this.get_diagram_info();
|
this.get_diagram_info();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
select_node: function (node, element) {
|
|
||||||
if (!this.selected_node) {
|
|
||||||
this.selected_node = node;
|
|
||||||
element.attr('stroke', 'red');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Re-click selected node, deselect it
|
|
||||||
if (node.id === this.selected_node.id) {
|
|
||||||
this.selected_node = null;
|
|
||||||
element.attr('stroke', 'black');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.add_edit_node(null, this.connector, {
|
|
||||||
act_from: this.selected_node.id,
|
|
||||||
act_to: node.id
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
draw_diagram: function(result) {
|
draw_diagram: function(result) {
|
||||||
|
var self = this;
|
||||||
console.log(result);
|
console.log(result);
|
||||||
var res_nodes = result['nodes'];
|
var res_nodes = result['nodes'];
|
||||||
var res_edges = result['conn'];
|
var res_edges = result['conn'];
|
||||||
var id_to_node = {}
|
var id_to_node = {}
|
||||||
var edge_list = [];
|
|
||||||
|
|
||||||
|
|
||||||
var style = { "background" : 'url("grid.png")',
|
var style = { "edge" : "#A0A0A0",
|
||||||
"edge" : "#A0A0A0",
|
|
||||||
"edge_label" : "#555",
|
"edge_label" : "#555",
|
||||||
"text" : "#333",
|
"text" : "#333",
|
||||||
"outline" : "#000",
|
"outline" : "#000",
|
||||||
|
@ -148,89 +130,48 @@ openerp.web.DiagramView = openerp.web.View.extend({
|
||||||
"node_size_x" : 90,
|
"node_size_x" : 90,
|
||||||
"node_size_y" : 60,
|
"node_size_y" : 60,
|
||||||
"edge_spacing" : 100,
|
"edge_spacing" : 100,
|
||||||
"edge_label_font_size" : 9 };
|
"edge_label_font_size" : 10 };
|
||||||
|
|
||||||
|
$('#dia-canvas *').remove(); // remove previous diagram
|
||||||
|
|
||||||
var r = new Raphael(document.getElementById("dia-canvas"), '100%','500px');
|
var r = new Raphael(document.getElementById("dia-canvas"), '100%','500px');
|
||||||
var graph = new CuteGraph(r,style);
|
var graph = new CuteGraph(r,style);
|
||||||
|
|
||||||
_.each(res_nodes, function(node) {
|
_.each(res_nodes, function(node) {
|
||||||
id_to_node[node.id] = new CuteNode( graph,
|
var n = new CuteNode( graph,
|
||||||
node.x,
|
node.x,
|
||||||
node.y,
|
node.y,
|
||||||
CuteGraph.wordwrap(node.name, 17),
|
CuteGraph.wordwrap(node.name, 17),
|
||||||
node.shape === 'rectangle' ? 'rect' : 'circle',
|
node.shape === 'rectangle' ? 'rect' : 'circle',
|
||||||
node.color === 'white' ? style.white : style.gray );
|
node.color === 'white' ? style.white : style.gray );
|
||||||
|
n.id = node.id;
|
||||||
|
id_to_node[node.id] = n;
|
||||||
});
|
});
|
||||||
|
|
||||||
_.each(res_edges, function(edge) {
|
_.each(res_edges, function(edge) {
|
||||||
edge_list.push( new CuteEdge( graph,
|
var e = new CuteEdge( graph,
|
||||||
CuteGraph.wordwrap(edge.signal, 32),
|
CuteGraph.wordwrap(edge.signal, 32),
|
||||||
id_to_node[edge.s_id],
|
id_to_node[edge.s_id],
|
||||||
id_to_node[edge.d_id] ));
|
id_to_node[edge.d_id] );
|
||||||
|
e.id = edge.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
CuteNode.double_click_callback = function(cutenode){
|
||||||
//Custom logic
|
self.add_edit_node( cutenode.id, self.node );
|
||||||
this.selected_node = null;
|
}
|
||||||
this.active_model = result['id_model'];
|
|
||||||
this.parent_field = result.parent_field;
|
|
||||||
var diagram = new Graph();
|
|
||||||
var self = this;
|
|
||||||
var renderer = function(r, n) {
|
|
||||||
var shape = (n.node.shape === 'rectangle') ? 'rect' : 'ellipse';
|
|
||||||
|
|
||||||
var node = r[shape](n.node.x, n.node.y).attr({
|
CuteEdge.double_click_callback = function(cuteedge){
|
||||||
"fill": n.node.color
|
self.add_edit_node(cuteedge.id,self.connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
CuteEdge.creation_callback = function(node_start, node_end){
|
||||||
|
console.log("creating edge from:",node_start," to:",node_end);
|
||||||
|
self.add_edit_node(null, self.connector, {
|
||||||
|
act_from: node_start.id,
|
||||||
|
act_to: node_end.id
|
||||||
});
|
});
|
||||||
|
return {label:""}; // TODO destroy edge on cancel
|
||||||
var nodes = r.set(node, r.text(n.node.x, n.node.y, (n.label || n.id)))
|
}
|
||||||
.attr("cursor", "pointer")
|
|
||||||
.dblclick(function() {
|
|
||||||
self.add_edit_node(n.node.id, self.node);
|
|
||||||
})
|
|
||||||
.mousedown(function () { node.moved = false; })
|
|
||||||
.mousemove(function () { node.moved = true; })
|
|
||||||
.click(function () {
|
|
||||||
// Ignore click from move event
|
|
||||||
if (node.moved) { return; }
|
|
||||||
self.select_node(n.node, node);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (shape === 'rect') {
|
|
||||||
node.attr({width: "60", height: "44"});
|
|
||||||
node.next.attr({"text-anchor": "middle", x: n.node.x + 20, y: n.node.y + 20});
|
|
||||||
} else {
|
|
||||||
node.attr({rx: "40", ry: "20"});
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
_.each(res_nodes, function(res_node) {
|
|
||||||
diagram.addNode(res_node['name'],{node: res_node,render: renderer});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Id for Path(Edges)
|
|
||||||
var edge_ids = [];
|
|
||||||
|
|
||||||
_.each(res_connectors, function(connector, index) {
|
|
||||||
edge_ids.push(index);
|
|
||||||
diagram.addEdge(connector['source'], connector['destination'], {directed : true, label: connector['signal']});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.$element.find('.diagram').empty();
|
|
||||||
|
|
||||||
var layouter = new Graph.Layout.Ordered(diagram);
|
|
||||||
var render_diagram = new Graph.Renderer.Raphael('dia-canvas', diagram, $('div#dia-canvas').width(), $('div#dia-canvas').height());
|
|
||||||
|
|
||||||
_.each(diagram.edges, function(edge, index) {
|
|
||||||
if(edge.connection) {
|
|
||||||
edge.connection.fg.attr({cursor: "pointer"}).dblclick(function() {
|
|
||||||
self.add_edit_node(edge_ids[index], self.connector);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
},
|
},
|
||||||
|
|
||||||
add_edit_node: function(id, model, defaults) {
|
add_edit_node: function(id, model, defaults) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
(function(window){
|
(function(window){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// this serves as the end of an edge when creating a link
|
// this serves as the end of an edge when creating a link
|
||||||
|
@ -61,7 +62,10 @@
|
||||||
graph.creating_edge = false;
|
graph.creating_edge = false;
|
||||||
self.edge_tmp.remove();
|
self.edge_tmp.remove();
|
||||||
if(graph.target_node && graph.target_node != node){
|
if(graph.target_node && graph.target_node != node){
|
||||||
new GraphEdge(graph,'new edge!', node,graph.target_node);
|
edge_prop = GraphEdge.creation_callback(node,graph.target_node);
|
||||||
|
if(edge_prop){
|
||||||
|
new GraphEdge(graph,edge_prop.label, node,graph.target_node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn_circle.drag(drag_move,drag_down,drag_up);
|
conn_circle.drag(drag_move,drag_down,drag_up);
|
||||||
|
@ -289,7 +293,7 @@
|
||||||
for(var i = 0; i < edges.length; i++){
|
for(var i = 0; i < edges.length; i++){
|
||||||
edges[i].label_disable();
|
edges[i].label_disable();
|
||||||
}
|
}
|
||||||
set_pos(this.opos.add_new_xy(dx,dy));
|
set_pos(this.opos.add_xy(dx,dy));
|
||||||
}
|
}
|
||||||
var drag_up = function(){
|
var drag_up = function(){
|
||||||
//we re-enable the
|
//we re-enable the
|
||||||
|
@ -314,12 +318,22 @@
|
||||||
node_fig.hover(hover_in,hover_out);
|
node_fig.hover(hover_in,hover_out);
|
||||||
node_label.hover(hover_in,hover_out);
|
node_label.hover(hover_in,hover_out);
|
||||||
|
|
||||||
|
function double_click(){
|
||||||
|
GraphNode.double_click_callback(self);
|
||||||
|
}
|
||||||
|
node_fig.dblclick(double_click);
|
||||||
|
node_label.dblclick(double_click);
|
||||||
|
|
||||||
this.connectors.push(new Connector(graph,this,-sx/2,0));
|
this.connectors.push(new Connector(graph,this,-sx/2,0));
|
||||||
this.connectors.push(new Connector(graph,this,sx/2,0));
|
this.connectors.push(new Connector(graph,this,sx/2,0));
|
||||||
this.connectors.push(new Connector(graph,this,0,-sy/2));
|
this.connectors.push(new Connector(graph,this,0,-sy/2));
|
||||||
this.connectors.push(new Connector(graph,this,0,sy/2));
|
this.connectors.push(new Connector(graph,this,0,sy/2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GraphNode.double_click_callback = function(node){
|
||||||
|
console.log("double click from node:",node);
|
||||||
|
}
|
||||||
|
|
||||||
// creates a new edge with label 'label' from start to end. start and end must implement get_pos_*,
|
// creates a new edge with label 'label' from start to end. start and end must implement get_pos_*,
|
||||||
// if tmp is true, the edge is not added to the graph, used for drag edges. TODO pass graph in constructor,
|
// if tmp is true, the edge is not added to the graph, used for drag edges. TODO pass graph in constructor,
|
||||||
// replace tmp == false by graph == null
|
// replace tmp == false by graph == null
|
||||||
|
@ -329,6 +343,7 @@
|
||||||
var curvature = 0; // 0 = straight, != 0 curved
|
var curvature = 0; // 0 = straight, != 0 curved
|
||||||
var s,e; // positions of the start and end point of the line between start and end
|
var s,e; // positions of the start and end point of the line between start and end
|
||||||
var mc; // position of the middle of the curve (bezier control point)
|
var mc; // position of the middle of the curve (bezier control point)
|
||||||
|
var mc1,mc2; // control points of the cubic bezier for the loop edges
|
||||||
var elfs = graph.style.edge_label_font_size || 10 ;
|
var elfs = graph.style.edge_label_font_size || 10 ;
|
||||||
var label_enabled = true;
|
var label_enabled = true;
|
||||||
this.uid = 0; // unique id used to order the curved edges
|
this.uid = 0; // unique id used to order the curved edges
|
||||||
|
@ -342,7 +357,7 @@
|
||||||
var cpos = path.getTotalLength() * 0.5;
|
var cpos = path.getTotalLength() * 0.5;
|
||||||
var cindex = Math.abs(Math.floor(curvature));
|
var cindex = Math.abs(Math.floor(curvature));
|
||||||
var mod = ((cindex % 3)) * (elfs * 3.1) - (elfs * 0.5);
|
var mod = ((cindex % 3)) * (elfs * 3.1) - (elfs * 0.5);
|
||||||
var verticality = Math.abs(end.get_pos().sub_new(start.get_pos()).normalize().dot_xy(0,1));
|
var verticality = Math.abs(end.get_pos().sub(start.get_pos()).normalize().dot_xy(0,1));
|
||||||
verticality = Math.max(verticality-0.5,0)*2;
|
verticality = Math.max(verticality-0.5,0)*2;
|
||||||
|
|
||||||
var lpos = path.getPointAtLength(cpos + mod * verticality);
|
var lpos = path.getPointAtLength(cpos + mod * verticality);
|
||||||
|
@ -358,12 +373,12 @@
|
||||||
}
|
}
|
||||||
s = start.get_pos();
|
s = start.get_pos();
|
||||||
e = end.get_pos();
|
e = end.get_pos();
|
||||||
mc = s.lerp_new(e,0.5); //middle of the line s->e
|
mc = s.lerp(e,0.5); //middle of the line s->e
|
||||||
var se = e.sub_new(s);
|
var se = e.sub(s);
|
||||||
se.normalize();
|
se = se.normalize();
|
||||||
se.rotate_deg(-90);
|
se = se.rotate_deg(-90);
|
||||||
se.scale(curvature * graph.style.edge_spacing);
|
se = se.scale(curvature * graph.style.edge_spacing);
|
||||||
mc.add(se);
|
mc = mc.add(se);
|
||||||
if(start.get_bound){
|
if(start.get_bound){
|
||||||
var col = start.get_bound().collide_segment(s,mc);
|
var col = start.get_bound().collide_segment(s,mc);
|
||||||
if(col.length > 0){
|
if(col.length > 0){
|
||||||
|
@ -377,6 +392,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
function update_loop_pos(){
|
||||||
|
s = start.get_pos();
|
||||||
|
mc = s.add_new(Vec2.new_polar_deg(graph.style.edge_loop_radius,45*self.uid));
|
||||||
|
var p = mc.normalize_new().rotate_deg(90);
|
||||||
|
mc1 = mc.add_new
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
function make_line(){
|
function make_line(){
|
||||||
return "M" + s.x + "," + s.y + "L" + e.x + "," + e.y ;
|
return "M" + s.x + "," + s.y + "L" + e.x + "," + e.y ;
|
||||||
|
@ -431,12 +454,31 @@
|
||||||
edge_label.remove();
|
edge_label.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function double_click(){
|
||||||
|
GraphEdge.double_click_callback(self);
|
||||||
|
}
|
||||||
|
edge.dblclick(double_click);
|
||||||
|
edge_label.dblclick(double_click);
|
||||||
|
|
||||||
this.label_enable = label_enable;
|
this.label_enable = label_enable;
|
||||||
this.label_disable = label_disable;
|
this.label_disable = label_disable;
|
||||||
this.update = update;
|
this.update = update;
|
||||||
this.remove = remove;
|
this.remove = remove;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GraphEdge.double_click_callback = function(edge){
|
||||||
|
console.log("double click from edge:",edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the default edge creation callback. It is called before an edge is created
|
||||||
|
// It returns an object containing the properties of the edge.
|
||||||
|
// If it returns null, the edge is not created.
|
||||||
|
GraphEdge.creation_callback = function(start,end){
|
||||||
|
var edge_prop = {};
|
||||||
|
edge_prop.label = 'new edge!';
|
||||||
|
return edge_prop;
|
||||||
|
}
|
||||||
|
|
||||||
// returns a new string with the same content as str, but with lines of maximum 'width' characters.
|
// returns a new string with the same content as str, but with lines of maximum 'width' characters.
|
||||||
// lines are broken on words, or into words if a word is longer than 'width'
|
// lines are broken on words, or into words if a word is longer than 'width'
|
||||||
function wordwrap( str, width) {
|
function wordwrap( str, width) {
|
||||||
|
@ -460,6 +502,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
window.onload = function(){
|
window.onload = function(){
|
||||||
|
//Example
|
||||||
var style = { "background" :'url("grid.png")',
|
var style = { "background" :'url("grid.png")',
|
||||||
"edge" :"#A0A0A0",
|
"edge" :"#A0A0A0",
|
||||||
"edge_label" :"#555",
|
"edge_label" :"#555",
|
||||||
|
@ -470,15 +513,17 @@ window.onload = function(){
|
||||||
"white" :"#FFF",
|
"white" :"#FFF",
|
||||||
"node_size_x" : 110,
|
"node_size_x" : 110,
|
||||||
"node_size_y" : 80,
|
"node_size_y" : 80,
|
||||||
"edge_spacing" : 100 };
|
"edge_spacing" : 100,
|
||||||
|
"edge_label_font_size" : 10
|
||||||
|
"edge_loop_radius": 50 };
|
||||||
|
|
||||||
var r = new Raphael(document.getElementById("canvas_container"),'100%','100%');
|
var r = new Raphael(document.getElementById("canvas_container"),'100%','100%');
|
||||||
|
|
||||||
var g = new CuteGraph(r,style);
|
var g = new CuteGraph(r,style);
|
||||||
|
|
||||||
var n1 = new GraphNode(g,100,250,'Hello World','circle',colors.white);
|
var n1 = new CuteNode(g,100,250,'Hello World','circle',colors.white);
|
||||||
var n2 = new GraphNode(g,400,250,'Hello Planet','rect',colors.white);
|
var n2 = new CuteNode(g,400,250,'Hello Planet','rect',colors.white);
|
||||||
var n3 = new GraphNode(g,250,400,'Lonely Node','rect',colors.gray);
|
var n3 = new CuteNode(g,250,400,'Lonely Node','rect',colors.gray);
|
||||||
var e1 = new GraphEdge(g,'test',n1,n2);
|
var e1 = new CuteEdge(g,'test',n1,n2);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
|
@ -6,24 +6,17 @@
|
||||||
// A Javascript 2D vector library
|
// A Javascript 2D vector library
|
||||||
// conventions :
|
// conventions :
|
||||||
// method that returns a float value do not modify the vector
|
// method that returns a float value do not modify the vector
|
||||||
// method that implement operators are applied onto the calling vector eg:
|
// method that implement operators return a new vector with the modifications without
|
||||||
|
// modifying the calling vector or the parameters.
|
||||||
//
|
//
|
||||||
// v1.add(v2); // v2 is added onto v1, v2 is modified, v1 is not
|
// v3 = v1.add(v2); // v3 is set to v1 + v2, v1, v2 are not modified
|
||||||
//
|
|
||||||
// but the parameters are never modified
|
|
||||||
// those methods also return the result so that the calls can be chained.
|
|
||||||
// method that implement operators are usually also available with a '_new'
|
|
||||||
// suffix. those method do not modify the calling vector and return the result
|
|
||||||
// as a new vector instead.
|
|
||||||
//
|
|
||||||
// v3 = v1.add_new(v2) // v3 is set to v1 + v2. v1 and v2 are not modified
|
|
||||||
//
|
//
|
||||||
// methods that take a single vector as a parameter are usually also available with
|
// methods that take a single vector as a parameter are usually also available with
|
||||||
// q '_xy' suffix. Those method takes two floats representing the x,y coordinates of
|
// q '_xy' suffix. Those method takes two floats representing the x,y coordinates of
|
||||||
// the vector parameter and allow you to avoid to needlessly create a vector object :
|
// the vector parameter and allow you to avoid to needlessly create a vector object :
|
||||||
//
|
//
|
||||||
// v1.add(new Vec2(3,4));
|
// v2 = v1.add(new Vec2(3,4));
|
||||||
// v1.add_xy(3,4); //equivalent to previous line
|
// v2 = v1.add_xy(3,4); //equivalent to previous line
|
||||||
//
|
//
|
||||||
// angles are in radians by default but method that takes angle as parameters
|
// angles are in radians by default but method that takes angle as parameters
|
||||||
// or return angle values usually have a variant with a '_deg' suffix that works in degrees
|
// or return angle values usually have a variant with a '_deg' suffix that works in degrees
|
||||||
|
@ -102,149 +95,55 @@
|
||||||
Vec2.prototype.clone = function(){
|
Vec2.prototype.clone = function(){
|
||||||
return new Vec2(this.x,this.y);
|
return new Vec2(this.x,this.y);
|
||||||
};
|
};
|
||||||
// sets the coordinate of this vector to (0,0)
|
|
||||||
Vec2.prototype.zero = function(){
|
|
||||||
this.x = 0;
|
|
||||||
this.y = 0;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// sets the coordinates of this to be equal to the coordinates of v
|
|
||||||
Vec2.prototype.set = function(v){
|
|
||||||
this.x = v.x;
|
|
||||||
this.y = v.y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// sets the coordinate of this to be equal to the vector (x,y)
|
|
||||||
Vec2.prototype.set_xy = function(x,y){
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// sets this to be the sum of this and vector v
|
|
||||||
Vec2.prototype.add = function(v){
|
|
||||||
this.x += v.x;
|
|
||||||
this.y += v.y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// sets this to be the sum of this and the vector (x,y)
|
|
||||||
Vec2.prototype.add_xy = function(x,y){
|
|
||||||
this.x += x;
|
|
||||||
this.y += y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// return the sum of this and vector v as a new vector
|
// return the sum of this and vector v as a new vector
|
||||||
Vec2.prototype.add_new = function(v){
|
Vec2.prototype.add = function(v){
|
||||||
return new Vec2(this.x+v.x,this.y+v.y);
|
return new Vec2(this.x+v.x,this.y+v.y);
|
||||||
};
|
};
|
||||||
// return the sum of this and vector (x,y) as a new vector
|
// return the sum of this and vector (x,y) as a new vector
|
||||||
Vec2.prototype.add_new_xy = function(x,y){
|
Vec2.prototype.add_xy = function(x,y){
|
||||||
return new Vec2(this.x+x,this.y+y);
|
return new Vec2(this.x+x,this.y+y);
|
||||||
};
|
};
|
||||||
// sets this to be (this - v) where v is a vector and - is the vector substraction
|
|
||||||
Vec2.prototype.sub = function(v){
|
|
||||||
this.x -= v.x;
|
|
||||||
this.y -= v.y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// sets this to be (this - (x,y)) where - is the vector substraction
|
|
||||||
Vec2.prototype.sub_xy = function(x,y){
|
|
||||||
this.x -= x;
|
|
||||||
this.y -= y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// returns (this - v) as a new vector where v is a vector and - is the vector substraction
|
// returns (this - v) as a new vector where v is a vector and - is the vector substraction
|
||||||
Vec2.prototype.sub_new = function(v){
|
Vec2.prototype.sub = function(v){
|
||||||
return new Vec2(this.x-v.x,this.y-v.y);
|
return new Vec2(this.x-v.x,this.y-v.y);
|
||||||
};
|
};
|
||||||
// returns (this - (x,y)) as a new vector where - is vector substraction
|
// returns (this - (x,y)) as a new vector where - is vector substraction
|
||||||
Vec2.prototype.sub_new_xy = function(x,y){
|
Vec2.prototype.sub_xy = function(x,y){
|
||||||
return new Vec2(this.x-x,this.y-y);
|
return new Vec2(this.x-x,this.y-y);
|
||||||
};
|
};
|
||||||
// sets this to be (this * v) where v is a vector and * is the by component product and
|
|
||||||
Vec2.prototype.mult = function(v){
|
|
||||||
this.x *= v.x;
|
|
||||||
this.y *= v.y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// sets this to be (this * (x,y) ) where v is a vector and * is the by component product
|
|
||||||
Vec2.prototype.mult_xy = function(x,y){
|
|
||||||
this.x *= x;
|
|
||||||
this.y *= y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// return (this * v) as a new vector where v is a vector and * is the by component product
|
// return (this * v) as a new vector where v is a vector and * is the by component product
|
||||||
Vec2.prototype.mult_new = function(v){
|
Vec2.prototype.mult = function(v){
|
||||||
return new Vec2(this.x*v.x,this.y*v.y);
|
return new Vec2(this.x*v.x,this.y*v.y);
|
||||||
};
|
};
|
||||||
// return (this * (x,y)) as a new vector where * is the by component product
|
// return (this * (x,y)) as a new vector where * is the by component product
|
||||||
Vec2.prototype.mult_new_xy = function(x,y){
|
Vec2.prototype.mult_xy = function(x,y){
|
||||||
return new Vec2(this.x*x,this.y*y);
|
return new Vec2(this.x*x,this.y*y);
|
||||||
};
|
};
|
||||||
// multiply all components of this vector by float f
|
|
||||||
Vec2.prototype.scale = function(f){
|
|
||||||
this.x *= f;
|
|
||||||
this.y *= f;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// return this scaled by float f as a new fector
|
// return this scaled by float f as a new fector
|
||||||
Vec2.prototype.scale_new = function(f){
|
Vec2.prototype.scale = function(f){
|
||||||
return new Vec2(this.x*f, this.y*f);
|
return new Vec2(this.x*f, this.y*f);
|
||||||
};
|
};
|
||||||
//sets this vector to be the negative of itself
|
|
||||||
Vec2.prototype.neg = function(f){
|
|
||||||
this.x = -this.x;
|
|
||||||
this.y = -this.y;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// return the negation of this vector
|
// return the negation of this vector
|
||||||
Vec2.prototype.neg_new = function(f){
|
Vec2.prototype.neg = function(f){
|
||||||
return new Vec2(-this.x,-this.y);
|
return new Vec2(-this.x,-this.y);
|
||||||
};
|
};
|
||||||
// normalizes this vector
|
|
||||||
Vec2.prototype.normalize = function(){
|
|
||||||
var len = this.len();
|
|
||||||
if(len == 0){
|
|
||||||
this.x = 1;
|
|
||||||
}else if(len != 1){
|
|
||||||
this.scale(1.0/len);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// return this vector normalized as a new vector
|
// return this vector normalized as a new vector
|
||||||
Vec2.prototype.normalize_new = function(){
|
Vec2.prototype.normalize = function(){
|
||||||
var len = this.len();
|
var len = this.len();
|
||||||
if(len == 0){
|
if(len == 0){
|
||||||
return new Vec2(0,1);
|
return new Vec2(0,1);
|
||||||
}else if(len != 1){
|
}else if(len != 1){
|
||||||
return this.scale_new(1.0/len);
|
return this.scale(1.0/len);
|
||||||
}
|
}
|
||||||
return new Vec2(this.x,this.y);
|
return new Vec2(this.x,this.y);
|
||||||
};
|
};
|
||||||
// sets the length of this vector to float l without changing its angle. (negative values of l will invert direction)
|
|
||||||
Vec2.prototype.set_len = function(l){
|
|
||||||
this.normalize();
|
|
||||||
this.scale(l);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
// return a new vector with the same direction as this vector of length float l. (negative values of l will invert direction)
|
// return a new vector with the same direction as this vector of length float l. (negative values of l will invert direction)
|
||||||
Vec2.prototype.set_len_new = function(l){
|
Vec2.prototype.set_len = function(l){
|
||||||
var v = this.normalize_new();
|
return this.normalize().scale(l);
|
||||||
v.scale(l);
|
|
||||||
return v;
|
|
||||||
};
|
|
||||||
// projects this vector onto the vector v
|
|
||||||
Vec2.prototype.project = function(v){
|
|
||||||
var d = this.dot(v);
|
|
||||||
this.set(v);
|
|
||||||
this.normalize();
|
|
||||||
this.scale(d);
|
|
||||||
return this;
|
|
||||||
};
|
};
|
||||||
// return the projection of this onto the vector v as a new vector
|
// return the projection of this onto the vector v as a new vector
|
||||||
Vec2.prototype.project_new = function(v){
|
Vec2.prototype.project = function(v){
|
||||||
var vc = this.clone();
|
return v.set_len(this.dot(v));
|
||||||
vc.project(v);
|
|
||||||
return vc;
|
|
||||||
};
|
};
|
||||||
// return a string representation of this vector
|
// return a string representation of this vector
|
||||||
Vec2.prototype.toString = function(){
|
Vec2.prototype.toString = function(){
|
||||||
|
@ -256,45 +155,25 @@
|
||||||
str += "]";
|
str += "]";
|
||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
// rotate this vector counterclockwise by rad radians.
|
//return this vector counterclockwise rotated by rad radians as a new vector
|
||||||
Vec2.prototype.rotate = function(rad){
|
Vec2.prototype.rotate = function(rad){
|
||||||
var c = Math.cos(rad);
|
var c = Math.cos(rad);
|
||||||
var s = Math.sin(rad);
|
var s = Math.sin(rad);
|
||||||
var px = this.x * c - this.y *s;
|
var px = this.x * c - this.y *s;
|
||||||
var py = this.x * s + this.y *c;
|
var py = this.x * s + this.y *c;
|
||||||
this.x = px;
|
return new Vec2(px,py);
|
||||||
this.y = py;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
//rotate this vector counterclockwise by deg degrees
|
|
||||||
Vec2.prototype.rotate_deg = function(deg){
|
|
||||||
return this.rotate(deg * deg2rad);
|
|
||||||
};
|
|
||||||
//return this vector counterclockwise rotated by rad radians as a new vector
|
|
||||||
Vec2.prototype.rotate_new = function(rad){
|
|
||||||
var v = this.clone();
|
|
||||||
return v.rotate(rad);
|
|
||||||
};
|
};
|
||||||
//return this vector counterclockwise rotated by deg degrees as a new vector
|
//return this vector counterclockwise rotated by deg degrees as a new vector
|
||||||
Vec2.prototype.rotate_deg_new = function(deg){
|
Vec2.prototype.rotate_deg = function(deg){
|
||||||
var v = this.clone();
|
return this.rotate(deg * deg2rad);
|
||||||
return v.rotate_deg(deg);
|
|
||||||
};
|
};
|
||||||
//linearly interpolate this vector towards the vector v by float factor alpha.
|
//linearly interpolate this vector towards the vector v by float factor alpha.
|
||||||
// alpha == 0 : does nothing
|
// alpha == 0 : does nothing
|
||||||
// alpha == 1 : sets this to v
|
// alpha == 1 : sets this to v
|
||||||
Vec2.prototype.lerp = function(v,alpha){
|
Vec2.prototype.lerp = function(v,alpha){
|
||||||
var inv_alpha = 1 - alpha;
|
var inv_alpha = 1 - alpha;
|
||||||
this.x = this.x * inv_alpha + v.x * alpha;
|
return new Vec2( this.x * inv_alpha + v.x * alpha,
|
||||||
this.y = this.y * inv_alpha + v.y * alpha;
|
|
||||||
};
|
|
||||||
// returns this vector lerped to v by alpha as a new vector
|
|
||||||
Vec2.prototype.lerp_new = function(v,alpha){
|
|
||||||
var inv_alpha = 1 - alpha;
|
|
||||||
var v2 = new Vec2( this.x * inv_alpha + v.x * alpha,
|
|
||||||
this.y * inv_alpha + v.y * alpha );
|
this.y * inv_alpha + v.y * alpha );
|
||||||
return v2;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
// returns the angle between this vector and the vector (1,0) in radians
|
// returns the angle between this vector and the vector (1,0) in radians
|
||||||
Vec2.prototype.angle = function(){
|
Vec2.prototype.angle = function(){
|
||||||
|
@ -359,8 +238,8 @@
|
||||||
// make all computations in a space where the ellipse is a circle
|
// make all computations in a space where the ellipse is a circle
|
||||||
// centered on zero
|
// centered on zero
|
||||||
var c = new Vec2(this.cx,this.cy);
|
var c = new Vec2(this.cx,this.cy);
|
||||||
a = a.sub_new(c).mult_xy(1/this.hx,1/this.hy);
|
a = a.sub(c).mult_xy(1/this.hx,1/this.hy);
|
||||||
b = b.sub_new(c).mult_xy(1/this.hx,1/this.hy);
|
b = b.sub(c).mult_xy(1/this.hx,1/this.hy);
|
||||||
|
|
||||||
|
|
||||||
if(a.len_sq() < 1 && b.len_sq() < 1){ //both points inside the ellipse
|
if(a.len_sq() < 1 && b.len_sq() < 1){ //both points inside the ellipse
|
||||||
|
@ -368,7 +247,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute the roots of the intersection
|
// compute the roots of the intersection
|
||||||
var ab = b.sub_new(a);
|
var ab = b.sub(a);
|
||||||
var A = (ab.x*ab.x + ab.y*ab.y);
|
var A = (ab.x*ab.x + ab.y*ab.y);
|
||||||
var B = 2*( ab.x*a.x + ab.y*a.y);
|
var B = 2*( ab.x*a.x + ab.y*a.y);
|
||||||
var C = a.x*a.x + a.y*a.y - 1;
|
var C = a.x*a.x + a.y*a.y - 1;
|
||||||
|
@ -383,18 +262,16 @@
|
||||||
var u2 = (-B - u) / (2*A);
|
var u2 = (-B - u) / (2*A);
|
||||||
|
|
||||||
if(u1 >= 0 && u1 <= 1){
|
if(u1 >= 0 && u1 <= 1){
|
||||||
var pos = a.clone();
|
var pos = a.add(ab.scale(u1));
|
||||||
pos.add(ab.scale_new(u1));
|
|
||||||
collisions.push(pos);
|
collisions.push(pos);
|
||||||
}
|
}
|
||||||
if(u1 != u2 && u2 >= 0 && u2 <= 1){
|
if(u1 != u2 && u2 >= 0 && u2 <= 1){
|
||||||
var pos = a.clone();
|
var pos = a.add(ab.scale(u2));
|
||||||
pos.add(ab.scale_new(u2));
|
|
||||||
collisions.push(pos);
|
collisions.push(pos);
|
||||||
}
|
}
|
||||||
for(var i = 0; i < collisions.length; i++){
|
for(var i = 0; i < collisions.length; i++){
|
||||||
collisions[i].mult_xy(this.hx,this.hy);
|
collisions[i] = collisions[i].mult_xy(this.hx,this.hy);
|
||||||
collisions[i].add_xy(this.cx,this.cy);
|
collisions[i] = collisions[i].add_xy(this.cx,this.cy);
|
||||||
}
|
}
|
||||||
return collisions;
|
return collisions;
|
||||||
};
|
};
|
||||||
|
@ -470,7 +347,7 @@
|
||||||
};
|
};
|
||||||
// returns true if the ellipse contains the position defined by the vector 'vec'
|
// returns true if the ellipse contains the position defined by the vector 'vec'
|
||||||
BEllipse.prototype.contains_vec = function(v){
|
BEllipse.prototype.contains_vec = function(v){
|
||||||
v = v.mult_new_xy(this.hx,this.hy);
|
v = v.mult_xy(this.hx,this.hy);
|
||||||
return v.len_sq() <= 1;
|
return v.len_sq() <= 1;
|
||||||
};
|
};
|
||||||
// returns true if the ellipse contains the position (x,y)
|
// returns true if the ellipse contains the position (x,y)
|
||||||
|
|
Loading…
Reference in New Issue