Add convex_polygon shape; wraps Voronoi cells into the shape pipeline (#114 follow-up) - #60
Merged
Merged
Conversation
…ementing the full shape_base contract — area (shoelace), is_inside (left-of-every-edge for convex polygons), AABB bounding box, centroid translation. Wraps voronoi_generator_2d's per-cell output so polycrystal RVEs flow through the standard writer/generator pipeline. End-to-end test confirms cells[0] and cells[1] from a 2-seed Voronoi are correctly classified by is_inside
Merged
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a 2D
convex_polygonshape that bridgesvoronoi_generator_2d's raw vertex output to the standard rvegen pipeline (writers, generators, intersection dispatch, etc.). After this PR a polycrystal-style RVE is two calls:```cpp
rvegen::voronoi_generator_2d gen{1.0, 1.0, seeds};
auto cells = gen.build();
std::vector<std::unique_ptr<rvegen::shape_base>> shapes;
for (auto& v : cells) {
shapes.push_back(std::make_unique<rvegen::convex_polygon>(std::move(v)));
}
// shapes now flows through voxel_writer / gmsh_geo_writer / svg_writer.
```
What lands
convex_polygon<T>shape type, registered viastatic_indexing<convex_polygon<T>, shape_base<T>>.shape_basecontract:area()— shoelace formula (abs of signed area, robust to winding).volume()— 0 (2D shape).is_inside(point)— left-of-every-edge test (O(N), correct for convex polygons only).make_bounding_box()— AABB over vertices, returnsrectangle_bounding.get_middle_point()/set_middle_point()— area-weighted centroid; translation moves every vertex.clone()returns an independent copy.Design notes
is_insideis the simple "same side of every edge" test, valid only for convex polygons. The motivating input (Voronoi cells) is always convex. A general-polygon shape with ray-castis_insidewould be a separate type.voronoi_generator_2dalready emits CCW. A CW polygon would passarea()(which usesabs) but makeis_insidereject every query — diagnosed easily by a test that constructs an obviously-inside point.set_middle_pointmoves every vertex by the centroid delta. For a typical Voronoi cell with 4–8 vertices this is cheap; future "thousands of vertices" cases would benefit from an offset-vector indirection (cf.mesh_inclusion's pattern from Add mesh_inclusion_input: JSON-driven STL placement (#9 phase 2) #27), but that's premature for current use cases.Test plan
set_middle_point({10, 5, 0})translates the polygon; original interior point now exterior, new centroid interior.clone()produces an independent copy (translating the copy doesn't affect the original).convex_polygonshapes, each correctly classifies its seed's neighbourhood.Deferred
voronoi_to_shapes(generator)that returns theshape_vectordirectly — trivial composition but a separate ergonomics call.ConvexPolygon.is_inside; gmsh_geo_writer'swrite_2dwould need aPlane Surfacedispatch case to emit the polygon natively (today it skips with(unsupported 2D shape skipped)). That's a separate gmsh-writer extension.