From 8d2db7eeeec3b684939d563db22bef2036f3c53d Mon Sep 17 00:00:00 2001 From: Nicolas Nattis Date: Fri, 2 Oct 2020 14:34:32 -0300 Subject: [PATCH] Improves code --- code/__HELPERS/matrices.dm | 52 +++++++++++-------- .../camera/camera_image_capturing.dm | 25 ++++----- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index 0cb19e9c0f4..3623c09d43b 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -1,3 +1,34 @@ +/// Datum which stores information about a matrix decomposed with decompose(). +/datum/decompose_matrix + ///? + var/scale_x = 1 + ///? + var/scale_y = 1 + ///? + var/rotation = 0 + ///? + var/shift_x = 0 + ///? + var/shift_y = 0 + +/// Decomposes a matrix into scale, shift and rotation. +/// +/// If other operations were applied on the matrix, such as shearing, the result +/// will not be precise. +/matrix/proc/decompose() + var/datum/decompose_matrix/decompose_matrix = new + . = decompose_matrix + decompose_matrix.scale_x = sqrt(a * a + d * d) + decompose_matrix.scale_y = sqrt(b * b + e * e) + decompose_matrix.shift_x = c + decompose_matrix.shift_y = f + if(!decompose_matrix.scale_x || !decompose_matrix.scale_y) + return + // If only translated, scaled and rotated, a/xs == e/ys and -d/xs == b/xy + var/cossine = (a/decompose_matrix.scale_x + e/decompose_matrix.scale_y) / 2 + var/sine = (b/decompose_matrix.scale_y - d/decompose_matrix.scale_x) / 2 + decompose_matrix.rotation = arctan(cossine, sine) + /matrix/proc/TurnTo(old_angle, new_angle) . = new_angle - old_angle Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT @@ -55,27 +86,6 @@ . += f . += 1 -///The X scale of the matrix -/matrix/proc/get_x_scale() - return sqrt(a * a + d * d) - -///The Y scale of the matrix -/matrix/proc/get_y_scale() - return sqrt(b * b + e * e) - -/// Gets the rotation of the matrix, in degrees. -/// Will produce correct results if the matrix is only being translated, scaled -/// and rotated. Otherwise this is a best attempt. -/matrix/proc/get_rotation() - var/xs = get_x_scale() - var/ys = get_y_scale() - if(!xs || !ys) - return 0 - // If only translated, scaled and rotated, a/xs == e/ys and -d/xs == b/xy - var/cossine = (a/xs + e/ys) / 2 - var/sine = (b/ys - d/xs) / 2 - return arctan(cossine, sine) - ///The X pixel offset of this matrix /matrix/proc/get_x_shift() . = c diff --git a/code/modules/photography/camera/camera_image_capturing.dm b/code/modules/photography/camera/camera_image_capturing.dm index 7f7caa0bfee..95966711a4f 100644 --- a/code/modules/photography/camera/camera_image_capturing.dm +++ b/code/modules/photography/camera/camera_image_capturing.dm @@ -85,20 +85,21 @@ // Center of the image in Y var/yo = (clone.y - center.y) * world.icon_size + clone.pixel_y + ycomp + clone.step_y - if(clone.transform) // getFlatIcon doesn't give a snot about transforms.' - var/sx = clone.transform.get_x_scale() - var/sy = clone.transform.get_y_scale() - if(sx != 1 || sy != 1) + if(clone.transform) // getFlatIcon doesn't give a snot about transforms. + var/datum/decompose_matrix/decompose = clone.transform.decompose() + // Scale in X, Y + if(decompose.scale_x != 1 || decompose.scale_y != 1) var/base_w = img.Width() var/base_h = img.Height() - img.Scale(base_w * sx, base_h * sy) - xo -= base_w * (sx - 1) / 2 - yo -= base_h * (sy - 1) / 2 - var/rx = clone.transform.get_rotation() - if(rx != 0) - img.Turn(rx) - xo += clone.transform.get_x_shift() - yo += clone.transform.get_x_shift() + img.Scale(base_w * decompose.scale_x, base_h * decompose.scale_y) + xo -= base_w * (decompose.scale_x - 1) / 2 + yo -= base_h * (decompose.scale_y - 1) / 2 + // Rotation + if(decompose.rotation != 0) + img.Turn(decompose.rotation) + // Shift + xo += decompose.shift_x + yo += decompose.shift_y res.Blend(img, blendMode2iconMode(clone.blend_mode), xo, yo) CHECK_TICK