簡體   English   中英

jQuery計算旋轉矩形的綁定框

[英]Jquery calculating bouding box of a rotated rectangle

我已經看過其他相關文章,但仍無法弄清楚該公式為何不起作用。

要計算旋轉矩形的邊界框:

w' = sin(a)*h + cos(a)*w;
h' = sin(a)*w + cos(a)*h;

問題是我得到了奇怪的行為,其中w'h'根本不精確。

 // calculate rotation angle of shape function getRotationDegrees(obj) { var matrix = obj.css("-webkit-transform") || obj.css("-moz-transform") || obj.css("-ms-transform") || obj.css("-o-transform") || obj.css("transform"); if (matrix !== 'none') { var values = matrix.split('(')[1].split(')')[0].split(','); var a = values[0]; var b = values[1]; var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI)); } else { var angle = 0; } if (angle < 0) angle += 360; return angle; } var shape = $('.shape'), shapeLeft = shape.position().left, shapeTop = shape.position().top, shapeWidth = shape.width(), shapeHeight = shape.height(), angle = getRotationDegrees(shape), // formula below height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle)), width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle)); $('#g1').css('width', width); $('#g2').css('height', height); 
 .elements, .element { position: absolute } #s2 { background: #333333; top: 60px; left: -25px; width: 300px; height: 100px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="layout" style="position:relative; margin-top:50px; margin-left:70px;"> <div class="elements"> <div id="g1" class="element" style="background:red;left:-35px;top:-10px;height:2px;"></div> <div id="g2" class="element" style="background:red;left:-35px;top:-10px;width:2px;"></div> <div id="s2" class="element shape" style="transform: rotate(8deg);"></div> </div> </div> 

我究竟做錯了什么 ?

兩種錯誤來源:

  1. (小)圓角。 (不知道您的意思是“已經有一個整數”)

  2. (主要)您可以直接在Math.cos / sin使用getRotationDegrees的結果。 這些函數需要弧度 ,即Math.atan2直接返回的結果。


下面的代碼段添加了邊界框的其他兩個邊緣以及正確的位置偏移。 我添加了一個滑塊來更改旋轉角度,以說明此代碼是可靠的。

 function getMatrix(obj) { var matrix = obj.css("-webkit-transform") || obj.css("-moz-transform") || obj.css("-ms-transform") || obj.css("-o-transform") || obj.css("transform"); return (matrix == 'none') ? null : matrix.split('(')[1].split(')')[0].split(','); } // calculate rotation angle of shape function getRotationRadians(matrix) { var angle = matrix ? Math.atan2(matrix[1], matrix[0]) : 0; if (angle < 0) angle += 2.0 * Math.PI; return angle; } // calculate translation function getTranslation(matrix) { return matrix ? [matrix[4], matrix[5]] : [0, 0]; } // calculate bounding box function getBoundingBox(shape) { var shapeLeft = shape.position().left, shapeTop = shape.position().top, shapeWidth = shape.width(), shapeHeight = shape.height(); var matrix = getMatrix(shape); var angle = getRotationRadians(matrix); var height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle)); var width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle)); var trans = getTranslation(matrix); var left = trans[0] - (width * 0.5); var top = trans[1] - (height * 0.5); return {'x': left, 'y': top, 'w': width, 'h': height}; } formatBox($('.shape')); function formatBox(shape) { var box = getBoundingBox(shape); var offx = 124, offy = 109; var g1 = $('#g1'), g2 = $('#g2'), g3 = $('#g3'), g4 = $('#g4'); g1.css('width', box.w); g2.css('height', box.h); g3.css('width', box.w); g4.css('height', box.h); g1.css('left', offx + box.x); g2.css('left', offx + box.x); g3.css('left', offx + box.x); g4.css('left', offx + box.x + box.w); g1.css('top', offy + box.y); g2.css('top', offy + box.y); g3.css('top', offy + box.y + box.h); g4.css('top', offy + box.y); } var angleInp = document.getElementById("angleInp"); angleInp.addEventListener("change", function() { var shape = $('.shape'); shape.css('transform', 'rotate(' + angleInp.value + 'deg)'); formatBox(shape); }, false); 
 .elements, .element { position: absolute } #s2 { background: #333333; top: 60px; left: -25px; width: 300px; height: 100px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="slider"> <input class="bar" type="range" id="angleInp" min="0" max="360" value="15" onchange="angleInp.value=value"/> </div> <div class="layout" style="position:relative; margin-top:50px; margin-left:70px;"> <div class="elements"> <div id="g1" class="element" style="background:red;left:0px;top:0px;height:2px;"></div> <div id="g2" class="element" style="background:red;left:0px;top:0px;width:2px;"></div> <div id="g3" class="element" style="background:red;left:0px;top:0px;height:2px;"></div> <div id="g4" class="element" style="background:red;left:0px;top:0px;width:2px;"></div> <div id="s2" class="element shape" style="transform: rotate(15deg);"></div> </div> </div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM