コード例 #1
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]
コード例 #2
0
    def is_b_not_far_than_a(self, origin, a, b):
        origin = sp.Point3D(origin[0], origin[1], origin[2])
        a = sp.Point3D(a[0], a[1], a[2])
        b = sp.Point3D(b[0], b[1], b[2])

        v1 = a - origin
        v2 = b - origin
        dot = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
        if dot < 0:
            return True
        return sp.Segment3D(origin, a).length > sp.Segment3D(origin, b).length
コード例 #3
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]))
コード例 #4
0
ファイル: utils.py プロジェクト: ArroyoDev-LLC/3dframe
def find_center_of_gravity(*points: Sequence[S.Point3D]) -> S.Point3D:
    """Find the barycenter of X num of points."""
    pts_range = len(points)
    x_coord = sum([p.x for p in points]) / pts_range
    y_coord = sum([p.y for p in points]) / pts_range
    z_coord = sum([p.z for p in points]) / pts_range
    return S.Point3D(x_coord, y_coord, z_coord)
コード例 #5
0
ファイル: structure.py プロジェクト: LPDI-EPFL/topobuilder
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')
コード例 #6
0
 def rotate_around_axis(self, axis, angle):
     transform_matrix = Quaternion.from_axis_angle(
         (axis[0], axis[1], axis[2]), angle).to_rotation_matrix(
             (self.center[0], self.center[1], self.center[2]))
     for i in range(8):
         p = self.points[i]
         spp = sp.Point3D(p[0], p[1], p[2])
         spp = spp.transform(transform_matrix)
         self.points[i] = [spp.x.evalf(), spp.y.evalf(), spp.z.evalf()]
コード例 #7
0
ファイル: structure.py プロジェクト: LPDI-EPFL/topobuilder
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)
コード例 #8
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]
コード例 #9
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]
コード例 #10
0
ファイル: utils.py プロジェクト: ArroyoDev-LLC/3dframe
def find_missing_rect_vertex(pa: S.Point3D, pb: S.Point3D,
                             pc: S.Point3D) -> S.Point3D:
    """Given 3 3d points of a rectangle, find a return the fourth missing vertex.

    Equation:
        (x,y,z)w = (x,y,z)t + (x,y,z)v − (x,y,z)u

    Where:
        Sub w: resulting missing vertex.
        Sub t: a point in hypotenuse TV.
        Sub v: a point in hypotenuse TV.
        Sub u: 'corner' point (usually forming right angle).

    """

    # Determine which two points are the furthest from each other.
    # The 'unused' point is our corner.
    vert_t = None
    vert_v = None
    for test_a, test_b in itertools.permutations(
        (
            pa,
            pb,
            pc,
        ),
            2,
    ):
        cur_dist = None
        if vert_t and vert_v:
            cur_dist = vert_t.distance(vert_v)
        dist = test_a.distance(test_b)
        if cur_dist is None:
            cur_dist = dist
        if dist >= cur_dist:
            vert_t = test_a
            vert_v = test_b

    vert_u = next(iter({pa, pb, pc} - {vert_t, vert_v}))

    x, y, z = S.symbols("x y z")
    expr = x + y - z
    pd_pts = []
    for attr in (
            "x",
            "y",
            "z",
    ):
        attr_pt = expr.subs([(x, getattr(vert_t, attr)),
                             (y, getattr(vert_v, attr)),
                             (z, getattr(vert_u, attr))])
        pd_pts.append(attr_pt)
    return S.Point3D(*pd_pts)
コード例 #11
0
 def centroid_point(self) -> S.Point3D:
     return S.Point3D(*self.centroid)
コード例 #12
0
 def as_sympy(self) -> S.Point3D:
     return S.Point3D(*self.point)
コード例 #13
0
 def face_centre(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]])
     p4 = sp.Point3D(self.points[self.faces[fid][2]])
     return (p1 + p2 + p3 + p4) / 4
コード例 #14
0
import platform
platform.platform()
platform.python_version()

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

import sympy
#from sympy import init_printing
#from sympy import Point3D

#zbroj radij vektora
print()
A = sympy.Point3D(1, -2, 7)
B = sympy.Point3D(9, 1, -5)
print("zbroj radij vektora: ", A + B, "\n")

#skaliranje radij vektora
print("skaliranje radij vektora: ", A.scale(2, 5, -3), "\n")

#skalarni produkt radij vektora
print("skalarni produkt radij vektora: ", A.dot(B), "\n")

#vektor odredjen s dvije tocke
A = sympy.Point3D(2, 3, 1)
B = sympy.Point3D(-4, 2, 5)
print("vektor odredjen s dvije tocke: ", A.direction_ratio(B), "\n")

#udaljenost tocaka
A = sympy.Point3D(1, 3, -2)
コード例 #15
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(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]
コード例 #16
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)
コード例 #17
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)
コード例 #18
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
コード例 #19
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))
コード例 #20
0
for i in range(DIM):
    mid[i] = 0.5 * (node1[i] + node2[i])
    edgevec[i] = node2[i] - node1[i]
    edgelength += edgevec[i] * edgevec[i]
edgelength = math.sqrt(edgelength)  # length of edgevec
for i in range(DIM):
    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
コード例 #21
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

pravac = sympy.Line3D(sympy.Point3D(66.5, -33.93, -93.39),
                      (41.22, 24.1, 69.82))
tocka = sympy.Point3D(19.43, -25.51, 32.48)
print(round(pravac.distance(tocka), 5))