/* * (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())); } } } } }