Commit df6efdc2 authored by JasonPries's avatar JasonPries
Browse files

Add RemoveInternalBoundary option to Pattern and subclasses

parent e5b45ec4
#include "Sketch.hpp" #include "Sketch.hpp"
MirrorCopy::MirrorCopy(std::vector<const Curve *> &input, LineSegment *l) { MirrorCopy::MirrorCopy(std::vector<const Curve *> &input, LineSegment *l, bool remove_internal) {
// Creates mirror copies of the input curves about a line // Creates mirror copies of the input curves about a line
// Assign Properties // Assign Properties
Input = input; Input = input;
SymmetryLine = l; SymmetryLine = l;
RemoveInternalBoundaries = remove_internal;
// Clone input curves and create a list of unique input verticies // Clone input curves and create a list of unique input verticies
Curves.reserve(Input.size()); Curves.reserve(Input.size());
std::list<Vertex *> input_vlist; std::list<Vertex *> input_vlist;
for (auto c : Input) { for (auto c : Input) {
if (!(l->is_coincident(c))) { if (l->is_coincident(c)) {
const_cast<Curve *>(c)->ForConstruction = RemoveInternalBoundaries; // TODO: const_cast is ugly
} else {
Curves.push_back(c->clone()); Curves.push_back(c->clone());
c->get_verticies(input_vlist); c->get_verticies(input_vlist);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
class MirrorCopy : public Pattern { class MirrorCopy : public Pattern {
public: public:
MirrorCopy(std::vector<const Curve *> &input, LineSegment *l); MirrorCopy(std::vector<const Curve *> &input, LineSegment *l, bool remove_internal = false);
private: private:
LineSegment *SymmetryLine; LineSegment *SymmetryLine;
......
...@@ -18,6 +18,7 @@ public: ...@@ -18,6 +18,7 @@ public:
protected: protected:
std::vector<const Curve *> Input; std::vector<const Curve *> Input;
bool RemoveInternalBoundaries;
std::vector<Vertex *> Verticies; std::vector<Vertex *> Verticies;
std::vector<Curve *> Curves; std::vector<Curve *> Curves;
......
#include "Sketch.hpp" #include "Sketch.hpp"
RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double angle, size_t copies) { RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double angle, size_t copies, bool remove_internal) {
// Creates rotated copies of the input curves about an vertex // Creates rotated copies of the input curves about an vertex
// #TODO: Need to rearrange code and reserve vector sizes in a way that makes more sense (much code copied from MirrorCopy constructor) // #TODO: Need to rearrange code and reserve vector sizes in a way that makes more sense (much code copied from MirrorCopy constructor)
// #TODO: Restructure to obviate the need for local_curves and local_verticies // #TODO: Restructure to obviate the need for local_curves and local_verticies
...@@ -15,6 +15,7 @@ RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double ...@@ -15,6 +15,7 @@ RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double
Curves.reserve(copies * input.size()); Curves.reserve(copies * input.size());
Verticies.reserve(3 * copies * input.size()); Verticies.reserve(3 * copies * input.size());
Constraints.reserve(3 * copies * input.size()); Constraints.reserve(3 * copies * input.size());
RemoveInternalBoundaries = remove_internal;
std::vector<const Curve *> leading_curves; std::vector<const Curve *> leading_curves;
std::vector<const Curve *> lagging_curves; std::vector<const Curve *> lagging_curves;
...@@ -101,6 +102,7 @@ RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double ...@@ -101,6 +102,7 @@ RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double
// Make rotated copies // Make rotated copies
std::vector<Vertex *> rotated_lagging(leading_verticies.begin(), leading_verticies.end()); std::vector<Vertex *> rotated_lagging(leading_verticies.begin(), leading_verticies.end());
for (size_t i = 0; i != Copies; ++i) { for (size_t i = 0; i != Copies; ++i) {
bool last_iteration = (i == Copies - 1);
// Create curve clones // Create curve clones
std::vector<Curve *> local_curves; std::vector<Curve *> local_curves;
for (auto c : internal_curves) { for (auto c : internal_curves) {
...@@ -111,6 +113,14 @@ RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double ...@@ -111,6 +113,14 @@ RotateCopy::RotateCopy(std::vector<const Curve *> &input, Vertex *center, double
for (auto c : leading_curves) { for (auto c : leading_curves) {
local_curves.push_back(c->clone()); local_curves.push_back(c->clone());
Curves.push_back(local_curves.back()); Curves.push_back(local_curves.back());
if (RemoveInternalBoundaries) {
if (!last_iteration) {
Curves.back()->ForConstruction = true;
} else {
const_cast<Curve *>(c)->ForConstruction = true; // TODO: const_cast is ugly
}
}
} }
// Create new verticies and constrain them // Create new verticies and constrain them
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
class RotateCopy : public Pattern { class RotateCopy : public Pattern {
public: public:
RotateCopy(std::vector<const Curve *> &input, Vertex *center, double angle, size_t copies); RotateCopy(std::vector<const Curve *> &input, Vertex *center, double angle, size_t copies, bool remove_internal = false);
private: private:
Vertex *Center; Vertex *Center;
......
...@@ -125,7 +125,7 @@ void test_rotated_curves(Sketch &s, std::vector<size_t> index, const Vertex *cen ...@@ -125,7 +125,7 @@ void test_rotated_curves(Sketch &s, std::vector<size_t> index, const Vertex *cen
} }
} }
TEST(Mirror, nonoverlapping) { TEST(MirrorCopy, nonoverlapping) {
Sketch s; Sketch s;
Vertex &v0 = s.new_element<Vertex>(2.0, 0.0); Vertex &v0 = s.new_element<Vertex>(2.0, 0.0);
...@@ -179,110 +179,115 @@ TEST(Mirror, nonoverlapping) { ...@@ -179,110 +179,115 @@ TEST(Mirror, nonoverlapping) {
} }
} }
TEST(MirrorCopy, overlapping) {
for (bool remove_internal : {true, false}) {
Sketch s;
TEST(Mirror, overlapping) { Vertex &v0 = s.new_element<Vertex>(0.0, 0.0);
Sketch s; Vertex &v1 = s.new_element<Vertex>(1.0, 0.0);
Vertex &v2 = s.new_element<Vertex>(2.0, 1.0);
Vertex &v0 = s.new_element<Vertex>(0.0, 0.0); Vertex &v3 = s.new_element<Vertex>(1.0, 1.0);
Vertex &v1 = s.new_element<Vertex>(1.0, 0.0);
Vertex &v2 = s.new_element<Vertex>(2.0, 1.0);
Vertex &v3 = s.new_element<Vertex>(1.0, 1.0);
LineSegment &l0 = s.new_element<LineSegment>(v0, v1);
LineSegment &l1 = s.new_element<LineSegment>(v1, v2);
LineSegment &l2 = s.new_element<LineSegment>(v2, v3);
LineSegment &l3 = s.new_element<LineSegment>(v3, v0);
l3.ForConstruction = true; LineSegment &l0 = s.new_element<LineSegment>(v0, v1);
s.new_element<Fixation>(v0); LineSegment &l1 = s.new_element<LineSegment>(v1, v2);
s.new_element<Fixation>(v3); LineSegment &l2 = s.new_element<LineSegment>(v2, v3);
LineSegment &l3 = s.new_element<LineSegment>(v3, v0);
std::vector<const Curve *> vec{&l0, &l1, &l2, &l3}; l3.ForConstruction = true;
MirrorCopy &mc0 = s.new_element<MirrorCopy>(vec, &l3); s.new_element<Fixation>(v0);
s.new_element<Fixation>(v3);
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, "Mirror__overlapping_parallelogram");
s.solve(); // std::vector<const Curve *> vec{&l0, &l1, &l2, &l3};
s.build(); auto mvec = s.curves();
MirrorCopy &mc0 = s.new_element<MirrorCopy>(mvec, &l3, remove_internal);
// Run Tests s.save_as<SaveMethod::Rasterize>(SAVE_DIR, std::string("Mirror__overlapping_parallelogram")+std::to_string(remove_internal));
{
test_sketch_size(s, 6, 7, 4, 1);
test_mirror_verticies(s, {1, 2}, l3);
test_mirror_curves(s, {0, 1, 2}, l3);
}
// Change elements
{
s.new_element<Length>(l1, 0.5);
s.solve(); s.solve();
s.build(); s.build();
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, "Mirror__overlapping_trapezoid"); // Run Tests
} {
test_sketch_size(s, 6, 7, 4, 2 - remove_internal);
test_mirror_verticies(s, {1, 2}, l3);
test_mirror_curves(s, {0, 1, 2}, l3);
}
// Run Tests // Change elements
{ {
test_sketch_size(s, 6, 7, 5, 1); s.new_element<Length>(l1, 0.5);
test_mirror_verticies(s, {1, 2}, l3); s.solve();
test_mirror_curves(s, {0, 1, 2}, l3); s.build();
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, std::string("Mirror__overlapping_trapezoid")+std::to_string(remove_internal));
}
// Run Tests
{
test_sketch_size(s, 6, 7, 5, 2 - remove_internal);
test_mirror_verticies(s, {1, 2}, l3);
test_mirror_curves(s, {0, 1, 2}, l3);
}
} }
} }
TEST(Mirror, multiple_overlapping) { TEST(MirrorCopy, multiple_overlapping) {
Sketch s; for (bool remove_internal : {true, false}) {
Sketch s;
Vertex &v0 = s.new_element<Vertex>(0.0, 0.0); Vertex &v0 = s.new_element<Vertex>(0.0, 0.0);
Vertex &v1 = s.new_element<Vertex>(2.0, 1.0); Vertex &v1 = s.new_element<Vertex>(2.0, 1.0);
Vertex &v2 = s.new_element<Vertex>(2.0, 2.0); Vertex &v2 = s.new_element<Vertex>(2.0, 2.0);
Vertex &v3 = s.new_element<Vertex>(1.0, 3.0); Vertex &v3 = s.new_element<Vertex>(1.0, 3.0);
Vertex &v4 = s.new_element<Vertex>(3.0, 2.0); Vertex &v4 = s.new_element<Vertex>(3.0, 2.0);
Vertex &v5 = s.new_element<Vertex>(2.0, 6.0); Vertex &v5 = s.new_element<Vertex>(2.0, 6.0);
LineSegment &l0 = s.new_element<LineSegment>(v0, v1); LineSegment &l0 = s.new_element<LineSegment>(v0, v1);
LineSegment &l1 = s.new_element<LineSegment>(v1, v2); LineSegment &l1 = s.new_element<LineSegment>(v1, v2);
LineSegment &l2 = s.new_element<LineSegment>(v2, v3); LineSegment &l2 = s.new_element<LineSegment>(v2, v3);
LineSegment &l3 = s.new_element<LineSegment>(v3, v0); LineSegment &l3 = s.new_element<LineSegment>(v3, v0);
LineSegment &l4 = s.new_element<LineSegment>(v2, v4); LineSegment &l4 = s.new_element<LineSegment>(v2, v4);
LineSegment &l5 = s.new_element<LineSegment>(v4, v5); LineSegment &l5 = s.new_element<LineSegment>(v4, v5);
LineSegment &l6 = s.new_element<LineSegment>(v5, v3); LineSegment &l6 = s.new_element<LineSegment>(v5, v3);
l3.ForConstruction = true; //l3.ForConstruction = true;
s.new_element<Coincident<LineSegment>>(v5, l3); s.new_element<Coincident<LineSegment>>(v5, l3);
std::vector<const Curve *> vec{&l0, &l1, &l2, &l3, &l4, &l5, &l6}; //std::vector<const Curve *> vec{&l0, &l1, &l2, &l3, &l4, &l5, &l6};
s.new_element<MirrorCopy>(vec, &l3); auto mvec = s.curves();
s.new_element<MirrorCopy>(mvec, &l3, remove_internal);
s.solve(); s.solve();
s.build(); s.build();
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, "Mirror__multiple_overlapping_0"); s.save_as<SaveMethod::Rasterize>(SAVE_DIR, std::string("Mirror__multiple_overlapping_0_")+std::to_string(remove_internal));
// Run Tests // Run Tests
{ {
test_sketch_size(s, 9, 12, 4, 3); test_sketch_size(s, 9, 12, 4, 4 - 2 * remove_internal);
test_mirror_verticies(s, {1, 2, 4}, l3); test_mirror_verticies(s, {1, 2, 4}, l3);
test_mirror_curves(s, {0, 1, 2, 4, 5}, l3); test_mirror_curves(s, {0, 1, 2, 4, 5}, l3);
} }
// Change elements // Change elements
{ {
s.new_element<Length>(l6, 2.0); s.new_element<Length>(l6, 2.0);
s.solve(); s.solve();
s.build(); s.build();
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, "Mirror__multiple_overlapping_1"); s.save_as<SaveMethod::Rasterize>(SAVE_DIR, std::string("Mirror__multiple_overlapping_1_")+std::to_string(remove_internal));
} }
// Run Tests // Run Tests
{ {
test_sketch_size(s, 9, 12, 5, 3); test_sketch_size(s, 9, 12, 5, 4 - 2 * remove_internal);
test_mirror_verticies(s, {1, 2, 4}, l3); test_mirror_verticies(s, {1, 2, 4}, l3);
test_mirror_curves(s, {0, 1, 2, 4, 5}, l3); test_mirror_curves(s, {0, 1, 2, 4, 5}, l3);
}
} }
} }
TEST(Rotate, nonoverlapping) { TEST(RotateCopy, nonoverlapping) {
Sketch s; Sketch s;
size_t N = 4; size_t N = 4;
...@@ -342,75 +347,90 @@ TEST(Rotate, nonoverlapping) { ...@@ -342,75 +347,90 @@ TEST(Rotate, nonoverlapping) {
} }
} }
TEST(Rotate, overlapping) { TEST(RotateCopy, overlapping) {
Sketch s; for(bool remove_internal : {true, false}) {
Sketch s;
size_t N = 4; size_t N = 4;
double a_deg = 360.0 / N; double a_deg = 360.0 / N;
double a_rad = M_PI * 2.0 / N; double a_rad = M_PI * 2.0 / N;
Vertex &v0 = s.new_element<Vertex>(0.0, 0.0); Vertex &v0 = s.new_element<Vertex>(0.0, 0.0);
Vertex &v1 = s.new_element<Vertex>(1.0, 0.0); Vertex &v1 = s.new_element<Vertex>(1.0, 0.1);
Vertex &v2 = s.new_element<Vertex>(2.0, 0.0); Vertex &v2 = s.new_element<Vertex>(2.0, 0.2);
Vertex &v3 = s.new_element<Vertex>(2.0 * cos(a_rad), 2.0 * sin(a_rad)); Vertex &v3 = s.new_element<Vertex>(2.0 * cos(a_rad), 2.0 * sin(a_rad));
Vertex &v4 = s.new_element<Vertex>(1.0 * cos(a_rad), 1.0 * sin(a_rad)); Vertex &v4 = s.new_element<Vertex>(1.0 * cos(a_rad), 1.0 * sin(a_rad));
Vertex &v5 = s.new_element<Vertex>(3.0, 0.0);
LineSegment &l0 = s.new_element<LineSegment>(v1, v2); LineSegment &l0 = s.new_element<LineSegment>(v1, v2);
LineSegment &l1 = s.new_element<LineSegment>(v4, v3); LineSegment &l1 = s.new_element<LineSegment>(v4, v3);
LineSegment &lh = s.new_element<LineSegment>(v0, v5);
lh.ForConstruction = remove_internal;
CircularArc &c0 = s.new_element<CircularArc>(v2, v3, v0, 2.0); CircularArc &c0 = s.new_element<CircularArc>(v2, v3, v0, 2.0);
CircularArc &c1 = s.new_element<CircularArc>(v1, v4, v0, 1.0); CircularArc &c1 = s.new_element<CircularArc>(v1, v4, v0, 1.0);
Radius &rad0 = s.new_element<Radius>(c0, 2.0); Horizontal &h = s.new_element<Horizontal>(lh);
Radius &rad1 = s.new_element<Radius>(c1, 1.0);
Fixation &f0 = s.new_element<Fixation>(v0); Radius &rad0 = s.new_element<Radius>(c0, 2.0);
Horizontal &h0 = s.new_element<Horizontal>(l0); Radius &rad1 = s.new_element<Radius>(c1, 1.0);
Coincident<LineSegment> &co0 = s.new_element<Coincident<LineSegment>>(v0, l1);
Angle &a0 = s.new_element<Angle>(l0, l1, a_deg);
std::vector<const Curve *> vec({&l0, &l1, &c0, &c1}); Fixation &f0 = s.new_element<Fixation>(v0);
RotateCopy &r0 = s.new_element<RotateCopy>(vec, &v0, 360.0 / N, N - 2);
s.solve(); Coincident<LineSegment> &co0 = s.new_element<Coincident<LineSegment>>(v0, l0);
s.build(); Coincident<LineSegment> &co1 = s.new_element<Coincident<LineSegment>>(v0, l1);
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, "Rotate__overlapping_0"); Angle &a0 = s.new_element<Angle>(lh, l0, 22.5);
//Horizontal &h = s.new_element<Horizontal>(l0);
// Run Tests Angle &a1 = s.new_element<Angle>(l0, l1, a_deg);
{
test_sketch_size(s, 9, 10, 10, 3);
test_rotated_verticies(s, {1, 2, 3, 4}, &v0, 360.0 / N, N - 2);
test_rotated_curves(s, {0, 1, 2, 3}, &v0, 360.0 / N, N - 2);
}
// Change Sketch s.solve();
rad0.Dim = 0.5;
rad1.Dim = 2.5;
s.solve(); s.save_as<SaveMethod::Rasterize>(SAVE_DIR, std::string("Rotate__overlapping_base_0_")+std::to_string(remove_internal));
s.build();
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, "Rotate__overlapping_1"); std::vector<const Curve *> rvec = {&l0,&l1,&c0,&c1};
RotateCopy &r0 = s.new_element<RotateCopy>(rvec, &v0, 360.0 / N, N - 2, remove_internal);
// Run Tests s.solve();
{ s.build();
test_sketch_size(s, 9, 10, 10, 3);
test_rotated_verticies(s, {1, 2, 3, 4}, &v0, 360.0 / N, N - 2);
test_rotated_curves(s, {0, 1, 2, 3}, &v0, 360.0 / N, N - 2);
}
FAIL(); // TODO: Change angle of horizontal line w.r.t. x-axis and rerun s.save_as<SaveMethod::Rasterize>(SAVE_DIR, std::string("Rotate__overlapping_0_")+std::to_string(remove_internal));
// Run Tests
{
test_sketch_size(s, 10, 11, 12, 3 - 2 * remove_internal);
test_rotated_verticies(s, {1, 2, 3, 4}, &v0, 360.0 / N, N - 2);
test_rotated_curves(s, {0, 1, 3, 4}, &v0, 360.0 / N, N - 2);
}
// Change Sketch
rad0.Dim = 2.5;
rad1.Dim = 0.5;
a0.Dim = 45;
s.solve();
s.build();
s.save_as<SaveMethod::Rasterize>(SAVE_DIR, std::string("Rotate__overlapping_1_")+std::to_string(remove_internal));
// Run Tests
{
test_sketch_size(s, 10, 11, 12, 3 - 2 * remove_internal);
test_rotated_verticies(s, {1, 2, 3, 4}, &v0, 360.0 / N, N - 2);
test_rotated_curves(s, {0, 1, 3, 4}, &v0, 360.0 / N, N - 2);
}
}
} }
TEST(Rotate, open_overlapping) { TEST(RotateCopy, open_overlapping) {
FAIL(); // TODO FAIL(); // TODO
} }
TEST(Rotate, closed_overlapping) { TEST(RotateCopy, closed_overlapping) {
FAIL(); // TODO FAIL(); // TODO: Need to implement detection of completely closed rotation copy
} }
TEST(Rotate, noncoincident_overlapping) { TEST(RotateCopy, noncoincident_overlapping) {
FAIL(); // TODO: Current implementation will fail if rotated boundaries overlap but are not identical FAIL(); // TODO: Current implementation will fail if rotated boundaries overlap but are not identical
} }
\ No newline at end of file
...@@ -35,7 +35,7 @@ TEST(Stator, 0) { ...@@ -35,7 +35,7 @@ TEST(Stator, 0) {
MirrorCopy &m0 = sketch.new_element<MirrorCopy>(mvec, &l1); MirrorCopy &m0 = sketch.new_element<MirrorCopy>(mvec, &l1);
auto rvec = sketch.curves(); auto rvec = sketch.curves();
RotateCopy &rcopy = sketch.new_element<RotateCopy>(rvec, &origin, 360.0 / Nt, 1); RotateCopy &rcopy = sketch.new_element<RotateCopy>(rvec, &origin, 360.0 / Nt, 1, true);
sketch.solve(); sketch.solve();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment