Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add furthestTime #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/2geom/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ math-utils.h
nearest-time.cpp
nearest-time.h

furthest-time.cpp
furthest-time.h

numeric/matrix.cpp

ord.h
Expand Down
18 changes: 18 additions & 0 deletions src/2geom/bezier-curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <2geom/path-sink.h>
#include <2geom/basic-intersection.h>
#include <2geom/nearest-time.h>
#include <2geom/furthest-time.h>

namespace Geom
{
Expand Down Expand Up @@ -222,6 +223,11 @@ Coord BezierCurve::nearestTime(Point const &p, Coord from, Coord to) const
return nearest_time(p, inner, from, to);
}

Coord BezierCurve::furthestTime(Point const &p, Coord from, Coord to) const
{
return furthest_time(p, inner, from, to);
}

void BezierCurve::feed(PathSink &sink, bool moveto_initial) const
{
if (size() > 4) {
Expand Down Expand Up @@ -294,6 +300,18 @@ Coord BezierCurveN<1>::nearestTime(Point const& p, Coord from, Coord to) const
else return from + t*(to-from);
}

template<>
Coord BezierCurveN<1>::furthestTime(Point const& p, Coord from, Coord to) const
{
using std::swap;

if ( from > to ) swap(from, to);
Point ip = pointAt(from);
Point fp = pointAt(to);
if ( Geom::distance(fp,p) >= Geom::distance(ip,p) ) return to;
else return from;
}

template <>
std::vector<CurveIntersection> BezierCurveN<1>::intersect(Curve const &other, Coord eps) const
{
Expand Down
6 changes: 6 additions & 0 deletions src/2geom/bezier-curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ class BezierCurve : public Curve {
return (inner[d] - v).roots();
}
virtual Coord nearestTime(Point const &p, Coord from = 0, Coord to = 1) const;
virtual Coord furthestTime(Point const& p, Coord from = 0, Coord to = 1) const;

virtual Coord length(Coord tolerance) const;
virtual std::vector<CurveIntersection> intersect(Curve const &other, Coord eps = EPSILON) const;
virtual Point pointAt(Coord t) const { return inner.pointAt(t); }
Expand Down Expand Up @@ -275,6 +277,9 @@ class BezierCurveN
virtual Coord nearestTime(Point const &p, Coord from = 0, Coord to = 1) const {
return BezierCurve::nearestTime(p, from, to);
}
virtual Coord furthestTime(Point const &p, Coord from = 0, Coord to = 1) const {
return BezierCurve::furthestTime(p, from, to);
}
virtual std::vector<CurveIntersection> intersect(Curve const &other, Coord eps = EPSILON) const {
// call super. this is implemented only to allow specializations
return BezierCurve::intersect(other, eps);
Expand Down Expand Up @@ -318,6 +323,7 @@ template <> inline bool BezierCurveN<1>::isDegenerate() const {
template <> inline bool BezierCurveN<1>::isLineSegment() const { return true; }
template <> Curve *BezierCurveN<1>::derivative() const;
template <> Coord BezierCurveN<1>::nearestTime(Point const &, Coord, Coord) const;
template <> Coord BezierCurveN<1>::furthestTime(Point const& p, Coord from, Coord to) const;
template <> std::vector<CurveIntersection> BezierCurveN<1>::intersect(Curve const &, Coord) const;
template <> int BezierCurveN<1>::winding(Point const &) const;
template <> void BezierCurveN<1>::feed(PathSink &sink, bool moveto_initial) const;
Expand Down
6 changes: 6 additions & 0 deletions src/2geom/circle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ Coord Circle::nearestTime(Point const &p) const {
return timeAt(p);
}

Coord Circle::furthestTime(Point const &p) const {
Coord angle = std::fmod(timeAt(p) + rad_from_deg(180), 2*M_PI);
if (angle < 0) angle += 2*M_PI;
return angle;
}

bool Circle::contains(Rect const &r) const
{
for (unsigned i = 0; i < 4; ++i) {
Expand Down
1 change: 1 addition & 0 deletions src/2geom/circle.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class Circle
Coord valueAt(Coord t, Dim2 d) const;
Coord timeAt(Point const &p) const;
Coord nearestTime(Point const &p) const;
Coord furthestTime(Point const &p) const;

bool contains(Point const &p) const { return distance(p, _center) <= _radius; }
bool contains(Rect const &other) const;
Expand Down
8 changes: 8 additions & 0 deletions src/2geom/conicsec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,14 @@ std::vector<Point> xAx::allNearestTimes (const Point &P) const
return points;
}

/*
* Maybe we also need do this?.
* std::vector<Point> xAx::allFurthestTimes (const Point &P) const
*
* P: the point to compute the furthest one
*/




bool clip (std::vector<RatQuad> & rq, const xAx & cs, const Rect & R)
Expand Down
13 changes: 13 additions & 0 deletions src/2geom/curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <2geom/curve.h>
#include <2geom/exception.h>
#include <2geom/nearest-time.h>
#include <2geom/furthest-time.h>
#include <2geom/sbasis-geometric.h>
#include <2geom/sbasis-to-bezier.h>
#include <2geom/ord.h>
Expand All @@ -49,11 +50,23 @@ Coord Curve::nearestTime(Point const& p, Coord a, Coord b) const
return nearest_time(p, toSBasis(), a, b);
}

Coord Curve::furthestTime(Point const& p, Coord a, Coord b) const
{
return furthest_time(p, toSBasis(), a, b);
}

std::vector<Coord> Curve::allNearestTimes(Point const& p, Coord from, Coord to) const
{
return all_nearest_times(p, toSBasis(), from, to);
}

std::vector<Coord> Curve::allFurthestTimes(Point const& p, Coord from, Coord to) const
{
return all_furthest_times(p, toSBasis(), from, to);
}



Coord Curve::length(Coord tolerance) const
{
return ::Geom::length(toSBasis(), tolerance);
Expand Down
32 changes: 32 additions & 0 deletions src/2geom/curve.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,33 @@ class Curve
return allNearestTimes(p, i.min(), i.max());
}

/** @brief Compute a time value at which the curve comes furthest to a specified point.
* The first value with the smallest distance is returned if there are multiple such points.
* @param p Query point
* @param a Minimum time value to consider
* @param b Maximum time value to consider; \f$a < b\f$
* @return \f$q \in [a, b]: ||\mathbf{C}(q) - \mathbf{p}|| =
\inf(\{r \in \mathbb{R} : ||\mathbf{C}(r) - \mathbf{p}||\})\f$ */
virtual Coord furthestTime( Point const& p, Coord a = 0, Coord b = 1 ) const;

/** @brief A version that takes an Interval. */
Coord furthestTime(Point const &p, Interval const &i) const {
return furthestTime(p, i.min(), i.max());
}

/** @brief Compute a time value at which the curve comes furthest to a specified point.
* @param p Query point
* @param a Minimum time value to consider
* @param b Maximum time value to consider; \f$a < b\f$
* @return Vector of points closest and equally far away from the query point */
virtual std::vector<Coord> allFurthestTimes( Point const& p, Coord from = 0,
Coord to = 1 ) const;

/** @brief A version that takes an Interval. */
std::vector<Coord> allFurthestTimes(Point const &p, Interval const &i) {
return allFurthestTimes(p, i.min(), i.max());
}

/** @brief Compute the arc length of this curve.
* For a curve \f$\mathbf{C}(t) = (C_x(t), C_y(t))\f$, arc length is defined for 2D curves as
* \f[ \ell = \int_{0}^{1} \sqrt { [C_x'(t)]^2 + [C_y'(t)]^2 }\, \text{d}t \f]
Expand Down Expand Up @@ -346,6 +373,11 @@ Coord nearest_time(Point const& p, Curve const& c) {
return c.nearestTime(p);
}

inline
Coord furthest_time(Point const& p, Curve const& c) {
return c.furthestTime(p);
}

// for make benefit glorious library of Boost Pointer Container
inline
Curve *new_clone(Curve const &c) {
Expand Down
Loading