Skip to content

Commit

Permalink
Added Quad constructor for point and normal. #24
Browse files Browse the repository at this point in the history
Modified Quad plane constructor to use the new constructor.
Modified the Quad triangle constructor to make a quad that fits exactly around the triangle.
  • Loading branch information
MStachowicz committed Jun 5, 2023
1 parent 04b2d98 commit 2601f98
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 29 deletions.
81 changes: 54 additions & 27 deletions source/Geometry/Quad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,72 @@

namespace Geometry
{
Quad::Quad(const Plane& p_plane) noexcept
: m_point_1{}
, m_point_2{}
, m_point_3{}
, m_point_4{}
Quad::Quad(const glm::vec3& p_point, const glm::vec3& p_normal) noexcept
{
glm::vec3 right;
if (p_plane.m_normal.x != 0 || p_plane.m_normal.z != 0)
right = glm::normalize(glm::vec3(p_plane.m_normal.z, 0.f, -p_plane.m_normal.x));
if (p_normal.x != 0 || p_normal.z != 0)
right = glm::normalize(glm::vec3(p_normal.z, 0.f, -p_normal.x));
else
right = glm::normalize(glm::vec3(p_plane.m_normal.y, -p_plane.m_normal.x, 0.f));
right = glm::normalize(glm::vec3(p_normal.y, -p_normal.x, 0.f));

const glm::vec3 up = glm::normalize(glm::cross(right, p_plane.m_normal));
const glm::vec3 up = glm::normalize(glm::cross(right, p_normal));

// Since Plane has no real position, we construct the quad at the arbitrary center-point represented by the closest point on the plane to the origin.
m_point_1 = glm::vec3(p_point + right + up);
m_point_2 = glm::vec3(p_point - right + up);
m_point_3 = glm::vec3(p_point - right - up);
m_point_4 = glm::vec3(p_point + right - up);
}
Quad::Quad(const Plane& p_plane) noexcept
{
// Since Plane has no real position, we construct the quad at the arbitrary center-point represented by the closest point
// on the plane to the origin.
const glm::vec3 p = p_plane.m_normal * p_plane.m_distance;

m_point_1 = glm::vec3(p + right + up);
m_point_2 = glm::vec3(p - right + up);
m_point_3 = glm::vec3(p - right - up);
m_point_4 = glm::vec3(p + right - up);
auto quad = Quad(p, p_plane.m_normal);
m_point_1 = quad.m_point_1;
m_point_2 = quad.m_point_2;
m_point_3 = quad.m_point_3;
m_point_4 = quad.m_point_4;
}
// Construct a unit quad at the centroid position of p_triangle.
Quad::Quad(const Triangle& p_triangle) noexcept
{
const glm::vec3 triangle_normal = p_triangle.normal();

// First find the up and right directions local to p_triangle.
// Next using the up, down, left and right directions find the how much to scale the unit quad to encompass the triangle,
// by finding the largest magnitude dot products of points from the centroid of p_triangle to the edges.
glm::vec3 right;
if (triangle_normal.x != 0 || triangle_normal.z != 0)
right = glm::normalize(glm::vec3(triangle_normal.z, 0.f, -triangle_normal.x));
if (p_triangle.normal().x != 0 || p_triangle.normal().z != 0)
right = glm::normalize(glm::vec3(p_triangle.normal().z, 0.f, -p_triangle.normal().x));
else
right = glm::normalize(glm::vec3(triangle_normal.y, -triangle_normal.x, 0.f));
right = glm::normalize(glm::vec3(p_triangle.normal().y, -p_triangle.normal().x, 0.f));

const glm::vec3 up = -glm::normalize(glm::cross(right, p_triangle.normal()));
float most_up_value = 0;
float most_down_value = 0;
float most_left_value = 0;
float most_right_value = 0;
auto triangle_center = p_triangle.centroid();
std::array<glm::vec3, 3> triangle_center_to_edges = {p_triangle.m_point_1 - triangle_center, p_triangle.m_point_2 - triangle_center, p_triangle.m_point_3 - triangle_center};

for (uint8_t i = 0; i < triangle_center_to_edges.size(); i++)
{
auto dot_up = glm::dot(triangle_center_to_edges[i], up);
auto dot_right = glm::dot(triangle_center_to_edges[i], right);
auto dot_down = glm::dot(triangle_center_to_edges[i], -up);
auto dot_left = glm::dot(triangle_center_to_edges[i], -right);

if (dot_up > most_up_value)
most_up_value = dot_up;
if (dot_down > most_down_value)
most_down_value = dot_down;
if (dot_right > most_right_value)
most_right_value = dot_right;
if (dot_left > most_left_value)
most_left_value = dot_left;
}

const glm::vec3 up = glm::normalize(glm::cross(right, triangle_normal));
const glm::vec3 p = p_triangle.centroid();
m_point_1 = glm::vec3(p + right + up);
m_point_2 = glm::vec3(p - right + up);
m_point_3 = glm::vec3(p - right - up);
m_point_4 = glm::vec3(p + right - up);
m_point_1 = glm::vec3(triangle_center + (right * most_right_value) + (up * most_up_value));
m_point_2 = glm::vec3(triangle_center + (-right * most_left_value) + (up * most_up_value));
m_point_3 = glm::vec3(triangle_center + (-right * most_left_value) + (-up * most_down_value));
m_point_4 = glm::vec3(triangle_center + (right * most_right_value) + (-up * most_down_value));
}

glm::vec3 Quad::center() const
Expand Down
6 changes: 4 additions & 2 deletions source/Geometry/Quad.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ namespace Geometry
, m_point_3{p_point_3}
, m_point_4{p_point_4}
{}
// Construct a unit quad at the centroid position of p_triangle.
// Construct a unit quad at p_point facing p_normal (counter-clockwise winding).
Quad(const glm::vec3& p_point, const glm::vec3& p_normal) noexcept;
// Construct a quad at the centroid position of p_triangle scaled to encompass it.
Quad(const Triangle& p_triangle) noexcept;
// Construct a unit quad inside the plane.
// Construct a unit quad inside the plane centered at the closest point of the plane to the origin.
Quad(const Plane& p_plane) noexcept;

// Uniformly scale the Quad by p_scale factor from its center.
Expand Down

0 comments on commit 2601f98

Please sign in to comment.