circumference-model.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
  2. import { GeometricObject } from "../../../core/models/objects/geometric-object";
  3. import { IntersectionModel } from "../../intersection-component/models/intersection-model";
  4. export class CircumferenceModel extends GeometricObject {
  5. constructor(center, radius, id) {
  6. super(id);
  7. this.center = center;
  8. this.radius = radius;
  9. this._coordinates = [];
  10. this._coordinates[0] = this.center.posX;
  11. this._coordinates[1] = this.center.posY;
  12. this._coordinates[2] = this.radius.posX;
  13. this._coordinates[3] = this.radius.posY;
  14. super.setClass(ELEMENTS_CLASS.CIRCUMFERENCE);
  15. }
  16. getRadius() {
  17. this._coordinates[0] = this.center.posX;
  18. this._coordinates[1] = this.center.posY;
  19. this._coordinates[2] = this.radius.posX;
  20. this._coordinates[3] = this.radius.posY;
  21. const legA = this._coordinates[2] - this._coordinates[0];
  22. const legB = this._coordinates[3] - this._coordinates[1];
  23. const radius = Math.sqrt(Math.pow(legA, 2) + Math.pow(legB, 2));
  24. return radius;
  25. }
  26. getStraight() {
  27. const dx = this.radius.posX - this.center.posX;
  28. const dy = this.radius.posY - this.center.posY;
  29. const c = Math.sqrt(dy * dy + dx * dx);
  30. return [dx, dy, c];
  31. }
  32. getDirection() {
  33. const aX = this.center.posX;
  34. const aY = this.center.posY;
  35. const bX = this.radius.posX;
  36. const bY = this.radius.posY;
  37. const a = bX - aX;
  38. const b = bY - aY;
  39. return [a, b];
  40. }
  41. getIntersection(geometricObject) {
  42. switch (geometricObject.elementClass) {
  43. case ELEMENTS_CLASS.LINE_SEGMENT:
  44. return this.getIntersectionByLine(geometricObject);
  45. case ELEMENTS_CLASS.CIRCUMFERENCE:
  46. return this.getIntersectionsByCircumference(geometricObject);
  47. default:
  48. break;
  49. }
  50. }
  51. distance(center) {
  52. const dx = center.posX - this.center.posX;
  53. const dy = center.posY - this.center.posY;
  54. const dist = Math.sqrt(dy * dy + dx * dx);
  55. return dist;
  56. }
  57. getIntersectionsByCircumference(circumference) {
  58. // if (this.cente().igual(cd.C()))
  59. // return null; // duas circ. com mesmo raio => devolva "null" (ambiguidade!)
  60. const r1 = this.getRadius(); // raio circ. atual
  61. const r2 = circumference.getRadius(); // raio circ. "cd"
  62. const d = this.distance(circumference); // distancia entre os raios das circ.
  63. if (r1 + r2 < d || Math.abs(r1 - r2) > d) return null;
  64. const A = this.center; // pega o centro da circunferencia atual
  65. const B = circumference.center; // pega o centro da circunferencia "cd"
  66. const x = B.posX - A.posX;
  67. const y = B.posY - A.posY;
  68. let cos = x / Math.sqrt(x * x + y * y); //(B.posX-A.posX)/Math.sqrt(x*x + y*y); // cos a = <z,w>/(|z||w|)
  69. let sen = Math.sqrt(1 - cos * cos);
  70. if (A.posY > B.posY) sen = -sen;
  71. let u1 = B.posX - A.posX;
  72. let v1 = B.posY - A.posY;
  73. let u = u1 * cos + v1 * sen;
  74. let v = -u1 * sen + v1 * cos;
  75. const rA = this.getRadius();
  76. const rB = circumference.getRadius();
  77. u = (u * u - rB * rB + rA * rA) / (2 * u);
  78. v = Math.sqrt(rA * rA - u * u);
  79. v1 = v;
  80. let v2 = -v;
  81. let x1 = u * cos - v1 * sen;
  82. let y1 = u * sen + v1 * cos;
  83. let x2 = u * cos - v2 * sen;
  84. let y2 = u * sen + v2 * cos;
  85. x1 = A.posX + x1;
  86. y1 = A.posY + y1;
  87. x2 = A.posX + x2;
  88. y2 = A.posY + y2;
  89. return [
  90. new IntersectionModel(x1, y1, undefined, this, circumference, true, 0),
  91. new IntersectionModel(x2, y2, undefined, this, circumference, true, 1)
  92. ];
  93. }
  94. getIntersectionByLine(lineSegment) {
  95. const r = this.getStraight();
  96. const s = lineSegment.getStraight();
  97. const a1 = r[0];
  98. const b1 = r[1];
  99. const c1 = r[2];
  100. const a2 = s[0];
  101. const b2 = s[1];
  102. const c2 = s[2];
  103. const determinant = a1 * b2 - a2 * b1;
  104. if (determinant == 0) {
  105. return [
  106. new IntersectionModel(
  107. Number.MAX_SAFE_INTEGER,
  108. Number.MAX_SAFE_INTEGER,
  109. undefined,
  110. this,
  111. lineSegment
  112. )
  113. ];
  114. } else {
  115. const x = (b2 * c1 - b1 * c2) / determinant;
  116. const y = (a1 * c2 - a2 * c1) / determinant;
  117. return [new IntersectionModel(x, y, undefined, this, lineSegment)];
  118. }
  119. }
  120. insideSegment(intersecX, intersecY) {
  121. const valuesR = this.getDirection();
  122. const dirX = valuesR[0];
  123. const dirY = valuesR[1];
  124. const cInterA = dirX * intersecX + dirY * intersecY;
  125. // comparaca cv do ponto A > cv da intersec => vazio
  126. const cRA = dirX * this.center.posX + dirY * this.center.posY;
  127. if (cInterA < cRA) {
  128. return false;
  129. }
  130. // comparaca cv do ponto B < cv da intersec => vazio
  131. const cRB = dirX * this.radius.posX + dirY * this.radius.posY;
  132. if (cInterA > cRB) {
  133. this.posX = Number.MAX_SAFE_INTEGER;
  134. this.posY = Number.MAX_SAFE_INTEGER;
  135. return false;
  136. }
  137. return true;
  138. }
  139. }