Rename Point -> Vec2 to distinguish it clearly from any 3d object

This commit is contained in:
2020-09-26 13:25:49 -07:00
parent fccdbc802b
commit bef423ce38
7 changed files with 86 additions and 86 deletions

View File

@@ -1,5 +1,5 @@
use coremem::{Driver, mat, meas}; use coremem::{Driver, mat, meas};
use coremem::geom::Point; use coremem::geom::Vec2;
fn main() { fn main() {
coremem::init_logging(); coremem::init_logging();
@@ -21,11 +21,11 @@ fn main() {
driver.add_measurement(meas::MagneticFlux(width / 2, width / 2)); driver.add_measurement(meas::MagneticFlux(width / 2, width / 2));
driver.add_measurement(meas::MagneticStrength(width / 2, width / 2)); driver.add_measurement(meas::MagneticStrength(width / 2, width / 2));
let center = Point::new((width/2) as _, (width/2) as _); let center = Vec2::new((width/2) as _, (width/2) as _);
for y in 0..width { for y in 0..width {
for x in 0..width { for x in 0..width {
let d = Point::new(x as _, y as _) - center; let d = Vec2::new(x as _, y as _) - center;
if (inner_rad as _..outer_rad as _).contains(&d.mag()) { if (inner_rad as _..outer_rad as _).contains(&d.mag()) {
*driver.state.get_mut(x, y).mat_mut() = mat::Static::conductor(conductivity).into(); *driver.state.get_mut(x, y).mat_mut() = mat::Static::conductor(conductivity).into();
} else if d.mag() < ferro_rad as _ { } else if d.mag() < ferro_rad as _ {
@@ -46,9 +46,9 @@ fn main() {
let e = drive_current/conductivity; let e = drive_current/conductivity;
for y in 0..width { for y in 0..width {
for x in 0..width { for x in 0..width {
let d = Point::new(x as _, y as _) - center; let d = Vec2::new(x as _, y as _) - center;
if (inner_rad as _..outer_rad as _).contains(&d.mag()) { if (inner_rad as _..outer_rad as _).contains(&d.mag()) {
let tangent = Point::new(-d.y(), d.x()).with_mag(e); let tangent = Vec2::new(-d.y(), d.x()).with_mag(e);
driver.state.impulse_ex(x, y, tangent.x()); driver.state.impulse_ex(x, y, tangent.x());
driver.state.impulse_ey(x, y, tangent.y()); driver.state.impulse_ey(x, y, tangent.y());
} }

View File

@@ -1,6 +1,6 @@
use coremem::{consts, Driver, Flt, mat, meas}; use coremem::{consts, Driver, Flt, mat, meas};
use coremem::coord::Coord; use coremem::coord::Coord;
use coremem::geom::{Circle, Point}; use coremem::geom::{Circle, Vec2};
fn main() { fn main() {
coremem::init_logging(); coremem::init_logging();
@@ -31,7 +31,7 @@ fn main() {
)); ));
// driver.add_term_renderer(); // driver.add_term_renderer();
driver.add_measurement(meas::Label(format!("Conductivity: {}, Imax: {:.2e}", conductivity, peak_current))); driver.add_measurement(meas::Label(format!("Conductivity: {}, Imax: {:.2e}", conductivity, peak_current)));
driver.add_measurement(meas::Current(Circle::new(Point::new( driver.add_measurement(meas::Current(Circle::new(Vec2::new(
to_m(half_width), to_m(half_width)), to_m(half_width), to_m(half_width)),
to_m(conductor_outer_rad)))); to_m(conductor_outer_rad))));
driver.add_measurement(meas::Magnetization( driver.add_measurement(meas::Magnetization(
@@ -62,12 +62,12 @@ fn main() {
(half_width + (ferro_inner_rad + ferro_outer_rad) / 2, half_width, 0).into() (half_width + (ferro_inner_rad + ferro_outer_rad) / 2, half_width, 0).into()
)); ));
let center = Point::new(half_width as _, half_width as _); let center = Vec2::new(half_width as _, half_width as _);
for y in 0..width { for y in 0..width {
for x in 0..width { for x in 0..width {
let loc = Coord::new(x, y, 0); let loc = Coord::new(x, y, 0);
let d = Point::new(loc.x().into(), loc.y().into()) - center; let d = Vec2::new(loc.x().into(), loc.y().into()) - center;
let r = d.mag(); let r = d.mag();
if (conductor_inner_rad as _..conductor_outer_rad as _).contains(&r) { if (conductor_inner_rad as _..conductor_outer_rad as _).contains(&r) {
*driver.state.get_mut(loc).mat_mut() = mat::Static::conductor(conductivity).into(); *driver.state.get_mut(loc).mat_mut() = mat::Static::conductor(conductivity).into();
@@ -96,7 +96,7 @@ fn main() {
for y in half_width-conductor_outer_rad..half_width+conductor_outer_rad { for y in half_width-conductor_outer_rad..half_width+conductor_outer_rad {
for x in half_width-conductor_outer_rad..half_width+conductor_outer_rad { for x in half_width-conductor_outer_rad..half_width+conductor_outer_rad {
let loc = Coord::new(x, y, 0); let loc = Coord::new(x, y, 0);
let d = Point::new(loc.x().into(), loc.y().into()) - center; let d = Vec2::new(loc.x().into(), loc.y().into()) - center;
if (conductor_inner_rad as _..conductor_outer_rad as _).contains(&d.mag()) { if (conductor_inner_rad as _..conductor_outer_rad as _).contains(&d.mag()) {
driver.state.impulse_ez(loc, e); driver.state.impulse_ez(loc, e);
} }

View File

@@ -1,5 +1,5 @@
use crate::flt::{Flt, Real}; use crate::flt::{Flt, Real};
pub use crate::vec::Point; pub use crate::vec::{Vec2, Vec3};
use std::fmt::{self, Display}; use std::fmt::{self, Display};
use std::ops::Add; use std::ops::Add;
@@ -9,22 +9,22 @@ fn real(f: Flt) -> Real {
#[derive(Copy, Clone, Debug, Default)] #[derive(Copy, Clone, Debug, Default)]
pub struct Line { pub struct Line {
from: Point, from: Vec2,
to: Point, to: Vec2,
} }
impl Add for Line { impl Add for Line {
type Output = Line; type Output = Line;
fn add(self, other: Line) -> Line { fn add(self, other: Line) -> Line {
Line { Line {
from: self.from + Point::new(0.0, other.y(self.from.x())), from: self.from + Vec2::new(0.0, other.y(self.from.x())),
to: self.to + Point::new(0.0, other.y(self.to.x())), to: self.to + Vec2::new(0.0, other.y(self.to.x())),
} }
} }
} }
impl Line { impl Line {
pub fn new(from: Point, to: Point) -> Self { pub fn new(from: Vec2, to: Vec2) -> Self {
Self { Self {
from, from,
to, to,
@@ -32,19 +32,19 @@ impl Line {
} }
pub fn x(&self, y: Flt) -> Flt { pub fn x(&self, y: Flt) -> Flt {
self.shifted(Point::new(0.0, -y)).x_intercept() self.shifted(Vec2::new(0.0, -y)).x_intercept()
} }
pub fn y(&self, x: Flt) -> Flt { pub fn y(&self, x: Flt) -> Flt {
(self.from.y + (real(x) - self.from.x) * self.slope()).into() (self.from.y + (real(x) - self.from.x) * self.slope()).into()
} }
pub fn at_x(&self, x: Flt) -> Point { pub fn at_x(&self, x: Flt) -> Vec2 {
Point::new(x, self.y(x)) Vec2::new(x, self.y(x))
} }
pub fn from(&self) -> Point { pub fn from(&self) -> Vec2 {
self.from self.from
} }
pub fn to(&self) -> Point { pub fn to(&self) -> Vec2 {
self.to self.to
} }
@@ -53,16 +53,16 @@ impl Line {
(self.from.x + t * (self.to.x - self.from.x)).into() (self.from.x + t * (self.to.x - self.from.x)).into()
} }
pub fn as_vector(&self) -> Point { pub fn as_vector(&self) -> Vec2 {
self.to + (-self.from) self.to + (-self.from)
} }
pub fn length_sq(&self) -> Flt { pub fn length_sq(&self) -> Flt {
let Point { x, y } = self.as_vector(); let Vec2 { x, y } = self.as_vector();
(x*x + y*y).into() (x*x + y*y).into()
} }
pub fn distance_sq(&self, pt: Point) -> Flt { pub fn distance_sq(&self, pt: Vec2) -> Flt {
// source: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points // source: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points
let d = self.as_vector(); let d = self.as_vector();
let twice_area = d.y*pt.x - d.x*pt.y + self.to.x*self.from.y - self.to.y*self.from.x; let twice_area = d.y*pt.x - d.x*pt.y + self.to.x*self.from.y - self.to.y*self.from.x;
@@ -112,7 +112,7 @@ impl Line {
} }
} }
pub fn clamp_by_x(&self, x: Flt) -> Point { pub fn clamp_by_x(&self, x: Flt) -> Vec2 {
self.at_x(self.clamp_x(x)) self.at_x(self.clamp_x(x))
} }
@@ -129,7 +129,7 @@ impl Line {
(real(start_x) + delta_x).into() (real(start_x) + delta_x).into()
} }
pub fn shifted(&self, p: Point) -> Line { pub fn shifted(&self, p: Vec2) -> Line {
Line { Line {
from: self.from + p, from: self.from + p,
to: self.to + p to: self.to + p
@@ -139,11 +139,11 @@ impl Line {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Polygon { pub struct Polygon {
points: Vec<Point>, points: Vec<Vec2>,
} }
impl Polygon { impl Polygon {
pub fn new(points: Vec<Point>) -> Self { pub fn new(points: Vec<Vec2>) -> Self {
Self { Self {
points points
} }
@@ -175,16 +175,16 @@ impl Polygon {
} }
pub trait Region { pub trait Region {
fn contains(&self, p: Point) -> bool; fn contains(&self, p: Vec2) -> bool;
} }
pub struct Circle { pub struct Circle {
center: Point, center: Vec2,
radius: Real, radius: Real,
} }
impl Circle { impl Circle {
pub fn new(center: Point, radius: Flt) -> Self { pub fn new(center: Vec2, radius: Flt) -> Self {
Self { Self {
center, center,
radius: radius.into() radius: radius.into()
@@ -193,7 +193,7 @@ impl Circle {
} }
impl Region for Circle { impl Region for Circle {
fn contains(&self, p: Point) -> bool { fn contains(&self, p: Vec2) -> bool {
p.distance_sq(self.center) <= (self.radius * self.radius).into() p.distance_sq(self.center) <= (self.radius * self.radius).into()
} }
} }

View File

@@ -1,6 +1,6 @@
use crate::{CellState, consts}; use crate::{CellState, consts};
use crate::flt::{Flt, Real}; use crate::flt::{Flt, Real};
use crate::geom::{Line, Point, Polygon}; use crate::geom::{Line, Vec2, Polygon};
use crate::vec::Vec3; use crate::vec::Vec3;
use log::{debug, trace}; use log::{debug, trace};
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
@@ -60,8 +60,8 @@ struct MHCurve {
impl MHCurve { impl MHCurve {
/// Construct a M(H) curve from a sweep from M = 0 to Ms and back down to M = 0. /// Construct a M(H) curve from a sweep from M = 0 to Ms and back down to M = 0.
/// The curve below M = 0 is derived by symmetry. /// The curve below M = 0 is derived by symmetry.
pub fn new(points: &[Point]) -> Self { pub fn new(points: &[Vec2]) -> Self {
let full_pts: Vec<Point> = points.iter().cloned().chain(points.iter().cloned().map(|p| -p)).collect(); let full_pts: Vec<Vec2> = points.iter().cloned().chain(points.iter().cloned().map(|p| -p)).collect();
Self { Self {
geom: Polygon::new(full_pts) geom: Polygon::new(full_pts)
@@ -87,20 +87,20 @@ impl MHCurve {
panic!("failed to find segment for h:{}, m:{}, {:?}", h, m, self.geom.segments().collect::<Vec<_>>()); panic!("failed to find segment for h:{}, m:{}, {:?}", h, m, self.geom.segments().collect::<Vec<_>>());
}); });
if line.contains_y(m.into()) && line.is_ascending() == is_ascending { if line.contains_y(m.into()) && line.is_ascending() == is_ascending {
if line.contains_x(h.into()) && line.distance_sq(Point::new(h.into(), m.into())) < 1.0e-6 { if line.contains_x(h.into()) && line.distance_sq(Vec2::new(h.into(), m.into())) < 1.0e-6 {
// (h, m) resides on this line // (h, m) resides on this line
break line; break line;
} else { } else {
// need to move the point toward this line // need to move the point toward this line
let h_intercept = line.x(m.into()); let h_intercept = line.x(m.into());
break Line::new(Point::new(h.into(), m.into()), Point::new(h_intercept.into(), m.into())); break Line::new(Vec2::new(h.into(), m.into()), Vec2::new(h_intercept.into(), m.into()));
} }
} }
}; };
trace!("active segment: {:?}", active_segment); trace!("active segment: {:?}", active_segment);
// Find some m(h) on the active_segment such that sum(h) = h + m(h) = target_hm // Find some m(h) on the active_segment such that sum(h) = h + m(h) = target_hm
let sum_h = active_segment + Line::new(Point::new(0.0, 0.0), Point::new(1.0, 1.0)); let sum_h = active_segment + Line::new(Vec2::new(0.0, 0.0), Vec2::new(1.0, 1.0));
trace!("sum_h: {:?}", sum_h); trace!("sum_h: {:?}", sum_h);
let new_h = if sum_h.to().y() != sum_h.from().y() { let new_h = if sum_h.to().y() != sum_h.from().y() {
sum_h.move_toward_y_unclamped(h.into(), target_hm.into()) sum_h.move_toward_y_unclamped(h.into(), target_hm.into())
@@ -153,10 +153,10 @@ pub struct PiecewiseLinearFerromagnet {
impl PiecewiseLinearFerromagnet { impl PiecewiseLinearFerromagnet {
/// Construct a B(H) curve from a sweep from H = 0 to Hs and back down to H = 0. /// Construct a B(H) curve from a sweep from H = 0 to Hs and back down to H = 0.
/// The curve below B = 0 is derived by symmetry. /// The curve below B = 0 is derived by symmetry.
/// Points are (H, B). /// Vec2s are (H, B).
pub fn from_bh(points: &[(Flt, Flt)]) -> Self { pub fn from_bh(points: &[(Flt, Flt)]) -> Self {
let mh_points: Vec<Point> = points.iter().cloned().map(|(h, b)| { let mh_points: Vec<Vec2> = points.iter().cloned().map(|(h, b)| {
Point::new(h, b / consts::MU0 - h) Vec2::new(h, b / consts::MU0 - h)
}).collect(); }).collect();
Self { Self {
@@ -238,17 +238,17 @@ mod test {
fn mh_curve_for_test() -> MHCurve { fn mh_curve_for_test() -> MHCurve {
MHCurve::new(&[ MHCurve::new(&[
// rising // rising
Point::new( 10.0, 0.0), Vec2::new( 10.0, 0.0),
Point::new( 20.0, 100.0), Vec2::new( 20.0, 100.0),
Point::new( 30.0, 150.0), Vec2::new( 30.0, 150.0),
// falling // falling
Point::new( 0.0, 120.0), Vec2::new( 0.0, 120.0),
// negative rising // negative rising
Point::new(-10.0, 0.0), Vec2::new(-10.0, 0.0),
Point::new(-20.0, -100.0), Vec2::new(-20.0, -100.0),
Point::new(-30.0, -150.0), Vec2::new(-30.0, -150.0),
// negative falling // negative falling
Point::new( 0.0, -120.0), Vec2::new( 0.0, -120.0),
]) ])
} }

View File

@@ -1,5 +1,5 @@
use crate::coord::Coord; use crate::coord::Coord;
use crate::geom::{Point, Region}; use crate::geom::{Vec2, Region};
use crate::mat::Material as _; use crate::mat::Material as _;
use crate::sim::{Cell, GenericSim}; use crate::sim::{Cell, GenericSim};
use std::fmt::Display; use std::fmt::Display;
@@ -41,7 +41,7 @@ impl AbstractMeasurement for Label {
fn sum_over_region<T: Default + Sum<T>, R: Region, F: Fn(Coord, &Cell) -> T>(state: &dyn GenericSim, r: &R, f: F) -> T { fn sum_over_region<T: Default + Sum<T>, R: Region, F: Fn(Coord, &Cell) -> T>(state: &dyn GenericSim, r: &R, f: F) -> T {
// TODO: z coordinate? // TODO: z coordinate?
state.map_sum_enumerated(|coord, cell| if r.contains(Point::new(coord.x().into(), coord.y().into())*state.feature_size()) { state.map_sum_enumerated(|coord, cell| if r.contains(Vec2::new(coord.x().into(), coord.y().into())*state.feature_size()) {
f(coord, cell) f(coord, cell)
} else { } else {
Default::default() Default::default()

View File

@@ -1,5 +1,5 @@
use ansi_term::Color::RGB; use ansi_term::Color::RGB;
use crate::geom::Point; use crate::geom::Vec2;
use crate::{flt::{Flt, Real}, Material as _}; use crate::{flt::{Flt, Real}, Material as _};
use crate::mat; use crate::mat;
use crate::sim::{Cell, GenericSim}; use crate::sim::{Cell, GenericSim};
@@ -48,7 +48,7 @@ fn scale_unsigned_to_u8(x: Flt, typ: Flt) -> u8 {
} }
/// Scale a vector to have magnitude between [0, 1). /// Scale a vector to have magnitude between [0, 1).
fn scale_vector(x: Point, typical_mag: Flt) -> Point { fn scale_vector(x: Vec2, typical_mag: Flt) -> Vec2 {
let new_mag = scale_unsigned(x.mag(), typical_mag); let new_mag = scale_unsigned(x.mag(), typical_mag);
x.with_mag(new_mag) x.with_mag(new_mag)
} }
@@ -112,7 +112,7 @@ impl<'a> RenderSteps<'a> {
self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 1.0e-9, |cell| cell.b().xy()); self.render_vector_field(Rgb([0xff, 0xff, 0xff]), 1.0e-9, |cell| cell.b().xy());
} }
fn render_vector_field<F: Fn(&Cell<mat::Static>) -> Point>(&mut self, color: Rgb<u8>, typical: Flt, measure: F) { fn render_vector_field<F: Fn(&Cell<mat::Static>) -> Vec2>(&mut self, color: Rgb<u8>, typical: Flt, measure: F) {
let w = self.im.width(); let w = self.im.width();
let h = self.im.height(); let h = self.im.height();
let vec_spacing = 10; let vec_spacing = 10;
@@ -123,7 +123,7 @@ impl<'a> RenderSteps<'a> {
let norm_vec = scale_vector(vec, typical); let norm_vec = scale_vector(vec, typical);
let alpha = 0.7*scale_unsigned(vec.mag_sq(), typical * 5.0); let alpha = 0.7*scale_unsigned(vec.mag_sq(), typical * 5.0);
let vec = norm_vec * (vec_spacing as Flt); let vec = norm_vec * (vec_spacing as Flt);
let center = Point::new(x as _, y as _) + Point::new(vec_spacing as _, vec_spacing as _)*0.5; let center = Vec2::new(x as _, y as _) + Vec2::new(vec_spacing as _, vec_spacing as _)*0.5;
self.im.draw_field_arrow(center, vec, color, alpha as f32); self.im.draw_field_arrow(center, vec, color, alpha as f32);
} }
} }
@@ -169,8 +169,8 @@ impl<'a> RenderSteps<'a> {
} }
} }
fn field_vector<F: Fn(&Cell<mat::Static>) -> Point>(&self, xidx: u32, yidx: u32, size: u32, measure: &F) -> Point { fn field_vector<F: Fn(&Cell<mat::Static>) -> Vec2>(&self, xidx: u32, yidx: u32, size: u32, measure: &F) -> Vec2 {
let mut field = Point::default(); let mut field = Vec2::default();
let w = self.im.width(); let w = self.im.width();
let h = self.im.height(); let h = self.im.height();
let xstart = xidx.min(w); let xstart = xidx.min(w);
@@ -186,7 +186,7 @@ impl<'a> RenderSteps<'a> {
let yw = yend - ystart; let yw = yend - ystart;
if xw == 0 || yw == 0 { if xw == 0 || yw == 0 {
// avoid division by zero // avoid division by zero
Point::new(0.0, 0.0) Vec2::new(0.0, 0.0)
} else { } else {
field * (1.0 / ((xw*yw) as Flt)) field * (1.0 / ((xw*yw) as Flt))
} }
@@ -194,11 +194,11 @@ impl<'a> RenderSteps<'a> {
} }
trait ImageRenderExt { trait ImageRenderExt {
fn draw_field_arrow(&mut self, center: Point, rel: Point, color: Rgb<u8>, alpha: f32); fn draw_field_arrow(&mut self, center: Vec2, rel: Vec2, color: Rgb<u8>, alpha: f32);
} }
impl ImageRenderExt for RgbImage { impl ImageRenderExt for RgbImage {
fn draw_field_arrow(&mut self, center: Point, rel: Point, color: Rgb<u8>, alpha: f32) { fn draw_field_arrow(&mut self, center: Vec2, rel: Vec2, color: Rgb<u8>, alpha: f32) {
let start = (center - rel * 0.5).round(); let start = (center - rel * 0.5).round();
let end = (center + rel * 0.5).round(); let end = (center + rel * 0.5).round();
let i_start = (start.x() as _, start.y() as _); let i_start = (start.x() as _, start.y() as _);

View File

@@ -8,67 +8,67 @@ fn round(f: Real) -> Real {
} }
#[derive(Copy, Clone, Debug, Default)] #[derive(Copy, Clone, Debug, Default)]
pub struct Point { pub struct Vec2 {
pub x: Real, pub x: Real,
pub y: Real, pub y: Real,
} }
impl Add for Point { impl Add for Vec2 {
type Output = Point; type Output = Vec2;
fn add(self, other: Point) -> Point { fn add(self, other: Vec2) -> Vec2 {
let mut ret = self.clone(); let mut ret = self.clone();
ret += other; ret += other;
ret ret
} }
} }
impl AddAssign for Point { impl AddAssign for Vec2 {
fn add_assign(&mut self, other: Point) { fn add_assign(&mut self, other: Vec2) {
self.x += other.x; self.x += other.x;
self.y += other.y; self.y += other.y;
} }
} }
impl Neg for Point { impl Neg for Vec2 {
type Output = Point; type Output = Vec2;
fn neg(self) -> Point { fn neg(self) -> Vec2 {
Point { Vec2 {
x: -self.x, x: -self.x,
y: -self.y, y: -self.y,
} }
} }
} }
impl Sub for Point { impl Sub for Vec2 {
type Output = Point; type Output = Vec2;
fn sub(self, other: Point) -> Point { fn sub(self, other: Vec2) -> Vec2 {
self + (-other) self + (-other)
} }
} }
impl Mul<Flt> for Point { impl Mul<Flt> for Vec2 {
type Output = Point; type Output = Vec2;
fn mul(self, s: Flt) -> Point { fn mul(self, s: Flt) -> Vec2 {
Point { Vec2 {
x: self.x * s, x: self.x * s,
y: self.y * s, y: self.y * s,
} }
} }
} }
impl Into<(Flt, Flt)> for Point { impl Into<(Flt, Flt)> for Vec2 {
fn into(self) -> (Flt, Flt) { fn into(self) -> (Flt, Flt) {
(self.x(), self.y()) (self.x(), self.y())
} }
} }
impl Into<(Real, Real)> for Point { impl Into<(Real, Real)> for Vec2 {
fn into(self) -> (Real, Real) { fn into(self) -> (Real, Real) {
(self.x, self.y) (self.x, self.y)
} }
} }
impl Point { impl Vec2 {
pub fn new(x: Flt, y: Flt) -> Self { pub fn new(x: Flt, y: Flt) -> Self {
Self { Self {
x: x.into(), x: x.into(),
@@ -84,8 +84,8 @@ impl Point {
self.y.into() self.y.into()
} }
pub fn round(&self) -> Point { pub fn round(&self) -> Vec2 {
Point { Vec2 {
x: round(self.x), x: round(self.x),
y: round(self.y), y: round(self.y),
} }
@@ -103,10 +103,10 @@ impl Point {
self.mag_sq().sqrt() self.mag_sq().sqrt()
} }
pub fn with_mag(&self, new_mag: Flt) -> Point { pub fn with_mag(&self, new_mag: Flt) -> Vec2 {
if new_mag == 0.0 { if new_mag == 0.0 {
// avoid div-by-zero if self.mag() == 0 and new_mag == 0 // avoid div-by-zero if self.mag() == 0 and new_mag == 0
Point::new(0.0, 0.0) Vec2::new(0.0, 0.0)
} else { } else {
let scale = Real::from_inner(new_mag) / self.mag(); let scale = Real::from_inner(new_mag) / self.mag();
self.clone() * scale.into_inner() self.clone() * scale.into_inner()
@@ -144,8 +144,8 @@ impl Vec3 {
pub fn z(&self) -> Flt { pub fn z(&self) -> Flt {
self.z.into() self.z.into()
} }
pub fn xy(&self) -> Point { pub fn xy(&self) -> Vec2 {
Point::new(self.x(), self.y()) Vec2::new(self.x(), self.y())
} }
pub fn mag(&self) -> Flt { pub fn mag(&self) -> Flt {
let Vec3 { x, y, z } = *self; let Vec3 { x, y, z } = *self;