示例#1
0
def intersection_of_plane_with_slice(slice_index, plane):
    """
    ASSUMING AXIAL ORIENTATION, finds the line that repreents the interection
    between the two planes IN 2D
    

    Parameters
    ----------
    slice_index : int
        the z index of the axial slice.
    plane : sympy Plane object
        The plane of interest.

    Returns
    -------
    sympy Line2D object.

    """

    # set up the plane of the slice
    flat_plane = sp.Plane((1, 0, slice_index), (-1, 0, slice_index),
                          (0, 1, slice_index))

    inter = plane.intersection(flat_plane)[0]

    intersection_2d = sp.Line((inter.p1[0], inter.p1[1]),
                              (inter.p2[0], inter.p2[1]))

    return intersection_2d
示例#2
0
    def _check_intersection(self, ray0, ray1, tri0, tri1, tri2):
        from pascal3d.utils.geometry import intersect3d_ray_triangle
        n_rays = len(ray0)
        assert len(ray1) == n_rays
        assert len(tri0) == n_rays
        assert len(tri1) == n_rays
        assert len(tri2) == n_rays

        l1 = sympy.Line3D(sympy.Point3D(*ray0.tolist()),
                          sympy.Point3D(*ray1.tolist()))
        p1 = sympy.Plane(sympy.Point3D(*tri0.tolist()),
                         sympy.Point3D(*tri1.tolist()),
                         sympy.Point3D(*tri2.tolist()))
        t1 = sympy.Triangle(sympy.Point3D(*tri0.tolist()),
                            sympy.Point3D(*tri1.tolist()),
                            sympy.Point3D(*tri2.tolist()))
        i1 = p1.intersection(l1)
        if len(i1) == 0:
            ret1 = False
        else:
            ret1 = t1.encloses(i1[0])

        ret2, i2 = intersect3d_ray_triangle(ray0, ray1, tri0, tri1, tri2)
        nose.tools.assert_equal(ret2.shape, (1, ))
        nose.tools.assert_equal(ret2[0] == 1, ret1)
        nose.tools.assert_equal(i2.shape, (1, 3))
        if ret1:
            np.testing.assert_allclose(i2[0],
                                       map(float, [i1[0].x, i1[0].y, i1[0].z]))
示例#3
0
def default_plane(pick: int) -> sy.Plane:
    """
    """
    x = sy.Point3D([30, 0, 0])
    y = sy.Point3D([0, 30, 0])
    z = sy.Point3D([0, 0, 30])
    c = sy.Point3D([0, 0, 0])

    if pick == 0:
        return sy.Plane(y, c, x)
    elif pick == 1:
        return sy.Plane(x, c, z)
    elif pick == 2:
        return sy.Plane(z, c, y)
    else:
        raise ValueError('Selection must be between 0 and 2')
示例#4
0
def plane_1(a,b,c): 
    '''
    a,b,c : tuples with three element (x,y,z)
    '''
    x, y , z = sp.symbols("x y z")
    plane_temp = sp.Plane(sp.Point3D(*a),sp.Point3D(*b),sp.Point3D(*c))
    vn = plane_temp.normal_vector;
    
    return -(vn[0]*(x-a[0])+vn[1]*(y-a[1]))/vn[2] + a[2]
示例#5
0
def make_angles_and_distances(pieces: Dict) -> pd.DataFrame:
    """Calculates the angles and distances from the vectors and planes.

    :param pieces: The SSE pieces to calculate the vectors from.
    """
    data = {
        'sse': [],
        'layer': [],
        'angles_layer': [],
        'angles_floor': [],
        'angles_side': [],
        'points_layer': [],
        'points_floor': [],
        'points_side': [],
        'tilted_layer': [],
        'tilted_floor': [],
        'tilted_side': []
    }

    for layer in sorted(set([x[0] for x in pieces if len(x) == 1])):
        for sse in [x for x in pieces if len(x) == 3]:
            if abs(ascii_uppercase.find(layer) -
                   ascii_uppercase.find(sse[0])) <= 1:
                data['sse'].append(sse)
                data['layer'].append(layer)
                for iplane, plane in enumerate(pieces[layer]):
                    if TBcore.get_option('system', 'debug'):
                        sys.stdout.write(
                            'PDB:{} geometry plane {} vs. sse {}\n'.format(
                                plane, layer, sse))
                    syPlane = sy.Plane(sy.Point3D(pieces[layer][plane][0]),
                                       sy.Point3D(pieces[layer][plane][1]),
                                       sy.Point3D(pieces[layer][plane][2]))
                    syLine = sy.Line(pieces[sse]['vector'][0],
                                     pieces[sse]['vector'][-1])
                    syPoint = sy.Point3D(*pieces[sse]['vector'][1])
                    data[f'angles_{plane}'].append(
                        math.degrees(syPlane.angle_between(syLine)))
                    data[f'points_{plane}'].append(
                        float(syPlane.distance(syPoint)))
                    data[f'tilted_{plane}'].append(
                        float(syPlane.distance(default_plane(iplane))))
    return pd.DataFrame(data)
示例#6
0
    def offset_face(self, fid):
        connected_edges = [
            self.get_connected_edge(self.faces[fid][i], fid) for i in range(4)
        ]

        plane = self.face2plane(fid)
        origin = self.face_centre(fid)
        norm = sp.Point3D(plane.normal_vector)
        offset_vector = (sp.Point3D(self.center) - origin)
        offset_vector /= sp.Segment3D(sp.Point3D(0, 0, 0),
                                      offset_vector).length
        origin += offset_vector * random.uniform(-self.max_offset,
                                                 self.max_offset)
        plane = sp.Plane(origin, normal_vector=norm)

        # find new points for face
        new_face_points = []
        for ce in connected_edges:
            line = sp.Line3D(sp.Point3D(self.points[ce[0]]),
                             sp.Point3D(self.points[ce[1]]))
            intersections = plane.intersection(line)
            if len(intersections) == 0:
                print("skip face offsetting - hex will not be valid")
                return

            new_point = intersections[0]
            new_point = [
                new_point.x.evalf(),
                new_point.y.evalf(),
                new_point.z.evalf()
            ]
            new_face_points.append(new_point)

            if not self.is_b_not_far_than_a(self.points[ce[0]],
                                            self.points[ce[1]], new_point):
                print("skip face offsetting - hex will not be valid")
                return

        # replace old points with new
        for i in range(4):
            pid = self.faces[fid][i]
            self.points[pid] = new_face_points[i]
示例#7
0
    def rotate_face(self, fid):
        connected_edges = [
            self.get_connected_edge(self.faces[fid][i], fid) for i in range(4)
        ]

        # rotate face plane around random axis with origin at face centre
        plane = self.face2plane(fid)
        origin = self.face_centre(fid)
        axis = plane.random_point() - plane.random_point()
        transform_matrix = Quaternion.from_axis_angle((axis[0], axis[1], axis[2]),
                                                      random.uniform(-self.max_angle_offset, self.max_angle_offset)
                                                      )\
            .to_rotation_matrix((origin[0], origin[1], origin[2]))

        norm = sp.Point3D(plane.normal_vector)
        plane = sp.Plane(origin,
                         normal_vector=norm.transform(transform_matrix))

        # find new points for face
        new_face_points = []
        for ce in connected_edges:
            line = sp.Line3D(sp.Point3D(self.points[ce[0]]),
                             sp.Point3D(self.points[ce[1]]))
            new_point = plane.intersection(line)[0]
            new_point = [
                new_point.x.evalf(),
                new_point.y.evalf(),
                new_point.z.evalf()
            ]
            new_face_points.append(new_point)

            if not self.is_b_not_far_than_a(self.points[ce[0]],
                                            self.points[ce[1]], new_point):
                print("skip face rotating - hex will not be valid")
                return

        # replace old points with new
        for i in range(4):
            pid = self.faces[fid][i]
            self.points[pid] = new_face_points[i]
示例#8
0
# -*- coding: utf-8 -*-
"""
Main entry point for neurosegment

"""

import sympy as sp
import matplotlib.pyplot as plt

from preprocessing import read_nifti, skull_strip, sobelize, binary_by_percentile_threshold
from preprocessing import calculate_projected_plane_coords, is_partnered, intersection_of_plane_with_slice
from preprocessing import score_midsagittal

px, py = (238, 242)

arbitrary_plane = sp.Plane((0, 0, 10), (300, 300, 20), (300, 300, 10))
slice_num = 23
img_path = r'/Users/manusdonahue/Documents/Sky/Infarcts/Donahue_114402.XMLPARREC.dcm2niix/NIFTI/Donahue_114402.04.01.14-42-52.WIP_MJD_FLAIR_AX_3MM_SENSE.01.nii'

img = read_nifti(img_path)
stripped_img, mask = skull_strip(img)
sobel_img = sobelize(stripped_img)
edge_img, abs_thresh = binary_by_percentile_threshold(sobel_img,
                                                      3,
                                                      invert=True)

# note that when plotting with imshow, imaging conventions for coordinates are used
# essentially x and y are swapped and the origin is at the upper left corner

raw_data = img[:, :, slice_num]
fig, ax = plt.subplots(2, 2)
示例#9
0
 def as_sympy_plane(self) -> S.Plane:
     return S.Plane(*self.sympy_vertices, normal_vector=self.normal)
示例#10
0
 def face2plane(self, fid):
     p1 = sp.Point3D(self.points[self.faces[fid][0]])
     p2 = sp.Point3D(self.points[self.faces[fid][1]])
     p3 = sp.Point3D(self.points[self.faces[fid][2]])
     return sp.Plane(p1, p2, p3)
    normvec[i] = edgevec[i] / edgelength
wrappedmidpt = geometry.wrap_positions([mid], cell)[0]
print("wrapped midpoint: ", wrappedmidpt)
print("cut: ", cutrad, "midpoint: ", mid[0], mid[1], mid[2], "vec: ",
      edgevec[0], edgevec[1], edgevec[2], "normvec: ", normvec[0], normvec[1],
      normvec[2])

# declare sympy Point3D from UNWRAPPED midpoint
# FIXME: not sure if this is the best thing to do though? should not matter if it is wrapped
midpoint = sympy.Point3D(mid[0], mid[1], mid[2])
nodepoint1 = sympy.Point3D(node1[0], node1[1], node1[2])
nodepoint2 = sympy.Point3D(node2[0], node2[1], node2[2])
vecline = sympy.geometry.Line(nodepoint1, nodepoint2)

# declare sympy Plane
plane = sympy.Plane(sympy.Point3D(mid[0], mid[1], mid[2]),
                    normal_vector=normvec)

# declare radii dictionary
radii = dict()

# declare containers to store atoms within cutoff
atomname = []  # atom names
point3D = []  # atom centers
projection3D = []  # projection of atom centers onto 3D plane
projection2D = []  # parameterization of atom centers onto a 2D plane
radius = []  # radius of atoms
indices = []
allatomnames = []
allatompos = []
allatomnames_supercell = []
allatompos_supercell = []
示例#12
0
import platform
platform.platform()
platform.python_version()

import numpy as np
import numpy.linalg as LA
import math

import sympy
from sympy import var

H = sympy.Point3D(-69.2, 89.23, 70.43)
tockanax = -(-33.21 / 80.86)
ravnina = sympy.Plane(sympy.Point3D(tockanax, 0, 0), (80.86, -66.12, -18.29))
presjeknaravnini = ravnina.projection(H)
Hc = presjeknaravnini + H.direction_ratio(presjeknaravnini)
E = sympy.Point3D(-32.6, 67.92, -51.91)
print(round(Hc.distance(E), 5))
示例#13
0
def reconstruct_room(candidate_virtual_sources,
                     loudspeaker,
                     dist_thresh,
                     shoebox=True):
    """
    This method uses the first-order virtual-sources to reconstruct the room:
    it processes the candidate virtual sources in the order of increasing distance
    from the loudspeaker to find the first-order virtual sources and add their planes
    to the list of half-spaces whose intersection determines the final room.
    :param candidate_virtual_sources: list of the coordinates of all the individuated
    virtual sources (it could contain even higher-order virtual sources)
    :param loudspeaker: x, y, z coordinates of the speaker location in the room
    :param dist_thresh: distance threshold (epsilon)
    :param shoebox: boolean to identify if the room is a shoebox
    :return: list of planes corresponding to the first-order virtual sources
    """
    def combine(s1, s2):
        """
        This method combines the virtual sources s1 and s2 to generate a higher-order
        virtual source; it is used as a criterion to discard higher-order virtual sources.
        :param s1: first virtual source coordinates
        :param s2: second virtual source coordinates
        :return: the coordinates of the higher order virtual source generated through
        the combination of s1 and s2
        """
        # p2 is a point on the hypothetical wall defined by s2, that is, a point on
        # the median plane between the loudspeaker and s2
        p2 = (loudspeaker + s2) / 2

        # n2 is the outward pointing unit normal
        n2 = (loudspeaker - s2) / np.linalg.norm(loudspeaker - s2)

        return s1 + 2 * np.dot((p2 - s1), n2) * n2

    def perpendicular(a):
        """
        This method computes the perpendicular to a given vector.
        :param a: the given vector
        :return: the perpendicular vector
        """
        b = np.empty_like(a)
        b[0] = -a[1]
        b[1] = a[0]
        return b

    # Instantiating the array to contain the distance of each virtual source from the loudspeaker
    distances_from_speaker = []

    # Computing the distances
    for source in candidate_virtual_sources:
        distances_from_speaker.append(np.linalg.norm(source - loudspeaker))

    # Re-ordering the list of virtual sources according to their distance from the loudspeaker
    candidate_virtual_sources = np.array(candidate_virtual_sources)
    sorted_virtual_sources = candidate_virtual_sources[np.array(
        distances_from_speaker).argsort()][1:]

    # Initialize the list of planes that constitutes the room
    room = []
    vertices = []
    # Initialize the boolean mask to identify the first-order virtual sources
    deleted = np.array([False] * len(sorted_virtual_sources), dtype=bool)

    for i in range(len(sorted_virtual_sources)):
        for j in range(i):
            for k in range(i):
                # The following two conditions verify if the current virtual source is a combination of lower order
                # virtual sources: if so, it is deleted from the available candidates
                if j != k and k < i:
                    if np.linalg.norm(
                            combine(sorted_virtual_sources[j],
                                    sorted_virtual_sources[k]) -
                            sorted_virtual_sources[i]) < dist_thresh:
                        deleted[i] = True

    # If the room is a "Shoebox" it is possible to exploit geometric properties to filter out
    # "ghost" image sources from the first order reflections.
    if shoebox:

        # Array containing the direction of the axes passing through the source position
        directions = []

        if len(loudspeaker) == 2:
            x = sp.Line(loudspeaker, loudspeaker + [0, 1])
            y = sp.Line(loudspeaker, loudspeaker + [1, 0])
            directions.append(x)
            directions.append(y)

        elif len(loudspeaker) == 3:
            planes = []
            x = sp.Plane(loudspeaker, [1, 0, 0])
            y = sp.Plane(loudspeaker, [0, 1, 0])
            z = sp.Plane(loudspeaker, [0, 0, 1])
            planes.append(x)
            planes.append(y)
            planes.append(z)
            for i in range(3):
                for j in range(i):
                    directions.append(planes[i].intersection(planes[j])[0])

        for i in range(len(sorted_virtual_sources)):
            if not deleted[i]:
                for index, direction in enumerate(directions):
                    if direction.distance(sp.Point(
                            sorted_virtual_sources[i])) < dist_thresh:
                        break
                    else:
                        if index == len(directions) - 1:
                            deleted[i] = True

    # If the virtual source is not a combination of lower order virtual sources, the corresponding plane
    # is built and it is added to the room's walls list

    for i in range(len(sorted_virtual_sources)):
        if not deleted[i]:
            # pi is a point on the hypothetical wall defined by si, that is, a point on
            # the median plane between the loudspeaker and si
            pi = (loudspeaker + sorted_virtual_sources[i]) / 2
            # ni is the outward pointing unit normal
            ni = (loudspeaker - sorted_virtual_sources[i]
                  ) / np.linalg.norm(loudspeaker - sorted_virtual_sources[i])

            plane = {}

            if len(pi) == 2:
                ni_perp = perpendicular(ni)
                pi2 = pi + ni_perp
                plane = sp.Line(pi, pi2)

            elif len(pi) == 3:
                plane = sp.Plane(sp.Point3D(pi), normal_vector=ni)

            # If the room is empty, we add the first plane to the list of half-spaces whose intersection
            # determines the final room
            if len(room) == 0:
                room.append(plane)
            else:
                for wall in room:
                    if len(plane.intersection(wall)) > 0:
                        room.append(plane)
                        break
                if plane not in room:
                    deleted[i] = True
    if room[0].ambient_dimension == 2:
        for wall1 in range(len(room)):
            for wall2 in range(wall1):
                if wall1 != wall2:
                    intersections = room[wall2].intersection(room[wall1])
                    if len(intersections) > 0:
                        for intersection in intersections:
                            if abs(float(intersection.x)) < 100 and abs(
                                    float(intersection.y)) < 100:
                                vertices.append(intersection)

    if room[0].ambient_dimension == 3:
        planes_intersections = []
        for wall1 in range(len(room)):
            for wall2 in range(wall1):
                if wall1 != wall2:
                    planes_intersections.append(room[wall2].intersection(
                        room[wall1]))

        for inter1 in range(len(planes_intersections)):
            for inter2 in range(inter1):
                if inter1 != inter2:
                    intersections = planes_intersections[inter2][
                        0].intersection(planes_intersections[inter1][0])
                    if len(intersections) > 0:
                        for intersection in intersections:
                            if abs(float(intersection.x)) < 100 and abs(
                                    float(intersection.y)) < 100 and abs(
                                        float(intersection.z)
                                    ) < 100 and intersection not in vertices:
                                vertices.append(intersection)
    return room, vertices
示例#14
0
文件: letsdothis.py 项目: al0cam/OPM
import platform
platform.platform()
platform.python_version()

import numpy as np
import numpy.linalg as LA
import math

import sympy
from sympy import var

#Zadavanje ravnine pomoću tri nekolinearne točke
T1 = sympy.Point3D(35, 33, -46)
T2 = sympy.Point3D(-36, -40, -44)
T3 = sympy.Point3D(0, -11, 48)
rav = sympy.Plane(T1, T2, T3)
print("Zadavanje ravnine pomoću tri nekolinearne točke: ", rav)

#dvije ravnine
pi1 = sympy.Plane(sympy.Point3D(0.92857, 0, 0), (-14, 7, -8))
print(pi1.equation())

pi2 = sympy.Plane(sympy.Point3D(0, 1.869565, 0), (21, -23, 32))
print(pi2.equation())

normala1 = pi1.intersection(pi2)[0]
print(normala1.equation())
kut = rav.angle_between(normala1)
print(kut)
print(kut)
kut2 = (round(kut, 10) * 180 / np.pi)
示例#15
0
import sympy
from sympy import var

H = sympy.Point3D(18, -95, 56)

pravac1 = sympy.Line3D(sympy.Point3D(10, -27, 24), sympy.Point3D(-17, -65, 63))
pravac2 = sympy.Line3D(sympy.Point3D(41, 54, 86), sympy.Point3D(43, 129, 32))

s1 = sympy.Matrix(pravac1.direction_ratio)
s2 = sympy.Matrix(pravac2.direction_ratio)

nor = s1.cross(s2)
nor_pi1 = s1.cross(nor)

pi1 = sympy.Plane(sympy.Point3D(10, -27, 24), nor_pi1)

nor_pi2 = s2.cross(nor)
pi2 = sympy.Plane(sympy.Point3D(41, 54, 86), nor_pi2)

normala = pi1.intersection(pi2)[0]

N1 = normala.intersection(pravac1)[0]
N2 = normala.intersection(pravac2)[0]

pravaca = sympy.Line3D(H, N1)
pravacb = sympy.Line3D(H, N2)

vektora = sympy.Matrix(pravaca.direction_ratio)
vektorb = sympy.Matrix(pravacb.direction_ratio)
cross = vektora.cross(vektorb).norm()
示例#16
0
print("tocke A, B i D nisu kolinearne: ", sympy.Point3D.are_collinear(A, B, D),
      "\n")

#kosinus smjera radij vektora
A = sympy.Point3D(1, -2, 3)
O = sympy.Point3D(0, 0, 0)
print("kosinus smjera radij vektora: ", O.direction_cosine(A), "\n")

#kosinus smjera vektora odredjenog s dvije tocke
A = sympy.Point3D(1, 4, -2)
B = sympy.Point3D(0, -2, 1)
print("kosinus smjera vektora odredjenog s dvije tocke: ",
      A.direction_cosine(B), "\n")

#zadavanje ravnine pomocu tocke i vektora normale
rav = sympy.Plane(sympy.Point3D(1, 2, 1), (-2, 3, -1))
print("Ravnina uz pomoc tocke i vektora normale: ", rav)

#opci oblik jednadzbe ravnine
print("opci oblik jednadzbe ravnine: ", rav.equation())

#slucajana tocka u ravnini
ranT = rav.random_point()
print("Slucajna tocak u ravnini: ", ranT)

from sympy import var
#parametarska jednadzba ravnine
u, v = var('u v')
par = rav.arbitrary_point(u, v)
print("parametarska jednadzba ravnine: ", par)