Intersection.Mod 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. MODULE Intersection;
  2. IMPORT G := Graph, Random, Int, Out;
  3. CONST eps = 0.001;
  4. TYPE
  5. Point = RECORD
  6. x, y: REAL
  7. END;
  8. Line = RECORD
  9. s, v: Point
  10. END;
  11. VAR W, H: INTEGER;
  12. f: G.Font;
  13. YY: INTEGER;
  14. PROCEDURE Intersect(A, B: Line; VAR t, T: REAL; VAR P: Point): BOOLEAN;
  15. VAR z: REAL;
  16. BEGIN
  17. z := A.v.x * B.v.y - A.v.y * B.v.x;
  18. IF (z < -eps) OR (z > eps) THEN
  19. t := ((B.s.x - A.s.x) * B.v.y - (B.s.y - A.s.y) * B.v.x) / z;
  20. P.x := A.s.x + A.v.x * t;
  21. P.y := A.s.y + A.v.y * t;
  22. IF (B.v.x < -eps) OR (B.v.x > eps) THEN
  23. T := (A.s.x - B.s.x + A.v.x * t) / B.v.x
  24. ELSE
  25. T := (A.s.y - B.s.y + A.v.y * t) / B.v.y
  26. END
  27. END
  28. RETURN (z < -eps) OR (z > eps) END Intersect;
  29. PROCEDURE SpreadLine(VAR A: Line);
  30. VAR B, C: Line;
  31. t1, t2, T: REAL;
  32. P1, P2, E: Point;
  33. c: G.Color;
  34. ZZ: ARRAY 100 OF CHAR;
  35. BEGIN
  36. B.s.x := 10.0;
  37. B.s.y := FLT(H) - 10.0;
  38. C.s.x := 10.0;
  39. C.s.y := 10.0;
  40. B.v.x := FLT(W) - 20.0;
  41. B.v.y := 0.0;
  42. C.v.x := FLT(W) - 20.0;
  43. C.v.y := 0.0;
  44. IF Intersect(A, B, t1, T, P1) & Intersect(A, C, t2, T, P2) THEN
  45. G.MakeCol(c, 0, 255, 0);
  46. G.FillRect(FLOOR(P1.x) - 3, FLOOR(P1.y) - 3, FLOOR(P1.x) + 3, FLOOR(P1.y) + 3, c);
  47. G.MakeCol(c, 255, 0, 0);
  48. G.FillRect(FLOOR(P2.x) - 3, FLOOR(P2.y) - 3, FLOOR(P2.x) + 3, FLOOR(P2.y) + 3, c);
  49. A.s := P1;
  50. A.v.x := P2.x - P1.x;
  51. A.v.y := P2.y - P1.y
  52. END;
  53. B.s.x := 10.0;
  54. B.s.y := 10.0;
  55. C.s.x := FLT(W) - 10.0;
  56. C.s.y := 10.0;
  57. B.v.x := 0.0;
  58. B.v.y := FLT(H) - 20.0;
  59. C.v.x := 0.0;
  60. C.v.y := FLT(H) - 20.0;
  61. IF Intersect(A, B, t1, T, P1) & Intersect(A, C, t2, T, P2) THEN
  62. G.MakeCol(c, 0, 255, 255);
  63. G.FillRect(FLOOR(P1.x) - 3, FLOOR(P1.y) - 3, FLOOR(P1.x) + 3, FLOOR(P1.y) + 3, c);
  64. G.MakeCol(c, 255, 0, 255);
  65. G.FillRect(FLOOR(P2.x) - 3, FLOOR(P2.y) - 3, FLOOR(P2.x) + 3, FLOOR(P2.y) + 3, c);
  66. Int.Str(FLOOR(t1 * 100.0), ZZ);
  67. G.DrawString(ZZ, 20, H - 50 + YY, f, c);
  68. Int.Str(FLOOR(t2 * 100.0), ZZ);
  69. G.DrawString(ZZ, 150, H - 50 + YY, f, c);
  70. INC(YY, 16);
  71. IF (t1 >= 0.0) & (t1 <= 1.0) THEN
  72. IF t1 < t2 THEN
  73. E.x := A.s.x + A.v.x;
  74. E.y := A.s.y + A.v.y;
  75. A.s := P1;
  76. A.v.x := E.x - A.s.x;
  77. A.v.y := E.y - A.s.y
  78. ELSE
  79. A.v.x := P1.x - A.s.x;
  80. A.v.y := P1.y - A.s.y
  81. END
  82. END;
  83. IF (t2 >= 0.0) & (t2 <= 1.0) THEN
  84. IF t1 < t2 THEN
  85. A.v.x := P2.x - A.s.x;
  86. A.v.y := P2.y - A.s.y
  87. ELSE
  88. E.x := A.s.x + A.v.x;
  89. E.y := A.s.y + A.v.y;
  90. A.s := P2;
  91. A.v.x := E.x - A.s.x;
  92. A.v.y := E.y - A.s.y
  93. END
  94. END
  95. END
  96. END SpreadLine;
  97. PROCEDURE Do;
  98. VAR A, B: Line;
  99. c: G.Color;
  100. P: Point;
  101. t, T: REAL;
  102. BEGIN
  103. YY := 0;
  104. G.ClearScreen;
  105. A.s.x := Random.Uniform() * FLT(W);
  106. A.s.y := Random.Uniform() * FLT(H);
  107. B.s.x := Random.Uniform() * FLT(W);
  108. B.s.y := Random.Uniform() * FLT(H);
  109. A.v.x := Random.Uniform() * FLT(W) - A.s.x;
  110. A.v.y := Random.Uniform() * FLT(H) - A.s.y;
  111. B.v.x := Random.Uniform() * FLT(W) - B.s.x;
  112. B.v.y := Random.Uniform() * FLT(H) - B.s.y;
  113. G.MakeCol(c, 155, 0, 0);
  114. G.ThickLine(FLOOR(A.s.x), FLOOR(A.s.y), FLOOR(A.s.x + A.v.x), FLOOR(A.s.y + A.v.y), c, 7);
  115. G.Rect(FLOOR(A.s.x) - 9, FLOOR(A.s.y) - 9, FLOOR(A.s.x) + 9, FLOOR(A.s.y) + 9, c);
  116. G.MakeCol(c, 155, 155, 0);
  117. G.ThickLine(FLOOR(B.s.x), FLOOR(B.s.y), FLOOR(B.s.x + B.v.x), FLOOR(B.s.y + B.v.y), c, 7);
  118. G.Rect(FLOOR(B.s.x) - 9, FLOOR(B.s.y) - 9, FLOOR(B.s.x) + 9, FLOOR(B.s.y) + 9, c);
  119. SpreadLine(A);
  120. SpreadLine(B);
  121. G.MakeCol(c, 255, 0, 0);
  122. G.Line(FLOOR(A.s.x), FLOOR(A.s.y), FLOOR(A.s.x + A.v.x), FLOOR(A.s.y + A.v.y), c);
  123. G.MakeCol(c, 255, 255, 0);
  124. G.Line(FLOOR(B.s.x), FLOOR(B.s.y), FLOOR(B.s.x + B.v.x), FLOOR(B.s.y + B.v.y), c);
  125. IF Intersect(A, B, t, T, P) THEN
  126. G.MakeCol(c, 0, 255, 255);
  127. G.Rect(FLOOR(P.x) - 9, FLOOR(P.y) - 9, FLOOR(P.x) + 9, FLOOR(P.y) + 9, c);
  128. G.MakeCol(c, 255, 255, 255);
  129. G.Rect(FLOOR(P.x) - 7, FLOOR(P.y) - 7, FLOOR(P.x) + 7, FLOOR(P.y) + 7, c)
  130. END;
  131. G.MakeCol(c, 0, 50, 255);
  132. G.Rect(10, 10, W - 10, H - 10, c)
  133. END Do;
  134. PROCEDURE Do2;
  135. VAR ch: CHAR;
  136. BEGIN
  137. G.Init;
  138. f := G.LoadFont('Data/Fonts/Main');
  139. IF f = NIL THEN
  140. Out.String("Could not load font."); Out.Ln
  141. ELSE
  142. G.GetScreenSize(W, H);
  143. REPEAT
  144. Do;
  145. G.Flip;
  146. ch := G.ReadKey();
  147. UNTIL ch = CHR(27);
  148. G.Close
  149. END
  150. END Do2;
  151. BEGIN
  152. Do2
  153. END Intersection.