Skip to content

Commit

Permalink
fix convex-save-area and polygon crossover bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
MangaBoba committed Nov 16, 2023
1 parent a0ec2d9 commit 23f364a
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 45 deletions.
4 changes: 1 addition & 3 deletions gefest/core/geometry/geometry_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,6 @@ def simplify(self, poly: Polygon, tolerance: float) -> Polygon:
if isinstance(simplified, MultiPolygon):
simplified = max(simplified.geoms, lambda p: p.area)

raise ValueError('Empty polygon produced 1')

out = Polygon([Point(p[0], p[1]) for p in simplified.exterior.coords])
else:
simplified = self._poly_to_shapely_line(poly).convex_hull.simplify(tolerance)
Expand Down Expand Up @@ -551,7 +549,7 @@ def split_polygon(self, poly, line: tuple[Point, Point], scale_factor=1000) -> l
scale_factor,
)
parts = get_parts(split(poly, line)).tolist()
parts = [lambda p: list(mapping(p)['coordinates'][0][:-1]) for p in parts]
parts = [mapping(p)['coordinates'][0][:-1] for p in parts]
return parts

def min_distance(self, obj_1, obj_2) -> float:
Expand Down
13 changes: 8 additions & 5 deletions gefest/core/geometry/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,10 @@ def get_convex_safe_area(
poly_idx: int,
**kwargs,
) -> Polygon:
"""Finds an area from which a new point can be selected without breaking the convexity."""
"""Finds an area from which a new point can be selected without breaking the convexity.
Point_left_idx and point_right_idx expected to be neighbours.
"""
geom = domain.geometry
movment_area = None

Expand Down Expand Up @@ -341,15 +344,18 @@ def get_convex_safe_area(
)

p1, p2 = left_cut[1], right_cut[1]
pad_vector_points = [p1, geom.rotate_point(p2, p1, 90)]
pad_vector_points = [p1, geom.rotate_point(p2, p1, -90)]

pad_vector = (
pad_vector_points[1].x - pad_vector_points[0].x,
pad_vector_points[1].y - pad_vector_points[0].y,
)

slice_line = (
Point(left_cut[1].x + pad_vector[0], left_cut[1].y + pad_vector[1]),
Point(right_cut[1].x + pad_vector[0], right_cut[1].y + pad_vector[1]),
)

scale_factor = max(domain.max_x, domain.max_y) * 100

if sum(cut_angles) < 170:
Expand Down Expand Up @@ -399,9 +405,6 @@ def get_convex_safe_area(
geom.intersection_line_line(right_cut, slice_line, scale_factor, scale_factor),
right_cut[1],
]
if base_area[1] is None or base_area[2] is None:
logger.warning('here')

if not geom._poly_to_shapely_poly(Polygon(base_area)).is_simple:
base_area = [
left_cut[1],
Expand Down
2 changes: 1 addition & 1 deletion gefest/core/opt/operators/crossovers.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def polygon_level_crossover(
poly_1 = pairs_dists[0][0][0]
poly_2 = pairs_dists[0][0][1]
if intersected:
# adaptive angle #
# now not adaptive angle #
split_angle = (np.random.rand() * 2 - 1) * (70)
elif pairs_dists[0][1] > domain.dist_between_polygons:
return (s1,)
Expand Down
2 changes: 2 additions & 0 deletions gefest/core/opt/operators/multiobjective_selections.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

class SPEA2:
"""SPEA2 selection strategy."""

def __init__(self, single_demention_selection, init_pop, steps, **kwargs):
self.steps = steps
self.step_cntr = 0
Expand Down Expand Up @@ -144,6 +145,7 @@ class MOEAD:
For details see: https://ieeexplore.ieee.org/document/4358754?arnumber=4358754
"""

def __init__(self, single_demention_selection, init_pop, moead_n_neighbors, *args, **kwargs):
self.ref_dirs, self.ideal, self.neighbors = self._setup(init_pop, moead_n_neighbors)
self.single_demention_selection = single_demention_selection
Expand Down
36 changes: 16 additions & 20 deletions gefest/tools/estimators/simulators/swan/swan_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@

class Swan(Estimator):
"""Class for SWAN estimator."""

def __init__(
self,
path,
targets,
grid,
domain,
input_file_path="INPUT",
hs_file_path="r/hs47dd8b1c0d4447478fec6f956c7e32d9.d",
input_file_path='INPUT',
hs_file_path='r/hs47dd8b1c0d4447478fec6f956c7e32d9.d',
):
self.path_to_model = path
self.path_to_input = path + input_file_path
Expand All @@ -35,56 +36,51 @@ def estimate(self, struct: Structure) -> float:
"""
polygons = struct.polygons

file_toread = self.path_to_input + "_2"
with open(file_toread, "r") as file_to_read:
file_toread = self.path_to_input + '_2'
with open(file_toread, 'r') as file_to_read:
content_read = file_to_read.read()
file_to_read.close()
for _j, poly in enumerate(polygons):
for_input = "\nOBSTACLE TRANSM 0. REFL 0. LINE "
for_input = '\nOBSTACLE TRANSM 0. REFL 0. LINE '
points = np.array([p.coords[:2] for p in poly.points])
individ = points.reshape(-1)
for i, gen in enumerate(individ):
for_input += "{:.6f}".format(gen / 500)
for_input += '{:.6f}'.format(gen / 500)
if i != len(individ) - 1:
for_input += ", "
for_input += ', '

for_input += "\n$optline"
for_input += '\n$optline'
content_to_replace = for_input
content_write = content_read.replace(
content_read[
content_read.find("OBSTACLE")
- 1 : content_read.rfind("$optline")
+ 10
content_read.find('OBSTACLE') - 1 : content_read.rfind('$optline') + 10
],
content_to_replace,
)

input_created = Path(self.path_to_input)
input_created.touch(exist_ok=True)
with open(self.path_to_input, "w") as file_to_write:
with open(self.path_to_input, 'w') as file_to_write:
file_to_write.write(content_write)

logger.info("Swan estimation started...")
logger.info('Swan estimation started...')
subprocess.run(
"swan.exe",
'swan.exe',
shell=True,
cwd=self.path_to_model,
stdout=subprocess.DEVNULL,
)
logger.info("Swan estimation finished.")
logger.info('Swan estimation finished.')

z = np.loadtxt(self.path_to_hs)
res = []
for i in range(1538 // 32):
hs_target = np.sum(
[
z[i * 32 : (i + 1) * 32][target[0], target[1]]
for target in self.targets
]
[z[i * 32 : (i + 1) * 32][target[0], target[1]] for target in self.targets]
)

res.append(hs_target)

hs_target = sum(res) / len(res)
print("hs_target", hs_target)
print('hs_target', hs_target)
return hs_target
33 changes: 17 additions & 16 deletions test/test_geometry_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,9 @@ class TestConvexSafeArea:
geometry='2D',
)

poly_points = [
(40, 25),
(30, 40),
(40, 55),
(60, 55),
(70, 40),
(60, 25),
(40, 25),
]
test_poly = Polygon(Point(p[0], p[1]) for p in poly_points)
test_structure = Structure([test_poly])
poly_points1 = [(21, 55), (18, 44), (41, 13), (48, 13), (56, 43)]
test_poly1 = Polygon(Point(p[0], p[1]) for p in poly_points1)
test_structure = Structure([test_poly1])

@pytest.mark.parametrize(
', '.join(
Expand All @@ -56,10 +48,19 @@ class TestConvexSafeArea:
],
),
[
(test_poly, domain, 2, 3, test_structure, 0, no_exception()),
(test_poly1, domain, 0, 1, test_structure, 0, no_exception()),
(test_poly1, domain, 1, 2, test_structure, 0, no_exception()),
(test_poly1, domain, 2, 3, test_structure, 0, no_exception()),
(test_poly1, domain, 3, 4, test_structure, 0, no_exception()),
(test_poly1, domain, 4, 0, test_structure, 0, no_exception()),
(test_poly1, domain, 0, 2, test_structure, 0, no_exception()),
(test_poly1, domain, 1, 3, test_structure, 0, no_exception()),
(test_poly1, domain, 2, 4, test_structure, 0, no_exception()),
(test_poly1, domain, 3, 0, test_structure, 0, no_exception()),
(test_poly1, domain, 4, 1, test_structure, 0, no_exception()),
],
)
def test_get_convex_safe_area_saves_convexity_triangle_area_case(
def test_convex_safe_area_saves_convexity_neighbour_indices(
self,
poly,
domain,
Expand All @@ -81,6 +82,6 @@ def test_get_convex_safe_area_saves_convexity_triangle_area_case(
)
s_poly = domain.geometry._poly_to_shapely_poly(poly)
union = unary_union([s_poly, movment_area])
assert union.area == union.convex_hull.area
assert union.is_simple
assert union.is_valid
assert round(union.area, 6) == round(union.convex_hull.area, 6)
if abs(point_right_idx - point_left_idx) == 1:
assert s_poly.intersection(movment_area).area == 0.0

0 comments on commit 23f364a

Please sign in to comment.