Example #1
0
arma::vec2
intersectionPoint(const Line2 & l1, const Line2 & l2)
{
  const double num1 = l1.b() * l2.c() - l2.b() * l1.c();
  const double num2 = l2.a() * l1.c() - l1.a() * l2.c();
  const double denom = l1.a() * l2.b() - l2.a() * l1.b();
  arma::vec2 pt;
  pt << num1 / denom << endr << num2 / denom;
  return pt;
}
Example #2
0
    Solution split(const Line2& line, bool up) const {
        Solution result;
        result.points = points;
        for (const auto& facet: facets) {
            if (doIntersect(facet.polygon, line)) {
                Facet facet1;
                facet1.transformation = facet.transformation;
                Facet facet2;
                Transformation2 reflection( sqr(line.b()) - sqr(line.a()), -2*line.a()*line.b(), -2*line.a()*line.c(),
                                            -2*line.a()*line.b(), sqr(line.a()) - sqr(line.b()), -2*line.b()*line.c(),
                                            sqr(line.a()) + sqr(line.b()) );
                facet2.transformation = reflection*facet.transformation;
                auto inverse = facet.transformation.inverse();
                bool fail = false;
                for (auto edge = facet.polygon.edges_begin(); edge != facet.polygon.edges_end(); ++edge) {
                    const auto len2 = edge->squared_length();
                    const auto len2new = edge->transform(facet2.transformation).squared_length();
                    if (len2 != len2new) {
                        throw runtime_error("bad transform");
                    }

                    if (line.has_on_positive_side(edge->source()) == up) {
                        facet1.polygon.push_back(edge->source());
                    } else {
                        facet2.polygon.push_back(reflection(edge->source()));
                    }
                    auto intersect = intersection(*edge, line);
                    if (intersect) {
                        Point2* p = boost::get<Point2>(&*intersect);
                        if (p) {
                            auto revPoint = inverse(*p);
                            if (!result.points.count(revPoint)) {
                                result.points[revPoint] = result.points.size();
                            }
                            facet1.polygon.push_back(*p);
                            facet2.polygon.push_back(*p);
                        } else {
                            fail = true;
                        }
                    }
                }
                auto normalize = [&](Facet& f) {
                    auto area = f.polygon.area();
                    if (area == 0) {
                        return;
                    }
                    vector<Point2> points(f.polygon.size());
                    for (size_t i = 0; i < f.polygon.size(); ++i) {
                        points[i] = f.polygon[i];
                    }
                    points.erase(unique(points.begin(), points.end()), points.end());
                    if (points.empty()) {
                        return;
                    }
                    if (area < 0) {
                        reverse(points.begin(), points.end());
                    }
                    Polygon2 p;
                    for (const auto& pnt: points) {
                        p.push_back(pnt);
                    }
                    f.polygon = p;
                    result.facets.push_back(f);
                };
                if (!fail) {
                    normalize(facet1);
                    normalize(facet2);
                } else {
                    result.facets.push_back(facet);
                }
            } else {
                result.facets.push_back(facet);
            }
        }

        for (const auto& f: result.facets) {
            result.polygon.join(f.polygon);
        }

        return result;
    }