mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
495da3de23
commit
fa301b0d32
|
|
@ -43,6 +43,22 @@ Vertex::Vertex (const db::DPoint &p)
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex::Vertex (const Vertex &v)
|
||||
: DPoint (), m_level (0)
|
||||
{
|
||||
operator= (v);
|
||||
}
|
||||
|
||||
Vertex &Vertex::operator= (const Vertex &v)
|
||||
{
|
||||
if (this != &v) {
|
||||
// NOTE: edges are not copied!
|
||||
db::DPoint::operator= (v);
|
||||
m_level = v.m_level;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vertex::Vertex (db::DCoord x, db::DCoord y)
|
||||
: DPoint (x, y), m_level (0)
|
||||
{
|
||||
|
|
@ -76,9 +92,30 @@ Vertex::triangles () const
|
|||
}
|
||||
|
||||
std::string
|
||||
Vertex::to_string () const
|
||||
Vertex::to_string (bool with_id) const
|
||||
{
|
||||
return db::DPoint::to_string () + tl::sprintf ("[%p]", (void *)this);
|
||||
std::string res = tl::sprintf ("(%.12g, %.12g)", x (), y());
|
||||
if (with_id) {
|
||||
res += tl::sprintf ("[%p]", (void *)this);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
Vertex::in_circle (const DPoint &point, const DPoint ¢er, double radius)
|
||||
{
|
||||
double dx = point.x () - center.x ();
|
||||
double dy = point.y () - center.y ();
|
||||
double d2 = dx * dx + dy * dy;
|
||||
double r2 = radius * radius;
|
||||
double delta = std::max (1.0, fabs (d2 + r2)) * db::epsilon;
|
||||
if (d2 < r2 - delta) {
|
||||
return 1;
|
||||
} else if (d2 < r2 + delta) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
|
@ -141,9 +178,13 @@ TriangleEdge::common_vertex (const TriangleEdge &other) const
|
|||
}
|
||||
|
||||
std::string
|
||||
TriangleEdge::to_string () const
|
||||
TriangleEdge::to_string (bool with_id) const
|
||||
{
|
||||
return mp_v1->to_string () + "," + mp_v2->to_string () + tl::sprintf ("[%p]", (void *)this);
|
||||
std::string res = std::string ("(") + mp_v1->to_string (with_id) + ", " + mp_v2->to_string (with_id) + ")";
|
||||
if (with_id) {
|
||||
res += tl::sprintf ("[%p]", (void *)this);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
double
|
||||
|
|
@ -279,19 +320,20 @@ Triangle::Triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3)
|
|||
}
|
||||
|
||||
std::string
|
||||
Triangle::to_string () const
|
||||
Triangle::to_string (bool with_id) const
|
||||
{
|
||||
std::string res;
|
||||
std::string res = "(";
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (i > 0) {
|
||||
res += ", ";
|
||||
}
|
||||
if (vertex (i)) {
|
||||
res += vertex (i)->to_string ();
|
||||
res += vertex (i)->to_string (with_id);
|
||||
} else {
|
||||
res += "(null)";
|
||||
}
|
||||
}
|
||||
res += ")";
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +437,7 @@ Triangle::contains (const db::DPoint &point) const
|
|||
int s = db::DEdge (*vl, *v).side_of (point);
|
||||
if (s == 0) {
|
||||
res = 0;
|
||||
} else if (s < 0) {
|
||||
} else if (s > 0) {
|
||||
return -1;
|
||||
}
|
||||
vl = v;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class TriangleEdge;
|
|||
* an integer value that can be used in traversal algorithms
|
||||
* ("level")
|
||||
*/
|
||||
class Vertex
|
||||
class DB_PUBLIC Vertex
|
||||
: public db::DPoint
|
||||
{
|
||||
public:
|
||||
|
|
@ -53,8 +53,11 @@ public:
|
|||
|
||||
Vertex ();
|
||||
Vertex (const DPoint &p);
|
||||
Vertex (const Vertex &v);
|
||||
Vertex (db::DCoord x, db::DCoord y);
|
||||
|
||||
Vertex &operator= (const Vertex &v);
|
||||
|
||||
bool is_outside () const;
|
||||
std::vector<db::Triangle *> triangles () const;
|
||||
|
||||
|
|
@ -64,7 +67,21 @@ public:
|
|||
size_t level () const { return m_level; }
|
||||
void set_level (size_t l) { m_level = l; }
|
||||
|
||||
std::string to_string () const;
|
||||
std::string to_string (bool with_id = false) const;
|
||||
|
||||
/**
|
||||
* @brief Returns 1 is the point is inside the circle, 0 if on the circle and -1 if outside
|
||||
* @@@ TODO: Move to db::DPoint
|
||||
*/
|
||||
static int in_circle (const db::DPoint &point, const db::DPoint ¢er, double radius);
|
||||
|
||||
/**
|
||||
* @brief Returns 1 is this point is inside the circle, 0 if on the circle and -1 if outside
|
||||
*/
|
||||
int in_circle (const db::DPoint ¢er, double radius) const
|
||||
{
|
||||
return in_circle (*this, center, radius);
|
||||
}
|
||||
|
||||
private:
|
||||
edges_type m_edges;
|
||||
|
|
@ -74,7 +91,7 @@ private:
|
|||
/**
|
||||
* @brief A class representing an edge in the Delaunay triangulation graph
|
||||
*/
|
||||
class TriangleEdge
|
||||
class DB_PUBLIC TriangleEdge
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
|
|
@ -136,6 +153,11 @@ public:
|
|||
Vertex *v1 () const { return mp_v1; }
|
||||
Vertex *v2 () const { return mp_v2; }
|
||||
|
||||
void reverse ()
|
||||
{
|
||||
std::swap (mp_v1, mp_v2);
|
||||
}
|
||||
|
||||
Triangle *left () const { return const_cast<Triangle *> (mp_left.get ()); }
|
||||
Triangle *right () const { return const_cast<Triangle *> (mp_right.get ()); }
|
||||
void set_left (Triangle *t) { mp_left = t; }
|
||||
|
|
@ -157,7 +179,7 @@ public:
|
|||
void set_is_segment (bool is_seg) { m_is_segment = is_seg; }
|
||||
bool is_segment () const { return m_is_segment; }
|
||||
|
||||
std::string to_string () const;
|
||||
std::string to_string (bool with_id = false) const;
|
||||
|
||||
/**
|
||||
* @brief Converts to an db::DEdge
|
||||
|
|
@ -186,7 +208,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating wether this edge crosses the other one
|
||||
* @brief Returns a value indicating whether this edge crosses the other one
|
||||
*
|
||||
* "crosses" is true, if both edges share at least one point which is not an endpoint
|
||||
* of one of the edges.
|
||||
|
|
@ -195,7 +217,7 @@ public:
|
|||
static bool crosses (const db::DEdge &e, const db::DEdge &other);
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating wether this edge crosses the other one
|
||||
* @brief Returns a value indicating whether this edge crosses the other one
|
||||
*
|
||||
* "crosses" is true, if both edges share at least one point which is not an endpoint
|
||||
* of one of the edges.
|
||||
|
|
@ -206,14 +228,25 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating wether this edge crosses the other one
|
||||
* @brief Returns a value indicating whether this edge crosses the other one
|
||||
*
|
||||
* "crosses" is true, if both edges share at least one point which is not an endpoint
|
||||
* of one of the edges.
|
||||
*/
|
||||
bool crosses (const db::TriangleEdge &other) const
|
||||
{
|
||||
return crosses (edge (), other.edge ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether this edge crosses the other one
|
||||
* "crosses" is true, if both edges share at least one point.
|
||||
* @@@ TODO: Move to db::DEdge
|
||||
*/
|
||||
static bool crosses_including (const db::DEdge &e, const db::DEdge &other);
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating wether this edge crosses the other one
|
||||
* @brief Returns a value indicating whether this edge crosses the other one
|
||||
* "crosses" is true, if both edges share at least one point.
|
||||
*/
|
||||
bool crosses_including (const db::DEdge &other) const
|
||||
|
|
@ -221,6 +254,15 @@ public:
|
|||
return crosses_including (edge (), other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether this edge crosses the other one
|
||||
* "crosses" is true, if both edges share at least one point.
|
||||
*/
|
||||
bool crosses_including (const db::TriangleEdge &other) const
|
||||
{
|
||||
return crosses_including (edge (), other.edge ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the intersection point
|
||||
* @@@ TODO: Move to db::DEdge
|
||||
|
|
@ -253,10 +295,22 @@ public:
|
|||
* @brief Gets the side the point is on
|
||||
*
|
||||
* -1 is for "left", 0 is "on" and +1 is "right"
|
||||
* @@@ TODO: correct to same definition as db::Edge (negative)
|
||||
*/
|
||||
static int side_of (const db::DEdge &e, const db::DPoint &point)
|
||||
{
|
||||
return -e.side_of (point);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the side the point is on
|
||||
*
|
||||
* -1 is for "left", 0 is "on" and +1 is "right"
|
||||
* @@@ TODO: correct to same definition as db::Edge (negative)
|
||||
*/
|
||||
int side_of (const db::DPoint &p) const
|
||||
{
|
||||
return edge ().side_of (p);
|
||||
return -edge ().side_of (p);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -317,12 +371,16 @@ private:
|
|||
tl::weak_ptr<Triangle> mp_left, mp_right;
|
||||
size_t m_level;
|
||||
bool m_is_segment;
|
||||
|
||||
// no copying
|
||||
TriangleEdge &operator= (const TriangleEdge &);
|
||||
TriangleEdge (const TriangleEdge &);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A class representing a triangle
|
||||
*/
|
||||
class Triangle
|
||||
class DB_PUBLIC Triangle
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
|
|
@ -332,7 +390,7 @@ public:
|
|||
bool is_outside () const { return m_is_outside; }
|
||||
void set_outside (bool o) { m_is_outside = o; }
|
||||
|
||||
std::string to_string () const;
|
||||
std::string to_string (bool with_id = false) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the nth vertex (n wraps around and can be negative)
|
||||
|
|
@ -379,6 +437,10 @@ private:
|
|||
bool m_is_outside;
|
||||
tl::weak_ptr<TriangleEdge> mp_e1, mp_e2, mp_e3;
|
||||
db::Vertex *mp_v1, *mp_v2, *mp_v3;
|
||||
|
||||
// no copying
|
||||
Triangle &operator= (const Triangle &);
|
||||
Triangle (const Triangle &);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,286 @@
|
|||
#include "dbTriangle.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
#include <list>
|
||||
|
||||
// Tests for Triangle class
|
||||
|
||||
TEST(Triangle_basic)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 2);
|
||||
db::Vertex v3 (2, 1);
|
||||
|
||||
db::TriangleEdge s1 (&v1, &v2);
|
||||
db::TriangleEdge s2 (&v2, &v3);
|
||||
db::TriangleEdge s3 (&v3, &v1);
|
||||
|
||||
db::Triangle tri (&s1, &s2, &s3);
|
||||
EXPECT_EQ (tri.to_string (), "((0, 0), (1, 2), (2, 1))");
|
||||
|
||||
// ordering
|
||||
db::TriangleEdge s11 (&v1, &v2);
|
||||
db::TriangleEdge s12 (&v3, &v2);
|
||||
db::TriangleEdge s13 (&v1, &v3);
|
||||
|
||||
db::Triangle tri2 (&s11, &s12, &s13);
|
||||
EXPECT_EQ (tri2.to_string (), "((0, 0), (1, 2), (2, 1))");
|
||||
}
|
||||
|
||||
TEST(Triangle_find_segment_with)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 2);
|
||||
db::Vertex v3 (2, 1);
|
||||
|
||||
db::TriangleEdge s1 (&v1, &v2);
|
||||
db::TriangleEdge s2 (&v2, &v3);
|
||||
db::TriangleEdge s3 (&v3, &v1);
|
||||
|
||||
db::Triangle tri (&s1, &s2, &s3);
|
||||
|
||||
EXPECT_EQ (tri.find_edge_with (&v1, &v2)->to_string (), "((0, 0), (1, 2))");
|
||||
EXPECT_EQ (tri.find_edge_with (&v2, &v1)->to_string (), "((0, 0), (1, 2))");
|
||||
}
|
||||
|
||||
TEST(Triangle_ext_vertex)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 2);
|
||||
db::Vertex v3 (2, 1);
|
||||
|
||||
db::TriangleEdge s1 (&v1, &v2);
|
||||
db::TriangleEdge s2 (&v2, &v3);
|
||||
db::TriangleEdge s3 (&v3, &v1);
|
||||
|
||||
db::Triangle tri (&s1, &s2, &s3);
|
||||
|
||||
EXPECT_EQ (tri.opposite (&s1)->to_string (), "(2, 1)");
|
||||
EXPECT_EQ (tri.opposite (&s3)->to_string (), "(1, 2)");
|
||||
}
|
||||
|
||||
TEST(Triangle_opposite_vertex)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 2);
|
||||
db::Vertex v3 (2, 1);
|
||||
|
||||
db::TriangleEdge s1 (&v1, &v2);
|
||||
db::TriangleEdge s2 (&v2, &v3);
|
||||
db::TriangleEdge s3 (&v3, &v1);
|
||||
|
||||
db::Triangle tri (&s1, &s2, &s3);
|
||||
|
||||
EXPECT_EQ (tri.opposite (&s1)->to_string (), "(2, 1)");
|
||||
EXPECT_EQ (tri.opposite (&s3)->to_string (), "(1, 2)");
|
||||
}
|
||||
|
||||
TEST(Triangle_opposite_edge)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 2);
|
||||
db::Vertex v3 (2, 1);
|
||||
|
||||
db::TriangleEdge s1 (&v1, &v2);
|
||||
db::TriangleEdge s2 (&v2, &v3);
|
||||
db::TriangleEdge s3 (&v3, &v1);
|
||||
|
||||
db::Triangle tri (&s1, &s2, &s3);
|
||||
|
||||
EXPECT_EQ (tri.opposite (&v1)->to_string (), "((1, 2), (2, 1))");
|
||||
EXPECT_EQ (tri.opposite (&v3)->to_string (), "((0, 0), (1, 2))");
|
||||
}
|
||||
|
||||
TEST(Triangle_contains)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 2);
|
||||
db::Vertex v3 (2, 1);
|
||||
|
||||
db::TriangleEdge s1 (&v1, &v2);
|
||||
db::TriangleEdge s2 (&v2, &v3);
|
||||
db::TriangleEdge s3 (&v3, &v1);
|
||||
|
||||
db::Triangle tri (&s1, &s2, &s3);
|
||||
|
||||
EXPECT_EQ (tri.contains (db::DPoint (0, 0)), 0);
|
||||
EXPECT_EQ (tri.contains (db::DPoint (-1, -2)), -1);
|
||||
EXPECT_EQ (tri.contains (db::DPoint (0.5, 1)), 0);
|
||||
EXPECT_EQ (tri.contains (db::DPoint (0.5, 2)), -1);
|
||||
EXPECT_EQ (tri.contains (db::DPoint (2.5, 1)), -1);
|
||||
EXPECT_EQ (tri.contains (db::DPoint (1, -1)), -1);
|
||||
EXPECT_EQ (tri.contains (db::DPoint (1, 1)), 1);
|
||||
|
||||
s1.reverse ();
|
||||
s2.reverse ();
|
||||
s3.reverse ();
|
||||
|
||||
db::Triangle tri2 (&s3, &s2, &s1);
|
||||
EXPECT_EQ (tri2.contains(db::DPoint(0, 0)), 0);
|
||||
EXPECT_EQ (tri2.contains(db::DPoint(0.5, 1)), 0);
|
||||
EXPECT_EQ (tri2.contains(db::DPoint(0.5, 2)), -1);
|
||||
EXPECT_EQ (tri2.contains(db::DPoint(2.5, 1)), -1);
|
||||
EXPECT_EQ (tri2.contains(db::DPoint(1, -1)), -1);
|
||||
EXPECT_EQ (tri2.contains(db::DPoint(1, 1)), 1);
|
||||
}
|
||||
|
||||
TEST(Triangle_circumcircle)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 2);
|
||||
db::Vertex v3 (2, 1);
|
||||
|
||||
db::TriangleEdge s1 (&v1, &v2);
|
||||
db::TriangleEdge s2 (&v2, &v3);
|
||||
db::TriangleEdge s3 (&v3, &v1);
|
||||
|
||||
db::Triangle tri (&s1, &s2, &s3);
|
||||
|
||||
auto cc = tri.circumcircle ();
|
||||
auto center = cc.first;
|
||||
auto radius = cc.second;
|
||||
|
||||
EXPECT_EQ (tl::to_string (center), "0.833333333333,0.833333333333");
|
||||
EXPECT_EQ (tl::to_string (radius), "1.17851130198");
|
||||
|
||||
EXPECT_EQ (db::Vertex::in_circle (center, center, radius), 1);
|
||||
EXPECT_EQ (db::Vertex::in_circle (db::DPoint (-1, -1), center, radius), -1);
|
||||
EXPECT_EQ (v1.in_circle (center, radius), 0);
|
||||
EXPECT_EQ (v2.in_circle (center, radius), 0);
|
||||
EXPECT_EQ (v3.in_circle (center, radius), 0);
|
||||
}
|
||||
|
||||
// Tests for TriangleEdge class
|
||||
|
||||
TEST(TriangleEdge_basic)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 0.5);
|
||||
|
||||
db::TriangleEdge edge (&v1, &v2);
|
||||
EXPECT_EQ (edge.to_string (), "((0, 0), (1, 0.5))");
|
||||
}
|
||||
|
||||
TEST(TriangleEdge_side_of)
|
||||
{
|
||||
db::Vertex v1;
|
||||
db::Vertex v2 (1, 0.5);
|
||||
|
||||
db::TriangleEdge edge (&v1, &v2);
|
||||
EXPECT_EQ (edge.to_string (), "((0, 0), (1, 0.5))");
|
||||
|
||||
EXPECT_EQ (edge.side_of (db::Vertex (0, 0)), 0)
|
||||
EXPECT_EQ (edge.side_of (db::Vertex (0.5, 0.25)), 0)
|
||||
EXPECT_EQ (edge.side_of (db::Vertex (0, 1)), -1)
|
||||
EXPECT_EQ (edge.side_of (db::Vertex (0, -1)), 1)
|
||||
EXPECT_EQ (edge.side_of (db::Vertex (0.5, 0.5)), -1)
|
||||
EXPECT_EQ (edge.side_of (db::Vertex (0.5, 0)), 1)
|
||||
|
||||
db::Vertex v3 (1, 0);
|
||||
db::Vertex v4 (0, 1);
|
||||
db::TriangleEdge edge2 (&v3, &v4);
|
||||
|
||||
EXPECT_EQ (edge2.side_of (db::Vertex(0.2, 0.2)), -1);
|
||||
}
|
||||
|
||||
namespace {
|
||||
class VertexHeap
|
||||
{
|
||||
public:
|
||||
db::Vertex *make_vertex (double x, double y)
|
||||
{
|
||||
m_heap.push_back (db::Vertex (x, y));
|
||||
return &m_heap.back ();
|
||||
}
|
||||
private:
|
||||
std::list<db::Vertex> m_heap;
|
||||
};
|
||||
}
|
||||
|
||||
TEST(TriangleEdge_crosses)
|
||||
{
|
||||
VertexHeap heap;
|
||||
|
||||
db::TriangleEdge s1 (heap.make_vertex (0, 0), heap.make_vertex (1, 0.5));
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, -0.5), heap.make_vertex(1, -0.5))), false);
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0), heap.make_vertex(1, 0))), false); // only cuts
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(1, 0.5))), false);
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(2, 0.5))), false);
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex(2, 0.25))), true);
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(-0.1, 0.5))), false);
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.6), heap.make_vertex(0, 0.6))), false);
|
||||
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 1), heap.make_vertex(1, 1))), false);
|
||||
|
||||
EXPECT_EQ (s1.crosses_including (db::TriangleEdge (heap.make_vertex (-1, -0.5), heap.make_vertex(1, -0.5))), false);
|
||||
EXPECT_EQ (s1.crosses_including (db::TriangleEdge (heap.make_vertex (-1, 0), heap.make_vertex(1, 0))), true); // only cuts
|
||||
EXPECT_EQ (s1.crosses_including (db::TriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex(2, 0.25))), true);
|
||||
}
|
||||
|
||||
#if 0
|
||||
class TestSegment(unittest.TestCase):
|
||||
|
||||
def test_crosses(self):
|
||||
s1 = t.TriangleEdge(t.Vertex(0, 0), t.Vertex(1, 0.5))
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, -0.5), t.Vertex(1, -0.5))), False)
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, 0), t.Vertex(1, 0))), False) # only cuts
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, 0.5), t.Vertex(1, 0.5))), False)
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, 0.5), t.Vertex(2, 0.5))), False)
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, 0.25), t.Vertex(2, 0.25))), True)
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, 0.5), t.Vertex(-0.1, 0.5))), False)
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, 0.6), t.Vertex(0, 0.6))), False)
|
||||
EXPECT_EQ (s1.crosses(t.TriangleEdge(t.Vertex(-1, 1), t.Vertex(1, 1))), False)
|
||||
|
||||
def test_point_on(self):
|
||||
s1 = t.TriangleEdge(t.Vertex(0, 0), t.Vertex(1, 0.5))
|
||||
EXPECT_EQ (s1.point_on(t.Point(0, 0)), False) # endpoints are not "on"
|
||||
EXPECT_EQ (s1.point_on(t.Point(0, -0.5)), False)
|
||||
EXPECT_EQ (s1.point_on(t.Point(0.5, 0)), False)
|
||||
EXPECT_EQ (s1.point_on(t.Point(0.5, 0.25)), True)
|
||||
EXPECT_EQ (s1.point_on(t.Point(1, 0.5)), False) # endpoints are not "on"
|
||||
EXPECT_EQ (s1.point_on(t.Point(1, 1)), False)
|
||||
EXPECT_EQ (s1.point_on(t.Point(2, 1)), False)
|
||||
|
||||
def test_intersection_point(self):
|
||||
s1 = t.TriangleEdge(t.Vertex(0, 0), t.Vertex(1, 0.5))
|
||||
EXPECT_EQ (str(s1.intersection_point(t.TriangleEdge(t.Vertex(-1, 0.25), t.Vertex(2, 0.25)))), "(0.5, 0.25)")
|
||||
|
||||
def test_can_flip(self):
|
||||
v1 = t.Vertex(2, -1)
|
||||
v2 = t.Vertex(0, 0)
|
||||
v3 = t.Vertex(1, 0)
|
||||
v4 = t.Vertex(0.5, 1)
|
||||
s1 = t.TriangleEdge(v1, v2)
|
||||
s2 = t.TriangleEdge(v1, v3)
|
||||
s3 = t.TriangleEdge(v2, v3)
|
||||
s4 = t.TriangleEdge(v2, v4)
|
||||
s5 = t.TriangleEdge(v3, v4)
|
||||
t1 = t.Triangle(s1, s2, s3)
|
||||
t2 = t.Triangle(s3, s4, s5)
|
||||
s3.left = t1
|
||||
s3.right = t2
|
||||
EXPECT_EQ (s3.can_flip(), False)
|
||||
v1.x = 0.5
|
||||
EXPECT_EQ (s3.can_flip(), True)
|
||||
v1.x = -0.25
|
||||
EXPECT_EQ (s3.can_flip(), True)
|
||||
v1.x = -0.5
|
||||
EXPECT_EQ (s3.can_flip(), False)
|
||||
v1.x = -1.0
|
||||
EXPECT_EQ (s3.can_flip(), False)
|
||||
|
||||
def test_distance(self):
|
||||
seg = t.TriangleEdge(t.Vertex(0, 0), t.Vertex(1, 0))
|
||||
EXPECT_EQ (seg.distance(t.Point(0, 0)), 0)
|
||||
EXPECT_EQ (seg.distance(t.Point(0, 1)), 1)
|
||||
EXPECT_EQ (seg.distance(t.Point(1, 2)), 2)
|
||||
EXPECT_EQ (seg.distance(t.Point(1, -1)), 1)
|
||||
EXPECT_EQ (seg.distance(t.Point(2, 0)), 1)
|
||||
EXPECT_EQ (seg.distance(t.Point(-2, 0)), 2)
|
||||
seg.reverse()
|
||||
EXPECT_EQ (seg.distance(t.Point(0, 0)), 0)
|
||||
EXPECT_EQ (seg.distance(t.Point(0, 1)), 1)
|
||||
EXPECT_EQ (seg.distance(t.Point(1, 2)), 2)
|
||||
EXPECT_EQ (seg.distance(t.Point(1, -1)), 1)
|
||||
EXPECT_EQ (seg.distance(t.Point(2, 0)), 1)
|
||||
EXPECT_EQ (seg.distance(t.Point(-2, 0)), 2)
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue