[交互式SVG组件]Isometric projection

http://www.petercollingridge.co.uk/interactive-svg-components/isometric-projection

 

Isometeric projections are commonly used in technical drawings and used to be used in some computer game graphics. In an isometeric projection the three axes appear 120° from each other and are equally foreshortened. It can be achieved by rotating an object 45° in the plane of the screen and ~35.3° through the horizontal axis (see Wikipedia for more information).

We start with an image, such as this floor plan.

If we rotate this image 45° now, it will move almost off screen as rotations are always centred on the point (0, 0).

Translation

So we first translate our image so the point around which we want to rotate it (probably the centre of the image) is now at the point (0, 0). For example, the centre of this image is at (150, 80), so we translate the room by wrappping it in a group ike so:

1<g transform="translate(-150, -80)">
2  room shapes...
3</g>

Rotation in the plane of the screen

We can now rotate our image. A rotation of 45° in the plane of the screen is easy enough with transform="rotate(45)", but a rotation through the horizontal axis is more tricky. The solution is to use matrices. A rotation in the plane of the screen is a rotation through the z-axis and given by the following 3x3 matrix:

Because SVGs are 2D, they don't bother with the final row of this matrix (although it is important for intermediate steps as we'll see). SVG matrices are given as a single line of parameters in the order (column 1, row 1), (column 1, row 2), (column 2, row 1) and so on. Therefore we can replace transform="rotate(45)" with:

1transform="matrix(0.707 0.707 -0.707 0.707 0 0)"

Rotation through the horizontal axis

Rotating something through the horizontal (or x-) axis means effectively tilting the image away from us. Such a rotation is given by the following 3x3 matrix:

In an isometric projection, the angle the camera moves is ~35.3°, however, this assumes that what we're looking at is lying on the floor (i.e. the xz-plane). Our image is "upright", in the xy-plane, so we actually need to rotate by 90°-35.3°. Theta is therefore 54.7°.

If we now multiply Rz(45°) by Rx(54.7°) we get:

Or in SVG terms:

1transform="matrix(0.707 0.409 -0.707 0.409 0 -0.816)"

We can now add this to a group that contains the group with the translate transformation.

Translation back to the centre

Finally, we need to move our image back to the centre of the screen. We can do this a few ways. We could leave the image where it is and change the viewBox to be centred on (0, 0):

viewBox="-150, -80, 300, 160"

Alternatively, we could just add another group with a translation back:

1<g transform="translate(150, 80)">

You may find that you have to tweak the translation a bit to ensure the corners stay within the bounds of the image.

Finally, if you're feeling very adventurous or want to minimise the size of the SVG and processing require to display it, you can combine the two translation matrices with the rotation matrix. The first translation matrix, T1, is given by:

The second translation matrix, T2, would be the same, but with positive 150 and 80. If we multiply T2 x Riso x T1 we get:

1<g transform="matrix(0.707 0.409 -0.707 0.409 100.51 -14.78)">

Note that this transformation will only work well if you want to rotate about the point (150, 80). As you can see from the file sizes below, we've saved ourselves 94 bytes.

AttachmentSize
room_plan.svg637 bytes
room_plan_translation.svg675 bytes
room_plan_rotate_without_translate.svg666 bytes
room_plan_isometric.svg794 bytes
room_plan_isometric_matrix.svg700 bytes
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值