mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
7bf23e7471
commit
495da3de23
|
|
@ -95,6 +95,8 @@ SOURCES = \
|
|||
dbTextWriter.cc \
|
||||
dbTilingProcessor.cc \
|
||||
dbTrans.cc \
|
||||
dbTriangle.cc \
|
||||
dbTriangles.cc \
|
||||
dbUserObject.cc \
|
||||
dbUtils.cc \
|
||||
dbVector.cc \
|
||||
|
|
@ -319,6 +321,8 @@ HEADERS = \
|
|||
dbTextWriter.h \
|
||||
dbTilingProcessor.h \
|
||||
dbTrans.h \
|
||||
dbTriangle.h \
|
||||
dbTriangles.h \
|
||||
dbTypes.h \
|
||||
dbUserObject.h \
|
||||
dbUtils.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,406 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbTriangle.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Vertex implementation
|
||||
|
||||
Vertex::Vertex ()
|
||||
: DPoint (), m_level (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex::Vertex (const db::DPoint &p)
|
||||
: DPoint (p), m_level (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex::Vertex (db::DCoord x, db::DCoord y)
|
||||
: DPoint (x, y), m_level (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool
|
||||
Vertex::is_outside () const
|
||||
{
|
||||
for (auto e = m_edges.begin (); e != m_edges.end (); ++e) {
|
||||
if (e->is_outside ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<db::Triangle *>
|
||||
Vertex::triangles () const
|
||||
{
|
||||
std::set<db::Triangle *> seen;
|
||||
std::vector<db::Triangle *> res;
|
||||
for (auto e = m_edges.begin (); e != m_edges.end (); ++e) {
|
||||
for (auto t = e->begin_triangles (); t != e->end_triangles (); ++t) {
|
||||
if (seen.insert (t.operator-> ()).second) {
|
||||
res.push_back (t.operator-> ());
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string
|
||||
Vertex::to_string () const
|
||||
{
|
||||
return db::DPoint::to_string () + tl::sprintf ("[%p]", (void *)this);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// TriangleEdge implementation
|
||||
|
||||
TriangleEdge::TriangleEdge ()
|
||||
: mp_v1 (0), mp_v2 (0), mp_left (), mp_right (), m_level (0), m_is_segment (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
TriangleEdge::TriangleEdge (Vertex *v1, Vertex *v2)
|
||||
: mp_v1 (v1), mp_v2 (v2), mp_left (), mp_right (), m_level (0), m_is_segment (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Triangle *
|
||||
TriangleEdge::other (const Triangle *t) const
|
||||
{
|
||||
if (t == mp_left.get ()) {
|
||||
return const_cast<Triangle *> (mp_right.get ());
|
||||
}
|
||||
if (t == mp_right.get ()) {
|
||||
return const_cast<Triangle *> (mp_left.get ());
|
||||
}
|
||||
tl_assert (false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vertex *
|
||||
TriangleEdge::other (const Vertex *t) const
|
||||
{
|
||||
if (t == mp_v1) {
|
||||
return mp_v2;
|
||||
}
|
||||
if (t == mp_v2) {
|
||||
return mp_v1;
|
||||
}
|
||||
tl_assert (false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::has_vertex (const Vertex *v) const
|
||||
{
|
||||
return mp_v1 == v || mp_v2 == v;
|
||||
}
|
||||
|
||||
Vertex *
|
||||
TriangleEdge::common_vertex (const TriangleEdge &other) const
|
||||
{
|
||||
if (has_vertex (other.v1 ())) {
|
||||
return (other.v1 ());
|
||||
}
|
||||
if (has_vertex (other.v2 ())) {
|
||||
return (other.v2 ());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string
|
||||
TriangleEdge::to_string () const
|
||||
{
|
||||
return mp_v1->to_string () + "," + mp_v2->to_string () + tl::sprintf ("[%p]", (void *)this);
|
||||
}
|
||||
|
||||
double
|
||||
TriangleEdge::distance (const db::DEdge &e, const db::DPoint &p)
|
||||
{
|
||||
double l = db::sprod (p - e.p1 (), e.d ()) / e.d ().sq_length ();
|
||||
db::DPoint pp;
|
||||
if (l <= 0.0) {
|
||||
pp = e.p1 ();
|
||||
} else if (l >= 1.0) {
|
||||
pp = e.p2 ();
|
||||
} else {
|
||||
pp = e.p1 () + e.d () * l;
|
||||
}
|
||||
return (p - pp).length ();
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::crosses (const db::DEdge &e, const db::DEdge &other)
|
||||
{
|
||||
return e.side_of (other.p1 ()) * e.side_of (other.p2 ()) < 0 &&
|
||||
other.side_of (e.p1 ()) * other.side_of (e.p2 ()) < 0;
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::crosses_including (const db::DEdge &e, const db::DEdge &other)
|
||||
{
|
||||
return e.side_of (other.p1 ()) * e.side_of (other.p2 ()) <= 0 &&
|
||||
other.side_of (e.p1 ()) * other.side_of (e.p2 ()) <= 0;
|
||||
}
|
||||
|
||||
db::DPoint
|
||||
TriangleEdge::intersection_point (const db::DEdge &e, const db::DEdge &other)
|
||||
{
|
||||
return e.intersect_point (other).second;
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::point_on (const db::DEdge &edge, const db::DPoint &point)
|
||||
{
|
||||
if (edge.side_of (point) != 0) {
|
||||
return false;
|
||||
} else {
|
||||
return db::sprod_sign (point - edge.p1 (), edge.d ()) * db::sprod_sign(point - edge.p2 (), edge.d ()) < 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::can_flip () const
|
||||
{
|
||||
if (! left () || ! right ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const db::Vertex *v1 = left ()->opposite (this);
|
||||
const db::Vertex *v2 = right ()->opposite (this);
|
||||
return crosses (db::DEdge (*v1, *v2));
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::can_join_via (const Vertex *vertex) const
|
||||
{
|
||||
if (! left () || ! right ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tl_assert (has_vertex (vertex));
|
||||
const db::Vertex *v1 = left ()->opposite (this);
|
||||
const db::Vertex *v2 = right ()->opposite (this);
|
||||
return db::DEdge (*v1, *v2).side_of (*vertex) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::is_outside () const
|
||||
{
|
||||
return left () == 0 || right () == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::is_for_outside_triangles () const
|
||||
{
|
||||
return (left () && left ()->is_outside ()) || (right () && right ()->is_outside ());
|
||||
}
|
||||
|
||||
bool
|
||||
TriangleEdge::has_triangle (const Triangle *t) const
|
||||
{
|
||||
return t != 0 && (left () == t || right () == t);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Triangle implementation
|
||||
|
||||
Triangle::Triangle ()
|
||||
: m_is_outside (false), mp_v1 (0), mp_v2 (0), mp_v3 (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Triangle::Triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3)
|
||||
: m_is_outside (false), mp_e1 (e1), mp_e2 (e2), mp_e3 (e3)
|
||||
{
|
||||
mp_v1 = e1->v1 ();
|
||||
mp_v2 = e1->other (mp_v1);
|
||||
|
||||
if (e2->has_vertex (mp_v2)) {
|
||||
mp_v3 = e2->other (mp_v2);
|
||||
tl_assert (e3->other (mp_v3) == mp_v1);
|
||||
} else {
|
||||
mp_v3 = e3->other (mp_v2);
|
||||
tl_assert (e2->other (mp_v3) == mp_v1);
|
||||
}
|
||||
|
||||
// enforce clockwise orientation
|
||||
if (db::vprod_sign (*mp_v3 - *mp_v1, *mp_v2 - *mp_v1) < 0) {
|
||||
std::swap (mp_v3, mp_v2);
|
||||
}
|
||||
|
||||
// establish link to edges
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TriangleEdge *e = edge (i);
|
||||
int side_of = 0;
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
side_of += e->side_of (*vertex (j));
|
||||
}
|
||||
// NOTE: in the degenerated case, the triangle is not attached to an edge!
|
||||
if (side_of < 0) {
|
||||
e->set_left (this);
|
||||
} else if (side_of > 0) {
|
||||
e->set_right (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
Triangle::to_string () const
|
||||
{
|
||||
std::string res;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (i > 0) {
|
||||
res += ", ";
|
||||
}
|
||||
if (vertex (i)) {
|
||||
res += vertex (i)->to_string ();
|
||||
} else {
|
||||
res += "(null)";
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Vertex *
|
||||
Triangle::vertex (int n) const
|
||||
{
|
||||
tl_assert (mp_e1 && mp_e2 && mp_e3);
|
||||
n = (n + 3) % 3;
|
||||
if (n == 0) {
|
||||
return mp_v1;
|
||||
} else if (n == 1) {
|
||||
return mp_v2;
|
||||
} else {
|
||||
return mp_v3;
|
||||
}
|
||||
}
|
||||
|
||||
TriangleEdge *
|
||||
Triangle::edge (int n) const
|
||||
{
|
||||
n = (n + 3) % 3;
|
||||
if (n == 0) {
|
||||
return const_cast<TriangleEdge *> (mp_e1.get ());
|
||||
} else if (n == 1) {
|
||||
return const_cast<TriangleEdge *> (mp_e2.get ());
|
||||
} else {
|
||||
return const_cast<TriangleEdge *> (mp_e3.get ());
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
Triangle::area () const
|
||||
{
|
||||
return fabs (db::vprod (mp_e1->d (), mp_e2->d ())) * 0.5;
|
||||
}
|
||||
|
||||
std::pair<db::DPoint, double>
|
||||
Triangle::circumcircle () const
|
||||
{
|
||||
db::DVector v1 = *vertex(0) - *vertex(1);
|
||||
db::DVector v2 = *vertex(0) - *vertex(2);
|
||||
db::DVector n1 = db::DVector (v1.y (), -v1.x ());
|
||||
db::DVector n2 = db::DVector (v2.y (), -v2.x ());
|
||||
|
||||
double p1s = vertex(0)->sq_distance (db::DPoint ());
|
||||
double p2s = vertex(1)->sq_distance (db::DPoint ());
|
||||
double p3s = vertex(2)->sq_distance (db::DPoint ());
|
||||
|
||||
double s = db::vprod (v1, v2);
|
||||
tl_assert (fabs (s) > db::epsilon);
|
||||
|
||||
db::DPoint center = db::DPoint () + (n2 * (p1s - p2s) - n1 * (p1s - p3s)) * (0.5 / s);
|
||||
double radius = (*vertex (0) - center).length ();
|
||||
|
||||
return std::make_pair (center, radius);
|
||||
}
|
||||
|
||||
Vertex *
|
||||
Triangle::opposite (const TriangleEdge *edge) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
Vertex *v = vertex (i);
|
||||
if (! edge->has_vertex (v)) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
TriangleEdge *
|
||||
Triangle::opposite (const Vertex *vertex) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TriangleEdge *e = edge (i);
|
||||
if (! e->has_vertex (vertex)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
TriangleEdge *
|
||||
Triangle::find_edge_with (const Vertex *v1, const Vertex *v2) const
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
TriangleEdge *e = edge (i);
|
||||
if (e->has_vertex (v1) && e->has_vertex (v2)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
int
|
||||
Triangle::contains (const db::DPoint &point) const
|
||||
{
|
||||
int res = 1;
|
||||
const Vertex *vl = vertex (-1);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const Vertex *v = vertex (i);
|
||||
int s = db::DEdge (*vl, *v).side_of (point);
|
||||
if (s == 0) {
|
||||
res = 0;
|
||||
} else if (s < 0) {
|
||||
return -1;
|
||||
}
|
||||
vl = v;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,388 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef HDR_dbTriangle
|
||||
#define HDR_dbTriangle
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbPoint.h"
|
||||
#include "dbEdge.h"
|
||||
|
||||
#include "tlObjectCollection.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
class Triangle;
|
||||
class TriangleEdge;
|
||||
|
||||
/**
|
||||
* @brief A class representing a vertex in a Delaunay triangulation graph
|
||||
*
|
||||
* The vertex carries information about the connected edges and
|
||||
* an integer value that can be used in traversal algorithms
|
||||
* ("level")
|
||||
*/
|
||||
class Vertex
|
||||
: public db::DPoint
|
||||
{
|
||||
public:
|
||||
typedef tl::weak_collection<db::TriangleEdge> edges_type;
|
||||
typedef edges_type::const_iterator edges_iterator;
|
||||
|
||||
Vertex ();
|
||||
Vertex (const DPoint &p);
|
||||
Vertex (db::DCoord x, db::DCoord y);
|
||||
|
||||
bool is_outside () const;
|
||||
std::vector<db::Triangle *> triangles () const;
|
||||
|
||||
edges_iterator begin_edges () const { return m_edges.begin (); }
|
||||
edges_iterator end_edges () const { return m_edges.end (); }
|
||||
|
||||
size_t level () const { return m_level; }
|
||||
void set_level (size_t l) { m_level = l; }
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
private:
|
||||
edges_type m_edges;
|
||||
size_t m_level;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A class representing an edge in the Delaunay triangulation graph
|
||||
*/
|
||||
class TriangleEdge
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
class TriangleIterator
|
||||
{
|
||||
public:
|
||||
typedef Triangle value_type;
|
||||
typedef Triangle &reference;
|
||||
typedef Triangle *pointer;
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
return *operator-> ();
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
return m_index ? mp_edge->right () : mp_edge->left ();
|
||||
}
|
||||
|
||||
bool operator== (const TriangleIterator &other) const
|
||||
{
|
||||
return mp_edge == other.mp_edge && m_index == other.m_index;
|
||||
}
|
||||
|
||||
bool operator!= (const TriangleIterator &other) const
|
||||
{
|
||||
return !operator== (other);
|
||||
}
|
||||
|
||||
TriangleIterator &operator++ ()
|
||||
{
|
||||
while (++m_index < 2 && operator-> () == 0)
|
||||
;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class TriangleEdge;
|
||||
|
||||
TriangleIterator (const TriangleEdge *edge)
|
||||
: mp_edge (edge), m_index (0)
|
||||
{
|
||||
if (! edge) {
|
||||
m_index = 2;
|
||||
} else {
|
||||
--m_index;
|
||||
operator++ ();
|
||||
}
|
||||
}
|
||||
|
||||
const TriangleEdge *mp_edge;
|
||||
unsigned int m_index;
|
||||
};
|
||||
|
||||
TriangleEdge ();
|
||||
TriangleEdge (Vertex *v1, Vertex *v2);
|
||||
|
||||
Vertex *v1 () const { return mp_v1; }
|
||||
Vertex *v2 () const { return 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; }
|
||||
void set_right (Triangle *t) { mp_right = t; }
|
||||
|
||||
TriangleIterator begin_triangles () const
|
||||
{
|
||||
return TriangleIterator (this);
|
||||
}
|
||||
|
||||
TriangleIterator end_triangles () const
|
||||
{
|
||||
return TriangleIterator (0);
|
||||
}
|
||||
|
||||
void set_level (size_t l) { m_level = l; }
|
||||
size_t level () const { return m_level; }
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @brief Converts to an db::DEdge
|
||||
*/
|
||||
db::DEdge edge () const
|
||||
{
|
||||
return db::DEdge (*mp_v1, *mp_v2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the distance of the given point to the edge
|
||||
*
|
||||
* The distance is the minimum distance of the point to one point from the edge.
|
||||
* @@@ TODO: Move to db::DEdge
|
||||
*/
|
||||
static double distance (const db::DEdge &e, const db::DPoint &p);
|
||||
|
||||
/**
|
||||
* @brief Returns the distance of the given point to the edge
|
||||
*
|
||||
* The distance is the minimum distance of the point to one point from the edge.
|
||||
*/
|
||||
double distance (const db::DPoint &p) const
|
||||
{
|
||||
return distance (edge (), p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating wether 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.
|
||||
* @@@ TODO: Move to db::DEdge
|
||||
*/
|
||||
static bool crosses (const db::DEdge &e, const db::DEdge &other);
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating wether 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::DEdge &other) const
|
||||
{
|
||||
return crosses (edge (), other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating wether 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
|
||||
* "crosses" is true, if both edges share at least one point.
|
||||
*/
|
||||
bool crosses_including (const db::DEdge &other) const
|
||||
{
|
||||
return crosses_including (edge (), other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the intersection point
|
||||
* @@@ TODO: Move to db::DEdge
|
||||
*/
|
||||
static db::DPoint intersection_point (const db::DEdge &e, const DEdge &other);
|
||||
|
||||
/**
|
||||
* @brief Gets the intersection point
|
||||
*/
|
||||
db::DPoint intersection_point (const db::DEdge &other) const
|
||||
{
|
||||
return intersection_point (edge (), other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the point is on the edge
|
||||
* @@@ TODO: Move to db::DEdge
|
||||
*/
|
||||
static bool point_on (const db::DEdge &edge, const db::DPoint &point);
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the point is on the edge
|
||||
*/
|
||||
bool point_on (const db::DPoint &point) const
|
||||
{
|
||||
return point_on (edge (), point);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the side the point is on
|
||||
*
|
||||
* -1 is for "left", 0 is "on" and +1 is "right"
|
||||
*/
|
||||
int side_of (const db::DPoint &p) const
|
||||
{
|
||||
return edge ().side_of (p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the distance vector
|
||||
*/
|
||||
db::DVector d () const
|
||||
{
|
||||
return *mp_v2 - *mp_v1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the other triangle for the given one
|
||||
*/
|
||||
Triangle *other (const Triangle *) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the other vertex for the given one
|
||||
*/
|
||||
Vertex *other (const Vertex *) const;
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the edge has the given vertex
|
||||
*/
|
||||
bool has_vertex (const Vertex *) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the common vertex of the other edge and this edge or null if there is no common vertex
|
||||
*/
|
||||
Vertex *common_vertex (const TriangleEdge &other) const;
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether this edge can be flipped
|
||||
*/
|
||||
bool can_flip () const;
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the edge separates two triangles that can be joined into one (via the given vertex)
|
||||
*/
|
||||
bool can_join_via (const Vertex *vertex) const;
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether this edge is an outside edge (no other triangles)
|
||||
*/
|
||||
bool is_outside () const;
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether this edge belongs to outside triangles
|
||||
*/
|
||||
bool is_for_outside_triangles () const;
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether t is attached to this edge
|
||||
*/
|
||||
bool has_triangle (const Triangle *t) const;
|
||||
|
||||
private:
|
||||
Vertex *mp_v1, *mp_v2;
|
||||
tl::weak_ptr<Triangle> mp_left, mp_right;
|
||||
size_t m_level;
|
||||
bool m_is_segment;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A class representing a triangle
|
||||
*/
|
||||
class Triangle
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
Triangle ();
|
||||
Triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3);
|
||||
|
||||
bool is_outside () const { return m_is_outside; }
|
||||
void set_outside (bool o) { m_is_outside = o; }
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the nth vertex (n wraps around and can be negative)
|
||||
* The vertexes are oriented clockwise.
|
||||
*/
|
||||
Vertex *vertex (int n) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the nth edge (n wraps around and can be negative)
|
||||
*/
|
||||
TriangleEdge *edge (int n) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the area
|
||||
*/
|
||||
double area () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the center point and radius of the circumcircle
|
||||
*/
|
||||
std::pair<db::DPoint, double> circumcircle () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the vertex opposite of the given edge
|
||||
*/
|
||||
Vertex *opposite (const TriangleEdge *edge) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the edge opposite of the given vertex
|
||||
*/
|
||||
TriangleEdge *opposite (const Vertex *vertex) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the edge with the given vertexes
|
||||
*/
|
||||
TriangleEdge *find_edge_with (const Vertex *v1, const Vertex *v2) const;
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the point is inside (1), on the triangle (0) or outside (-1)
|
||||
*/
|
||||
int contains (const db::DPoint &point) const;
|
||||
|
||||
private:
|
||||
bool m_is_outside;
|
||||
tl::weak_ptr<TriangleEdge> mp_e1, mp_e2, mp_e3;
|
||||
db::Vertex *mp_v1, *mp_v2, *mp_v3;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbTriangles.h"
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef HDR_dbTriangles
|
||||
#define HDR_dbTriangles
|
||||
|
||||
#include "dbCommon.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbTriangle.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2023 Matthias Koefferlein
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbTriangles.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ SOURCES = \
|
|||
dbFillToolTests.cc \
|
||||
dbRecursiveInstanceIteratorTests.cc \
|
||||
dbRegionCheckUtilsTests.cc \
|
||||
dbTriangleTests.cc \
|
||||
dbTrianglesTests.cc \
|
||||
dbUtilsTests.cc \
|
||||
dbWriterTools.cc \
|
||||
dbLoadLayoutOptionsTests.cc \
|
||||
|
|
|
|||
Loading…
Reference in New Issue