PostGIS 3.0.6dev-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 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: