mirror of
https://github.com/mpusz/mp-units.git
synced 2026-07-09 01:50:50 +02:00
feat(representation): add embed/project conversions between 2D and 3D cartesian types
`embed` is the canonical inclusion of the plane into space and `project` the canonical projection back, for both vectors and tensors: - vector: embed (x,y) -> (x,y,0); project (x,y,z) -> (x,y) - tensor: embed the 2x2 into the top-left block of a zeroed 3x3; project keeps that top-left 2x2 block They are explicit named free functions (no implicit cross-dimension conversion), each defined for a single source dimension (embed: 2D only; project: 3D only). The zero fill is the additive identity derived from a component (`x - x`), so no value-initialization of the element type is required. Also route `tensor_product` through `cartesian_tensor_from` instead of a default-constructed result, matching the other constructing operations (the element type need not be default-constructible). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -558,3 +558,38 @@ TEST_CASE("cartesian_vector with a complex representation", "[vector][complex]")
|
||||
REQUIRE(t[0] == c{2.0, 2.0});
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
template<typename V>
|
||||
concept embeddable = requires(V v) { embed(v); };
|
||||
template<typename V>
|
||||
concept projectable = requires(V v) { project(v); };
|
||||
} // namespace
|
||||
// embed only lifts 2D->3D and project only lowers 3D->2D (each defined for one source dimension)
|
||||
static_assert(embeddable<cartesian_vector<double, 2>> && !embeddable<cartesian_vector<double, 3>>);
|
||||
static_assert(projectable<cartesian_vector<double, 3>> && !projectable<cartesian_vector<double, 2>>);
|
||||
|
||||
TEST_CASE("cartesian_vector embed/project between 2D and 3D", "[vector]")
|
||||
{
|
||||
SECTION("embed zero-fills the new coordinate")
|
||||
{
|
||||
cartesian_vector v3 = embed(cartesian_vector{1.0, 2.0});
|
||||
static_assert(std::is_same_v<decltype(v3), cartesian_vector<double, 3>>);
|
||||
REQUIRE(v3[0] == 1.0);
|
||||
REQUIRE(v3[1] == 2.0);
|
||||
REQUIRE(v3[2] == 0.0);
|
||||
}
|
||||
|
||||
SECTION("project drops the last coordinate")
|
||||
{
|
||||
cartesian_vector v2 = project(cartesian_vector{1.0, 2.0, 3.0});
|
||||
static_assert(std::is_same_v<decltype(v2), cartesian_vector<double, 2>>);
|
||||
REQUIRE(v2[0] == 1.0);
|
||||
REQUIRE(v2[1] == 2.0);
|
||||
}
|
||||
|
||||
SECTION("project . embed is the identity on 2D")
|
||||
{
|
||||
REQUIRE(project(embed(cartesian_vector{1.0, 2.0})) == cartesian_vector{1.0, 2.0});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user