nphysics2d/algebra/
force2.rs1use na::storage::Storage;
2use na::{self, Isometry2, Point2, RealField, Vector, Vector1, Vector2, Vector3, U3};
3use std::mem;
4use std::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign};
5
6#[repr(C)]
8#[derive(Copy, Clone, Debug)]
9pub struct Force2<N: RealField + Copy> {
10 pub linear: Vector2<N>,
12 pub angular: N,
14}
15
16impl<N: RealField + Copy> Force2<N> {
17 #[inline]
19 pub fn new(linear: Vector2<N>, angular: N) -> Self {
20 Force2 { linear, angular }
21 }
22
23 #[inline]
25 pub fn zero() -> Self {
26 Self::new(na::zero(), N::zero())
27 }
28
29 #[inline]
31 pub fn from_slice(data: &[N]) -> Self {
32 Self::new(Vector2::new(data[0], data[1]), data[2])
33 }
34
35 #[inline]
37 pub fn from_vector<S: Storage<N, U3>>(data: &Vector<N, U3, S>) -> Self {
38 Self::new(Vector2::new(data[0], data[1]), data[2])
39 }
40
41 #[inline]
43 pub fn from_vectors(linear: Vector2<N>, angular: Vector1<N>) -> Self {
44 Self {
45 linear,
46 angular: angular.x,
47 }
48 }
49
50 #[inline]
52 pub fn torque(torque: N) -> Self {
53 Self::new(na::zero(), torque)
54 }
55
56 #[inline]
58 pub fn torque_from_vector(torque: Vector1<N>) -> Self {
59 Self::new(na::zero(), torque.x)
60 }
61
62 #[inline]
64 pub fn linear(linear: Vector2<N>) -> Self {
65 Self::new(linear, na::zero())
66 }
67
68 #[inline]
70 pub fn linear_at_point(linear: Vector2<N>, point: &Point2<N>) -> Self {
71 Self::new(linear, point.coords.perp(&linear))
72 }
73
74 #[inline]
76 pub fn torque_at_point(torque: N, point: &Point2<N>) -> Self {
77 Self::new(point.coords * -torque, torque)
78 }
79
80 #[inline]
82 pub fn torque_from_vector_at_point(torque: Vector1<N>, point: &Point2<N>) -> Self {
83 Self::torque_at_point(torque.x, point)
84 }
85
86 #[inline]
88 pub fn angular_vector(&self) -> Vector1<N> {
89 Vector1::new(self.angular)
90 }
91
92 #[inline]
94 pub fn transform_by(&self, m: &Isometry2<N>) -> Self {
95 Self::new(m * self.linear, self.angular)
96 }
97
98 #[inline]
102 pub fn as_slice(&self) -> &[N] {
103 self.as_vector().as_slice()
104 }
105
106 #[inline]
110 pub fn as_vector(&self) -> &Vector3<N> {
111 unsafe { mem::transmute(self) }
112 }
113
114 #[inline]
118 pub fn as_vector_mut(&mut self) -> &mut Vector3<N> {
119 unsafe { mem::transmute(self) }
120 }
121}
122
123impl<N: RealField + Copy> Add<Force2<N>> for Force2<N> {
124 type Output = Self;
125
126 #[inline]
127 fn add(self, rhs: Self) -> Self {
128 Force2::new(self.linear + rhs.linear, self.angular + rhs.angular)
129 }
130}
131
132impl<N: RealField + Copy> AddAssign<Force2<N>> for Force2<N> {
133 #[inline]
134 fn add_assign(&mut self, rhs: Self) {
135 self.linear += rhs.linear;
136 self.angular += rhs.angular;
137 }
138}
139
140impl<N: RealField + Copy> Sub<Force2<N>> for Force2<N> {
141 type Output = Self;
142
143 #[inline]
144 fn sub(self, rhs: Self) -> Self {
145 Force2::new(self.linear - rhs.linear, self.angular - rhs.angular)
146 }
147}
148
149impl<N: RealField + Copy> SubAssign<Force2<N>> for Force2<N> {
150 #[inline]
151 fn sub_assign(&mut self, rhs: Self) {
152 self.linear -= rhs.linear;
153 self.angular -= rhs.angular;
154 }
155}
156
157impl<N: RealField + Copy> Mul<N> for Force2<N> {
158 type Output = Self;
159
160 #[inline]
161 fn mul(self, rhs: N) -> Self {
162 Force2::new(self.linear * rhs, self.angular * rhs)
163 }
164}
165
166impl<N: RealField + Copy> Neg for Force2<N> {
167 type Output = Self;
168
169 #[inline]
170 fn neg(self) -> Self {
171 Force2::new(-self.linear, -self.angular)
172 }
173}