Mercurial > hg > dmlib
comparison src/dmcurves.c @ 976:1b439304ff3c
Add new module dmcurves, that will contain functions for spline generation
etc and the LERP functions. Move LERP functions from dmlib.h to dmcurves.h.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 27 Feb 2015 16:16:59 +0200 |
parents | |
children | fecf3967abee |
comparison
equal
deleted
inserted
replaced
975:139b801f8d1c | 976:1b439304ff3c |
---|---|
1 /* | |
2 * DMLib | |
3 * -- Curve and spline functions | |
4 * Programmed and designed by Matti 'ccr' Hamalainen | |
5 * (C) Copyright 2015 Tecnic Software productions (TNSP) | |
6 */ | |
7 #include "dmcurves.h" | |
8 | |
9 | |
10 static inline const DMVector *dmSplineGetPoint(const DMVector *points, const int npoints, const int n) | |
11 { | |
12 return (n < 0) ? &points[0] : ((n < npoints) ? &points[n] : &points[npoints - 1]); | |
13 } | |
14 | |
15 | |
16 int dmBSplineGenerate(DMVector *dst, const int ndst, const DMVector *points, const int npoints, const int slod) | |
17 { | |
18 int cv, j; | |
19 DMVector *curr = dst; | |
20 | |
21 for (cv = -3, j = 0; j != npoints + 1 && j < ndst; j++, cv++, curr++) | |
22 { | |
23 // for each section of curve, draw 'lod' number of divisions | |
24 int i; | |
25 for (i = 0; i != slod; i++) | |
26 { | |
27 // use the parametric time value 0.0 to 1.0 for this curve segment | |
28 const float t = (float) i / slod; | |
29 | |
30 // inverse value of 't' | |
31 const float it = 1.0f - t; | |
32 | |
33 // calculate blending functions for cubic bspline | |
34 const float t2 = t * t; | |
35 const float t3 = t2 * t; | |
36 const float b0 = it * it * it / 6.0f; | |
37 const float b1 = ( 3*t3 - 6*t2 + 4) / 6.0f; | |
38 const float b2 = (-3*t3 + 3*t2 + 3*t + 1) / 6.0f; | |
39 const float b3 = t3 / 6.0f; | |
40 | |
41 // calculate the x,y and z of the curve point | |
42 curr->x = b0 * dmSplineGetPoint(points, npoints, cv + 0)->x + | |
43 b1 * dmSplineGetPoint(points, npoints, cv + 1)->x + | |
44 b2 * dmSplineGetPoint(points, npoints, cv + 2)->x + | |
45 b3 * dmSplineGetPoint(points, npoints, cv + 3)->x; | |
46 | |
47 curr->y = b0 * dmSplineGetPoint(points, npoints, cv + 0)->y + | |
48 b1 * dmSplineGetPoint(points, npoints, cv + 1)->y + | |
49 b2 * dmSplineGetPoint(points, npoints, cv + 2)->y + | |
50 b3 * dmSplineGetPoint(points, npoints, cv + 3)->y; | |
51 | |
52 curr->z = b0 * dmSplineGetPoint(points, npoints, cv + 0)->z + | |
53 b1 * dmSplineGetPoint(points, npoints, cv + 1)->z + | |
54 b2 * dmSplineGetPoint(points, npoints, cv + 2)->z + | |
55 b3 * dmSplineGetPoint(points, npoints, cv + 3)->z; | |
56 } | |
57 } | |
58 | |
59 return (j == ndst) ? DMERR_OK : DMERR_BOUNDS; | |
60 } | |
61 | |
62 | |
63 int dmBSplineGenerateAlloc(DMVector **dst, int *ndst, const DMVector *points, const int npoints, const int slod) | |
64 { | |
65 if (ndst == NULL || dst == NULL) | |
66 return DMERR_NULLPTR; | |
67 | |
68 if ((*ndst = dmBSplineGetNPoints(npoints, slod)) <= 0) | |
69 return DMERR_INVALID_DATA; | |
70 | |
71 if ((*dst = dmCalloc(*ndst, sizeof(DMVector))) == NULL) | |
72 return DMERR_MALLOC; | |
73 | |
74 return dmBSplineGenerate(*dst, *ndst, points, npoints, slod); | |
75 } |