convex constraint

This commit is contained in:
Val Erastov 2016-05-27 20:36:44 -07:00
parent 2471272ee4
commit 17b7c8bade
5 changed files with 257 additions and 20 deletions

View file

@ -26,6 +26,8 @@ TCAD.constraints.create = function(name, params, values) {
var _ = true, x = false;
// Exclude angle value from parameters
return new TCAD.constraints.ConstantWrapper(new TCAD.constraints.Angle(params), [x,x,x,x,x,x,x,x,_]);
case 'LockConvex':
return new TCAD.constraints.LockConvex(params);
}
};
@ -82,6 +84,47 @@ TCAD.constraints.MinLength = function(params, distance) {
}
};
TCAD.constraints.LockConvex = function(params) {
this.params = params;
var _pcx = 0;
var _pcy = 1;
var _pax = 2;
var _pay = 3;
var _ptx = 4;
var _pty = 5;
this.error = function() {
var cx = params[_pcx].get();
var cy = params[_pcy].get();
var ax = params[_pax].get();
var ay = params[_pay].get();
var tx = params[_ptx].get();
var ty = params[_pty].get();
var crossProductNorm = (cx - ax) * (ty - ay) - (cy - ay) * (tx - ax);
var violate = crossProductNorm < 0;
return violate ? crossProductNorm : 0;
};
this.gradient = function(out) {
var cx = params[_pcx].get();
var cy = params[_pcy].get();
var ax = params[_pax].get();
var ay = params[_pay].get();
var tx = params[_ptx].get();
var ty = params[_pty].get();
out[_pcx] = ty-ay;
out[_pcy] = ax-tx;
out[_pax] = cy-ty;
out[_pay] = tx-cx;
out[_ptx] = ay-cy;
out[_pty] = cx-ax;
}
};
/** @constructor */
TCAD.constraints.ConstantWrapper = function(constr, mask) {

View file

@ -193,6 +193,9 @@ TCAD.App2D = function() {
this.registerAction('symmetry', "Symmetry", function () {
app.viewer.parametricManager.symmetry(app.viewer.selected, prompt);
});
this.registerAction('lockConvex', "Lock Convexity", function () {
app.viewer.parametricManager.lockConvex(app.viewer.selected, alert);
});
this.registerAction('analyzeConstraint', "Analyze Constraint", function () {
app.viewer.parametricManager.analyze(alert);

View file

@ -167,6 +167,56 @@ TCAD.TWO.ParametricManager.prototype.perpendicular = function(objs) {
this.add(new TCAD.TWO.Constraints.Perpendicular(lines[0], lines[1]));
};
TCAD.TWO.ParametricManager.prototype.lockConvex = function(objs, warnCallback) {
var lines = this._fetchTwoLines(objs);
var l1 = lines[0];
var l2 = lines[1];
var pts =[l1.a, l1.b, l2.a, l2.b];
function isLinked(p1, p2) {
for (var i = 0; i < p1.linked.length; ++i) {
if (p1.linked[i].id === p2.id) {
return true;
}
}
return false;
}
function swap(arr, i1, i2) {
var _ = arr[i1];
arr[i1] = arr[i2];
arr[i2] = _;
}
if (isLinked(pts[0], pts[2])) {
swap(pts, 0, 1);
} else if (isLinked(pts[0], pts[3])) {
swap(pts, 0, 1);
swap(pts, 2, 3);
} else if (isLinked(pts[1], pts[3])) {
swap(pts, 2, 3);
} else if (isLinked(pts[1], pts[2])) {
//we are good
} else {
warnCallback("Lines must be connected");
return;
}
var c = pts[0];
var a = pts[1];
var t = pts[3];
// ||ac x at|| > 0
var crossNorma = (c.x - a.x) * (t.y - a.y) - (c.y - a.y) * (t.x - a.x);
if (crossNorma < 0) {
var _ = c;
c = t;
t = _;
}
this.add(new TCAD.TWO.Constraints.LockConvex(c, a, t));
};
TCAD.TWO.ParametricManager.prototype.tangent = function(objs) {
var al = this._fetchArcCircAndLine(objs);
var arc = al[0];
@ -721,6 +771,25 @@ TCAD.TWO.ParametricManager.prototype.prepareForSubSystem = function(locked, subS
return solver;
};
TCAD.TWO.Constraints.ParentsCollector = function() {
this.parents = [];
var parents = this.parents;
var index = {};
function add(obj) {
if (index[obj.id] === undefined) {
index[obj.id] = obj;
parents.push(obj);
}
}
this.check = function(obj) {
if (obj.parent !== null) {
add(obj.parent);
} else {
add(obj);
}
};
};
TCAD.TWO.Constraints.Factory = {};
// ------------------------------------------------------------------------------------------------------------------ //
@ -1348,28 +1417,50 @@ TCAD.TWO.Constraints.Factory[TCAD.TWO.Constraints.Angle.prototype.NAME] = functi
};
TCAD.TWO.Constraints.Angle.prototype.getObjects = function() {
var out = [];
var index = {};
function add(obj) {
if (index[obj.id] === undefined) {
index[obj.id] = obj;
out.push(obj);
}
}
function check(obj) {
if (obj.parent !== null) {
add(obj.parent);
} else {
add(obj);
}
}
check(this.p1);
check(this.p2);
check(this.p3);
check(this.p4);
return out;
var collector = new TCAD.TWO.Constraints.ParentsCollector();
collector.check(this.p1);
collector.check(this.p2);
collector.check(this.p3);
collector.check(this.p4);
return collector.parents;
};
TCAD.TWO.Constraints.Angle.prototype.SettableFields = {'angle' : "Enter the angle value"};
// ------------------------------------------------------------------------------------------------------------------ //
/** @constructor */
TCAD.TWO.Constraints.LockConvex = function(c, a, t) {
this.c = c;
this.a = a;
this.t = t;
};
TCAD.TWO.Constraints.LockConvex.prototype.NAME = 'LockConvex';
TCAD.TWO.Constraints.LockConvex.prototype.UI_NAME = 'Lock Convexity';
TCAD.TWO.Constraints.LockConvex.prototype.getSolveData = function() {
var params = [];
this.c.collectParams(params);
this.a.collectParams(params);
this.t.collectParams(params);
return [['LockConvex', params, []]];
};
TCAD.TWO.Constraints.LockConvex.prototype.serialize = function() {
return [this.NAME, [this.c.id, this.a.id, this.t.id]];
};
TCAD.TWO.Constraints.Factory[TCAD.TWO.Constraints.LockConvex.prototype.NAME] = function(refs, data) {
return new TCAD.TWO.Constraints.LockConvex(refs(data[0]), refs(data[1]), refs(data[2]));
};
TCAD.TWO.Constraints.LockConvex.prototype.getObjects = function() {
var collector = new TCAD.TWO.Constraints.ParentsCollector();
collector.check(this.c);
collector.check(this.a);
collector.check(this.t);
return collector.parents;
};
// ------------------------------------------------------------------------------------------------------------------ //

99
web/img/vec/convex.svg Normal file
View file

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="35"
height="35"
viewBox="0 0 34.999999 34.999996"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="convex.svg">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="159.63273 : 549.86846 : 1"
inkscape:vp_y="0 : 999.99987 : 0"
inkscape:vp_z="744.09445 : 526.18102 : 1"
inkscape:persp3d-origin="372.04723 : 350.78736 : 1"
id="perspective4168" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#545454"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="15.535661"
inkscape:cx="12.681338"
inkscape:cy="24.986016"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="false"
inkscape:snap-global="true"
inkscape:window-width="1858"
inkscape:window-height="1178"
inkscape:window-x="54"
inkscape:window-y="-8"
inkscape:window-maximized="1"
units="px"
width="100mm" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1017.3622)">
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.76900005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 4.1992958,1022.4097 13.3656642,25.6954 13.297765,-25.9348"
id="path4184"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<circle
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.35827634px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3336-3"
cx="30.077709"
cy="1023.4678"
r="3.3208618" />
<circle
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.35827634px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3336-3-0"
cx="4.3586669"
cy="1022.4956"
r="3.3208618" />
<circle
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.35827634px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path3336-3-7"
cx="17.443739"
cy="1047.6632"
r="3.3208618" />
<path
style="fill:#00ff00;fill-opacity:0.18934911;stroke:none;stroke-width:0.12873608;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 15.97966,24.63144 C 15.35824,23.435127 13.259765,19.400453 11.316384,15.665498 L 7.7829621,8.8746696 12.633078,8.858173 c 2.667563,-0.00907 7.034303,-0.00907 9.703865,0 l 4.853749,0.016497 -4.589179,8.947157 -4.589177,8.947157 -0.45141,0.01879 -0.451411,0.01879 -1.129855,-2.175115 z"
id="path4185"
inkscape:connector-curvature="0"
transform="translate(0,1017.3622)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -88,6 +88,7 @@
<button class="btn rbtn act-pointInMiddle" style="background-image: url(img/vec/pointInMiddle.svg);"></button>
<button class="btn rbtn act-llAngle" style="background-image: url(img/vec/angle.svg);"></button>
<button class="btn rbtn act-symmetry" style="background-image: url(img/vec/symmetry.svg);"></button>
<button class="btn rbtn act-lockConvex" style="background-image: url(img/vec/convex.svg);"></button>
<button class="btn rbtn act-lockConstraint" ><i class="fa fa-lock"></i></button>
</div>
<div style="background: black; overflow: hidden; height: 100%;">