Beispiel #1
0
 def random_instance(size_range, distortion_range):
     size = uniform(*size_range)
     distortion = uniform(*distortion_range)
     return RectangleShape(Point(size, size / distortion))
Beispiel #2
0
 def random_location(self):
     return Point.random_instance(Point.zero, Point.one)
Beispiel #3
0
 def polygon(self):
     return (Point(-self.extent.x, -self.extent.y),
             Point(self.extent.x, -self.extent.y),
             Point(-self.extent.x, self.extent.y),
             self.extent)
Beispiel #4
0
from __future__ import division
from math import cos, pi, sin
from random import choice, random
from shapeworld.util import Point
from shapeworld.world import Shape, Color, Texture

default_resolution = Point(100, 100)


class Entity(object):

    __slots__ = ('id', 'shape', 'color', 'texture', 'center', 'rotation',
                 'rotation_sin', 'rotation_cos', 'relative_topleft',
                 'relative_bottomright', 'topleft', 'bottomright',
                 'collisions')

    def __init__(self, shape, color, texture, center, rotation):
        assert isinstance(shape, Shape)
        assert isinstance(color, Color)
        assert isinstance(texture, Texture)
        assert isinstance(center, Point)
        assert isinstance(rotation, float) and 0.0 <= rotation < 1.0
        self.id = None
        self.shape = shape
        self.color = color
        self.texture = texture
        self.rotation = rotation
        self.rotation_sin = sin(-rotation * 2.0 * pi)
        self.rotation_cos = cos(-rotation * 2.0 * pi)
        self.set_center(center=center)
        self.collisions = dict()
Beispiel #5
0
    def collides(self, other, ratio=False, symmetric=False, resolution=None):
        if other.id in self.collisions and self.id in other.collisions:
            if not ratio:
                return min(self.collisions[other.id],
                           other.collisions[self.id]) > 0.0
            elif symmetric:
                return min(self.collisions[other.id],
                           other.collisions[self.id])
            else:
                return (self.collisions[other.id], other.collisions[self.id])

        topleft1 = self.topleft
        bottomright1 = self.bottomright
        topleft2 = other.topleft
        bottomright2 = other.bottomright
        if bottomright1.x < topleft2.x or topleft1.x > bottomright2.x or bottomright1.y < topleft2.y or topleft1.y > bottomright2.y:
            if other.id is not None:
                self.collisions[other.id] = 0.0
            if self.id is not None:
                other.collisions[self.id] = 0.0
            if not ratio:
                return False
            elif symmetric:
                return 0.0
            else:
                return (0.0, 0.0)
        else:
            topleft, bottomright = topleft1.max(topleft2), bottomright1.min(
                bottomright2)

        if resolution is None:
            resolution = default_resolution
        topleft *= resolution
        bottomright *= resolution
        average_resolution = 0.5 * (resolution.x + resolution.y)
        if ratio:
            granularity = 1.0 / resolution.x / resolution.y
            collision = 0.0
            for _, point in Point.range(topleft, bottomright, resolution):
                distance1 = max(
                    1.0 -
                    average_resolution * self.distance(point - self.center),
                    0.0)
                distance2 = max(
                    1.0 -
                    average_resolution * other.distance(point - other.center),
                    0.0)
                average_distance = 0.5 * (distance1 + distance2)
                if average_distance > 0.95:
                    collision += granularity * average_distance
            collision1 = collision / self.shape.area
            collision2 = collision / other.shape.area
            if other.id is not None:
                self.collisions[other.id] = collision1
            if self.id is not None:
                other.collisions[self.id] = collision2
            if symmetric:
                return min(collision1, collision2)
            else:
                return (collision1, collision2)
        else:
            min_distance = 1.0 / average_resolution
            for _, point in Point.range(topleft, bottomright, resolution):
                if (self.distance(point - self.center) <= min_distance) and (
                        other.distance(point - other.center) <= min_distance):
                    return True
Beispiel #6
0
 def size(self):
     return Point(0.5, 0.5)
Beispiel #7
0
 def __init__(self, size):
     if isinstance(size, float):
         size = Point(size, size)
     return super(SquareShape, self).__init__(size=size)
Beispiel #8
0
 def distance(self, offset):
     offset += Point(0.0, self.size.y)
     if offset.y < 0.0:
         return (abs(offset) - Point(self.size.x, 0.0)).positive().length
     else:
         return max(offset.length - self.size.x, 0.0)
Beispiel #9
0
 def polygon(self):
     return (Point(-self.size.x,
                   -self.size.y), Point(self.size.x, -self.size.y),
             Point(-self.size.x,
                   self.size.y), Point(self.size.x, self.size.y))
Beispiel #10
0
 def __contains__(self, offset):
     offset += Point(0.0, self.size.y)
     return offset.length <= self.size.x and offset.y >= 0.0
Beispiel #11
0
 def __init__(self, size):
     if isinstance(size, float):
         size = Point(size, size * 0.5)
     return super(SemicircleShape, self).__init__(size=size)
Beispiel #12
0
 def from_model(model):
     return Shape.shapes[model['name']](
         size=Point.from_model(model['size']))
Beispiel #13
0
 def __init__(self, size):
     if isinstance(size, float):
         size = Point(size, size * cos18)
     return super(PentagonShape, self).__init__(size=size)
Beispiel #14
0
 def __init__(self, size):
     if isinstance(size, float):
         size = Point(size, size * sqrt34)
     return super(TriangleShape, self).__init__(size=size)