PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.

References LWDEBUGF, and lwerror().

Referenced by lwarc_linearize().

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