在html5画布上我绘制了对象(矩形,圆形等等),这些对象具有缩放,倾斜,旋转等变换属性......这些对象可以嵌套。
当我应用变换后出现问题时,我想找到给定对象的精确x,y坐标,但是它超越了我的脑袋。
致所有进入交互式计算机图形学的专家;请帮我解决这个问题。
提前致谢。
答案 0 :(得分:8)
2D中的所有仿射变换可以表示为以下形式的矩阵:
[ a c dx ]
T = [ b d dy ]
[ 0 0 1 ]
这可以用方法context.transform(a, b, c, d, dx, dy);
来表达。
当应用于某个坐标(x,y)
时,首先必须添加第三个坐标,该坐标始终为1
:<x, y, 1>
。然后你可以将变换矩阵相乘得到结果:
[ a*x + c*y + dx ]
[ b*x + d*y + dy ]
[ 1 ]
如果在最后一个坐标中得到“1”以外的任何值,则必须将矢量除以它。
换句话说,你必须反转矩阵:
[ d/M -c/M (c*dy - d*dx)/M ]
[ b/M a/M (b*dx - a*dy)/M ]
[ 0 0 1 ]
其中M
为(a*d - b*c)
。
可以通过将它们的矩阵相乘来按顺序应用多个转换。乘法的顺序很重要。
context.translate(dx,dy) <==> context.transform( 1, 0, 0, 1, dx, dy)
context.rotate(θ) <==> context.transform( c, s, -s, c, 0, 0)
context.scale(sx,sy) <==> context.transform(sx, 0, 0, sy, 0, 0)
其中c = Math.cos(θ)
和s = Math.sin(θ)
如果你在对象空间中得到了一些坐标(x,y)
,并且想要知道它在屏幕上的最终位置,你可以将转换应用到它。
如果屏幕上有一些坐标(x,y)
,并且您想知道对象上的哪个点,则乘以变换的倒数。
答案 1 :(得分:0)
Tom Larkworthy 的回答是完美的,但有一个小错误。 正确的矩阵求逆公式为:
[ d/M -c/M (c*dy - d*dx)/M ]
[ -b/M a/M (b*dx - a*dy)/M ]
[ 0 0 1 ]