use of maspack.matrix.Plane in project artisynth_core by artisynth.
the class LineSegment method getPlane.
public Plane getPlane() {
Plane plane = new Plane();
getPlane(plane);
return plane;
}
use of maspack.matrix.Plane in project artisynth_core by artisynth.
the class SegmentedPlanarCoupling method getConstraintInfo.
@Override
public void getConstraintInfo(ConstraintInfo[] info, RigidTransform3d TGD, RigidTransform3d TCD, RigidTransform3d XERR, boolean setEngaged) {
myErr.set(XERR);
Plane plane = doProject(null, TCD);
myPnt.set(TCD.p);
myNrm.inverseTransform(TGD, plane.normal);
info[0].flags = LINEAR;
if (!myUnilateral) {
info[0].flags |= BILATERAL;
}
info[0].wrenchC.set(myNrm, Vector3d.ZERO);
// double d = plane.distance (myPnt);
double d = info[0].wrenchC.dot(myErr);
info[0].distance = d;
info[0].dotWrenchC.setZero();
if (setEngaged) {
if (myUnilateral && d < getContactDistance()) {
info[0].engaged = 1;
}
}
}
use of maspack.matrix.Plane in project artisynth_core by artisynth.
the class SegmentedPlanarCoupling method makePlanesFromSegments.
private void makePlanesFromSegments(ArrayList<Point3d> segPoints) {
myPlanes = new ArrayList<Plane>();
// now create the planes
Vector3d u = new Vector3d();
Vector3d nrm = new Vector3d();
Vector3d y = new Vector3d(0, 1, 0);
for (int i = 1; i < segPoints.size(); i++) {
u.sub(segPoints.get(i), segPoints.get(i - 1));
nrm.cross(u, y);
nrm.normalize();
myPlanes.add(new Plane(nrm, nrm.dot(segPoints.get(i))));
}
}
use of maspack.matrix.Plane in project artisynth_core by artisynth.
the class FemMuscleHeart method build.
// Model builder
@Override
public void build(String[] args) throws IOException {
super.build(args);
setMaxStepSize(0.005);
// Root mechanical model
MechModel mech = new MechModel("mech");
mech.setGravity(0, 0, -9.8);
addModel(mech);
// -------------------------------------------------------------
// HEART LOAD / ADD GEOMETRY
// -------------------------------------------------------------
// Heart surface mesh, with texture
String heartFile = ArtisynthPath.getSrcRelativePath(this, "data/HumanHeart.obj");
WavefrontReader wfr = new WavefrontReader(new File(heartFile));
PolygonalMesh heartMesh = new PolygonalMesh();
wfr.readMesh(heartMesh);
// triangulate for interaction
heartMesh.triangulate();
// FEM heart:
// - FEM mesh of heart convex hull
// - embedded heart surface geometry
FemMuscleModel heart = new FemMuscleModel("heart");
TetGenReader.read(heart, ArtisynthPath.getSrcRelativePath(this, "data/HumanHeartHull.node"), ArtisynthPath.getSrcRelativePath(this, "data/HumanHeartHull.ele"));
// add real-looking mesh
FemMeshComp embeddedHeart = heart.addMesh(heartMesh);
embeddedHeart.setName("embedded");
// Allow inverted elements (poor quality mesh)
heart.setWarnOnInvertedElements(false);
heart.setAbortOnInvertedElements(false);
// Convert unites to metres (original was cm)
heart.scaleDistance(0.01);
heart.setGravity(0, 0, -9.8);
heart.setStiffnessDamping(0.02);
// Set material properties
heart.setDensity(1000);
FemMaterial femMat = new LinearMaterial(2500, 0.33, true);
// simple muscle
MuscleMaterial muscleMat = new SimpleForceMuscle(500.0);
heart.setMaterial(femMat);
// Add heart to model
mech.addModel(heart);
// -------------------------------------------------------------
// MUSCLE BUNDLES
// -------------------------------------------------------------
// One "long" direction muscle bundle
// One "radial" muscle bundle
// LONG BUNDLE
// Compute the "long" direction of the heart
PolygonalMesh hull = heart.getSurfaceMesh();
RigidTransform3d trans = hull.computePrincipalAxes();
Vector3d longAxis = new Vector3d();
// first column of rotation
trans.R.getColumn(0, longAxis);
// Create the long axis muscle bundle
MuscleBundle longBundle = new MuscleBundle("long");
for (FemElement3d elem : heart.getElements()) {
longBundle.addElement(elem, longAxis);
}
longBundle.setMuscleMaterial(muscleMat);
heart.addMuscleBundle(longBundle);
// RADIAL BUNDLE
// Compute a plane through centre of heart
Plane plane = new Plane(longAxis, new Point3d(trans.p));
Point3d centroid = new Point3d();
Vector3d radialDir = new Vector3d();
// Create the radial muscle bundle
MuscleBundle radialBundle = new MuscleBundle("radial");
for (FemElement3d elem : heart.getElements()) {
elem.computeCentroid(centroid);
// project to plane and compute radial direction
plane.project(centroid, centroid);
radialDir.sub(centroid, trans.p);
radialDir.normalize();
radialBundle.addElement(elem, radialDir);
}
radialBundle.setMuscleMaterial(muscleMat);
heart.addMuscleBundle(radialBundle);
// -------------------------------------------------------------
// RIGID TABLE AND COLLISION
// -------------------------------------------------------------
// Create a rigid box for the heart to fall on
RigidBody box = RigidBody.createBox("box", 0.2, 0.2, 0.02, 0, /*addnormals*/
true);
box.setPose(new RigidTransform3d(new Vector3d(0, 0, -0.2), AxisAngle.IDENTITY));
box.setDynamic(false);
mech.addRigidBody(box);
// Enable collisions between the heart and table
mech.setCollisionBehavior(heart, box, true);
// -------------------------------------------------------------
// RENDER PROPERTIES
// -------------------------------------------------------------
// Hide elements and nodes
RenderProps.setVisible(heart.getElements(), false);
RenderProps.setVisible(heart.getNodes(), false);
RenderProps.setLineColor(radialBundle, Color.BLUE);
RenderProps.setLineColor(longBundle, Color.RED);
radialBundle.setDirectionRenderLen(0.1);
longBundle.setDirectionRenderLen(0.1);
RenderProps.setVisible(radialBundle, false);
RenderProps.setVisible(longBundle, false);
RenderProps.setVisible(heart.getSurfaceMeshComp(), false);
// adjust table render properties
RenderProps.setShading(box, Shading.METAL);
RenderProps.setSpecular(box, new Color(0.8f, 0.8f, 0.8f));
// adjust heart mesh render properties
RenderProps rprops = embeddedHeart.getRenderProps();
rprops.getBumpMap().setScaling(0.01f);
// don't modify specular
rprops.getColorMap().setSpecularColoring(false);
rprops.setShading(Shading.SMOOTH);
rprops.setFaceColor(new Color(0.8f, 0.8f, 0.8f));
rprops.getColorMap().setColorMixing(ColorMixing.MODULATE);
rprops.setSpecular(new Color(0.4f, 0.4f, 0.4f));
rprops.setShininess(128);
// -------------------------------------------------------------
// INPUT PROBES
// -------------------------------------------------------------
// Add heart probe
addHeartProbe(longBundle, radialBundle);
}
use of maspack.matrix.Plane in project artisynth_core by artisynth.
the class DistanceGridSurfCalc method findSurfaceTangentInTet.
protected boolean findSurfaceTangentInTet(Point3d ptLoc, TetDesc tdesc, Point3d paLoc, Plane planeLoc) {
// XXX convert normal, off, and pa to tet coordinates
Plane planeCell = new Plane();
Point3d paCell = new Point3d();
transformToQuadCell(planeCell, planeLoc, tdesc);
transformToQuadCell(paCell, paLoc, tdesc);
double[] c = new double[10];
double[] b = new double[6];
myGrid.computeQuadCoefs(c, tdesc);
PlaneType planeType;
Vector2d[] pnts = new Vector2d[] { new Vector2d(), new Vector2d() };
Vector3d r = new Vector3d();
planeType = computeBCoefs(b, r, c, planeCell);
double x = 0, y = 0, z = 0;
boolean found = false;
switch(planeType) {
case YZ:
{
int nr = findTangentPoints(pnts, b, paCell.y, paCell.z);
for (int i = 0; i < nr; i++) {
y = pnts[i].x;
z = pnts[i].y;
x = r.z - r.x * y - r.y * z;
if (tdesc.myTetId.isInside(x, y, z)) {
found = true;
break;
}
}
break;
}
case ZX:
{
int nr = findTangentPoints(pnts, b, paCell.z, paCell.x);
for (int i = 0; i < nr; i++) {
z = pnts[i].x;
x = pnts[i].y;
y = r.z - r.x * z - r.y * x;
if (tdesc.myTetId.isInside(x, y, z)) {
found = true;
break;
}
}
break;
}
case XY:
{
int nr = findTangentPoints(pnts, b, paCell.x, paCell.y);
for (int i = 0; i < nr; i++) {
x = pnts[i].x;
y = pnts[i].y;
z = r.z - r.x * x - r.y * y;
if (tdesc.myTetId.isInside(x, y, z)) {
found = true;
break;
}
}
break;
}
}
if (found) {
// System.out.println ("dist=" + computeDist (c, x, y, z));
// System.out.println ("perp=" + computePerp (c, x, y, z, paCell));
transformFromQuadCell(ptLoc, x, y, z, tdesc);
return true;
} else {
return false;
}
}
Aggregations