nmmtl_circle_segments.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. FACILITY: NMMTL
  3. MODULE DESCRIPTION:
  4. Routines dealing with circle segments.
  5. nmmtl_cirseg_endpoint
  6. nmmtl_cirset_angle_to_normal
  7. nmmtl_cirseg_point_angle
  8. nmmtl_cirseg_angle_point
  9. AUTHOR(S):
  10. Kevin J. Buchs
  11. CREATION DATE: Mon Jan 13 14:48:00 1992
  12. COPYRIGHT: Copyright (C) 1992 by Mayo Foundation. All rights reserved.
  13. */
  14. /*
  15. *******************************************************************
  16. ** INCLUDE FILES
  17. *******************************************************************
  18. */
  19. #include "nmmtl.h"
  20. /*
  21. *******************************************************************
  22. ** STRUCTURE DECLARATIONS AND TYPE DEFINTIONS
  23. *******************************************************************
  24. */
  25. /*
  26. *******************************************************************
  27. ** MACRO DEFINITIONS
  28. *******************************************************************
  29. */
  30. /*
  31. *******************************************************************
  32. ** PREPROCESSOR CONSTANTS
  33. *******************************************************************
  34. */
  35. /*
  36. *******************************************************************
  37. ** GLOBALS
  38. *******************************************************************
  39. */
  40. /*
  41. *******************************************************************
  42. ** FUNCTION DECLARATIONS
  43. *******************************************************************
  44. */
  45. /*
  46. *******************************************************************
  47. ** FUNCTION DEFINITIONS
  48. *******************************************************************
  49. */
  50. /*
  51. FUNCTION NAME: nmmtl_cirseg_endpoint
  52. FUNCTIONAL DESCRIPTION:
  53. Determine if a given point hits either endpoint of the circle segment.
  54. Assume the point is on the circumference, so just find the angle to
  55. the point and see if it matches one of the angles of the circle
  56. segment.
  57. FORMAL PARAMETERS:
  58. CIRCLE_SEGMENTS_P cirseg
  59. POINT_P point
  60. RETURN VALUE:
  61. None
  62. CALLING SEQUENCE:
  63. cirseg_endpoint = nmmtl_cirseg_endpoint(cirseg,intersection1);
  64. */
  65. int nmmtl_cirseg_endpoint(CIRCLE_SEGMENTS_P cirseg,POINT_P point)
  66. {
  67. double theta;
  68. /* yields a theta between pi/2 and -pi/2 */
  69. if(point->x == cirseg->centerx)
  70. {
  71. if(point->y > cirseg->centery) theta = PI/2;
  72. else theta = - PI/2;
  73. }
  74. else
  75. theta = atan((point->y - cirseg->centery)/(point->x - cirseg->centerx));
  76. /* determine if 2nd or 3rd quadrant by sign of point->y - cirseg->centery */
  77. if(point->x - cirseg->centerx < 0) theta += PI;
  78. /* handle the case of exactly PI radians */
  79. if(theta == 0.0F && point->y == cirseg->centery &&
  80. point->x < cirseg->centerx)
  81. theta = PI;
  82. /* fourth quadrant angle gets offset */
  83. if(theta < 0) theta += 2*PI;
  84. /* check angle against endpoints */
  85. if(theta == cirseg->startangle) return(INITIAL_ENDPOINT);
  86. else if(theta == cirseg->endangle) return(TERMINAL_ENDPOINT);
  87. else return(NO_ENDPOINT);
  88. }
  89. /*
  90. FUNCTION NAME: nmmtl_cirset_angle_to_normal
  91. FUNCTIONAL DESCRIPTION:
  92. Compute the angle between a normal vector for given circle segment to
  93. the point given and then turning to an endpoint of the given segment.
  94. FORMAL PARAMETERS:
  95. CIRCLE_SEGMENTS_P cirseg
  96. POINT_P point
  97. LINESEG_P seg
  98. int seg_index
  99. RETURN VALUE:
  100. the angle
  101. CALLING SEQUENCE:
  102. nmmtl_cirseg_angle_to_normal(segment,&intersection1,
  103. &dseg,dseg_index)
  104. */
  105. double nmmtl_cirseg_angle_to_normal(CIRCLE_SEGMENTS_P cirseg,
  106. POINT_P point,
  107. LINESEG_P seg,
  108. int seg_index)
  109. {
  110. double x1,y1,x2,y2;
  111. x1 = point->x - cirseg->centerx;
  112. y1 = point->y - cirseg->centery;
  113. /*
  114. Modified from this :
  115. x2 = seg->x[seg_index] - point->x;
  116. y2 = seg->y[seg_index] - point->y;
  117. To what is below :
  118. to avoid potentially, the point being on an endpoint of the segment. It has
  119. the same effect. We just need to determine which direction the caller wanted
  120. to go. If he wanted to go from point to dseg [0], i.e. seg_index=0, then
  121. we will go from dseg[1] to dseg[0]. Since the line segment is a line, this
  122. will have the correct intended result.
  123. */
  124. if(seg_index == 0)
  125. {
  126. x2 = seg->x[1] - seg->x[0];
  127. y2 = seg->y[1] - seg->y[0];
  128. }
  129. else
  130. {
  131. x2 = seg->x[0] - seg->x[1];
  132. y2 = seg->y[0] - seg->y[1];
  133. }
  134. return(nmmtl_angle_of_intersection(x1,y1,x2,y2));
  135. }
  136. /*
  137. FUNCTION NAME: nmmtl_cirseg_point_angle
  138. FUNCTIONAL DESCRIPTION:
  139. Find the angle to the given point within the circle segment.
  140. FORMAL PARAMETERS:
  141. CIRCLE_SEGMENTS_P cirseg, - pointer to the circle segment
  142. double point_x, - point of interest x coordinate
  143. double point_y - y coordinate
  144. RETURN VALUE:
  145. the angle in double
  146. CALLING SEQUENCE:
  147. angle = nmmtl_cirseg_point_angle(segment,x,y);
  148. */
  149. double nmmtl_cirseg_point_angle(CIRCLE_SEGMENTS_P cirseg,double point_x,
  150. double point_y)
  151. {
  152. double theta;
  153. /* yields a theta between pi/2 and -pi/2 */
  154. if(point_x == cirseg->centerx)
  155. {
  156. if(point_y > cirseg->centery) theta = PI/2;
  157. else theta = - PI/2;
  158. }
  159. else
  160. theta = atan((point_y - cirseg->centery)/(point_x - cirseg->centerx));
  161. /* determine if 2nd or 3rd quadrant by sign of point_y - cirseg->centery */
  162. if(point_x - cirseg->centerx < 0) theta += PI;
  163. /* handle the case of exactly PI radians */
  164. if(theta == 0.0F && point_y == cirseg->centery &&
  165. point_x < cirseg->centerx)
  166. theta = PI;
  167. /* fourth quadrant angle gets offset */
  168. if(theta < 0) theta += 2*PI;
  169. return(theta);
  170. }
  171. /*
  172. FUNCTION NAME: nmmtl_cirseg_angle_point
  173. FUNCTIONAL DESCRIPTION:
  174. Find the x and y coordinates of a point on the circumference at the
  175. given angle.
  176. FORMAL PARAMETERS:
  177. CIRCLE_SEGMENTS_P cirseg - the circle segment
  178. double angle - the angle to place point at
  179. double *point_x,*point_y - returned coordinants
  180. RETURN VALUE:
  181. None
  182. CALLING SEQUENCE:
  183. */
  184. void nmmtl_cirseg_angle_point(CIRCLE_SEGMENTS_P cirseg,double angle,
  185. double *point_x,double *point_y)
  186. {
  187. *point_x = cirseg->radius * cos(angle) + cirseg->centerx;
  188. *point_y = cirseg->radius * sin(angle) + cirseg->centery;
  189. }