src/grid.cpp

Wed, 08 Mar 2017 22:48:43 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 08 Mar 2017 22:48:43 +0200
changeset 1206
743dc95e0be6
parent 1199
613a981223a6
permissions
-rw-r--r--

Better encapsulated the BaseConfiguration class.

/*
 *  LDForge: LDraw parts authoring CAD
 *  Copyright (C) 2013 - 2017 Teemu Piippo
 *
 *  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 <http://www.gnu.org/licenses/>.
 */

#include "grid.h"
#include "linetypes/modelobject.h"

qreal Grid::coordinateSnap()
{
	switch (configuration().grid())
	{
	default:
	case Grid::Coarse: return configuration().gridCoarseCoordinateSnap();
	case Grid::Medium: return configuration().gridMediumCoordinateSnap();
	case Grid::Fine: return configuration().gridFineCoordinateSnap();
	}
}


qreal Grid::angleSnap()
{
	switch (configuration().grid())
	{
	default:
	case Grid::Coarse: return configuration().gridCoarseAngleSnap();
	case Grid::Medium: return configuration().gridMediumAngleSnap();
	case Grid::Fine: return configuration().gridFineAngleSnap();
	}
}


qreal Grid::angleAsRadians()
{
	return (pi * angleSnap()) / 180;
}


int Grid::bezierCurveSegments()
{
	switch (configuration().grid())
	{
	default:
	case Grid::Coarse: return configuration().gridCoarseBezierCurveSegments();
	case Grid::Medium: return configuration().gridMediumBezierCurveSegments();
	case Grid::Fine: return configuration().gridFineBezierCurveSegments();
	}
}


QPointF Grid::snap(QPointF point)
{
	switch (type())
	{
	default:
	case Cartesian:
		{
			// For each co-ordinate, extract the amount of grid steps the value is away from zero, round that to remove the remainder,
			// and multiply back by the the grid size.
			double size = coordinateSnap();
			return {round(point.x() / size) * size, round(point.y() / size) * size};
		}

	case Polar:
		{
			qreal radius = hypot(point.x() - pole().x(), point.y() - -pole().y());
			qreal azimuth = atan2(point.y() - -pole().y(), point.x() - pole().x());
			double size = coordinateSnap();
			double angleStep = 2 * pi / polarDivisions();
			radius = round(radius / size) * size;
			azimuth = round(azimuth / angleStep) * angleStep;
			return {pole().x() + cos(azimuth) * radius, -pole().y() + sin(azimuth) * radius};
		}
	}
}

/*
 * Returns the pole of the grid, in ideal X/Y co-ordinates. Z is left up for the caller to decide.
 */
QPointF Grid::pole()
{
	return {0, 0};
}

/*
 * Returns the amount of divisions (slices) to be used in the polar grid.
 */
int Grid::polarDivisions()
{
	switch (configuration().grid())
	{
	default:
	case Coarse:
	case Medium:
		return LowResolution;

	case Fine:
		return HighResolution;
	}
}

/*
 * Returns whether to use a cartesian or polar grid.
 */
Grid::Type Grid::type()
{
	return configuration().polarGrid() ? Polar : Cartesian;
}

mercurial