Mercurial > hg > digilib
changeset 1371:a71ca1a6251c
oval construction; some new line geometry functions
author | hertzhaft |
---|---|
date | Mon, 23 Feb 2015 17:51:22 +0100 |
parents | eaa128e7cb14 |
children | 5da9dc7b5f42 |
files | webapp/src/main/webapp/jquery/jquery.digilib.geometry.js webapp/src/main/webapp/jquery/jquery.digilib.measure.css webapp/src/main/webapp/jquery/jquery.digilib.measure.js |
diffstat | 3 files changed, 102 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/webapp/src/main/webapp/jquery/jquery.digilib.geometry.js Mon Feb 23 01:01:35 2015 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.geometry.js Mon Feb 23 17:51:22 2015 +0100 @@ -111,7 +111,7 @@ y : parseFloat(y) }; }; - // returns a copy of this Rectangle + // return a copy of this position that.copy = function() { return position(this); }; @@ -119,7 +119,7 @@ that.equals = function(other) { return (this.x === other.x && this.y === other.y); }; - // add position other to this + // add vector or position to this that.add = function(other) { if ($.isArray(other)) { this.x += other[0]; @@ -173,23 +173,35 @@ var dy = pos.y - this.y; return Math.sqrt(dx * dx + dy * dy); }; + // nearest of several points + that.nearest = function (points) { + var nearest = points[0]; + var dist = this.distance(nearest); + $.each(points, function(index, item) { + var len = this.distance(item); + if (len < dist) { + dist = len; + nearest = item; + } + }); + return nearest; + }; // 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); - } + }; // degree of angle between line and the positive X axis that.deg = function (pos) { return this.rad(pos) / Math.PI * 180; - } + }; // returns position in css-compatible format that.getAsCss = function() { @@ -265,11 +277,15 @@ that.perpendicularVector = function(clockwise) { return clockwise ? [-this.dy, this.dx] : [this.dy, -this.dx]; }; + // vector distance + that.dist = function() { + return Math.sqrt(this.dx * this.dx + this.dy * this.dy); + }; // get/set vector length that.length = function(length) { - var dist = Math.sqrt(this.dx * this.dx + this.dy * this.dy); + var dist = this.dist(); if (length == null) { - return dist; + return this.dist; } var ratio = length/dist; this.dx *= ratio; @@ -308,22 +324,39 @@ return line(p, this.perpendicularPoint(p)); }; // return point in mirrored position (with regard to this line) - that.mirrorPoint = function(p) { + that.mirror = function(p) { var line = this.perpendicularLine(p); - return line.add(line.vector()); + return line.addEnd(line.vector()); }; - // return a point (position) by adding a vector to the definition point - that.add = function(vector) { - return $.isArray(vector) - ? position(this.x + vector[0], this.y + vector[1]) - : position(this.x + vector.x, this.y + vector.y); + // return a position by adding a vector/position/distance to origin + that.add = function(item) { + if (item == null) { + return this.origin(); + } else if ($.isArray(item)) { // add a vector + return position(this.x + item[0], this.y + item[1]) + } else if (item.x != null) { // add a position + return position(this.x + item.x, this.y + item.y); + } else if (typeof item === 'number' && isFinite(item)) { // add a distance + ratio = item/this.dist(); + return position(this.x + this.dx*ratio, this.y + this.dy*ratio); + } else { + return this.origin(); + } }; - // point on the line, moved from origin by factor + // return a position by adding a vector/position/distance to end point + that.addEnd = function(item) { + return this.add(item).add(this.vector()); + }; + // end point on the line (pointed to by vector) that.point = function(factor) { if (factor == null) { factor = 1; } var vector = [factor*this.dx, factor*this.dy]; return this.add(vector); }; + // midpoint on the line (half of vector distance, multiplied by factor) + that.mid = function(factor) { + return this.origin().mid(this.point(factor)); + }; // factor of point (assuming it is on the line) that.factor = function(p) { return (dx === 0)
--- a/webapp/src/main/webapp/jquery/jquery.digilib.measure.css Mon Feb 23 01:01:35 2015 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.measure.css Mon Feb 23 17:51:22 2015 +0100 @@ -99,3 +99,10 @@ .dl-measure-selected { stroke: cyan; } + +.dl-measure-guide { + stroke: blue; + stroke-dasharray: 10 5; + fill: none; +} +
--- a/webapp/src/main/webapp/jquery/jquery.digilib.measure.js Mon Feb 23 01:01:35 2015 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.measure.js Mon Feb 23 17:51:22 2015 +0100 @@ -1189,14 +1189,13 @@ var p = props.screenpos; var vtx = props.vtx; 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); // base line + var line1 = geom.line(p[0], p[1]); // base line var line2 = line1.parallel(p[2]); var p3 = line1.perpendicular().intersection(line2); - var p2 = p3.copy().add(d); + var p2 = p3.copy().add(line1.vector()); p[2] = p2.mid(p3); // handle position shape.geometry.coordinates[2] = trafo.invtransform(p[2]).toArray(); - props.pos = [p3, p2]; // save other points + props.pos = [p2, p3]; // save other points } this.attr({points: [p[0], p[1], p2, p3].join(" ")}); }; @@ -1205,31 +1204,56 @@ factory['Oval'] = function (shape) { var trafo = data.imgTrafo; var $s = factory['Rect'](shape); + var props = shape.properties; var place = $s.place; - var props = shape.properties; + var guide = CSS+'measure-guide'; + $s.attr({'class' : guide}); props.maxvtx = 4; var $g = $(fn.svgElement('g', {'id': shape.id + '-oval'})); - var $c1 = $(fn.svgElement('circle', {'id': shape.id + '-circle1', stroke: props.stroke, fill: 'none'})); - var $c2 = $(fn.svgElement('circle', {'id': shape.id + '-circle2', stroke: props.stroke, fill: 'none'})); - var $l1 = $(fn.svgElement('line', {'id': shape.id + '-line1', stroke: props.stroke })); - var $l2 = $(fn.svgElement('line', {'id': shape.id + '-line2', stroke: props.stroke })); - $g.append($s).append($c1).append($c2).append($l1).append($l2); + var $c1 = $(fn.svgElement('circle', {'id': shape.id + '-circ1', 'class': guide })); + var $c2 = $(fn.svgElement('circle', {'id': shape.id + '-circ2', 'class': guide })); + var $p1 = $(fn.svgElement('path', {'id': shape.id + '-lines', 'class': guide })); + var $p2 = $(fn.svgElement('path', {'id': shape.id + '-arc', stroke: props.stroke, fill: 'none' })); + $g.append($s).append($c1).append($c2).append($p1).append($p2); $g.place = function () { var p = props.screenpos; place.call($s); if (p.length > 3) { // p[3] is the mouse pointer - var mp0 = p[0].mid(p[1]); - var line1 = geom.line(p[2], mp0); - var mp1 = line1.perpendicularPoint(p[3]); - var radius = mp1.distance(p[2]); - var mp2 = geom.line(mp0, p[2]).length(radius).point(); - var pt = geom.line(p[0], p[1]).parallel(p[0].mid(props.pos[0])).length(radius).point(); - $c1.attr({cx: mp1.x, cy: mp1.y, r: radius}); - $c2.attr({cx: mp2.x, cy: mp2.y, r: radius}); - $l1.attr({x1: mp1.x, y1: mp1.y, x2 : pt.x, y2 : pt.y}); - $l2.attr({x1: mp2.x, y1: mp2.y, x2 : pt.x, y2 : pt.y}); - p[3] = mp1; - shape.geometry.coordinates[3] = trafo.invtransform(p[3]).toArray(); + var side0 = geom.line(p[0], p[1]) + var side1 = geom.line(p[1], props.pos[0]); + var side2 = geom.line(props.pos[0], props.pos[1]); + var side3 = geom.line(props.pos[1], p[0]); + var pt0 = side0.mid(); // midpoint of base line + var axis1 = geom.line(p[2], pt0); // longitudinal axis + var handle = axis1.perpendicularPoint(p[3]); // drag point projected on axis + var mp1 = handle.mid(p[2]); // midpoint of first small circle + var rad1 = mp1.distance(p[2]); // radius of small circles + var mp2 = geom.line(pt0, p[2]).length(rad1).point(); // midpoint of second small circle + var pt1 = side1.mid(); // midpoints of long axis + var pt2 = side3.mid(); + var axis2 = side0.parallel(pt2); // short axis + var pt3 = axis2.copy().length(rad1).point(); // radius distance from short axis + var mp3 = axis2.intersection(geom.line(pt3, mp1).perpendicular(pt2.mid(mp1))); // perpendicular bisector + var mp4 = axis1.mirror(mp3); + var sp1 = geom.line(mp3, mp1).addEnd(rad1); // the lozenge of midpoints + var sp2 = geom.line(mp3, mp2).addEnd(rad1); + var sp3 = geom.line(mp4, mp1).addEnd(rad1); + var sp4 = geom.line(mp4, mp2).addEnd(rad1); + var rad2 = mp3.distance(sp1); // radius of big circles + $c1.attr({cx: mp1.x, cy: mp1.y, r: rad1}); + $c2.attr({cx: mp2.x, cy: mp2.y, r: rad1}); + $p1.attr({d: + 'M'+sp1+' L'+mp3+' '+sp2+ + 'M'+sp3+' L'+mp4+' '+sp4+ + 'M'+pt0+' L'+p[2]+ + 'M'+pt1+' L'+pt2}); + $p2.attr({d: 'M'+sp2+ + ' A'+rad2+','+rad2+' 0 0,1 '+sp1+ + ' A'+rad1+','+rad1+' 0 0,1 '+sp3+ + ' A'+rad2+','+rad2+' 0 0,1 '+sp4+ + ' A'+rad1+','+rad1+' 0 0,1 '+sp2}); + p[3] = handle; + shape.geometry.coordinates[3] = trafo.invtransform(handle).toArray(); } }; return $g;