fork download
  1. #include <cmath>
  2. #include <iomanip>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. struct t {
  7. double x, y;
  8. t() {
  9. x = 0;
  10. y = 0;
  11. }
  12. t(double x, double y) {
  13. this->x = x;
  14. this->y = y;
  15. }
  16. t operator+(t &tt) { return t(this->x + tt.x, this->y + tt.y); }
  17.  
  18. t operator-(t &tt) { return t(this->x - tt.x, this->y - tt.y); }
  19.  
  20. bool operator==(t &p) { return ((x == p.x) && (y == p.y)); }
  21.  
  22. bool operator!=(t &p) { return !(*this == p); }
  23.  
  24. bool t_is_line_segment(t &t1, t &t2) {
  25. t t3 = *this;
  26. t a = t2 - t1;
  27. t b = t3 - t1;
  28. double sa = a.x * b.y - b.x * a.y;
  29. if (sa > 0.0) return false;
  30. if (sa < 0.0) return false;
  31. if ((a.x * b.x < 0.0) || (a.y * b.y < 0.0)) return false;
  32. if (a.length() < b.length()) return false;
  33. if (t1 == t3) return false;
  34. if (t2 == t3) return false;
  35. return true;
  36. }
  37. double distance(const t &p) {
  38. double a = this->x - p.x;
  39. double b = this->y - p.y;
  40. return sqrt(a * a + b * b);
  41. }
  42.  
  43. double length(void) { return sqrt(x * x + y * y); }
  44. };
  45.  
  46. struct line {
  47. double a, b, c;
  48. line(const t &t1, const t &t2) {
  49. a = t1.y - t2.y;
  50. b = t2.x - t1.x;
  51. c = t1.x * t2.y - t2.x * t1.y;
  52. }
  53. };
  54.  
  55. bool intersect(const line &l1, const line &l2, t &res) {
  56. if (l1.a * l2.b == l2.a * l1.b)
  57. return false;
  58. double g = l1.a * l2.b - l2.a * l1.b;
  59. res.x = -(l1.c * l2.b - l2.c * l1.b) / g;
  60. res.y = -(l1.a * l2.c - l2.a * l1.c) / g;
  61. return true;
  62. }
  63.  
  64. int main() {
  65.  
  66. t x0, x1, x2, x3, m; // m точка пересечения
  67.  
  68. double h = 6, answer = 0;
  69.  
  70. cin >> x0.x >> x0.y >> x1.x >> x1.y >> x2.x >> x2.y >> x3.x >> x3.y >> h;
  71. double x0x1_d = x0.distance(x1);
  72. if (((x3.y - x2.y) * (x0.x - x1.x) - (x3.x - x2.x) * (x0.y - x1.y)) == 0) {
  73. if (x0.t_is_line_segment(x2, x3)) {
  74. if (x1.t_is_line_segment(x2, x3)) {
  75. if (x0x1_d <= h) {
  76. answer = M_PI * x0x1_d/2;
  77. } else {
  78. answer = x0x1_d * asin(h / x0x1_d);
  79. }
  80. } else {
  81. if (x2.t_is_line_segment(x1, x3)) {
  82. if (x0x1_d <= h) answer = x0x1_d * asin(x0.distance(x2) / x0x1_d);
  83. else if (x0x1_d * x0x1_d <= h * h + x0.distance(x2) * x0.distance(x2)){
  84. answer = x0x1_d * (asin (h / x0x1_d) - acos(x0.distance(x2) / x0x1_d));
  85. }
  86. } else {
  87. if (x0x1_d <= h) answer = x0x1_d * asin(x0.distance(x3) / x0x1_d);
  88. else if (x0x1_d * x0x1_d <= h * h + x0.distance(x3) * x0.distance(x3)){
  89. answer = x0x1_d * (asin (h / x0x1_d) - acos(x0.distance(x3) / x0x1_d));
  90. }
  91. }
  92.  
  93. }
  94. } else {
  95. double a;
  96. if (x1.t_is_line_segment(x2, x3)) {
  97. a = min(x0.distance(x2), x0.distance(x3));
  98. if (x0x1_d < sqrt(a * a + h * h)) {
  99. answer = x0x1_d * acos(a / x0x1_d);
  100. } else {
  101. answer = x0x1_d * asin(a / x0x1_d);
  102. }
  103. } else {
  104. a = max(x0.distance(x2), x0.distance(x3));
  105. if (x0x1_d < sqrt(a * a + h * h)) {
  106. answer = x0x1_d * (asin(h / x0x1_d) - acos(a / x0x1_d));
  107. }
  108. }
  109. }
  110. } else {
  111. line l10(x0, x1), l23(x2, x3);
  112. if (intersect(l10, l23, m)) {
  113. if (m.t_is_line_segment(x2, x3)) {
  114. double x0m_d = m.distance(x0);
  115. answer = sqrt(x0x1_d * x0x1_d - x0m_d * x0m_d);
  116. if (answer > h) answer = h;
  117. }
  118. }
  119. }
  120. cout << fixed << setprecision(3) << answer << endl;
  121. return 0;
  122. }
Success #stdin #stdout 0s 4532KB
stdin
0 0 6 0 2 0 5 0 5
stdout
2.397