Corylus
Corylus

Reputation: 889

How to retrieve scale factors from geo::AffineTransform in Rust?

I'm using the geo crate (version 0.28.0) in a Rust project and I need to retrieve the amount of scaling in the x and y directions from a geo::AffineTransform instance.

However, after going through the documentation and source code, I couldn't find a direct way to access the scale factors. The internal matrix representation is private, and the public API doesn't seem to expose methods to retrieve the scale factors.

I have tried the following approach:

let [a, b, c, d, tx, ty] = transform.into();
let sx = (a * a + c * c).sqrt()

But this approach assumes knowledge of the internal matrix structure and doesn't work with the public API.

Is there a way to retrieve the scale factors using the existing public API of geo::AffineTransform? Or would I need to modify the crate and submit a pull request to add this functionality?

I'm open to alternative approaches or workarounds if directly retrieving the scale factors is not possible with the current API.

Upvotes: 0

Views: 47

Answers (2)

mkirk
mkirk

Reputation: 4040

These methods are now public.

https://docs.rs/geo/latest/geo/algorithm/affine_ops/struct.AffineTransform.html#method.new

/// Create a new custom transform matrix
///
/// The argument order matches that of the affine transform matrix:
///```ignore
/// [[a, b, xoff],
///  [d, e, yoff],
///  [0, 0, 1]] <-- not part of the input arguments
/// ```
pub fn new(a: T, b: T, xoff: T, d: T, e: T, yoff: T) -> Self {
    Self([[a, b, xoff], [d, e, yoff], [T::zero(), T::zero(), T::one()]])
}
pub fn a(&self) -> T {
    self.0[0][0]
}
pub fn b(&self) -> T {
    self.0[0][1]
}
pub fn xoff(&self) -> T {
    self.0[0][2]
}
pub fn d(&self) -> T {
    self.0[1][0]
}
pub fn e(&self) -> T {
    self.0[1][1]
}
pub fn yoff(&self) -> T {
    self.0[1][2]
}

Upvotes: 1

Jmb
Jmb

Reputation: 23443

You can get tx and ty by applying the transform to (0, 0), then you can get a and d by applying it to (1, 0) and b and e by applying it to (0, 1):

let Coord { x: tx, y: ty } = transform.apply (Coord::zero());
let u = transform.apply (Coord { x: 1.0, y: 0.0 };
let a = u.x - tx;
let d = u.y - ty;
let v = transform.apply (Coord { x: 0.0, y: 1.0 };
let b = v.x - tx;
let e = v.y - ty;

Upvotes: 1

Related Questions