All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Types | Public Member Functions | Static Public Member Functions
TapePositioningSystem::Cluster Class Reference

Brief description of class still missing. More...

#include <Cluster.h>

List of all members.

Public Types

enum  Type { None, Quad, StrongQuad, WeakQuad }

Public Member Functions

bool add (const Cluster &quad, const Anchoring *anchoring)
Anchoringanchoring (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)

Detailed Description

Brief description of class still missing.

Full description of class still missing


Member Enumeration Documentation

Enumerator:
None 
Quad 
StrongQuad 
WeakQuad 

Constructor & Destructor Documentation

References None, and TRACE.

  {
    TRACE;
    _type=None;
  }

References TRACE.

  {
    TRACE;
    _type=o._type;
    _origin=o._origin;
    _nodes=o._nodes;
  }
{}

Member Function Documentation

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;
  }

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);}

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

References TRACE.

Referenced by add().

  {
    TRACE;

    return _nodes[node1].distanceTo(_nodes[node2]);
  }
QMap<Node *, Point2D>::const_iterator TapePositioningSystem::Cluster::end ( ) const [inline]
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]
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;}

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

References count(), and TRACE.

  {
    TRACE;
    if(count()!=o.count()) {
      return false;
    }
    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++;
    }
    return it1==_nodes.end();
  }
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;
  }

References TRACE.

  {
    TRACE;
    _nodes.clear();
    _nodes.insert(node, Point2D());
    _origin=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;
  }
{return _type;}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines