"""mesh building block - Edge class definition"""
import os
from typing import Any, Union, Tuple
if os.environ.get('__USE_CUDA', '0') == '1':
import cupy as np
from cupy import ndarray, float64
from cupyx.scipy.interpolate import make_interp_spline
from cupyx.scipy.interpolate import BSpline
else:
import numpy as np
from numpy import ndarray, float64
from scipy.interpolate import make_interp_spline
from scipy.interpolate import BSpline
from g3d.defs import G3DWorld
from g3d.defs import AngleType
from g3d.defs import Axis
from g3d.defs import Direction
from g3d.defs import Position
from g3d.defs import NodeDistribution
from g3d.defs import FunctionByPass
from g3d.mesh.geo import Coordinates
from g3d.mesh.geo import Coord
from g3d.mesh.tools import rotate
[docs]
class Edge(Coordinates):
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.__nodes_distributed = False
self.__start = Coord(tag='start')
self.__end = Coord(tag='end')
self.__origo = Coord(tag='origo')
self._distribute = NodeDistribution.UNDEFINED
self._stretch_rate = 'default'
self._ialt = AngleType.UNDEFINED
self._alpha = 0.
self._beta = 0.
self._direction = Direction.UNDEFINED
self._axis = Axis.UNDEFINED
self._data = None
self._angle_dim = AngleType.DEGREES
self._tolerance = 1.e-10
self._applied = False
self._i0 = 0
self._j0 = 0
self._k0 = 0
self._idir = 0
self._npi = 0
super().__init__(*args, **kwargs)
self.__init_Edge()
def _set_default(self) -> None:
self.__reset_def()
super()._set_default()
self._tag = 'g3d_edge'
def _set_from_args(self, *args: Any, **kwargs: Any) -> ndarray:
bps = self._get_function_evaluate_status(**kwargs)
if bps is FunctionByPass.SELF:
args_stat = np.ones(len(args))
else:
args_stat = super()._set_from_args(*args, bps=FunctionByPass.BYPASS)
if bps in [FunctionByPass.EVALUATE, FunctionByPass.SELF]:
if np.sum(args_stat) > 0:
n_int = 0
for arg in args:
if type(arg) in [int, np.int64, np.int32]:
n_int += 1
edge_def = []
start_coordinate_is_defined = False
for i in range(len(args)):
if args_stat[i] == 1:
arg = args[i]
if type(arg) in [int, np.int64, np.int32]:
args_stat[i] = 0
if n_int == 1:
if type(arg) in [np.int64, np.int32]:
self._npi = arg.item()
else:
self._npi = arg
else:
edge_def.append(arg)
elif type(arg) is Coord:
args_stat[i] = 0
if start_coordinate_is_defined:
self.__end = Coord(arg, copy_settings=True)
else:
self.__start = Coord(arg, copy_settings=True)
start_coordinate_is_defined = True
elif type(arg) is Edge:
# if caught by a super class, the child class instance of copy will be used
args_stat[i] = 0
self.copy(arg)
self.__nodes_distributed = True
elif type(arg) is list:
args_stat[i] = 0
if self._list_is_all_ints(arg) and len(arg) == 5:
self._i0, self._j0, self._k0, self._idir, self._npi = arg
if len(edge_def) == 5:
# will be caught by the for-loop below in a sub call to _set_from_args
self._set_from_args(edge_def, bps=FunctionByPass.SELF)
return args_stat
def __reset_def(self) -> None:
self._i0 = 0
self._j0 = 0
self._k0 = 0
self._idir = 0
self._npi = 0
[docs]
def copy_settings(self, e: 'Edge') -> None:
"""
:param e:
"""
super().copy(e)
self._distribute = e.distribute
self._stretch_rate = e.stretch_rate
self._ialt = e.ialt
self._alpha = e.alpha
self._beta = e.beta
self._direction = e.direction
self._axis = e.axis
self._data = e.data
self._angle_dim = e.angle_dim
self._tolerance = e.tolerance
def __init_Edge(self) -> None:
if not self.__nodes_distributed:
if self._size != self._npi:
self.allocate_XYZ()
self.distribute_nodes()
[docs]
def set_from_key_value(self, key: str, value: Any) -> bool:
if super().set_from_key_value(key, value):
return True
elif key == 'start':
self.__start = Coord(value, copy_settings=True)
return True
elif key == 'end':
self.__end = Coord(value, copy_settings=True)
return True
elif key == 'origo':
self.__origo = Coord(value, copy_settings=True)
return True
elif key == 'distribute':
self._distribute = value
return True
elif key == 'stretch_rate':
self._stretch_rate = value
return True
elif key == 'data':
self._data = value
return True
elif key == 'direction':
self._direction = value
return True
elif key == 'axis':
self._axis = value
return True
elif key == 'angle_dim':
self._angle_dim = value
return True
elif key == 'ialt':
self._ialt = value
return True
elif key == 'alpha':
self._alpha = value
return True
elif key == 'beta':
self._beta = value
return True
elif key == 'x_shift':
self.shift(x_shift=value)
return True
elif key == 'y_shift':
self.shift(y_shift=value)
return True
elif key == 'z_shift':
self.shift(z_shift=value)
return True
elif key == 'x':
self.set_coordinates(x=value)
return True
elif key == 'y':
self.set_coordinates(y=value)
return True
elif key == 'z':
self.set_coordinates(z=value)
return True
elif key == 'tolerance':
self._tolerance = value
return True
return False
[docs]
def allocate_XYZ(self, N: int = None) -> None:
self._size = self._npi
super().allocate_XYZ(N)
[docs]
def define_Edge(self, e: Union[list[int], int]) -> None:
"""
:param e:
"""
if type(e) is list:
if len(e) == 5:
self._i0, self._j0, self._k0, self._idir, self._npi = e
elif type(e) is int:
self._npi = e
self._i0 = self._j0 = self._k0 = self._idir = 0
if self._size != self._npi:
self.allocate_XYZ()
@property
def applied(self) -> bool:
"""
:return:
"""
return self._applied
@applied.setter
def applied(self, b: bool) -> None:
self._applied = b
@property
def i0(self) -> int:
"""
:return:
"""
return self._i0
@i0.setter
def i0(self, i_val: int) -> None:
self._i0 = i_val
@property
def j0(self) -> int:
"""
:return:
"""
return self._j0
@j0.setter
def j0(self, i_val: int) -> None:
self._j0 = i_val
@property
def k0(self) -> int:
"""
:return:
"""
return self._k0
@k0.setter
def k0(self, i_val: int) -> None:
self._k0 = i_val
@property
def idir(self) -> int:
"""
:return:
"""
return self._idir
@idir.setter
def idir(self, i_val: int) -> None:
self._idir = i_val
@property
def npi(self) -> int:
"""
:return:
"""
return self._npi
@npi.setter
def npi(self, i_val: int) -> None:
self._npi = i_val
@property
def start(self) -> Coord:
"""
:return:
"""
return self.__start
@property
def end(self) -> Coord:
"""
:return:
"""
return self.__end
@property
def stretch_rate(self) -> Union[float, str]:
"""
:return:
"""
return self._stretch_rate
@stretch_rate.setter
def stretch_rate(self, val: Union[float, str]) -> None:
self._stretch_rate = val
@property
def direction(self) -> Any:
"""
:return:
"""
return self._direction
@direction.setter
def direction(self, val: Any) -> None:
if type(val) is Direction:
self._direction = val
@property
def axis(self) -> Any:
"""
:return:
"""
return self._axis
@axis.setter
def axis(self, val: Any) -> None:
if type(val) is Axis:
self._axis = val
@property
def angle_dim(self) -> Any:
"""
:return:
"""
return self._angle_dim
@angle_dim.setter
def angle_dim(self, val: Any) -> None:
if type(val) is AngleType:
self._angle_dim = val
@property
def ialt(self) -> Any:
"""
:return:
"""
return self._ialt
@ialt.setter
def ialt(self, val: Any) -> None:
if type(val) is AngleType:
self._ialt = val
@property
def alpha(self) -> float:
"""
:return:
"""
return self._alpha
@alpha.setter
def alpha(self, val: float) -> None:
self._alpha = val
@property
def beta(self) -> float:
"""
:return:
"""
return self._beta
@beta.setter
def beta(self, val: float) -> None:
self._beta = val
@property
def distribute(self) -> Any:
"""
:return:
"""
return self._distribute
@distribute.setter
def distribute(self, val: Any) -> None:
if type(val) is NodeDistribution:
self._distribute = val
@property
def data(self) -> Any:
"""
:return:
"""
return self._data
@data.setter
def data(self, val: Any) -> None:
self._data = val
@property
def tolerance(self) -> float:
"""
:return:
"""
return self._tolerance
@tolerance.setter
def tolerance(self, val: float) -> None:
self._tolerance = val
@property
def h0(self) -> float:
"""
:return:
"""
return self.get_spacing(position=Position.START)
@property
def h1(self) -> float:
"""
:return:
"""
return self.get_spacing(position=Position.END)
[docs]
def print(self) -> None:
super().print()
print('edge definition: [i0=%d, j0=%d, k0=%d, idir=%d, npi=%d]' %
(self._i0, self._j0, self._k0, self._idir, self._npi))
print('edge start coordinate: ')
self.__start.print()
print('edge end coordinate: ')
self.__end.print()
print('settings: ')
print(' angle dimension: %s' % self._angle_dim.name)
print(' node distribution: %s' % self._distribute.name)
if type(self._stretch_rate) is str:
print(' stretch rate: %s' % self._stretch_rate)
else:
print(' stretch rate: %f' % float(self._stretch_rate))
if self._direction.name != Direction.UNDEFINED:
print(' direction: %s' % self._direction.name)
if self._data is not None:
if len(self._data) != 0:
print(' data: %s' % str(self._data.size))
[docs]
def set_start_end_Coord(self, start: Union[Coord, list], end: Union[Coord, list]) -> None:
"""
:param start:
:param end:
"""
self.set_start_Coord(start)
self.set_end_Coord(end)
[docs]
def set_start_Coord(self, start: Union[Coord, list]) -> None:
"""
:param start:
"""
if start is not None:
self.__start = Coord(start, copy_settings=True)
if len(self._X) != 0:
self._X[0] = self.__start.x
self._Y[0] = self.__start.y
self._Z[0] = self.__start.z
[docs]
def set_end_Coord(self, end: Union[Coord, list]) -> None:
"""
:param end:
"""
if end is not None:
self.__end = Coord(end, copy_settings=True)
if len(self._X) != 0:
self._X[-1] = self.__end.x
self._Y[-1] = self.__end.y
self._Z[-1] = self.__end.z
[docs]
def update_start_Coord(self) -> None:
"""
"""
self.__start.x = self._X[0]
self.__start.y = self._Y[0]
self.__start.z = self._Z[0]
[docs]
def update_end_Coord(self) -> None:
"""
"""
self.__end.x = self._X[-1]
self.__end.y = self._Y[-1]
self.__end.z = self._Z[-1]
[docs]
def distribute_nodes(self) -> None:
"""
"""
if self._npi != 0 and self.__start is not None and self.__end is not None:
if self._size != self._npi:
self.allocate_XYZ()
self._X[0] = self.__start.x
self._Y[0] = self.__start.y
self._Z[0] = self.__start.z
self._X[-1] = self.__end.x
self._Y[-1] = self.__end.y
self._Z[-1] = self.__end.z
self.__distribute_nodes()
self.__nodes_distributed = True
[docs]
def re_distribute_nodes(self, **kwargs: Any) -> None:
"""
:param kwargs:
"""
if self._npi != 0 and self.__start is not None and self.__end is not None:
self.set(**kwargs)
if self._distribute == NodeDistribution.CURVE_1:
self._data = np.zeros(shape=(self._npi, 3))
for i in range(self._npi):
self._data[i, 0] = self._X[i]
self._data[i, 1] = self._Y[i]
self._data[i, 2] = self._Z[i]
self.__distribute_nodes()
[docs]
def copy(self, e: 'Edge') -> None:
if e.start is not None:
if self.__start is not None:
self.__start.copy(e.start, copy_settings=True)
else:
self.__start = Coord(e.start, copy_settings=True)
if e.end is not None:
if self.__end is not None:
self.__end.copy(e.end, copy_settings=True)
else:
self.__end = Coord(e.end, copy_settings=True)
self.copy_settings(e)
self.copy_def(e)
self.copy_XYZ(e)
self.__nodes_distributed = True
[docs]
def copy_def(self, e: 'Edge') -> None:
"""
:param e:
"""
self._i0, self._j0, self._k0, self._idir, self._npi = e.get_def()
[docs]
def get_def(self) -> Tuple[int, int, int, int, int]:
"""
:return:
"""
return self._i0, self._j0, self._k0, self._idir, self._npi
[docs]
def get_Coord(self, lp: int) -> Coord:
"""
:param lp:
:return:
"""
x, y, z = self.get_XYZ(lp)
c = Coord(x, y, z)
return c
[docs]
def append(self, e: 'Edge', **kwargs: Any) -> None:
"""
:param e:
:param kwargs:
"""
include_start_node = False
for key, value in kwargs.items():
if key == 'include_start_node':
include_start_node = value
npi_tmp = self._npi
X_tmp = np.zeros(npi_tmp)
Y_tmp = np.zeros(npi_tmp)
Z_tmp = np.zeros(npi_tmp)
for i in range(npi_tmp):
X_tmp[i] = self._X[i]
Y_tmp[i] = self._Y[i]
Z_tmp[i] = self._Z[i]
self._npi += e.npi - 1
if include_start_node:
self._npi += 1
self.allocate_XYZ()
for i in range(npi_tmp):
self._X[i] = X_tmp[i]
self._Y[i] = Y_tmp[i]
self._Z[i] = Z_tmp[i]
i1 = 1
if include_start_node:
i1 = 0
X_tmp, Y_tmp, Z_tmp = e.get_XYZ()
for i in range(i1, e.npi):
self._X[i + npi_tmp - i1] = X_tmp[i]
self._Y[i + npi_tmp - i1] = Y_tmp[i]
self._Z[i + npi_tmp - i1] = Z_tmp[i]
self.update_end_Coord()
[docs]
def prepend(self, e: 'Edge', **kwargs: Any) -> None:
"""
:param e:
:param kwargs:
"""
include_end_node = False
for key, value in kwargs.items():
if key == 'include_end_node':
include_end_node = value
npi_tmp = self._npi
X_tmp = np.zeros(npi_tmp)
Y_tmp = np.zeros(npi_tmp)
Z_tmp = np.zeros(npi_tmp)
for i in range(npi_tmp):
X_tmp[i] = self._X[i]
Y_tmp[i] = self._Y[i]
Z_tmp[i] = self._Z[i]
self._npi += e.npi - 1
if include_end_node:
self._npi += 1
self.allocate_XYZ()
i2 = e.npi - 1
if include_end_node:
i2 += 1
for i in range(npi_tmp):
self._X[i + i2] = X_tmp[i]
self._Y[i + i2] = Y_tmp[i]
self._Z[i + i2] = Z_tmp[i]
X_tmp, Y_tmp, Z_tmp = e.get_XYZ()
for i in range(i2):
self._X[i] = X_tmp[i]
self._Y[i] = Y_tmp[i]
self._Z[i] = Z_tmp[i]
self.update_start_Coord()
[docs]
def get_sub(self, **kwargs: Any) -> 'Edge':
"""
:param kwargs:
:return:
"""
i1 = 0
i2 = self._npi
for key, value in kwargs.items():
if key == 'first':
i1 = value - 1
elif key == 'last':
i2 = value
n = i2 - i1
e = Edge(n)
X_sub, Y_sub, Z_sub = e.get_XYZ()
for i in range(i1, i2):
X_sub[i - i1] = self._X[i]
Y_sub[i - i1] = self._Y[i]
Z_sub[i - i1] = self._Z[i]
e.update_start_Coord()
e.update_end_Coord()
return e
[docs]
def generate_offset_Edge(self, offset: float, in_plane_vector: ndarray = np.array([0, 0, 1])) -> 'Edge':
"""
:param offset:
:param in_plane_vector:
:return:
"""
x3 = in_plane_vector[0]
y3 = in_plane_vector[1]
z3 = in_plane_vector[2]
nx = np.zeros(self._npi)
ny = np.zeros(self._npi)
nz = np.zeros(self._npi)
e = Edge(self)
X_offset, Y_offset, Z_offset = e.get_XYZ()
for i in range(self._npi - 1):
x1 = self._X[i]
x2 = self._X[i + 1]
y1 = self._Y[i]
y2 = self._Y[i + 1]
z1 = self._Z[i]
z2 = self._Z[i + 1]
nx[i] += ((z2 - z1) * y3 - (y2 - y1) * z3)
ny[i] += ((x2 - x1) * z3 - (z2 - z1) * x3)
nz[i] += ((y2 - y1) * x3 - (x2 - x1) * y3)
nx[i + 1] += ((y1 - y2) * z3 - (z1 - z2) * y3)
ny[i + 1] += ((z1 - z2) * x3 - (x1 - x2) * z3)
nz[i + 1] += ((x1 - x2) * y3 - (y1 - y2) * x3)
for i in range(self._npi):
r = np.sqrt(nx[i] ** 2 + ny[i] ** 2 + nz[i] ** 2)
r = max(r, 1.e-20)
X_offset[i] = self._X[i] + offset * nx[i] / r
Y_offset[i] = self._Y[i] + offset * ny[i] / r
Z_offset[i] = self._Z[i] + offset * nz[i] / r
e.set_start_Coord([X_offset[0], Y_offset[0], Z_offset[0]])
e.set_end_Coord([X_offset[-1], Y_offset[-1], Z_offset[-1]])
return e
[docs]
def rotate(self, **kwargs: Any) -> None:
"""
:param kwargs:
:return:
"""
alpha = 0.
beta = 0.
gamma = 0.
angle_dim = AngleType.DEGREES
if len(kwargs) != 0:
g3d_world = G3DWorld()
for key, value in kwargs.items():
if g3d_world.display.verbose:
print('%s == %s' % (key, str(value)))
if key == 'alpha':
alpha = value
elif key == 'beta':
beta = value
elif key == 'gamma':
gamma = value
elif key == 'angle_dim':
angle_dim = value
else:
print('warning! parameter %s is not defined' % key)
if alpha == 0. and beta == 0. and gamma == 0.:
print('warning! no rotation angle specified')
return
if angle_dim == AngleType.DEGREES:
alpha *= np.pi / 180.
beta *= np.pi / 180.
gamma *= np.pi / 180.
eps = 1.e-6
csa = np.cos(alpha)
ssa = np.sin(alpha)
csb = np.cos(beta)
ssb = np.sin(beta)
csg = np.cos(gamma)
ssg = np.sin(gamma)
for ip in range(self._npi):
if np.abs(alpha) > eps:
yy = self._Y[ip]
zz = self._Z[ip]
self._Y[ip] = csa * yy - ssa * zz
self._Z[ip] = ssa * yy + csa * zz
if np.abs(beta) > eps:
xx = self._X[ip]
zz = self._Z[ip]
self._Z[ip] = csb * zz + ssb * xx
self._X[ip] = -ssb * zz + csb * xx
if np.abs(gamma) > eps:
xx = self._X[ip]
yy = self._Y[ip]
self._X[ip] = csg * xx - ssg * yy
self._Y[ip] = ssg * xx + csg * yy
[docs]
def set_coordinates(self, **kwargs: Any) -> None:
"""
:param kwargs:
"""
if len(kwargs) != 0:
g3d_world = G3DWorld()
for key, value in kwargs.items():
if g3d_world.display.verbose:
print('%s == %s' % (key, str(value)))
if key == 'x':
for i in range(self._npi):
self._X[i] = value
elif key == 'y':
for i in range(self._npi):
self._Y[i] = value
elif key == 'z':
for i in range(self._npi):
self._Z[i] = value
else:
print('warning! parameter %s is not defined' % key)
[docs]
def shift(self, **kwargs: Any) -> None:
"""
:param kwargs:
:return:
"""
x_shift = 0.
y_shift = 0.
z_shift = 0.
if len(kwargs) != 0:
g3d_world = G3DWorld()
for key, value in kwargs.items():
if g3d_world.display.verbose:
print('%s == %s' % (key, str(value)))
if key == 'x_shift':
x_shift = value
elif key == 'y_shift':
y_shift = value
elif key == 'z_shift':
z_shift = value
else:
print('warning! parameter %s is not defined' % key)
if x_shift == 0. and y_shift == 0. and z_shift == 0.:
print('warning! no shift specified')
return
for i in range(self._npi):
self._X[i] += x_shift
self._Y[i] += y_shift
self._Z[i] += z_shift
self.__start.shift(x_shift=x_shift, y_shift=y_shift, z_shift=z_shift)
self.__end.shift(x_shift=x_shift, y_shift=y_shift, z_shift=z_shift)
[docs]
def get_spacing(self, **kwargs: Any) -> Union[float, float64]:
"""
:param kwargs:
:return:
"""
position = Position.START
if len(kwargs) != 0:
g3d_world = G3DWorld()
for key, value in kwargs.items():
if g3d_world.display.verbose:
print('%s == %s' % (key, str(value)))
if key == 'position':
position = value
else:
print('warning! parameter %s is not defined' % key)
dx = 0.
dy = 0.
dz = 0.
if position == Position.START and len(self._X) > 1:
dx = self._X[1] - self._X[0]
dy = self._Y[1] - self._Y[0]
dz = self._Z[1] - self._Z[0]
if position == Position.END and len(self._X) > 1:
dx = self._X[-1] - self._X[-2]
dy = self._Y[-1] - self._Y[-2]
dz = self._Z[-1] - self._Z[-2]
return np.sqrt(dx ** 2 + dy ** 2 + dz ** 2)
[docs]
def get_angle(self, **kwargs: Any) -> Union[None, Tuple[float, float]]:
"""
:param kwargs:
:return:
"""
direction = Direction.START_TO_END
if len(kwargs) != 0:
g3d_world = G3DWorld()
for key, value in kwargs.items():
if g3d_world.display.verbose:
print('%s == %s' % (key, str(value)))
if key == 'direction':
direction = value
if direction == Direction.START_TO_END or direction == Direction.POSITIVE:
return self.__start.get_angle(self.__end, **kwargs)
elif direction == Direction.END_TO_START or direction == Direction.NEGATIVE:
return self.__end.get_angle(self.__start, **kwargs)
elif direction == Direction.START_INWARD or direction == Direction.START_OUTWARD:
if len(self._X) > 0:
c_tmp = self.get_Coord(1)
if direction == Direction.START_OUTWARD:
return c_tmp.get_angle(self.__start, **kwargs)
else:
return self.__start.get_angle(c_tmp, **kwargs)
elif direction == Direction.END_INWARD or direction == Direction.END_OUTWARD:
if len(self._X) > 0 and self._npi >= 2:
c_tmp = self.get_Coord(self._npi - 2)
if direction == Direction.END_OUTWARD:
return c_tmp.get_angle(self.__end, **kwargs)
else:
return self.__end.get_angle(c_tmp, **kwargs)
return None
[docs]
def get_tangent(self, lp: int, **kwargs: Any) -> Tuple[float, float]:
"""
:param lp:
:param kwargs:
:return:
"""
direction = Direction.POSITIVE
if len(kwargs) != 0:
g3d_world = G3DWorld()
for key, value in kwargs.items():
if g3d_world.display.verbose:
print('%s == %s' % (key, str(value)))
if key == 'direction':
direction = value
lpm = max([lp - 1, 0])
lpp = min([lp + 1, self._npi - 1])
cm = self.get_Coord(lpm)
cp = self.get_Coord(lpp)
if direction == Direction.POSITIVE:
return cm.get_angle(cp, **kwargs)
else:
return cp.get_angle(cm, **kwargs)
[docs]
def find_index(self, x: float, **kwargs: Any) -> int:
"""
:param x:
:param kwargs:
:return:
"""
axis = Axis.X_AXIS
for key, value in kwargs.items():
if key == 'axis':
axis = value
if axis == Axis.X_AXIS:
return int(np.argmin(np.abs(self._X - x)))
elif axis == Axis.Y_AXIS:
return int(np.argmin(np.abs(self._Y - x)))
else: # axis == Axis.Z_AXIS:
return int(np.argmin(np.abs(self._Z - x)))
# ===============================================================================
# NODE DISTRIBUTE FUNCTIONS
# ===============================================================================
def __distribute_nodes(self) -> None:
self.allocate_XYZ()
distribute = self._distribute
if distribute == NodeDistribution.UNDEFINED:
return
elif distribute == NodeDistribution.ARC_1:
self.__arc1()
return
elif distribute == NodeDistribution.CURVE_1:
self.__curve1()
return
elif distribute == NodeDistribution.CURVE_2:
self.__curve2()
return
elif distribute == NodeDistribution.CURVE_3:
self.__curve3()
return
elif distribute == NodeDistribution.CURVE_4:
self.__curve4()
return
elif distribute == NodeDistribution.CURVE_5:
self.__curve5()
return
elif distribute == NodeDistribution.CURVE_10:
self.__curve10()
return
return
def __arc1(self) -> None:
V = np.array
xo = V(self.__origo.get_array())
x0 = V(self.__start.get_array())
x1 = V(self.__end.get_array())
npi = self._npi
axis = self._axis
if type(axis) is int:
axis = Axis(axis)
elif axis == Axis.UNDEFINED:
axis = Axis.X_AXIS
rad = self._alpha
if self._angle_dim == AngleType.DEGREES and rad != 0.:
rad *= np.pi / 180.
if axis == Axis.X_AXIS:
org = V([xo[2], xo[1]])
pnt1 = V([x0[2], x0[1]])
pnt2 = V([x1[2], x1[1]])
a = float(np.linalg.norm(org - pnt2))
b = float(np.linalg.norm(org - pnt1))
c = float(np.linalg.norm(pnt1 - pnt2))
if rad == 0.:
rad = np.arccos((c ** 2. - a ** 2. - b ** 2.) / (2. * a * b))
angles = np.linspace(0, rad, npi)
self._Z, self._Y = rotate(org, pnt1, angles)
self._X = V([x0[0]] * npi)
elif axis == Axis.Y_AXIS:
org = V([xo[0], xo[2]])
pnt1 = V([x0[0], x0[2]])
pnt2 = V([x1[0], x1[2]])
a = float(np.linalg.norm(org - pnt2))
b = float(np.linalg.norm(org - pnt1))
c = float(np.linalg.norm(pnt1 - pnt2))
if rad == 0.:
rad = np.arccos((c ** 2. - a ** 2. - b ** 2.) / (2. * a * b))
angles = np.linspace(0, rad, npi)
self._X, self._Z = rotate(org, pnt1, angles)
self._Y = V([x0[1]] * npi)
else:
org = V([xo[0], xo[1]])
pnt1 = V([x0[0], x0[1]])
pnt2 = V([x1[0], x1[1]])
a = float(np.linalg.norm(org - pnt2))
b = float(np.linalg.norm(org - pnt1))
c = float(np.linalg.norm(pnt1 - pnt2))
if rad == 0.:
rad = np.arccos((c ** 2. - a ** 2. - b ** 2.) / (2. * a * b))
angles = np.linspace(0, rad, npi)
self._X, self._Y = rotate(org, pnt1, angles)
self._Z = V([x0[2]] * npi)
def __curve1(self) -> None:
V = np.array
x1 = V(self.__start.get_array())
x2 = V(self.__end.get_array())
npi = self._npi
h1 = self.__start.spacing
h2 = self.__end.spacing
direction = self._direction
alpha = self._stretch_rate
XX = self._data
tolerance = self._tolerance
if alpha == 'default':
alpha = 0.
if type(direction) is int:
direction = Direction(direction)
elif direction == Direction.UNDEFINED:
direction = Direction.X_DIRECTION
# in case specified coordinates are outside of data set,
# add additional data point using zero-order extrapolation
xx, yy, zz = [], [], []
if direction == Direction.X_DIRECTION:
if x1[0] < XX[0, 0]:
xx.append(x1[0])
yy.append(XX[0, 1])
zz.append(XX[0, 2])
if direction == Direction.Y_DIRECTION:
if x1[1] < XX[0, 1]:
xx.append(XX[0, 0])
yy.append(x1[1])
zz.append(XX[0, 2])
if direction == Direction.Z_DIRECTION:
if x1[2] < XX[0, 2]:
xx.append(XX[0, 0])
yy.append(XX[0, 1])
zz.append(x1[2])
for i in range(len(XX[:, 0])):
xx.append(XX[i, 0])
yy.append(XX[i, 1])
zz.append(XX[i, 2])
if direction == Direction.X_DIRECTION:
if x2[0] > XX[-1, 0]:
xx.append(x2[0])
yy.append(XX[-1, 1])
zz.append(XX[-1, 2])
if direction == Direction.Y_DIRECTION:
if x2[1] > XX[-1, 1]:
xx.append(XX[-1, 0])
yy.append(x2[1])
zz.append(XX[-1, 2])
if direction == Direction.Z_DIRECTION:
if x2[2] > XX[-1, 2]:
xx.append(XX[-1, 0])
yy.append(XX[-1, 0])
zz.append(x2[2])
N = len(xx)
X = np.zeros(shape=(N, 3))
X[:, 0] = V(xx)
X[:, 1] = V(yy)
X[:, 2] = V(zz)
s = np.zeros(N)
for i in range(1, N):
s[i] = s[i - 1] + float(np.linalg.norm(X[i, :] - X[i - 1, :]))
bs_x = make_interp_spline(s, X[:, 0])
bs_y = make_interp_spline(s, X[:, 1])
bs_z = make_interp_spline(s, X[:, 2])
# find parameter value for the specified edge start coordinate
s1 = 0
s1x = bs_x(s1) - x1[0]
s1y = bs_y(s1) - x1[1]
s1z = bs_z(s1) - x1[2]
s1_diff = float(np.linalg.norm(np.array([s1x, s1y, s1z])))
if s1_diff > tolerance:
if direction == Direction.X_DIRECTION:
tck_x = bs_x.tsk
(t, c, k) = (tck_x[0], tck_x[1] - x1[0], tck_x[2])
bs = BSpline(t, c, k)
s1 = bs.roots()
elif direction == Direction.Y_DIRECTION:
tck_y = bs_y.tsk
(t, c, k) = (tck_y[0], tck_y[1] - x1[1], tck_y[2])
bs = BSpline(t, c, k)
s1 = bs.roots()
elif direction == Direction.Z_DIRECTION:
tck_z = bs_z.tsk
(t, c, k) = (tck_z[0], tck_z[1] - x1[2], tck_z[2])
bs = BSpline(t, c, k)
s1 = bs.roots()
if len(s1) == 0:
s1 = 0
elif len(s1) > 1:
s1 = s1[0]
s2 = s[-1]
s2x = bs_x(s2) - x2[0]
s2y = bs_y(s2) - x2[1]
s2z = bs_z(s2) - x2[2]
s2_diff = float(np.linalg.norm(np.array([s2x, s2y, s2z])))
if s2_diff > tolerance:
if direction == Direction.X_DIRECTION:
tck_x = bs_x.tsk
(t, c, k) = (tck_x[0], tck_x[1] - x2[0], tck_x[2])
bs = BSpline(t, c, k)
s2 = bs.roots()
elif direction == Direction.Y_DIRECTION:
tck_y = bs_y.tsk
(t, c, k) = (tck_y[0], tck_y[1] - x2[1], tck_y[2])
bs = BSpline(t, c, k)
s2 = bs.roots()
elif direction == Direction.Z_DIRECTION:
tck_z = bs_z.tsk
(t, c, k) = (tck_z[0], tck_z[1] - x2[2], tck_z[2])
bs = BSpline(t, c, k)
s2 = bs.roots()
if len(s2) == 0:
s2 = s[-1]
elif len(s2) > 1:
s2 = s2[-1]
if h1 < 0.:
h1 = -h1 * (s2 - s1) / (npi - 1)
if h2 < 0.:
h2 = -h2 * (s2 - s1) / (npi - 1)
ds1 = h1 * (npi - 1)
ds2 = h2 * (npi - 1)
self._X = np.zeros(npi)
self._Y = np.zeros(npi)
self._Z = np.zeros(npi)
for i in range(npi):
xsi = i / (npi - 1)
# sp = 1.
if alpha == 0.:
g10 = 1. + (2. * xsi - 3.) * xsi * xsi
g11 = (1. + (xsi - 2.) * xsi) * xsi
g20 = (3. - 2. * xsi) * xsi * xsi
g21 = (xsi - 1.) * xsi * xsi
sp = g10 * s1 + g11 * ds1 + g20 * s2 + g21 * ds2
else:
# gf = 1.
if xsi < 0.5:
gf = 0.5 * (np.exp(2. * alpha * xsi) - 1. - 2. * alpha * xsi) / (np.exp(alpha) - 1. - alpha)
else:
gf = 1. - 0.5 * ((np.exp(2. * alpha * (1. - xsi)) - 1. - 2. * alpha * (1. - xsi))
/ (np.exp(alpha) - 1. - alpha))
g10 = 1. - gf
g20 = gf
g11 = xsi * g10
g21 = (xsi - 1.) * g20
sp = g10 * s1 + g11 * ds1 + g20 * s2 + g21 * ds2
self._X[i] = bs_x(sp)
self._Y[i] = bs_y(sp)
self._Z[i] = bs_z(sp)
self._X[0] = x1[0]
self._Y[0] = x1[1]
self._Z[0] = x1[2]
self._X[-1] = x2[0]
self._Y[-1] = x2[1]
self._Z[-1] = x2[2]
def __curve2(self) -> None:
V = np.array
x0 = V(self.__start.get_array())
x1 = V(self.__end.get_array())
npi = self._npi
h1 = self.__start.spacing
h2 = self.__end.spacing
alpha = self._stretch_rate
if alpha == 'default':
alpha = 0.
if h1 == -1:
h1 = float(np.linalg.norm(x1 - x0)) / (npi - 1)
if h2 == -1:
h2 = float(np.linalg.norm(x1 - x0)) / (npi - 1)
dt1 = h1 / float(np.linalg.norm(x1 - x0)) * (npi - 1)
dt2 = h2 / float(np.linalg.norm(x1 - x0)) * (npi - 1)
self._X = np.zeros(npi)
self._Y = np.zeros(npi)
self._Z = np.zeros(npi)
for i in range(npi):
xsi = i / (npi - 1)
if alpha > 0.:
if xsi < 0.5:
GF = (0.5 * (np.exp(2.0 * alpha * xsi)
- 1.0 - 2.0 * alpha * xsi) / (np.exp(alpha) - 1.0 - alpha))
else:
GF = (1.0 - 0.5 * (np.exp(2.0 * alpha * (1.0 - xsi))
- 1.0 - 2.0 * alpha * (1.0 - xsi)) / (np.exp(alpha) - 1.0 - alpha))
G20 = GF
G11 = xsi * (1.0 - GF)
G21 = (xsi - 1.0) * GF
else:
G11 = xsi - 2.0 * np.square(xsi) + np.power(xsi, 3.0)
G20 = 3.0 * np.square(xsi) - 2.0 * np.power(xsi, 3.0)
G21 = -np.square(xsi) + np.power(xsi, 3.0)
T = G11 * dt1 + G20 + G21 * dt2
self._X[i] = (1.0 - T) * x0[0] + T * x1[0]
self._Y[i] = (1.0 - T) * x0[1] + T * x1[1]
self._Z[i] = (1.0 - T) * x0[2] + T * x1[2]
def __curve3(self) -> None:
# ialt=IALT_1
# alpha: angle between vector and x-axis
# beta: angle between projection of vector on yz-plane and y-axis (positive towards z-axis)
#
# ialt=IALT_2
# alpha: angle between vector and y-axis
# beta: angle between projection of vector on xz-plane and z-axis (positive towards x-axis)
#
# ialt=IALT_3
# alpha: angle between vector and z-axis
# beta: angle between projection of vector on xy-plane and x-axis (positive towards y-axis)
V = np.array
x1 = V(self.__start.get_array())
x2 = V(self.__end.get_array())
npi = self._npi
ialt1 = self.__start.ialt
a1 = self.__start.alpha
b1 = self.__start.beta
d1 = self.__start.shape_factor
h1 = self.__start.spacing
alpha = self._stretch_rate
if alpha == 'default':
alpha = 0.
if type(ialt1) is int:
ialt1 = AngleType(ialt1)
elif ialt1 == AngleType.UNDEFINED:
ialt1 = AngleType.IALT_1
if self.__start.angle_dim == AngleType.DEGREES:
a1 *= np.pi / 180.
b1 *= np.pi / 180.
if d1 < 0.:
d1 = np.abs(d1) * float(np.linalg.norm(x2 - x1))
dx1 = V([np.cos(a1), np.sin(a1) * np.cos(b1), np.sin(a1) * np.sin(b1)])
if ialt1 == AngleType.IALT_2:
dx1 = V([np.sin(a1) * np.sin(b1), np.cos(a1), np.sin(a1) * np.cos(b1)])
elif ialt1 == AngleType.IALT_3:
dx1 = V([np.sin(a1) * np.cos(b1), np.sin(a1) * np.sin(b1), np.cos(a1)])
dx1 *= d1
N = 50
X = np.zeros(shape=(N, 3))
for i in range(N):
xsi = i / (N - 1)
g10 = 1. - xsi * xsi
g11 = (1. - xsi) * xsi
g20 = xsi * xsi
X[i, 0] = g10 * x1[0] + g11 * dx1[0] + g20 * x2[0]
X[i, 1] = g10 * x1[1] + g11 * dx1[1] + g20 * x2[1]
X[i, 2] = g10 * x1[2] + g11 * dx1[2] + g20 * x2[2]
s = np.zeros(N)
for i in range(1, N):
s[i] = s[i - 1] + float(np.linalg.norm(X[i, :] - X[i - 1, :]))
bs_x = make_interp_spline(s, X[:, 0])
bs_y = make_interp_spline(s, X[:, 1])
bs_z = make_interp_spline(s, X[:, 2])
if h1 < 0.:
h1 = -h1 * s[-1] / (npi - 1)
ds1 = h1 * (npi - 1)
self._X = np.zeros(npi)
self._Y = np.zeros(npi)
self._Z = np.zeros(npi)
for i in range(npi):
xsi = i / (npi - 1)
gf = (np.exp(alpha * xsi) - 1. - alpha * xsi) / (np.exp(alpha) - 1. - alpha)
g10 = 1. - gf
g11 = xsi - gf
g20 = gf
sp = g10 * s[0] + g11 * ds1 + g20 * s[-1]
self._X[i] = bs_x(sp)
self._Y[i] = bs_y(sp)
self._Z[i] = bs_z(sp)
def __curve4(self) -> None:
# ialt=IALT_1
# alpha: angle between vector and x-axis
# beta: angle between projection of vector on yz-plane and y-axis (positive towards z-axis)
#
# ialt=IALT_2
# alpha: angle between vector and y-axis
# beta: angle between projection of vector on xz-plane and z-axis (positive towards x-axis)
#
# ialt=IALT_3
# alpha: angle between vector and z-axis
# beta: angle between projection of vector on xy-plane and x-axis (positive towards y-axis)
V = np.array
x1 = V(self.__start.get_array())
x2 = V(self.__end.get_array())
npi = self._npi
ialt1 = self.__start.ialt
a1 = self.__start.alpha
b1 = self.__start.beta
d1 = self.__start.shape_factor
h1 = self.__start.spacing
ialt2 = self.__end.ialt
a2 = self.__end.alpha
b2 = self.__end.beta
d2 = self.__end.shape_factor
h2 = self.__end.spacing
alpha = self._stretch_rate
if alpha == 'default':
alpha = 0.
if type(ialt1) is int:
ialt1 = AngleType(ialt1)
elif ialt1 == AngleType.UNDEFINED:
ialt1 = AngleType.IALT_1
if type(ialt2) is int:
ialt2 = AngleType(ialt2)
elif ialt2 == AngleType.UNDEFINED:
ialt2 = AngleType.IALT_1
if self.__start.angle_dim == AngleType.DEGREES:
a1 *= np.pi / 180.
b1 *= np.pi / 180.
if self.__end.angle_dim == AngleType.DEGREES:
a2 *= np.pi / 180.
b2 *= np.pi / 180.
if d1 < 0.:
d1 = np.abs(d1) * float(np.linalg.norm(x2 - x1))
if d2 < 0.:
d2 = np.abs(d2) * float(np.linalg.norm(x2 - x1))
dx1 = V([np.cos(a1), np.sin(a1) * np.cos(b1), np.sin(a1) * np.sin(b1)])
if ialt1 == AngleType.IALT_2:
dx1 = V([np.sin(a1) * np.sin(b1), np.cos(a1), np.sin(a1) * np.cos(b1)])
elif ialt1 == AngleType.IALT_3:
dx1 = V([np.sin(a1) * np.cos(b1), np.sin(a1) * np.sin(b1), np.cos(a1)])
dx1 *= d1
dx2 = V([np.cos(a2), np.sin(a2) * np.cos(b2), np.sin(a2) * np.sin(b2)])
if ialt2 == AngleType.IALT_2:
dx2 = V([np.sin(a2) * np.sin(b2), np.cos(a2), np.sin(a2) * np.cos(b2)])
elif ialt2 == AngleType.IALT_3:
dx2 = V([np.sin(a2) * np.cos(b2), np.sin(a2) * np.sin(b2), np.cos(a2)])
dx2 *= d2
N = 50
X = np.zeros(shape=(N, 3))
for i in range(N):
xsi = i / (N - 1)
g10 = 1. + (2. * xsi - 3.) * xsi * xsi
g11 = (1. + (xsi - 2.) * xsi) * xsi
g20 = (3. - 2. * xsi) * xsi * xsi
g21 = (xsi - 1.) * xsi * xsi
X[i, 0] = g10 * x1[0] + g11 * dx1[0] + g20 * x2[0] + g21 * dx2[0]
X[i, 1] = g10 * x1[1] + g11 * dx1[1] + g20 * x2[1] + g21 * dx2[1]
X[i, 2] = g10 * x1[2] + g11 * dx1[2] + g20 * x2[2] + g21 * dx2[2]
s = np.zeros(N)
for i in range(1, N):
s[i] = s[i - 1] + float(np.linalg.norm(X[i, :] - X[i - 1, :]))
bs_x = make_interp_spline(s, X[:, 0])
bs_y = make_interp_spline(s, X[:, 1])
bs_z = make_interp_spline(s, X[:, 2])
if h1 < 0.:
h1 = -h1 * s[-1] / (npi - 1)
if h2 < 0.:
h2 = -h2 * s[-1] / (npi - 1)
ds1 = h1 * (npi - 1)
ds2 = h2 * (npi - 1)
self._X = np.zeros(npi)
self._Y = np.zeros(npi)
self._Z = np.zeros(npi)
for i in range(npi):
xsi = i / (npi - 1)
# sp = 1.
if alpha == 0.:
g10 = 1. + (2. * xsi - 3.) * xsi * xsi
g11 = (1. + (xsi - 2.) * xsi) * xsi
g20 = (3. - 2. * xsi) * xsi * xsi
g21 = (xsi - 1.) * xsi * xsi
sp = g10 * s[0] + g11 * ds1 + g20 * s[-1] + g21 * ds2
else:
# gf = 1.
if xsi < 0.5:
gf = 0.5 * (np.exp(2. * alpha * xsi) - 1. - 2. * alpha * xsi) / (np.exp(alpha) - 1. - alpha)
else:
gf = 1. - 0.5 * ((np.exp(2. * alpha * (1. - xsi)) - 1. - 2. * alpha * (1. - xsi))
/ (np.exp(alpha) - 1. - alpha))
g10 = 1. - gf
g20 = gf
g11 = xsi * g10
g21 = (xsi - 1.) * g20
sp = g10 * s[0] + g11 * ds1 + g20 * s[-1] + g21 * ds2
self._X[i] = bs_x(sp)
self._Y[i] = bs_y(sp)
self._Z[i] = bs_z(sp)
def __curve5(self) -> None:
V = np.array
x1 = V(self.__start.get_array())
x2 = V(self.__end.get_array())
npi = self._npi
h1 = self.__start.spacing
alpha = self._stretch_rate
if alpha == 'default':
alpha = 0.
N = 50
X = np.zeros(shape=(N, 3))
for i in range(N):
xsi = i / (N - 1)
g10 = 1. - xsi * xsi
# g11 = (1. - xsi) * xsi
g20 = xsi * xsi
X[i, 0] = g10 * x1[0] + g20 * x2[0]
X[i, 1] = g10 * x1[1] + g20 * x2[1]
X[i, 2] = g10 * x1[2] + g20 * x2[2]
s = np.zeros(N)
for i in range(1, N):
s[i] = s[i - 1] + float(np.linalg.norm(X[i, :] - X[i - 1, :]))
bs_x = make_interp_spline(s, X[:, 0])
bs_y = make_interp_spline(s, X[:, 1])
bs_z = make_interp_spline(s, X[:, 2])
if h1 < 0.:
h1 = -h1 * s[-1] / (npi - 1)
ds1 = h1 * (npi - 1)
self._X = np.zeros(npi)
self._Y = np.zeros(npi)
self._Z = np.zeros(npi)
for i in range(npi):
xsi = i / (npi - 1)
gf = (np.exp(alpha * xsi) - 1. - alpha * xsi) / (np.exp(alpha) - 1. - alpha)
g10 = 1. - gf
g11 = xsi - gf
g20 = gf
sp = g10 * s[0] + g11 * ds1 + g20 * s[-1]
self._X[i] = bs_x(sp)
self._Y[i] = bs_y(sp)
self._Z[i] = bs_z(sp)
def __curve10(self) -> None:
# ialt=IALT_1
# alpha: angle between vector and x-axis
# beta: angle between projection of vector on yz-plane and y-axis (positive towards z-axis)
#
# ialt=IALT_2
# alpha: angle between vector and y-axis
# beta: angle between projection of vector on xz-plane and z-axis (positive towards x-axis)
#
# ialt=IALT_3
# alpha: angle between vector and z-axis
# beta: angle between projection of vector on xy-plane and x-axis (positive towards y-axis)
npi = self._npi
ialt = self._ialt
alpha = self._alpha
beta = self._beta
if self._angle_dim == AngleType.DEGREES:
alpha *= np.pi / 180.
beta *= np.pi / 180.
direction = Direction.UNDEFINED
stretch_rate = self._stretch_rate
XX = self._data
start_rot = Coord(self.__start, copy_settings=True)
end_rot = Coord(self.__end, copy_settings=True)
cosa = np.cos(alpha)
cosb = np.cos(beta)
sina = np.sin(alpha)
sinb = np.sin(beta)
XX_rot = np.zeros(XX.shape)
# rotate end coordinates and data set
if ialt == AngleType.IALT_1:
# alpha: angle between vector and x-axis
# beta: angle between projection of vector on yz-plane and y-axis (positive towards z-axis)
direction = Direction.X_DIRECTION
x = self.__start.x
y = self.__start.y
z = self.__start.z
start_rot.x = x * cosa + y * cosb * sina + z * sinb * sina
start_rot.y = -x * sina + y * cosb * cosa + z * sinb * cosa
start_rot.z = -y * sinb + z * cosb
x = self.__end.x
y = self.__end.y
z = self.__end.z
end_rot.x = x * cosa + y * cosb * sina + z * sinb * sina
end_rot.y = -x * sina + y * cosb * cosa + z * sinb * cosa
end_rot.z = -y * sinb + z * cosb
for i in range(len(XX[:, 0])):
x = XX[i, 0]
y = XX[i, 1]
z = XX[i, 2]
XX_rot[i, 0] = x * cosa + y * cosb * sina + z * sinb * sina
XX_rot[i, 1] = -x * sina + y * cosb * cosa + z * sinb * cosa
XX_rot[i, 2] = -y * sinb + z * cosb
elif ialt == AngleType.IALT_2:
# alpha: angle between vector and y-axis
# beta: angle between projection of vector on xz-plane and z-axis (positive towards x-axis)
direction = Direction.Y_DIRECTION
x = self.__start.x
y = self.__start.y
z = self.__start.z
start_rot.x = x * cosb - z * sinb
start_rot.y = x * sinb * sina + y * cosa + z * cosb * sina
start_rot.z = x * sinb * cosa - y * sina + z * cosb * cosa
x = self.__end.x
y = self.__end.y
z = self.__end.z
end_rot.x = x * cosb - z * sinb
end_rot.y = x * sinb * sina + y * cosa + z * cosb * sina
end_rot.z = x * sinb * cosa - y * sina + z * cosb * cosa
for i in range(len(XX[:, 0])):
x = XX[i, 0]
y = XX[i, 1]
z = XX[i, 2]
XX_rot[i, 0] = x * cosb - z * sinb
XX_rot[i, 1] = x * sinb * sina + y * cosa + z * cosb * sina
XX_rot[i, 2] = x * sinb * cosa - y * sina + z * cosb * cosa
elif ialt == AngleType.IALT_3:
# alpha: angle between vector and z-axis
# beta: angle between projection of vector on xy-plane and x-axis (positive towards y-axis)
direction = Direction.Z_DIRECTION
x = self.__start.x
y = self.__start.y
z = self.__start.z
start_rot.x = x * cosb * cosa + y * sinb * cosa - z * sina
start_rot.y = -x * sinb + y * cosb
start_rot.z = x * cosb * sina + y * sinb * sina + z * cosa
x = self.__end.x
y = self.__end.y
z = self.__end.z
end_rot.x = x * cosb * cosa + y * sinb * cosa - z * sina
end_rot.y = -x * sinb + y * cosb
end_rot.z = x * cosb * sina + y * sinb * sina + z * cosa
for i in range(len(XX[:, 0])):
x = XX[i, 0]
y = XX[i, 1]
z = XX[i, 2]
XX_rot[i, 0] = x * cosb * cosa + y * sinb * cosa - z * sina
XX_rot[i, 1] = -x * sinb + y * cosb
XX_rot[i, 2] = x * cosb * sina + y * sinb * sina + z * cosa
# distribute coordinates along edge in rotated coordinate system
e = Edge(npi, start_rot, end_rot, distribute=NodeDistribution.CURVE_1,
direction=direction, stretch_rate=stretch_rate, data=XX_rot)
# rotate edge coordinates back to physical coordinate system
xp_rot, yp_rot, zp_rot = e.get_XYZ()
self._X = np.zeros(npi)
self._Y = np.zeros(npi)
self._Z = np.zeros(npi)
if ialt == AngleType.IALT_1:
for i in range(npi):
x = xp_rot[i]
y = yp_rot[i]
z = zp_rot[i]
self._X[i] = x * cosa - y * sina
self._Y[i] = x * sina * cosb + y * cosa * cosb - z * sinb
self._Z[i] = x * sina * sinb + y * cosa * sinb + z * cosb
elif ialt == AngleType.IALT_2:
for i in range(npi):
x = xp_rot[i]
y = yp_rot[i]
z = zp_rot[i]
self._X[i] = x * cosb + y * sina * sinb + z * cosa * sinb
self._Y[i] = y * cosa - z * sina
self._Z[i] = -x * sinb + y * sina * cosb + z * cosa * cosb
elif ialt == AngleType.IALT_3:
for i in range(npi):
x = xp_rot[i]
y = yp_rot[i]
z = zp_rot[i]
self._X[i] = x * cosa * cosb - y * sinb + z * sina * cosb
self._Y[i] = x * cosa * sinb + y * cosb + z * sina * sinb
self._Z[i] = -x * sina + z * cosa