Commit a98721a9 authored by hertzhaft's avatar hertzhaft

draw rectangle with only 3 handles; first step towards oval

parent b5f7e682
......@@ -159,7 +159,7 @@
this.y = Math.max(this.y, p1.y);
this.x = Math.min(this.x, p2.x);
this.y = Math.min(this.y, p2.y);
return this;
return this;
};
// returns distance of this position to pos (length if pos == null)
that.distance = function(pos) {
......@@ -173,6 +173,14 @@
var dy = pos.y - this.y;
return Math.sqrt(dx * dx + dy * dy);
};
// midpoint of this and other pos
that.mid = function (pos) {
return position({
x : (this.x + pos.x)/2,
y : (this.y + pos.y)/2
});
return ;
}
// radians of angle between line and the positive X axis
that.rad = function (pos) {
return Math.atan2(pos.y - this.y, pos.x - this.x);
......@@ -231,17 +239,23 @@
that.dx = 1;
that.dy = 1;
}
that.ratio = that.dx/that.dy; // slope
// slope
that.slope = function() {
return this.dx/this.dy;
};
// return a copy
that.copy = function() {
return line(position(this.x, this.y), this.ratio);
return line(position(this.x, this.y), [this.dx, this.dy]);
};
// return a parallel through a point
that.parallel = function(p) {
return line(position(p.x, p.y), [this.dx, this.dy]);
};
// return orthogonal line
that.orthogonal = function() {
return (this.ratio === Infinity || this.ratio === -Infinity)
? line(position(this.x, this.y), 0)
: line(position(this.x, this.y), [-this.dy, this.dx]);
// return perpendicular line, with optional directon
that.perpendicular = function(clockwise) {
var delta = clockwise ? [-this.dy, this.dx] : [this.dy, -this.dx];
return line(position(this.x, this.y), delta)
};
// return a point (position) by adding a vector to the definition point
that.add = function(q) {
......@@ -249,17 +263,17 @@
? position(this.x + q[0], this.y + q[1])
: position(this.x + q.x, this.y + q.y);
};
// point on line
// point on line, moved from origin by factor
that.point = function(factor) {
return position(this.x + factor*this.dx, this.y + factor*this.dy)
};
// intersection point with other line
that.intersection = function(other) {
var det = this.dy*other.dx - this.dx*other.dy
that.intersection = function(line) {
var det = this.dy*line.dx - this.dx*line.dy
if (det === 0) { // parallel
return null; }
var c = this.dx*(other.y - this. y) + this.dy*(this.x - other.x);
return other.point(c/det);
var c = this.dx*(line.y - this. y) + this.dy*(this.x - line.x);
return line.point(c/det);
};
return that;
};
......
......@@ -708,7 +708,7 @@
// color while the line is drawn
drawColor : 'green',
// implemented measuring shape types, for select widget
implementedShapes : ['Line', 'LineString', 'Proportion', 'Rect', 'Rectangle', 'Polygon', 'Circle', 'Ellipse', 'Grid'],
implementedShapes : ['Line', 'LineString', 'Proportion', 'Rect', 'Rectangle', 'Polygon', 'Circle', 'Ellipse', 'Oval', 'Grid'],
// all measuring shape types
shapeInfo : {
Line : { name : 'line', display : 'length', },
......@@ -720,10 +720,8 @@
Polygon : { name : 'polygon', display : 'area' },
Circle : { name : 'circle', display : 'radius' },
Ellipse : { name : 'ellipse', display : 'area' },
Arch : { name : 'arch', display : 'radius' },
Ratio : { name : 'ratio', display : 'ratio' },
Grid : { name : 'linegrid', display : 'spacing' },
InterCol : { name : 'intercolumnium', display : 'ratio' }
Oval : { name : 'oval', display : 'length' },
Grid : { name : 'linegrid', display : 'spacing' }
},
// currently selected shape type
activeShapeType : 'Line',
......@@ -1189,34 +1187,51 @@
props.maxvtx = 3;
$s.place = function () {
var p = props.screenpos;
var g = shape.geometry;
var vtx = props.vtx;
if (p.length > 2) {
var pt = (vtx > 1) ? p[vtx] : p[2];
if (p.length > 2) { // p[2] is the mouse pointer
var d = p[0].delta(p[1]).toArray();
var line1 = geom.line(p[0], d);
var line2 = geom.line(pt, d); // parallel (same slope)
var orth = line1.orthogonal();
p[3] = orth.intersection(line2);
p[2] = p[3].copy().add(d);
g.coordinates[2] = trafo.invtransform(p[2]).toArray();
g.coordinates[3] = trafo.invtransform(p[3]).toArray();
var line1 = geom.line(p[0], d); // base line
var line2 = line1.parallel(p[2]);
var p3 = line1.perpendicular().intersection(line2);
var p2 = p3.copy().add(d);
p[2] = p2.mid(p3); // handle position
shape.geometry.coordinates[2] = trafo.invtransform(p[2]).toArray();
}
this.attr({'points': p.join(" ")});
this.attr({points: [p[0], p[1], p2, p3].join(" ")});
};
return $s;
};
factory['Oval'] = function (shape) {
var $s = factory['Rect'](shape);
var place = $s.place;
var props = shape.properties;
props.maxvtx = 4;
var $g = $(fn.svgElement('g', {'id': shape.id + '-oval'}));
var $c = $(fn.svgElement('circle', {'id': shape.id + '-circle', stroke: props.stroke, fill: 'none'}));
$g.append($s).append($c);
$g.place = function () {
var p = props.screenpos;
var vtx = props.vtx;
place.call($s);
if (p.length > 3) { // p[3] is the mouse pointer
var m = p[2].mid(p[3]);
var r = m.distance(p[2]);
$c.attr({cx: m.x, cy: m.y, r: r});
}
};
return $g;
};
factory['Grid'] = function (shape) {
var $s = factory['Line'](shape);
var place = $s.place;
var gridID = shape.id + '-grid';
var props = shape.properties;
props.maxvtx = 2;
var $g = $(fn.svgElement('g', {'id': shape.id + '-g'}));
var $g = $(fn.svgElement('g', {id: shape.id + '-g'}));
var $defs = $(fn.svgElement('defs'));
var $pat = $(fn.svgElement('pattern', {'id': gridID, 'height': '10%', 'width': '10%', 'patternUnits': 'objectBoundingBox'}));
var $path = $(fn.svgElement('path', {'d': "M100,0 L0,0 0,100", 'fill': 'none', 'stroke': props.stroke, 'stroke-width': '1'}));
var $r = $(fn.svgElement('rect', {'id': shape.id + '-rect', stroke: props.stroke, fill: 'url(#'+gridID+')'}));
var $pat = $(fn.svgElement('pattern', {id: gridID, height: '10%', width: '10%', patternUnits: 'objectBoundingBox'}));
var $path = $(fn.svgElement('path', {d: "M100,0 L0,0 0,100", fill: 'none', stroke: props.stroke, 'stroke-width': '1'}));
var $r = $(fn.svgElement('rect', {id: shape.id + '-rect', stroke: props.stroke, fill: 'url(#'+gridID+')'}));
$g.append($defs.append($pat.append($path))).append($r).append($s);
$g.place = function () {
place.call($s);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment