Exemplo n.º 1
0
 def __init__(self, cameraOverlay, radius=20, mouseVisible=True):
     self.cameraOverlay = cameraOverlay
     Cursor.__init__(self, Vertex(0, 0))
     Dimensioned.__init__(self, Vertex(radius * 2, radius * 2))
     self.radius = radius
     self.color = (191, 191, 191)
     setMouseVisibility(mouseVisible)
Exemplo n.º 2
0
 def __init__(self, timer, length, height, algorithm, data):
     PyGameScene.__init__(self, timer, length, height)
     resolution = Milli()
     Intervaled.__init__(self, 1 / (resolution.scalor * 120), resolution)
     self.origin = Vertex(length / 2, height / 2)
     self.radius = min(*self.origin.components) * 0.80
     self.algorithm = algorithm
     self.reset(data)
Exemplo n.º 3
0
 def __init__(self, timer, length, height):
     PyGameScene.__init__(self, timer, length, height)
     Gravitational.__init__(
         self, 10, Vertex(DEMO_WINDOW_LENGTH / 2, DEMO_WINDOW_HEIGHT << 4))
     self.ball = Ball(
         32, Vertex(DEMO_WINDOW_LENGTH / 3, DEMO_WINDOW_HEIGHT / 3),
         Vector(BALL_VELOCITY, BALL_VELOCITY))
     self.wind = Wind(0.125)
     self.addEntity(self.ball)
Exemplo n.º 4
0
class ClockingScene(PyGameScene):
    def __init__(self, timer, length, height, continuous=False):
        PyGameScene.__init__(self, timer, length, height)
        # Start a new clock at the current local time.
        instant = datetime.now()
        self.clock = Clock(instant.hour, instant.minute, instant.second)
        self.addEntity(self.clock)  # Tap into the Temporal entity updating.

        # Use the center of the view as the origin of the clock face.
        self.origin = Vertex(length / 2, height / 2)

        # Track request for continuous mode or not.
        self.continuous = continuous

    def update(self, **kwargs):
        PyGameScene.update(self, **kwargs)

        self.scene.fill((0, 0, 0))

        # Draw a clock face.
        radius = min(self.origin.components) * 0.75
        pygame.draw.circle(self.scene, (127, 127, 127), self.origin.tupled(),
                           radius, 2)

        # Adjust reference angle from 0 tau (3 o'clock) to 1/4 tau (midnight).
        referenceAngle = -0.25 * tau
        referencePosition = self.origin + Vertex(
            cos(referenceAngle) * radius,
            sin(referenceAngle) * radius)
        # pygame.draw.line(self.scene, (127, 127, 0), self.origin.tupled(), referencePosition.tupled(), 2)

        # Draw the hour hand.
        hoursAngle = referenceAngle + (self.clock.hours % 12) / 12 * tau
        hourHandPosition = self.origin + Vertex(
            cos(hoursAngle) * radius,
            sin(hoursAngle) * radius)
        pygame.draw.line(self.scene, (127, 0, 0), self.origin.tupled(),
                         hourHandPosition.tupled(), 2)

        # Draw the minute hand.
        minutesAngle = referenceAngle + self.clock.minutes / 60 * tau
        minuteHandPosition = self.origin + Vertex(
            cos(minutesAngle) * radius,
            sin(minutesAngle) * radius)
        pygame.draw.line(self.scene, (0, 127, 0), self.origin.tupled(),
                         minuteHandPosition.tupled(), 2)

        # Draw the second hand.
        secondsAngle = referenceAngle + (self.clock.seconds
                                         if self.continuous else floor(
                                             self.clock.seconds)) / 60 * tau
        secondHandPosition = self.origin + Vertex(
            cos(secondsAngle) * radius,
            sin(secondsAngle) * radius)
        pygame.draw.line(self.scene, (0, 0, 127), self.origin.tupled(),
                         secondHandPosition.tupled(), 2)
Exemplo n.º 5
0
    def __init__(self, timer, length, height, continuous=False):
        PyGameScene.__init__(self, timer, length, height)
        # Start a new clock at the current local time.
        instant = datetime.now()
        self.clock = Clock(instant.hour, instant.minute, instant.second)
        self.addEntity(self.clock)  # Tap into the Temporal entity updating.

        # Use the center of the view as the origin of the clock face.
        self.origin = Vertex(length / 2, height / 2)

        # Track request for continuous mode or not.
        self.continuous = continuous
Exemplo n.º 6
0
    def __init__(self, timer, length, height):
        PyGameScene.__init__(self, timer, length, height)

        self.borders = []
        self.borders.append(
            Segment(Vertex(BORDER_SIZE, BORDER_SIZE),
                    Vertex(length - BORDER_SIZE, BORDER_SIZE)))  # Top
        self.borders.append(
            Segment(Vertex(length - BORDER_SIZE, BORDER_SIZE),
                    Vertex(length - BORDER_SIZE,
                           height - BORDER_SIZE)))  # Right
        self.borders.append(
            Segment(Vertex(BORDER_SIZE, height - BORDER_SIZE),
                    Vertex(length - BORDER_SIZE,
                           height - BORDER_SIZE)))  # Bottom
        self.borders.append(
            Segment(Vertex(BORDER_SIZE, BORDER_SIZE),
                    Vertex(BORDER_SIZE, height - BORDER_SIZE)))  # Left

        self.previewColor = (127, 127, 127)
        self.segmentColor = (0, 0, 127)

        # Track the four vertices/vectors comprising of the line segments AC and BD.
        self.capturePosition = False
        self.A = None
        self.AC = None

        # Indicate a 'mode' for checking for intersection between the line segments.
        self.checking = False
        self.derivativesColor = (127, 127, 0)
        self.intersectionColor = (255, 127, 127)
Exemplo n.º 7
0
    def __init__(self, columns, rows):
        if columns * rows <= 0:
            raise ValueError(
                f"The pixel dimensions of the sensor array are invalid: [{columns}, {rows}]"
            )

        Dimensioned.__init__(self, Vertex(columns, rows))
Exemplo n.º 8
0
  def live(self):
    # Breathe! Enjoy the moment(s) that have elapsed!
    velocity = self.velocity * self.accumulatedTime
    self.accumulatedTime = 0

    lastPosition = self.position.copy()

    # TODO: Use perception (do a perception check! lol) to determine
    # nearby entities that might interfere with the projection.

    nextPosition = self.projectBy(velocity)

    # Uh oh, there might be a barrier..!
    if self.environment:
      length, height = self.environment.dimensions.tupled()

      # Reflect the ray if necessary.
      px, vx = reflect(0, nextPosition.x, velocity.x, length)
      py, vy = reflect(0, nextPosition.y, velocity.y, height)

      if velocity.x != vx:
        self.onReflection()
        self.velocity.x *= -1

      if velocity.y != vy:
        self.onReflection()
        self.velocity.y *= -1

      nextPosition = Vertex(px, py)
  
    self.position = nextPosition

    # Use a line segment to indicate change in position.
    self.segment = Segment(lastPosition, self.position)
Exemplo n.º 9
0
  def __init__(self, timer, length, height, continuous=False):
    PyGameScene.__init__(self, timer, length, height)
    self.origin = Vertex(length / 2, height / 2)

    self.borders = list()
    self.borders.append(Segment(Vertex(BORDER_SIZE, BORDER_SIZE), Vertex(length - BORDER_SIZE, BORDER_SIZE))) # Top
    self.borders.append(Segment(Vertex(length - BORDER_SIZE, BORDER_SIZE), Vertex(length - BORDER_SIZE, height - BORDER_SIZE))) # Right
    self.borders.append(Segment(Vertex(BORDER_SIZE, height - BORDER_SIZE), Vertex(length - BORDER_SIZE, height - BORDER_SIZE))) # Bottom
    self.borders.append(Segment(Vertex(BORDER_SIZE, BORDER_SIZE), Vertex(BORDER_SIZE, height - BORDER_SIZE))) # Left

    # Ensure the radar beam can reach the corners of the screen.
    self.radar = Radar(self.origin)
    self.addEntity(self.radar) # Tap into the Temporal entity updating.
Exemplo n.º 10
0
    def update(self, **kwargs):
        PyGameScene.update(self, **kwargs)

        self.scene.fill((0, 0, 0))

        # Draw a clock face.
        radius = min(self.origin.components) * 0.75
        pygame.draw.circle(self.scene, (127, 127, 127), self.origin.tupled(),
                           radius, 2)

        # Adjust reference angle from 0 tau (3 o'clock) to 1/4 tau (midnight).
        referenceAngle = -0.25 * tau
        referencePosition = self.origin + Vertex(
            cos(referenceAngle) * radius,
            sin(referenceAngle) * radius)
        # pygame.draw.line(self.scene, (127, 127, 0), self.origin.tupled(), referencePosition.tupled(), 2)

        # Draw the hour hand.
        hoursAngle = referenceAngle + (self.clock.hours % 12) / 12 * tau
        hourHandPosition = self.origin + Vertex(
            cos(hoursAngle) * radius,
            sin(hoursAngle) * radius)
        pygame.draw.line(self.scene, (127, 0, 0), self.origin.tupled(),
                         hourHandPosition.tupled(), 2)

        # Draw the minute hand.
        minutesAngle = referenceAngle + self.clock.minutes / 60 * tau
        minuteHandPosition = self.origin + Vertex(
            cos(minutesAngle) * radius,
            sin(minutesAngle) * radius)
        pygame.draw.line(self.scene, (0, 127, 0), self.origin.tupled(),
                         minuteHandPosition.tupled(), 2)

        # Draw the second hand.
        secondsAngle = referenceAngle + (self.clock.seconds
                                         if self.continuous else floor(
                                             self.clock.seconds)) / 60 * tau
        secondHandPosition = self.origin + Vertex(
            cos(secondsAngle) * radius,
            sin(secondsAngle) * radius)
        pygame.draw.line(self.scene, (0, 0, 127), self.origin.tupled(),
                         secondHandPosition.tupled(), 2)
Exemplo n.º 11
0
    def handle(self, event):
        handled = False

        if event.type == pygame.QUIT:
            handled = self.onQuit()
        elif event.type == pygame.MOUSEMOTION:
            handled = self.onMousePositionChanged(Vertex(*event.pos))
        elif event.type == pygame.MOUSEBUTTONDOWN:
            handled = self.onMouseButtonPressed(event.button)
        elif event.type == pygame.MOUSEBUTTONUP:
            handled = self.onMouseButtonReleased(event.button)

        return handled
Exemplo n.º 12
0
    def __init__(self, length, height, sensorArray, frameRate=FRAME_RATE):
        if length * height <= 0:
            raise ValueError(
                f"The physical dimensions of the camera sensor are invalid: [{length}, {height}]"
            )
        if not isinstance(sensorArray, CameraSensorArray):
            raise ValueError(
                "Expected 'sensorArray' to be a CameraSensorArray instance.")

        Dimensioned.__init__(self, Vertex(length, height))
        self.sensorArray = sensorArray
        interval = Milli()
        Intervaled.__init__(self, millisecondsPerFrame(frameRate), interval)
        self.capturing = False
Exemplo n.º 13
0
    def update(self, **kwargs):
        self.scene.fill((0, 0, 0))

        length, height = self.dimensions.tupled()

        # Draw a line for each data point.
        for index in range(len(self.data)):
            point = self.data[index]
            rads = self.radialize(index)

            outer = self.origin + Vertex(
                cos(rads) * length * .45,
                sin(rads) * height * .45)
            color = self.colorize(point)

            try:
                smoothLine(self.scene, color, self.origin.tupled(),
                           outer.tupled())
                # jaggedLine(self.scene, color, self.origin.tupled(), outer.tupled())
            except TypeError as oops:
                print(f"Failed at {origin} -> {outer}: {oops}!")
                break
Exemplo n.º 14
0
 def __init__(self, timer, dimensions):
     Dimensioned.__init__(self, Vertex(*dimensions))
     Environment.__init__(self, timer)
Exemplo n.º 15
0
 def __init__(self, length, height):
     CameraMount.__init__(self, Vertex(length, height))
Exemplo n.º 16
0
    def intersection(AC, BD):
        if not isinstance(AC, Segment):
            raise TypeError("Expected 'a' to be an instance of Segment!")

        if not isinstance(BD, Segment):
            raise TypeError("Expected 'b' to be an instance of Segment!")

        # Goal: Determine the intersection of line segments AC and BD, if it exists.
        I, delta = None, None

        try:
            # Objective: Find the angle of intersection from A to I to B, or angle AIB.
            # ================================
            # The method used will be to find the angles of ABD and BAC, and subtract
            # their summation from the sum of angles in any triangle, 180* or π. We'll
            # be using radians, so as to find a "slice of π". ^_^

            # Task: Calculate angle ABD.
            # --------------------------------
            vAB = AC.debut - BD.debut
            vBD = BD.arret - BD.debut
            ABD = Vertex.angleBetween(vAB, vBD)

            # Task: Calculate angle BAC.
            # --------------------------------
            vBA = BD.debut - AC.debut
            vAC = AC.arret - AC.debut
            BAC = Vertex.angleBetween(vBA, vAC)

            # Task: Derive the angle AIB.
            # --------------------------------
            AIB = pi - (ABD + BAC)

            # Objective: Find the lengths of line segments AB, AI, and BI.
            # ================================
            # We'll be using the rule of sines, as we already know the length of
            # line segment AB, which also happens to correspond to angle AIB, so
            # we'll call it.. i.
            ai = vAB.magnitude()
            bi = vBA.magnitude()

            # Task: Calculate the lengths of line segments AI and BI.
            # --------------------------------
            af = abs(
                ai * sin(ABD) / sin(AIB)
            )  # The length of line segment AI along line segment AC. It can't be negative.
            bf = abs(
                bi * sin(BAC) / sin(AIB)
            )  # The length of line segment BI along line segment BD. It can't be negative.

            # Objective: Find the intersection vertex I.
            # ================================
            # If an intersection exists, the lengths of AI or BI must be less than or equal to
            # AC or BD, respectively.
            if af <= vAC.magnitude() and bf <= vBD.magnitude():

                # Task: Calculate the intersection vertices Ia and Ib.
                # --------------------------------
                # Since we know the lengths of AI and BI, we can scale the unit vectors of the
                # respective line segments to derive "their I"s.
                Ia = AC.debut + (vAC.unit() * af)
                Ib = BD.debut + (vBD.unit() * bf)

                # print(f"Ia: {Ia}; Ib: {Ib}")

                # Task: Derive the intersection vertex I.
                # --------------------------------
                # But only if the values are close enough; otherwise, no deal!

                if isclose(Ia[0], Ib[0]) and isclose(Ia[1], Ib[1]):
                    I = Ia

                    # Due to potential rounding issues, we'll provide the delta of the calculated
                    # intersection vectors.
                    delta = Ia - Ib

        except ZeroDivisionError:
            # If we get a division by zero error... either there was a line length of 0, or
            # something... interesting happened.
            pass
            # TODO: What to do in this case? As one test outputs:
            # No intersection between [130, 351] --- [521, 154] and [521, 154] --- [521, 154].
            # Technically, the intersection point is [521, 154], but because the second line
            # has a length of zero, the algorithm above cannot find one of the angles, given
            # that the vector has zero length (in this case, vBD).
        except ValueError:
            # This can happen when exceeding the domain of math.acos(numerator/divisor).
            # I didn't know .. math had a domain that could error out.
            pass

        return (I, delta)
Exemplo n.º 17
0
class SortingScene(PyGameScene, Intervaled):
    def __init__(self, timer, length, height, algorithm, data):
        PyGameScene.__init__(self, timer, length, height)
        resolution = Milli()
        Intervaled.__init__(self, 1 / (resolution.scalor * 120), resolution)
        self.origin = Vertex(length / 2, height / 2)
        self.radius = min(*self.origin.components) * 0.80
        self.algorithm = algorithm
        self.reset(data)

    def shuffle(self, shuffles=3000):
        count = 0
        while count < shuffles:
            a = randint(0, len(self.data) - 1)
            b = randint(0, len(self.data) - 1)

            if a != b:
                self.data[a], self.data[b] = self.data[b], self.data[a]
                count += 1

    def reset(self, data):
        self.data = data
        self.shuffle()
        self.algorithm.reset()
        self.delayed = False

    def onMouseButtonPressed(self, button):
        handled = False

        if button == pygame.BUTTON_LEFT:
            # Only allow a shuffle if the algorithm is finished.
            if self.algorithm.finished(self.data):
                if not self.delayed:
                    self.delayed = True
                else:
                    self.reset(self.data)
            handled = True

        return handled

    def radialize(self, value):
        return radians((value - 0) / (len(self.data) - 0) * 360)

    def colorize(self, value):
        # Based on https://www.particleincell.com/2014/colormap/ (the "Long Rainbow")
        f = (value - 0) / (len(self.data) - 0)

        a = (1 - f) / 0.2
        X = floor(a)
        Y = floor(255 * (a - X))

        r, g, b = 0, 0, 0

        if X == 0:
            r, g, b = 255, Y, 0
        elif X == 1:
            r, g, b = 255 - Y, 255, 0
        elif X == 2:
            r, g, b = 0, 255, Y
        elif X == 3:
            r, g, b = 0, 255 - Y, 255
        elif X == 4:
            r, g, b = Y, 0, 255
        else:
            r, g, b = 255, 0, 255

        return (r, g, b)

    def onInterval(self):
        self.data = self.algorithm.step(self.data)

    def onElapsedTime(self, elapsedTime):
        Intervaled.onElapsedTime(self, elapsedTime)
        PyGameScene.onElapsedTime(self, elapsedTime)

    def update(self, **kwargs):
        self.scene.fill((0, 0, 0))

        length, height = self.dimensions.tupled()

        # Draw a line for each data point.
        for index in range(len(self.data)):
            point = self.data[index]
            rads = self.radialize(index)

            outer = self.origin + Vertex(
                cos(rads) * length * .45,
                sin(rads) * height * .45)
            color = self.colorize(point)

            try:
                smoothLine(self.scene, color, self.origin.tupled(),
                           outer.tupled())
                # jaggedLine(self.scene, color, self.origin.tupled(), outer.tupled())
            except TypeError as oops:
                print(f"Failed at {origin} -> {outer}: {oops}!")
                break
Exemplo n.º 18
0
 def resize(self, length, height):
     if self.display:
         self.display.resize(length, height)
         self.dimensions = Vertex(
             length, height)  # TODO: Make this a Dimensioned object..?
Exemplo n.º 19
0
 def __init__(self, radius):
     CameraMount.__init__(self, Vertex(radius, radius))
Exemplo n.º 20
0
 def initialize(self, length, height):
     pygame.display.init()
     self.output = pygame.display.set_mode((length, height))
     self.frame = None
     self.overlay = None
     self.dimensions = Vertex(*self.output.get_size())
Exemplo n.º 21
0
 def emissionHeading(self):
   # Pick a random heading for the ray.
   heading = random() * 2 * pi
   vx = cos(heading) * MAXIMUM_VELOCITY * INITIAL_VELOCITY_MODIFIER
   vy = sin(heading) * MAXIMUM_VELOCITY * INITIAL_VELOCITY_MODIFIER
   return Vertex(vx, vy)
Exemplo n.º 22
0
 def update(self, **kwargs):
     # Render unto the overlay thine .. rendering..?
     self.cameraOverlay.displayRendering(
         self.render(), self.position - Vertex(self.radius, self.radius))
Exemplo n.º 23
0
 def live(self):
   # As long as the radar lives, it shall emit a beam!
   self.environment.addEntity(RadarBeam(self.position, Vertex(cos(self.angle), sin(self.angle))))