Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Amanda Ghassaei
OrigamiSimulator
Commits
109d726a
Commit
109d726a
authored
May 26, 2017
by
amandaghassaei
Browse files
working on a rigid solver
parent
2a9f4cde
Changes
10
Hide whitespace changes
Inline
Side-by-side
index.html
View file @
109d726a
...
...
@@ -388,6 +388,7 @@
<script
type=
"text/javascript"
src=
"js/3dUI.js"
></script>
<script
type=
"text/javascript"
src=
"js/staticSolver.js"
></script>
<script
type=
"text/javascript"
src=
"js/dynamic/dynamicSolver.js"
></script>
<script
type=
"text/javascript"
src=
"js/rigidSolver.js"
></script>
<script
type=
"text/javascript"
src=
"js/pattern.js"
></script>
<script
type=
"text/javascript"
src=
"js/saveSTL.js"
></script>
<script
type=
"text/javascript"
src=
"js/saveFOLD.js"
></script>
...
...
@@ -508,6 +509,10 @@
<input
name=
"simType"
value=
"static"
data-toggle=
"radio"
class=
"custom-radio"
type=
"radio"
><span
class=
"icons"
><span
class=
"icon-unchecked"
></span><span
class=
"icon-checked"
></span></span>
Compliant Static Simulation
<a
class=
"about floatRight"
href=
"#"
id=
"aboutStaticSim"
><span
class=
"fui-question-circle"
></span></a>
</label>
<label
class=
"radio"
>
<input
name=
"simType"
value=
"rigid"
data-toggle=
"radio"
class=
"custom-radio"
type=
"radio"
><span
class=
"icons"
><span
class=
"icon-unchecked"
></span><span
class=
"icon-checked"
></span></span>
Rigid Static Simulation
<a
class=
"about floatRight"
href=
"#"
id=
"aboutRigidSim"
><span
class=
"fui-question-circle"
></span></a>
</label>
</div><br/>
<label
class=
"checkbox"
for=
"userInteractionEnabled"
>
<input
id=
"userInteractionEnabled"
data-toggle=
"checkbox"
class=
"custom-checkbox layersSelector"
type=
"checkbox"
><span
class=
"icons"
><span
class=
"icon-unchecked"
></span><span
class=
"icon-checked"
></span></span>
...
...
@@ -937,6 +942,20 @@
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
<div
class=
"modal fade"
id=
"aboutRigidSimModal"
tabindex=
"-1"
role=
"dialog"
>
<div
class=
"modal-dialog modal-med"
>
<div
class=
"modal-content"
>
<div
class=
"modal-body"
>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
<p><b>
Rigid Static Simulation
</b><br/><br/>
....
</p>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
<div
class=
"modal fade"
id=
"aboutAxialStrainModal"
tabindex=
"-1"
role=
"dialog"
>
<div
class=
"modal-dialog modal-med"
>
<div
class=
"modal-content"
>
...
...
js/controls.js
View file @
109d726a
...
...
@@ -123,12 +123,8 @@ function initControls(globals){
setRadio
(
"
simType
"
,
globals
.
simType
,
function
(
val
){
if
(
val
==
"
static
"
){
globals
.
staticSolver
.
syncNodesAndEdges
();
}
else
if
(
val
==
"
dynamic
"
){
globals
.
dynamicSolver
.
syncNodesAndEdges
();
}
globals
.
simType
=
val
;
globals
.
needsSync
=
true
;
});
setSliderInput
(
"
#axialStiffness
"
,
globals
.
axialStiffness
,
10
,
40
,
1
,
function
(
val
){
...
...
@@ -252,6 +248,9 @@ function initControls(globals){
setLink
(
"
#aboutStaticSim
"
,
function
(){
$
(
"
#aboutStaticSimModal
"
).
modal
(
"
show
"
);
});
setLink
(
"
#aboutRigidSim
"
,
function
(){
$
(
"
#aboutRigidSimModal
"
).
modal
(
"
show
"
);
});
setLink
(
"
#aboutAxialStrain
"
,
function
(){
$
(
"
#aboutAxialStrainModal
"
).
modal
(
"
show
"
);
});
...
...
js/dynamic/dynamicSolver.js
View file @
109d726a
...
...
@@ -38,7 +38,7 @@ function initDynamicSolver(globals){
faces
=
globals
.
model
.
getFaces
();
creases
=
globals
.
model
.
getCreases
();
globals
.
model
.
sync
();
//
globals.model.sync();
positions
=
globals
.
model
.
getPositionsArray
();
colors
=
globals
.
model
.
getColorsArray
();
...
...
@@ -64,49 +64,45 @@ function initDynamicSolver(globals){
}
function
solve
(
_numSteps
){
if
(
globals
.
shouldSyncWithModel
){
syncNodesAndEdges
();
globals
.
shouldSyncWithModel
=
false
;
}
else
{
if
(
globals
.
forceHasChanged
)
{
updateExternalForces
();
globals
.
forceHasChanged
=
false
;
}
if
(
globals
.
fixedHasChanged
)
{
updateFixed
();
globals
.
fixedHasChanged
=
false
;
}
if
(
globals
.
nodePositionHasChanged
)
{
updateLastPosition
();
globals
.
nodePositionHasChanged
=
false
;
}
if
(
globals
.
creaseMaterialHasChanged
)
{
updateCreasesMeta
();
globals
.
creaseMaterialHasChanged
=
false
;
}
if
(
globals
.
materialHasChanged
)
{
updateMaterials
();
globals
.
materialHasChanged
=
false
;
}
if
(
globals
.
shouldChangeCreasePercent
)
{
setCreasePercent
(
globals
.
creasePercent
);
globals
.
shouldChangeCreasePercent
=
false
;
}
// if (globals.shouldZeroDynamicVelocity){
// globals.gpuMath.step("zeroTexture", [], "u_velocity");
// globals.gpuMath.step("zeroTexture", [], "u_lastVelocity");
// globals.shouldZeroDynamicVelocity = false;
// }
if
(
globals
.
shouldCenterGeo
){
var
avgPosition
=
getAvgPosition
();
globals
.
gpuMath
.
setProgram
(
"
centerTexture
"
);
globals
.
gpuMath
.
setUniformForProgram
(
"
centerTexture
"
,
"
u_center
"
,
[
avgPosition
.
x
,
avgPosition
.
y
,
avgPosition
.
z
],
"
3f
"
);
globals
.
gpuMath
.
step
(
"
centerTexture
"
,
[
"
u_lastPosition
"
],
"
u_position
"
);
globals
.
gpuMath
.
swapTextures
(
"
u_position
"
,
"
u_lastPosition
"
);
globals
.
gpuMath
.
step
(
"
zeroTexture
"
,
[],
"
u_lastVelocity
"
);
globals
.
gpuMath
.
step
(
"
zeroTexture
"
,
[],
"
u_velocity
"
);
globals
.
shouldCenterGeo
=
false
;
}
if
(
globals
.
forceHasChanged
)
{
updateExternalForces
();
globals
.
forceHasChanged
=
false
;
}
if
(
globals
.
fixedHasChanged
)
{
updateFixed
();
globals
.
fixedHasChanged
=
false
;
}
if
(
globals
.
nodePositionHasChanged
)
{
updateLastPosition
();
globals
.
nodePositionHasChanged
=
false
;
}
if
(
globals
.
creaseMaterialHasChanged
)
{
updateCreasesMeta
();
globals
.
creaseMaterialHasChanged
=
false
;
}
if
(
globals
.
materialHasChanged
)
{
updateMaterials
();
globals
.
materialHasChanged
=
false
;
}
if
(
globals
.
shouldChangeCreasePercent
)
{
setCreasePercent
(
globals
.
creasePercent
);
globals
.
shouldChangeCreasePercent
=
false
;
}
// if (globals.shouldZeroDynamicVelocity){
// globals.gpuMath.step("zeroTexture", [], "u_velocity");
// globals.gpuMath.step("zeroTexture", [], "u_lastVelocity");
// globals.shouldZeroDynamicVelocity = false;
// }
if
(
globals
.
shouldCenterGeo
){
var
avgPosition
=
getAvgPosition
();
globals
.
gpuMath
.
setProgram
(
"
centerTexture
"
);
globals
.
gpuMath
.
setUniformForProgram
(
"
centerTexture
"
,
"
u_center
"
,
[
avgPosition
.
x
,
avgPosition
.
y
,
avgPosition
.
z
],
"
3f
"
);
globals
.
gpuMath
.
step
(
"
centerTexture
"
,
[
"
u_lastPosition
"
],
"
u_position
"
);
globals
.
gpuMath
.
swapTextures
(
"
u_position
"
,
"
u_lastPosition
"
);
globals
.
gpuMath
.
step
(
"
zeroTexture
"
,
[],
"
u_lastVelocity
"
);
globals
.
gpuMath
.
step
(
"
zeroTexture
"
,
[],
"
u_velocity
"
);
globals
.
shouldCenterGeo
=
false
;
}
if
(
_numSteps
==
undefined
)
_numSteps
=
globals
.
numSteps
;
...
...
js/globals.js
View file @
109d726a
...
...
@@ -29,10 +29,10 @@ function initGlobals(){
creaseMaterialHasChanged
:
false
,
shouldResetDynamicSim
:
false
,
shouldChangeCreasePercent
:
false
,
shouldSyncWithModel
:
false
,
nodePositionHasChanged
:
false
,
shouldZeroDynamicVelocity
:
false
,
shouldCenterGeo
:
false
,
needsSync
:
false
,
//3d vis
simType
:
"
dynamic
"
,
...
...
js/main.js
View file @
109d726a
...
...
@@ -16,6 +16,7 @@ $(function() {
globals
.
model
=
initModel
(
globals
);
globals
.
staticSolver
=
initStaticSolver
(
globals
);
globals
.
dynamicSolver
=
initDynamicSolver
(
globals
);
globals
.
rigidSolver
=
initRigidSolver
(
globals
);
globals
.
pattern
=
initPattern
(
globals
);
globals
.
vive
=
initViveInterface
(
globals
);
$
(
"
.demo[data-url='Tessellations/waterbomb.svg']
"
).
click
();
...
...
js/model.js
View file @
109d726a
...
...
@@ -98,55 +98,6 @@ function initModel(globals){
return
colors
;
}
// nodes.push(new Node(new THREE.Vector3(0,0,0), nodes.length));
// nodes.push(new Node(new THREE.Vector3(0,0,10), nodes.length));
// nodes.push(new Node(new THREE.Vector3(10,0,0), nodes.length));
// nodes.push(new Node(new THREE.Vector3(0,0,-10), nodes.length));
// nodes.push(new Node(new THREE.Vector3(10,0,-10), nodes.length));
// nodes.push(new Node(new THREE.Vector3(-10,0,0), nodes.length));
// nodes[0].setFixed(true);
// nodes[1].setFixed(true);
// nodes[2].setFixed(true);
// edges.push(new Beam([nodes[1], nodes[0]]));
// edges.push(new Beam([nodes[1], nodes[2]]));
// edges.push(new Beam([nodes[2], nodes[0]]));
// edges.push(new Beam([nodes[3], nodes[0]]));
// edges.push(new Beam([nodes[3], nodes[2]]));
// edges.push(new Beam([nodes[3], nodes[4]]));
// edges.push(new Beam([nodes[2], nodes[4]]));
// edges.push(new Beam([nodes[4], nodes[0]]));
// edges.push(new Beam([nodes[4], nodes[1]]));
// edges.push(new Beam([nodes[3], nodes[4]]));
// faces.push(new THREE.Face3(0,1,2));
// faces.push(new THREE.Face3(0,2,3));
// faces.push(new THREE.Face3(4,3,2));
// faces.push(new THREE.Face3(4,1,0));
// faces.push(new THREE.Face3(3,4,0));
// creases.push(new Crease(edges[2], 0, 1, Math.PI, 1, nodes[1], nodes[3], 0));
// creases.push(new Crease(edges[4], 2, 1, -Math.PI, 1, nodes[4], nodes[0], 1));
// creases.push(new Crease(edges[5], 3, 2, -Math.PI, 1, nodes[3], nodes[1], 1));
// creases.push(new Crease(edges[0], 3, 0, Math.PI, 1, nodes[4], nodes[2], 2));
// var _allNodeObject3Ds = [];
// _.each(nodes, function(node){
// var obj3D = node.getObject3D();
// _allNodeObject3Ds.push(obj3D);
// globals.threeView.sceneAddModel(obj3D);
// });
// allNodeObject3Ds = _allNodeObject3Ds;
// _.each(edges, function(edge){
// globals.threeView.sceneAddModel(edge.getObject3D());
// });
function
pause
(){
globals
.
threeView
.
pauseSimulation
();
}
...
...
@@ -156,12 +107,23 @@ function initModel(globals){
}
function
reset
(){
getSolver
().
reset
();
var
solver
=
getSolver
();
if
(
globals
.
needsSync
){
solver
.
syncNodesAndEdges
();
globals
.
needsSync
=
false
;
}
solver
.
reset
();
setGeoUpdates
();
}
function
step
(
numSteps
){
getSolver
().
solve
(
numSteps
);
var
solver
=
getSolver
();
if
(
globals
.
needsSync
){
solver
.
syncNodesAndEdges
();
globals
.
needsSync
=
false
;
}
solver
.
solve
(
numSteps
);
geometry
.
attributes
.
position
.
needsUpdate
=
true
;
setGeoUpdates
();
}
...
...
@@ -179,9 +141,7 @@ function initModel(globals){
function
startSolver
(){
globals
.
threeView
.
startAnimation
(
function
(){
if
(
!
inited
)
return
;
getSolver
().
solve
();
geometry
.
attributes
.
position
.
needsUpdate
=
true
;
setGeoUpdates
();
step
();
});
}
...
...
@@ -203,9 +163,9 @@ function initModel(globals){
for
(
var
i
=
0
;
i
<
_vertices
.
length
;
i
++
){
_nodes
.
push
(
new
Node
(
_vertices
[
i
].
clone
(),
_nodes
.
length
));
}
// _nodes[_faces[0]
.a
].setFixed(true);
// _nodes[_faces[0]
.b
].setFixed(true);
// _nodes[_faces[0]
.c
].setFixed(true);
// _nodes[_faces[0]
[0]
].setFixed(true);
// _nodes[_faces[0]
[1]
].setFixed(true);
// _nodes[_faces[0]
[2]
].setFixed(true);
var
_edges
=
[];
for
(
var
i
=
0
;
i
<
_allEdges
.
length
;
i
++
)
{
...
...
@@ -257,7 +217,6 @@ function initModel(globals){
globals
.
threeView
.
sceneAddModel
(
object3D
);
globals
.
threeView
.
sceneAddModel
(
object3D2
);
globals
.
shouldSyncWithModel
=
true
;
inited
=
true
;
updateEdgeVisibility
();
updateMeshVisibility
();
...
...
@@ -271,14 +230,15 @@ function initModel(globals){
}
if
(
!
globals
.
threeView
.
running
())
{
getSolver
().
syncNodesAndEdges
();
sync
();
}
globals
.
needsSync
=
true
;
}
function
getSolver
(){
if
(
globals
.
simType
==
"
dynamic
"
)
return
globals
.
dynamicSolver
;
return
globals
.
staticSolver
;
else
if
(
globals
.
simType
==
"
static
"
)
return
globals
.
staticSolver
;
return
globals
.
rigidSolver
;
}
function
sync
(){
...
...
js/node.js
View file @
109d726a
...
...
@@ -164,6 +164,11 @@ Node.prototype.render = function(position){
this
.
object3D
.
position
.
set
(
position
.
x
,
position
.
y
,
position
.
z
);
//todo need this?
return
position
;
};
Node
.
prototype
.
renderDelta
=
function
(
delta
){
// if (this.fixed) return;
this
.
object3D
.
position
.
add
(
delta
);
return
this
.
object3D
.
position
;
};
Node
.
prototype
.
renderChange
=
function
(
change
){
this
.
object3D
.
position
.
add
(
change
);
...
...
js/pattern.js
View file @
109d726a
...
...
@@ -717,6 +717,7 @@ function initPattern(globals){
if
(
!
containsInnerCrease
)
{
polygons
.
splice
(
i
,
1
);
polygonEdges
.
splice
(
i
,
1
);
break
;
//todo only remove once
}
}
...
...
js/rigidSolver.js
0 → 100644
View file @
109d726a
/**
* Created by amandaghassaei on 5/26/17.
*/
function
initRigidSolver
(){
var
nodes
;
var
edges
;
var
faces
;
var
creases
;
var
positions
;
var
C
,
F
;
function
syncNodesAndEdges
(){
nodes
=
globals
.
model
.
getNodes
();
edges
=
globals
.
model
.
getEdges
();
faces
=
globals
.
model
.
getFaces
();
creases
=
globals
.
model
.
getCreases
();
positions
=
globals
.
model
.
getPositionsArray
();
setUpParams
();
}
function
solve
(){
updateMatrices
();
solveStep
();
}
function
reset
(){
}
// function pinv(A) { //for linearly ind rows
// var AT = numeric.transpose(A);
// return numeric.dot(AT, numeric.inv(numeric.dot(AT,A)));
// }
function
pinv
(
A
)
{
//http://www.numericjs.com/workshop.php?link=b923cdeb84e188a11b44e3e82e44897b3b7da1d6640ddb46ab7330a6625f8e19
var
z
=
numeric
.
svd
(
A
),
foo
=
z
.
S
[
0
];
var
U
=
z
.
U
,
S
=
z
.
S
,
V
=
z
.
V
;
var
m
=
A
.
length
,
n
=
A
[
0
].
length
,
tol
=
Math
.
max
(
m
,
n
)
*
numeric
.
epsilon
*
foo
,
M
=
S
.
length
;
var
i
,
Sinv
=
new
Array
(
M
);
for
(
i
=
M
-
1
;
i
!==-
1
;
i
--
)
{
if
(
S
[
i
]
>
tol
)
Sinv
[
i
]
=
1
/
S
[
i
];
else
Sinv
[
i
]
=
0
;
}
return
numeric
.
dot
(
numeric
.
dot
(
V
,
numeric
.
diag
(
Sinv
)),
numeric
.
transpose
(
U
))
}
function
solveStep
(){
//todo add external forces
var
X
=
numeric
.
dot
(
numeric
.
sub
(
numeric
.
identity
(
3
*
nodes
.
length
),
numeric
.
dot
(
numeric
.
transpose
(
pinv
(
numeric
.
transpose
(
C
))),
C
)),
F
);
//todo valid psuedoinv?
// var sum = new THREE.Vector3();
// for (var i=0;i<_F.length;i+=3){
// sum.x += _F[i];
// sum.y += _F[i+1];
// sum.z += _F[i+2];
// }
// console.log(sum);
console
.
log
(
X
);
render
(
X
);
}
function
render
(
X
){
for
(
var
i
=
0
;
i
<
nodes
.
length
;
i
++
){
var
nodePosition
=
new
THREE
.
Vector3
(
X
[
3
*
i
],
X
[
3
*
i
+
1
],
X
[
3
*
i
+
2
]);
var
nexPos
=
nodes
[
i
].
renderDelta
(
nodePosition
);
positions
[
3
*
i
]
=
nexPos
.
x
;
positions
[
3
*
i
+
1
]
=
nexPos
.
y
;
positions
[
3
*
i
+
2
]
=
nexPos
.
z
;
}
for
(
var
i
=
0
;
i
<
edges
.
length
;
i
++
){
edges
[
i
].
render
();
}
}
function
initEmptyArray
(
dim1
,
dim2
,
dim3
){
if
(
dim2
===
undefined
)
dim2
=
0
;
if
(
dim3
===
undefined
)
dim3
=
0
;
var
array
=
[];
for
(
var
i
=
0
;
i
<
dim1
;
i
++
){
if
(
dim2
==
0
)
array
.
push
(
0
);
else
array
.
push
([]);
for
(
var
j
=
0
;
j
<
dim2
;
j
++
){
if
(
dim3
==
0
)
array
[
i
].
push
(
0
);
else
array
[
i
].
push
([]);
for
(
var
k
=
0
;
k
<
dim3
;
k
++
){
array
[
i
][
j
].
push
(
0
);
}
}
}
return
array
;
}
function
setUpParams
(){
//C = (edges + creases) x 3nodes
//disp = 1 x 3nodes
C
=
initEmptyArray
(
edges
.
length
,
3
*
nodes
.
length
);
//todo change size
F
=
initEmptyArray
(
3
*
nodes
.
length
);
// for (var i=0;i<nodes.length;i++){
// F[3*i] = 0;
// F[3*i+1] = 0;
// F[3*i+2] = 0;
// }
}
function
updateMatrices
(){
var
numNodes
=
nodes
.
length
;
var
numEdges
=
edges
.
length
;
F
=
initEmptyArray
(
3
*
numNodes
);
for
(
var
j
=
0
;
j
<
numEdges
;
j
++
){
var
edge
=
edges
[
j
];
var
_nodes
=
edge
.
nodes
;
var
edgeVector0
=
edge
.
getVector
(
_nodes
[
0
]);
var
length
=
edge
.
getOriginalLength
();
var
diff
=
edgeVector0
.
length
()
-
length
;
var
rxnForceScale
=
globals
.
axialStiffness
*
diff
/
length
;
edgeVector0
.
normalize
();
var
i
=
_nodes
[
0
].
getIndex
();
C
[
j
][
3
*
i
]
=
edgeVector0
.
x
;
C
[
j
][
3
*
i
+
1
]
=
edgeVector0
.
y
;
C
[
j
][
3
*
i
+
2
]
=
edgeVector0
.
z
;
F
[
3
*
i
]
-=
edgeVector0
.
x
*
rxnForceScale
;
F
[
3
*
i
+
1
]
-=
edgeVector0
.
y
*
rxnForceScale
;
F
[
3
*
i
+
2
]
-=
edgeVector0
.
z
*
rxnForceScale
;
i
=
_nodes
[
1
].
getIndex
();
C
[
j
][
3
*
i
]
=
-
edgeVector0
.
x
;
C
[
j
][
3
*
i
+
1
]
=
-
edgeVector0
.
y
;
C
[
j
][
3
*
i
+
2
]
=
-
edgeVector0
.
z
;
F
[
3
*
i
]
+=
edgeVector0
.
x
*
rxnForceScale
;
F
[
3
*
i
+
1
]
+=
edgeVector0
.
y
*
rxnForceScale
;
F
[
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
=
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
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
();
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
[
3
*
i
]
-=
partial1
.
x
*
rxnForceScale
;
F
[
3
*
i
+
1
]
-=
partial1
.
y
*
rxnForceScale
;
F
[
3
*
i
+
2
]
-=
partial1
.
z
*
rxnForceScale
;
}
if
(
!
crease
.
node2
.
fixed
){
var
i
=
indicesMapping
.
indexOf
(
crease
.
node2
.
getIndex
());
var
dist
=
crease
.
getLengthToNode2
();
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
[
3
*
i
]
-=
partial2
.
x
*
rxnForceScale
;
F
[
3
*
i
+
1
]
-=
partial2
.
y
*
rxnForceScale
;
F
[
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
[
3
*
i
]
+=
(
partial1
.
x
+
partial2
.
x
)
/
2
*
rxnForceScale
;
F
[
3
*
i
+
1
]
+=
(
partial1
.
y
+
partial2
.
y
)
/
2
*
rxnForceScale
;
F
[
3
*
i
+
2
]
+=
(
partial1
.
z
+
partial2
.
z
)
/
2
*
rxnForceScale
;
}
}
}
return
{
syncNodesAndEdges
:
syncNodesAndEdges
,
solve
:
solve
,
reset
:
reset
}
}
\ No newline at end of file
js/staticSolver.js
View file @
109d726a
...
...
@@ -34,6 +34,11 @@ function initStaticSolver(){
function
reset
(){
}
function
pinv
(
A
)
{
//for linearly ind rows
var
AT
=
numeric
.
transpose
(
A
);
return
numeric
.
dot
(
AT
,
numeric
.
inv
(
numeric
.
dot
(
AT
,
A
)));
}
function
solveStep
(){
console
.
log
(
"
static solve
"
);
// if (fixedIndicesMapping.length == 0){//no boundary conditions
...
...
@@ -47,9 +52,14 @@ function initStaticSolver(){
for
(
var
i
=
0
;
i
<
_F
.
length
;
i
++
)
{
_F
[
i
]
+=
F_rxn
[
i
];
}
var
X
=
numeric
.
dot
(
numeric
.
inv
(
Ctrans_Q_C
),
_F
);
console
.
log
(
_F
);
var
X
=
numeric
.
solve
(
Ctrans_Q_C
,
_F
);
// var sum = new THREE.Vector3();
// for (var i=0;i<_F.length;i+=3){
// sum.x += _F[i];
// sum.y += _F[i+1];
// sum.z += _F[i+2];
// }
// console.log(sum);
render
(
X
);
}
...
...
@@ -59,7 +69,7 @@ function initStaticSolver(){
for
(
var
i
=
0
;
i
<
numVerticesFree
;
i
++
){
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
);
var
nexPos
=
nodes
[
index
].
render
Delta
(
nodePosition
);
positions
[
3
*
index
]
=
nexPos
.
x
;
positions
[
3
*
index
+
1
]
=
nexPos
.
y
;
positions
[
3
*
index
+
2
]
=
nexPos
.
z
;
...
...
@@ -98,6 +108,7 @@ function initStaticSolver(){
function
updateMatrices
(){
calcCsAndRxns
();
Ctrans
=
numeric
.
transpose
(
C
);
// console.log(Q);
Ctrans_Q
=
numeric
.
dot
(
Ctrans
,
Q
);
Ctrans_Q_C
=
numeric
.
dot
(
Ctrans_Q
,
C
);
}
...
...
@@ -201,65 +212,64 @@ function initStaticSolver(){
}