Skip to content

Commit

Permalink
Merge pull request #92 from gaganjyot/master
Browse files Browse the repository at this point in the history
Cubic Beziers, Intersections.
  • Loading branch information
rvt committed Jul 28, 2016
2 parents 8d90ff1 + 2159f81 commit d40cc4c
Show file tree
Hide file tree
Showing 17 changed files with 762 additions and 158 deletions.
20 changes: 20 additions & 0 deletions lcDXFDWG/lcDXF/dxfimpl.cpp
Expand Up @@ -599,6 +599,26 @@ void DXFimpl::writeEllipse(const lc::entity::Ellipse_CSPtr s) {
dxfW->writeEllipse(&el);
}

void DXFimpl::writeSpline(const lc::entity::Spline_CSPtr s) {
DRW_Spline sp;
//getEntityAttributes(&el, s);

// el.basePoint.x = s->center().x();
// el.basePoint.y = s->center().y();
// el.secPoint.x = s->majorP().x();
// el.secPoint.y = s->majorP().y();
// el.ratio = s->ratio();
// if (s->isReversed()) {
// el.staparam = s->startAngle();
// el.endparam = s->endAngle();
// } else {
// el.staparam = s->endAngle();
// el.endparam = s->startAngle();
// }
// dxfW->writeEllipse(&el);
dxfW->writeSpline(&sp);
}

void DXFimpl::getEntityAttributes(DRW_Entity *ent, lc::entity::CADEntity_CSPtr entity) {
auto layer_ = entity->layer();
auto metaPen_ = entity->metaInfo<lc::DxfLinePattern>(lc::DxfLinePattern::LCMETANAME());
Expand Down
1 change: 1 addition & 0 deletions lcDXFDWG/lcDXF/dxfimpl.h
Expand Up @@ -101,6 +101,7 @@ class DXFimpl : public DRW_Interface {
void writeCircle(const lc::entity::Circle_CSPtr c);
void writeArc(const lc::entity::Arc_CSPtr a);
void writeEllipse(const lc::entity::Ellipse_CSPtr s);
void writeSpline(const lc::entity::Spline_CSPtr s);
void writeDimension(const lc::entity::Dimension_CSPtr d);
void writeLWPolyline(const lc::entity::LWPolyline_CSPtr p);
void writeImage(const lc::entity::Image_CSPtr i);
Expand Down
3 changes: 3 additions & 0 deletions lckernel/CMakeLists.txt
Expand Up @@ -27,6 +27,7 @@ cad/geometry/geocoordinate.cpp
cad/geometry/geoellipse.cpp
cad/geometry/geospline.cpp
cad/geometry/geobezier.cpp
cad/geometry/geobeziercubic.cpp
cad/math/lcmath.cpp
cad/math/equation.cpp
cad/math/intersectionhandler.cpp
Expand Down Expand Up @@ -93,7 +94,9 @@ cad/geometry/geocircle.h
cad/geometry/geoellipse.h
cad/geometry/geospline.h
cad/geometry/geovector.h
cad/geometry/geobezierbase.h
cad/geometry/geobezier.h
cad/geometry/geobeziercubic.h
cad/interface/entitydispatch.h
cad/interface/metatype.h
cad/interface/snapable.h
Expand Down
2 changes: 1 addition & 1 deletion lckernel/cad/base/visitor.h
Expand Up @@ -18,6 +18,7 @@ namespace lc {
class Ellipse;
class Spline;
class Arc;
class BezierBase;
}

class EntityDispatch;
Expand Down Expand Up @@ -83,7 +84,6 @@ namespace lc {
class Image;
using Image_SPtr = std::shared_ptr<Image>;
using Image_CSPtr = std::shared_ptr<const Image>;

}
}

Expand Down
1 change: 1 addition & 0 deletions lckernel/cad/const.h
Expand Up @@ -5,6 +5,7 @@
#define LCTOLERANCE 1.0e-10
#define LCARCTOLERANCE 1.0e-10
#define BBHEURISTIC 1.0e-5
#define BBHEURISTIC2 1.0e-3
//squared tolerance
#define TOLERANCE15 1.5e-15
#define TOLERANCE2 1.0e-20
Expand Down
59 changes: 27 additions & 32 deletions lckernel/cad/geometry/geobezier.cpp
Expand Up @@ -13,6 +13,11 @@ Bezier::Bezier(const Bezier &bez) :

}

const std::vector<geo::Coordinate> Bezier::getCP() const {
return {_pointA, _pointB, _pointC };
}


const Area Bezier::boundingBox() const {

/*
Expand Down Expand Up @@ -162,28 +167,10 @@ const std::vector<Coordinate> Bezier::Curve(double precession) {
std::vector<Coordinate> ret;
for(auto i = 0.; i < 1.; i+=precession) {
ret.push_back(CasteljauAt(v, i));

/* TODO
* Should we use Casteljau or direct method?
*/

// ret.push_back(DirectValueAt(i));
}
return ret;
}

const Coordinate Bezier::pointA() const {
return _pointA;
}

const Coordinate Bezier::pointB() const {
return _pointB;
}

const Coordinate Bezier::pointC() const {
return _pointC;
}

const double Bezier::length() const {

auto Bx = 2*(_pointB.x() - _pointA.x());
Expand All @@ -204,24 +191,27 @@ const double Bezier::length() const {
return ( A_32 * Sabc + A_2 * B * (Sabc - C_2) + (4 * C * A - B * B) * std::log((2* A_2 + BA + Sabc)/(BA + C_2))) / (4 * A_32);
}

Bezier Bezier::rotate(const geo::Coordinate& center, double angle) {
return Bezier(_pointA.rotate(center, angle),
BB_CSPtr Bezier::rotate(const geo::Coordinate& center, double angle) const {
auto z = std::make_shared<const Bezier>(_pointA.rotate(center, angle),
_pointB.rotate(center, angle),
_pointC.rotate(center, angle));
return z;
}

Bezier Bezier::scale(const geo::Coordinate& center, const geo::Coordinate& factor) const {
return Bezier(_pointA.scale(center, factor),
_pointB.scale(center, factor),
_pointC.scale(center, factor)
);
BB_CSPtr Bezier::scale(const geo::Coordinate& center, const geo::Coordinate& factor) const {
auto z = std::make_shared<const Bezier>(_pointA.scale(center, factor),
_pointB.scale(center, factor),
_pointC.scale(center, factor)
);
return z;
}

Bezier Bezier::move(const geo::Coordinate& offset) const {
return Bezier(_pointA + offset,
BB_CSPtr Bezier::move(const geo::Coordinate& offset) const {
auto z = std::make_shared<const Bezier>(_pointA + offset,
_pointB + offset,
_pointC + offset
);
return z;
}

const Coordinate Bezier::tangent(double t) const {
Expand Down Expand Up @@ -253,21 +243,26 @@ const Coordinate Bezier::normal(double t) const {
return Coordinate(tanx, tany);
}

Bezier Bezier::mirror(const geo::Coordinate& axis1, const geo::Coordinate& axis2) const {
return Bezier(_pointA.mirror(axis1, axis2),
BB_CSPtr Bezier::mirror(const geo::Coordinate& axis1, const geo::Coordinate& axis2) const {
auto z = std::make_shared<const Bezier>(_pointA.mirror(axis1, axis2),
_pointB.mirror(axis1, axis2),
_pointC.mirror(axis1, axis2)
);
return z;
}

std::vector<Bezier> Bezier::splitHalf() const {
std::vector<BB_CSPtr> Bezier::splitHalf() const {
auto AB = (_pointA + _pointB) / 2;
auto BC = (_pointB + _pointC) / 2;
auto D = (AB + BC)/2;
return {Bezier(_pointA, AB, D), Bezier(D, BC, _pointC)};

BB_CSPtr b1 = std::make_shared<Bezier>(Bezier(_pointA, AB, D));
BB_CSPtr b2 = std::make_shared<Bezier>(Bezier(D, BC, _pointC));

return {b1, b2};
}

Bezier Bezier::offset(const geo::Coordinate& offset) const {
BB_CSPtr Bezier::offset(const geo::Coordinate& offset) const {
auto tx_ = (_pointA.x() - _pointB.x())/(_pointA.x() - (_pointB.x()*2.0) + _pointC.x());
auto ty_ = (_pointA.y() - _pointB.y())/(_pointA.y() - (_pointB.y()*2.0) + _pointC.y());

Expand Down
45 changes: 21 additions & 24 deletions lckernel/cad/geometry/geobezier.h
Expand Up @@ -8,10 +8,11 @@
#include <cmath>
#include <cstdlib>
#include <vector>
#include "geobezierbase.h"

namespace lc {
namespace geo {
class Bezier : public Base, virtual public Visitable {
class Bezier : public BezierBase {
public:
/**
* Create a new Bezier
Expand All @@ -20,45 +21,41 @@ namespace lc {

Bezier(const Bezier &bez);

const Coordinate pointA() const;
virtual const std::vector<Coordinate> getCP() const override;

const Coordinate pointB() const;
const Area boundingBox() const override;

const Coordinate pointC() const;
Coordinate nearestPointOnPath(const Coordinate& coord) const override;
Coordinate nearestPointOnEntity(const Coordinate& coord) const override;

const Area boundingBox() const;
Coordinate CasteljauAt(std::vector<Coordinate> points, double t) const override;

Coordinate nearestPointOnPath(const Coordinate& coord) const;
Coordinate nearestPointOnEntity(const Coordinate& coord) const;
Coordinate DirectValueAt(double t) const override;

Coordinate CasteljauAt(std::vector<Coordinate> points, double t) const;
const std::vector<Coordinate> Curve(double precession) override;

Coordinate DirectValueAt(double t) const;
const double length() const override;

const std::vector<Coordinate> Curve(double precession);
const Coordinate tangent(double t) const override;

const double length() const;
const Coordinate normal(double t) const override;

const Coordinate tangent(double t) const;
std::vector<BB_CSPtr> splitHalf() const override;

const Coordinate normal(double t) const;
BB_CSPtr offset(const geo::Coordinate& offset) const override;

std::vector<Bezier> splitHalf() const;
BB_CSPtr rotate(const geo::Coordinate& center, double angle) const override;
BB_CSPtr scale(const geo::Coordinate& center, const geo::Coordinate& factor) const override;
BB_CSPtr move(const geo::Coordinate& offset) const override;
BB_CSPtr mirror(const geo::Coordinate& axis1, const geo::Coordinate& axis2) const override;

Bezier offset(const geo::Coordinate& offset) const;

Bezier rotate(const geo::Coordinate& center, double angle);
Bezier scale(const geo::Coordinate& center, const geo::Coordinate& factor) const;
Bezier move(const geo::Coordinate& offset) const;
Bezier mirror(const geo::Coordinate& axis1, const geo::Coordinate& axis2) const;

virtual void accept(GeoEntityVisitor &v) const override { v.visit(*this); }
// virtual void accept(GeoEntityVisitor &v) const override { v.visit(*this); }
private:

std::vector<double> nearestPointTValue(const Coordinate &coord) const;
std::vector<double> nearestPointTValue(const Coordinate &coord) const override;
const lc::geo::Coordinate returnCasesForNearestPoint(
double min_distance, const lc::geo::Coordinate &coord,
const Coordinate &ret) const;
const Coordinate &ret) const override;

friend std::ostream& operator<<(std::ostream& os, const Bezier& bez) {
os << "Bezier(A=" << bez._pointA << " radius=" << bez._pointB << " startAngle=" << bez._pointC << ")";
Expand Down
Empty file.
60 changes: 60 additions & 0 deletions lckernel/cad/geometry/geobezierbase.h
@@ -0,0 +1,60 @@
#pragma once

#include "cad/const.h"
#include "geoarea.h"
#include "geocoordinate.h"
#include "geobase.h"
#include <cad/math/lcmath.h>
#include <cmath>
#include <cstdlib>
#include <vector>

namespace lc {
namespace geo {
class BezierBase;
using BB_CSPtr = std::shared_ptr<const BezierBase>;
using BB_SPtr = std::shared_ptr<BezierBase>;

class BezierBase : public Base, virtual public Visitable {
public:

BezierBase() {}
virtual ~BezierBase() {}

virtual const Area boundingBox() const = 0;

virtual Coordinate nearestPointOnPath(const Coordinate& coord) const = 0;
virtual Coordinate nearestPointOnEntity(const Coordinate& coord) const = 0;

virtual Coordinate CasteljauAt(std::vector<Coordinate> points, double t) const = 0;

virtual const std::vector<Coordinate> getCP() const = 0;

virtual Coordinate DirectValueAt(double t) const = 0;

virtual const std::vector<Coordinate> Curve(double precession) = 0;

virtual const double length() const = 0;

virtual const Coordinate tangent(double t) const = 0;

virtual const Coordinate normal(double t) const = 0;

virtual std::vector<BB_CSPtr> splitHalf() const = 0;

virtual BB_CSPtr offset(const geo::Coordinate& offset) const = 0;

virtual BB_CSPtr rotate(const geo::Coordinate& center, double angle) const = 0;
virtual BB_CSPtr scale(const geo::Coordinate& center, const geo::Coordinate& factor) const = 0;
virtual BB_CSPtr move(const geo::Coordinate& offset) const = 0;
virtual BB_CSPtr mirror(const geo::Coordinate& axis1, const geo::Coordinate& axis2) const = 0;

virtual void accept(GeoEntityVisitor &v) const override { v.visit(*this); }

virtual std::vector<double> nearestPointTValue(const Coordinate &coord) const = 0;
virtual const lc::geo::Coordinate returnCasesForNearestPoint(
double min_distance, const lc::geo::Coordinate &coord,
const Coordinate &ret) const = 0;
};
}
}

0 comments on commit d40cc4c

Please sign in to comment.