Brief description of class still missing. More...
#include <Cluster.h>
Public Types | |
| enum | Type { None, Quad, StrongQuad, WeakQuad } |
Public Member Functions | |
| bool | add (const Cluster &quad, const Anchoring *anchoring) |
| Anchoring * | anchoring (const Cluster &quad) const |
| Cluster () | |
| Cluster (const Cluster &o) | |
| bool | contains (Node *node) const |
| Point2D | coordinates (Node *node) const |
| int | count () const |
| double | distance (Node *node1, Node *node2) const |
| QMap< Node *, Point2D > ::const_iterator | end () const |
| QMap< Node *, Point2D > ::const_iterator | find (Node *node) const |
| bool | isRobustQuad (double stddev) const |
| QString | name () const |
| QList< Node * > | nodes () const |
| bool | operator< (const Cluster &o) const |
| bool | operator== (const Cluster &o) const |
| bool | setCoordinateSystem (Node *origin, Node *north, Node *eastward) |
| void | setOrigin (Node *node) |
| bool | setQuad (QList< Node * > nodes) |
| Type | type () const |
| ~Cluster () | |
Static Public Member Functions | |
| static bool | equal (const Cluster *c1, const Cluster *c2) |
| static bool | lessThan (const Cluster *c1, const Cluster *c2) |
Brief description of class still missing.
Full description of class still missing
{None, Quad, StrongQuad, WeakQuad};
| TapePositioningSystem::Cluster::Cluster | ( | const Cluster & | o | ) |
| TapePositioningSystem::Cluster::~Cluster | ( | ) | [inline] |
{}
| bool TapePositioningSystem::Cluster::add | ( | const Cluster & | quad, |
| const Anchoring * | anchoring | ||
| ) |
Adds a new quad to this cluster with a valid anchoring.
References TapePositioningSystem::Anchoring::a(), TapePositioningSystem::Anchoring::b(), TapePositioningSystem::Anchoring::c(), distance(), QGpCoreTools::endl(), QGpCoreTools::Circle::intersect(), TapePositioningSystem::Anchoring::n(), TapePositioningSystem::Node::name(), QGpCoreTools::tr(), and TRACE.
{
TRACE;
// Localization
Circle c1(_nodes[anchoring->a()], quad.distance(anchoring->n(), anchoring->a()));
Circle c2(_nodes[anchoring->b()], quad.distance(anchoring->n(), anchoring->b()));
Circle c3(_nodes[anchoring->c()], quad.distance(anchoring->n(), anchoring->c()));
bool ok;
int n=0;
Point2D p, solution;
p=c1.intersect(c2, ok, c3);
if(ok) {solution+=p; n++;}
p=c2.intersect(c3, ok, c1);
if(ok) {solution+=p; n++;}
p=c3.intersect(c1, ok, c2);
if(ok) {solution+=p; n++;}
if(n!=0) {
solution/=n;
} else {
App::stream() << tr("No solution when localizing node %1 (unconsistent distances)").arg(anchoring->n()->name()) << endl;
return false;
}
_nodes.insert(anchoring->n(), solution);
return true;
}
| Anchoring * TapePositioningSystem::Cluster::anchoring | ( | const Cluster & | quad | ) | const |
Check for anchors between this cluster and quad.
References TapePositioningSystem::Anchoring::addAnchor(), count(), QGpCoreTools::endl(), TapePositioningSystem::Anchoring::isValidAnchor(), TapePositioningSystem::Anchoring::n(), TapePositioningSystem::Anchoring::setNewNode(), QGpCoreTools::tr(), and TRACE.
{
TRACE;
// Preliminary checks
if(quad.count()!=4) {
App::stream() << tr("A quad must have exactly 4 nodes") << endl;
return false;
}
// Identification of the new node
Anchoring * res=new Anchoring;
for(QMap<Node *, Point2D>::const_iterator it=quad._nodes.begin(); it!=quad._nodes.end(); it++) {
Node * quadNode=it.key();
if(_nodes.contains(quadNode)) {
res->addAnchor(quadNode);
} else if(res->n()) {
// More than 1 node does not belong to this cluster hence less than 3 in common
delete res;
return 0;
} else {
res->setNewNode(quadNode);
}
}
if(!res->isValidAnchor()) {
delete res;
return 0;
} else {
return res;
}
}
| bool TapePositioningSystem::Cluster::contains | ( | Node * | node | ) | const [inline] |
{return _nodes.contains(node);}
| Point2D TapePositioningSystem::Cluster::coordinates | ( | Node * | node | ) | const [inline] |
Referenced by TapePositioningSystem::Triangulator::printClusters().
{return _nodes[node];}
| int TapePositioningSystem::Cluster::count | ( | ) | const [inline] |
Referenced by anchoring(), operator<(), and operator==().
{return _nodes.count();}
| double TapePositioningSystem::Cluster::distance | ( | Node * | node1, |
| Node * | node2 | ||
| ) | const |
| QMap<Node *, Point2D>::const_iterator TapePositioningSystem::Cluster::end | ( | ) | const [inline] |
Referenced by TapePositioningSystem::Triangulator::setPriorCoordinates(), and TapePositioningSystem::Triangulator::solutions().
{return _nodes.end();}
| static bool TapePositioningSystem::Cluster::equal | ( | const Cluster * | c1, |
| const Cluster * | c2 | ||
| ) | [inline, static] |
Referenced by TapePositioningSystem::Triangulator::aggregate().
{return *c1==*c2;}
| QMap<Node *, Point2D>::const_iterator TapePositioningSystem::Cluster::find | ( | Node * | node | ) | const [inline] |
Referenced by TapePositioningSystem::Triangulator::setPriorCoordinates(), and TapePositioningSystem::Triangulator::solutions().
{return _nodes.find(node);}
| bool TapePositioningSystem::Cluster::isRobustQuad | ( | double | stddev | ) | const |
For quads only (node count is 4). Returns true if b*sin(theta)^2>3*stddev where b is the length of the shortest side and theta the smallest angle.
Cluster must fist be calculated with calculateQuad()
References TRACE.
{
TRACE;
if(_nodes.count()!=4) {
return false;
}
QList<Point2D> points=_nodes.values();
return isRobustTriangle(points.at(0), points.at(1), points.at(2), stddev) &&
isRobustTriangle(points.at(1), points.at(2), points.at(3), stddev) &&
isRobustTriangle(points.at(0), points.at(2), points.at(3), stddev) &&
isRobustTriangle(points.at(0), points.at(1), points.at(3), stddev);
}
| static bool TapePositioningSystem::Cluster::lessThan | ( | const Cluster * | c1, |
| const Cluster * | c2 | ||
| ) | [inline, static] |
Referenced by TapePositioningSystem::Triangulator::aggregate().
{return *c1<*c2;}
| QString TapePositioningSystem::Cluster::name | ( | ) | const |
References TRACE.
Referenced by TapePositioningSystem::Triangulator::printClusters().
{
TRACE;
QMap<Node *, Point2D>::const_iterator it=_nodes.begin();
QString n;
if(it!=_nodes.end()) {
n=it.key()->name();
} else {
return "empty";
}
for(it++; it!=_nodes.end(); it++) {
n+=","+it.key()->name();
}
return n;
}
| QList<Node *> TapePositioningSystem::Cluster::nodes | ( | ) | const [inline] |
Referenced by TapePositioningSystem::Triangulator::printClusters().
{return _nodes.keys();}
| bool TapePositioningSystem::Cluster::operator< | ( | const Cluster & | o | ) | const |
References count(), and TRACE.
{
TRACE;
if(count()==o.count()) {
QMap<Node *, Point2D>::const_iterator it1=_nodes.begin();
QMap<Node *, Point2D>::const_iterator it2=o._nodes.begin();
while(it1!=_nodes.end() &&
it1.key()==it2.key()){
it1++;
it2++;
}
if(it1!=_nodes.end()) {
return it1.key()<it2.key();
} else {
return false;
}
} else {
return count()<o.count();
}
}
| bool TapePositioningSystem::Cluster::operator== | ( | const Cluster & | o | ) | const |
| bool TapePositioningSystem::Cluster::setCoordinateSystem | ( | Node * | origin, |
| Node * | north, | ||
| Node * | eastward | ||
| ) |
References QGpCoreTools::endl(), TapePositioningSystem::Node::name(), QGpCoreTools::Matrix2x2::rotation(), QGpCoreTools::Angle::setRadianAzimuth(), QGpCoreTools::tr(), TRACE, and QGpCoreTools::Point2D::translate().
Referenced by TapePositioningSystem::Triangulator::setCoordinates().
{
TRACE;
if(!origin || !north || !eastward) {
return false;
}
QMap<Node *, Point2D>::iterator itlu;
// Translation
itlu=_nodes.find(origin);
if(itlu==_nodes.end()) {
App::stream() << tr("Node %1 does not belong to this cluster").arg(origin->name()) << endl;
return false;
}
Point2D co=Point2D()-itlu.value();
for(QMap<Node *, Point2D>::iterator it=_nodes.begin(); it!=_nodes.end(); it++) {
it.value().translate(co);
}
// Rotation
itlu=_nodes.find(north);
if(itlu==_nodes.end()) {
App::stream() << tr("Node %1 does not belong to this cluster").arg(north->name()) << endl;
return false;
}
Matrix2x2 rotMatrix;
Angle angle;
angle.setRadianAzimuth(Point2D().azimuthTo(itlu.value()));
rotMatrix.rotation(angle);
for(QMap<Node *, Point2D>::iterator it=_nodes.begin(); it!=_nodes.end(); it++) {
it.value()=rotMatrix*it.value();
}
// Flip
itlu=_nodes.find(eastward);
if(itlu==_nodes.end()) {
App::stream() << tr("Node %1 does not belong to this cluster").arg(eastward->name()) << endl;
return false;
}
if(itlu.value().x()<0.0) {
for(QMap<Node *, Point2D>::iterator it=_nodes.begin(); it!=_nodes.end(); it++) {
it.value().setX(-it.value().x());
}
}
return true;
}
| void TapePositioningSystem::Cluster::setOrigin | ( | Node * | node | ) |
| bool TapePositioningSystem::Cluster::setQuad | ( | QList< Node * > | nodes | ) |
References QGpCoreTools::endl(), Quad, StrongQuad, QGpCoreTools::tr(), TRACE, and WeakQuad.
{
TRACE;
if(nodes.count()!=3) {
App::stream() << tr("A quad is made of 4 nodes") << endl;
return false;
}
_type=Quad;
QList<Node *> fullLinkNodes;
if(nodes.at(0)->isConnected(nodes.at(1)) &&
nodes.at(0)->isConnected(nodes.at(2))) {
fullLinkNodes.append(nodes.at(0));
}
if(nodes.at(1)->isConnected(nodes.at(0)) &&
nodes.at(1)->isConnected(nodes.at(2))) {
fullLinkNodes.append(nodes.at(1));
}
if(nodes.at(2)->isConnected(nodes.at(0)) &&
nodes.at(2)->isConnected(nodes.at(1))) {
fullLinkNodes.append(nodes.at(2));
}
switch(fullLinkNodes.count()) {
case 3:
_type=StrongQuad;
if(!calculateStrongQuad(nodes)) {
return false;
}
break;
case 1: {
Node * a=fullLinkNodes.first();
nodes.removeAll(a);
_type=WeakQuad;
if(!calculateWeakQuad(a, nodes)) {
return false;
}
}
break;
default:
return false;
}
return true;
}
| Type TapePositioningSystem::Cluster::type | ( | ) | const [inline] |
{return _type;}