/*
* 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