Frederic Francis (pffred++at++llogic.com)
Fri, 24 Oct 1997 23:07:48 -0400 (EDT)
> Hi all,
> This question is not especifically a pf one, but a general 3D animation
> question.
>
> I know the following input space-time data :
> at time t1 : x1, y1, z1, vx1, vy1, vz1
> at time t2 : x2, y2, z2, vx2, vy2, vz2
>
> I want the interpolated : x, y, z for time t, where t1 <= t < t2
> The path should obviously be smooth and derivable.
>
> I know this may be a cubic spline (4 constraints), or something like that,
> but I would like to get a good formula, without re-inventing the wheel...
>
> the pfuPath utilities does not convince me, because it is working with a set
> of lines and fillets, while I am working with a discrete set of points and
> speeds. But maybe there is a simple way to convert my input data given above,
> into pfuPath input lines-arcs data...
>
> Thanks
> Mike
Hi Michael,
Here is some code which creates a pf line segment from a
Bezier curve segment. I haven't used in a while but it
should work.
Feel free to mail me directly if you have problems getting
what you need out of it.
Fred.
__________________________________________________________
#include <math.h>
#include <Performer/pr/pfGeoSet.h>
#include <Performer/pr/pfLinMath.h>
#include <Performer/pf/pfGeode.h>
#include <iostream.h>
struct controlPoints {
pfVec3 p0,p1,p2,p3;
};
void calculateBezierQ(pfVec3 &q, float t, const controlPoints &cp);
pfNode *makeSpline(void) {
int numSegments = 1;
int numControlPoints = 4;
int numCoordsPerSegment = 10;
controlPoints cp;
// Refer to Computer Graphics Principles and Practice
// 2nd Edition by Foley, van Dam, Feiner, Hughes
// pages 488-489 to see how to relate your v1 and v2
// vectors to the middle control points:
// v1 = 3(cp.p1 - cp.p0) v2 = 3(cp.p3 - cp.p2)
cp.p0.set(0.0f, 0.0f, 0.0f); // x1, y1, z1
cp.p1.set(4.0f, 0.0f, 3.0f);
cp.p2.set(4.0f, 0.0f, 0.0f);
cp.p3.set(5.0f, 0.0f, 0.8f); // x2, y2, z2
int numCoords = numSegments * numCoordsPerSegment;
pfVec3 *coords = (pfVec3 *) new(numCoords * sizeof(pfVec3)) pfMemory;
float delta = numCoords - 1;
delta = 1.0f / delta;
for (int i=0; i < numCoords; i++)
{
float t = i * delta;
calculateNurbsQ(coords[i], t, cp);
}
pfVec4 *colors = (pfVec4 *) new(sizeof(pfVec4)) pfMemory;
colors[0].set(0.0f, 1.0f, 0.0f, 1.0f);
pfGeoSet *gset = new pfGeoSet;
gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, coords, NULL);
gset->setAttr(PFGS_COLOR4, PFGS_OVERALL, colors, NULL);
gset->setPrimType(PFGS_LINESTRIPS);
int numPrims = 1;
gset->setNumPrims(numPrims);
int *len = (int *) new(numPrims*sizeof(int)) pfMemory;
len[0] = numCoords;
gset->setPrimLengths(len);
pfGeode *geode = new pfGeode;
geode->addGSet(gset);
return geode;
}
void calculateBezierQ(pfVec3 &q, float t, const controlPoints &cp) {
float qvalue[3];
float oneMinusT = 1.0f - t;
float b0 = pow(oneMinusT,3);
float b1 = 3.0 * t * pow(oneMinusT,2);
float b2 = 3.0 * pow(t, 2) * oneMinusT;
float b3 = pow(t, 3);
for (int i=0; i < 3; i++)
{
qvalue[i] = b0 * cp.p0[i] + b1 * cp.p1[i] + b2 * cp.p2[i] + b3 * cp.p3[i];
}
q.set(qvalue[0], qvalue[1], qvalue[2]);
}
__________________________________________________________________
Frederic Francis email: fred++at++llogic.com
Director of Technology phone: 1-514-287-1166
Lateral Logic fax: 1-514-287-3360
__________________________________________________________________
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
Submissions: info-performer++at++sgi.com
Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:56:07 PDT