+////////// add point to point //////////////////////////////////////////////////
+impl<T: Add<Output = T>> Add for Point2D<T> {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self {
+ x: self.x + rhs.x,
+ y: self.y + rhs.y,
+ }
+ }
+}
+
+impl<T: Add<Output = T> + Copy> AddAssign for Point2D<T> {
+ fn add_assign(&mut self, rhs: Self) {
+ *self = Self {
+ x: self.x + rhs.x,
+ y: self.y + rhs.y,
+ }
+ }
+}
+
+////////// add tuple to point //////////////////////////////////////////////////
+impl<T: Add<Output = T>> Add<(T, T)> for Point2D<T> {
+ type Output = Self;
+
+ fn add(self, rhs: (T, T)) -> Self {
+ Self {
+ x: self.x + rhs.0,
+ y: self.y + rhs.1,
+ }
+ }
+}
+
+////////// subtract point from point ///////////////////////////////////////////
+impl<T: Sub<Output = T>> Sub for Point2D<T> {
+ type Output = Self;
+
+ fn sub(self, rhs: Self) -> Self {
+ Self {
+ x: self.x - rhs.x,
+ y: self.y - rhs.y,
+ }
+ }
+}
+
+impl<T: Sub<Output = T> + Copy> SubAssign for Point2D<T> {
+ fn sub_assign(&mut self, rhs: Self) {
+ *self = Self {
+ x: self.x - rhs.x,
+ y: self.y - rhs.y,
+ }
+ }
+}
+
+////////// multiply point with scalar //////////////////////////////////////////
+impl<T: Mul<Output = T> + Copy> Mul<T> for Point2D<T> {
+ type Output = Self;
+
+ fn mul(self, rhs: T) -> Self {
+ Self {
+ x: self.x * rhs,
+ y: self.y * rhs,
+ }
+ }
+}
+
+impl<T: Mul<Output = T> + Copy> MulAssign<T> for Point2D<T> {
+ fn mul_assign(&mut self, rhs: T) {
+ *self = Self {
+ x: self.x * rhs,
+ y: self.y * rhs,
+ }
+ }
+}
+
+////////// multiply components of two points ///////////////////////////////////
+impl<T: Mul<Output = T>> Mul for Point2D<T> {
+ type Output = Self;
+
+ fn mul(self, rhs: Self) -> Self {
+ Self {
+ x: self.x * rhs.x,
+ y: self.y * rhs.y,
+ }
+ }
+}
+
+impl<T: Mul<Output = T> + Copy> MulAssign for Point2D<T> {
+ fn mul_assign(&mut self, rhs: Self) {
+ *self = Self {
+ x: self.x * rhs.x,
+ y: self.y * rhs.y,
+ }
+ }
+}
+
+////////// divide point with scalar ////////////////////////////////////////////
+impl<T: Div<Output = T> + Copy> Div<T> for Point2D<T> {
+ type Output = Self;
+
+ fn div(self, rhs: T) -> Self {
+ Self {
+ x: self.x / rhs,
+ y: self.y / rhs,
+ }
+ }
+}
+
+impl<T: Div<Output = T> + Copy> DivAssign<T> for Point2D<T> {
+ fn div_assign(&mut self, rhs: T) {
+ *self = Self {
+ x: self.x / rhs,
+ y: self.y / rhs,
+ }
+ }
+}
+
+////////// divide components of two points /////////////////////////////////////
+impl<T: Div<Output = T>> Div for Point2D<T> {
+ type Output = Self;
+
+ fn div(self, rhs: Self) -> Self {
+ Self {
+ x: self.x / rhs.x,
+ y: self.y / rhs.y,
+ }
+ }
+}
+
+impl<T: Div<Output = T> + Copy> DivAssign for Point2D<T> {
+ fn div_assign(&mut self, rhs: Self) {
+ *self = Self {
+ x: self.x / rhs.x,
+ y: self.y / rhs.y,
+ }
+ }
+}
+
+impl<T: Neg<Output = T>> Neg for Point2D<T> {
+ type Output = Self;