rectangles.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. class Rect {
  2. constructor(w, h, x1=0, y1=0, alpha=0, text = "", fontSize = 20){
  3. this.w = Math.abs(w);
  4. this.h = Math.abs(h);
  5. this.x1 = x1;
  6. this.y1 = y1;
  7. this.alpha = alpha;
  8. this.alphaRad = this.alpha*Math.PI/180;
  9. this.text = text;
  10. this.fontSize = fontSize;
  11. this.initBoundingBox();
  12. }
  13. getQuadrant(){
  14. if(0<=this.alphaRad<Math.PI/2) return 1;
  15. if(Math.PI/2<=this.alphaRad<Math.PI) return 2;
  16. if(Math.PI<=this.alphaRad<3*Math.PI/2) return 3;
  17. if(3*Math.PI/2<=this.alphaRad<2*Math.PI) return 4;
  18. }
  19. initBoundingBox(){
  20. let cAlpha = Math.cos(this.alphaRad);
  21. let sAlpha = Math.sin(this.alphaRad);
  22. this.xx = [this.x1, this.x1 + this.w*cAlpha, this.x1 + this.w*cAlpha - this.h*sAlpha, this.x1 - this.h*sAlpha];
  23. this.yy = [this.y1, this.y1 + this.w*sAlpha, this.y1 + this.w*sAlpha + this.h*cAlpha, this.y1 + this.h*cAlpha];
  24. this.minX = Math.min(...this.xx);
  25. this.maxX = Math.max(...this.xx);
  26. this.minY = Math.min(...this.yy);
  27. this.maxY = Math.max(...this.yy);
  28. }
  29. printCoords(showRectangles=true, maxFontSize=80, minFontSize=20){
  30. let styleR = ' style="fill:red;stroke:black;stroke-width:2;opacity:0.5"';
  31. let styleG = ' style="fill:green;stroke:black;stroke-width:2;opacity:0.5"';
  32. let styleB = ' style="fill:blue;stroke:black;stroke-width:2;opacity:0.5"';
  33. let style;
  34. let selector = Math.floor(Math.random()*3);
  35. //console.log('sel', selector);
  36. if(selector==0) style=styleR;
  37. if(selector==1) style=styleG;
  38. if(selector==2) style=styleB;
  39. //console.log('st', style);
  40. let toRet = "";
  41. let rectCoordsHtml = ' x="'+this.x1+'" y="'+this.y1+'" width="'+(this.w)+'" height="'+(this.h)+'"';
  42. let rotateHtml = ' transform="rotate('+this.alpha+','+this.x1+','+this.y1+')"'
  43. if(this.text!=""){
  44. let rectsHtml = showRectangles ? '<rect' + rectCoordsHtml + style + '/>' : "";
  45. let textCoordsHtml = ' x="'+this.x1+'" y="'+(this.y1+2/3*this.h)+'"';
  46. toRet = '<g' + rotateHtml + '>' +
  47. rectsHtml +
  48. '<text' + textCoordsHtml + ' font-family="Verdana" fill="RGB('+(2*this.fontSize)+','+(0)+','+(155-2*this.fontSize)+')" font-size="'+this.fontSize+'">' + this.text + '</text>' +
  49. '</g>'
  50. } else{
  51. toRet = '<rect' + rectCoordsHtml + rotateHtml + style + '/>';
  52. }
  53. return toRet;
  54. }
  55. }
  56. function rotate(rect, angle, x0, y0){
  57. let alpha1 = rect.alpha+angle;
  58. let angleRad = angle*Math.PI/180;
  59. let x1Temp = rect.x1-x0;
  60. let y1Temp= rect.y1-y0;
  61. let x11 = Math.cos(angleRad)*x1Temp - Math.sin(angleRad)*y1Temp + x0;
  62. let y11 = Math.sin(angleRad)*x1Temp + Math.cos(angleRad)*y1Temp + y0;
  63. return new Rect(rect.w, rect.h, x11, y11, alpha1, rect.text, rect.fontSize);
  64. }
  65. function rotoTranslate(rect, angle, x0, y0){
  66. let alpha1 = rect.alpha+angle;
  67. let angleRad = angle*Math.PI/180;
  68. let x1Temp = rect.x1-x0;
  69. let y1Temp= rect.y1-y0;
  70. let x11 = Math.cos(angleRad)*x1Temp - Math.sin(angleRad)*y1Temp;
  71. let y11 = Math.sin(angleRad)*x1Temp + Math.cos(angleRad)*y1Temp;
  72. return new Rect(rect.w, rect.h, x11, y11, alpha1);
  73. }
  74. function checkColl(r1, r2){
  75. // 1. Check bounding box collision:
  76. if( r1.minX>r2.maxX || r1.maxX<r2.minX || r1.minY>r2.maxY || r1.maxY<r2.minY ) return false;
  77. let newR1 = rotoTranslate(r1, -r2.alpha, r2.x1, r2.y1);
  78. if( newR1.minX>r2.w || newR1.maxX<0 || newR1.minY>r2.h || newR1.maxY<0 ) return false;
  79. let newR2 = rotoTranslate(r2, -r1.alpha, r1.x1, r1.y1);
  80. if( newR2.minX>r1.w || newR2.maxX<0 || newR2.minY>r1.h || newR2.maxY<0 ) return false;
  81. // A Rectangle has a parametric description through s and t:
  82. // (x1, y1) + t*(cAlpha, sAlpha ) + s*(-sAlpha, cAlphs)
  83. // 0 <= t <= w, 0 <= s <= h.
  84. //
  85. // Start by limiting s through t range check
  86. return true;
  87. }