fork(4) download
  1. #ifndef _GEOMETRY_HPP_
  2. #define _GEOMETRY_HPP_
  3.  
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <iostream>
  7. #include <utility>
  8.  
  9. namespace geo
  10. {
  11. #define MEMBER_TYPE double
  12. const MEMBER_TYPE EPS = 1e-10;
  13.  
  14. // 度数法から弧度法へ変換する。
  15. template<typename T>
  16. inline T degToRad(T d)
  17. {
  18. return d * M_PI / 180.0;
  19. }
  20.  
  21. // 弧度法から度数法へ変換する。
  22. template<typename T>
  23. inline T radToDeg(T r)
  24. {
  25. return r * 180.0 / M_PI;
  26. }
  27.  
  28. template<typename T>
  29. class _Vector2D
  30. {
  31. public:
  32. T x, y;
  33.  
  34. inline _Vector2D() {}
  35. inline _Vector2D(T x, T y) : x(x), y(y) {}
  36.  
  37. // ノルムの二乗を返す。
  38. inline T sqnorm()const {
  39. return x*x + y*y;
  40. }
  41. // ノルムを返す。
  42. inline T norm()const {
  43. return std::sqrt(sqnorm());
  44. }
  45. // 偏角を返す。
  46. inline T arg()const {
  47. return std::atan2(y, x);
  48. }
  49. // 同じ方向の単位ベクトルを返す。
  50. inline _Vector2D getNormalized()const {
  51. return *this / norm();
  52. }
  53. // 回転したベクトルを返す。
  54. inline _Vector2D getRotated(T angle)const {
  55. T c = std::cos(angle), s = std::sin(angle);
  56. return _Vector2D(c*x - s*y, s*x + c*y);
  57. }
  58. // 法線ベクトルを返す。
  59. inline _Vector2D getNormal()const {
  60. return _Vector2D(-y, x);
  61. }
  62. // 0ベクトルかどうかを返す。
  63. inline bool isZero()const {
  64. return std::abs(x) < EPS && std::abs(y) < EPS;
  65. }
  66.  
  67. // unary operators
  68. inline _Vector2D operator+ ()const {
  69. return *this;
  70. }
  71. inline _Vector2D operator- ()const {
  72. return _Vector2D(-x, -y);
  73. }
  74.  
  75. // binary operators
  76. inline _Vector2D operator+ (const _Vector2D& v)const {
  77. return _Vector2D(x+v.x, y+v.y);
  78. }
  79. inline _Vector2D operator- (const _Vector2D& v)const {
  80. return _Vector2D(x-v.x, y-v.y);
  81. }
  82. inline _Vector2D operator* (T k)const {
  83. return _Vector2D(x*k, y*k);
  84. }
  85. inline _Vector2D operator/ (T k)const {
  86. return _Vector2D(x/k, y/k);
  87. }
  88. inline _Vector2D& operator+=(const _Vector2D& v) {
  89. x += v.x;
  90. y += v.y;
  91. return *this;
  92. }
  93. inline _Vector2D& operator-=(const _Vector2D& v) {
  94. x -= v.x;
  95. y -= v.y;
  96. return *this;
  97. }
  98. inline _Vector2D& operator*=(T k) {
  99. x *= k;
  100. y *= k;
  101. return *this;
  102. }
  103. inline _Vector2D& operator/=(T k) {
  104. x /= k;
  105. y /= k;
  106. return *this;
  107. }
  108. inline bool operator==(const _Vector2D& v)const {
  109. return (*this-v).sqnorm() < EPS;
  110. }
  111.  
  112. // 直交座標からベクトルを定義する。
  113. inline static _Vector2D fromCoordinates(T x, T y)
  114. {
  115. return _Vector2D(x, y);
  116. }
  117.  
  118. // 長さr, 偏角θのベクトルを定義する。
  119. inline static _Vector2D fromPolarForm(T r, T theta)
  120. {
  121. return _Vector2D(r*std::cos(theta), r*std::sin(theta));
  122. }
  123. };
  124.  
  125. // 内積を返す。
  126. template<typename T>
  127. inline T dot(const _Vector2D<T>& a, const _Vector2D<T>& b)
  128. {
  129. return a.x*b.x + a.y*b.y;
  130. }
  131.  
  132. // 外積を返す。2次元ベクトルの場合はスカラ。
  133. template<typename T>
  134. inline T cross(const _Vector2D<T>& a, const _Vector2D<T>& b)
  135. {
  136. return a.x*b.y - a.y*b.x;
  137. }
  138.  
  139. // 二つのベクトルが成す角(a->b)のsinを返す。
  140. template<typename T>
  141. inline T sin(const _Vector2D<T>& a, const _Vector2D<T>& b)
  142. {
  143. return cross(a, b) / sqrt(a.sqnorm() * b.sqnorm());
  144. }
  145.  
  146. // 二つのベクトルが成す角(a->b)のcosを返す。
  147. template<typename T>
  148. inline T cos(const _Vector2D<T>& a, const _Vector2D<T>& b)
  149. {
  150. return dot(a, b) / sqrt(a.sqnorm() * b.sqnorm());
  151. }
  152.  
  153. // 二つのベクトルが成す角(a->b)のtanを返す。
  154. template<typename T>
  155. inline T tan(const _Vector2D<T>& a, const _Vector2D<T>& b)
  156. {
  157. return cross(a, b) / dot(a, b);
  158. }
  159.  
  160. // 二つのベクトルが成す角(a->b)を(-π, π]の範囲で返す。
  161. template<typename T>
  162. inline T arg(const _Vector2D<T>& a, const _Vector2D<T>& b)
  163. {
  164. return std::acos(cos(a, b)) * (cross(a, b) < 0.0 ? -1.0 : 1.0);
  165. }
  166.  
  167. // scalar * vector
  168. template<typename T>
  169. inline _Vector2D<T> operator* (MEMBER_TYPE k, const _Vector2D<T>& v)
  170. {
  171. return _Vector2D<T>(k*v.x, k*v.y);
  172. }
  173.  
  174. // output
  175. template<typename T>
  176. inline std::ostream& operator<<(std::ostream& out, const _Vector2D<T>& v)
  177. {
  178. return out << '(' << v.x << ", " << v.y << ')';
  179. }
  180.  
  181. template<typename T>
  182. class _Line2D
  183. {
  184. public:
  185. _Vector2D<T> p; // p : 直線上の一点の位置ベクトル
  186. _Vector2D<T> d; // d : 直線の方向ベクトル
  187.  
  188. inline _Line2D() {}
  189. inline _Line2D(const _Vector2D<T>& p, const _Vector2D<T>& d) : p(p), d(d) {}
  190.  
  191. // 指定されたy座標に対応する直線上のx座標を返す。
  192. inline T getX(T y)const {
  193. return p.x + (y - p.y)*d.x / d.y;
  194. }
  195.  
  196. // 指定されたx座標に対応する直線上のy座標を返す。
  197. inline T getY(T x)const {
  198. return p.y + (x - p.x)*d.y / d.x;
  199. }
  200.  
  201. // 直線がx軸と成す角を(-π/2, π/2]の範囲で返す。
  202. inline T getAngle()const {
  203. T angle = d.arg();
  204. return angle + (angle > M_PI_2 ? -M_PI : (angle > -M_PI_2 ? 0.0 : M_PI));
  205. }
  206.  
  207. // 直線の傾きを返す。
  208. inline T getSlope()const {
  209. return d.y / d.x;
  210. }
  211.  
  212. // 直線の方程式 ax+by+c=0 の係数a, b, cをそれぞれ引数に代入する。
  213. inline void getLineEquation(T& a, T& b, T& c)const {
  214. a = d.y;
  215. b = -d.x;
  216. c = cross(d, p);
  217. }
  218.  
  219. inline bool operator==(const _Line2D L)const {
  220. return std::abs(cross(d, L.d)) < EPS && std::abs(cross(p-L.p, d)) < EPS;
  221. }
  222.  
  223. // 点pを通り、dに平行な直線を定義する。
  224. inline static _Line2D fromPointAndDirection(const _Vector2D<T>& p, const _Vector2D<T>& d)
  225. {
  226. return _Line2D(p, d);
  227. }
  228.  
  229. // 2点pとqを通る直線を定義する。
  230. inline static _Line2D fromTwoPoints(const _Vector2D<T>& p, const _Vector2D<T>& q)
  231. {
  232. return _Line2D(p, q-p);
  233. }
  234.  
  235. // pを通り、x軸と成す角度がθの直線を定義する。
  236. inline static _Line2D fromPointAndAngle(const _Vector2D<T>& p, T theta)
  237. {
  238. return _Line2D(p, _Vector2D<T>::fromPolarForm(1.0, theta));
  239. }
  240.  
  241. // pを通り、傾きがaの直線を定義する。
  242. inline static _Line2D fromPointAndSlope(const _Vector2D<T>& p, T a)
  243. {
  244. return _Line2D(p, _Vector2D<T>(1.0, a));
  245. }
  246.  
  247. // 直線 y=ax+b を定義する。
  248. inline static _Line2D fromSlopeAndIntercept(T a, T b)
  249. {
  250. return fromPointAndSlope(_Vector2D<T>(0.0, b), a);
  251. }
  252.  
  253. // 直線 ax+by+c=0 を定義する。
  254. inline static _Line2D fromLineEquation(T a, T b, T c)
  255. {
  256. if(std::abs(a) > std::abs(b))
  257. return _Line2D(_Vector2D<T>(-c/a, 0.0), _Vector2D<T>(-b, a));
  258. else
  259. return _Line2D(_Vector2D<T>(0.0, -c/b), _Vector2D<T>(b, -a));
  260. }
  261. };
  262.  
  263. template<typename T>
  264. class _Ellipse2D
  265. {
  266. public:
  267. _Vector2D<T> center; // 中心座標
  268. T A, B; // A : 軸A方向の半長, B : 軸B方向の半長
  269. T angle; // 軸Aとx軸の成す角
  270.  
  271. inline _Ellipse2D() {}
  272. inline _Ellipse2D(const _Vector2D<T>& center, T A, T B, T angle) : center(center), A(A), B(B), angle(angle) {}
  273.  
  274. // 長軸の半長を返す。
  275. inline T getHalfMajorLength()const {
  276. return std::max(A, B);
  277. }
  278.  
  279. // 長軸の全長を返す。
  280. inline T getMajorLength()const {
  281. return getHalfMajorLength() * 2.0;
  282. }
  283.  
  284. // 短軸の半長を返す。
  285. inline T getHalfMinorLength()const {
  286. return std::min(A, B);
  287. }
  288.  
  289. // 短軸の全長を返す。
  290. inline T getMinorLength()const {
  291. return getHalfMinorLength() * 2.0;
  292. }
  293.  
  294. // 長軸の両端の座標を返す。
  295. inline std::pair<_Vector2D<T>, _Vector2D<T> > getMajorEnds()const {
  296. _Vector2D<T> tmp;
  297. if(A < B)
  298. tmp = B * _Vector2D<T>(-std::sin(angle), std::cos(angle));
  299. else
  300. tmp = A * _Vector2D<T>(std::cos(angle), std::sin(angle));
  301. return std::make_pair(center + tmp, center - tmp);
  302. }
  303.  
  304. // 短軸の両端の座標を返す。
  305. inline std::pair<_Vector2D<T>, _Vector2D<T> > getMinorEnds()const {
  306. _Vector2D<T> tmp;
  307. if(A < B)
  308. tmp = A * _Vector2D<T>(std::cos(angle), std::sin(angle));
  309. else
  310. tmp = B * _Vector2D<T>(-std::sin(angle), std::cos(angle));
  311. return std::make_pair(center + tmp, center - tmp);
  312. }
  313.  
  314. // 長軸とx軸が成す角を返す。
  315. inline T getMajorArgument()const {
  316. if(A < B)
  317. return angle + (angle < 0.0 ? M_PI_2 : -M_PI_2);
  318. else
  319. return angle;
  320. }
  321.  
  322. // 短軸とx軸が成す角を返す。
  323. inline T getMinorArgument()const {
  324. if(A < B)
  325. return angle;
  326. else
  327. return angle + (angle < 0.0 ? M_PI_2 : -M_PI_2);
  328. }
  329.  
  330. // 長軸の直線を返す。
  331. inline _Line2D<T> getMajorLine()const {
  332. T arg = getMajorArgument();
  333. return _Line2D<T>(center, _Vector2D<T>(std::cos(arg), std::sin(arg)));
  334. }
  335.  
  336. // 短軸の直線を返す。
  337. inline _Line2D<T> getMinorLine()const {
  338. T arg = getMinorArgument();
  339. return _Line2D<T>(center, _Vector2D<T>(std::cos(arg), std::sin(arg)));
  340. }
  341.  
  342. // 楕円が円かどうかを返す。
  343. inline bool isCircle()const {
  344. return abs(A-B) < EPS;
  345. }
  346.  
  347. // 面積を返す。
  348. inline T getArea()const {
  349. return M_PI * A * B;
  350. }
  351.  
  352. // 楕円弧上で最もx座標が小さい点を返す。
  353. inline _Vector2D<T> getLeft()const {
  354. T cos = std::cos(angle);
  355. T sin = std::sin(angle);
  356. T x = -_Vector2D<T>(A*cos, B*sin).norm();
  357. return _Vector2D<T>(x+center.x, (A*A-B*B)*sin*cos/x + center.y);
  358. }
  359.  
  360. // 楕円弧上で最もx座標が大きい点を返す。
  361. inline _Vector2D<T> getRight()const {
  362. T cos = std::cos(angle);
  363. T sin = std::sin(angle);
  364. T x = _Vector2D<T>(A*cos, B*sin).norm();
  365. return _Vector2D<T>(x+center.x, (A*A-B*B)*sin*cos/x + center.y);
  366. }
  367.  
  368. // 楕円弧上で最もy座標が小さい点を返す。
  369. inline _Vector2D<T> getTop()const {
  370. T cos = std::cos(angle);
  371. T sin = std::sin(angle);
  372. T y = -_Vector2D<T>(A*sin, B*cos).norm();
  373. return _Vector2D<T>((A*A-B*B)*sin*cos/y + center.x, y+center.y);
  374. }
  375.  
  376. // 楕円弧上で最もy座標が大きい点を返す。
  377. inline _Vector2D<T> getBottom()const {
  378. T cos = std::cos(angle);
  379. T sin = std::sin(angle);
  380. T y = _Vector2D<T>(A*sin, B*cos).norm();
  381. return _Vector2D<T>((A*A-B*B)*sin*cos/y + center.x, y+center.y);
  382. }
  383.  
  384. // 指定されたy座標に対応する直線上のx座標を引数にそれぞれ代入する(x1≦x2)。
  385. // 戻り値は対応点の個数(0~2)。
  386. inline int getX(T y, T& x1, T& x2)const {
  387. T a, b, c, d, e, f;
  388. getEquation(a, b, c, d, e, f);
  389. b = b*y + d;
  390. c = c*y*y + e*y + f;
  391.  
  392. T D = b*b - 4.0*a*c;
  393. if(std::abs(D) < EPS){
  394. x1 = x2 = -b / (2.0*a);
  395. return 1;
  396. }
  397. else if(D > 0.0){
  398. D = std::sqrt(D);
  399. x1 = (-b-D)/(2.0*a);
  400. x2 = (-b+D)/(2.0*a);
  401. return 2;
  402. }
  403. else
  404. return 0;
  405. }
  406.  
  407. // 楕円の方程式 ax^2+bxy+cy^2+dx+ey+f=0 の各係数をそれぞれ引数に代入する。
  408. inline void getEquation(T& a, T& b, T& c, T& d, T& e, T& f)const {
  409. T cos = std::cos(angle);
  410. T sin = std::sin(angle);
  411. T a2 = 1.0 / (A * A);
  412. T b2 = 1.0 / (B * B);
  413.  
  414. a = cos*cos*a2 + sin*sin*b2;
  415. b = 2.0*(a2-b2)*sin*cos;
  416. c = sin*sin*a2 + cos*cos*b2;
  417. d = -2.0*center.x*a - center.y*b;
  418. e = -2.0*center.y*c - center.x*b;
  419. T tmp1 = center.x*cos + center.y*sin;
  420. T tmp2 = -center.x*sin + center.y*cos;
  421. f = tmp1*tmp1*a2 + tmp2*tmp2*b2 - 1.0;
  422. }
  423.  
  424. inline bool operator==(const _Ellipse2D& ell)const {
  425. return center == ell.center
  426. && std::abs(getMajorLength() - ell.getMajorLength()) < EPS
  427. && std::abs(getMinorLength() - ell.getMinorLength()) < EPS
  428. && (std::abs(A-B) < EPS || std::abs(getMajorArgument() - ell.getMajorArgument()));
  429. }
  430.  
  431. // 楕円の中心と軸の半長と角度から楕円を定義する。
  432. inline static _Ellipse2D fromCenterAndLengthesAndAngle(const _Vector2D<T>& center, T A, T B, T angle)
  433. {
  434. return _Ellipse2D(center, A, B, angle);
  435. }
  436.  
  437. // (v.x, v.y), (v.x+w, v.y), (v.x, v.y+h), (v.x+w, v.y+h)を頂点とする長方形に内接する楕円を定義する。
  438. inline static _Ellipse2D fromRectangle(const _Vector2D<T>& v, T w, T h)
  439. {
  440. w *= 0.5;
  441. h *= 0.5;
  442. return _Ellipse2D(_Vector2D<T>(v.x + w, v.y + h), w, h, 0.0);
  443. }
  444.  
  445. // 二次曲線 ax^2+bxy+cy^2+dx+ey+f=0 が楕円の方程式かどうかを判別する。
  446. inline static bool isEllipseEquation(T a, T b, T c, T d, T e, T f)
  447. {
  448. T D = 4.0*a*c - b*b;
  449. return D > 0.0 && a*((d*(b*e-2.0*c*d)+e*(b*d-2.0*a*e))/D + 2.0*f) < 0.0;
  450. }
  451.  
  452. // 楕円の方程式 ax^2+bxy+cy^2+dx+ey+f=0 から楕円を定義する。
  453. inline static _Ellipse2D fromEquation(T a, T b, T c, T d, T e, T f)
  454. {
  455. _Ellipse2D ell;
  456. ell.center = _Vector2D<T>(b*e-2.0*c*d, b*d-2.0*a*e) / (4.0*a*c - b*b);
  457. T sum = a + c;
  458. T diff = a - c;
  459. T sq = std::sqrt(diff*diff + b*b);
  460. T beta = -d*ell.center.x - e*ell.center.y - 2.0*f;
  461. ell.A = std::sqrt(beta/(sum+sq));
  462. ell.B = std::sqrt(beta/(sum-sq));
  463. ell.angle = a>c ? std::atan2(b, diff+sq) : std::atan2(-diff+sq, b);
  464. return ell;
  465. }
  466. };
  467.  
  468. template<typename T>
  469. class _Circle2D
  470. {
  471. public:
  472. _Vector2D<T> center; // 中心座標
  473. T radius; // 半径
  474.  
  475. inline _Circle2D() {}
  476. inline _Circle2D(const _Vector2D<T>& center, T radius) : center(center), radius(radius) {}
  477.  
  478. // 円の方程式 x^2+ax+y^2+by+c=0 の各係数a, b, cをそれぞれ引数に代入する。
  479. inline void getCircleEquation(T& a, T& b, T& c)const {
  480. a = -2.0 * center.x;
  481. b = -2.0 * center.y;
  482. c = center.sqnorm() - radius*radius;
  483. }
  484.  
  485. // 面積を返す。
  486. inline T getArea()const {
  487. return M_PI * radius * radius;
  488. }
  489.  
  490. inline bool operator==(const _Circle2D& C)const {
  491. return center == C.center && std::abs(radius - C.radius) < EPS;
  492. }
  493.  
  494. // 楕円への変換
  495. inline operator _Ellipse2D<T>() const{
  496. return _Ellipse2D<T>::fromCenterAndLengthesAndAngle(center, radius, radius, 0.0);
  497. }
  498.  
  499. // 中心座標と半径から円を定義する。
  500. inline static _Circle2D fromCenterAndRadius(const _Vector2D<T>& c, T r)
  501. {
  502. return _Circle2D(c, r);
  503. }
  504.  
  505. // 中心座標と円周上の一点から円を定義する。
  506. inline static _Circle2D fromCenterAndPoint(const _Vector2D<T>& c, const _Vector2D<T>& p)
  507. {
  508. return _Circle2D(c, (c-p).norm());
  509. }
  510.  
  511. // 指定された二点を直径の両端とする円を定義する。
  512. inline static _Circle2D fromDiaEnds(const _Vector2D<T>& a, const _Vector2D<T>& b)
  513. {
  514. return _Circle2D((a+b)*0.5, (a-b).norm()*0.5);
  515. }
  516.  
  517. // 円周上の三点から円を定義する。
  518. inline static _Circle2D fromThreePoints(const _Vector2D<T>& a, const _Vector2D<T>& b, const _Vector2D<T>& c)
  519. {
  520. _Vector2D<T> A(2.0*(b.x-a.x), 2.0*(c.x-a.x));
  521. _Vector2D<T> B(2.0*(b.y-a.y), 2.0*(c.y-a.y));
  522. T asq = a.sqnorm();
  523. _Vector2D<T> C(asq-b.sqnorm(), asq-c.sqnorm());
  524. _Vector2D<T> center = Vector2D(cross(B, C), cross(C, A)) / cross(A, B);
  525. return _Circle2D(center, (center-a).norm());
  526. }
  527.  
  528. // (v.x, v.y), (v.x+a, v.y), (v.x, v.y+a), (v.x+a, v.y+a)を頂点とする正方形に内接する円を定義する。
  529. inline static _Circle2D fromSquare(const _Vector2D<T>& v, T a)
  530. {
  531. a *= 0.5;
  532. return _Circle2D(_Vector2D<T>(v.x+a, v.y+a), std::abs(a));
  533. }
  534.  
  535. // 円 x^2+ax+y^2+by+c=0 を定義する。
  536. inline static _Circle2D fromCircleEquation(T a, T b, T c)
  537. {
  538. _Vector2D<T> center(-a*0.5, -b*0.5);
  539. return _Circle2D(center, sqrt(center.sqnorm() - c));
  540. }
  541. };
  542.  
  543. // 点Pと直線Lの距離を返す。
  544. template<typename T>
  545. inline T getDistance(const _Vector2D<T>& P, const _Line2D<T>& L)
  546. {
  547. T a, b, c;
  548. L.getLinearEquation(a, b, c);
  549. return std::abs(a*P.x + b*P.y + c)/std::sqrt(a*a + b*b);
  550. }
  551.  
  552. // 直線Lと直線Mの交点をinterに代入する。
  553. // 戻り値は交点の個数(0~1)。aとbが重なっている時は-1。
  554. template<typename T>
  555. int getIntersection(const _Line2D<T>& L, const _Line2D<T>& M, _Vector2D<T>& inter)
  556. {
  557. T denominator = cross(L.d, M.d);
  558. T numerator = cross(M.p-L.p, M.d);
  559. if(std::abs(denominator) < EPS){
  560. return std::abs(numerator) < EPS ? -1 : 0;
  561. }
  562. else{
  563. inter = L.p + numerator/denominator * L.d;
  564. return 1;
  565. }
  566. }
  567.  
  568. // 直線Lと円Cの交点をinter1, inter2に代入する。
  569. // 戻り値は交点の個数(0~2)。
  570. template<typename T>
  571. int getIntersection(const _Line2D<T>& L, const _Circle2D<T>& C, _Vector2D<T>& inter1, _Vector2D<T>& inter2)
  572. {
  573. _Vector2D<T> diff = L.p - C.center;
  574. T a = L.d.sqnorm();
  575. T b = dot(L.d, diff);
  576. T c = diff.sqnorm() - C.radius * C.radius;
  577. T D = b*b - a*c;
  578. if(std::abs(D) < EPS){
  579. inter1 = inter2 = L.p - b/a * L.d;
  580. return 1;
  581. }
  582. else if(D > 0.0){
  583. D = std::sqrt(D);
  584. inter1 = L.p + (-b+D)/a * L.d;
  585. inter2 = L.p - (b+D)/a * L.d;
  586. return 2;
  587. }
  588. else{
  589. return 0;
  590. }
  591. }
  592.  
  593. typedef _Vector2D<MEMBER_TYPE> Vector2D;
  594. typedef _Line2D<MEMBER_TYPE> Line2D;
  595. typedef _Circle2D<MEMBER_TYPE> Circle2D;
  596. typedef _Ellipse2D<MEMBER_TYPE> Ellipse2D;
  597.  
  598. #ifdef __OPENCV_CORE_C_H__
  599. namespace opencv
  600. {
  601. template<typename T>
  602. inline CvPoint vecToCP(T x, T y) {
  603. return cvPoint(static_cast<int>(x + 0.5), static_cast<int>(y + 0.5));
  604. }
  605.  
  606. template<typename T>
  607. inline CvPoint vecToCP(const _Vector2D<T>& v) {
  608. return vecToCP(v.x, v.y);
  609. }
  610.  
  611. // 点を描く。
  612. template<typename T>
  613. inline void drawPoint(CvArr* img, const _Vector2D<T>& point, CvScalar color, int radius=3, int thickness=-1, int lineType=CV_AA, int shift=0)
  614. {
  615. cvCircle(img, vecToCP(point), radius, color, thickness, lineType, shift);
  616. }
  617.  
  618. // 直線を描く。
  619. template<typename T>
  620. void drawLine(IplImage* img, const _Line2D<T>& line, CvScalar color, int thickness=1, int line_type=8, int shift=0)
  621. {
  622. double h = img->height + 1.0, w = img->width + 1.0;
  623.  
  624. CvPoint p1, p2;
  625. if(std::abs(line.d.x) < std::abs(line.d.y)){
  626. p1 = vecToCP(line.getX(-1.0), -1.0);
  627. p2 = vecToCP(line.getX(h), h);
  628. }
  629. else{
  630. p1 = vecToCP(-1.0, line.getY(-1.0));
  631. p2 = vecToCP(w, line.getY(w));
  632. }
  633. cvLine(img, p1, p2, color, thickness, line_type, shift);
  634. }
  635.  
  636. // 円を描く。
  637. template<typename T>
  638. inline void drawCircle(CvArr* img, const _Circle2D<T>& circle, CvScalar color, int thickness=1, int lineType=8, int shift=0)
  639. {
  640. cvCircle(img, vecToCP(circle.center), static_cast<int>(circle.radius + 0.5), color, thickness, lineType, shift);
  641. }
  642.  
  643. // 楕円を描く。
  644. template<typename T>
  645. inline void drawEllipse(CvArr* img, const _Ellipse2D<T>& ellipse, CvScalar color, int thickness=1, int lineType=8, int shift=0)
  646. {
  647. cvEllipse(
  648. img,
  649. vecToCP(ellipse.center),
  650. cvSize(static_cast<int>(ellipse.A + 0.5), static_cast<int>(ellipse.B + 0.5)),
  651. radToDeg(ellipse.angle), 0.0, 360.0,
  652. color, thickness, lineType, shift
  653. );
  654. }
  655. }
  656. #endif
  657. }
  658.  
  659. #endif
  660.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty