00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Core/precomp.h"
00014 #include "API/Core/Math/bezier.h"
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 CL_BezierCurve::CL_BezierCurve(const CL_Vector *cp, int cs, int steps, bool stepping)
00031 {
00032 curve = new CL_Vector[cs*steps];
00033 this->cp = new CL_Vector[cs*4];
00034 this->steps = steps;
00035 this->stepping = stepping;
00036 this->cs = cs;
00037
00038 for (int i=0;i<cs*4;i++)
00039 this->cp[i] = cp[i];
00040
00041 make_curve();
00042 }
00043
00044
00045 CL_BezierCurve::~CL_BezierCurve()
00046 {
00047 delete [] curve;
00048 delete [] cp;
00049 }
00050
00051
00052
00053
00054
00055
00056 void CL_BezierCurve::make_curve()
00057 {
00058
00059 for (int n=0; n<cs; n++)
00060 {
00061 curve[n*steps] = cp[n*4];
00062
00063 float t, delta;
00064 delta = 1.0/steps;
00065
00066 for (int i=1; i<steps; i++)
00067 {
00068 t = i*delta;
00069 curve[n*steps+i].x =
00070 cp[n*4+0].x * (1.0 - t) * (1.0 - t) * (1.0 - t) +
00071 cp[n*4+1].x * 3.0 * t * (1.0 - t) * (1.0 - t) +
00072 cp[n*4+2].x * 3.0 * t * t * (1.0 - t) +
00073 cp[n*4+3].x * t * t * t;
00074
00075 curve[n*steps+i].y =
00076 cp[n*4+0].y * (1.0 - t) * (1.0 - t) * (1.0 - t) +
00077 cp[n*4+1].y * 3.0 * t * (1.0 - t) * (1.0 - t) +
00078 cp[n*4+2].y * 3.0 * t * t * (1.0 - t) +
00079 cp[n*4+3].y * t * t * t;
00080
00081 curve[n*steps+i].z =
00082 cp[n*4+0].z * (1.0 - t) * (1.0 - t) * (1.0 - t) +
00083 cp[n*4+1].z * 3.0 * t * (1.0 - t) * (1.0 - t) +
00084 cp[n*4+2].z * 3.0 * t * t * (1.0 - t) +
00085 cp[n*4+3].z * t * t * t;
00086 }
00087 }
00088 }
00089
00090
00091 float CL_BezierCurve::get_length(int segment) const
00092 {
00093 if (segment == -1)
00094 {
00095 float length = 0;
00096 for (int i=0;i<cs;i++)
00097 length += get_length(cs);
00098 return length;
00099 }
00100
00101 return 0;
00102 }
00103
00104
00105 void CL_BezierCurve::set_steps(int steps)
00106 {
00107 delete [] curve;
00108 curve = new CL_Vector[cs*steps];
00109 this->steps = steps;
00110 make_curve();
00111 }
00112
00113
00114 void CL_BezierCurve::set_stepping(bool stepping)
00115 {
00116 this->stepping = stepping;
00117 make_curve();
00118 }
00119
00120
00121
00122
00123 CL_BezierSurface::CL_BezierSurface(const CL_Vector *cp, int xs, int ys, int xsteps, int ysteps, bool stepping)
00124 {
00125 surface = new CL_Vector[xs*xsteps*ys*ysteps];
00126 this->cp = new CL_Vector[xs*ys*16];
00127 this->xsteps = xsteps;
00128 this->ysteps = ysteps;
00129 this->stepping = stepping;
00130 this->xs = xs;
00131 this->ys = ys;
00132
00133 for (int i=0;i<xs*ys*16;i++)
00134 this->cp[i] = cp[i];
00135
00136 make_surface();
00137 }
00138
00139
00140 CL_BezierSurface::~CL_BezierSurface()
00141 {
00142 delete [] surface;
00143 delete [] cp;
00144 }
00145
00146
00147 CL_Vector CL_BezierSurface::evaluate(float s, float t, int offset)
00148 {
00149 int stride = 4 * xs;
00150 CL_Vector v;
00151
00152 for (int i=0; i<3; i++)
00153 {
00154 v[i] = (1-s)*(1-s)*(1-s)* (
00155 cp[offset+0+0*stride][i] * (1-t)*(1-t)*(1-t) +
00156 cp[offset+0+1*stride][i] * 3*(1-t)*(1-t)*t +
00157 cp[offset+0+2*stride][i] * 3*(1-t)*t*t +
00158 cp[offset+0+3*stride][i] *t*t*t) +
00159
00160 3*(1-s)*(1-s)*s* (
00161 cp[offset+1+0*stride][i] * (1-t)*(1-t)*(1-t) +
00162 cp[offset+1+1*stride][i] * 3*(1-t)*(1-t)*t +
00163 cp[offset+1+2*stride][i] * 3*(1-t)*t*t +
00164 cp[offset+1+3*stride][i] *t*t*t) +
00165
00166 3*(1-s)*s*s* (
00167 cp[offset+2+0*stride][i] * (1-t)*(1-t)*(1-t) +
00168 cp[offset+2+1*stride][i] * 3*(1-t)*(1-t)*t +
00169 cp[offset+2+2*stride][i] * 3*(1-t)*t*t +
00170 cp[offset+2+3*stride][i] *t*t*t) +
00171
00172 s*s*s* (
00173 cp[offset+3+0*stride][i] * (1-t)*(1-t)*(1-t) +
00174 cp[offset+3+1*stride][i] * 3*(1-t)*(1-t)*t +
00175 cp[offset+3+2*stride][i] * 3*(1-t)*t*t +
00176 cp[offset+3+3*stride][i] *t*t*t);
00177 }
00178 return v;
00179 }
00180
00181 void CL_BezierSurface::make_surface()
00182 {
00183
00184
00185 for (int y=0; y<ys; y++)
00186 {
00187 for (int x=0; x<xs; x++)
00188 {
00189 float s,t, deltax, deltay;
00190
00191 deltax = 1.0/xsteps;
00192 deltay = 1.0/ysteps;
00193
00194 for (int ny=0; ny<ysteps; ny++)
00195 {
00196 for (int nx=0; nx<xsteps; nx++)
00197 {
00198 s = nx * deltax;
00199 t = ny * deltay;
00200
00201 surface[y*ysteps*xsteps*xs + x] = evaluate(s,t, y*16*xs + x);
00202 }
00203 }
00204 }
00205 }
00206 }
00207
00208
00209 void CL_BezierSurface::set_xsteps(int xsteps)
00210 {
00211 delete [] surface;
00212 surface = new CL_Vector[xs*xsteps*ys*ysteps];
00213 this->xsteps = xsteps;
00214 make_surface();
00215 }
00216
00217
00218 void CL_BezierSurface::set_ysteps(int ysteps)
00219 {
00220 delete [] surface;
00221 surface = new CL_Vector[xs*xsteps*ys*ysteps];
00222 this->ysteps = ysteps;
00223 make_surface();
00224 }
00225
00226
00227 void CL_BezierSurface::set_stepping(bool stepping)
00228 {
00229 this->stepping = stepping;
00230 make_surface();
00231 }