def nearest_land_pos(self, point: Point, extend_dist: int = 50) -> Point:
     """Returns the nearest point inside a land exclusion zone from point
     `extend_dist` determines how far inside the zone the point should be placed"""
     if self.is_on_land(point):
         return point
     point = geometry.Point(point.x, point.y)
     nearest_points = []
     if not self.landmap:
         raise RuntimeError("Landmap not initialized")
     for inclusion_zone in self.landmap[0]:
         nearest_pair = ops.nearest_points(point, inclusion_zone)
         nearest_points.append(nearest_pair[1])
     min_distance = point.distance(
         nearest_points[0])  # type: geometry.Point
     nearest_point = nearest_points[0]  # type: geometry.Point
     for pt in nearest_points[1:]:
         distance = point.distance(pt)
         if distance < min_distance:
             min_distance = distance
             nearest_point = pt
     assert isinstance(nearest_point, geometry.Point)
     point = Point(point.x, point.y)
     nearest_point = Point(nearest_point.x, nearest_point.y)
     new_point = point.point_from_heading(
         point.heading_between_point(nearest_point),
         point.distance_to_point(nearest_point) + extend_dist)
     return new_point
 def intercept_conflict(cls, attacker_name: str, defender_name: str,
                        attacker: Country, defender: Country,
                        position: Point, from_cp: ControlPoint,
                        to_cp: ControlPoint, theater: ConflictTheater):
     heading = from_cp.position.heading_between_point(position)
     return cls(position=position.point_from_heading(
         position.heading_between_point(to_cp.position),
         INTERCEPT_CONFLICT_DISTANCE),
                theater=theater,
                from_cp=from_cp,
                to_cp=to_cp,
                attackers_side=attacker_name,
                defenders_side=defender_name,
                attackers_country=attacker,
                defenders_country=defender,
                ground_attackers_location=None,
                ground_defenders_location=None,
                air_attackers_location=position.point_from_heading(
                    random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading,
                    INTERCEPT_ATTACKERS_DISTANCE),
                air_defenders_location=position)
    def heading_to_conflict_from(self, position: Point) -> Optional[Heading]:
        # Heading for a Group to the enemy.
        # Should be the point between the nearest and the most distant conflict
        conflicts: dict[MissionTarget, float] = {}

        for conflict in self.conflicts():
            conflicts[conflict] = conflict.position.distance_to_point(position)

        if len(conflicts) == 0:
            return None

        sorted_conflicts = [
            k for k, v in sorted(conflicts.items(), key=lambda item: item[1])
        ]
        last = len(sorted_conflicts) - 1

        conflict_center = sorted_conflicts[0].position.midpoint(
            sorted_conflicts[last].position
        )

        return Heading.from_degrees(position.heading_between_point(conflict_center))
Example #4
0
    def add_oblong(
        self,
        p1: Point,
        p2: Point,
        radius: float,
        color=Rgba(255, 0, 0, 255),
        fill=Rgba(255, 0, 0, 60),
        line_thickness=4,
        line_style=LineStyle.Solid,
        resolution=20,
    ) -> FreeFormPolygon:
        hdg_p1_p2 = p1.heading_between_point(p2)
        points: List[Point] = []

        for i in range(0, resolution + 1):
            hdg = hdg_p1_p2 - 90 + i * (180 / resolution)
            points.append(p2.point_from_heading(hdg, radius))

        for i in range(0, resolution + 1):
            hdg = hdg_p1_p2 + 90 + i * (180 / resolution)
            points.append(p1.point_from_heading(hdg, radius))

        # Copy first point and insert last to close the polygon
        points.append(points[0] * 1)

        # Transform points to local coordinates
        startPoint = points[0] * 1  # Copy
        for point in points:
            point.x -= startPoint.x
            point.y -= startPoint.y

        polygon = self.add_freeform_polygon(
            startPoint,
            points,
            color=color,
            fill=fill,
            line_thickness=line_thickness,
            line_style=line_style,
        )
        return polygon