Search in sources :

Example 6 with Point

use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.

the class FemElement3d method getNaturalCoordinatesGSS.

/**
 * Given point p, get its natural coordinates with respect to this element.
 * Returns a positive number if the algorithm converges, or -1 if a maximum
 * number of iterations has been reached. Uses a modified Newton's method to solve the
 * equations. The <code>coords</code> argument that returned the coordinates is
 * used, on input, to supply an initial guess of the coordinates.
 * Zero is generally a safe guess.
 *
 * @param coords
 * Outputs the natural coordinates, and supplies (on input) an initial
 * guess as to their position.
 * @param pnt
 * A given point (in world coords)
 * @param maxIters
 * Maximum number of Newton iterations
 * @return the number of iterations required for convergence, or
 * -1 if the calculation did not converge.
 */
public int getNaturalCoordinatesGSS(Vector3d coords, Point3d pnt, int maxIters) {
    if (!coordsAreInside(coords)) {
        // if not inside, reset coords to 0
        coords.setZero();
    }
    // if FEM is frame-relative, transform to local coords
    Point3d lpnt = new Point3d(pnt);
    if (getGrandParent() instanceof FemModel3d) {
        FemModel3d fem = (FemModel3d) getGrandParent();
        if (fem.isFrameRelative()) {
            lpnt.inverseTransform(fem.getFrame().getPose());
        }
    }
    Vector3d res = new Point3d();
    int i;
    double tol = RenderableUtils.getRadius(this) * 1e-12;
    computeNaturalCoordsResidual(res, coords, lpnt);
    double prn = res.norm();
    // System.out.println ("res=" + prn);
    if (prn < tol) {
        // already have the right answer
        return 0;
    }
    LUDecomposition LUD = new LUDecomposition();
    Point3d prevCoords = new Point3d();
    Vector3d dNds = new Vector3d();
    Matrix3d dxds = new Matrix3d();
    Vector3d del = new Point3d();
    GSSResidual func = new GSSResidual(this, lpnt);
    /*
       * solve using Newton's method.
       */
    for (i = 0; i < maxIters; i++) {
        // compute the Jacobian dx/ds for the current guess
        dxds.setZero();
        for (int k = 0; k < numNodes(); k++) {
            getdNds(dNds, k, coords);
            dxds.addOuterProduct(myNodes[k].getLocalPosition(), dNds);
        }
        LUD.factor(dxds);
        double cond = LUD.conditionEstimate(dxds);
        if (cond > 1e10)
            System.err.println("Warning: condition number for solving natural coordinates is " + cond);
        // solve Jacobian to obtain an update for the coords
        LUD.solve(del, res);
        del.negate();
        // use an absolute value for a tolerance threshold
        if (del.norm() < 1e-10) {
            // System.out.println ("1 res=" + res.norm());
            return i + 1;
        }
        prevCoords.set(coords);
        coords.add(del);
        computeNaturalCoordsResidual(res, coords, lpnt);
        double rn = res.norm();
        // If the residual norm is within tolerance, we have converged.
        if (rn < tol) {
            // System.out.println ("2 res=" + rn);
            return i + 1;
        }
        // do a golden section search in range
        double eps = 1e-12;
        func.set(prevCoords, del);
        double alpha = GoldenSectionSearch.minimize(func, 0, 1, eps, 0.8 * prn * prn);
        coords.scaledAdd(alpha, del, prevCoords);
        computeNaturalCoordsResidual(res, coords, lpnt);
        rn = res.norm();
        // System.out.println (" alpha=" + alpha + " rn=" + rn + " prn=" + prn);
        if (alpha < eps) {
            // failed
            return -1;
        }
        prn = rn;
    }
    // failed
    return -1;
}
Also used : Point(artisynth.core.mechmodels.Point)

Example 7 with Point

use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.

the class FemElement3d method getNaturalCoordinates.

/**
 * Given point p, get its natural coordinates with respect to this element.
 * Returns a positive number if the algorithm converges, or -1 if a maximum
 * number of iterations has been reached. Uses a modified Newton's method to solve the
 * equations. The <code>coords</code> argument that returned the coordinates is
 * used, on input, to supply an initial guess of the coordinates.
 * Zero is generally a safe guess.
 *
 * @param coords
 * Outputs the natural coordinates, and supplies (on input) an initial
 * guess as to their position.
 * @param pnt
 * A given point (in world coords)
 * @param maxIters
 * Maximum number of Newton iterations
 * @return the number of iterations required for convergence, or
 * -1 if the calculation did not converge.
 */
public int getNaturalCoordinates(Vector3d coords, Point3d pnt, int maxIters) {
    if (!coordsAreInside(coords)) {
        // if not inside, reset coords to 0
        coords.setZero();
    }
    // if FEM is frame-relative, transform to local coords
    Point3d lpnt = new Point3d(pnt);
    if (getGrandParent() instanceof FemModel3d) {
        FemModel3d fem = (FemModel3d) getGrandParent();
        if (fem.isFrameRelative()) {
            lpnt.inverseTransform(fem.getFrame().getPose());
        }
    }
    Vector3d res = new Point3d();
    int i;
    double tol = RenderableUtils.getRadius(this) * 1e-12;
    computeNaturalCoordsResidual(res, coords, lpnt);
    double prn = res.norm();
    // System.out.println ("res=" + prn);
    if (prn < tol) {
        // already have the right answer
        return 0;
    }
    LUDecomposition LUD = new LUDecomposition();
    Vector3d prevCoords = new Vector3d();
    Vector3d dNds = new Vector3d();
    Matrix3d dxds = new Matrix3d();
    Vector3d del = new Point3d();
    /*
       * solve using Newton's method.
       */
    for (i = 0; i < maxIters; i++) {
        // compute the Jacobian dx/ds for the current guess
        dxds.setZero();
        for (int k = 0; k < numNodes(); k++) {
            getdNds(dNds, k, coords);
            dxds.addOuterProduct(myNodes[k].getLocalPosition(), dNds);
        }
        LUD.factor(dxds);
        double cond = LUD.conditionEstimate(dxds);
        if (cond > 1e10)
            System.err.println("Warning: condition number for solving natural coordinates is " + cond);
        // solve Jacobian to obtain an update for the coords
        LUD.solve(del, res);
        // use an absolute value for a tolerance threshold
        if (del.norm() < 1e-10) {
            // System.out.println ("1 res=" + res.norm());
            return i + 1;
        }
        prevCoords.set(coords);
        coords.sub(del);
        computeNaturalCoordsResidual(res, coords, lpnt);
        double rn = res.norm();
        // If the residual norm is within tolerance, we have converged.
        if (rn < tol) {
            // System.out.println ("2 res=" + rn);
            return i + 1;
        }
        if (rn > prn) {
            // it may be that "coords + del" is a worse solution.  Let's make
            // sure we go the correct way binary search suitable alpha in [0 1]
            double eps = 1e-12;
            // start by limiting del to a magnitude of 1
            if (del.norm() > 1) {
                del.normalize();
            }
            // and keep cutting the step size in half until the residual starts
            // dropping again
            double alpha = 0.5;
            while (alpha > eps && rn > prn) {
                coords.scaledAdd(-alpha, del, prevCoords);
                computeNaturalCoordsResidual(res, coords, lpnt);
                rn = res.norm();
                alpha *= 0.5;
            // System.out.println ("  alpha=" + alpha + " rn=" + rn);
            }
            // System.out.println (" alpha=" + alpha + " rn=" + rn + " prn=" + prn);
            if (alpha < eps) {
                // failed
                return -1;
            }
        }
        prn = rn;
    }
    // failed
    return -1;
}
Also used : Point(artisynth.core.mechmodels.Point)

Example 8 with Point

use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.

the class FemMeshComp method createPointAttachment.

public PointFem3dAttachment createPointAttachment(Point pnt) {
    if (!(getMesh() instanceof PolygonalMesh)) {
        return null;
    }
    PolygonalMesh mesh = (PolygonalMesh) getMesh();
    if (!mesh.isTriangular()) {
        return null;
    }
    // Find nearest face to the point. The vertices of this face will be used
    // to find the nodes and weight for the attachment.
    BVFeatureQuery query = new BVFeatureQuery();
    Point3d near = new Point3d();
    Vector2d uv = new Vector2d();
    Face face = query.nearestFaceToPoint(near, uv, mesh, pnt.getPosition());
    Vertex3d[] vtxs = face.getTriVertices();
    double[] wgts = new double[] { 1 - uv.x - uv.y, uv.x, uv.y };
    HashMap<FemNode, Double> nodeWeights = new HashMap<FemNode, Double>();
    for (int i = 0; i < vtxs.length; i++) {
        PointAttachment va = myVertexAttachments.get(vtxs[i].getIndex());
        if (va instanceof PointParticleAttachment) {
            PointParticleAttachment ppa = (PointParticleAttachment) va;
            FemNode node = (FemNode) ppa.getParticle();
            accumulateNodeWeights(node, wgts[i], nodeWeights);
        } else if (va instanceof PointFem3dAttachment) {
            PointFem3dAttachment pfa = (PointFem3dAttachment) va;
            for (int k = 0; k < pfa.numMasters(); k++) {
                FemNode node = pfa.getNodes()[k];
                double w = pfa.getCoordinate(k);
                accumulateNodeWeights(node, w * wgts[i], nodeWeights);
            }
        }
    }
    // Create a new PointFem3dAttachment
    PointFem3dAttachment ax = new PointFem3dAttachment(pnt);
    VectorNd weightVec = new VectorNd();
    for (Double d : nodeWeights.values()) {
        weightVec.append(d);
    }
    ax.setFromNodes(nodeWeights.keySet(), weightVec);
    return ax;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) HashMap(java.util.HashMap) PointAttachment(artisynth.core.mechmodels.PointAttachment) PolygonalMesh(maspack.geometry.PolygonalMesh) BVFeatureQuery(maspack.geometry.BVFeatureQuery) ContactPoint(artisynth.core.mechmodels.ContactPoint) Point(artisynth.core.mechmodels.Point) Vector2d(maspack.matrix.Vector2d) Point3d(maspack.matrix.Point3d) VectorNd(maspack.matrix.VectorNd) Face(maspack.geometry.Face) PointParticleAttachment(artisynth.core.mechmodels.PointParticleAttachment)

Example 9 with Point

use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.

the class PointSkinAttachment method getSoftReferences.

@Override
public void getSoftReferences(List<ModelComponent> refs) {
    super.getSoftReferences(refs);
    Point point = getPoint();
    if (point != null) {
        refs.add(point);
    }
    for (int i = 0; i < myNumConnections; i++) {
        ModelComponent m = myConnections[i].getMaster();
        if (m != null) {
            refs.add(myConnections[i].getMaster());
        }
    }
}
Also used : ModelComponent(artisynth.core.modelbase.ModelComponent) Point(artisynth.core.mechmodels.Point) Point(artisynth.core.mechmodels.Point)

Example 10 with Point

use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.

the class InverseManager method configureTargetMotionProbe.

private void configureTargetMotionProbe(NumericProbeBase probe, ArrayList<MotionTargetComponent> targets, String filename) {
    // System.out.println ("configuring motion probe");
    ArrayList<Property> props = new ArrayList<Property>();
    for (ModelComponent target : targets) {
        if (target instanceof Point) {
            props.add(target.getProperty("position"));
        } else if (target instanceof Frame) {
            props.add(target.getProperty("position"));
            props.add(target.getProperty("orientation"));
        } else {
            System.err.println("Unknown target component type: " + target.getClass().toString());
        }
    }
    // probe.setModel(myController.getMech());
    probe.setAttachedFileName(filename);
    if (probe instanceof NumericInputProbe) {
        ((NumericInputProbe) probe).setInputProperties(props.toArray(new Property[props.size()]));
    } else if (probe instanceof NumericOutputProbe) {
        ((NumericOutputProbe) probe).setOutputProperties(props.toArray(new Property[props.size()]));
    }
    if (probe instanceof NumericInputProbe) {
        File file = probe.getAttachedFile();
        if (file == null || !file.exists()) {
            ((NumericInputProbe) probe).loadEmpty();
            probe.setActive(false);
        } else {
            try {
                probe.load();
                probe.setActive(true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
Also used : Frame(artisynth.core.mechmodels.Frame) ModelComponent(artisynth.core.modelbase.ModelComponent) NumericInputProbe(artisynth.core.probes.NumericInputProbe) ArrayList(java.util.ArrayList) NumericOutputProbe(artisynth.core.probes.NumericOutputProbe) Point(artisynth.core.mechmodels.Point) WayPoint(artisynth.core.probes.WayPoint) IOException(java.io.IOException) Property(maspack.properties.Property) File(java.io.File)

Aggregations

Point (artisynth.core.mechmodels.Point)33 Point3d (maspack.matrix.Point3d)9 Frame (artisynth.core.mechmodels.Frame)8 ArrayList (java.util.ArrayList)8 VectorNd (maspack.matrix.VectorNd)8 ContactPoint (artisynth.core.mechmodels.ContactPoint)6 MotionTargetComponent (artisynth.core.mechmodels.MotionTargetComponent)5 Vertex3d (maspack.geometry.Vertex3d)5 PointParticleAttachment (artisynth.core.mechmodels.PointParticleAttachment)4 BVFeatureQuery (maspack.geometry.BVFeatureQuery)4 BVNode (maspack.geometry.BVNode)4 Boundable (maspack.geometry.Boundable)4 Vector3d (maspack.matrix.Vector3d)4 FemNode3d (artisynth.core.femmodels.FemNode3d)3 BVTree (maspack.geometry.BVTree)3 Face (maspack.geometry.Face)3 PolygonalMesh (maspack.geometry.PolygonalMesh)3 RotationMatrix3d (maspack.matrix.RotationMatrix3d)3 Vector2d (maspack.matrix.Vector2d)3 FemElement3d (artisynth.core.femmodels.FemElement3d)2