summaryrefslogtreecommitdiffstats
path: root/src/libavoid/visibility.cpp
diff options
context:
space:
mode:
authorSylvain Chiron <chironsylvain@orange.fr>2017-07-01 11:36:41 +0000
committerSylvain Chiron <chironsylvain@orange.fr>2017-07-01 11:36:41 +0000
commitfd733201b82f39655488a286c89142f321ef9dc9 (patch)
treea12c70f213414f69467f666619b1552103f6370e /src/libavoid/visibility.cpp
parentHackfest icon work: restore selected menu icons and make theming easier (diff)
downloadinkscape-fd733201b82f39655488a286c89142f321ef9dc9.tar.gz
inkscape-fd733201b82f39655488a286c89142f321ef9dc9.zip
Updated libs from the Adaptagrams project: libavoid, libcola and libvspc; changed the code to match the new API
Signed-off-by: Sylvain Chiron <chironsylvain@orange.fr>
Diffstat (limited to '')
-rw-r--r--src/libavoid/visibility.cpp234
1 files changed, 87 insertions, 147 deletions
diff --git a/src/libavoid/visibility.cpp b/src/libavoid/visibility.cpp
index 089911f35..8f98d575a 100644
--- a/src/libavoid/visibility.cpp
+++ b/src/libavoid/visibility.cpp
@@ -27,14 +27,12 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
- * Author(s): Michael Wybrow <mjwybrow@users.sourceforge.net>
+ * Author(s): Michael Wybrow
*/
#include <algorithm>
#include <cfloat>
-#define _USE_MATH_DEFINES
-#include <cmath>
#include "libavoid/shape.h"
#include "libavoid/debug.h"
@@ -45,27 +43,24 @@
#include "libavoid/router.h"
#include "libavoid/assertions.h"
-#ifdef LINEDEBUG
- #include "SDL_gfxPrimitives.h"
-#endif
namespace Avoid {
-void shapeVis(ShapeRef *shape)
-{
- Router *router = shape->router();
+static void vertexSweep(VertInf *vert);
- if ( !(router->InvisibilityGrph) )
+void Obstacle::computeVisibilityNaive(void)
+{
+ if ( !(router()->InvisibilityGrph) )
{
// Clear shape from graph.
- shape->removeFromGraph();
+ removeFromGraph();
}
- VertInf *shapeBegin = shape->firstVert();
- VertInf *shapeEnd = shape->lastVert()->lstNext;
+ VertInf *shapeBegin = firstVert();
+ VertInf *shapeEnd = lastVert()->lstNext;
- VertInf *pointsBegin = router->vertices.connsBegin();
+ VertInf *pointsBegin = router()->vertices.connsBegin();
for (VertInf *curr = shapeBegin; curr != shapeEnd; curr = curr->lstNext)
{
bool knownNew = true;
@@ -85,7 +80,7 @@ void shapeVis(ShapeRef *shape)
}
db_printf("\tSecond Half:\n");
- VertInf *pointsEnd = router->vertices.end();
+ VertInf *pointsEnd = router()->vertices.end();
for (VertInf *k = shapeEnd; k != pointsEnd; k = k->lstNext)
{
if (k->id == dummyOrthogID)
@@ -99,18 +94,16 @@ void shapeVis(ShapeRef *shape)
}
-void shapeVisSweep(ShapeRef *shape)
+void Obstacle::computeVisibilitySweep(void)
{
- Router *router = shape->router();
-
- if ( !(router->InvisibilityGrph) )
+ if ( !(router()->InvisibilityGrph) )
{
// Clear shape from graph.
- shape->removeFromGraph();
+ removeFromGraph();
}
- VertInf *startIter = shape->firstVert();
- VertInf *endIter = shape->lastVert()->lstNext;
+ VertInf *startIter = firstVert();
+ VertInf *endIter = lastVert()->lstNext;
for (VertInf *i = startIter; i != endIter; i = i->lstNext)
{
@@ -126,14 +119,14 @@ void vertexVisibility(VertInf *point, VertInf *partner, bool knownNew,
const VertID& pID = point->id;
// Make sure we're only doing ptVis for endpoints.
- COLA_ASSERT(!(pID.isShape));
+ COLA_ASSERT(pID.isConnPt());
if ( !(router->InvisibilityGrph) )
{
point->removeFromGraph();
}
- if (gen_contains && !(pID.isShape))
+ if (gen_contains && pID.isConnPt())
{
router->generateContains(point);
}
@@ -145,7 +138,7 @@ void vertexVisibility(VertInf *point, VertInf *partner, bool knownNew,
else
{
VertInf *shapesEnd = router->vertices.end();
- for (VertInf *k = router->vertices.shapesBegin(); k != shapesEnd;
+ for (VertInf *k = router->vertices.connsBegin(); k != shapesEnd;
k = k->lstNext)
{
if (k->id == dummyOrthogID)
@@ -153,6 +146,13 @@ void vertexVisibility(VertInf *point, VertInf *partner, bool knownNew,
// Don't include orthogonal dummy vertices.
continue;
}
+ else if (k->id.isConnPt() && !k->id.isConnectionPin() &&
+ !(k->id.isConnCheckpoint() && k->id.objID == pID.objID))
+ {
+ // Include connection pins, but not connectors.
+ // Also include checkpoints with same ID as sweep point.
+ continue;
+ }
EdgeInf::checkEdgeVisibility(point, k, knownNew);
}
if (partner)
@@ -167,21 +167,15 @@ void vertexVisibility(VertInf *point, VertInf *partner, bool knownNew,
// SWEEP CODE
//
-static VertInf *centerInf;
-static Point centerPoint;
-static VertID centerID;
-
class PointPair
{
public:
- PointPair(VertInf *inf)
- : vInf(inf)
+ PointPair(const Point& centerPoint, VertInf *inf)
+ : vInf(inf),
+ centerPoint(centerPoint)
{
- double x = vInf->point.x - centerPoint.x;
- double y = vInf->point.y - centerPoint.y;
-
- angle = pos_to_angle(x, y);
+ angle = rotationalAngle(vInf->point - centerPoint);
distance = euclideanDist(centerPoint, vInf->point);
}
bool operator<(const PointPair& rhs) const
@@ -206,60 +200,39 @@ class PointPair
}
return angle < rhs.angle;
}
- static double pos_to_angle(double x, double y)
- {
- if (y == 0)
- {
- return ((x < 0) ? 180 : 0);
- }
- else if (x == 0)
- {
- return ((y < 0) ? 270 : 90);
- }
-
- double ang = atan(y / x);
- ang = (ang * 180) / M_PI;
-
- if (x < 0)
- {
- ang += 180;
- }
- else if (y < 0)
- {
- ang += 360;
- }
- COLA_ASSERT(ang >= 0);
- COLA_ASSERT(ang <= 360);
- return ang;
- }
VertInf *vInf;
double angle;
double distance;
+ Point centerPoint;
};
-
typedef std::set<PointPair > VertSet;
class EdgePair
{
public:
- EdgePair() :
- vInf1(NULL), vInf2(NULL), dist1(0.0), dist2(0.0), angle(0.0),
- angleDist(0.0)
+ EdgePair()
+ : vInf1(NULL),
+ vInf2(NULL),
+ dist1(0.0),
+ dist2(0.0),
+ angle(0.0),
+ angleDist(0.0)
{
// The default constuctor should never be called.
// This is defined to appease the MSVC compiler.
COLA_ASSERT(false);
}
- EdgePair(const PointPair& p1, VertInf *v) :
- vInf1(p1.vInf),
- vInf2(v),
- dist1(p1.distance),
- dist2(euclideanDist(vInf2->point, centerPoint)),
- angle(p1.angle),
- angleDist(p1.distance)
+ EdgePair(const PointPair& p1, VertInf *v)
+ : vInf1(p1.vInf),
+ vInf2(v),
+ dist1(p1.distance),
+ dist2(euclideanDist(vInf2->point, p1.centerPoint)),
+ angle(p1.angle),
+ angleDist(p1.distance),
+ centerPoint(p1.centerPoint)
{
}
bool operator<(const EdgePair& rhs) const
@@ -337,6 +310,7 @@ class EdgePair
double dist2;
double angle;
double angleDist;
+ Point centerPoint;
};
typedef std::list<EdgePair> SweepEdgeList;
@@ -355,7 +329,7 @@ class isBoundingShape
// The following is an overloading of the function call operator.
bool operator () (const PointPair& pp)
{
- if (pp.vInf->id.isShape &&
+ if (!(pp.vInf->id.isConnPt()) &&
(ss.find(pp.vInf->id.objID) != ss.end()))
{
return true;
@@ -404,7 +378,7 @@ static bool sweepVisible(SweepEdgeList& T, const PointPair& point,
return true;
}
- if (! point.vInf->id.isShape )
+ if (point.vInf->id.isConnPt())
{
// It's a connector endpoint, so we have to ignore
// edges of containing shapes for determining visibility.
@@ -454,33 +428,20 @@ static bool sweepVisible(SweepEdgeList& T, const PointPair& point,
if (!visible)
{
*blocker = (*closestIt).vInf1->id.objID;
-#ifdef LINEDEBUG
- Point &e1 = (*closestIt).vInf1->point;
- Point &e2 = (*closestIt).vInf2->point;
-
- if (router->avoid_screen)
- {
- int canx = 151;
- int cany = 55;
- lineRGBA(router->avoid_screen, e1.x + canx, e1.y + cany,
- e2.x + canx, e2.y + cany, 0, 0, 225, 255);
- }
-#endif
}
return visible;
}
-void vertexSweep(VertInf *vert)
+static void vertexSweep(VertInf *vert)
{
Router *router = vert->_router;
VertID& pID = vert->id;
Point& pPoint = vert->point;
- centerInf = vert;
- centerID = pID;
- centerPoint = pPoint;
- Point centerPt = pPoint;
+ VertInf *centerInf = vert;
+ VertID centerID = pID;
+ Point centerPoint = pPoint;
// List of shape (and maybe endpt) vertices, except p
// Sort list, around
@@ -503,7 +464,8 @@ void vertexSweep(VertInf *vert)
continue;
}
- if (!(centerID.isShape) && (ss.find(inf->id.objID) != ss.end()))
+ if (centerID.isConnPt() && (ss.find(inf->id.objID) != ss.end()) &&
+ !inf->id.isConnPt())
{
// Don't include edge points of containing shapes.
unsigned int shapeID = inf->id.objID;
@@ -511,32 +473,39 @@ void vertexSweep(VertInf *vert)
shapeID);
continue;
}
-
- if (inf->id.isShape)
- {
- // Add shape vertex.
- v.insert(inf);
- }
- else
+
+ if (inf->id.isConnPt())
{
// Add connector endpoint.
- if (centerID.isShape)
+ if (centerID.isConnPt())
{
- // Center is a shape vertex, so add all endpoint vertices.
- v.insert(inf);
+ if (inf->id.isConnectionPin())
+ {
+ v.insert(PointPair(centerPoint, inf));
+ }
+ else if (centerID.isConnectionPin())
+ {
+ // Connection pins have visibility to everything.
+ v.insert(PointPair(centerPoint, inf));
+ }
+ else if (inf->id.objID == centerID.objID)
+ {
+ // Center is an endpoint, so only include the other
+ // endpoints or checkpoints from the matching connector.
+ v.insert(PointPair(centerPoint, inf));
+ }
}
else
{
- // Center is an endpoint, so only include the other
- // endpoint from the matching connector.
- VertID partnerID = VertID(centerID.objID, false,
- (centerID.vn == 1) ? 2 : 1);
- if (inf->id == partnerID)
- {
- v.insert(inf);
- }
+ // Center is a shape vertex, so add all endpoint vertices.
+ v.insert(PointPair(centerPoint, inf));
}
}
+ else
+ {
+ // Add shape vertex.
+ v.insert(PointPair(centerPoint, inf));
+ }
}
std::set<unsigned int> onBorderIDs;
@@ -544,14 +513,12 @@ void vertexSweep(VertInf *vert)
SweepEdgeList e;
VertSet::const_iterator vbegin = v.begin();
VertSet::const_iterator vend = v.end();
+ const Point xaxis(DBL_MAX, centerInf->point.y);
for (VertSet::const_iterator t = vbegin; t != vend; ++t)
{
VertInf *k = t->vInf;
COLA_ASSERT(centerInf != k);
- COLA_ASSERT(centerID.isShape || (ss.find(k->id.objID) == ss.end()));
-
- Point xaxis(DBL_MAX, centerInf->point.y);
VertInf *kPrev = k->shPrev;
VertInf *kNext = k->shNext;
@@ -564,8 +531,7 @@ void vertexSweep(VertInf *vert)
EdgePair intPair = EdgePair(*t, kPrev);
e.push_back(intPair);
}
- if ((vecDir(kPrev->point, k->point, centerInf->point) == 0) &&
- inBetween(kPrev->point, k->point, centerInf->point))
+ if (pointOnLine(kPrev->point, k->point, centerInf->point))
{
// Record that centerPoint is on an obstacle line.
onBorderIDs.insert(k->id.objID);
@@ -580,8 +546,7 @@ void vertexSweep(VertInf *vert)
EdgePair intPair = EdgePair(*t, kNext);
e.push_back(intPair);
}
- if ((vecDir(kNext->point, k->point, centerInf->point) == 0) &&
- inBetween(kNext->point, k->point, centerInf->point))
+ if (pointOnLine(kNext->point, k->point, centerInf->point))
{
// Record that centerPoint is on an obstacle line.
onBorderIDs.insert(k->id.objID);
@@ -604,17 +569,6 @@ void vertexSweep(VertInf *vert)
VertID& currID = currInf->id;
Point& currPt = currInf->point;
-#ifdef LINEDEBUG
- Sint16 ppx = (int) centerPt.x;
- Sint16 ppy = (int) centerPt.y;
-
- Sint16 cx = (int) currPt.x;
- Sint16 cy = (int) currPt.y;
-
- int canx = 151;
- int cany = 55;
-#endif
-
const double& currDist = (*t).distance;
EdgeInf *edge = EdgeInf::existingEdge(centerInf, currInf);
@@ -634,13 +588,13 @@ void vertexSweep(VertInf *vert)
bool currVisible = sweepVisible(e, *t, onBorderIDs, &blocker);
bool cone1 = true, cone2 = true;
- if (centerID.isShape)
+ if (!(centerID.isConnPt()))
{
cone1 = inValidRegion(router->IgnoreRegions,
centerInf->shPrev->point, centerPoint,
centerInf->shNext->point, currInf->point);
}
- if (currInf->id.isShape)
+ if (!(currInf->id.isConnPt()))
{
cone2 = inValidRegion(router->IgnoreRegions,
currInf->shPrev->point, currInf->point,
@@ -660,14 +614,6 @@ void vertexSweep(VertInf *vert)
{
if (currVisible)
{
-#ifdef LINEDEBUG
- if (router->avoid_screen)
- {
- lineRGBA(router->avoid_screen, ppx + canx, ppy + cany,
- cx + canx, cy + cany, 255, 0, 0, 75);
- SDL_Delay(1000);
- }
-#endif
db_printf("\tSetting visibility edge... \n\t\t");
edge->setDist(currDist);
edge->db_print();
@@ -686,14 +632,14 @@ void vertexSweep(VertInf *vert)
edge = NULL;
}
- if (currID.isShape)
+ if (!(currID.isConnPt()))
{
// This is a shape edge
if (currInf->shPrev != centerInf)
{
Point& prevPt = currInf->shPrev->point;
- int prevDir = vecDir(centerPt, currPt, prevPt);
+ int prevDir = vecDir(centerPoint, currPt, prevPt);
EdgePair prevPair = EdgePair(*t, currInf->shPrev);
if (prevDir == BEHIND)
@@ -709,7 +655,7 @@ void vertexSweep(VertInf *vert)
if (currInf->shNext != centerInf)
{
Point& nextPt = currInf->shNext->point;
- int nextDir = vecDir(centerPt, currPt, nextPt);
+ int nextDir = vecDir(centerPoint, currPt, nextPt);
EdgePair nextPair = EdgePair(*t, currInf->shNext);
if (nextDir == BEHIND)
@@ -722,12 +668,6 @@ void vertexSweep(VertInf *vert)
}
}
}
-#ifdef LINEDEBUG
- if (router->avoid_screen)
- {
- SDL_Flip(router->avoid_screen);
- }
-#endif
}
}