示例#1
0
bool QgsTriangle::moveVertex( QgsVertexId vId, const QgsPoint &newPos )
{
  if ( !mExteriorRing || vId.part != 0 || vId.ring != 0 || vId.vertex < 0 || vId.vertex > 4 )
  {
    return false;
  }

  if ( vId.vertex == 4 )
  {
    vId.vertex = 0;
  }

  QgsPoint p1( vId.vertex == 0 ? newPos : vertexAt( 0 ) );
  QgsPoint p2( vId.vertex == 1 ? newPos : vertexAt( 1 ) );
  QgsPoint p3( vId.vertex == 2 ? newPos : vertexAt( 2 ) );

  if ( !validateGeom( p1, p2, p3 ) )
  {
    return false;
  }

  int n = mExteriorRing->numPoints();
  bool success = mExteriorRing->moveVertex( vId, newPos );
  if ( success )
  {
    // If first or last vertex is moved, also move the last/first vertex
    if ( vId.vertex == 0 )
      mExteriorRing->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
    clearCache();
  }
  return success;
}
示例#2
0
QVector<QgsLineString> QgsTriangle::altitudes() const
{
  QVector<QgsLineString> alt;
  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 0 ), vertexAt( 2 ), vertexAt( 1 ) ) );
  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 1 ), vertexAt( 0 ), vertexAt( 2 ) ) );
  alt.append( QgsGeometryUtils::perpendicularSegment( vertexAt( 2 ), vertexAt( 0 ), vertexAt( 1 ) ) );

  return alt;
}
示例#3
0
ExclusionPolygon::ExclusionPolygon(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule)
    : ExclusionShape()
    , m_vertices(vertices)
    , m_fillRule(fillRule)
{
    unsigned nVertices = numberOfVertices();
    m_edges.resize(nVertices);
    m_empty = nVertices < 3;

    if (nVertices)
        m_boundingBox.setLocation(vertexAt(0));

    if (m_empty)
        return;

    unsigned minVertexIndex = 0;
    for (unsigned i = 1; i < nVertices; ++i) {
        const FloatPoint& vertex = vertexAt(i);
        if (vertex.y() < vertexAt(minVertexIndex).y() || (vertex.y() == vertexAt(minVertexIndex).y() && vertex.x() < vertexAt(minVertexIndex).x()))
            minVertexIndex = i;
    }
    FloatPoint nextVertex = vertexAt((minVertexIndex + 1) % nVertices);
    FloatPoint prevVertex = vertexAt((minVertexIndex + nVertices - 1) % nVertices);
    bool clockwise = determinant(vertexAt(minVertexIndex) - prevVertex, nextVertex - prevVertex) > 0;

    unsigned edgeIndex = 0;
    unsigned vertexIndex1 = 0;
    do {
        m_boundingBox.extend(vertexAt(vertexIndex1));
        unsigned vertexIndex2 = findNextEdgeVertexIndex(vertexIndex1, clockwise);
        m_edges[edgeIndex].polygon = this;
        m_edges[edgeIndex].vertexIndex1 = vertexIndex1;
        m_edges[edgeIndex].vertexIndex2 = vertexIndex2;
        m_edges[edgeIndex].edgeIndex = edgeIndex;
        edgeIndex++;
        vertexIndex1 = vertexIndex2;
    } while (vertexIndex1);

    if (edgeIndex > 3) {
        const ExclusionPolygonEdge& firstEdge = m_edges[0];
        const ExclusionPolygonEdge& lastEdge = m_edges[edgeIndex - 1];
        if (areCollinearPoints(lastEdge.vertex1(), lastEdge.vertex2(), firstEdge.vertex2())) {
            m_edges[0].vertexIndex1 = lastEdge.vertexIndex1;
            edgeIndex--;
        }
    }

    m_edges.resize(edgeIndex);
    m_empty = m_edges.size() < 3;

    if (m_empty)
        return;

    for (unsigned i = 0; i < m_edges.size(); i++) {
        ExclusionPolygonEdge* edge = &m_edges[i];
        m_edgeTree.add(EdgeInterval(edge->minY(), edge->maxY(), edge));
    }
}
示例#4
0
bool QgsTriangle::operator==( const QgsTriangle &other ) const
{
  if ( isEmpty() && other.isEmpty() )
  {
    return true;
  }
  else if ( isEmpty() || other.isEmpty() )
  {
    return false;
  }

  return ( ( vertexAt( 0 ) == other.vertexAt( 0 ) ) &&
           ( vertexAt( 1 ) == other.vertexAt( 1 ) ) &&
           ( vertexAt( 2 ) == other.vertexAt( 2 ) )
         );
}
示例#5
0
unsigned ExclusionPolygon::findNextEdgeVertexIndex(unsigned vertexIndex1, bool clockwise) const
{
    unsigned nVertices = numberOfVertices();
    unsigned vertexIndex2 = nextVertexIndex(vertexIndex1, nVertices, clockwise);

    while (vertexIndex2 && areCoincidentPoints(vertexAt(vertexIndex1), vertexAt(vertexIndex2)))
        vertexIndex2 = nextVertexIndex(vertexIndex2, nVertices, clockwise);

    while (vertexIndex2) {
        unsigned vertexIndex3 = nextVertexIndex(vertexIndex2, nVertices, clockwise);
        if (!areCollinearPoints(vertexAt(vertexIndex1), vertexAt(vertexIndex2), vertexAt(vertexIndex3)))
            break;
        vertexIndex2 = vertexIndex3;
    }

    return vertexIndex2;
}
示例#6
0
QgsTriangle QgsTriangle::medial() const
{
  QgsPoint p1, p2, p3;
  p1 = QgsGeometryUtils::midpoint( vertexAt( 0 ), vertexAt( 1 ) );
  p2 = QgsGeometryUtils::midpoint( vertexAt( 1 ), vertexAt( 2 ) );
  p3 = QgsGeometryUtils::midpoint( vertexAt( 2 ), vertexAt( 0 ) );
  return QgsTriangle( p1, p2, p3 );
}
示例#7
0
QVector<double> QgsTriangle::lengths() const
{
  QVector<double> lengths;
  lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) );
  lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) );
  lengths.append( vertexAt( 2 ).distance( vertexAt( 0 ) ) );

  return lengths;
}
示例#8
0
QgsPoint QgsTriangle::inscribedCenter() const
{

  QVector<double> l = lengths();
  double x = ( l.at( 0 ) * vertexAt( 2 ).x() +
               l.at( 1 ) * vertexAt( 0 ).x() +
               l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter();
  double y = ( l.at( 0 ) * vertexAt( 2 ).y() +
               l.at( 1 ) * vertexAt( 0 ).y() +
               l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter();

  return QgsPoint( x, y );
}
示例#9
0
QVector<QgsLineString> QgsTriangle::medians() const
{
  QVector<QgsLineString> med;

  QgsLineString med1;
  QgsLineString med2;
  QgsLineString med3;
  med1.setPoints( QgsPointSequence() << vertexAt( 0 ) << QgsGeometryUtils::midpoint( vertexAt( 1 ), vertexAt( 2 ) ) );
  med2.setPoints( QgsPointSequence() << vertexAt( 1 ) << QgsGeometryUtils::midpoint( vertexAt( 0 ), vertexAt( 2 ) ) );
  med3.setPoints( QgsPointSequence() << vertexAt( 2 ) << QgsGeometryUtils::midpoint( vertexAt( 0 ), vertexAt( 1 ) ) );
  med.append( med1 );
  med.append( med2 );
  med.append( med3 );

  return med;
}
示例#10
0
QgsPointV2 QgsAbstractGeometryV2::centroid() const
{
    // http://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
    // Pick the first ring of first part for the moment

    int n = vertexCount( 0, 0 );
    if ( n == 1 )
    {
        return vertexAt( QgsVertexId( 0, 0, 0 ) );
    }

    double A = 0.;
    double Cx = 0.;
    double Cy = 0.;
    int i = 0, j = 1;
    if ( vertexAt( QgsVertexId( 0, 0, 0 ) ) != vertexAt( QgsVertexId( 0, 0, n - 1 ) ) )
    {
        i = n - 1;
        j = 0;
    }
    for ( ; j < n; i = j++ )
    {
        QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) );
        QgsPointV2 vj = vertexAt( QgsVertexId( 0, 0, j ) );
        double d = vi.x() * vj.y() - vj.x() * vi.y();
        A += d;
        Cx += ( vi.x() + vj.x() ) * d;
        Cy += ( vi.y() + vj.y() ) * d;
    }

    if ( A < 1E-12 )
    {
        Cx = Cy = 0.;
        for ( int i = 0; i < n - 1; ++i )
        {
            QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) );
            Cx += vi.x();
            Cy += vi.y();
        }
        return QgsPointV2( Cx / ( n - 1 ), Cy / ( n - 1 ) );
    }
    else
    {
        return QgsPointV2( Cx / ( 3. * A ), Cy / ( 3. * A ) );
    }
}
示例#11
0
QVector<double> QgsTriangle::angles() const
{
  QVector<double> angles;
  double ax, ay, bx, by, cx, cy;

  ax = vertexAt( 0 ).x();
  ay = vertexAt( 0 ).y();
  bx = vertexAt( 1 ).x();
  by = vertexAt( 1 ).y();
  cx = vertexAt( 2 ).x();
  cy = vertexAt( 2 ).y();

  double a1 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( cx, cy, ax, ay, bx, by ), M_PI );
  double a2 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( ax, ay, bx, by, cx, cy ), M_PI );
  double a3 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( bx, by, cx, cy, ax, ay ), M_PI );

  angles.append( ( a1 > M_PI_2 ? a1 - M_PI_2 : a1 ) );
  angles.append( ( a2 > M_PI_2 ? a2 - M_PI_2 : a2 ) );
  angles.append( ( a3 > M_PI_2 ? a3 - M_PI_2 : a3 ) );

  return angles;
}
示例#12
0
double QgsTriangle::circumscribedRadius() const
{
  double r, x, y;
  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
  return r;
}
示例#13
0
QVector<QgsLineString> QgsTriangle::bisectors( double lengthTolerance ) const
{
  QVector<QgsLineString> bis;
  QgsLineString bis1;
  QgsLineString bis2;
  QgsLineString bis3;
  QgsPoint incenter = inscribedCenter();
  QgsPoint out;

  QgsGeometryUtils::segmentIntersection( vertexAt( 0 ), incenter, vertexAt( 1 ), vertexAt( 2 ), out, lengthTolerance );
  bis1.setPoints( QgsPointSequence() <<  vertexAt( 0 ) << out );

  QgsGeometryUtils::segmentIntersection( vertexAt( 1 ), incenter, vertexAt( 0 ), vertexAt( 2 ), out, lengthTolerance );
  bis2.setPoints( QgsPointSequence() <<  vertexAt( 1 ) << out );

  QgsGeometryUtils::segmentIntersection( vertexAt( 2 ), incenter, vertexAt( 0 ), vertexAt( 1 ), out, lengthTolerance );
  bis3.setPoints( QgsPointSequence() <<  vertexAt( 2 ) << out );

  bis.append( bis1 );
  bis.append( bis2 );
  bis.append( bis3 );

  return bis;
}
示例#14
0
QgsPointV2 QgsTriangle::circumscribedCenter() const
{
  double r, x, y;
  QgsGeometryUtils::circleCenterRadius( vertexAt( 0 ), vertexAt( 1 ), vertexAt( 2 ), r, x, y );
  return QgsPointV2( x, y );
}