Clean project structure.

This commit is contained in:
jmsgrogan 2023-01-17 10:13:25 +00:00
parent 78a4fa99ff
commit 947bf937fd
496 changed files with 206 additions and 137 deletions

View file

@ -0,0 +1,35 @@
#pragma once
#include "Bounds.h"
#include "Point.h"
template<typename T>
class SparseGrid;
class AbstractGeometricItem
{
public:
enum class Type
{
LINE,
LINE_SEGMENT,
CURVE,
RECTANGLE,
TRIANGLE,
POINT,
PATH,
CIRCLE,
UNKNOWN
};
virtual ~AbstractGeometricItem() = default;
virtual Bounds getBounds() const = 0;
virtual const Point& getLocation() const = 0;
virtual void sample(SparseGrid<bool>* grid) const = 0;
virtual Type getType() const { return Type::UNKNOWN; };
};

View file

@ -0,0 +1,63 @@
#pragma once
struct Bounds
{
Bounds(double minX, double maxX, double minY, double maxY, double minZ = 0.0, double maxZ = 0.0)
: mMinX(minX),
mMaxX(maxX),
mMinY(minY),
mMaxY(maxY),
mMinZ(minZ),
mMaxZ(maxZ)
{
}
double mMinX{ 0.0 };
double mMaxX{ 0.0 };
double mMinY{ 0.0 };
double mMaxY{ 0.0 };
double mMinZ{ 0.0 };
double mMaxZ{ 0.0 };
void intialize(double x, double y, double z = 0.0)
{
mMinX = x;
mMaxX = x;
mMinY = y;
mMaxY = y;
mMinZ = z;
mMaxZ = z;
}
void includePoint(double x, double y, double z)
{
if (x < mMinX)
{
mMinX = x;
}
else if (x > mMaxX)
{
mMaxX = x;
}
if (y < mMinY)
{
mMinY = y;
}
else if (y > mMaxY)
{
mMaxY = y;
}
if (z < mMinZ)
{
mMinZ = z;
}
else if (z > mMaxZ)
{
mMaxZ = z;
}
}
};

View file

@ -0,0 +1,60 @@
set(MODULE_NAME geometry)
list(APPEND HEADERS
AbstractGeometricItem.h
Bounds.h
grid/AbstractGrid.h
grid/TypedGrid.h
grid/Grid.h
grid/SparseGrid.h
math/Linalg.h
math/Matrix.h
math/Vector.h
path/Curve.h
path/Line.h
path/LineSegment.h
path/Path.h
path/PathElement.h
points/Point.h
points/PointCollection.h
points/DiscretePoint.h
primitives/Circle.h
primitives/Quad.h
primitives/Rectangle.h
primitives/Triangle.h
)
list(APPEND SOURCES
Transform.cpp
grid/AbstractGrid.cpp
math/Linalg.cpp
math/Matrix.cpp
math/Vector.cpp
path/Curve.cpp
path/Line.cpp
path/LineSegment.cpp
path/Path.cpp
path/PathElement.cpp
points/Point.cpp
points/PointCollection.cpp
points/DiscretePoint.cpp
primitives/Circle.cpp
primitives/Quad.cpp
primitives/Rectangle.cpp
primitives/Triangle.cpp
)
add_library(${MODULE_NAME} SHARED ${SOURCES} ${HEADERS})
target_include_directories(${MODULE_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/math
${CMAKE_CURRENT_SOURCE_DIR}/path
${CMAKE_CURRENT_SOURCE_DIR}/points
${CMAKE_CURRENT_SOURCE_DIR}/primitives
${CMAKE_CURRENT_SOURCE_DIR}/grid
)
target_link_libraries( ${MODULE_NAME} PUBLIC core)
set_target_properties( ${MODULE_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/base)

View file

@ -0,0 +1,30 @@
#include "Transform.h"
Transform::Transform(const Point& location, double scaleX, double scaleY, double scaleZ)
: mLocation(location),
mScaleX(scaleX),
mScaleY(scaleY),
mScaleZ(scaleZ)
{
}
const Point& Transform::getLocation() const
{
return mLocation;
}
double Transform::getScaleX() const
{
return mScaleX;
}
double Transform::getScaleY() const
{
return mScaleY;
}
double Transform::getScaleZ() const
{
return mScaleZ;
}

View file

@ -0,0 +1,35 @@
#pragma once
#include "Point.h"
class Transform
{
public:
Transform(const Point& location = {}, double scaleX = 1.0, double scaleY = 1.0, double scaleZ = 1.0);
const Point& getLocation() const;
double getScaleX() const;
double getScaleY() const;
double getScaleZ() const;
bool operator==(const Transform& rhs) const
{
return (mLocation == rhs.mLocation)
&& (mScaleX == rhs.mScaleX)
&& (mScaleY == rhs.mScaleY)
&& (mScaleZ == rhs.mScaleZ);
}
bool operator!=(const Transform& rhs) const
{
return !operator==(rhs);
}
private:
Point mLocation;
double mScaleX{1};
double mScaleY{1};
double mScaleZ{1};
};

View file

@ -0,0 +1,32 @@
#include "AbstractGrid.h"
AbstractGrid::AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ)
: mBounds(bounds),
mNumX(numPointsX),
mNumY(numPointsY),
mNumZ(numPointsZ)
{
}
const Bounds& AbstractGrid::getBounds() const
{
return mBounds;
}
double AbstractGrid::getXSpacing() const
{
const auto width = mBounds.mMaxX - mBounds.mMinX;
return width / double(mNumX);
}
double AbstractGrid::getYSpacing() const
{
const auto height = mBounds.mMaxY - mBounds.mMinY;
return height / double(mNumY);
}
void AbstractGrid::resetBounds(const Bounds& bounds)
{
mBounds = bounds;
}

View file

@ -0,0 +1,28 @@
#pragma once
#include "Bounds.h"
#include <vector>
#include <memory>
class AbstractGrid
{
public:
AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1);
const Bounds& getBounds() const;
virtual std::size_t getDataSize() const = 0;
double getXSpacing() const;
double getYSpacing() const;
void resetBounds(const Bounds& bounds);
protected:
Bounds mBounds;
std::size_t mNumX{ 0 };
std::size_t mNumY{ 0 };
std::size_t mNumZ{ 0 };
};

View file

@ -0,0 +1,39 @@
#pragma once
#include "TypedGrid.h"
template<typename T>
class Grid : public TypedGrid<T>
{
public:
Grid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1)
: TypedGrid<T>(bounds, numPointsX, numPointsY, numPointsZ)
{
this->mData->initializeTo(numPointsX * numPointsY * numPointsZ, T());
}
T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx) const override
{
return this->mData->getItem(getOffset(idx, jdx, kdx));
}
std::size_t getOffset(std::size_t idx, std::size_t jdx, std::size_t kdx) const
{
return idx * this->mNumZ + jdx * this->mNumX * this->mNumZ + kdx;
}
void setData(const std::vector<T>& data)
{
this->mData->setData(data);
}
void setItem(std::size_t idx, std::size_t jdx, std::size_t kdx, const T& value) override
{
this->mData->setItem(getOffset(idx, jdx, kdx), value);
}
std::size_t getDataSize() const
{
return this->mData->getLength();
}
};

View file

@ -0,0 +1,15 @@
#pragma once
#include "TypedGrid.h"
template<typename T>
class SparseGrid : public TypedGrid
{
public:
SparseGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY)
: TypedGrid<T>(bounds, numPointsX, numPointsY)
{
}
};

View file

@ -0,0 +1,30 @@
#pragma once
#include "List.h"
#include "AbstractGrid.h"
#include <memory>
template <typename T>
class TypedGrid : public AbstractGrid
{
public:
TypedGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1)
: AbstractGrid(bounds, numPointsX, numPointsY, numPointsZ),
mData(std::make_unique<List<T> >())
{
}
virtual ~TypedGrid() = default;
virtual T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx) const = 0;
virtual void setItem(std::size_t idx, std::size_t jdx, std::size_t kdx, const T& value) = 0;
List<T>* getInternalData() const
{
return mData.get();
}
protected:
std::unique_ptr<List<T> > mData;
};

View file

@ -0,0 +1,11 @@
#include "Linalg.h"
double Linalg::dotProduct(const Vector& v0, const Vector& v1)
{
return v0.dotProduct(v1);
}
Vector Linalg::crossProduct(const Vector& v0, const Vector& v1)
{
return v0.crossProduct(v1);
}

View file

@ -0,0 +1,10 @@
#pragma once
#include "Vector.h"
class Linalg
{
static double dotProduct(const Vector& v0, const Vector& v1);
static Vector crossProduct(const Vector& v0, const Vector& v1);
};

View file

View file

@ -0,0 +1,14 @@
#pragma once
#include <vector>
class Matrix
{
public:
Matrix(unsigned numRows, unsigned numColumns)
{
mData = std::vector<double>(numRows * numColumns, 0.0);
}
private:
std::vector<double> mData;
};

View file

@ -0,0 +1,61 @@
#include "Vector.h"
Vector::Vector(double x, double y, double z)
: mX(x),
mY(y),
mZ(z)
{
updateLength();
}
Vector::~Vector()
{
};
double Vector::getX() const
{
return mX;
}
double Vector::getY() const
{
return mY;
}
double Vector::getZ() const
{
return mZ;
}
double Vector::getLength() const
{
return mLength;
}
double Vector::dotProduct(const Vector& v) const
{
return mX * v.mX + mY * v.mY + mZ * v.mZ;
}
Vector Vector::crossProduct(const Vector& v) const
{
return Vector(v.mY * mZ - v.mZ * mY, v.mZ * mX - v.mX * mZ, v.mX * mY - v.mY * mX);
}
Vector Vector::getNormalized() const
{
return Vector(mX / mLength, mY / mLength, mZ / mLength);
}
void Vector::scale(double x, double y, double z)
{
mX = x * mX;
mY = y * mY;
mZ = z * mZ;
updateLength();
}
void Vector::updateLength()
{
mLength = std::sqrt(mX * mX + mY * mY + mZ * mZ);
}

View file

@ -0,0 +1,48 @@
#pragma once
#include <memory>
#include <cmath>
class Vector
{
public:
Vector(double x = 0, double y = 0, double z = 0);
~Vector();
double getX() const;
double getY() const;
double getZ() const;
double getLength() const;
Vector getNormalized() const;
void scale(double x, double y, double z = 1.0);
double dotProduct(const Vector& v) const;
Vector crossProduct(const Vector& v) const;
bool operator==(const Vector& rhs) const
{
return (mX == rhs.mX)
&& (mY == rhs.mY)
&& (mZ == rhs.mZ);
}
bool operator!=(const Vector& rhs) const
{
return !operator==(rhs);
}
private:
void updateLength();
double mLength{ 0 };
double mX{ 0 };
double mY{ 0 };
double mZ{ 0 };
};

View file

View file

@ -0,0 +1,13 @@
#pragma once
#include "PathElement.h"
class Curve : public PathElement
{
public:
enum class CurveType
{
ARC,
CUBIC_BEZIER
};
};

View file

@ -0,0 +1,30 @@
#include "Line.h"
Line::Line(const Point& start, const PointCollection& points)
: mStartPoint(start),
mPoints(points)
{
}
const PointCollection& Line::getPoints() const
{
return mPoints;
}
Line::Type Line::getType() const
{
return Line::Type::LINE;
}
const Point& Line::getLocation() const
{
return mStartPoint;
}
Bounds Line::getBounds() const
{
auto bounds = mPoints.getBounds();
bounds.includePoint(mStartPoint.getX(), mStartPoint.getY(), mStartPoint.getZ());
return bounds;
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "PathElement.h"
#include "PointCollection.h"
#include <vector>
class Line : public PathElement
{
public:
Line(const Point& start, const PointCollection& points);
const PointCollection& getPoints() const;
Line::Type getType() const override;
const Point& getLocation() const override;
Bounds getBounds() const override;
void sample(SparseGrid<bool>* grid) const override {};
private:
Point mStartPoint;
PointCollection mPoints;
};

View file

@ -0,0 +1,49 @@
#include "LineSegment.h"
LineSegment::LineSegment(const Point& p0, const Point& p1)
: mP0(p0),
mP1(p1)
{
}
std::unique_ptr<LineSegment> LineSegment::Create(const Point& p0, const Point& p1)
{
return std::make_unique<LineSegment>(p0, p1);
}
double LineSegment::getLength() const
{
return mP0.getDistance(mP1);
}
const Point& LineSegment::getPoint0() const
{
return mP0;
}
const Point& LineSegment::getPoint1() const
{
return mP1;
}
void LineSegment::sample(SparseGrid<bool>* grid) const
{
}
Bounds LineSegment::getBounds() const
{
const auto minX = std::min(mP0.getX(), mP1.getX());
const auto maxX = std::max(mP0.getX(), mP1.getX());
const auto minY = std::min(mP0.getY(), mP1.getY());
const auto maxY = std::max(mP0.getY(), mP1.getY());
return {minX, maxX, minY, maxY};
}
const Point& LineSegment::getLocation() const
{
return mP0;
}

View file

@ -0,0 +1,27 @@
#pragma once
#include "PathElement.h"
class LineSegment : public PathElement
{
public:
LineSegment(const Point& p0, const Point& p1);
static std::unique_ptr<LineSegment> Create(const Point& p0, const Point& p1);
double getLength() const;
const Point& getPoint0() const;
const Point& getPoint1() const;
void sample(SparseGrid<bool>* grid) const override;
Bounds getBounds() const override;
const Point& getLocation() const override;
private:
Point mP0;
Point mP1;
};

View file

@ -0,0 +1,11 @@
#include "Path.h"
Path::~Path()
{
}
const std::vector<PathElementPtr>& Path::getElements() const
{
return mElements;
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "PathElement.h"
#include <vector>
#include <memory>
using PathElementPtr = std::unique_ptr<PathElement>;
class Path : public AbstractGeometricItem
{
public:
~Path();
const std::vector<PathElementPtr>& getElements() const;
private:
std::vector<PathElementPtr> mElements;
};

View file

@ -0,0 +1,6 @@
#include "PathElement.h"
PathElement::~PathElement()
{
}

View file

@ -0,0 +1,9 @@
#pragma once
#include "AbstractGeometricItem.h"
class PathElement : public AbstractGeometricItem
{
public:
~PathElement();
};

View file

@ -0,0 +1,28 @@
#include "DiscretePoint.h"
DiscretePoint::DiscretePoint(unsigned x, unsigned y)
: mX(x),
mY(y)
{
}
DiscretePoint::~DiscretePoint()
{
};
std::shared_ptr<DiscretePoint> DiscretePoint::Create(unsigned x, unsigned y)
{
return std::make_shared<DiscretePoint>(x, y);
}
unsigned DiscretePoint::getX() const
{
return mX;
}
unsigned DiscretePoint::getY() const
{
return mY;
}

View file

@ -0,0 +1,35 @@
#pragma once
#include <memory>
class DiscretePoint
{
public:
DiscretePoint(unsigned x = 0, unsigned y = 0);
~DiscretePoint();
std::shared_ptr<DiscretePoint> Create(unsigned x, unsigned y);
unsigned getX() const;
unsigned getY() const;
bool operator==(const DiscretePoint& rhs) const
{
return (mX == rhs.mX)
&& (mY == rhs.mY);
}
bool operator!=(const DiscretePoint& rhs) const
{
return !operator==(rhs);
}
private:
unsigned mX{ 0 };
unsigned mY{ 0 };
};
using Pixel = DiscretePoint;
using DiscretePointPtr = std::shared_ptr<DiscretePoint>;
using PixelPtr = DiscretePointPtr;

View file

@ -0,0 +1,91 @@
#include "Point.h"
#include "Transform.h"
#include <cmath>
Point::Point(double x, double y, double z)
: mX(x),
mY(y),
mZ(z)
{
}
Point::Point(const DiscretePoint& point)
: mX(static_cast<double>(point.getX())),
mY(static_cast<double>(point.getY())),
mZ(0)
{
}
Point::Point(const Point& reference, double offSetX, double offSetY, double offSetZ)
: mX(reference.getX() + offSetX),
mY(reference.getY() + offSetY),
mZ(reference.getZ() + offSetZ)
{
}
Point::~Point()
{
};
std::shared_ptr<Point> Point::Create(double x, double y, double z)
{
return std::make_shared<Point>(x, y, z);
}
double Point::getX() const
{
return mX;
}
double Point::getY() const
{
return mY;
}
double Point::getZ() const
{
return mZ;
}
double Point::getDistance(const Point& point) const
{
const auto deltaX = getDeltaX(point);
const auto deltaY = getDeltaY(point);
const auto deltaZ = getDeltaZ(point);
return std::sqrt(deltaX* deltaX + deltaY* deltaY + deltaZ* deltaZ);
}
Vector Point::getDelta(const Point& point) const
{
return Vector(point.mX - mX, point.mY - mY, point.mZ - mZ);
}
double Point::getDeltaX(const Point& point) const
{
return point.getX() - mX;
}
double Point::getDeltaY(const Point& point) const
{
return point.getY() - mY;
}
double Point::getDeltaZ(const Point& point) const
{
return point.getZ() - mZ;
}
void Point::apply(const Transform& transform)
{
mX -= transform.getLocation().getX();
mY -= transform.getLocation().getY();
mZ -= transform.getLocation().getZ();
mX *= transform.getScaleX();
mY *= transform.getScaleY();
mZ *= transform.getScaleZ();
}

View file

@ -0,0 +1,60 @@
#pragma once
#include "DiscretePoint.h"
#include "Vector.h"
#include <memory>
#include <vector>
class Transform;
class Point
{
public:
Point(double x = 0, double y = 0, double z = 0);
Point(const DiscretePoint& point);
Point(const Point& reference, double offSetX, double offSetY, double offSetZ = 0);
~Point();
static std::shared_ptr<Point> Create(double x, double y, double z = 0);
void apply(const Transform& transform);
double getX() const;
double getY() const;
double getZ() const;
double getDistance(const Point& point) const;
double getDeltaX(const Point& point) const;
double getDeltaY(const Point& point) const;
double getDeltaZ(const Point& point) const;
Vector getDelta(const Point& point) const;
bool operator==(const Point& rhs) const
{
return (mX == rhs.mX)
&& (mY == rhs.mY)
&& (mZ == rhs.mZ);
}
bool operator!=(const Point& rhs) const
{
return !operator==(rhs);
}
private:
double mX{0};
double mY{0};
double mZ{0};
};
using PointPtr = std::unique_ptr<Point>;

View file

@ -0,0 +1,32 @@
#include "PointCollection.h"
PointCollection::PointCollection(const std::vector<Point> points)
: mPoints(points)
{
}
void PointCollection::apply(const Transform& transform)
{
for (auto& point : mPoints)
{
point.apply(transform);
}
}
Bounds PointCollection::getBounds() const
{
Bounds bounds{0.0, 0.0, 0.0, 0.0};
if (mPoints.size() == 0)
{
return bounds;
}
bounds.intialize(mPoints[0].getX(), mPoints[0].getY(), mPoints[0].getZ());
for(const auto& point : mPoints)
{
bounds.includePoint(point.getX(), point.getY(), point.getZ());
}
return bounds;
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "Point.h"
#include "Transform.h"
#include "Bounds.h"
class PointCollection
{
public:
PointCollection(const std::vector<Point> points = {});
void apply(const Transform& transform);
Bounds getBounds() const;
private:
std::vector<Point> mPoints;
};

View file

@ -0,0 +1,52 @@
#include "Circle.h"
Circle::Circle(const Point& centre, double radius)
: mCentre(centre),
mRadius(radius)
{
mMinorRadius = mRadius;
}
const Point& Circle::getLocation() const
{
return mCentre;
}
double Circle::getRadius() const
{
return mRadius;
}
double Circle::getMinorRadius() const
{
return mMinorRadius;
}
void Circle::setMinorRadius(double radius)
{
mMinorRadius = radius;
}
void Circle::sample(SparseGrid<bool>* grid) const
{
}
bool Circle::isEllipse() const
{
return mRadius != mMinorRadius;
}
Bounds Circle::getBounds() const
{
double minX = mCentre.getX() - mRadius;
double maxX = mCentre.getX() + mRadius;
double minY = mCentre.getY() - mMinorRadius;
double maxY = mCentre.getY() + mMinorRadius;
return { minX, maxX, minY, maxY };
}
Circle::Type Circle::getType() const
{
return Type::CIRCLE;
}

View file

@ -0,0 +1,31 @@
#pragma once
#include "AbstractGeometricItem.h"
#include "Point.h"
class Circle : public AbstractGeometricItem
{
public:
Circle(const Point& centre, double radius = 0.5);
const Point& getLocation() const override;
double getRadius() const;
double getMinorRadius() const;
Bounds getBounds() const override;
Type getType() const override;
bool isEllipse() const;
void setMinorRadius(double radius);
void sample(SparseGrid<bool>* grid) const override;
private:
double mMinorRadius{ 0.5 };
double mRadius{ 0.5 };
Point mCentre;
};

View file

View file

View file

@ -0,0 +1,53 @@
#include "Rectangle.h"
namespace ntk {
Rectangle::Rectangle(const Point& bottomLeft, const Point& topRight)
: mBottomLeft(bottomLeft)
{
mHeight = mBottomLeft.getDeltaY(topRight);
mWidth = mBottomLeft.getDeltaX(topRight);
}
Rectangle::Rectangle(const Point& bottomLeft, double width, double height)
: mBottomLeft(bottomLeft),
mHeight(height),
mWidth(width)
{
}
Rectangle::Type Rectangle::getType() const
{
return AbstractGeometricItem::Type::RECTANGLE;
}
Bounds Rectangle::getBounds() const
{
const auto minX = mBottomLeft.getX();
const auto maxX = mBottomLeft.getX() + mWidth;
const auto minY = mBottomLeft.getY();
const auto maxY = mBottomLeft.getY() + mHeight;
return { minX , maxX , minY , maxY };
}
void Rectangle::sample(SparseGrid<bool>* grid) const
{
}
double Rectangle::getHeight() const
{
return mHeight;
}
double Rectangle::getWidth() const
{
return mWidth;
}
const Point& Rectangle::getLocation() const
{
return mBottomLeft;
}
}

View file

@ -0,0 +1,30 @@
#pragma once
#include "AbstractGeometricItem.h"
namespace ntk{
class Rectangle : public AbstractGeometricItem
{
public:
Rectangle(const Point& bottomLeft, const Point& topRight);
Rectangle(const Point& bottomLeft, double width, double height);
double getHeight() const;
double getWidth() const;
const Point& getLocation() const override;
Bounds getBounds() const override;
Type getType() const override;
void sample(SparseGrid<bool>* grid) const override;
private:
Point mBottomLeft;
double mWidth{0};
double mHeight{0};
};
}

View file

@ -0,0 +1,8 @@
#pragma once
#include "AbstractGeometricItem.h"
class Triangle : public AbstractGeometricItem
{
};