예제 #1
0
def angle_between(road1: Segment, road2: Segment) -> float:
    """
    Gets the smaller angle in deg formed by two connected roads.
    Always returns a positive float
    """

    len1 = road1.length()
    len2 = road2.length()

    # Find the third line in the triangle formed by lines 1 & 2
    if road1.start == road2.start:
        len3 = vectors.distance(road1.end, road2.end)
    elif road1.start == road2.end:
        len3 = vectors.distance(road1.end, road2.start)
    elif road1.end == road2.start:
        len3 = vectors.distance(road1.start, road2.end)
    elif road1.end == road2.end:
        len3 = vectors.distance(road1.start, road2.start)

    # Calculate the angle between the roads using the law of cosines
    num = math.pow(len1, 2) + math.pow(len2, 2) - math.pow(len3, 2)
    den = 2 * len1 * len2

    quo = num / den

    # Avoid errors from floating point inaccuracy
    if quo > 1:
        quo = 1
    elif quo < -1:
        quo = -1

    res = math.degrees(math.acos(quo))

    return res
예제 #2
0
    def spans_feature(self, cube):
        x0, y0, z0, x1, y1, z1 = cube
        if y0 < 0 or y1 < 0:
            return False
        if self.depth < 6:  # this may require adjustment
            for circle in Octree.circles:
                rad, x, y, z = circle
                edges = self.getedges()
                for edge in edges:
                    dist, loc = pnt2line((x, y, z), edge[0], edge[1])
                    if dist <= rad:
                        return True
        verts = [(x0, y0, z0), (x0, y1, z0), (x1, y1, z0), (x1, y0, z0),
                 (x0, y0, z1), (x0, y1, z1), (x1, y1, z1), (x1, y0, z1)]

        for circle in Octree.circles:
            rad, x, y, z = circle
            center = (x, y, z)
            span = 0

            for vert in verts:
                d = distance(vert, center)
                span += (d <= rad)
            #if span > 0: print span
            if span > 0 and span < 8:
                return True
        return False
예제 #3
0
def road_near_point(screen_pos: Tuple[float, float],
                    screen_data: 'drawing.ScreenData',
                    city: generation.City) -> Optional[roads.Segment]:
    """
    Gets the closest road to the given point within 100 units
    :param screen_pos: The screen-position to look around
    :param screen_data: The current state of the view port
    :param city: A city with sectors and roads to search
    :return: The nearest road if there is one within 100 units of the point,
    None otherwise
    """
    world_pos = drawing.screen_to_world(screen_pos, screen_data.pan,
                                        screen_data.zoom)
    closest: Tuple[roads.Segment, float] = (None, 9999)
    found_road = None
    examine_sectors = sectors.from_point(world_pos, 100)

    for sector in examine_sectors:
        if sector in city.sectors:
            for road in city.sectors[sector]:
                dist = vectors.distance(world_pos, road.point_at(0.5))
                if dist < closest[1]:
                    closest = (road, dist)
            if closest[1] < 100:
                found_road = closest[0]

    return found_road
예제 #4
0
파일: octree.py 프로젝트: squeakus/octree
    def spans_feature(self, cube):
        x0,y0,z0,x1,y1,z1 = cube
        if y0 < 0 or y1 < 0:
            return False
        if self.depth < 6: # this may require adjustment
            for circle in Octree.circles:
                rad,x,y,z = circle
                edges = self.getedges()
                for edge in edges:
                    dist,loc = pnt2line((x,y,z), edge[0], edge[1])
                    if dist <= rad:
                        return True
        verts = [(x0,y0,z0),(x0,y1,z0),(x1,y1,z0),(x1,y0,z0),
                 (x0,y0,z1),(x0,y1,z1),(x1,y1,z1),(x1,y0,z1)]

        for circle in Octree.circles:
            rad,x,y,z = circle
            center = (x,y,z)
            span = 0
            
            for vert in verts:
                d = distance(vert,center)
                span += (d <= rad)
            #if span > 0: print span
            if span > 0 and span < 8:
                return True
        return False
예제 #5
0
def getNeighborhood(boid):
	neighborhood = []
	for b in boids:

		if b.getName() == boid.getName():
			continue

		distance = vectors.distance(b.getPosition(), boid.getPosition())
		if distance < boid.neighborhoodRadius:
			neighborhood.append(b)

	return neighborhood
def pnt2line(pnt, start, end):
    line_vec = vec.vector(start, end)
    pnt_vec = vec.vector(start, pnt)
    line_len = vec.length(line_vec)
    line_unitvec = vec.unit(line_vec)
    pnt_vec_scaled = vec.scale(pnt_vec, 1.0 / line_len)
    t = vec.dot(line_unitvec, pnt_vec_scaled)
    if t < 0.0:
        t = 0.0
    elif t > 1.0:
        t = 1.0
    nearest = vec.scale(line_vec, t)
    dist = vec.distance(nearest, pnt_vec)
    nearest = vec.add(nearest, start)
    return (dist, nearest)
예제 #7
0
def do_segments_intersect(s1, s2):
    u1, u2 = s1
    v1, v2 = s2
    l1, l2 = distance(*s1), distance(*s2)
    try:
        x, y = intersection(u1, u2, v1, v2)
        return (distance(u1, (x, y)) <= l1 and distance(u2, (x, y)) <= l1
                and distance(v1, (x, y)) <= l2 and distance(v2, (x, y)) <= l2)
    except np.linalg.linalg.LinAlgError:
        return False
예제 #8
0
def segment_checks(s1, s2):
    u1, u2 = s1
    v1, v2 = s2
    l1, l2 = distance(*s1), distance(*s2)
    x, y = intersection(u1, u2, v1, v2)
    return [
        distance(u1, (x, y)) <= l1,
        distance(u2, (x, y)) <= l1,
        distance(v1, (x, y)) <= l2,
        distance(v2, (x, y)) <= l2
    ]
예제 #9
0
파일: geometry.py 프로젝트: ienlaw/sequtus
def rect_collision_distance(a1, a2, testing=False):
    """
    Returns a pair of distances moving a1 and a2 to the point of collision
    when testing is set to true it will return the internal variables used
    to ensure that all parts of the function are working correctly.
    
    Each argument is assumed to be the angle of position and movement
    for each actor.
    
    We have a triangle of A, B and C where A and B are the two actors
    and C is the point of collision. a, b and c are the edges opposite
    their respective angle.
    
    Our first problem is to find A and B. We have Angle to C and Angle to A/B
    to start with and can work out the inside angle from those.
    """

    # Calcuate angles
    A, B, C = inside_angles(a1, a2)

    # Now for the sides, we can start with c using just pythagoras
    c = vectors.distance(a1[0], a2[0])

    try:
        a = c / math.sin(math.radians(C)) * math.sin(math.radians(A))
        b = c / math.sin(math.radians(C)) * math.sin(math.radians(B))
    except Exception as e:
        print("a1 = %s" % a1)
        print("a2 = %s" % a2)
        print("A: %s, B: %s, C: %s" % (A, B, C))
        raise

    if testing:
        return A, B, C, a, b, c
    else:
        return a, b
예제 #10
0
파일: geometry.py 프로젝트: Teifion/sequtus
def rect_collision_distance(a1, a2, testing=False):
    """
    Returns a pair of distances moving a1 and a2 to the point of collision
    when testing is set to true it will return the internal variables used
    to ensure that all parts of the function are working correctly.
    
    Each argument is assumed to be the angle of position and movement
    for each actor.
    
    We have a triangle of A, B and C where A and B are the two actors
    and C is the point of collision. a, b and c are the edges opposite
    their respective angle.
    
    Our first problem is to find A and B. We have Angle to C and Angle to A/B
    to start with and can work out the inside angle from those.
    """
    
    # Calcuate angles
    A, B, C = inside_angles(a1, a2)
    
    # Now for the sides, we can start with c using just pythagoras
    c = vectors.distance(a1[0], a2[0])
    
    try:
        a = c/math.sin(math.radians(C)) * math.sin(math.radians(A))
        b = c/math.sin(math.radians(C)) * math.sin(math.radians(B))
    except Exception as e:
        print("a1 = %s" % a1)
        print("a2 = %s" % a2)
        print("A: %s, B: %s, C: %s" % (A, B, C))
        raise
    
    if testing:
        return A, B, C, a, b, c
    else:
        return a, b
예제 #11
0
def heuristic(road: roads.Segment, goal: roads.Segment) -> float:
    return vectors.distance(road.point_at(0.5), goal.point_at(0.5)) * 0.1
예제 #12
0
    ]


def sum_of_squares_gradient(v):
    return [2 * v_i for v_i in v]


#pick a random starting point
v = [random.randint(-10, 10) for i in range(3)]

tolerance = 0.0000001

while True:
    gradient = sum_of_squares_gradient(v)  #compute the gradient at v
    next_v = step(v, gradient, -0.01)  #take a negtive gradient step
    if distance(next_v, v) < tolerance:  #stop if you are converging
        break
    v = next_v  #continue if you're not
"""Choosing the right step_size"""
"""Some step sizes can result invalid inputs for functions.
 avoid this, we create a safe apply function."""


def safe(f):
    """return new function that's the sme as f,
    except htat it outputs infinity whenever
    f produces an error"""
    def safe_f(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except:
예제 #13
0
def is_between(a, b, p, epsilon=10):
    total_distance = vectors.distance(a, b)
    part_distance1 = vectors.distance(a, p)
    part_distance2 = vectors.distance(b, p)
    return abs(part_distance1 + part_distance2 - total_distance) < epsilon
예제 #14
0
 def length(self) -> float:
     return vectors.distance(self.start, self.end)
예제 #15
0
 def test_can_calculate_distance(self):
     vector_a = [5, 8]
     vector_b = [2, 4]
     self.assertEquals(vectors.distance(vector_a, vector_b), 5)