MirrorCopy.cpp 2.33 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#include "MirrorCopy.h"
#include "Vertex.h"
#include "LineSegment.h"
#include "Symmetry.h"

MirrorCopy::MirrorCopy(std::vector<std::shared_ptr<Curve const>> &input, std::shared_ptr<LineSegment const> l, bool remove_internal) {
    // Creates mirror copies of the input curves about a line

    // Assign Properties
    Input = input;
    SymmetryLine = l;
    RemoveInternalBoundaries = remove_internal;

    // Clone input curves and create a list of unique input verticies
    Curves.reserve(Input.size());

    std::list<std::shared_ptr<Vertex const>> input_vlist;
    for (auto c : Input) {
        if (l->is_coincident(c)) {
            std::const_pointer_cast<Curve>(c)->for_construction(RemoveInternalBoundaries);
        } else {
            Curves.push_back(c->clone());
            c->get_verticies(input_vlist);
        }
    }
    input_vlist.sort();
    input_vlist.unique();

    // Mirror input verticies
    double x0 = l->start()->x();
    double y0 = l->start()->y();
    double dx = l->end()->x() - x0;
    double dy = l->end()->y() - y0;
    double d = sqrt(dx * dx + dy * dy);
    dx /= d;
    dy /= d;

    Verticies.reserve(input_vlist.size());
    auto v = input_vlist.begin();
    while (v != input_vlist.end()) {
        double x = (*v)->x();
        double y = (*v)->y();
        double px = x - x0;
        double py = y - y0;
        double pd = dx * px + dy * py;

        px -= pd * dx;
        py -= pd * dy;

        if (sqrt(px * px + py * py) > d * FLT_EPSILON) {
            px = x - 2.0 * px;
            py = y - 2.0 * py;

            //Verticies.push_back(new Vertex(px, py));
            Verticies.push_back(std::make_shared<Vertex>(px, py));

            ++v;
        } else {
            v = input_vlist.erase(v);
        }
    }

    // Replace verticies in mirror curves
    std::vector<std::shared_ptr<Vertex const>> input_vvector{input_vlist.begin(), input_vlist.end()};
    for (auto c : Curves) {
        c->replace_verticies(input_vvector, std::vector<std::shared_ptr<Vertex const>>{Verticies.begin(), Verticies.end()});
        c->reverse();
    }

    // Constrain mirrored verticies to be symmetric about the SymmetryLine
    Constraints.reserve(Verticies.size());
    for (size_t i = 0; i != Verticies.size(); ++i) {
        Constraints.push_back(std::make_shared<Symmetry>(input_vvector[i], Verticies[i], SymmetryLine));
    }
}