【问题标题】:Scaling a rotated rectangle and find the new control points and centre缩放旋转的矩形并找到新的控制点和中心
【发布时间】:2017-06-27 07:07:24
【问题描述】:

我要分享的代码笔链接中的这段代码有点复杂和密集,所以我实际上不是要代码而是要建议。

https://codepen.io/anon/pen/LLEedg?editors=0010

这是关于缩放一个旋转的矩形并找到新的缩放矩形的顶点坐标。

当我旋转矩形时,我将其中心平移到视口的 0,0 并进行旋转。然后我翻译回原来的地方。有用。

然后我将transform-origin 移动到矩形的右下角。为了避免跳跃,我补偿了缩放量以及旋转动作应用于我的控制点的平移。最后,当我将transform origin 移动到矩形的旋转左下角时,我看不到任何跳转。我用新的控制点计算了一个新的边界框(不是旋转坐标,而是缩放版本。)

之后,我用同样的方法对新的transform-origin 进行缩放。这次我采用新的缩放但未旋转的新边界框,并用相同的方法进行旋转以找到新的缩放和旋转的控制点坐标。

我希望它们恰好位于图像顶点,但它们有点偏离。

可能是关于从旋转控制点的原点进行缩放并且没有正确补偿。

在我分享的代码笔链接中重现问题。

首先向左旋转任意量。

然后通过将左上角的手柄向左拖动来进行缩放。

小黑点应该正好落在绿色手柄的中心。

小黑点是我计算的新控制点坐标, 红色描边矩形是新的边界框,它在 0,0 处旋转并平移回来以计算新的控制点。带有红色填充的蓝色目标是图像的transform-origin。带有绿色填充的黄色目标是句柄的transform-origin,我不会有意更新以免混淆。半径较大且不透明度的蓝色填充圆是从小黑点计算的新中心。

【问题讨论】:

    标签: javascript svg matrix css-transforms


    【解决方案1】:

    我像下面这样解决了这个问题,我很想听到更好的解决方案。

    这包括在旋转和缩放操作后找到新的顶点和中心。

    以下所有代码块都应在每个缩放事件和旋转事件之后进行评估。

    这可能是手柄的拖动事件。

    heightOfRectangleWidthOfRectangle 应该是缩放后的值。

    例如。如果您当前的比例为 1.3,那么 heightOfRectangle 应该是您的 initial rectangle's height*1.3

    rotationAngle 应该是之前应用的所有旋转角度的总和,以弧度表示。

    alphaMath.atan2(heightOfRectangle,WidthOfRectangle)

    rMath.sqrt(Math.pow(WidthOfRectangle,2)+Math.pow(heightOfRectangle,2))/2 换句话说,斜边由构成矩形的两个直角三角形共享;

    假设您克服了变换原点问题并且可以缩放 来自不同手柄的矩形防止变换原点跳跃,活动手柄是您拖动的手柄 而对面是变换原点所在的位置。 例如,如果您从左上角的手柄拖动,原点应该位于 在右下手柄位置。

    activeHandle 是您拖动的句柄。

    tl 用于左上角,o 用于原点 br 用于右下角等等..

    tc 表示我的代码的顶部中心,我在其中拖动以进行旋转。

    它只是意味着从原点事件旋转。

    old 开头的值应该是您在此轮换之前的最后一个句柄位置。 以new 开头的值将是此轮换后的新句柄位置。

    rx是旋转x的缩写 ry是旋转y的缩写

    您仍然可以在此处查看笔,问题已解决。

    https://codepen.io/anon/pen/LLEedg?editors=0010

    您可以在第 251 行查看updateControlPoints 函数。

     var cosRot = Math.cos(rotationAngle);
     var sinRot = Math.sin(rotationAngle);
    
     if (activeHandle === 'tc') {
    
         var cosAMinusRot = Math.cos(alpha - rotationAngle);
         var sinAMinusRot = Math.sin(alpha - rotationAngle);
         var cosAPlusRot = Math.cos(alpha + rotationAngle);
         var sinAPlusRot = Math.sin(alpha + rotationAngle);
         var cos90APlusRot = Math.cos(Math.PI / 2 - alpha + rotationAngle);
         var sin90APlusRot = Math.sin(Math.PI / 2 - alpha + rotationAngle);
         var ox = old_ox; //means current ox
         var oy = old_oy; //means current oy
         //tl
         var new_x = -r * cosAPlusRot + ox
         var new_y = -r * sinAPlusRot + oy
         new_tl.rx = new_x;
         new_tl.ry = new_y;
         //tr           
    
         new_x = +r * sin90APlusRot + ox
         new_y = -r * cos90APlusRot + oy
         new_tr.rx = new_x;
         new_tr.ry = new_y;
         //bl
         new_x = -r * cosAMinusRot + ox
         new_y = +r * sinAMinusRot + oy
         new_bl.rx = new_x;
         new_bl.ry = new_y;
         //br
         new_x = +r * cosAPlusRot + ox
         new_y = +r * sinAPlusRot + oy
         new_br.rx = new_x;
         new_br.ry = new_y;
    
     }
    
     else if (activeHandle === 'tl') {
    
         var cosAPlusRot = Math.cos(alpha + rotationAngle);
         var sinAPlusRot = Math.sin(alpha + rotationAngle);
    
         new_tl.rx = old_br.rx - 2 * r * cosAPlusRot;
         new_tl.ry = old_br.ry - 2 * r * sinAPlusRot;
    
         new_bl.rx = old_br.rx - WidthOfRectangle * cosRot;
         new_bl.ry = old_br.ry - WidthOfRectangle * sinRot;
    
         new_tr.rx = old_br.rx + HeightOfRectangle * sinRot;
         new_tr.ry = old_br.ry - HeightOfRectangle * cosRot;
    
         new_ox = old_br.rx - r * cosAPlusRot;
         new_oy = old_br.ry - r * sinAPlusRot;
    
    
     } else if (activeHandle === 'tr') {
    
         var cos180APlusRot = Math.cos(Math.PI - alpha + rotationAngle);
         var sin180APlusRot = Math.sin(Math.PI - alpha + rotationAngle);
    
         new_tl.rx = old_bl.rx + HeightOfRectangle * sinRot;
         new_tl.ry = old_bl.ry - HeightOfRectangle * cosRot;
    
         new_br.rx = old_bl.rx + WidthOfRectangle * cosRot;
         new_br.ry = old_bl.ry + WidthOfRectangle * sinRot;
    
         new_tr.rx = old_bl.rx - 2 * r * cos180APlusRot;
         new_tr.ry = old_bl.ry - 2 * r * sin180APlusRot;
    
         new_ox = old_bl.rx - r * cos180APlusRot;
         new_oy = old_bl.ry - r * sin180APlusRot;
    
    
    
    
     } else if (activeHandle === 'bl') {
    
         var cosAPlus90MinusRot = Math.cos(alpha + Math.PI / 2 - rotationAngle);
         var sinAPlus90MinusRot = Math.sin(alpha + Math.PI / 2 - rotationAngle);
    
         new_bl.rx = old_tr.rx - 2 * r * sinAPlus90MinusRot;
         new_bl.ry = old_tr.ry - 2 * r * cosAPlus90MinusRot;
    
         new_br.rx = old_tr.rx - HeightOfRectangle * sinRot;
         new_br.ry = old_tr.ry + HeightOfRectangle * cosRot;
    
         new_tl.rx = old_tr.rx - WidthOfRectangle * cosRot;
         new_tl.ry = old_tr.ry - WidthOfRectangle * sinRot;
    
         new_ox = old_tr.rx - r * sinAPlus90MinusRot;
         new_oy = old_tr.ry - r * cosAPlus90MinusRot;
    
    
    
     } else if (activeHandle === 'br') {
    
         var cosAPlusRot = Math.cos(alpha + rotationAngle);
         var sinAPlusRot = Math.sin(alpha + rotationAngle);
    
         new_bl.rx = old_tl.rx - HeightOfRectangle * sinRot;
         new_bl.ry = old_tl.ry + HeightOfRectangle * cosRot;
    
         new_br.rx = old_tl.rx + 2 * r * cosAPlusRot;
         new_br.ry = old_tl.ry + 2 * r * sinAPlusRot;
    
         new_tr.rx = old_tl.rx + WidthOfRectangle * cosRot;
         new_tr.ry = old_tl.ry + WidthOfRectangle * sinRot;
    
         new_ox = old_tl.rx + r * cosAPlusRot;
         new_oy = old_tl.ry + r * sinAPlusRot;
    
    
    
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 2019-05-22
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      相关资源
      最近更新 更多