84 lines
2.0 KiB
Python
84 lines
2.0 KiB
Python
"""
|
|
Plane module
|
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|
Copyright © 2022 Concordia CERC group
|
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|
"""
|
|
|
|
from typing import TypeVar
|
|
import numpy as np
|
|
|
|
Point = TypeVar('Point')
|
|
|
|
|
|
class Plane:
|
|
"""
|
|
Plane class
|
|
"""
|
|
|
|
def __init__(self, origin, normal):
|
|
# todo: other options to define the plane:
|
|
# by two lines
|
|
# by three points
|
|
self._origin = origin
|
|
self._normal = normal
|
|
self._equation = None
|
|
self._opposite_normal = None
|
|
|
|
@property
|
|
def origin(self) -> Point:
|
|
"""
|
|
Get plane origin point
|
|
:return: Point
|
|
"""
|
|
return self._origin
|
|
|
|
@property
|
|
def normal(self):
|
|
"""
|
|
Get plane normal [x, y, z]
|
|
:return: np.ndarray
|
|
"""
|
|
return self._normal
|
|
|
|
@property
|
|
def equation(self) -> (float, float, float, float):
|
|
"""
|
|
Get the plane equation components Ax + By + Cz + D = 0
|
|
:return: (A, B, C, D)
|
|
"""
|
|
if self._equation is None:
|
|
|
|
a = self.normal[0]
|
|
b = self.normal[1]
|
|
c = self.normal[2]
|
|
d = ((-1 * self.origin.coordinates[0]) * self.normal[0])
|
|
d += ((-1 * self.origin.coordinates[1]) * self.normal[1])
|
|
d += ((-1 * self.origin.coordinates[2]) * self.normal[2])
|
|
self._equation = (a, b, c, d)
|
|
return self._equation
|
|
|
|
def distance(self, point):
|
|
"""
|
|
Distance between the given point and the plane
|
|
:return: float
|
|
"""
|
|
p = point
|
|
e = self.equation
|
|
denominator = np.abs((p[0] * e[0]) + (p[1] * e[1]) + (p[2] * e[2]) + e[3])
|
|
numerator = np.sqrt((e[0]**2) + (e[1]**2) + (e[2]**2))
|
|
return float(denominator / numerator)
|
|
|
|
@property
|
|
def opposite_normal(self):
|
|
"""
|
|
get plane normal in the opposite direction [x, y, z]
|
|
:return: np.ndarray
|
|
"""
|
|
if self._opposite_normal is None:
|
|
coordinates = []
|
|
for coordinate in self.normal:
|
|
coordinates.append(-coordinate)
|
|
self._opposite_normal = np.array(coordinates)
|
|
return self._opposite_normal
|