当前位置: 首页 > 面试题库 >

为什么转换顺序很重要?旋转/缩放的结果与缩放/旋转的结果不同

叶煌
2023-03-14
问题内容

通过梳理后SVG规范和指南,如这个和这个,我仍然在努力理解究竟是如何链接转换工作。

精选相关报价

当将transform属性应用于SVG元素时,该元素将获得使用中的当前用户坐标系的“副本”。

和:

当转换链接在一起时,最重要的是要意识到,就像HTML元素转换一样,每个转换都将在坐标系被先前的转换转换后应用于坐标系。

和:

例如,如果要对元素应用旋转,然后进行平移,则平移将根据新的坐标系发生,而不是初始的非旋转坐标系。

和:

转换的顺序很重要。在transform属性中指定变换函数的顺序是将它们应用于形状的顺序。

先缩放第一个矩形的当前坐标系,然后旋转(注意顺序)。旋转第二个矩形的当前坐标系,然后缩放。

svg {

  border: 1px solid green;

}


<svg xmlns="html" target="_blank">http://www.w3.org/2000/svg">

  <style>

    rect#s1 {

      fill: red;

      transform: scale(2, 1) rotate(10deg);

    }

  </style>

  <rect id="s1" x="" y="" width="100" height="100" />

</svg>



<svg xmlns="http://www.w3.org/2000/svg">

  <style>

    rect#s2 {

      fill: blue;

      transform: rotate(10deg) scale(2, 1);

    }

  </style>

  <rect id="s2" x="" y="" width="100" height="100" />

</svg>

我们知道,当我们链接变换时,将复制该元素当前使用的坐标系,然后按指定的顺序应用变换。

当我们有一个已经缩放的用户坐标系并且对其应用旋转时,矩形(如图所示)有效地倾斜(注意更改的角度)。如果我们以相反的方式(旋转,然后缩放)进行两个变换,则不会发生这种情况。

我们将不胜感激地提供有关缩放电流坐标系确切旋转方式的专家帮助。我试图从技术(内部工作)的角度理解为什么偏斜发生在第一个矩形中。

谢谢。


问题答案:

为了说明其工作原理,让我们考虑一个动画,以显示缩放效果如何改变旋转。

.red {

  width:80px;

  height:20px;

  background:red;

  margin:80px;

  transform-origin:left center;

  animation: rotate 2s linear infinite;

}

@keyframes rotate {

  from{transform:rotate(0)}

  to{transform:rotate(360deg)}



}


<div class="container">

<div class="red">

</div>

</div>

正如您在上面看到的,旋转创建了一个完美的圆形。

现在让我们缩放容器并查看差异:

.red {

  width:80px;

  height:20px;

  background:red;

  margin:80px;

  transform-origin:left center;

  animation: rotate 5s linear infinite;

}

@keyframes rotate {

  from{transform:rotate(0)}

  to{transform:rotate(360deg)}



}

.container {

  display:inline-block;

  transform:scale(3,1);

  transform-origin:left center;

}


<div class="container">

<div class="red">

</div>

</div>

请注意,我们现在不再是圆形,而是椭圆。就像我们取了一个圆并固定了它,这在矩形内创建了偏斜效果。

如果我们做相反的效果,我们先从缩放效果开始,然后应用旋转,则不会有任何倾斜。

.red {

  width:80px;

  height:20px;

  background:red;

  margin:80px;

  animation: rotate 2s linear infinite;

}

@keyframes rotate {

  from{transform:scale(1,1)}

  to{transform:scale(3,1)}



}

.container {

  display:inline-block;

  transform:rotate(30deg);

  transform-origin:left center;

}


<div class="container">

<div class="red">

</div>

</div>

用不同的方式来解释:施加旋转将使X和Y轴之间的比率保持相同,因此以后进行缩放时不会看到任何不良影响,但是仅缩放一个轴会破坏该比率,因此,当我们尝试时,我们的形状看起来很糟糕进行旋转。

以下是相关部分:

转换是累积的。也就是说,元素在其父级坐标系内建立其局部坐标系。

从用户的角度来看,元素有效地累积了其祖先的所有变换属性以及应用于该元素的任何局部变换

让我们做一些数学运算,以了解两个转换之间的差异。让我们考虑矩阵乘法和因为我们面对的是一个二维线性变换,我们将做到这一点上ℝ²为简单起见 1

因为scale(2, 1) rotate(10deg)我们将有

 |2 0|   |cos(10deg) -sin(10deg)|   |2*cos(10deg) -2*sin(10deg) |
 |0 1| x |sin(10deg) cos(10deg) | = |1*sin(10deg) 1*cos(10deg)  |

现在,如果我们将此矩阵应用于,(Xi,Yi)我们将获得(Xf,Yf)如下所示:

 Xf = 2* (Xi*cos(10deg) - Yi*sin(10deg))
 Yf =     Xi*sin(10deg) + Yi*cos(10deg)

请注意,它Xf是如何具有一个额外的乘数的,这是造成偏斜效果的元凶。就像我们更改了行为或Xf保留了Yf

现在让我们考虑rotate(10deg) scale(2, 1)

 |cos(10deg) -sin(10deg)|   |2 0|   |2*cos(10deg) -1*sin(10deg) |
 |sin(10deg) cos(10deg) | x |0 1| = |2*sin(10deg) 1*cos(10deg)  |

然后我们将有

 Xf =  2*Xi*cos(10deg) - Yi*sin(10deg)
 Yf =  2*Xi*sin(10deg) + Yi*cos(10deg)

我们可以将其2*Xi视为an Xt,并且可以说我们旋转了(Xt,Yi)元素,并且此元素最初是考虑X轴缩放的。

1 CSS还使用仿射变换(例如平移),因此使用ℝ²(笛卡尔坐标)不足以执行我们的计算,因此我们需要考虑ℝℙ²(同质坐标)。我们之前的计算将是:

 |2 0 0|   |cos(10deg) -sin(10deg) 0|   |2*cos(10deg) -2*sin(10deg) 0|
 |0 1 0| x |sin(10deg) cos(10deg)  0| = |1*sin(10deg) 1*cos(10deg)  0|
 |0 0 1|   |0          0           1|   |0            0             1|

在这种情况下,什么都不会改变,因为仿射部分为 空, 但是如果我们将翻译与其他转换结合在一起(例如:),scale(2, 1) translate(10px,20px)我们将具有以下优势:

 |2 0 0|   |1 0 10px|   |2 0 20px|
 |0 1 0| x |0 1 20px| = |0 1 20px|
 |0 0 1|   |0 0 1   |   |0 0  1  |

Xf =  2*Xi + 20px;
Yf =  Yi + 20px;
1  =  1 (to complete the multiplication)


 类似资料:
  • 我有一个被JScrollPane包围的JPanel。该JPanel用于显示图像。我需要提供zoomIn、zoomOut、顺时针旋转和逆时针旋转等功能。所有这些功能单独运行良好。对于缩放,我称之为图形对象的缩放。它发生在从左上到右下的基础上。对于旋转,我重置比例,然后平移、旋转 因此,问题是当面板坐标更改时,图像的坐标不会改变。有人可以帮助我更改图像的坐标吗?

  • 选择要变换的文字 您可以像对其他对象一样,对文字进行旋转、镜像、比例缩放和倾斜。但是,您选择文字的方式会影响变换结果: 要变换文字及其边框路径,请选择文字对象,然后使用旋转工具旋转对象和文本。 要只变换边框路径(而不变换它所包含的文字),请使用选择工具选择文字对象并进行拖移。 旋转文字路径(左图)与旋转文字和路径(右图)的对比图 另请参阅 第 197 页的 “变换对象 ” 调整文字缩放比例 您可以

  • 通过前7节课的学习,我相信你已经对Threejs几何体内部顶点构成有了一定了解。 几何体Geometry对象有一系列的顶点属性,也封装了一系列的方法,通过.scale()、.translate()、.rotateX()等方法可以对几何体本身进行缩放、平移、旋转等几何变换。通过.scale()、.translate()、.rotateX()这些方法对几何体进行变换,注意本质上都是改变结合体顶点位置坐

  • 点模型Points、线模型Line、网格网格模型Mesh等模型对象的基类都是Object3D,如果想对这些模型进行旋转、缩放、平移等操作,如何实现,可以查询Threejs文档Object3D对相关属性和方法的介绍。 缩放 网格模型Mesh的属性.scale表示模型对象的缩放比例,默认值是THREE.Vector3(1.0,1.0,1.0),.scale的属性值是一个三维向量对象Vector3,查看

  • 我有不同维度的文档图像,我希望能够有效地缩放和旋转他们在以下方式(标准的“旋转”和“缩放”逻辑)。我怎么做? 一幅图像是H像素高,W像素宽。最初,它应该缩放到600像素宽。在每次旋转时,面板的宽度和高度应该互换,缩放图像应该旋转90度。在每次缩放时,图像应按因子“比例”缩放。 以下是我到目前为止在...得到的BufferedImage会缩放和旋转,但不会平移(旋转90度后位于面板顶部的中心):

  • 问题内容: 我使用Java中的Graphics2D缩放和旋转绘制的图片。现在,我想知道当单击图片中的某个点时的原始坐标是什么。因此,鉴于旋转坐标和缩放坐标,我想计算原始坐标。有没有简单的方法可以做到这一点? 问题答案: 如果保留在绘制图像时使用的副本,则可以使用 AffineTransform.inverseTransform(Point2D ptSrc,Point2D ptDst) 将设备空间坐