Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenbezierEval.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
1.7.6.1
|