src/geometry.h

Mon, 06 Jun 2022 22:01:22 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 06 Jun 2022 22:01:22 +0300
changeset 200
ca23936b455b
parent 187
30204975694a
child 201
5d201ee4a9c3
permissions
-rw-r--r--

Giant refactor

#pragma once
#include <QPolygonF>
#include "basics.h"

namespace geom
{
	struct Plane
	{
		glm::vec3 normal;
		glm::vec3 anchor;
	};

	template<int N, typename T = float, glm::qualifier Q = glm::defaultp>
	struct Line
	{
		glm::vec<N, T, Q> direction;
		glm::vec<N, T, Q> anchor;
	};

	template<int N, typename T = float, glm::qualifier Q = glm::defaultp>
	struct Ray
	{
		glm::vec<N, T, Q> direction;
		glm::vec<N, T, Q> anchor;
	};

	inline const glm::vec3 origin = {0, 0, 0};
	inline const Plane XY = {{0, 0, 1}, origin};
	inline const Plane XZ = {{0, 1, 0}, origin};
	inline const Plane YZ = {{1, 0, 0}, origin};

	struct LineSegment
	{
		glm::vec3 p1, p2;
	};
	struct Triangle
	{
		glm::vec3 p1, p2, p3;
	};
	struct Quadrilateral
	{
		glm::vec3 p1, p2, p3, p4;
	};
	struct ConditionalEdge
	{
		glm::vec3 p1, p2;
		glm::vec3 c1, c2;
	};
	struct LineSegment2D
	{
		glm::vec2 p1, p2;
	};

	// get polygon type from amount of points
	template<int N>
	struct PolygonType {};
	template<>
	struct PolygonType<2> { using type = LineSegment; };
	template<>
	struct PolygonType<3> { using type = Triangle; };
	template<>
	struct PolygonType<4> { using type = Quadrilateral; };
	template<int N>
	using Polygon = typename PolygonType<N>::type;

	/**
	 * @brief Computes a line from two points
	 * @param point_1
	 * @param point_2
	 * @return line
	 */
	template<int N, typename T, glm::qualifier Q>
	Line<N, T, Q> lineFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2)
	{
		return {point_2 - point_1, point_1};
	}

	template<int N, typename T, glm::qualifier Q>
	Ray<N, T, Q> rayFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2)
	{
		return {point_2 - point_1, point_1};
	}

	template<int N, typename T, glm::qualifier Q>
	Line<N, T, Q> rayToLine(const Ray<N, T, Q>& ray)
	{
		return {ray.direction, ray.anchor};
	}

	enum class RectangleSide
	{
		Top,
		Left,
		Bottom,
		Right
	};

	struct PointOnRectagle
	{
		glm::vec2 position;
		RectangleSide side;
	};

	std::optional<glm::vec2> lineLineIntersection(const Line<2>& line_1, const Line<2>& line_2);
	std::optional<glm::vec2> rayLineSegmentIntersection(const Ray<2>& ray, const LineSegment2D& line);
	std::optional<PointOnRectagle> rayRectangleIntersection(const Ray<2>& ray, const QRectF& rectangle);
	Plane planeFromTriangle(const Triangle& triangle);
	glm::vec3 normalVector(const Triangle& triangle);
	std::optional<glm::vec3> linePlaneIntersection(
		const Line<3>& line,
		const Plane& plane, const float epsilon = 1e-6f);
	glm::vec3 scalingVector(const glm::mat4 matrix);
	LineSegment2D top(const QRectF& rectangle);
	LineSegment2D bottom(const QRectF& rectangle);
	LineSegment2D left(const QRectF& rectangle);
	LineSegment2D right(const QRectF& rectangle);
	bool isConvex(const std::vector<glm::vec3>& polygon);
	Winding winding(const QPolygonF& polygon);
	struct ScalingExtract
	{
		glm::vec3 scaling;
		glm::mat4 unscaled;
	};
	ScalingExtract extractScaling(const glm::mat4& matrix);

	struct NPolygon
	{
		std::vector<glm::vec3> points;
	};

	inline constexpr bool isclose(const glm::vec3& a, const glm::vec3& b)
	{
		return qFuzzyCompare(a.x, b.x)
			and qFuzzyCompare(a.y, b.y)
			and qFuzzyCompare(a.z, b.z);
	}

	struct CircleF
	{
		QPointF center;
		qreal radius;
	};

	/**
	 * @brief Inscribes a circle
	 * @param circle
	 * @return a QRectF that inscribes the specified circle
	 */
	inline constexpr QRectF inscribe(const CircleF& circle)
	{
		return {
			circle.center.x() - circle.radius,
			circle.center.y() - circle.radius,
			circle.radius * 2,
			circle.radius * 2
		};
	}

	struct BezierCurve
	{
		glm::vec3 points[4];
		const glm::vec3& operator[](int x) const
		{
			Q_ASSERT(x >= 0 and x < 4);
			return this->points[x];
		}
		glm::vec3& operator[](int x)
		{
			Q_ASSERT(x >= 0 and x < 4);
			return this->points[x];
		}
	};

	glm::vec3 pointOnCurve(const BezierCurve& curve, float t);
	glm::vec3 derivativeOnCurve(const BezierCurve& curve, float t);
}
using namespace geom;

mercurial