3 Mechanical Models I

3.6 Other point-based forces

All ArtiSynth components which are capable of exerting forces, including the axial springs of Section 3.1 and the frame springs of Section 3.5, are subclasses of ForceComponent. Other force effector types include PointPlaneForce and PointMeshForce, described in this section.

3.6.1 Forces between points and planes or meshes

A PointPlaneForce component produces forces between a point and a plane, based on the point’s signed distance d from the plane. Similarly, a PointMeshForce component produces forces between one or more points and a closed polygonal mesh, based on the signed distance d to the mesh. These components thus implement “soft” constraint forces that bind points to either a plane or a mesh. If the component’s unilateral property is set to true, as described below, forces are applied only when d<0. This allows the simulation of force-based contact between points and planes or meshes.

PointPlaneForce and PointMeshForce can be used for particles, FEM nodes and point-based markers, all of which are subclasses of Point.

These force components result in a force {\bf f} acting on the point given by

{\bf f}=f(d,\dot{d})\;{\bf n},\qquad f(d,\dot{d})=-\text{sgn}(d)f_{K}(|d|)-D%
\dot{d},

where d is the signed distance to the plane (or mesh), {\bf n} is the plane normal (or surface normal at the nearest mesh point), f_{K}(d) is a stiffness force and D is a damping constant. The stiffness force may be either linear or quadratic, according to

f_{K}(d)=\begin{cases}Kd&\text{(linear)}\\
Kd^{2}&\text{(quadratic)}\end{cases}

where K is a stiffness constant and the choice of linear or quadratic is controlled by the component’s forceType property.

If the component’s unilateral property is set to true, then the computed force will be 0 whenever d>0:

{\bf f}=\begin{cases}f(d,\dot{d})d&d\leq 0\\
0&d>0\end{cases}

This allows plane and mesh force objects to implement “soft” collisions.

In the unilateral case, a quadratic force function provides smoother force transitions at d=0.

PointPlaneForce may be created with the following constructors:

PointPlaneForce (Point p, Plane plane)

Plane force component for point p

PointPlaneForce (Point p, Vector3d nrml, Point3d center)

Plane is specified by its normal and center.

Each of these creates a force component for a single point p, with the plane specified by either a Plane object or by its normal and center.

PointMeshForce may be created with the following constructors:

PointMeshForce (MeshComponent mcomp)

Mesh force for the mesh component mcomp.

PointMeshForce (String name, MeshComponent mcomp)

Named mesh force for mesh mcomp.

PointMeshForce (String name, MeshComponent mcomp, Mdouble K, double D)

Named mesh force with specified stiffness and damping.

These create PointMeshForce for a mesh contained within a MeshComponent (Section 3.8). The mesh must a polygonal mesh composed of triangles.

The points associated with a PointMeshForce are added to after creation. The following methods are used to manage the point set:

void addPoint (Point p)

Adds point p.

boolean removePoint (Point p)

Removes point p.

int numPoints()

Returns the number of points.

Point getPoint (int idx)

Returns the idx-th point.

void clearAllPoints()

Removes all points.

PointPlaneForce and PointMeshForce export a variety of properties that control their force behavior and appearance:

  • stiffness: A double value giving the stiffness constant K. Default value 1.0.

  • damping: A double value giving the damping constant D. Default value 0.0.

  • forceType: A value of type PointPlaneForce.ForceType or PointMeshForce.ForceType which describes the stiffness force, with the options being LINEAR and QUADRATIC. Default value LINEAR.

  • unilateral: A boolean value, which if true means that no force will be generated for d>0. Default value false for PointPlaneForce and true for PointMeshForce.

  • enabled: A boolean value, which if false disables the component so that it will generate no force. Default value true.

  • planeSize: For PointPlaneForce only, a double value that gives the size of the plane for rendering purposes only. Default value 1.0.

These properties can be set either interactively in the GUI, or in code using their accessor methods.

3.6.2 Example: point plane forces

Figure 3.30: PointPlaneForces model running in ArtiSynth.

An example using PointPlaneForce is given by

  artisynth.demos.tutorial.PointPlaneForces

which implements soft collision between a particle and two planes. The build() method is shown below:

1    public void build (String[] args) {
2       MechModel mech = new MechModel ("mech");
3       addModel (mech);
4
5       // create the particle that will collide with the planes
6       Particle p = new Particle ("part", 1, 1.0, 0, 2.0);
7       mech.addParticle (p);
8
9       // create the PointPlaneForce for the left plane
10       double stiffness = 1000;
11       PointPlaneForce ppfL =
12          new PointPlaneForce (p, new Vector3d (1, 0, 1), Point3d.ZERO);
13       ppfL.setStiffness (stiffness);
14       ppfL.setPlaneSize (5.0);
15       ppfL.setUnilateral (true);
16       mech.addForceEffector (ppfL);
17
18       // create the PointPlaneForce for the right plane
19       PointPlaneForce ppfR =
20          new PointPlaneForce (p, new Vector3d (-1, 0, 1), Point3d.ZERO);
21       ppfR.setStiffness (stiffness);
22       ppfR.setPlaneSize (5.0);
23       ppfR.setUnilateral (true);
24       mech.addForceEffector (ppfR);
25
26       // render properties: make the particle red, and the planes blue-gray
27       RenderProps.setSphericalPoints (mech, 0.1, Color.RED);
28       RenderProps.setFaceColor (mech, new Color (0.7f, 0.7f, 0.9f));
29    }
30 }

A MechModel is created in the usual way (lines 2-3), followed by a particle (lines 6-7). Then two PointPlaneForces are created to act on this particle (lines 10-24), each centered on the origin, with plane normals of (1,0,1) and (-1,0,1), respectively. The forces are unilateral and linear (the default), with a stiffness of 1000. Each plane’s size is set to 5; this is for rendering purposes only, as the planes have infinite extent for purposes of force calculation. Lastly, rendering properties are set (lines 27-28) to make the particle appear as a red sphere and the planes blue-gray.

To run this example in ArtiSynth, select All demos > tutorial > PointPlaneForces from the Models menu. When run, the particle will drop and bounce off the planes (Figure 3.30), finally coming to rest along the line where they intersect.

This model does not include damping, and so damping effects are due entirely to the default implicit integrator ConstrainedBackwardEuler. If the integrator is changed to an explicit one, using a directive such as

  mech.setIntegrator (Integrator.RungeKutta4);

then the ball will continue to bounce during the simulation.

3.6.3 Example: point mesh forces

Figure 3.31: PointMeshForces model running in ArtiSynth.

An example using PointMeshForce is given by

  artisynth.demos.tutorial.PointMeshForces

which implements soft collision between a rigid cube and a bowl-shaped mesh, using a PointMeshForce to create force between the mesh and markers at the cube corners. The build() method is shown below:

1    public void build (String[] args) throws IOException {
2       // create a MechModel and add it to the root model
3       MechModel mech = new MechModel ("mech");
4       mech.setInertialDamping (1.0);
5       addModel (mech);
6
7       // create the cube as a rigid body
8       RigidBody cube = RigidBody.createBox (
9          "cube", /*wx*/0.5, /*wy*/0.5, /*wz*/0.5, /*density*/1000);
10       mech.addRigidBody (cube);
11       // position the cube to drop into the bowl
12       cube.setPose (new RigidTransform3d (0.3, 0, 1));
13
14       // add a marker to each vertex of the cube
15       for (Vertex3d vtx : cube.getSurfaceMesh().getVertices()) {
16          // vertex positions will be in cube local coordinates
17          mech.addFrameMarker (cube, vtx.getPosition());
18       }
19       // create the bowl for the cube to drop into
20       String geoDir = PathFinder.getSourceRelativePath (this, "data/");
21       PolygonalMesh mesh = new PolygonalMesh (geoDir + "bowl.obj");
22       mesh.triangulate(); // mesh must be triangulated
23       FixedMeshBody bowl = new FixedMeshBody (mesh);
24       mech.addMeshBody (bowl);
25
26       // Create a PointMeshForce to produce collision interaction between the
27       // bowl and the cube. Use the markers as the mesh-colliding points.
28       PointMeshForce pmf =
29          new PointMeshForce ("pmf", bowl, /*stiffness*/2000000, /*damping*/1000);
30       for (FrameMarker m : mech.frameMarkers()) {
31          pmf.addPoint (m);
32       }
33       pmf.setForceType (ForceType.QUADRATIC);
34       mech.addForceEffector (pmf);
35
36       // render properties: make cube blue-gray, bowl light gray, and
37       // the markers red spheres
38       RenderProps.setFaceColor (cube, new Color (0.7f, 0.7f, 1f));
39       RenderProps.setFaceColor (bowl, new Color (0.8f, 0.8f, 0.8f));
40       RenderProps.setSphericalPoints (mech, 0.04, Color.RED);
41    }
42 }

A MechModel is created (lines 3-5), with inertialDamping set to 1.0 to help reduce oscillations as the cube bounces off the bowl. The cube itself is created as a RigidBody and positioned so as to fall into the bowl under gravity (lines 8-12). A frame marker is placed at each of the cube’s corners, using the (local) positions of its surface mesh vertices to determine the marker locations (lines 13-18); these markers will act as the collision points.

The bowl is constructed as a FixedMeshBody containing a mesh read from the folder "data/" located beneath the source folder of the model (lines 8-12). A PointMeshForce is then allocated for the bowl (lines 28-34), with unilateral behavior (the default) and a quadratic stiffness force with K=200000 and D=1000. Each marker point is added to it to enforce the collision. Lastly, rendering properties are set (lines 38-40) to set the colors for the cube and bowl and make the markers appear as a red spheres.

To run this example in ArtiSynth, select All demos > tutorial > PointMeshForces from the Models menu. When run, the cube will drop into the bowl and bounce around (Figure 3.31).

Because of the discrete nature of the simulation, force-based collision handling is subject to the same time step limitations as constraint-based collisions (Section 8.9). In particular, insufficiently small time steps, or too small a stiffness, may cause objects to pass through each other. Insufficient damping may also result in excessive bouncing.