fork download
  1. /* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */
  2.  
  3. //請完成兩個運算子覆載,err_detection和find_intersection函式
  4. #include <iostream>
  5. #include <cmath>
  6. using namespace std;
  7. const double TOL = 1.e-13;
  8. //異常處理類別
  9. class Err{
  10. private:
  11. int kind;//可用來判斷異常的種類,如兩點重疊(目前設定的值為1)、沒有交點、兩線重疊
  12. public:
  13. Err(int i) : kind(i){}
  14. //完成運算子覆載功能,透過kind的值將不同種類的異常狀態回傳
  15. friend ostream& operator<<(ostream& out, const Err& foo);
  16. };
  17. //生成點座標的類別
  18. class Point{
  19. private:
  20. double x, y;
  21.  
  22. public:
  23. Point(double a = 0. , double b = 0.) : x(a) , y(b){}
  24. //將交於一點的該點根據題意輸出
  25. friend ostream& operator<<(ostream& out , const Point& pt){
  26. return out << "(" << (abs(pt.x) < TOL ? 0. : pt.x)
  27. << "," << (abs(pt.y) < TOL ? 0. : pt.y)
  28. << ")";
  29. }
  30.  
  31. friend istream& operator>> (istream& in , Point& pt){
  32. return in >> pt.x >> pt.y;
  33. }
  34. //完成運算子覆載功能,透過該函式比較兩點座標是否相等,相等回傳true
  35. friend bool operator==(const Point& a, const Point& b);
  36. friend class Line;
  37. };
  38. //透過兩點(Point物件)構成一線
  39. class Line{
  40. private:
  41. Point pt1, pt2;
  42. double a, b, c;//直線方程式為ax+by=c
  43.  
  44. public:
  45. Line(const Point& m, const Point& n) : pt1(m), pt2(n){
  46. if(m == n){//透過運算子覆載功能比較兩點座標
  47. throw(Err(1));//若無法構成線(兩點重疊)的情況,擲出Err物件
  48. }
  49. if(pt1.x == pt2.x){
  50. a = 1;
  51. b = 0;
  52. c = pt1.x;
  53. }
  54. else{
  55. a = (pt2.y - pt1.y) / (pt2.x - pt1.x);
  56. b = -1;
  57. c = a * pt1.x - pt1.y;
  58. }
  59. }
  60.  
  61. friend Point intersection(const Line& line1 , const Line& line2);
  62.  
  63. //待完成的函式,功能主要是回傳異常的種類("沒有交點"或"兩線重疊"),沒有異常回傳0
  64. friend int err_detection(const Line& line1 , const Line& line2);
  65. //待完成的函式,計算出兩線交於一點的點座標,可透過x,y儲存計算出的xy座標
  66. friend void find_intersection(const Line& line1, const Line& line2, double *x, double *y);
  67. };
  68. //先透過err_detection()判斷line1, line2是否有異常,之後再透過find_intersection()找出交於一點的點座標
  69. Point intersection(const Line& line1, const Line& line2){
  70. double point_x, point_y;//交點的點座標
  71. int errlog = err_detection(line1, line2);//先找出是否有異常
  72. if (errlog != 0) throw(Err(errlog));
  73. else{
  74. find_intersection(line1, line2, &point_x, &point_y);//計算出交於一點的點座標
  75. return Point(point_x, point_y);
  76. }
  77. }
  78.  
  79. int main(){
  80. Point pt1, pt2, pt3, pt4;
  81. while(cin >> pt1 >> pt2 >> pt3 >> pt4){
  82. try{
  83. Line line1(pt1, pt2);
  84. Line line2(pt3, pt4);
  85. cout << intersection(line1, line2) << endl;
  86. }
  87. catch(const Err& err){
  88. cout << err << endl;
  89. }
  90. }
  91. return 0;
  92. }
  93.  
  94. /* PRESET CODE END - NEVER TOUCH CODE ABOVE*/
  95. int err_detection(const Line& line1 , const Line& line2){
  96. double m,n,r;
  97. m=fabs(line1.a/line2.a);
  98. n=fabs(line1.b/line2.b);
  99. r=fabs(line1.c/line2.c);
  100. if(m==n&&n==r){
  101. return 2;
  102. //重和
  103. }
  104. else if(m==n&&n!=r){
  105. return 3;
  106. //沒焦點
  107. }
  108. else{
  109. return 0;
  110. }
  111. }
  112. void find_intersection(const Line& line1, const Line& line2, double *x, double *y){
  113. double det=line1.a*line2.b-line1.b*line2.a;
  114. double ans1;
  115. double ans2;
  116. ans1=(line1.c*line2.b-line1.b*line2.c)/det;
  117. ans2=(line1.a*line2.c-line1.c*line2.a)/det;
  118. x=&ans1;
  119. y=&ans2;
  120. //對應點 line1.a line1.b line1.c line2.a line2.b line2.c
  121. }
  122. ostream& operator<<(ostream& out, const Err& foo){
  123. if (foo.kind == 1) {
  124. return out << "兩點重疊";
  125. }
  126. else if (foo.kind == 2) {
  127. return out << "兩線重疊";
  128. }
  129. else if (foo.kind == 3) {
  130. return out << "沒有交點";
  131. }
  132. }
  133. bool operator==(const Point& a, const Point& b) {
  134. if (a.x==b.x&&a.y==b.y){
  135. return true;
  136. }
  137. else{
  138. return false;
  139. }
  140. }
Success #stdin #stdout 0s 5360KB
stdin
3 1 4 2
2 1 4 1
3 1 4 2
2 0 4 2
3 1 4 2
3 2 4 3
3 1 4 2
3 2 3 2
stdout
(0,0)
兩線重疊
沒有交點
兩點重疊