Beispiel #1
0
  /*
   * (non-Javadoc)
   *
   * @see math.geom2d.Shape2D#signedDistance(math.geom2d.Point2D)
   */
  public double signedDistance(double x, double y) {
    boolean direct = angleExtent >= 0;

    double dist = distance(x, y);
    Point2D point = new Point2D(x, y);

    boolean inside = ellipse.isInside(point);
    if (inside) return angleExtent > 0 ? -dist : dist;

    Point2D p1 = point(startAngle);
    double endAngle = startAngle + angleExtent;
    Point2D p2 = point(endAngle);
    boolean onLeft = (new StraightLine2D(p1, p2)).isInside(point);

    if (direct && !onLeft) return dist;
    if (!direct && onLeft) return -dist;

    Ray2D ray = new Ray2D(p1, -sin(startAngle), cos(startAngle));
    boolean left1 = ray.isInside(point);
    if (direct && !left1) return dist;
    if (!direct && left1) return -dist;

    ray = new Ray2D(p2, -sin(endAngle), cos(endAngle));
    boolean left2 = ray.isInside(point);
    if (direct && !left2) return dist;
    if (!direct && left2) return -dist;

    if (direct) return -dist;
    else return dist;
  }
  /**
   * Kiszámolja a lézerek útjait. (Az eredményt a {@link GameObjectLaser#laserLine} objektumokban
   * tárolja le.)
   */
  private static void updateLaserLinePaths() {
    List<LineSegment2D> reflectiveSurfaces = new ArrayList<>();
    List<LineSegment2D> mattSurfaces = new ArrayList<>();

    for (GameObjectMirror mirror : level.getMirrors()) {
      reflectiveSurfaces.addAll(mirror.getReflectiveLines());
      mattSurfaces.addAll(mirror.getMattLines());
    }

    double drawAreaWidth = getGameArea().getWidth();
    double drawAreaHeight = getGameArea().getHeight();
    // a rajzterület szélei
    LineSegment2D[] drawAreaSides = {
      new LineSegment2D(0, 0, drawAreaWidth, 0),
      new LineSegment2D(drawAreaWidth, 0, drawAreaWidth, drawAreaHeight),
      new LineSegment2D(drawAreaWidth, drawAreaHeight, 0, drawAreaHeight),
      new LineSegment2D(0, drawAreaHeight, 0, 0)
    };
    mattSurfaces.addAll(Arrays.asList(drawAreaSides));

    // lézer útjának kiszámolása
    for (GameObjectLaser laser : level.getLasers()) {
      double remainingLength = Settings.LASERLINE_LENGTH;
      double x = laser.getX();
      double y = laser.getY();
      double rot = laser.getRotation() - 90;
      Ray2D ray = new Ray2D(x, y, Math.toRadians(rot));
      GameObjectLaser.Laserline laserline = laser.getLaserLine();
      laserline.clearPoints();
      laserline.addPoint(ray.firstPoint());
      LineSegment2D lastActor = null;
      int iterations = 0;

      // Amíg ki nem rajzoltuk a teljes hosszúságú lézervonalat...
      // (Vagy el nem értük a maximális iterációszámot.)
      drawLineUntilTooShort:
      while (remainingLength > 0) {
        if (iterations++ > Settings.MAX_REFLECTIONS_PER_LASER) {
          break;
        }
        List<Intersection> intersections = new ArrayList<>();
        // tükröződő metszéspontok összeszedése
        for (LineSegment2D reflectiveSurface : reflectiveSurfaces) {
          if (reflectiveSurface == lastActor) { // ne pattogjon egy pontban
            continue;
          }
          Point2D intersection = ray.intersection(reflectiveSurface);
          if (intersection != null) {
            double squareDist = MyMath.squareDist(intersection, ray.firstPoint());
            intersections.add(new Intersection(intersection, squareDist, reflectiveSurface, true));
          }
        }
        // elnyelő metszéspontok összeszedése
        for (LineSegment2D mattSurface : mattSurfaces) {
          Point2D intersection = ray.intersection(mattSurface);
          if (intersection != null) {
            double squareDist = MyMath.squareDist(intersection, ray.firstPoint());
            intersections.add(new Intersection(intersection, squareDist, mattSurface, false));
          }
        }
        // Van metszéspont. Elér odáig a lézersugár?
        if (intersections.size() > 0) {
          // Legközelebbi kiválasztása.
          Intersection nearestIntersection = intersections.remove(0);
          for (Intersection intersection : intersections) {
            if (intersection.squareDist < nearestIntersection.squareDist) {
              nearestIntersection = intersection;
            }
          }
          double distance = Math.sqrt(nearestIntersection.squareDist);
          // Nem ér el odáig a lézer?
          if (distance > remainingLength) {
            laserline.addPoint(ray.point(remainingLength));
            break;
            // Elér odáig a lézer.
          } else {
            lastActor = nearestIntersection.lineSegment;
            laserline.addPoint(nearestIntersection.point);
            // új hossz beállítása
            if (nearestIntersection.reflective) {
              remainingLength -= distance;
            } else {
              remainingLength = 0;
            }
            // Az új Ray2D szögének kiszámolása.
            ray =
                new Ray2D(
                    nearestIntersection.point,
                    MyMath.reflectionAngle(
                        ray.horizontalAngle(), nearestIntersection.lineSegment.horizontalAngle()));
          }
        }
      }
    }
  }