Search in sources :

Example 6 with Point3d

use of maspack.matrix.Point3d in project artisynth_core by artisynth.

the class MeshCollider method createContactPlanes.

/**
 * From a complete set of intersections, get all of the regions so that each
 * region is defined by a set of continuous intersections.
 *
 * @param regions (output) the complete set of intersection regions.
 * @param intersections
 * The complete set of intersections.
 * @param regionTol tolerance
 */
static void createContactPlanes(ArrayList<ContactPlane> regions, ArrayList<TriTriIntersection> intersections, double regionTol) {
    if (intersections.size() == 0) {
        // no intersections, so no planes to compute
        return;
    }
    AccelerationGrid<TriTriIntersection> accgrid = new AccelerationGrid<TriTriIntersection>();
    Point3d min = new Point3d(intersections.get(0).points[0]), max = new Point3d(intersections.get(0).points[0]);
    for (TriTriIntersection isect : intersections) for (Point3d p : isect.points) {
        min.min(p);
        max.max(p);
    }
    double dist = Math.max(min.distance(max), EPS);
    min.x -= dist * 0.1;
    min.y -= dist * 0.1;
    min.z -= dist * 0.1;
    max.x += dist * 0.1;
    max.y += dist * 0.1;
    max.z += dist * 0.1;
    accgrid.set(min, max, intersections.size() * 2);
    for (TriTriIntersection isect : intersections) for (Point3d p : isect.points) accgrid.add_element(isect, p, p);
    for (TriTriIntersection isect : intersections) {
        ContactPlane region = new ContactPlane();
        if (accgrid.elementidxs.get(isect) != null) {
            traverseRegion(accgrid, region, isect, regionTol);
            regions.add(region);
        }
    }
// System.out.println("region time " + (System.currentTimeMillis() - t0));
}
Also used : Point3d(maspack.matrix.Point3d) TriTriIntersection(maspack.geometry.TriTriIntersection)

Example 7 with Point3d

use of maspack.matrix.Point3d in project artisynth_core by artisynth.

the class MeshCollider method getContactPlaneInfo.

/**
 * Get information about a specific region of intersections.
 */
static void getContactPlaneInfo(ContactPlane region, PolygonalMesh mesh0, PolygonalMesh mesh1, double pointTol) {
    Vector3d sectnormal = new Vector3d(), tmpnormal = new Vector3d();
    BVFeatureQuery query = new BVFeatureQuery();
    RigidTransform3d trans0 = mesh0.getMeshToWorld();
    RigidTransform3d trans1 = mesh1.getMeshToWorld();
    // calculate a weighted average of the face normals
    for (TriTriIntersection isect : region.intersections) {
        region.points = new ArrayList<Point3d>();
        region.points.add(isect.points[0]);
        region.points.add(isect.points[1]);
        double length = isect.points[0].distance(isect.points[1]);
        tmpnormal.transform(trans0, isect.face0.getNormal());
        tmpnormal.negate();
        sectnormal.scaledAdd(length, tmpnormal, sectnormal);
        tmpnormal.transform(trans1, isect.face1.getNormal());
        sectnormal.scaledAdd(length, tmpnormal, sectnormal);
    }
    // calculate the weighted intersection center
    Point3d center = new Point3d();
    double weight = 0;
    for (TriTriIntersection isect : region.intersections) {
        double length = isect.points[0].distance(isect.points[1]);
        center.scaledAdd(length, isect.points[0], center);
        center.scaledAdd(length, isect.points[1], center);
        weight += 2 * length;
    }
    center.scale(1.0 / weight);
    region.centroid = center;
    // calculate the weighted normal
    Vector3d cp0 = new Vector3d(), cp1 = new Vector3d();
    region.normal.setZero();
    for (TriTriIntersection isect : region.intersections) {
        cp0.sub(isect.points[0], center);
        cp1.sub(isect.points[1], center);
        tmpnormal.cross(cp0, cp1);
        if (tmpnormal.dot(sectnormal) < 0)
            tmpnormal.negate();
        region.normal.add(tmpnormal);
    }
    if (region.normal.dot(sectnormal) < 0)
        region.normal.negate();
    // handle degenerate cases
    if (region.normal.containsNaN() || region.normal.norm() < EPS) {
        region.normal.setZero();
        Point3d p0 = new Point3d();
        Point3d p1 = new Point3d();
        Vector3d c0 = new Vector3d();
        Vector3d c1 = new Vector3d();
        for (TriTriIntersection isect : region.intersections) {
            for (Point3d p : isect.points) {
                p0.inverseTransform(trans0, p);
                p1.inverseTransform(trans1, p);
                Vertex3d u0 = isect.face0.getVertex(0);
                Vertex3d u1 = isect.face0.getVertex(1);
                Vertex3d u2 = isect.face0.getVertex(2);
                Vertex3d v0 = isect.face1.getVertex(0);
                Vertex3d v1 = isect.face1.getVertex(1);
                Vertex3d v2 = isect.face1.getVertex(2);
                getCoordinates(c0, u0.pnt, u1.pnt, u2.pnt, p0);
                getCoordinates(c1, v0.pnt, v1.pnt, v2.pnt, p1);
                int[] type0 = classifyPoint(c0);
                int[] type1 = classifyPoint(c1);
                if (type0[0] == 2) {
                    if (type1[0] == 2) {
                        // vertex,vertex
                        region.normal.add(vertexVertexNormal(trans0, trans1, isect.face0, isect.face1, type0[1], type1[1]));
                    } else if (type1[0] == 1) {
                        // vertex,edge
                        region.normal.add(vertexEdgeNormal(trans0, trans1, isect.face0, isect.face1, type0[1], type1[1]));
                    } else {
                        // vertex,face
                        region.normal.add(vertexFaceNormal(trans0, trans1, isect.face0, isect.face1, type0[1]));
                    }
                } else if (type0[0] == 1) {
                    if (type1[0] == 2) {
                        // edge,vertex
                        region.normal.sub(vertexEdgeNormal(trans1, trans0, isect.face1, isect.face0, type1[1], type0[1]));
                    } else if (type1[0] == 1) {
                        // edge,edge
                        region.normal.add(edgeEdgeNormal(trans0, trans1, isect.face0, isect.face1, type0[1], type1[1]));
                    } else {
                        // edge,face
                        region.normal.add(edgeFaceNormal(trans0, trans1, isect.face0, isect.face1, type0[1]));
                    }
                } else {
                    if (type1[0] == 2) {
                        // face,vertex
                        region.normal.sub(vertexFaceNormal(trans1, trans0, isect.face1, isect.face0, type1[1]));
                    } else if (type1[0] == 1) {
                        // face,edge
                        region.normal.sub(edgeFaceNormal(trans1, trans0, isect.face1, isect.face0, type1[1]));
                    } else {
                        // face,face
                        region.normal.add(faceFaceNormal(trans0, trans1, isect.face0, isect.face1));
                    }
                }
            }
        }
    }
    region.normal.normalize();
    // calculate the contact depth for the region
    boolean foundPenetratingVertice = false;
    Point3d p = new Point3d();
    Point3d nearest = new Point3d();
    Vector3d diff = new Vector3d();
    Vector2d coords = new Vector2d();
    Vertex3d v;
    Face nf;
    Point3d plocal = new Point3d();
    LinkedHashSet<Vertex3d> regionvertices0 = new LinkedHashSet<Vertex3d>();
    LinkedHashSet<Vertex3d> regionvertices1 = new LinkedHashSet<Vertex3d>();
    region.depth = 0;
    for (TriTriIntersection isect : region.intersections) {
        for (int i = 0; i < 3; i++) {
            // face0 vertex depths
            v = isect.face0.getVertex(i);
            p.transform(trans0, v.pnt);
            plocal.inverseTransform(trans1, p);
            plocal.sub(isect.face1.getVertex(0).pnt);
            if (plocal.dot(isect.face1.getNormal()) <= 0) {
                regionvertices0.add(v);
            }
            // face1 vertex depths
            v = isect.face1.getVertex(i);
            p.transform(trans1, v.pnt);
            plocal.inverseTransform(trans0, p);
            plocal.sub(isect.face0.getVertex(0).pnt);
            if (plocal.dot(isect.face0.getNormal()) <= 0) {
                regionvertices1.add(v);
            }
        }
    }
    for (Vertex3d v0 : regionvertices0) {
        p.transform(trans0, v0.pnt);
        // XXX Sanchez, Jun 22, 2014
        // Changed to isInside.  Sometimes a vertex is outside
        // the mesh but determined to be "penetrating" due to
        // normal (e.g. when nearest to an edge)
        // nf = myQuery.nearestFaceToPoint (nearest, coords, mesh1, p);
        boolean inside = query.isInsideOrientedMesh(mesh1, p, 0);
        if (inside) {
            query.getFaceForInsideOrientedTest(nearest, coords);
            nearest.transform(trans1);
            diff.sub(p, nearest);
            diff.inverseTransform(trans1);
            foundPenetratingVertice = true;
            // -diff.dot (nf.getNormal());
            double dist = diff.norm();
            if (dist > region.depth)
                region.depth = dist;
        }
    }
    for (Vertex3d v1 : regionvertices1) {
        p.transform(trans1, v1.pnt);
        // nf = myQuery.nearestFaceToPoint (nearest, coords, mesh0, p);
        boolean inside = query.isInsideOrientedMesh(mesh0, p, 0);
        if (inside) {
            query.getFaceForInsideOrientedTest(nearest, coords);
            nearest.transform(trans0);
            diff.sub(p, nearest);
            diff.inverseTransform(trans0);
            foundPenetratingVertice = true;
            // -diff.dot (nf.getNormal());
            double dist = diff.norm();
            if (dist > region.depth)
                region.depth = dist;
        }
    }
    if (!foundPenetratingVertice) {
        double min = Double.POSITIVE_INFINITY, max = Double.NEGATIVE_INFINITY;
        for (int i = 0; i < region.points.size(); i++) {
            double d = region.points.get(i).dot(region.normal);
            if (d < min)
                min = d;
            if (d > max)
                max = d;
        }
        region.depth = max - min;
    }
    // eliminate redundant points
    // use point tolerance
    region.points.clear();
    for (TriTriIntersection isect : region.intersections) {
        for (Point3d pcandidate : isect.points) {
            boolean add = true;
            for (Point3d other : region.points) if (pcandidate.epsilonEquals(other, pointTol)) {
                add = false;
                break;
            }
            if (add) {
                region.points.add(pcandidate);
            }
        }
    }
    // take extrema along n axes
    if (numextremaaxes > 0) {
        // final ArrayList<Vector3d> axes = new ArrayList<Vector3d>();
        Vector3d crosszup = new Vector3d(0, 0, 1);
        crosszup.cross(region.normal, crosszup);
        double crosszupnorm = crosszup.norm();
        RigidTransform3d normtoworld;
        if (crosszup.norm() > EPS) {
            normtoworld = new RigidTransform3d(new Vector3d(), new AxisAngle(crosszup, Math.asin(crosszupnorm)));
        } else {
            normtoworld = new RigidTransform3d();
        }
        boolean[] keep = new boolean[region.points.size()];
        for (int j = 0; j < region.points.size(); j++) keep[j] = false;
        Vector3d offset = new Vector3d();
        Vector3d axis = new Vector3d();
        for (int i = 0; i < numextremaaxes; i++) {
            double min = Double.POSITIVE_INFINITY, max = Double.NEGATIVE_INFINITY;
            int mini = 0, maxi = 0;
            double angle = Math.PI * i / numextremaaxes;
            axis.set(Math.cos(angle), Math.sin(angle), 0);
            axis.transform(normtoworld);
            for (int j = 0; j < region.points.size(); j++) {
                offset.sub(region.points.get(j), center);
                double dot = offset.dot(axis);
                if (dot < min) {
                    min = dot;
                    mini = j;
                }
                if (dot > max) {
                    max = dot;
                    maxi = j;
                }
            }
            keep[mini] = true;
            keep[maxi] = true;
        }
        for (int j = (region.points.size() - 1); j >= 0; j--) {
            if (!keep[j])
                region.points.remove(j);
        }
    }
}
Also used : Vertex3d(maspack.geometry.Vertex3d) LinkedHashSet(java.util.LinkedHashSet) RigidTransform3d(maspack.matrix.RigidTransform3d) TriTriIntersection(maspack.geometry.TriTriIntersection) BVFeatureQuery(maspack.geometry.BVFeatureQuery) AxisAngle(maspack.matrix.AxisAngle) Vector2d(maspack.matrix.Vector2d) Vector3d(maspack.matrix.Vector3d) Point3d(maspack.matrix.Point3d) Face(maspack.geometry.Face)

Example 8 with Point3d

use of maspack.matrix.Point3d in project artisynth_core by artisynth.

the class WavefrontToMaya method stringifyPolyline.

private static String stringifyPolyline(int[] vtxIndices, ArrayList<Point3d> vtxList, String name, NumberFormat fmt) {
    if (fmt == null) {
        fmt = new NumberFormat();
    }
    String lineStr = "";
    String transname = name + "trans";
    lineStr += "createNode transform -n \"" + transname + "\";\n";
    lineStr += "createNode nurbsCurve -n \"" + name + "\";\n";
    lineStr += "\tsetAttr -k off \".v\";\n";
    lineStr += "\tsetAttr \".cc\" -type \"nurbsCurve\"\n";
    int nverts = vtxIndices.length;
    lineStr += "\t\t1 " + (nverts - 1) + " 0 no 3\n";
    lineStr += "\t\t" + nverts;
    for (int i = 0; i < nverts; i++) {
        lineStr += " " + i;
    }
    lineStr += "\n\t\t" + nverts + "\n";
    // vertex locations
    for (int i = 0; i < nverts; i++) {
        Point3d pos = vtxList.get(vtxIndices[i]);
        lineStr += "\t\t" + fmt.format(pos.x) + " " + fmt.format(pos.y) + " " + fmt.format(pos.z) + "\n";
    }
    lineStr += "\t\t;\n";
    return lineStr;
}
Also used : Point3d(maspack.matrix.Point3d) NumberFormat(maspack.util.NumberFormat)

Example 9 with Point3d

use of maspack.matrix.Point3d in project artisynth_core by artisynth.

the class AhoIntersectionContour method getArea.

/**
 * Return the area of this (approximately planar) contour.
 *
 * @return area
 */
public double getArea() {
    /* Compute the centroid of all the points. */
    int pSize = size();
    if (pSize < 3)
        return (0);
    Point3d centroid = new Point3d();
    int N = size();
    if (!isOpen()) {
        N--;
    }
    for (int i = 0; i < N; i++) {
        centroid.add(get(i));
    }
    centroid.scale(1.0d / N);
    Vector3d cp = new Vector3d();
    Vector3d normalSum = new Vector3d();
    Vector3d rLast = new Vector3d();
    rLast.sub(get(pSize - 1), centroid);
    Vector3d r = new Vector3d();
    for (int i = 0; i < pSize; i++) {
        r.sub(get(i), centroid);
        cp.cross(r, rLast);
        normalSum.add(cp);
        Vector3d rTemp = rLast;
        rLast = r;
        r = rTemp;
    }
    return normalSum.norm() * 0.5;
}
Also used : Vector3d(maspack.matrix.Vector3d) Point3d(maspack.matrix.Point3d)

Example 10 with Point3d

use of maspack.matrix.Point3d in project artisynth_core by artisynth.

the class EdgeEdgeContact method isPointInsideFace.

/*
    * return true if the specified point is "opposite" and inside the face,
    * which means close to being inside a volume swept by translating the face
    * along its normal.
    */
boolean isPointInsideFace(SurfaceMeshCollider collider, Point3d p, Face f) {
    Point3d nearest = new Point3d();
    collider.getNearestPoint(nearest, f, p);
    nearest.sub(p);
    if (nearest.dot(nearest) == 0) {
        return true;
    }
    double x = nearest.angle(f.getWorldNormal());
    return x < insideLim;
}
Also used : Point3d(maspack.matrix.Point3d)

Aggregations

Point3d (maspack.matrix.Point3d)464 Vector3d (maspack.matrix.Vector3d)128 ArrayList (java.util.ArrayList)59 RigidTransform3d (maspack.matrix.RigidTransform3d)48 Vertex3d (maspack.geometry.Vertex3d)35 Point (artisynth.core.mechmodels.Point)30 PolygonalMesh (maspack.geometry.PolygonalMesh)30 Face (maspack.geometry.Face)25 ReaderTokenizer (maspack.util.ReaderTokenizer)19 IOException (java.io.IOException)18 RotationMatrix3d (maspack.matrix.RotationMatrix3d)17 Vector2d (maspack.matrix.Vector2d)16 VectorNd (maspack.matrix.VectorNd)16 IntegrationPoint3d (artisynth.core.femmodels.IntegrationPoint3d)15 HashMap (java.util.HashMap)14 Muscle (artisynth.core.mechmodels.Muscle)13 FemNode3d (artisynth.core.femmodels.FemNode3d)12 Particle (artisynth.core.mechmodels.Particle)12 BufferedReader (java.io.BufferedReader)11 Plane (maspack.matrix.Plane)11