ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bezierEval.cc
Go to the documentation of this file.
00001 /*
00002 ** License Applicability. Except to the extent portions of this file are
00003 ** made subject to an alternative license as permitted in the SGI Free
00004 ** Software License B, Version 1.1 (the "License"), the contents of this
00005 ** file are subject only to the provisions of the License. You may not use
00006 ** this file except in compliance with the License. You may obtain a copy
00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
00009 **
00010 ** http://oss.sgi.com/projects/FreeB
00011 **
00012 ** Note that, as provided in the License, the Software is distributed on an
00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00017 **
00018 ** Original Code. The Original Code is: OpenGL Sample Implementation,
00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
00021 ** Copyright in any portions created by third parties is as indicated
00022 ** elsewhere herein. All Rights Reserved.
00023 **
00024 ** Additional Notice Provisions: The application programming interfaces
00025 ** established by SGI in conjunction with the Original Code are The
00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software
00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
00031 ** published by SGI, but has not been independently verified as being
00032 ** compliant with the OpenGL(R) version 1.2.1 Specification.
00033 **
00034 */
00035 /*
00036 */
00037 
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <assert.h>
00041 #include <math.h>
00042 #include "bezierEval.h"
00043 
00044 #ifdef __WATCOMC__
00045 #pragma warning 14  10
00046 #endif
00047 
00048 #define TOLERANCE 0.0001
00049 
00050 #ifndef MAX_ORDER
00051 #define MAX_ORDER 16
00052 #endif
00053 
00054 #ifndef MAX_DIMENSION
00055 #define MAX_DIMENSION 4
00056 #endif
00057 
00058 static void normalize(float vec[3]);
00059 static void crossProduct(float x[3], float y[3], float ret[3]);
00060 
00061 static float binomialCoefficients[8][8] = {
00062   {1,0,0,0,0,0,0,0},
00063   {1,1,0,0,0,0,0,0},
00064   {1,2,1,0,0,0,0,0},
00065   {1,3,3,1,0,0,0,0},
00066   {1,4,6,4,1,0,0,0},
00067   {1,5,10,10,5,1,0,0},
00068   {1,6,15,20,15,6,1,0},
00069   {1,7,21,35,35,21,7,1}
00070 };
00071 
00072 void bezierCurveEval(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[])
00073 {
00074   float uprime = (u-u0)/(u1-u0);
00075   float *ctlptr = ctlpoints;
00076   float oneMinusX = 1.0f-uprime;
00077   float XPower = 1.0f;
00078 
00079   int i,k;
00080   for(k=0; k<dimension; k++)
00081     retpoint[k] = (*(ctlptr + k));
00082 
00083   for(i=1; i<order; i++){
00084     ctlptr += stride;
00085     XPower *= uprime;
00086     for(k=0; k<dimension; k++) {
00087       retpoint[k] = retpoint[k]*oneMinusX + ctlptr[k]* binomialCoefficients[order-1][i] * XPower;
00088     }
00089   }
00090 }
00091 
00092 
00093 /*order = degree +1 >=1.
00094  */
00095 void bezierCurveEvalDer(float u0, float u1, int order, float *ctlpoints, int stride,  int dimension, float u, float retDer[])
00096 {
00097   int i,k;
00098   float width = u1-u0;
00099   float *ctlptr = ctlpoints;
00100 
00101   float buf[MAX_ORDER][MAX_DIMENSION];
00102   if(order == 1){
00103     for(k=0; k<dimension; k++)
00104       retDer[k]=0;
00105   }
00106   for(i=0; i<order-1; i++){
00107     for(k=0; k<dimension; k++) {
00108       buf[i][k] = (ctlptr[stride+k] - ctlptr[k])*(order-1)/width;
00109     }
00110     ctlptr += stride;
00111   }
00112 
00113   bezierCurveEval(u0, u1, order-1, (float*) buf, MAX_DIMENSION,  dimension, u, retDer);
00114 }
00115 
00116 void bezierCurveEvalDerGen(int der, float u0, float u1, int order, float *ctlpoints, int stride,  int dimension, float u, float retDer[])
00117 {
00118   int i,k,r;
00119   float *ctlptr = ctlpoints;
00120   float width=u1-u0;
00121   float buf[MAX_ORDER][MAX_ORDER][MAX_DIMENSION];
00122   if(der<0) der=0;
00123   for(i=0; i<order; i++){
00124     for(k=0; k<dimension; k++){
00125       buf[0][i][k] = ctlptr[k];
00126     }
00127     ctlptr += stride;
00128   }
00129 
00130 
00131   for(r=1; r<=der; r++){
00132     for(i=0; i<order-r; i++){
00133       for(k=0; k<dimension; k++){
00134     buf[r][i][k] = (buf[r-1][i+1][k] - buf[r-1][i][k])*(order-r)/width;
00135       }
00136     }
00137   }
00138 
00139   bezierCurveEval(u0, u1, order-der, (float *) (buf[der]), MAX_DIMENSION, dimension, u, retDer);
00140 }
00141 
00142 /*the Bezier bivarite polynomial is:
00143  * sum[i:0,uorder-1][j:0,vorder-1] { ctlpoints[i*ustride+j*vstride] * B(i)*B(j)
00144  * where B(i) and B(j) are basis functions
00145  */
00146 void bezierSurfEvalDerGen(int uder, int vder, float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[])
00147 {
00148   int i;
00149   float newPoints[MAX_ORDER][MAX_DIMENSION];
00150 
00151   for(i=0; i<uorder; i++){
00152 
00153     bezierCurveEvalDerGen(vder, v0, v1, vorder, ctlpoints+ustride*i, vstride, dimension, v, newPoints[i]);
00154 
00155   }
00156 
00157   bezierCurveEvalDerGen(uder, u0, u1, uorder, (float *) newPoints, MAX_DIMENSION, dimension, u, ret);
00158 }
00159 
00160 
00161 /*division by w is performed*/
00162 void bezierSurfEval(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[])
00163 {
00164   bezierSurfEvalDerGen(0, 0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, ret);
00165   if(dimension == 4) /*homogeneous*/{
00166     ret[0] /= ret[3];
00167     ret[1] /= ret[3];
00168     ret[2] /= ret[3];
00169   }
00170 }
00171 
00172 void bezierSurfEvalNormal(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float retNormal[])
00173 {
00174   float partialU[4];
00175   float partialV[4];
00176   assert(dimension>=3 && dimension <=4);
00177   bezierSurfEvalDerGen(1,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialU);
00178   bezierSurfEvalDerGen(0,1, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialV);
00179 
00180   if(dimension == 3){/*inhomogeneous*/
00181     crossProduct(partialU, partialV, retNormal);
00182 
00183     normalize(retNormal);
00184 
00185     return;
00186   }
00187   else { /*homogeneous*/
00188     float val[4]; /*the point coordinates (without derivative)*/
00189     float newPartialU[MAX_DIMENSION];
00190     float newPartialV[MAX_DIMENSION];
00191     int i;
00192     bezierSurfEvalDerGen(0,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, val);
00193 
00194     for(i=0; i<=2; i++){
00195       newPartialU[i] = partialU[i] * val[3] - val[i] * partialU[3];
00196       newPartialV[i] = partialV[i] * val[3] - val[i] * partialV[3];
00197     }
00198     crossProduct(newPartialU, newPartialV, retNormal);
00199     normalize(retNormal);
00200   }
00201 }
00202 
00203 /*if size is 0, then nothing is done*/
00204 static void normalize(float vec[3])
00205 {
00206   float size = (float)sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
00207 
00208   if(size < TOLERANCE)
00209     {
00210 #ifdef DEBUG
00211       fprintf(stderr, "Warning: in oglBSpline.c normal is 0\n");
00212 #endif
00213       return;
00214     }
00215   else {
00216     vec[0] = vec[0]/size;
00217     vec[1] = vec[1]/size;
00218     vec[2] = vec[2]/size;
00219   }
00220 }
00221 
00222 
00223 static void crossProduct(float x[3], float y[3], float ret[3])
00224 {
00225   ret[0] = x[1]*y[2] - y[1]*x[2];
00226   ret[1] = x[2]*y[0] - y[2]*x[0];
00227   ret[2] = x[0]*y[1] - y[0]*x[1];
00228 
00229 }
00230 

Generated on Sun May 27 2012 04:23:37 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.