Add convenience translation, rotation, and scaling methods to `Transform2D`

This commit is contained in:
Patrick Walton 2019-07-12 11:34:48 -07:00
parent 1eb28a5539
commit 2c984de1ea
7 changed files with 29 additions and 44 deletions

View File

@ -441,8 +441,7 @@ impl Path2D {
start_angle: f32,
end_angle: f32,
direction: ArcDirection) {
let mut transform = Transform2F::from_scale(Vector2F::splat(radius));
transform = Transform2F::from_translation(center) * transform;
let transform = Transform2F::from_scale(Vector2F::splat(radius)).translate(center);
self.current_contour.push_arc(&transform, start_angle, end_angle, direction);
}
@ -456,8 +455,7 @@ impl Path2D {
let bisector = vu0 + vu1;
let center = ctrl + bisector.scale(hypot / bisector.length());
let mut transform = Transform2F::from_scale(Vector2F::splat(radius));
transform = Transform2F::from_translation(center) * transform;
let transform = Transform2F::from_scale(Vector2F::splat(radius)).translate(center);
let chord = LineSegment2F::new(vu0.yx().scale_xy(Vector2F::new(-1.0, 1.0)),
vu1.yx().scale_xy(Vector2F::new(1.0, -1.0)));
@ -483,9 +481,7 @@ impl Path2D {
end_angle: f32) {
self.flush_current_contour();
let mut transform = Transform2F::from_translation(center);
transform *= Transform2F::from_rotation(rotation);
transform *= Transform2F::from_scale(axes);
let transform = Transform2F::from_scale(axes).rotate(rotation).translate(center);
self.current_contour.push_arc(&transform, start_angle, end_angle, ArcDirection::CW);
if end_angle - start_angle >= 2.0 * PI {

View File

@ -138,9 +138,8 @@ impl<'a> OutlineStrokeToFill<'a> {
LineCap::Round => {
let scale = Vector2F::splat(width * 0.5);
let offset = gradient.yx().scale_xy(Vector2F::new(-1.0, 1.0));
let mut transform = Transform2F::from_scale(scale);
let translation = p1 + offset.scale(width * 0.5);
transform = Transform2F::from_translation(translation) * transform;
let transform = Transform2F::from_scale(scale).translate(translation);
let chord = LineSegment2F::new(-offset, offset);
contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW);
}
@ -374,8 +373,7 @@ impl Contour {
}
LineJoin::Round => {
let scale = Vector2F::splat(distance.abs());
let mut transform = Transform2F::from_translation(join_point);
transform *= Transform2F::from_scale(scale);
let transform = Transform2F::from_scale(scale).translate(join_point);
let chord_from = (prev_tangent.to() - join_point).normalize();
let chord_to = (next_tangent.to() - join_point).normalize();
let chord = LineSegment2F::new(chord_from, chord_to);

View File

@ -14,7 +14,7 @@
// proper.
use crate::window::{OcularTransform, View};
use pathfinder_geometry::vector::{Vector2F, Vector2I, Vector4F};
use pathfinder_geometry::vector::{Vector2I, Vector4F};
use pathfinder_geometry::rect::RectF;
use pathfinder_geometry::transform2d::Transform2F;
use pathfinder_geometry::transform3d::{Perspective, Transform4F};
@ -56,8 +56,7 @@ impl Camera {
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32
* scale_factor_for_view_box(view_box);
let origin = viewport_size.to_f32().scale(0.5) - view_box.size().scale(scale * 0.5);
Camera::TwoD(Transform2F::from_translation(origin) *
Transform2F::from_uniform_scale(scale))
Camera::TwoD(Transform2F::from_uniform_scale(scale).translate(origin))
}
fn new_3d(mode: Mode, view_box: RectF, viewport_size: Vector2I) -> Camera {

View File

@ -327,10 +327,10 @@ impl<W> DemoApp<W> where W: Window {
if let Camera::TwoD(ref mut transform) = self.camera {
let backing_scale_factor = self.window_size.backing_scale_factor;
let position = position.to_f32().scale(backing_scale_factor);
*transform = Transform2F::from_translation(-position) * *transform;
let scale_delta = 1.0 + d_dist * CAMERA_SCALE_SPEED_2D;
*transform = Transform2F::from_uniform_scale(scale_delta) * *transform;
*transform = Transform2F::from_translation(position) * *transform;
*transform = transform.translate(-position)
.uniform_scale(scale_delta)
.translate(position);
}
}
Event::Look { pitch, yaw } => {
@ -587,8 +587,7 @@ impl<W> DemoApp<W> where W: Window {
}
UIEvent::MouseDragged(position) => {
if let Camera::TwoD(ref mut transform) = self.camera {
*transform = Transform2F::from_translation(position.relative.to_f32()) *
*transform;
*transform = transform.translate(position.relative.to_f32());
}
}
_ => {}
@ -608,10 +607,7 @@ impl<W> DemoApp<W> where W: Window {
if let Camera::TwoD(ref mut transform) = self.camera {
let scale = Vector2F::splat(1.0 + CAMERA_ZOOM_AMOUNT_2D);
let center = center_of_window(&self.window_size);
*transform = Transform2F::from_translation(center) *
Transform2F::from_scale(scale) *
Transform2F::from_translation(-center) *
*transform;
*transform = transform.translate(-center).scale(scale).translate(center);
self.dirty = true;
}
}
@ -619,10 +615,7 @@ impl<W> DemoApp<W> where W: Window {
if let Camera::TwoD(ref mut transform) = self.camera {
let scale = Vector2F::splat(1.0 - CAMERA_ZOOM_AMOUNT_2D);
let center = center_of_window(&self.window_size);
*transform = Transform2F::from_translation(center) *
Transform2F::from_scale(scale) *
Transform2F::from_translation(-center) *
*transform;
*transform = transform.translate(-center).scale(scale).translate(center);
self.dirty = true;
}
}
@ -636,10 +629,9 @@ impl<W> DemoApp<W> where W: Window {
if let Camera::TwoD(ref mut transform) = self.camera {
let old_rotation = transform.rotation();
let center = center_of_window(&self.window_size);
*transform = Transform2F::from_translation(-center) *
Transform2F::from_rotation(*theta - old_rotation) *
Transform2F::from_translation(center) *
*transform;
*transform = transform.translate(-center)
.rotate(*theta - old_rotation)
.translate(center);
}
}
}

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, LineJoin, Path2D};
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
use pathfinder_content::color::ColorF;
use pathfinder_geometry::rect::RectF;
use pathfinder_geometry::vector::{Vector2F, Vector2I};
@ -57,7 +57,6 @@ fn main() {
// Set line width.
canvas.set_line_width(10.0);
canvas.set_line_join(LineJoin::Round);
// Draw walls.
canvas.stroke_rect(RectF::new(Vector2F::new(75.0, 140.0), Vector2F::new(150.0, 110.0)));

View File

@ -246,22 +246,25 @@ impl Transform2F {
self.matrix.m22()
}
/*
#[inline]
pub fn post_translate(&self, vector: Vector2F) -> Transform2F {
self.post_mul(&Transform2F::from_translation(vector))
pub fn translate(&self, vector: Vector2F) -> Transform2F {
Transform2F::from_translation(vector) * *self
}
#[inline]
pub fn post_rotate(&self, theta: f32) -> Transform2F {
self.post_mul(&Transform2F::from_rotation(theta))
pub fn rotate(&self, theta: f32) -> Transform2F {
Transform2F::from_rotation(theta) * *self
}
#[inline]
pub fn post_scale(&self, scale: Vector2F) -> Transform2F {
self.post_mul(&Transform2F::from_scale(scale))
pub fn scale(&self, scale: Vector2F) -> Transform2F {
Transform2F::from_scale(scale) * *self
}
#[inline]
pub fn uniform_scale(&self, scale: f32) -> Transform2F {
self.scale(Vector2F::splat(scale))
}
*/
/// Returns the translation part of this matrix.
///

View File

@ -93,9 +93,7 @@ impl SceneExt for Scene {
// FIXME(pcwalton): Cache this!
let scale = style.size / (font.metrics().units_per_em as f32);
let scale = Vector2F::new(scale, -scale);
let transform = *transform *
Transform2F::from_translation(offset) *
Transform2F::from_scale(scale);
let transform = *transform * Transform2F::from_scale(scale).translate(offset);
self.push_glyph(font,
glyph.glyph_id,
&transform,