/* * 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(int x, int y) { Point *prev = NULL, *cur; int left = 0, right = 0, maxy, miny; for (std::vector::iterator it = vertices.begin() ; it != vertices.end(); it++) { if (!prev) { prev = vertices.back(); } cur = *it; miny = std::min(cur->y(), prev->y()); maxy = std::max(cur->y(), prev->y()); if (y > miny && y < maxy) { if (prev->x() == cur->x()) { if (x < cur->x()) right++; else left++; } else { double slope = (cur->y() - prev->y()) / (cur->x() - prev->x()); double offset = cur->y() - slope * cur->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 (std::vector::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 (std::vector::const_iterator it = vertices.begin() ; it != vertices.end(); ++it) { polygon.append((*it)->toPoint()); } 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 QList& 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( new Point(points[k].x(), points[k].y()) ); _vertices2d[x][y] = k; k++; } } QPolygonF Mesh::toPolygon() const { QPolygonF polygon; polygon.append(getVertex2d(0, 0)->toPoint()); polygon.append(getVertex2d(nColumns()-1, 0)->toPoint()); polygon.append(getVertex2d(nColumns()-1, nRows()-1)->toPoint()); polygon.append(getVertex2d(0, nRows()-1)->toPoint()); return polygon; } void Mesh::resizeVertices2d(std::vector< std::vector >& vertices2d, int nColumns, int nRows) { vertices2d.resize(nColumns); for (int i=0; i > newVertices2d; resizeVertices2d(newVertices2d, nColumns()+1, nRows()); // Left displacement of points already there. float leftMoveProp = 1.0f/(nColumns()-1) - 1.0f/nColumns(); // Add a point at each row. int k = nVertices(); for (int y=0; y > newVertices2d; resizeVertices2d(newVertices2d, nColumns(), nRows()+1); // Top displacement of points already there. float topMoveProp = 1.0f/(nRows()-1) - 1.0f/nRows(); // Add a point at each row. int k = nVertices(); for (int x=0; x= 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 { std::vector quads; for (int i=0; i > Mesh::getQuads2d() const { std::vector< std::vector > quads2d; for (int i=0; i column; for (int j=0; j newVertices(vertices.size()); int k = 0; for (int x=0; x