0

I am running this example from Flame engine source, and I wonder what is the purpose of angle %= 2 * math.pi; in the update method. Commenting it also doesn't affect the circular animation of rectangle! If there is a mathematical reason please put a link to the related article if possible.

import 'dart:math' as math;

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flame/palette.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(
    GameWidget(
      game: MyGame(),
    ),
  );
}

/// This example simply adds a rotating white square on the screen, if you press
/// somewhere other than on the existing square another square will be added and
/// if you press on a square it will be removed.
class MyGame extends FlameGame with DoubleTapDetector, HasTappables {
  bool running = true;

  @override
  Future<void> onLoad() async {
    add(Square(Vector2(100, 200)));
  }

  @override
  void onTapUp(int id, TapUpInfo info) {
    super.onTapUp(id, info);
    if (!info.handled) {
      final touchPoint = info.eventPosition.game;
      add(Square(touchPoint));
    }
  }

  @override
  void onDoubleTap() {
    if (running) {
      pauseEngine();
    } else {
      resumeEngine();
    }

    running = !running;
  }
}

class Square extends PositionComponent with Tappable {
  static const speed = 0.25;
  static const squareSize = 128.0;

  static Paint white = BasicPalette.white.paint();
  static Paint red = BasicPalette.red.paint();
  static Paint blue = BasicPalette.blue.paint();

  Square(Vector2 position) : super(position: position);

  @override
  Future<void> onLoad() async {
    super.onLoad();
    size.setValues(squareSize, squareSize);
    anchor = Anchor.center;
  }

  @override
  void render(Canvas canvas) {
    canvas.drawRect(size.toRect(), white);
    canvas.drawRect(const Rect.fromLTWH(0, 0, 30, 30), red);
    canvas.drawRect(Rect.fromLTWH(width / 2, height / 2, 3, 3), blue);
  }

  @override
  void update(double dt) {
    super.update(dt);
    angle += speed * dt;
    angle %= 2 * math.pi;      //<---- What is the reason behind this line?
  }

  @override
  bool onTapUp(TapUpInfo info) {
    removeFromParent();
    return true;
  }
}
Progman
  • 16,827
  • 6
  • 33
  • 48
Davoud
  • 2,576
  • 1
  • 32
  • 53

2 Answers2

4

At some point, after a very long time if you don't have a high rotational speed, the angle will overflow what a double can fit.

The angle here is in radians, and one full circle is 2π (360°). Since when we have rotated a full circle we can just as well go back to 0 again we use modulo to remove all the "unused" full circles that are in currently in angle.

What will happen if exceeds 2*pi.

Nothing will happen, it will just continue rotating, but angle will keep on growing to an unnecessarily large value.

spydon
  • 9,372
  • 6
  • 33
  • 63
1

It ensures that angle never exceeds 2×PI, the maximum value of an angle in radians. By performing a modulus by this value, any number that exceeds 2×PI will just wrap around from 0.

Joshua Crotts
  • 69
  • 1
  • 8
  • What will happen if exceeds 2*pi. It doesn't do anything when I increase or decrease the speed. I couldn't get what you mean. – Davoud Apr 05 '22 at 11:05