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

geom.c
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 ** Author: Eric Veach, July 1994.
00037 **
00038 ** $Date: 2007-10-19 23:21:45 +0000 (Fri, 19 Oct 2007) $ $Revision: 1.1 $
00039 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libtess/geom.c,v 1.1 2004/02/02 16:39:15 navaraf Exp $
00040 */
00041 
00042 #include "gluos.h"
00043 #include <assert.h>
00044 #include "mesh.h"
00045 #include "geom.h"
00046 
00047 int __gl_vertLeq( GLUvertex *u, GLUvertex *v )
00048 {
00049   /* Returns TRUE if u is lexicographically <= v. */
00050 
00051   return VertLeq( u, v );
00052 }
00053 
00054 GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
00055 {
00056   /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w),
00057    * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
00058    * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v.
00059    * If uw is vertical (and thus passes thru v), the result is zero.
00060    *
00061    * The calculation is extremely accurate and stable, even when v
00062    * is very close to u or w.  In particular if we set v->t = 0 and
00063    * let r be the negated result (this evaluates (uw)(v->s)), then
00064    * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t).
00065    */
00066   GLdouble gapL, gapR;
00067 
00068   assert( VertLeq( u, v ) && VertLeq( v, w ));
00069 
00070   gapL = v->s - u->s;
00071   gapR = w->s - v->s;
00072 
00073   if( gapL + gapR > 0 ) {
00074     if( gapL < gapR ) {
00075       return (v->t - u->t) + (u->t - w->t) * (gapL / (gapL + gapR));
00076     } else {
00077       return (v->t - w->t) + (w->t - u->t) * (gapR / (gapL + gapR));
00078     }
00079   }
00080   /* vertical line */
00081   return 0;
00082 }
00083 
00084 GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
00085 {
00086   /* Returns a number whose sign matches EdgeEval(u,v,w) but which
00087    * is cheaper to evaluate.  Returns > 0, == 0 , or < 0
00088    * as v is above, on, or below the edge uw.
00089    */
00090   GLdouble gapL, gapR;
00091 
00092   assert( VertLeq( u, v ) && VertLeq( v, w ));
00093 
00094   gapL = v->s - u->s;
00095   gapR = w->s - v->s;
00096 
00097   if( gapL + gapR > 0 ) {
00098     return (v->t - w->t) * gapL + (v->t - u->t) * gapR;
00099   }
00100   /* vertical line */
00101   return 0;
00102 }
00103 
00104 
00105 /***********************************************************************
00106  * Define versions of EdgeSign, EdgeEval with s and t transposed.
00107  */
00108 
00109 GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
00110 {
00111   /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w),
00112    * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
00113    * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v.
00114    * If uw is vertical (and thus passes thru v), the result is zero.
00115    *
00116    * The calculation is extremely accurate and stable, even when v
00117    * is very close to u or w.  In particular if we set v->s = 0 and
00118    * let r be the negated result (this evaluates (uw)(v->t)), then
00119    * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s).
00120    */
00121   GLdouble gapL, gapR;
00122 
00123   assert( TransLeq( u, v ) && TransLeq( v, w ));
00124 
00125   gapL = v->t - u->t;
00126   gapR = w->t - v->t;
00127 
00128   if( gapL + gapR > 0 ) {
00129     if( gapL < gapR ) {
00130       return (v->s - u->s) + (u->s - w->s) * (gapL / (gapL + gapR));
00131     } else {
00132       return (v->s - w->s) + (w->s - u->s) * (gapR / (gapL + gapR));
00133     }
00134   }
00135   /* vertical line */
00136   return 0;
00137 }
00138 
00139 GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
00140 {
00141   /* Returns a number whose sign matches TransEval(u,v,w) but which
00142    * is cheaper to evaluate.  Returns > 0, == 0 , or < 0
00143    * as v is above, on, or below the edge uw.
00144    */
00145   GLdouble gapL, gapR;
00146 
00147   assert( TransLeq( u, v ) && TransLeq( v, w ));
00148 
00149   gapL = v->t - u->t;
00150   gapR = w->t - v->t;
00151 
00152   if( gapL + gapR > 0 ) {
00153     return (v->s - w->s) * gapL + (v->s - u->s) * gapR;
00154   }
00155   /* vertical line */
00156   return 0;
00157 }
00158 
00159 
00160 int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w )
00161 {
00162   /* For almost-degenerate situations, the results are not reliable.
00163    * Unless the floating-point arithmetic can be performed without
00164    * rounding errors, *any* implementation will give incorrect results
00165    * on some degenerate inputs, so the client must have some way to
00166    * handle this situation.
00167    */
00168   return (u->s*(v->t - w->t) + v->s*(w->t - u->t) + w->s*(u->t - v->t)) >= 0;
00169 }
00170 
00171 /* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b),
00172  * or (x+y)/2 if a==b==0.  It requires that a,b >= 0, and enforces
00173  * this in the rare case that one argument is slightly negative.
00174  * The implementation is extremely stable numerically.
00175  * In particular it guarantees that the result r satisfies
00176  * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate
00177  * even when a and b differ greatly in magnitude.
00178  */
00179 #define RealInterpolate(a,x,b,y)            \
00180   (a = (a < 0) ? 0 : a, b = (b < 0) ? 0 : b,        \
00181   ((a <= b) ? ((b == 0) ? ((x+y) / 2)           \
00182                         : (x + (y-x) * (a/(a+b))))  \
00183             : (y + (x-y) * (b/(a+b)))))
00184 
00185 #ifndef FOR_TRITE_TEST_PROGRAM
00186 #define Interpolate(a,x,b,y)    RealInterpolate(a,x,b,y)
00187 #else
00188 
00189 /* Claim: the ONLY property the sweep algorithm relies on is that
00190  * MIN(x,y) <= r <= MAX(x,y).  This is a nasty way to test that.
00191  */
00192 #include <stdlib.h>
00193 extern int RandomInterpolate;
00194 
00195 GLdouble Interpolate( GLdouble a, GLdouble x, GLdouble b, GLdouble y)
00196 {
00197 printf("*********************%d\n",RandomInterpolate);
00198   if( RandomInterpolate ) {
00199     a = 1.2 * drand48() - 0.1;
00200     a = (a < 0) ? 0 : ((a > 1) ? 1 : a);
00201     b = 1.0 - a;
00202   }
00203   return RealInterpolate(a,x,b,y);
00204 }
00205 
00206 #endif
00207 
00208 #define Swap(a,b)   if (1) { GLUvertex *t = a; a = b; b = t; } else
00209 
00210 void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
00211              GLUvertex *o2, GLUvertex *d2,
00212              GLUvertex *v )
00213 /* Given edges (o1,d1) and (o2,d2), compute their point of intersection.
00214  * The computed point is guaranteed to lie in the intersection of the
00215  * bounding rectangles defined by each edge.
00216  */
00217 {
00218   GLdouble z1, z2;
00219 
00220   /* This is certainly not the most efficient way to find the intersection
00221    * of two line segments, but it is very numerically stable.
00222    *
00223    * Strategy: find the two middle vertices in the VertLeq ordering,
00224    * and interpolate the intersection s-value from these.  Then repeat
00225    * using the TransLeq ordering to find the intersection t-value.
00226    */
00227 
00228   if( ! VertLeq( o1, d1 )) { Swap( o1, d1 ); }
00229   if( ! VertLeq( o2, d2 )) { Swap( o2, d2 ); }
00230   if( ! VertLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
00231 
00232   if( ! VertLeq( o2, d1 )) {
00233     /* Technically, no intersection -- do our best */
00234     v->s = (o2->s + d1->s) / 2;
00235   } else if( VertLeq( d1, d2 )) {
00236     /* Interpolate between o2 and d1 */
00237     z1 = EdgeEval( o1, o2, d1 );
00238     z2 = EdgeEval( o2, d1, d2 );
00239     if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
00240     v->s = Interpolate( z1, o2->s, z2, d1->s );
00241   } else {
00242     /* Interpolate between o2 and d2 */
00243     z1 = EdgeSign( o1, o2, d1 );
00244     z2 = -EdgeSign( o1, d2, d1 );
00245     if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
00246     v->s = Interpolate( z1, o2->s, z2, d2->s );
00247   }
00248 
00249   /* Now repeat the process for t */
00250 
00251   if( ! TransLeq( o1, d1 )) { Swap( o1, d1 ); }
00252   if( ! TransLeq( o2, d2 )) { Swap( o2, d2 ); }
00253   if( ! TransLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
00254 
00255   if( ! TransLeq( o2, d1 )) {
00256     /* Technically, no intersection -- do our best */
00257     v->t = (o2->t + d1->t) / 2;
00258   } else if( TransLeq( d1, d2 )) {
00259     /* Interpolate between o2 and d1 */
00260     z1 = TransEval( o1, o2, d1 );
00261     z2 = TransEval( o2, d1, d2 );
00262     if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
00263     v->t = Interpolate( z1, o2->t, z2, d1->t );
00264   } else {
00265     /* Interpolate between o2 and d2 */
00266     z1 = TransSign( o1, o2, d1 );
00267     z2 = -TransSign( o1, d2, d1 );
00268     if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
00269     v->t = Interpolate( z1, o2->t, z2, d2->t );
00270   }
00271 }

Generated on Fri May 25 2012 04:21:58 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.