PostGIS  2.2.7dev-r@@SVN_REVISION@@
double lw_arc_length ( const POINT2D A1,
const POINT2D A2,
const POINT2D A3 
)

Returns the length of a circular arc segment.

Definition at line 104 of file lwalgorithm.c.

References lw_arc_center(), lw_arc_is_pt(), LW_FALSE, lw_segment_side(), LW_TRUE, p2d_same(), POINT2D::x, and POINT2D::y.

105 {
106  POINT2D C;
107  double radius_A, circumference_A;
108  int a2_side, clockwise;
109  double a1, a3;
110  double angle;
111 
112  if ( lw_arc_is_pt(A1, A2, A3) )
113  return 0.0;
114 
115  radius_A = lw_arc_center(A1, A2, A3, &C);
116 
117  /* Co-linear! Return linear distance! */
118  if ( radius_A < 0 )
119  {
120  double dx = A1->x - A3->x;
121  double dy = A1->y - A3->y;
122  return sqrt(dx*dx + dy*dy);
123  }
124 
125  /* Closed circle! Return the circumference! */
126  circumference_A = M_PI * 2 * radius_A;
127  if ( p2d_same(A1, A3) )
128  return circumference_A;
129 
130  /* Determine the orientation of the arc */
131  a2_side = lw_segment_side(A1, A3, A2);
132 
133  /* The side of the A1/A3 line that A2 falls on dictates the sweep
134  direction from A1 to A3. */
135  if ( a2_side == -1 )
136  clockwise = LW_TRUE;
137  else
138  clockwise = LW_FALSE;
139 
140  /* Angles of each point that defines the arc section */
141  a1 = atan2(A1->y - C.y, A1->x - C.x);
142  a3 = atan2(A3->y - C.y, A3->x - C.x);
143 
144  /* What's the sweep from A1 to A3? */
145  if ( clockwise )
146  {
147  if ( a1 > a3 )
148  angle = a1 - a3;
149  else
150  angle = 2*M_PI + a1 - a3;
151  }
152  else
153  {
154  if ( a3 > a1 )
155  angle = a3 - a1;
156  else
157  angle = 2*M_PI + a3 - a1;
158  }
159 
160  /* Length as proportion of circumference */
161  return circumference_A * (angle / (2*M_PI));
162 }
int lw_arc_is_pt(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3)
Returns true if arc A is actually a point (all vertices are the same) .
Definition: lwalgorithm.c:91
double x
Definition: liblwgeom.h:312
#define LW_FALSE
Definition: liblwgeom.h:62
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:61
double y
Definition: liblwgeom.h:312
double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *result)
Determines the center of the circle defined by the three given points.
Definition: lwalgorithm.c:213
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:35
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition: lwalgorithm.c:50

Here is the call graph for this function: