More work on rotate method for objects.

这个提交包含在:
Craig Warren
2020-06-22 14:54:19 +01:00
父节点 4f040a1cc3
当前提交 93b77a97bc
共有 10 个文件被更改,包括 170 次插入139 次删除

查看文件

@@ -24,7 +24,7 @@ import numpy as np
from ..fractals import FractalSurface, Grass from ..fractals import FractalSurface, Grass
from ..materials import DispersiveMaterial from ..materials import DispersiveMaterial
from ..utilities import round_value from ..utilities import round_value
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry, rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -52,8 +52,7 @@ class AddGrass(UserObjectGeometry):
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) pts = np.array([self.kwargs['p1'], self.kwargs['p2']])
rotation = UserObjectGeometry.rotate_2point_object rot_pts = rotate_2point_object(pts, axis, angle, origin)
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
self.kwargs['p2'] = tuple(rot_pts[1, :]) self.kwargs['p2'] = tuple(rot_pts[1, :])

查看文件

@@ -22,7 +22,7 @@ import numpy as np
from ..fractals import FractalSurface from ..fractals import FractalSurface
from ..utilities import round_value from ..utilities import round_value
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry, rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -52,8 +52,7 @@ class AddSurfaceRoughness(UserObjectGeometry):
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) pts = np.array([self.kwargs['p1'], self.kwargs['p2']])
rotation = UserObjectGeometry.rotate_2point_object rot_pts = rotate_2point_object(pts, axis, angle, origin)
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
self.kwargs['p2'] = tuple(rot_pts[1, :]) self.kwargs['p2'] = tuple(rot_pts[1, :])

查看文件

@@ -23,7 +23,7 @@ import numpy as np
from ..materials import DispersiveMaterial from ..materials import DispersiveMaterial
from ..utilities import round_value from ..utilities import round_value
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry, rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -47,8 +47,7 @@ class AddSurfaceWater(UserObjectGeometry):
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) pts = np.array([self.kwargs['p1'], self.kwargs['p2']])
rotation = UserObjectGeometry.rotate_2point_object rot_pts = rotate_2point_object(pts, axis, angle, origin)
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
self.kwargs['p2'] = tuple(rot_pts[1, :]) self.kwargs['p2'] = tuple(rot_pts[1, :])

查看文件

@@ -22,7 +22,7 @@ import numpy as np
from ..cython.geometry_primitives import build_box from ..cython.geometry_primitives import build_box
from ..materials import Material from ..materials import Material
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry, rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -48,8 +48,7 @@ class Box(UserObjectGeometry):
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) pts = np.array([self.kwargs['p1'], self.kwargs['p2']])
rotation = UserObjectGeometry.rotate_2point_object rot_pts = rotate_2point_object(pts, axis, angle, origin)
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
self.kwargs['p2'] = tuple(rot_pts[1, :]) self.kwargs['p2'] = tuple(rot_pts[1, :])

查看文件

@@ -44,95 +44,140 @@ class UserObjectGeometry:
return f'{self.hash}: {s[:-1]}' return f'{self.hash}: {s[:-1]}'
def create(self, grid, uip): def create(self, grid, uip):
"""Create the object and add it to the grid.""" """Create object and add it to the grid."""
pass pass
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
"""Rotate object - specialised for each object.""" """Rotate object - specialised for each object."""
pass pass
def rotate_point(self, p, axis, angle, origin=(0, 0, 0)):
"""Rotate a point. def rotate_point(p, axis, angle, origin=(0, 0, 0)):
"""Rotate a point.
Args:
p (array): coordinates of point (x, y, z)
axis (str): axis about which to perform rotation (x, y, or z)
angle (int): angle of rotation (degrees)
origin (tuple): point about which to perform rotation (x, y, z)
Returns:
p (array): coordinates of rotated point (x, y, z)
"""
origin = np.array(origin)
# Move point to axis of rotation
p -= origin
# Calculate rotation matrix
r = R.from_euler(axis, angle, degrees=True)
# Apply rotation
p = r.apply(p)
# Move object back to original axis
p += origin
return p
Args:
p (array): coordinates of point (x, y, z)
axis (str): axis about which to perform rotation (x, y, or z)
angle (int): angle of rotation (degrees)
origin (tuple): point about which to perform rotation (x, y, z)
Returns: def rotate_2point_object(pts, axis, angle, origin=None):
p (array): coordinates of rotated point (x, y, z) """Rotate a geometry object that is defined by 2 points.
"""
Args:
pts (array): coordinates of points of object to be rotated
axis (str): axis about which to perform rotation (x, y, or z)
angle (int): angle of rotation (degrees)
origin (tuple): point about which to perform rotation (x, y, z)
origin = np.array(origin) Returns:
new_pts (array): coordinates of points of rotated object
"""
# Use origin at centre of object if not given
if not origin:
origin = pts[0,:] + (pts[1,:] - pts[0,:]) / 2
# Check angle value is suitable
angle = int(angle)
if angle < 0 or angle > 360:
logger.exception(self.__str__() + ' angle of rotation must be between 0-360 degrees')
raise ValueError
if angle % 90 != 0:
logger.exception(self.__str__() + ' angle of rotation must be a multiple of 90 degrees')
raise ValueError
# Move point to axis of rotation # Check axis is valid
p -= origin if axis != 'x' and axis != 'y' and axis != 'z':
logger.exception(self.__str__() + ' axis of rotation must be x, y, or z')
raise ValueError
# Calculate rotation matrix # Save original points
r = R.from_euler(axis, angle, degrees=True) orig_pts = pts
# Apply rotation # Rotate points that define object
p = r.apply(p) pts[0, :] = rotate_point(pts[0, :], axis, angle, origin)
pts[1, :] = rotate_point(pts[1, :], axis, angle, origin)
# Move object back to original axis # Get lower left and upper right coordinates to define new object
p += origin new_pts = np.zeros(pts.shape)
new_pts[0, :] = np.min(pts, axis=0)
new_pts[1, :] = np.max(pts, axis=0)
return p # Reset coordinates of invariant direction
# - only needed for 2D models, has no effect on 3D models.
def rotate_2point_object(self, pts, axis, angle, origin=None): if axis =='x':
"""Rotate a geometry object that is defined by 2 points. new_pts[0, 0] = orig_pts[0, 0]
new_pts[1, 0] = orig_pts[1, 0]
Args: elif axis == 'y':
pts (array): coordinates of points of object to be rotated new_pts[0, 1] = orig_pts[0, 1]
axis (str): axis about which to perform rotation (x, y, or z) new_pts[1, 1] = orig_pts[1, 1]
angle (int): angle of rotation (degrees) elif axis == 'z':
origin (tuple): point about which to perform rotation (x, y, z) new_pts[0, 2] = orig_pts[0, 2]
new_pts[1, 2] = orig_pts[1, 2]
Returns: return new_pts
new_pts (array): coordinates of points of rotated object
"""
# Use origin at centre of object if not given
if not origin:
origin = pts[0,:] + (pts[1,:] - pts[0,:]) / 2
# Check angle value is suitable def rotate_polarisation(p, polarisation, axis, angle):
angle = int(angle) """Rotate a geometry object that is defined by 2 points.
if angle < 0 or angle > 360:
logger.exception(self.__str__() + ' angle of rotation must be between 0-360 degrees') Args:
raise ValueError p (array): coordinates of point (x, y, z)
if angle % 90 != 0: polarisation (str): current polarisation (x, y, or z)
logger.exception(self.__str__() + ' angle of rotation must be a multiple of 90 degrees') axis (str): axis about which to perform rotation (x, y, or z)
raise ValueError angle (int): angle of rotation (degrees)
# Check axis is valid Returns:
if axis != 'x' and axis != 'y' and axis != 'z': pts (array): coordinates of points of rotated object
logger.exception(self.__str__() + ' axis of rotation must be x, y, or z') new_polarisation (str): new polarisation (x, y, or z)
raise ValueError """
# Save original points logger.debug('Need to get dxdydz into this function')
orig_pts = pts dxdydz = np.array([0.001, 0.001, 0.001])
# Rotate points that define object if polarisation.lower() == 'x':
pts[0, :] = self.rotate_point(pts[0, :], axis, angle, origin) new_pt = (p[0] + dxdydz[0], p[1], p[2])
pts[1, :] = self.rotate_point(pts[1, :], axis, angle, origin) if axis == 'y' and angle == 90 or angle == 270:
new_polarisation = 'z'
if axis == 'z' and angle == 90 or angle == 270:
new_polarisation = 'y'
# Get lower left and upper right coordinates to define new object elif polarisation.lower() == 'y':
new_pts = np.zeros(pts.shape) new_pt = (p[0], p[1] + dxdydz[1], p[2])
new_pts[0, :] = np.min(pts, axis=0) if axis == 'x' and angle == 90 or angle == 270:
new_pts[1, :] = np.max(pts, axis=0) new_polarisation = 'z'
if axis == 'z' and angle == 90 or angle == 270:
new_polarisation = 'x'
# Reset coordinates of invariant direction elif polarisation.lower() == 'z':
# - only needed for 2D models, has no effect on 3D models. new_pt = (p[0], p[1], p[2] + dxdydz[2])
if axis =='x': if axis == 'x' and angle == 90 or angle == 270:
new_pts[0, 0] = orig_pts[0, 0] new_polarisation = 'y'
new_pts[1, 0] = orig_pts[1, 0] if axis == 'y' and angle == 90 or angle == 270:
elif axis == 'y': new_polarisation = 'x'
new_pts[0, 1] = orig_pts[0, 1]
new_pts[1, 1] = orig_pts[1, 1]
elif axis == 'z':
new_pts[0, 2] = orig_pts[0, 2]
new_pts[1, 2] = orig_pts[1, 2]
return new_pts pts = np.array([p, new_pt])
return pts, new_polarisation

查看文件

@@ -22,7 +22,7 @@ import numpy as np
from ..cython.geometry_primitives import (build_edge_x, build_edge_y, from ..cython.geometry_primitives import (build_edge_x, build_edge_y,
build_edge_z) build_edge_z)
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry, rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -44,8 +44,7 @@ class Edge(UserObjectGeometry):
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) pts = np.array([self.kwargs['p1'], self.kwargs['p2']])
rotation = UserObjectGeometry.rotate_2point_object rot_pts = rotate_2point_object(pts, axis, angle, origin)
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
self.kwargs['p2'] = tuple(rot_pts[1, :]) self.kwargs['p2'] = tuple(rot_pts[1, :])

查看文件

@@ -21,7 +21,7 @@ import logging
import numpy as np import numpy as np
from ..fractals import FractalVolume from ..fractals import FractalVolume
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry, rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -55,8 +55,7 @@ class FractalBox(UserObjectGeometry):
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) pts = np.array([self.kwargs['p1'], self.kwargs['p2']])
rotation = UserObjectGeometry.rotate_2point_object rot_pts = rotate_2point_object(pts, axis, angle, origin)
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
self.kwargs['p2'] = tuple(rot_pts[1, :]) self.kwargs['p2'] = tuple(rot_pts[1, :])

查看文件

@@ -22,7 +22,7 @@ import numpy as np
from ..cython.geometry_primitives import (build_face_xy, build_face_xz, from ..cython.geometry_primitives import (build_face_xy, build_face_xz,
build_face_yz) build_face_yz)
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry, rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -46,8 +46,7 @@ class Plate(UserObjectGeometry):
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) pts = np.array([self.kwargs['p1'], self.kwargs['p2']])
rotation = UserObjectGeometry.rotate_2point_object rot_pts = rotate_2point_object(pts, axis, angle, origin)
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
self.kwargs['p2'] = tuple(rot_pts[1, :]) self.kwargs['p2'] = tuple(rot_pts[1, :])

查看文件

@@ -46,9 +46,6 @@ class Sphere(UserObjectGeometry):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = '#sphere' self.hash = '#sphere'
def rotate(self, axis, angle, origin=None):
pass
def create(self, grid, uip): def create(self, grid, uip):
try: try:
p1 = self.kwargs['p1'] p1 = self.kwargs['p1']

查看文件

@@ -18,10 +18,13 @@
import logging import logging
import gprMax.config as config
import numpy as np import numpy as np
from .cmds_geometry.cmds_geometry import UserObjectGeometry import gprMax.config as config
from .cmds_geometry.cmds_geometry import (UserObjectGeometry,
rotate_2point_object,
rotate_polarisation)
from .geometry_outputs import GeometryObjects as GeometryObjectsUser from .geometry_outputs import GeometryObjects as GeometryObjectsUser
from .materials import DispersiveMaterial as DispersiveMaterialUser from .materials import DispersiveMaterial as DispersiveMaterialUser
from .materials import Material as MaterialUser from .materials import Material as MaterialUser
@@ -48,7 +51,6 @@ class UserObjectMulti:
self.order = None self.order = None
self.hash = '#example' self.hash = '#example'
self.autotranslate = True self.autotranslate = True
self.rotate_point = UserObjectGeometry.rotate_point
def __str__(self): def __str__(self):
"""Readable user string as per hash commands.""" """Readable user string as per hash commands."""
@@ -61,10 +63,11 @@ class UserObjectMulti:
return f'{self.hash}: {s[:-1]}' return f'{self.hash}: {s[:-1]}'
def create(self, grid, uip): def create(self, grid, uip):
"""Create the object and add it to the grid.""" """Create object and add it to the grid."""
pass pass
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
"""Rotate object - specialised for each object."""
pass pass
def params_str(self): def params_str(self):
@@ -142,50 +145,10 @@ class VoltageSource(UserObjectMulti):
self.hash = '#voltage_source' self.hash = '#voltage_source'
def rotate(self, axis, angle, origin=None): def rotate(self, axis, angle, origin=None):
pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle)
dxdydz = (0.001, 0.001, 0.001) rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin)
if self.kwargs['polarisation'].lower() == 'x':
new_pt = (self.kwargs['p1'][0] + dxdydz[0],
self.kwargs['p1'][1],
self.kwargs['p1'][2])
if axis == 'y' and angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'z'
if axis == 'z' and angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'y'
pts = np.array([self.kwargs['p1'], new_pt])
rotation = UserObjectGeometry.rotate_2point_object
rot_pts = rotation(self, pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :]) self.kwargs['p1'] = tuple(rot_pts[0, :])
if axis == 'x':
p[0] = origp[0]
if self.kwargs['polarisation'].lower() == 'y':
if angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'z'
elif self.kwargs['polarisation'].lower() =='z':
if angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'y'
elif axis == 'y':
p[1] = origp[1]
if self.kwargs['polarisation'].lower() == 'x':
if angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'z'
elif self.kwargs['polarisation'].lower() == 'z':
if angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'x'
elif axis == 'z':
p[2] = origp[2]
if self.kwargs['polarisation'].lower() == 'x':
if angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'y'
elif self.kwargs['polarisation'].lower() == 'y':
if angle == 90 or angle == 270:
self.kwargs['polarisation'] = 'x'
def create(self, grid, uip): def create(self, grid, uip):
try: try:
p1 = self.kwargs['p1'] p1 = self.kwargs['p1']
@@ -282,6 +245,11 @@ class HertzianDipole(UserObjectMulti):
self.order = 3 self.order = 3
self.hash = '#hertzian_dipole' self.hash = '#hertzian_dipole'
def rotate(self, axis, angle, origin=None):
rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle)
rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :])
def create(self, grid, uip): def create(self, grid, uip):
try: try:
polarisation = self.kwargs['polarisation'].lower() polarisation = self.kwargs['polarisation'].lower()
@@ -387,6 +355,11 @@ class MagneticDipole(UserObjectMulti):
self.order = 4 self.order = 4
self.hash = '#magnetic_dipole' self.hash = '#magnetic_dipole'
def rotate(self, axis, angle, origin=None):
rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle)
rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :])
def create(self, grid, uip): def create(self, grid, uip):
try: try:
polarisation = self.kwargs['polarisation'].lower() polarisation = self.kwargs['polarisation'].lower()
@@ -482,6 +455,11 @@ class TransmissionLine(UserObjectMulti):
self.order = 5 self.order = 5
self.hash = '#transmission_line' self.hash = '#transmission_line'
def rotate(self, axis, angle, origin=None):
rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle)
rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :])
def create(self, grid, uip): def create(self, grid, uip):
try: try:
polarisation = self.kwargs['polarisation'].lower() polarisation = self.kwargs['polarisation'].lower()
@@ -583,6 +561,24 @@ class Rx(UserObjectMulti):
self.hash = '#rx' self.hash = '#rx'
self.constructor = RxUser self.constructor = RxUser
def rotate(self, axis, angle, origin=None):
logger.debug('Need to get dxdydz into this function')
dxdydz = np.array([0.001, 0.001, 0.001])
new_pt = (self.kwargs['p1'][0] + dxdydz[0], self.kwargs['p1'][1] + dxdydz[1], self.kwargs['p1'][2] + dxdydz[2])
pts = np.array([self.kwargs['p1'], new_pt])
rot_pts = rotate_2point_object(pts, axis, angle, origin)
self.kwargs['p1'] = tuple(rot_pts[0, :])
# If specific field components are specified, set to output all components
try:
ID = self.kwargs['id']
outputs = [self.kwargs['outputs']]
rxargs = dict(self.kwargs)
del rxargs['outputs']
self.kwargs = rxargs
except KeyError:
pass
def create(self, grid, uip): def create(self, grid, uip):
try: try:
p1 = self.kwargs['p1'] p1 = self.kwargs['p1']