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 Segment and generalize Path #318

Draft
wants to merge 59 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
35dec36
Add interface for Segment
saraedum Sep 14, 2022
ad97695
Speed up Segment::start() and Segment::end()
saraedum Sep 14, 2022
134a5fa
Add test suite for Segment
saraedum Sep 16, 2022
98eb663
Adapt to changes in Path
saraedum Sep 16, 2022
327ff3a
Drop unused aliases
saraedum Sep 16, 2022
9f3be69
Fix compilation error
saraedum Sep 16, 2022
5eabf40
Fix compiler warning
saraedum Sep 16, 2022
2bf0798
Add implementation stubs for Segment
saraedum Sep 18, 2022
5fe2f32
Add Vector::parallel()
saraedum Sep 18, 2022
4a43f78
Implement construction of Segment from full data
saraedum Sep 18, 2022
c8fbeea
Implement hashing of Segments
saraedum Sep 18, 2022
64d8276
Fix missing import
saraedum Sep 19, 2022
3d7c6ed
Add SegmentIterator stubs
saraedum Sep 19, 2022
2995eea
Add Ray stubs
saraedum Sep 20, 2022
af2044f
Added preliminary news
saraedum Sep 21, 2022
5350840
Implement Segment::saddleConnection()
saraedum Sep 21, 2022
ce2a061
Implement Segment::start(), end(), source(), target()
saraedum Sep 21, 2022
46d6048
Implement Segment::surface(), vector()
saraedum Sep 21, 2022
0d36783
Implement printing of segments
saraedum Sep 21, 2022
14bbb4e
Implement equality of segments
saraedum Sep 21, 2022
0cbb3d4
Make segments print in the same way that saddle connections print
saraedum Sep 21, 2022
3531dfa
Implement Path(Segment) constructor
saraedum Sep 21, 2022
147b0b8
Add Chain::vector() helper
saraedum Sep 21, 2022
51fd649
Fix hashing of saddle connections
saraedum Sep 21, 2022
bd54f17
Implement Segment::operator-
saraedum Sep 26, 2022
524c223
Implement Segment::ray()
saraedum Sep 26, 2022
ce71d12
Implement Ray constructors
saraedum Sep 26, 2022
41bbb67
Mostly implement Ray
saraedum Sep 28, 2022
80833dd
Add TODO for segments
saraedum Sep 28, 2022
2b59eee
Test all of Ray
saraedum Sep 28, 2022
6fd9d97
Adapt tightening of paths to work with paths built from segments
saraedum Sep 28, 2022
30df7fa
Implement Segment::overlapping
saraedum Sep 29, 2022
904c549
Implement Segment::overlapping
saraedum Sep 29, 2022
a0d2bd7
Implement Path::push_back() and Path::push_front()
saraedum Oct 1, 2022
d52c35e
Test Path for more kinds of coefficients
saraedum Oct 1, 2022
cc81554
Implement Path::segment()
saraedum Oct 1, 2022
8b61b47
Implement SaddleConnections::sector(Ray, Ray)
saraedum Oct 1, 2022
f1f93c3
Fix tightening of paths
saraedum Oct 4, 2022
b9032c3
Implement Ray::operator==
saraedum Oct 4, 2022
96ad0c0
Implement segment generator for testing
saraedum Oct 5, 2022
33a4ebc
Fix path test
saraedum Oct 5, 2022
b84b155
Fix path tests
saraedum Oct 5, 2022
876368f
Fix translation of points when creating segments
saraedum Oct 5, 2022
95cdcdd
Implement conversion of deprecated PathIterator to SegmentIterator
saraedum Oct 6, 2022
c4cc1b4
Fix translation of points
saraedum Oct 6, 2022
d1a3ed0
Implement printing of Ray
saraedum Oct 6, 2022
e1f2238
Fix ray equality testing
saraedum Oct 6, 2022
654b45b
Implement ray generator for testing
saraedum Oct 6, 2022
21a1785
Ship segment generator in tarball
saraedum Oct 6, 2022
b3d21ae
Fix Ray::ccw() for non-vertices
saraedum Oct 6, 2022
2f9ae7e
Do not allow hashing of Rays
saraedum Oct 6, 2022
77dde5a
Fix Segment test case
saraedum Oct 6, 2022
19a42c5
Fix segment test cases
saraedum Oct 6, 2022
a4b711c
Merge branch 'master' into segment
saraedum Nov 24, 2022
b39d18f
Fix segment test case
saraedum Oct 6, 2022
99d1725
Fix segment test cases
saraedum Oct 6, 2022
7b06810
Improve error message
saraedum Nov 11, 2022
cd2dc34
Use Segment in more places
saraedum Nov 11, 2022
5c970e6
Register TODOs
saraedum Nov 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 33 additions & 0 deletions doc/news/segment.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
**Added:**

* Added `Ray` to describe a direction at a point; this unifies some functionality from `SaddleConnection` and `Vertical`.

* Added `Vector::parallel` as a shortcut for the repetetive `Vector::ccw() == COLLINEAR && Vector::orientation() == SAME`.

* Added `Segment` generalizing `SaddleConnection`.

* Added possibility to create `Path` from `Segment` or a sequence of `Segment`
(before paths could only be built from saddle connections.)

# Added `Chain::vector()` method to make it easier to cast a chain to vector in Python.

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* Fixed hashing of `SaddleConnection`. Before, two saddle connections with different underlying representations as chains that represented the same vector were considered different from each other.
* <news item>

**Performance:**

* <news item>
2 changes: 2 additions & 0 deletions libflatsurf/flatsurf/chain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class Chain : public Serializable<Chain<Surface>>,
explicit Chain(const Surface&);
Chain(const Surface&, HalfEdge);

const Vector<T>& vector() const;

operator const Vector<T> &() const;
operator const Vector<exactreal::Arb> &() const;

Expand Down
3 changes: 3 additions & 0 deletions libflatsurf/flatsurf/deformation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class Deformation {
// Return the image of the point under this deformation.
Point<Surface> operator()(const Point<Surface>&) const;

// Return the image of this ray under the deformation.
Ray<Surface> operator()(const Ray<Surface>&) const;

// Return the result of the deformation.
[[deprecated("Use codomain().clone() instead.")]] Surface surface();

Expand Down
3 changes: 3 additions & 0 deletions libflatsurf/flatsurf/detail/vector_exact.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class VectorExact : public VectorBase<Vector>,

CCW ccw(const Vector &) const;
ORIENTATION orientation(const Vector &) const;
// Return whether this vector is parallel to the given vector, i.e., whether
// the vectors are collinear and euqally oriented.
bool parallel(const Vector&) const;
bool insideCircumcircle(std::initializer_list<Vector>) const;

// Return the scalar product with the argument
Expand Down
4 changes: 3 additions & 1 deletion libflatsurf/flatsurf/flatsurf.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of flatsurf.
*
* Copyright (C) 2019-2020 Julian Rüth
* Copyright (C) 2019-2022 Julian Rüth
*
* Flatsurf is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -72,6 +72,8 @@
#include "saddle_connections_iterator.hpp"
#include "saddle_connections_sample.hpp"
#include "saddle_connections_sample_iterator.hpp"
#include "segment.hpp"
#include "segment_iterator.hpp"
#include "serializable.hpp"
#include "tracked.hpp"
#include "vector.hpp"
Expand Down
6 changes: 6 additions & 0 deletions libflatsurf/flatsurf/fmt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,11 @@ template <typename Surface>
struct fmt::formatter<::flatsurf::Path<Surface>> : ::flatsurf::GenericFormatter<::flatsurf::Path<Surface>> {};
template <typename Surface>
struct fmt::formatter<::flatsurf::PathIterator<Surface>> : ::flatsurf::GenericFormatter<::flatsurf::PathIterator<Surface>> {};
template <typename Surface>
struct fmt::formatter<::flatsurf::Ray<Surface>> : ::flatsurf::GenericFormatter<::flatsurf::Ray<Surface>> {};
template <typename Surface>
struct fmt::formatter<::flatsurf::Segment<Surface>> : ::flatsurf::GenericFormatter<::flatsurf::Segment<Surface>> {};
template <typename Surface>
struct fmt::formatter<::flatsurf::SegmentIterator<Surface>> : ::flatsurf::GenericFormatter<::flatsurf::SegmentIterator<Surface>> {};

#endif
9 changes: 9 additions & 0 deletions libflatsurf/flatsurf/forward.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ struct PrivateConstructor {};

struct ProtectedConstructor {};

template <typename Surface>
class Ray;

template <typename Surface>
class SaddleConnection;

Expand All @@ -155,6 +158,12 @@ class SaddleConnectionsSample;
template <typename Surface>
class SaddleConnectionsSampleIterator;

template <typename Surface>
class Segment;

template <typename Surface>
class SegmentIterator;

template <typename T>
class Serializable;

Expand Down
41 changes: 33 additions & 8 deletions libflatsurf/flatsurf/path.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of flatsurf.
*
* Copyright (C) 2021 Julian Rüth
* Copyright (C) 2021-2022 Julian Rüth
*
* Flatsurf is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -22,36 +22,48 @@

#include <boost/operators.hpp>
#include <iosfwd>
#include <optional>
#include <vector>

#include "copyable.hpp"
#include "serializable.hpp"

namespace flatsurf {

// A connected list of SaddleConnections in a Surface.
// A connected list of Segments in a Surface.
template <typename Surface>
class Path : public Serializable<Path<Surface>>,
boost::equality_comparable<Path<Surface>> {
using Segment = SaddleConnection<Surface>;
using T = typename Surface::Coordinate;

public:
Path() noexcept;
Path(const Segment&);
Path(const std::vector<Segment>&);
Path(const Segment<Surface>&);
Path(const std::vector<Segment<Surface>>&);

operator const std::vector<Segment> &() const;
[[deprecated("crete a path from the .segment() of a saddle connection instead")]]
Path(const SaddleConnection<Surface>&);
[[deprecated("crete a path from the sequence of .segment() of a saddle connections instead")]]
Path(const std::vector<SaddleConnection<Surface>>&);

[[deprecated("a path cannot always be converted to a sequence of saddle connections; convert to a vector of segments instead")]]
operator const std::vector<SaddleConnection<Surface>> &() const;

operator const std::vector<Segment<Surface>> &() const;

// Return whether two paths are indistinguishable, i.e., they are made up of
// the same sequence of segments.
bool operator==(const Path&) const;

// Return whether the path is cyclic, i.e., the last element joins up with the first.
bool closed() const;

// Return whether there are no segments showing up more than once.
// TODO: We need to consider partial segments here.
bool simple() const;

// Return whether there are no segments followed by their negatives.
// TODO: We need to consider partial segments here.
bool reduced() const;

// Return whether the two paths are equivalent in homotopy.
Expand Down Expand Up @@ -80,8 +92,18 @@ class Path : public Serializable<Path<Surface>>,
// connections in reverse order.
Path operator-() const;

void push_front(const Segment&);
void push_back(const Segment&);
// Return a single segment that is equivalent to this path.
// Return nullopt if this path is not made up of segments that join up to a
// single segment.
std::optional<Segment<Surface>> segment() const;

void push_front(const Segment<Surface>&);
void push_back(const Segment<Surface>&);

[[deprecated("push the saddle connection's .segment() instead")]]
void push_front(const SaddleConnection<Surface>&);
[[deprecated("push the saddle connection's .segment() instead")]]
void push_back(const SaddleConnection<Surface>&);

void pop_front();
void pop_back();
Expand All @@ -103,7 +125,9 @@ class Path : public Serializable<Path<Surface>>,

friend ImplementationOf<Path>;
friend iterator;
friend SegmentIterator<Surface>;
friend ImplementationOf<iterator>;
friend ImplementationOf<SegmentIterator<Surface>>;
};

template <typename Surface>
Expand All @@ -113,4 +137,5 @@ template <typename Surface>
Path(const SaddleConnection<Surface>&) -> Path<Surface>;

} // namespace flatsurf

#endif
7 changes: 5 additions & 2 deletions libflatsurf/flatsurf/path_iterator.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of flatsurf.
*
* Copyright (C) 2020 Julian Rüth
* Copyright (C) 2020-2022 Julian Rüth
*
* Flatsurf is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -30,7 +30,7 @@ namespace flatsurf {

// Iterates over a path in a surface, i.e., over a connected sequence of saddle connections.
template <typename Surface>
class PathIterator : public boost::iterator_facade<PathIterator<Surface>, const SaddleConnection<Surface>&, boost::forward_traversal_tag> {
class [[deprecated("use SegmentIterator instead")]] PathIterator : public boost::iterator_facade<PathIterator<Surface>, const SaddleConnection<Surface>&, boost::forward_traversal_tag> {
template <typename... Args>
PathIterator(PrivateConstructor, Args&&...);

Expand All @@ -41,6 +41,9 @@ class PathIterator : public boost::iterator_facade<PathIterator<Surface>, const
const value_type& dereference() const;
bool equal(const PathIterator& other) const;

operator const SegmentIterator<Surface>() const;
operator SegmentIterator<Surface>();

template <typename S>
friend std::ostream& operator<<(std::ostream&, const PathIterator<S>&);

Expand Down
107 changes: 107 additions & 0 deletions libflatsurf/flatsurf/ray.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**********************************************************************
* This file is part of flatsurf.
*
* Copyright (C) 2022 Julian Rüth
*
* Flatsurf is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Flatsurf is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with flatsurf. If not, see <https://www.gnu.org/licenses/>.
*********************************************************************/

#ifndef LIBFLATSURF_RAY_HPP
#define LIBFLATSURF_RAY_HPP

#include <boost/operators.hpp>
#include <iosfwd>
#include <type_traits>

#include "copyable.hpp"
#include "serializable.hpp"

namespace flatsurf {

// A ray starting at a point of a translation surface.
template <typename Surface>
class Ray : Serializable<Ray<Surface>>,
boost::equality_comparable<Ray<Surface>> {
static_assert(std::is_same_v<Surface, std::decay_t<Surface>>, "type must not have modifiers such as const");

using T = typename Surface::Coordinate;

public:
Ray(const Point<Surface>&, const Vector<T>&);
Ray(const Point<Surface>&, HalfEdge source, const Vector<T>&);
Ray(const Surface&, HalfEdge source, const Vector<T>&);
Ray(const Surface&, HalfEdge);

const Point<Surface>& start() const;

// Return a source half edge for this ray.
// This is only really meaningful if start() is a vertex. In that case it
// returns one of the outgoing half edges of the vertex such that the
// vector() is inSector().
// If start() is on an edge, returns the half edge corresponding to the face
// into which the vector points (if parallel to the edge, then the half edge
// that is parallel to the vector.)
// If start() is in a face, returns a half edge such that vector or -vector
// is inSector of that half edge.
HalfEdge source() const;

// Return a vector pointing in the direction of this ray.
explicit operator const Vector<T> &() const;

// Return a vector pointing in the direction of this ray.
const Vector<T>& vector() const;

operator Vertical<Surface>() const;

// Return the saddle connection obtained by extending this ray.
SaddleConnection<Surface> saddleConnection() const;

// Return the turns between two rays starting at the same point.
// If the angle between this ray and the argument is α going
// in counter-clockwise direction, returns ⌊α/2π⌋.
int angle(const Ray&) const;

// Return the turn direction between rays.
// Returns whether it is shorter to turn in counterclockwise or
// clockwise direction. Returns COLLINEAR if both are the same.
CCW ccw(const Ray&) const;

// Return whether two rays are the same, i.e., they are pointing in the same
// direction from the same starting point.
bool operator==(const Ray&) const;

const Surface &surface() const;

// Return the segment obtained by following this ray until ``end``.
Segment<Surface> segment(const Point<Surface>& end) const;

template <typename S>
friend std::ostream &operator<<(std::ostream &, const Ray<S> &);

private:
Copyable<Ray> self;

friend ImplementationOf<Ray>;
};

template <typename Surface, typename... Args>
Ray(const Surface &, Args &&...) -> Ray<Surface>;

template <typename Surface, typename... Args>
Ray(const Point<Surface>&, Args &&...) -> Ray<Surface>;

} // namespace flatsurf

#endif