PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ angle_increment_using_max_deviation()

static double angle_increment_using_max_deviation ( double  max_deviation,
double  radius 
)
static

Definition at line 155 of file lwstroke.c.

156 {
157  double increment, halfAngle, maxErr;
158  if ( max_deviation <= 0 )
159  {
160  lwerror("lwarc_linearize: max deviation must be bigger than 0, got %.15g", max_deviation);
161  return -1;
162  }
163 
164  /*
165  * Ref: https://en.wikipedia.org/wiki/Sagitta_(geometry)
166  *
167  * An arc "sagitta" (distance between middle point of arc and
168  * middle point of corresponding chord) is defined as:
169  *
170  * sagitta = radius * ( 1 - cos( angle ) );
171  *
172  * We want our sagitta to be at most "tolerance" long,
173  * and we want to find out angle, so we use the inverse
174  * formula:
175  *
176  * tol = radius * ( 1 - cos( angle ) );
177  * 1 - cos( angle ) = tol/radius
178  * - cos( angle ) = tol/radius - 1
179  * cos( angle ) = - tol/radius + 1
180  * angle = acos( 1 - tol/radius )
181  *
182  * Constraints: 1.0 - tol/radius must be between -1 and 1
183  * which means tol must be between 0 and 2 times
184  * the radius, which makes sense as you cannot have a
185  * sagitta bigger than twice the radius!
186  *
187  */
188  maxErr = max_deviation;
189  if ( maxErr > radius * 2 )
190  {
191  maxErr = radius * 2;
192  LWDEBUGF(2,
193  "lwarc_linearize: tolerance %g is too big, "
194  "using arc-max 2 * radius == %g",
195  max_deviation,
196  maxErr);
197  }
198  do {
199  halfAngle = acos( 1.0 - maxErr / radius );
200  /* TODO: avoid a loop here, going rather straight to
201  * a minimum angle value */
202  if ( halfAngle != 0 ) break;
203  LWDEBUGF(2, "lwarc_linearize: tolerance %g is too small for this arc"
204  " to compute approximation angle, doubling it", maxErr);
205  maxErr *= 2;
206  } while(1);
207  increment = 2 * halfAngle;
208  LWDEBUGF(2,
209  "lwarc_linearize: maxDiff:%g, radius:%g, halfAngle:%g, increment:%g (%g degrees)",
210  max_deviation,
211  radius,
212  halfAngle,
213  increment,
214  increment * 180 / M_PI);
215 
216  return increment;
217 }
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190

References LWDEBUGF, and lwerror().

Referenced by lwarc_linearize().

Here is the call graph for this function:
Here is the caller graph for this function: