rectangles.js 4.4 KB

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