Commit 2a9f4cde authored by amandaghassaei's avatar amandaghassaei
Browse files

adding in static solver

parent 3c7d3cb8
......@@ -531,10 +531,9 @@
<input value="" placeholder="" class="form-control" type="text">
</div>
<br/><br/>
<b>Error:</b><br/>
<b>Error:</b><a class="about floatRight" href="#" id="aboutError"><span class="fui-question-circle"></span></a><br/>
<div class="indent">
<label>Average node error: <span id="globalError"></span></label>
<a class="about floatRight" href="#" id="aboutError"><span class="fui-question-circle"></span></a>
</div><br/>
<b>Animation Settings:</b><a class="about floatRight" href="#" id="aboutAnimation"><span class="fui-question-circle"></span></a><br/>
<div class="indent">
......@@ -710,7 +709,7 @@
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div class="modal fade" id="aboutVRmodal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-med">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
......@@ -733,14 +732,14 @@
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div class="modal fade" id="aboutAnimationModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-med">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<p><b>Animation Settings</b><br/><br/>
The dynamic simulation is calculated by moving time forward in small <b>&Delta; t</b> steps, solving the system, and moving the
The dynamic simulation is calculated by moving time forward in small <b>&Delta;t</b> steps, solving the system, and moving the
vertices of the origami incrementally. The time step size for this animation is calculated automatically
based on the material stiffnesses set in the <b>Stiffness Settings</b> section: more stiff settings
require shorter time steps to solve and will slow down the simulation.<br/>
......@@ -872,7 +871,7 @@
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div class="modal fade" id="aboutErrorModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-med">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
......
......@@ -38,6 +38,9 @@ Beam.prototype.getLength = function(){
Beam.prototype.getOriginalLength = function(){
return this.originalLength;
};
Beam.prototype.recalcOriginalLength = function(){
this.originalLength = this.getVector().length();
};
Beam.prototype.isFixed = function(){
return this.nodes[0].fixed && this.nodes[1].fixed;
......
......@@ -121,17 +121,13 @@ function initControls(globals){
$("#svgViewer").hide();
});
setCheckbox("#dynamic", globals.simType == "dynamic", function(val){
globals.simType = val;
});
setCheckbox("#static", globals.simType == "static", function(val){
globals.simType = val;
});
setCheckbox("#schematic", globals.schematicVisible, function(val){
globals.schematicVisible = val;
});
setRadio("simType", globals.simType, function(val){
if (val == "static"){
globals.staticSolver.syncNodesAndEdges();
} else if (val == "dynamic"){
globals.dynamicSolver.syncNodesAndEdges();
}
globals.simType = val;
});
......
......@@ -10,7 +10,7 @@ function Crease(edge, face1Index, face2Index, targetTheta, type, node1, node2, i
for (var i=0;i<edge.nodes.length;i++){
edge.nodes[i].addInvCrease(this);
}
this.face1Index = face1Index;
this.face1Index = face1Index;//todo this is useless
this.face2Index = face2Index;
this.targetTheta = targetTheta;
this.type = type;
......@@ -38,8 +38,6 @@ Crease.prototype.getNormal2Index = function(){
};
Crease.prototype.getTargetTheta = function(){
// if (this.targetTheta<0) this.edge.setMountain();
// else this.edge.setValley();
return this.targetTheta;
};
......
......@@ -24,7 +24,7 @@ function initModel(globals){
var vertices = [];
function setMeshMaterial() {
var polygonOffset = 2;
var polygonOffset = 0.5;
if (globals.colorMode == "normal") {
material = new THREE.MeshNormalMaterial({
shading:THREE.FlatShading, side: THREE.DoubleSide,
......@@ -168,7 +168,6 @@ function initModel(globals){
function setGeoUpdates(){
geometry.attributes.position.needsUpdate = true;
if (globals.colorMode == "axialStrain") geometry.attributes.color.needsUpdate = true;
else geometry.computeVertexNormals();
if (globals.userInteractionEnabled || globals.vrEnabled) geometry.computeBoundingBox();
// geometry.computeBoundingSphere();
......@@ -330,10 +329,13 @@ function initModel(globals){
vertices[i].multiplyScalar(scale);
}
//update vertices
//update vertices and edges
for (var i=0;i<vertices.length;i++){
nodes[i].setOriginalPosition(positions[3*i], positions[3*i+1], positions[3*i+2]);
}
for (var i=0;i<edges.length;i++){
edges[i].recalcOriginalLength();
}
if (!globals.threeView.running()) reset();
}
......
......@@ -333,8 +333,6 @@ function initPattern(globals){
var edge1 = set1[i];
var edge2 = set2[j];
if ((edge2[0] == edge1[0] || edge2[0] == edge1[1]) && (edge2[1] == edge1[0] || edge2[1] == edge1[1])){
console.log(edge1);
console.log(edge2);
set2.splice(j, 1);
if (set2 == set1) i--;
j--;
......
......@@ -9,6 +9,7 @@ function initStaticSolver(){
var edges;
var faces;
var creases;
var positions;
var Q, C, Ctrans, F, F_rxn;
var Ctrans_Q, Ctrans_Q_C;
......@@ -21,29 +22,34 @@ function initStaticSolver(){
faces = globals.model.getFaces();
creases = globals.model.getCreases();
positions = globals.model.getPositionsArray();
setUpParams();
}
function solve(){
updateMatrices();
solveStep();
}
function reset(){
}
function solveStep(){
console.log("static solve");
if (fixedIndicesMapping.length == 0){//no boundary conditions
var X = initEmptyArray(numVerticesFree*3);
render(X);
console.warn("no boundary conditions");
return;
}
// if (fixedIndicesMapping.length == 0){//no boundary conditions
// var X = initEmptyArray(numVerticesFree*3);
// render(X);
// console.warn("no boundary conditions");
// return;
// }
var _F = F.slice();
for (var i=0;i<_F.length;i++) {
_F[i] += F_rxn[i];
}
X = numeric.dot(numeric.inv(Ctrans_Q_C), _F);
var X = numeric.dot(numeric.inv(Ctrans_Q_C), _F);
console.log(_F);
render(X);
}
......@@ -51,21 +57,24 @@ function initStaticSolver(){
function render(X){
for (var i=0;i<numVerticesFree;i++){
var nodePosition = new THREE.Vector3(X[3*i],X[3*i+1],X[3*i+2]);
var node = nodes[indicesMapping[i]];
node.renderChange(nodePosition);
var index = indicesMapping[i];
var nodePosition = new THREE.Vector3(X[3*i], X[3*i+1], X[3*i+2]);
var nexPos = nodes[index].render(nodePosition);
positions[3*index] = nexPos.x;
positions[3*index+1] = nexPos.y;
positions[3*index+2] = nexPos.z;
}
for (var i=0;i<numVerticesFixed;i++){
nodes[fixedIndicesMapping[i]].render(new THREE.Vector3(0,0,0));
for (var i=0;i<numVerticesFixed;i++){//todo necessary?
var index = fixedIndicesMapping[i];
var nodePosition = new THREE.Vector3(0, 0, 0);
var nexPos = nodes[index].render(nodePosition);
positions[3*index] = nexPos.x;
positions[3*index+1] = nexPos.y;
positions[3*index+2] = nexPos.z;
}
for (var i=0;i<edges.length;i++){
edges[i].render(true);
edges[i].render();
}
geometry.verticesNeedUpdate = true;
geometry.computeFaceNormals();
updateMatrices();
}
function initEmptyArray(dim1, dim2, dim3){
......@@ -109,7 +118,7 @@ function initStaticSolver(){
freeEdgesMapping.push(i);
}
for (var i=0;i<creases.length;i++){
freeCreasesMapping.push(i);//todo check for locked creases
freeCreasesMapping.push(i);
}
numVerticesFree = indicesMapping.length;
......@@ -136,8 +145,6 @@ function initStaticSolver(){
}
updateMatrices();
startSolver();
}
function calcCsAndRxns(){
......@@ -157,60 +164,94 @@ function initStaticSolver(){
C[j][3*i] = edgeVector0.x;
C[j][3*i+1] = edgeVector0.y;
C[j][3*i+2] = edgeVector0.z;
F_rxn[3*i] += edgeVector0.x*rxnForceScale;
F_rxn[3*i+1] += edgeVector0.y*rxnForceScale;
F_rxn[3*i+2] += edgeVector0.z*rxnForceScale;
F_rxn[3*i] -= edgeVector0.x*rxnForceScale;
F_rxn[3*i+1] -= edgeVector0.y*rxnForceScale;
F_rxn[3*i+2] -= edgeVector0.z*rxnForceScale;
}
if (!_nodes[1].fixed) {
var i = indicesMapping.indexOf(_nodes[1].getIndex());
C[j][3*i] = -edgeVector0.x;
C[j][3*i+1] = -edgeVector0.y;
C[j][3*i+2] = -edgeVector0.z;
F_rxn[3*i] -= edgeVector0.x*rxnForceScale;
F_rxn[3*i+1] -= edgeVector0.y*rxnForceScale;
F_rxn[3*i+2] -= edgeVector0.z*rxnForceScale;
F_rxn[3*i] += edgeVector0.x*rxnForceScale;
F_rxn[3*i+1] += edgeVector0.y*rxnForceScale;
F_rxn[3*i+2] += edgeVector0.z*rxnForceScale;
}
}
var geometry = globals.model.getGeometry();
var indices = geometry.index.array;
var normals = [];
//compute all normals
var cb = new THREE.Vector3(), ab = new THREE.Vector3();
for (var j=0;j<indices.length;j+=3){
var index = 3*indices[j];
var vA = new THREE.Vector3(positions[index], positions[index+1], positions[index+2]);
index = 3*indices[j+1];
var vB = new THREE.Vector3(positions[index], positions[index+1], positions[index+2]);
index = 3*indices[j+2];
var vC = new THREE.Vector3(positions[index], positions[index+1], positions[index+2]);
cb.subVectors( vC, vB );
ab.subVectors( vA, vB );
cb.cross( ab );
cb.normalize();
normals.push(cb.clone());
}
for (var j=0;j<numFreeCreases;j++){
var crease = creases[freeCreasesMapping[j]];
var normal1 = geometry.faces[crease.face1Index].normal;
var normal2 = geometry.faces[crease.face2Index].normal;
var normal1 = normals[crease.face1Index];
var normal2 = normals[crease.face2Index];
var dotNormals = normal1.dot(normal2);
if (dotNormals < -1.0) dotNormals = -1.0;
else if (dotNormals > 1.0) dotNormals = 1.0;
var theta = Math.acos(dotNormals);
var creaseVector = crease.getVector();
var sign = (normal1.clone().cross(normal2)).dot(creaseVector);
if (sign < 0.0) theta *= -1.0;
// if (theta > 2.0 && lastTheta[0] < -2.0) theta -= TWO_PI*(1.0+floor(-lastTheta[0]/TWO_PI));
// if (theta < -2.0 && lastTheta[0] > 2.0) theta += TWO_PI*(1.0+floor(lastTheta[0]/TWO_PI));
var creaseVector = crease.getVector().normalize();
//https://math.stackexchange.com/questions/47059/how-do-i-calculate-a-dihedral-angle-given-cartesian-coordinates
var theta = Math.atan2((normal1.clone().cross(creaseVector)).dot(normal2), dotNormals);
var diff = theta - globals.creasePercent*crease.targetTheta;
var rxnForceScale = crease.getK()*diff;
var partial1, partial2;
if (!crease.node1.fixed){
var i = indicesMapping.indexOf(crease.node1.getIndex());
var dist = crease.getLengthToNode1();
C[j+numFreeEdges][3*i] = -normal1.x/dist;
C[j+numFreeEdges][3*i+1] = -normal1.y/dist;
C[j+numFreeEdges][3*i+2] = -normal1.z/dist;
rxnForceScale = crease.getK()*diff/dist;
F_rxn[3*i] += normal1.x*rxnForceScale;
F_rxn[3*i+1] += normal1.y*rxnForceScale;
F_rxn[3*i+2] += normal1.z*rxnForceScale;
var partial1 = normal1.clone().divideScalar(dist);
C[j+numFreeEdges][3*i] = partial1.x;
C[j+numFreeEdges][3*i+1] = partial1.y;
C[j+numFreeEdges][3*i+2] = partial1.z;
F_rxn[3*i] -= partial1.x*rxnForceScale;
F_rxn[3*i+1] -= partial1.y*rxnForceScale;
F_rxn[3*i+2] -= partial1.z*rxnForceScale;
}
if (!crease.node2.fixed){
var i = indicesMapping.indexOf(crease.node2.getIndex());
var dist = crease.getLengthToNode2();
C[j+numFreeEdges][3*i] = -normal2.x/dist;
C[j+numFreeEdges][3*i+1] = -normal2.y/dist;
C[j+numFreeEdges][3*i+2] = -normal2.z/dist;
rxnForceScale = crease.getK()*diff/dist;
F_rxn[3*i] += normal2.x*rxnForceScale;
F_rxn[3*i+1] += normal2.y*rxnForceScale;
F_rxn[3*i+2] += normal2.z*rxnForceScale;
var partial2 = normal2.clone().divideScalar(dist);
C[j+numFreeEdges][3*i] = partial2.x;
C[j+numFreeEdges][3*i+1] = partial2.y;
C[j+numFreeEdges][3*i+2] = partial2.z;
F_rxn[3*i] -= partial2.x*rxnForceScale;
F_rxn[3*i+1] -= partial2.y*rxnForceScale;
F_rxn[3*i+2] -= partial2.z*rxnForceScale;
}
var creaseNodes = crease.edge.nodes;
for (var k=0;k<creaseNodes.length;k++){
var node = creaseNodes[k];
if (node.fixed) continue;
var i = indicesMapping.indexOf(node.getIndex());
C[j+numFreeEdges][3*i] = -(partial1.x+partial2.x)/2;
C[j+numFreeEdges][3*i+1] = -(partial1.y+partial2.y)/2;
C[j+numFreeEdges][3*i+2] = -(partial1.z+partial2.z)/2;
F_rxn[3*i] += (partial1.x+partial2.x)/2*rxnForceScale;
F_rxn[3*i+1] += (partial1.y+partial2.y)/2*rxnForceScale;
F_rxn[3*i+2] += (partial1.z+partial2.z)/2*rxnForceScale;
}
}
}
......
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