PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ angle_increment_using_max_deviation()

static double angle_increment_using_max_deviation ( double  max_deviation,
double  radius 
)
static

Definition at line 143 of file lwstroke.c.

144 {
145  double increment, halfAngle, maxErr;
146  if ( max_deviation <= 0 )
147  {
148  lwerror("lwarc_linearize: max deviation must be bigger than 0, got %.15g", max_deviation);
149  return -1;
150  }
151 
152  /*
153  * Ref: https://en.wikipedia.org/wiki/Sagitta_(geometry)
154  *
155  * An arc "sagitta" (distance between middle point of arc and
156  * middle point of corresponding chord) is defined as:
157  *
158  * sagitta = radius * ( 1 - cos( angle ) );
159  *
160  * We want our sagitta to be at most "tolerance" long,
161  * and we want to find out angle, so we use the inverse
162  * formula:
163  *
164  * tol = radius * ( 1 - cos( angle ) );
165  * 1 - cos( angle ) = tol/radius
166  * - cos( angle ) = tol/radius - 1
167  * cos( angle ) = - tol/radius + 1
168  * angle = acos( 1 - tol/radius )
169  *
170  * Constraints: 1.0 - tol/radius must be between -1 and 1
171  * which means tol must be between 0 and 2 times
172  * the radius, which makes sense as you cannot have a
173  * sagitta bigger than twice the radius!
174  *
175  */
176  maxErr = max_deviation;
177  if ( maxErr > radius * 2 )
178  {
179  maxErr = radius * 2;
180  LWDEBUGF(2,
181  "lwarc_linearize: tolerance %g is too big, "
182  "using arc-max 2 * radius == %g",
183  max_deviation,
184  maxErr);
185  }
186  do {
187  halfAngle = acos( 1.0 - maxErr / radius );
188  /* TODO: avoid a loop here, going rather straight to
189  * a minimum angle value */
190  if ( halfAngle != 0 ) break;
191  LWDEBUGF(2, "lwarc_linearize: tolerance %g is too small for this arc"
192  " to compute approximation angle, doubling it", maxErr);
193  maxErr *= 2;
194  } while(1);
195  increment = 2 * halfAngle;
196  LWDEBUGF(2,
197  "lwarc_linearize: maxDiff:%g, radius:%g, halfAngle:%g, increment:%g (%g degrees)",
198  max_deviation,
199  radius,
200  halfAngle,
201  increment,
202  increment * 180 / M_PI);
203 
204  return increment;
205 }
#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: