예제 #1
0
DimAngular_SPtr DimAngular::dimAuto(geo::Coordinate const& p2, geo::Coordinate const& p3, double const textOffset, std::string const& explicitValue, const Layer_CSPtr layer, const MetaInfo_CSPtr metaInfo) {

    geo::Coordinate dir = (p3 - p2).rotate(0.5 * M_PI);
    geo::Coordinate p0 = p3.move(dir, textOffset);
    geo::Coordinate middletext(p2.mid(p3).move(dir, textOffset));


    return std::make_shared<DimAngular>(p0, middletext, TextConst::AttachmentPoint::Top_center, 0., 0., TextConst::LineSpacingStyle::AtLeast, explicitValue, p2, p3, p3, p3, layer, metaInfo);
}
예제 #2
0
CADEntity_CSPtr Circle::scale(const geo::Coordinate& scale_center, const geo::Coordinate& scale_factor) const {
    // TODO return ellipse if scalefactor.x != scalefactor.y
    auto newCircle = std::make_shared<Circle>(this->center().scale(scale_center, scale_factor), this->radius() * fabs(scale_factor.x()), layer());
    newCircle->setID(this->id());
    //    return newCircle;

    if (fabs(scale_factor.x() - scale_factor.y()) > TOLERANCE) {
        auto newEllipse = std::make_shared<Ellipse>(this->center(), geo::Coordinate(this->radius(), 1.0), 1.0, 0., 0., layer());
        newEllipse->setID(this->id());
        return newEllipse;
    } else {
        return newCircle;
    }

}
예제 #3
0
// ARC
void Intersect::visit(Arc_CSPtr arc, const geo::Vector& line) {
    const geo::Coordinate nearest = line.nearestPointOnPath(arc->center());
    double dist = arc->center().distanceTo(nearest);

    // special case: arc touches line (tangent):
    // TODO: We properly should add a tolorance here ??
    if (fabs(dist - arc->radius()) < _tolerance) {
        _intersectionPoints.push_back(nearest);
        return;
    }

    const geo::Coordinate d = line.end() - line.start();
    const double r = arc->radius();
    const geo:: Coordinate delta = line.start() - arc->center();
    const double d2 = d.squared();

    //intersection
    // solution = p + t d;
    //| p -c+ t d|^2 = r^2
    // |d|^2 t^2 + 2 (p-c).d t + |p-c|^2 -r^2 = 0
    const double a1 = delta.dot(d);
    const double discriminant = a1 * a1 - d2 * (delta.squared() - r * r);

    if (discriminant < - _tolerance) {
        return;
    } else {
        const double t = sqrtf(fabs(discriminant));
        //two intersections
        const geo::Coordinate c1(line.start() + d * (t - a1) / d2);
        const geo::Coordinate c2(line.start() - d * (t + a1) / d2);

        if (_method == Method::Any || (_method == Method::OnPath && arc->isCoordinateOnPath(c1) && line.isCoordinateOnPath(c1))) {
            _intersectionPoints.push_back(c1);
        }

        if (_method == Method::Any || (_method == Method::OnPath && arc->isCoordinateOnPath(c2) && line.isCoordinateOnPath(c2))) {
            _intersectionPoints.push_back(c2);
        }
    }
}
예제 #4
0
void Intersect::visit(Line_CSPtr l1, const geo::Vector& v) {
    const geo::Coordinate p1 = l1->start();
    const geo::Coordinate p2 = l1->end();
    const geo::Coordinate p3 = v.start();
    const geo::Coordinate p4 = v.end();

    const double num = ((p4.x() - p3.x()) * (p1.y() - p3.y()) - (p4.y() - p3.y()) * (p1.x() - p3.x()));
    const double div = ((p4.y() - p3.y()) * (p2.x() - p1.x()) - (p4.x() - p3.x()) * (p2.y() - p1.y()));

    // TODO: We properly should add a tolorance here ??
    if (std::abs(div) > _tolerance) {
        double u = num / div;
        double xs = p1.x() + u * (p2.x() - p1.x());
        double ys = p1.y() + u * (p2.y() - p1.y());
        const geo::Coordinate coord(xs, ys);

        const geo::Area a1(p1, p2);
        const geo::Area a2(p3, p4);

        const bool a1b = a1.inArea(coord);
        const bool a2b = a2.inArea(coord);

        if (_method == Method::Any) {
            _intersectionPoints.push_back(coord);
        } else if (a1b && a2b) { // Test if it positivly fit's within a area
            _intersectionPoints.push_back(coord);
        } else if (
            (p1.x() == p2.x() && ys >= a1.minP().y() && ys <= a1.maxP().y() && a2b) || // when we deal with orizontal or vertical lines, inArea might not
            (p3.x() == p4.x() && ys >= a2.minP().y() && ys <= a2.maxP().y() && a1b) || // give a positive result, this conditions will confirm without using tolerance
            (p1.y() == p2.y() && xs >= a1.minP().x() && xs <= a1.maxP().x() && a2b) ||
            (p3.y() == p4.y() && xs >= a2.minP().x() && xs <= a2.maxP().x() && a1b)
        ) {
            _intersectionPoints.push_back(coord);
        }
    }
}
예제 #5
0
CADEntity_CSPtr Coordinate::copy(const geo::Coordinate& offset) const {
    auto newCoordinate = std::make_shared<Coordinate>(this->x() + offset.x(), this->y() + offset.y(), layer());
    return newCoordinate;
}
예제 #6
0
DimRadial::DimRadial(geo::Coordinate const& definitionPoint, TextConst::AttachmentPoint const& attachmentPoint, double const lineSpacingFactor,
                     TextConst::LineSpacingStyle const& lineSpacingStyle, std::string const& explicitValue,  geo::Coordinate const& definitionPoint2,
                     const double leader, const Layer_CSPtr layer, const MetaInfo_CSPtr metaInfo): CADEntity(layer, metaInfo), Dimension(definitionPoint, definitionPoint.mid(definitionPoint2), attachmentPoint, 0., lineSpacingFactor, lineSpacingStyle, explicitValue),
    _leader(leader), _definitionPoint2(definitionPoint2) {
}
예제 #7
0
CADEntity_CSPtr Arc::scale(const geo::Coordinate& scale_center, const geo::Coordinate& scale_factor) const {
    auto newArc = std::make_shared<Arc>(this->center().scale(scale_center, scale_factor), this->radius() * fabs(scale_factor.x()),
                                        this->startAngle(), this->endAngle(), layer());
    newArc->setID(this->id());
    return newArc;

}