use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class FemMuscleModel method getSegmentInsideSphere.
// intersects segment with the given sphere, and returns
// the portion inside or null if no intersection
private static LineSegment getSegmentInsideSphere(LineSegment segment, Point3d pos, double rad) {
Point3d p1 = segment.myVtx0.getPosition();
Point3d p2 = segment.myVtx1.getPosition();
// check if segment starts inside
boolean isP1Inside = isInsideSphere(p1, pos, rad);
// p2-c
Point3d p = new Point3d();
// p1-p2
Point3d dp = new Point3d();
double r2 = rad * rad;
// for use with quadratic equation
double a, b, c, d, lambda1, lambda2;
p.sub(p2, pos);
dp.sub(p1, p2);
// find intersection with sphere
a = dp.normSquared();
b = 2 * dp.dot(p);
c = p.normSquared() - r2;
d = b * b - 4 * a * c;
if (d >= 0) {
d = Math.sqrt(d);
lambda1 = (-b + d) / (2 * a);
lambda2 = (-b - d) / (2 * a);
} else {
lambda1 = Double.NaN;
lambda2 = Double.NaN;
}
// if p2 is inside, return
if (p.normSquared() <= r2) {
if (isP1Inside) {
return segment;
} else {
// find intersection
if (lambda1 >= 0 && lambda1 <= 1) {
p1.scaledAdd(lambda1, dp, p2);
} else {
p1.scaledAdd(lambda2, dp, p2);
}
return new LineSegment(new Vertex3d(p1), new Vertex3d(p2));
}
} else {
// if p1 inside, find single intersection
if (isP1Inside) {
if (lambda1 >= 0 && lambda1 <= 1) {
p2.scaledAdd(lambda1, dp);
} else {
p2.scaledAdd(lambda2, dp);
}
return new LineSegment(new Vertex3d(p1), new Vertex3d(p2));
} else {
// check if passes entirely through sphere
if (d >= 0) {
if (lambda1 >= 0 && lambda1 <= 1 && lambda2 >= 0 && lambda2 <= 1) {
p1.scaledAdd(lambda1, dp, p2);
p2.scaledAdd(lambda2, dp);
return new LineSegment(new Vertex3d(p1), new Vertex3d(p2));
}
}
// done checking if crossed sphere
}
// done checking if p1 outside
}
return null;
}
use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class SimpleFemWriter method writeSurfaceFile.
public void writeSurfaceFile(FemModel3d fem, PrintWriter surfaceWriter) {
PolygonalMesh mesh = fem.getSurfaceMesh();
for (Face face : mesh.getFaces()) {
surfaceWriter.print(faceToken);
for (Vertex3d vtx : face.getVertices()) {
FemNode3d node = fem.getSurfaceNode(vtx);
if (node != null) {
surfaceWriter.print(" " + (node.getNumber() + nodeOffset));
}
}
surfaceWriter.println();
}
}
use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class SkinMeshBody method collectVertices.
private void collectVertices(Vertex3d vtx, int networkDist, ArrayList<Vertex3d> list) {
if (list.contains(vtx)) {
return;
}
list.add(vtx);
if (networkDist > 0) {
Iterator<HalfEdge> it = vtx.getIncidentHalfEdges();
while (it.hasNext()) {
HalfEdge he = it.next();
Vertex3d vtxTail = he.tail;
collectVertices(vtxTail, networkDist - 1, list);
}
}
}
use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class SkinMeshBody method resetBasePositions.
/**
* Resets the base positions for all attachments in this SkinMeshBody
* to the current vertex position.
*/
protected void resetBasePositions() {
MeshBase mesh = getMesh();
for (int i = 0; i < myVertexAttachments.size(); i++) {
PointSkinAttachment a = myVertexAttachments.get(i);
Vertex3d vtx = mesh.getVertices().get(a.getNumber());
a.setBasePosition(vtx.getPosition());
}
}
use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class SkinMeshBody method computeDisplacementAttachments.
/**
* Computes displacement-based attachments for each vertex attachment in
* this skin mesh. For each vertex, the weights are determined using the
* relative distances from the vertex to the surface meshes of each of the
* controlling bodies (Frame, FemModel, etc.). Controlling bodies which
* don't have a surface mesh are ignored.
*
* <p>
* Bodies further away have a lower weighting. If <code>sigma</code>
* is non-positive, the weighting is determined using an inverse-square
* attenuation. Otherwise, the weighting is determined using a
* Gaussian attention controlled by <code>sigma</code>.
*
* @param sigma if greater than 0, specifies a Gaussian weighting
* attenuation.
*/
public void computeDisplacementAttachments(double sigma) {
MeshBase mesh = getMesh();
MeshDistCalc dcalc = new MeshDistCalc();
clearAttachments();
for (int i = 0; i < mesh.numVertices(); i++) {
Vertex3d vtx = mesh.getVertices().get(i);
dcalc.computeDistancesAndWeights(vtx.getPosition(), sigma);
PointSkinAttachment a = dcalc.computeDisplacementAttachment();
addAttachment(a);
}
myLastSigma = sigma;
}
Aggregations