Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement some missing functionalities that would be useful in WebRender. #170

Merged
merged 4 commits into from Dec 9, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -11,7 +11,6 @@ use super::{UnknownUnit, Radians};
use num::{One, Zero};
use point::TypedPoint2D;
use rect::TypedRect;
use size::TypedSize2D;
use std::ops::{Add, Mul, Div, Sub};
use std::marker::PhantomData;
use approxeq::ApproxEq;
@@ -214,28 +213,12 @@ where T: Copy + Clone +
/// matrix.
#[inline]
pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
let top_left = self.transform_point(&rect.origin);
let top_right = self.transform_point(&rect.top_right());
let bottom_left = self.transform_point(&rect.bottom_left());
let bottom_right = self.transform_point(&rect.bottom_right());
let (mut min_x, mut min_y) = (top_left.x, top_left.y);
let (mut max_x, mut max_y) = (min_x, min_y);
for point in &[top_right, bottom_left, bottom_right] {
if point.x < min_x {
min_x = point.x
}
if point.x > max_x {
max_x = point.x
}
if point.y < min_y {
min_y = point.y
}
if point.y > max_y {
max_y = point.y
}
}
TypedRect::new(TypedPoint2D::new(min_x, min_y),
TypedSize2D::new(max_x - min_x, max_y - min_y))
TypedRect::from_points(&[
self.transform_point(&rect.origin),
self.transform_point(&rect.top_right()),
self.transform_point(&rect.bottom_left()),
self.transform_point(&rect.bottom_right()),
])
}

/// Computes and returns the determinant of this matrix.
@@ -11,6 +11,7 @@ use super::{UnknownUnit, Radians};
use approxeq::ApproxEq;
use trig::Trig;
use point::{TypedPoint2D, TypedPoint3D, TypedPoint4D};
use rect::TypedRect;
use matrix2d::TypedMatrix2D;
use scale_factor::ScaleFactor;
use num::{One, Zero};
@@ -196,6 +197,28 @@ where T: Copy + Clone +
)
}

/// Drop the units, preserving only the numeric value.
#[inline]
pub fn to_untyped(&self) -> Matrix4D<T> {
Matrix4D::row_major(
self.m11, self.m12, self.m13, self.m14,
self.m21, self.m22, self.m23, self.m24,
self.m31, self.m32, self.m33, self.m34,
self.m41, self.m42, self.m43, self.m44,
)
}

/// Tag a unitless value with units.
#[inline]
pub fn from_untyped(m: &Matrix4D<T>) -> Self {
TypedMatrix4D::row_major(
m.m11, m.m12, m.m13, m.m14,
m.m21, m.m22, m.m23, m.m24,
m.m31, m.m32, m.m33, m.m34,
m.m41, m.m42, m.m43, m.m44,
)
}

/// Returns the multiplication of the two matrices such that mat's transformation
/// applies after self's transformation.
pub fn post_mul<NewDst>(&self, mat: &TypedMatrix4D<T, Dst, NewDst>) -> TypedMatrix4D<T, Src, NewDst> {
@@ -376,6 +399,17 @@ where T: Copy + Clone +
TypedPoint4D::new(x, y, z, w)
}

/// Returns a rectangle that encompasses the result of transforming the given rectangle by this
/// matrix.
pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
TypedRect::from_points(&[
self.transform_point(&rect.origin),
self.transform_point(&rect.top_right()),
self.transform_point(&rect.bottom_left()),
self.transform_point(&rect.bottom_right()),
])
}

/// Create a 3d translation matrix
pub fn create_translation(x: T, y: T, z: T) -> TypedMatrix4D<T, Src, Dst> {
let (_0, _1): (T, T) = (Zero::zero(), One::one());
@@ -38,6 +38,12 @@ impl<T: Copy + Zero, U> TypedPoint2D<T, U> {
pub fn zero() -> TypedPoint2D<T, U> {
TypedPoint2D::new(Zero::zero(), Zero::zero())
}

/// Convert into a 3d point.
#[inline]
pub fn to_3d(&self) -> TypedPoint3D<T, U> {
TypedPoint3D::new(self.x, self.y, Zero::zero())
}
}

impl<T: fmt::Debug, U> fmt::Debug for TypedPoint2D<T, U> {
@@ -352,6 +358,12 @@ impl<T: Copy, U> TypedPoint3D<T, U> {
pub fn from_untyped(p: &Point3D<T>) -> TypedPoint3D<T, U> {
TypedPoint3D::new(p.x, p.y, p.z)
}

/// Convert into a 2d point.
#[inline]
pub fn to_2d(&self) -> TypedPoint2D<T, U> {
TypedPoint2D::new(self.x, self.y)
}
}

impl<T: Mul<T, Output=T> +
@@ -748,6 +760,18 @@ impl<T: ApproxEq<T>, U> ApproxEq<T> for TypedPoint4D<T, U> {
}
}

pub fn point2<T: Copy, U>(x: T, y: T) -> TypedPoint2D<T, U> {

This comment has been minimized.

@Ms2ger

Ms2ger Dec 9, 2016

Contributor

Meh.

TypedPoint2D::new(x, y)
}

pub fn point3<T: Copy, U>(x: T, y: T, z: T) -> TypedPoint3D<T, U> {
TypedPoint3D::new(x, y, z)
}

pub fn point4<T: Copy, U>(x: T, y: T, z: T, w: T) -> TypedPoint4D<T, U> {
TypedPoint4D::new(x, y, z, w)
}

#[cfg(test)]
mod point2d {
use super::Point2D;
@@ -215,6 +215,31 @@ where T: Copy + Clone + Zero + PartialOrd + PartialEq + Add<T, Output=T> + Sub<T
pub fn translate_by_size(&self, size: &TypedSize2D<T, U>) -> TypedRect<T, U> {
self.translate(&TypedPoint2D::new(size.width, size.height))
}

/// Returns the smallest rectangle containing the four points.

This comment has been minimized.

@Ms2ger

Ms2ger Dec 9, 2016

Contributor

Four?

pub fn from_points(points: &[TypedPoint2D<T, U>]) -> Self {
if points.len() == 0 {
return TypedRect::zero();
}
let (mut min_x, mut min_y) = (points[0].x, points[0].y);
let (mut max_x, mut max_y) = (min_x, min_y);
for point in &points[1..] {
if point.x < min_x {
min_x = point.x
}
if point.x > max_x {
max_x = point.x
}
if point.y < min_y {
min_y = point.y
}
if point.y > max_y {
max_y = point.y
}
}
TypedRect::new(TypedPoint2D::new(min_x, min_y),
TypedSize2D::new(max_x - min_x, max_y - min_y))
}
}

impl<T, U> TypedRect<T, U>
@@ -402,6 +427,10 @@ impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
}
}

/// Shorthand for TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h)).
pub fn rect<T: Copy, U>(x: T, y: T, w: T, h: T) -> TypedRect<T, U> {
TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h))
}

#[cfg(test)]
mod tests {
@@ -44,7 +44,7 @@ impl<T: fmt::Display, U> fmt::Display for TypedSize2D<T, U> {
}

impl<T, U> TypedSize2D<T, U> {
/// Constructor taing scalar values.
/// Constructor taking scalar values.
pub fn new(width: T, height: T) -> TypedSize2D<T, U> {
TypedSize2D {
width: width,
@@ -55,7 +55,7 @@ impl<T, U> TypedSize2D<T, U> {
}

impl<T: Clone, U> TypedSize2D<T, U> {
/// Constructor taing scalar stronlgy typed lengths.
/// Constructor taking scalar stronlgy typed lengths.
pub fn from_lengths(width: Length<T, U>, height: Length<T, U>) -> TypedSize2D<T, U> {
TypedSize2D::new(width.get(), height.get())
}
@@ -227,6 +227,11 @@ impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
}
}

/// Shorthand for TypedSize2D::new(w, h).
pub fn size2<T, U>(w: T, h: T) -> TypedSize2D<T, U> {
TypedSize2D::new(w, h)
}

#[cfg(test)]
mod size2d {
use super::Size2D;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.