【问题标题】:Implementing SVG scale/rotate transformations (and how to understand the coordinate system)实现 SVG 缩放/旋转变换(以及如何理解坐标系)
【发布时间】:2012-06-26 23:49:34
【问题描述】:

所以我对 SVG 坐标系有点困惑。我正在做一个将 SVG 对象转换为多边形的项目(然后在 OpenGL 中显示)。我有所有的代码,包括矩形、圆形、路径(使用曲线近似)等,并将它们转换为每个对象的一组点。到目前为止,这一切都很好。

我现在正处于实施转换的阶段。我已经编写好所有矩阵函数并准备使用,但我对 translate(x,y) 与任何以 0,0 为中心的操作(主要是旋转和缩放)之间的关系感到困惑。

假设我们在 0,0 处有一个对象。 rotate(45, 100, 100) 等价于 translate(100, 100) rotate(45) translate(-100, -100),但是如果我将对象移动到 100,100 并且旋转仍然应用在 0,0,这并不意味着旋转中心实际上相对于 -100,-100物体的原始位置?

我想我的问题是translate 如何影响对象的坐标系?似乎在某些情况下它用于将 0,0 移动到指定点不移动对象,而在其他情况下它用于移动对象。

我对坐标系的理解完全有缺陷吗?

【问题讨论】:

    标签: svg


    【解决方案1】:

    我认为SVG specification 非常清楚地解释了coordinate transformations。每次转换都意味着将当前坐标与 3x3 矩阵相乘。您可以在transform attribute 中指定的最通用转换是自定义matrix(...),而所有其他类型的转换(平移、旋转、缩放、倾斜)只是易于使用的快捷方式。最后,一切都以矩阵形式结束。

    组合几个变换很简单,它只是意味着每个变换矩阵按顺序与其他变换矩阵相乘,跟踪所有变换意味着记住从这个乘法得到的最终 3x3 矩阵,并计算最终的坐标一个元素意味着只需将初始坐标的 3x1 矩阵与该 3x3 矩阵相乘。

    所以,我的建议是只使用矩阵,忘记手动应用每个转换。

    【讨论】:

    • 我对每个将它们变成矩阵的转换都有函数。这一切都完美无缺。不过,我的问题是更高级别的。执行translate(100,100) rotate(45) translate(-100,-100) 不会以 (100,100) 为中心,而是以 (-100,-100) 为中心,因为它将对象从 (0,0) 移动到 (100,100)。当旋转发生时,它仍然发生在 (0,0)。所以要么规范有错字(不太可能),要么我遗漏了一些关于坐标系的东西(更有可能)。
    • 别忘了改变的不是对象,而是坐标系。 translate(100, 100) rotate (45) translate(-100, -100)并不是说先把物体移动(100, 100),然后再旋转,是说把坐标系的原点移动了(100, 100),效果正好相反:原来的物体在(100, 100) 突然发现自己正好位于local 坐标系的原点。
    • 这更有意义。我想我的问题是我该如何实现呢?因为如果我要直接为translate(100, 100) rotate (45) translate(-100, -100) 生成矩阵并将它们相乘,它围绕(-100, -100) 旋转。似乎对于翻译,我必须生成反向翻译,然后在将实际翻译应用于点之前,再次将其反转。这是真的吗?
    • 你确定吗?我created a SVG file 试图举例说明会发生什么。蓝线是从 (100, 100) 到 (100, 110) 没有变换的线,绿线用translate, rotate, translate back变换,红线用rotate around (100, 100)变换。矩阵数学是根据规范完成的,最后我得到了正确的坐标。我在计算出的坐标上放了一个黄点,它落在实线末端,是变换后得到的。
    • 要注意的另一件事是,旋转也以相反的方式应用:rotate(45) 逆时针旋转线,尽管角度是正的并且角度值应该是顺时针的。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 2012-02-29
    相关资源
    最近更新 更多