Source code for octadist.src.linear

# OctaDist  Copyright (C) 2019-2024  Rangsiman Ketkaew et al.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

import numpy as np
from math import sqrt, pow, degrees, acos


[docs] def angle_sign(v1, v2, direct): """ Compute angle between two vectors with sign and return value in degree. Parameters ---------- v1 : array_like Vector in 3D space. v2 : array_like Vector in 3D space. direct : array Vector that refers to orientation of the plane. Returns ------- angle : float64 Angle between two vectors in degree unit with sign. See Also -------- calc.calc_theta : Calculate theta parameter. Examples -------- >>> vector1 = [1.21859514, -0.92569245, -0.51717955] >>> vector2 = [1.02186387, 0.57480095, -0.95220433] >>> direction = [1.29280503, 0.69301873, 1.80572438] >>> angle_sign(vector1, vector2, direction) 60.38697927455357 """ v1 = np.asarray(v1, dtype=np.float64) v2 = np.asarray(v2, dtype=np.float64) v1 = v1 / np.linalg.norm(v1) v2 = v2 / np.linalg.norm(v2) angle = np.degrees(np.arccos(np.clip(np.dot(v1, v2), -1.0, 1.0))) matrix = np.array([v1, v2, direct], dtype=np.float64) det = np.float64(np.linalg.det(matrix)) if det < 0: angle = angle * -1 return angle
[docs] def angle_btw_vectors(v1, v2): """ Compute angle between two vectors and return value in degree. Parameters ---------- v1 : array_like Vector in 3D space. v2 : array_like Vector in 3D space. Returns ------- angle : float64 Angle between two vectors in degree unit. Examples -------- >>> vector1 = [-0.412697, -0.357008, -1.788172] >>> vector2 = [-0.550839, 1.799178, -0.039114] >>> angle_btw_vectors(vector1, vector2) 95.62773246517462 """ v1 = np.asarray(v1, dtype=np.float64) v2 = np.asarray(v2, dtype=np.float64) v1 = v1 / np.linalg.norm(v1) v2 = v2 / np.linalg.norm(v2) angle = np.degrees(np.arccos(np.clip(np.dot(v1, v2), -1.0, 1.0)), dtype=np.float64) return angle
[docs] def angle_btw_planes(a1, b1, c1, a2, b2, c2): """ Find the angle between 2 planes in 3D and return value in degree. :: General equation of plane: a*X + b*Y + c*Z + d = 0 Parameters ---------- a1, b1, c1 : float Coefficient of the equation of plane 1. a2, b2, c2 : float Coefficient of the equation of plane 2. Returns ------- angle : float64 Angle between 2 planes in degree unit. Examples -------- >>> # Plane 1 >>> a1 = -3.231203733528 >>> b1 = -0.9688526458499996 >>> c1 = 0.9391692927779998 >>> # Plane 2 >>> a2 = 1.3904813057000005 >>> b2 = 3.928502357473003 >>> c2 = -4.924114034864001 >>> angle_btw_planes(a1, b1, c1, a2, b2, c2) 124.89920902358416 """ d = a1 * a2 + b1 * b2 + c1 * c2 e1 = sqrt(a1 * a1 + b1 * b1 + c1 * c1) e2 = sqrt(a2 * a2 + b2 * b2 + c2 * c2) d = d / (e1 * e2) angle = np.float64(degrees(acos(d))) return angle
[docs] def triangle_area(a, b, c): """ Calculate the area of the triangle using the cross product: :: Area = abs(ab X ac)/2 where vector ab = b - a and vector ac = c - a. Parameters ---------- a : array_like 3D Coordinate of point. b : array_like 3D Coordinate of point. c : array_like 3D Coordinate of point. Returns ------- area : float64 The triangle area. Examples -------- >>> # Three vertices >>> a = [2.298354000, 5.161785000, 7.971898000] >>> b = [1.885657000, 4.804777000, 6.183726000] >>> c = [1.747515000, 6.960963000, 7.932784000] >>> triangle_area(a, b, c) 1.7508135235821773 """ a = np.asarray(a, dtype=np.float64) b = np.asarray(b, dtype=np.float64) c = np.asarray(c, dtype=np.float64) ab = b - a ac = c - a value = ( pow(np.dot(ab[1], ac[2]) - np.dot(ab[2], ac[1]), 2) + pow(np.dot(ab[2], ac[0]) - np.dot(ab[0], ac[2]), 2) + pow(np.dot(ab[0], ac[1]) - np.dot(ab[1], ac[0]), 2) ) area = np.float64(sqrt(value) / 2) return area