/* * Shape.cpp * * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com * * 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 3 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, see . */ #include "Shape.h" bool Shape::includesPoint(qreal x, qreal y) { return toPolygon().containsPoint(QPointF(x, y), Qt::OddEvenFill); // QVector::iterator prev; // int left = 0, right = 0, maxy, miny; // for (QVector::iterator it = vertices.begin() ; // it != vertices.end(); it++) // { // if (!prev) { // prev = vertices.back(); // } // miny = qMin(it->y(), prev->y()); // maxy = qMax(it->y(), prev->y()); // // if (y > miny && y < maxy) { // if (prev->x() == it->x()) // { // if (x < it->x()) // right++; // else left++; // } // else // { // double slope = (it->y() - prev->y()) / (it->x() - prev->x()); // double offset = it->y() - slope * it->x(); // int xintersect = int((y - offset ) / slope); // if (x < xintersect) // right++; // else left++; // } // } // prev = *it; // } // if (right % 2 && left % 2) // return true; // return false; } void Shape::translate(int x, int y) { for (QVector::iterator it = vertices.begin() ; it != vertices.end(); ++it) { it->setX(it->x() + x); it->setY(it->y() + y); } } QPolygonF Shape::toPolygon() const { QPolygonF polygon; for (QVector::const_iterator it = vertices.begin() ; it != vertices.end(); ++it) { polygon.append(*it); } return polygon; } Mesh::Mesh(QPointF p1, QPointF p2, QPointF p3, QPointF p4, int nColumns, int nRows) : Quad(p1, p2, p3, p4), _nColumns(0), _nRows(0) { Q_ASSERT(nColumns >= 2 && nRows >= 2); init(nColumns, nRows); } Mesh::Mesh(const QVector& points, int nColumns, int nRows) : Quad(), _nColumns(nColumns), _nRows(nRows) { Q_ASSERT(nColumns >= 2 && nRows >= 2); Q_ASSERT(points.size() == nColumns * nRows); // Resize the vertices2d vector to appropriate dimensions. resizeVertices2d(_vertices2d, _nColumns, _nRows); // Just build vertices2d in the standard order. int k = 0; for (int x=0; x<_nColumns; x++) for (int y=0; y<_nRows; y++) { vertices.push_back( points[k] ); _vertices2d[x][y] = k; k++; } } QPolygonF Mesh::toPolygon() const { QPolygonF polygon; polygon.append(getVertex2d(0, 0)); polygon.append(getVertex2d(nColumns()-1, 0)); polygon.append(getVertex2d(nColumns()-1, nRows()-1)); polygon.append(getVertex2d(0, nRows()-1)); return polygon; } void Mesh::resizeVertices2d(IndexVector2d& vertices2d, int nColumns, int nRows) { vertices2d.resize(nColumns); for (int i=0; i= nColumns() && nRows_ >= nRows()); while (nColumns_ != nColumns()) addColumn(); while (nRows_ != nRows()) addRow(); } // void removeColumn(int columnId) // { // // Cannot remove first and last columns // Q_ASSERT(columnId >= 1 && columnId < nColumns()-1); // // std::vector< std::vector > newVertices2d; // resizeVertices2d(newVertices2d, nColumns()-1, nRows()); // // // Right displacement of points already there. // float rightMoveProp = 1.0f/(nColumns()-2) - 1.0f/(nColumns()-1); // // // Remove a point at each row. // int k = nVertices(); // for (int y=0; y Mesh::getQuads() const { QVector quads; for (int i=0; i > Mesh::getQuads2d() const { QVector< QVector > quads2d; for (int i=0; i column; for (int j=0; j newVertices(vertices.size()); int k = 0; for (int x=0; x