use of maspack.matrix.Vector4d in project artisynth_core by artisynth.
the class NURBSCurve3d method eval.
/**
* {@inheritDoc}
*/
public void eval(Point3d pnt, double u) {
int numc = numControlPoints();
if (numc == 0) {
throw new IllegalStateException("curve does not contain control points");
}
int k = getKnotIndex(u);
double[] bvals = new double[this.myDegree + 1];
basisValues(bvals, k, u);
pnt.setZero();
double w = 0;
for (int i = 0; i <= myDegree; i++) {
Vector4d cpnt = myCtrlPnts.get(getCtrlIndex(k, i, numc));
double wb = cpnt.w * bvals[i];
pnt.x += wb * cpnt.x;
pnt.y += wb * cpnt.y;
pnt.z += wb * cpnt.z;
w += wb;
}
pnt.scale(1 / w);
}
use of maspack.matrix.Vector4d in project artisynth_core by artisynth.
the class NURBSCurveBase method insertKnot.
public void insertKnot(int k, double uval) {
int d = myDegree;
if (k < d - 2 && !myClosedP) {
throw new IllegalArgumentException("k is " + k + ", must be >= degree-1 for open curves");
}
int numc = numControlPoints();
Vector4d[] q = new Vector4d[d];
for (int i = 0; i < d; i++) {
q[i] = new Vector4d();
Vector4d c0 = getControlPoint(getCtrlIndex(k, i, numc));
Vector4d c1 = getControlPoint(getCtrlIndex(k, i + 1, numc));
double u0, u1;
u1 = myKnots[k + 1 + i];
if (k - d + 1 + i >= 0) {
u0 = myKnots[k - d + 1 + i];
} else {
// look at the end of the knot sequence to get appropriate value
u0 = myKnots[0] - (myKnots[numc] - myKnots[numc + k - d + 1 + i]);
}
double alpha = (uval - u0) / (u1 - u0);
q[i].combine(1 - alpha, c0, alpha, c1);
}
for (int i = 0; i < d; i++) {
if (i < d - 1) {
// just overwrite existing control point
getControlPoint(getCtrlIndex(k, i + 1, numc)).set(q[i]);
} else {
// insert new control point.
addControlPoint(getCtrlIndex(k, d, numc), q[i]);
numc++;
}
}
ensureKnotCapacity(myNumKnots + 1);
myNumKnots++;
for (int i = myNumKnots - 1; i > k + 1; i--) {
myKnots[i] = myKnots[i - 1];
}
myKnots[k + 1] = uval;
if (myClosedP) {
// the intervals of the end knots match those at the beginning.
for (int i = 0; i < 2 * d - 2; i++) {
myKnots[numc + 1 + i] = myKnots[numc + i] + (myKnots[i + 1] - myKnots[i]);
}
myUstart = myKnots[d - 1];
myUend = myKnots[myNumKnots - d];
}
}
use of maspack.matrix.Vector4d in project artisynth_core by artisynth.
the class NURBSCurveBase method computeControlPolygonLength.
public double computeControlPolygonLength() {
double len = 0;
int numc = numControlPoints();
if (numc > 0) {
Point3d diff = new Point3d();
Vector4d c0 = getControlPoint(0);
for (int i = 1; i < numControlPoints(); i++) {
Vector4d c1 = getControlPoint(i);
diff.x = c1.x - c0.x;
diff.y = c1.y - c0.y;
diff.z = c1.z - c0.z;
len += diff.norm();
c0 = c1;
}
}
return len;
}
use of maspack.matrix.Vector4d in project artisynth_core by artisynth.
the class NURBSCurve2dTest method addTestCurves.
public void addTestCurves() {
Vector4d[] q4 = new Vector4d[] { new Vector4d(300, 100, 0, 1), new Vector4d(300, 300, 0, 1), new Vector4d(100, 300, 0, 1), new Vector4d(100, 100, 0, 1) };
double[] k4 = new double[] { -2, -1, 0, 1, 2, 3, 4, 5, 6 };
Vector4d[] qclosed = new Vector4d[] { new Vector4d(150, 50, 0, 1), new Vector4d(250, 50, 0, 1), new Vector4d(300, 100, 0, 1), new Vector4d(350, 150, 0, 1), new Vector4d(350, 250, 0, 1), new Vector4d(300, 300, 0, 1), new Vector4d(250, 350, 0, 1), new Vector4d(150, 350, 0, 1), new Vector4d(100, 300, 0, 1), new Vector4d(50, 250, 0, 1), new Vector4d(50, 150, 0, 1), new Vector4d(100, 100, 0, 1) };
double[] kclosed = new double[] { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5 };
Vector4d[] qopen = new Vector4d[] { new Vector4d(100, 100, 0, 1), new Vector4d(150, 50, 0, 1), new Vector4d(250, 50, 0, 1), new Vector4d(300, 100, 0, 1), new Vector4d(350, 150, 0, 1), new Vector4d(350, 250, 0, 1), new Vector4d(300, 300, 0, 1), new Vector4d(250, 350, 0, 1), new Vector4d(150, 350, 0, 1), new Vector4d(100, 300, 0, 1), new Vector4d(50, 250, 0, 1), new Vector4d(50, 150, 0, 1), new Vector4d(100, 100, 0, 1) };
double[] kopen = new double[] { 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11 };
Vector4d[] qsimple = new Vector4d[] { new Vector4d(100, 100, 0, 1), new Vector4d(200, 100, 0, 1), new Vector4d(200, 200, 0, 1), new Vector4d(200, 300, 0, 1), new Vector4d(100, 300, 0, 1), new Vector4d(50, 200, 0, 1) };
double[] ksimple = new double[] { 0, 0, 1, 1 };
// NURBSCurve2d curve = new NURBSCurve2d (2, NURBSCurve2d.CLOSED, q4, null);
NURBSCurve2d curve = new NURBSCurve2d(2, NURBSCurve2d.CLOSED, qsimple, null);
curve.convertToBezier();
writeCurve("curve.txt", curve);
NURBSCurve2d curve2 = readCurve("curve.txt");
NURBSCurve2d check = new NURBSCurve2d(3, NURBSCurve2d.CLOSED, q4, null);
check.transform(new RigidTransform3d(300, 0, 0));
DistanceGrid grid = new DistanceGrid(150, 200, 500, 500, 51, 51);
grid.update(curve2, 50);
QuadBezierDistance2d dist = new QuadBezierDistance2d(curve2);
Vector2d pnt = new Vector2d(250, 200);
Vector2d near = new Vector2d();
double d = dist.computeDistance(near, pnt, 1e10);
System.out.println("max curvature=" + dist.computeMaxCurvature());
myFrame.addRenderable(curve2);
myFrame.addRenderable(grid);
}
use of maspack.matrix.Vector4d in project artisynth_core by artisynth.
the class WavefrontReader method processLine.
protected boolean processLine(ReaderTokenizer rtok) throws IOException {
if (curve != null || surface != null) {
if (!rtok.sval.equals("parm") && !rtok.sval.equals("end")) {
throw new IOException("unexpected keyword '" + rtok.sval + "' between curv/surf and end, line " + rtok.lineno());
}
}
int lineno = rtok.lineno();
if (rtok.sval.equals("v")) {
Vector4d pnt = new Vector4d();
if ((pnt.x = scanDouble(rtok)) != pnt.x || (pnt.y = scanDouble(rtok)) != pnt.y || (pnt.z = scanDouble(rtok)) != pnt.z) {
throw new IOException("vertex coordinate expected, line " + lineno);
}
pnt.w = scanOptionalNumber(rtok, "vertex w coordinate", 1);
vertexList.add(pnt);
// 3 or 4, so flush any extra numbers
if (toEOL(rtok)) {
// extra numbers, so number 4 probably wasn't w
pnt.w = 1;
}
} else if (rtok.sval.equals("vn")) {
Vector3d nrm = new Vector3d();
if ((nrm.x = scanDouble(rtok)) != nrm.x || (nrm.y = scanDouble(rtok)) != nrm.y || (nrm.z = scanDouble(rtok)) != nrm.z) {
throw new IOException("normal coordinate expected, line " + lineno);
}
normalList.add(nrm);
} else if (rtok.sval.equals("vt")) {
Vector3d txt = new Vector3d();
if ((txt.x = scanDouble(rtok)) != txt.x) {
throw new IOException("texture vertex u coordinate expected, line " + lineno);
}
txt.y = scanOptionalNumber(rtok, "texture vertex v coordinate", 0);
txt.z = scanOptionalNumber(rtok, "texture vertex w coordinate", 0);
textureVertexList.add(txt);
} else if (rtok.sval.equals("voff")) {
// non-standard - used when we are reading a snippet from an obj file
myVertexOffset = rtok.scanInteger();
} else if (rtok.sval.equals("vtoff")) {
// non-standard - used when we are reading a snippet from an obj file
myVertexTextureOffset = rtok.scanInteger();
} else if (rtok.sval.equals("vnoff")) {
// non-standard - used when we are reading a snippet from an obj file
myVertexNormalOffset = rtok.scanInteger();
} else if (rtok.sval.equals("f")) {
Face face = new Face();
scanFaceIndices(face, rtok);
myCurrentGroup.faceList.add(face);
} else if (rtok.sval.equals("l")) {
Line line = new Line();
scanLineIndices(line, rtok);
myCurrentGroup.lineList.add(line);
} else if (rtok.sval.equals("deg")) {
double num = scanDouble(rtok);
if (num != num || num != (int) num) {
throw new IOException("u curve degree expected, line " + lineno);
}
degreeu = (int) num;
num = scanOptionalNumber(rtok, "v curve degree", -1);
if (num != (int) num) {
throw new IOException("v curve degree expected, line " + lineno);
}
degreev = (int) num;
} else if (rtok.sval.equals("curv")) {
curve = new Curve();
curve.lineNum = lineno;
curve.isRational = true;
curve.type = BSPLINE;
if ((curve.u0 = scanDouble(rtok)) != curve.u0 || (curve.u1 = scanDouble(rtok)) != curve.u1) {
throw new IOException("u start and end values expected, line " + lineno);
}
curve.indices = scanIndexList(rtok, "control point index");
if (degreeu == -1) {
throw new IOException("degree not specified for curv, line " + lineno);
}
curve.degree = degreeu;
} else if (rtok.sval.equals("surf")) {
surface = new Surface();
surface.lineNum = lineno;
surface.isRational = true;
surface.type = BSPLINE;
if ((surface.u0 = scanDouble(rtok)) != surface.u0 || (surface.u1 = scanDouble(rtok)) != surface.u1 || (surface.v0 = scanDouble(rtok)) != surface.v0 || (surface.v1 = scanDouble(rtok)) != surface.v1) {
throw new IOException("u and v start and end values expected, line " + lineno);
}
Face face = new Face();
scanFaceIndices(face, rtok);
surface.indices = face.indices;
surface.textureIndices = face.textureIndices;
surface.normalIndices = face.normalIndices;
if (degreeu == -1) {
throw new IOException("u degree not specified for surf, line " + lineno);
}
if (degreev == -1) {
throw new IOException("v degree not specified for surf, line " + lineno);
}
surface.udegree = degreeu;
surface.vdegree = degreev;
} else if (rtok.sval.equals("parm")) {
if (curve != null || surface != null) {
boolean closed = false;
boolean isu = true;
double[] knots = null;
nextToken(rtok);
if (rtok.ttype != ReaderTokenizer.TT_WORD || (!rtok.sval.equals("u") && !rtok.sval.equals("v"))) {
if (curve != null) {
throw new IOException("u keyword expected, line " + lineno);
} else {
throw new IOException("u or v keyword expected, line " + lineno);
}
}
if (rtok.sval.equals("v")) {
if (curve != null) {
throw new IOException("v keyword inappropriate for curve construct, line " + lineno);
}
isu = false;
}
nextToken(rtok);
if (rtok.ttype == ReaderTokenizer.TT_WORD && rtok.sval.equals("closed")) {
closed = true;
nextToken(rtok);
}
rtok.pushBack();
knots = scanDoubleList(rtok, "knot point");
if (isu) {
if (curve != null) {
curve.isClosed = closed;
curve.knots = knots;
} else {
surface.uIsClosed = closed;
surface.uknots = knots;
}
} else {
surface.vIsClosed = closed;
surface.vknots = knots;
}
}
} else if (rtok.sval.equals("end")) {
if (surface != null) {
myCurrentGroup.surfaceList.add(surface);
surface = null;
} else if (curve != null) {
myCurrentGroup.curveList.add(curve);
curve = null;
}
} else if (rtok.sval.equals("g") || rtok.sval.equals("sg") || rtok.sval.equals("mg") || rtok.sval.equals("o")) {
rtok.parseNumbers(false);
String groupName = scanName(rtok);
if (rtok.ttype == ReaderTokenizer.TT_WORD) {
setGroup(groupName);
}
while (rtok.ttype != ReaderTokenizer.TT_EOL) {
// ignore secondary
// groups?
nextToken(rtok);
}
rtok.pushBack();
rtok.parseNumbers(true);
} else if (rtok.sval.equals("mtllib")) {
String matFileName = scanFileName(rtok);
try {
parseMaterialFile(matFileName);
} catch (Exception e) {
if (verbose) {
System.out.println("WavefrontReader warning: can't read mtllib '" + matFileName + "'; ignoring");
}
}
} else if (rtok.sval.equals("usemtl")) {
String matName = scanName(rtok);
RenderProps props = myMaterialMap.get(matName);
if (props != null) {
// System.out.println ("usemtl " + matName);
myCurrentGroup.props = props;
} else {
if (verbose) {
System.out.println("WavefrontReader warning: material '" + matName + "' not found; ignoring");
}
}
} else if (rtok.sval.equals("s")) {
// process smoothing group
// either a number, or "off"
nextToken(rtok);
if (rtok.ttype == ReaderTokenizer.TT_NUMBER) {
if (verbose) {
System.out.println("Wavefront smoothing group: " + (int) rtok.lval);
}
} else if ((rtok.ttype != ReaderTokenizer.TT_WORD) || !("off".equals(rtok.sval))) {
System.out.println("Wavefront: unrecognized smoothing group" + rtok);
}
toEOL(rtok);
} else {
return false;
}
return true;
}
Aggregations