예제 #1
0
def coll_box2box(box1, box2, **kwargs):
    atol = cmp_atol
    verbose = False
    # handle all arguments
    for key, value in kwargs.items():
        if key == 'verbose':
            verbose = value
        elif key == 'atol':
            atol = value

    if verbose:
        debug('calculating collision between two boxes')
        debug(' atol=%g' % atol)
    result = CollisionResult()

    collision = box_inside_box(box1, box2, atol, verbose)
    if not collision:
        collision = box_inside_box(box2, box1, atol, verbose)

    result['collision'] = collision

    if verbose:
        debug('collision:', result['collision'])
        debug('Done.')

    return result
예제 #2
0
    def __init__(self, x1: Vector, x2: Vector, verbose: bool=False):
        BasicObject.__init__(self, verbose=verbose)
        self._x1 = x1
        self._x2 = x2

        self._center = (x2 - x1) / 2.

        self._six, self._corners = self.get_box_planes_and_corners(self._x1,
                                                                   self._x2)

        self._volume = self.get_volume(self._center)

        if self._verbose:
            debug('reference volume:', self._volume)
예제 #3
0
def box_inside_box(box1, box2, atol, verbose):
    # the algorithm based on the assumption that we can check if
    # all corner points of box1 are not in box2 the box1 has no
    # overlap with box2 (true, but one has to check the other way
    # as well)!

    for i in box1._corners:
        i = box1.calculate_position(i)
        vol = box2.get_volume(center=i)
        if verbose:
            debug(' c=%s vol=%g vol_ref=%g' % (i, vol, box2._volume))
        if np.isclose(vol, box2._volume, rtol=atol, atol=atol):
            return True

    return False
예제 #4
0
def coll_plane2plane(plane1, plane2, **kwargs):
    atol = cmp_atol
    verbose = False
    # handle all arguments
    for key, value in kwargs.items():
        if key == 'verbose':
            verbose = value
        elif key == 'atol':
            atol = value

    if verbose:
        debug('calculating collision between two planes')
        debug(' atol=%g' % atol)
    result = CollisionResult()

    cross = np.cross(plane1.norm_vector, plane2.norm_vector)

    if verbose:
        debug(' cross_check_vector=%s' % cross)

    # if the cross vector has zero length, that there both
    # norm vectors are parallel
    if not np.isclose(nl.norm(cross), 0., atol=atol):
        result['collision'] = True
        result['type'] = 'crossing'
        p, v = intersection_of_planes(plane1.norm_vector, plane1.distance,
                                      plane2.norm_vector, plane2.distance)
        result['intersection'] = 'line'
        result['intersection_params'] = (p, v)
    else:
        if np.isclose(plane1.distance, plane2.distance, atol=atol):
            result['collision'] = True
            result['type'] = 'identical'
            result['intersection'] = 'plane'
            result['intersection_params'] = (plane1.distance, plane2.distance)

    if verbose:
        debug('collision:', result['collision'])
        debug('Done.')

    return result
예제 #5
0
def intersection_line_plane(edge, norm_vector, distance, atol=cmp_atol):
    """
    intersection_line_plane

    calculates the intersection point between a ray and a plane
    """
    edge_direction = edge[0] - edge[1]

    plane_point = point_of_plane(norm_vector, distance)

    debug(' plane_point=%s' % plane_point)

    ndotu = norm_vector.dot(edge_direction)

    if abs(ndotu) < atol:
        debug(' no intersection or line is within plane')
        return None

    w = edge[0] - plane_point
    si = -norm_vector.dot(w) / ndotu
    Psi = w + si * edge_direction + plane_point

    print(Psi)
    debug(' intersection point=%s' % Psi)

    return Psi
예제 #6
0
def coll_sphere2sphere(sph1, sph2, **kwargs):
    atol = cmp_atol
    verbose = False
    # handle all arguments
    for key, value in kwargs.items():
        if key == 'verbose':
            verbose = value
        elif key == 'atol':
            atol = value

    if verbose:
        debug('calculating collision between two spheres')
    result = CollisionResult()

    # calculate the distance of the two spheres
    distance = np.sqrt(np.sum((sph1.position - sph2.position)**2))

    result['distance'] = distance
    if verbose:
        debug(' absolute distance is: %g' % distance)

    distance -= sph1.radius + sph2.radius

    result['outerdistance'] = distance
    if verbose:
        debug(' outer distance is: %g' % distance)

    # every outside atol is clear
    if distance < atol:
        result['collision'] = True
    else:
        result['collision'] = np.isclose(distance, 0., atol=atol)

    if verbose:
        debug(' collision:', result['collision'])
        debug('Done.')

    return result
예제 #7
0
def coll_box2plane(box, plane, **kwargs):
    atol = cmp_atol
    verbose = False
    # handle all arguments
    for key, value in kwargs.items():
        if key == 'verbose':
            verbose = value
        elif key == 'atol':
            atol = value

    if verbose:
        debug('calculating collision between a box and a plane')
        debug(' atol=%g' % atol)
    result = CollisionResult()

    distances = np.zeros(len(box._corners))
    c = box.corners
    for i in range(len(distances)):
        distances[i] = distance_to_plane(c[i], plane.norm_vector,
                                         plane.distance)

    if verbose:
        debug(' distances=%s' % distances)

    nnp = nnm = nnn = 0
    for i in distances:
        if np.isclose(i, 0., atol=atol):
            nnn += 1
        elif i > atol:
            nnp += 1
        else:
            nnm += 1

    if verbose:
        debug(' (nnp, nnm, nnn)=(%i, %i, %i)' % (nnp, nnm, nnn))

    if nnn > 0:
        # one or more points directly on the plane
        result['collision'] = True
    else:
        if (nnp != 8) or (nnm != 8):
            result['collision'] = True

    if result['collision']:
        # try to get the intersection figure
        edges = box.edges
        points = []
        for e in edges:
            # test a single edge ...
            p = intersection_line_plane(e, plane.norm_vector, plane.distance)
            if p is not None:
                vol = box.get_volume(center=p)
                if verbose:
                    debug(' c=%s vol=%g vol_ref=%g' % (i, vol, box._volume))
                if np.isclose(vol, box._volume, rtol=atol, atol=atol):
                    points.append(p)

        points = np.array(points)

        if verbose:
            debug(' points (unsorted) in the plane = %s' % points)
        if len(points) > 3:
            points = polygon_sort(points, plane.norm_vector, atol=atol)

        if verbose:
            debug(' points (sorted) in the plane = %s' % points)

    if verbose:
        debug('collision:', result['collision'])
        debug('Done.')

    return result
예제 #8
0
def coll_sphere2plane(sphere, plane, **kwargs):
    atol = cmp_atol
    verbose = False
    # handle all arguments
    for key, value in kwargs.items():
        if key == 'verbose':
            verbose = value
        elif key == 'atol':
            atol = value

    if verbose:
        debug('calculating collision between a sphere and a plane')
        debug(' atol=%g' % atol)
    result = CollisionResult()

    v = sphere.position

    # the vector s is the vector which is perpendicular to
    # the plane pointing direct to the center of the sphere
    # s = projection_vector(v, plane.norm_vector)
    # distance = nl.norm(s) + plane.distance
    distance = np.abs(distance_to_plane(v, plane.norm_vector, plane.distance))

    result['distance'] = distance
    if verbose:
        debug(' absolute distance is: %g' % distance)

    distance -= sphere.radius

    result['outerdistance'] = distance
    if verbose:
        debug(' outer distance is: %g' % distance)

    # every outside atol is clear
    result['collision'] = np.isclose(distance, 0., atol=atol)

    if verbose:
        debug('collision:', result['collision'])
        debug('Done.')

    return result