/** * Computes a list of points along the spline which are close to uniformly separated by the given * step distance. The uniform distribution is only an approximation and is based on the estimated * arc length of the polyline. The distance between returned points might vary in places, * especially if there're sharp angles between line segments. * * @param step * @param doAddFinalVertex true, if the last vertex computed should be added regardless of its * distance. * @return point list */ public List<Vec3D> getDecimatedVertices(float step, boolean doAddFinalVertex) { ArrayList<Vec3D> uniform = new ArrayList<Vec3D>(); if (vertices.size() < 3) { if (vertices.size() == 2) { new Line3D(vertices.get(0), vertices.get(1)).splitIntoSegments(uniform, step, true); if (!doAddFinalVertex) { uniform.remove(uniform.size() - 1); } } else { return null; } } float arcLen = getEstimatedArcLength(); double delta = (double) step / arcLen; int currIdx = 0; for (double t = 0; t < 1.0; t += delta) { double currT = t * arcLen; while (currT >= arcLenIndex[currIdx]) { currIdx++; } ReadonlyVec3D p = vertices.get(currIdx - 1); ReadonlyVec3D q = vertices.get(currIdx); float frac = (float) ((currT - arcLenIndex[currIdx - 1]) / (arcLenIndex[currIdx] - arcLenIndex[currIdx - 1])); Vec3D i = p.interpolateTo(q, frac); uniform.add(i); } if (doAddFinalVertex) { uniform.add(vertices.get(vertices.size() - 1).copy()); } return uniform; }
public float getEstimatedArcLength() { if (arcLenIndex == null || (arcLenIndex != null && arcLenIndex.length != vertices.size())) { arcLenIndex = new float[vertices.size()]; } float arcLen = 0; for (int i = 1; i < arcLenIndex.length; i++) { ReadonlyVec3D p = vertices.get(i - 1); ReadonlyVec3D q = vertices.get(i); arcLen += p.distanceTo(q); arcLenIndex[i] = arcLen; } return arcLen; }
public LineStrip3D add(ReadonlyVec3D p) { vertices.add(p.copy()); return this; }
/** * Creates particle at the position of the passed in vector * * @param v position */ public VerletParticle3D(ReadonlyVec3D v) { this(v.x(), v.y(), v.z(), 1); }
/** * Creates particle with weight w at the position of the passed in vector * * @param v position * @param w weight */ public VerletParticle3D(ReadonlyVec3D v, float w) { this(v.x(), v.y(), v.z(), w); }