LCOV - code coverage report
Current view: top level - lib/src/geometry - circle.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 31 39 79.5 %
Date: 2021-08-10 15:50:53 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:math';
       2             : import 'dart:ui';
       3             : 
       4             : import '../../game.dart';
       5             : import '../../geometry.dart';
       6             : import '../extensions/vector2.dart';
       7             : import 'shape.dart';
       8             : 
       9             : class Circle extends Shape {
      10             :   /// The [normalizedRadius] is how many percentages of the shortest edge of
      11             :   /// [size] that the circle should cover.
      12             :   double normalizedRadius = 1;
      13             : 
      14             :   /// With this constructor you can create your [Circle] from a radius and
      15             :   /// a position. It will also calculate the bounding rectangle [size] for the
      16             :   /// [Circle].
      17           1 :   Circle({
      18             :     double? radius,
      19             :     Vector2? position,
      20             :     double angle = 0,
      21           1 :   }) : super(
      22             :           position: position,
      23           2 :           size: Vector2.all((radius ?? 0) * 2),
      24             :           angle: angle,
      25             :         );
      26             : 
      27             :   /// This constructor is used by [HitboxCircle]
      28             :   /// definition is the percentages of the shortest edge of [size] that the
      29             :   /// circle should fill.
      30           1 :   Circle.fromDefinition({
      31             :     this.normalizedRadius = 1.0,
      32             :     Vector2? position,
      33             :     Vector2? size,
      34             :     double? angle,
      35           1 :   }) : super(position: position, size: size, angle: angle ?? 0);
      36             : 
      37           9 :   double get radius => (min(size.x, size.y) / 2) * normalizedRadius;
      38             : 
      39             :   /// This render method doesn't rotate the canvas according to angle since a
      40             :   /// circle will look the same rotated as not rotated.
      41           0 :   @override
      42             :   void render(Canvas canvas, Paint paint) {
      43           0 :     canvas.drawCircle(localCenter.toOffset(), radius, paint);
      44             :   }
      45             : 
      46             :   /// Checks whether the represented circle contains the [point].
      47           0 :   @override
      48             :   bool containsPoint(Vector2 point) {
      49           0 :     return absoluteCenter.distanceToSquared(point) < radius * radius;
      50             :   }
      51             : 
      52             :   /// Returns the locus of points in which the provided line segment intersect
      53             :   /// the circle.
      54             :   ///
      55             :   /// This can be an empty list (if they don't intersect), one point (if the
      56             :   /// line is tangent) or two points (if the line is secant).
      57           1 :   List<Vector2> lineSegmentIntersections(
      58             :     LineSegment line, {
      59             :     double epsilon = double.minPositive,
      60             :   }) {
      61           3 :     double sq(double x) => pow(x, 2).toDouble();
      62             : 
      63           2 :     final cx = absoluteCenter.x;
      64           2 :     final cy = absoluteCenter.y;
      65             : 
      66           1 :     final point1 = line.from;
      67           1 :     final point2 = line.to;
      68             : 
      69           1 :     final delta = point2 - point1;
      70             : 
      71           5 :     final A = sq(delta.x) + sq(delta.y);
      72          10 :     final B = 2 * (delta.x * (point1.x - cx) + delta.y * (point1.y - cy));
      73          10 :     final C = sq(point1.x - cx) + sq(point1.y - cy) - sq(radius);
      74             : 
      75           4 :     final det = B * B - 4 * A * C;
      76           1 :     final result = <Vector2>[];
      77           2 :     if (A <= epsilon || det < 0) {
      78           1 :       return [];
      79           1 :     } else if (det == 0) {
      80           0 :       final t = -B / (2 * A);
      81           0 :       result.add(Vector2(point1.x + t * delta.x, point1.y + t * delta.y));
      82             :     } else {
      83           5 :       final t1 = (-B + sqrt(det)) / (2 * A);
      84           1 :       final i1 = Vector2(
      85           4 :         point1.x + t1 * delta.x,
      86           4 :         point1.y + t1 * delta.y,
      87             :       );
      88             : 
      89           5 :       final t2 = (-B - sqrt(det)) / (2 * A);
      90           1 :       final i2 = Vector2(
      91           4 :         point1.x + t2 * delta.x,
      92           4 :         point1.y + t2 * delta.y,
      93             :       );
      94             : 
      95           2 :       result.addAll([i1, i2]);
      96             :     }
      97           3 :     result.removeWhere((v) => !line.containsPoint(v));
      98             :     return result;
      99             :   }
     100             : }
     101             : 
     102             : class HitboxCircle extends Circle with HitboxShape {
     103           0 :   @override
     104             :   HitboxCircle({double definition = 1})
     105           0 :       : super.fromDefinition(
     106             :           normalizedRadius: definition,
     107             :         );
     108             : }

Generated by: LCOV version 1.15