mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-07-03 06:44:56 -04:00
Initial source commit
Initial source commit
This commit is contained in:
252
Source/Ember/CarToRas.h
Normal file
252
Source/Ember/CarToRas.h
Normal file
@ -0,0 +1,252 @@
|
||||
#pragma once
|
||||
|
||||
#include "Point.h"
|
||||
|
||||
/// <summary>
|
||||
/// CarToRas class.
|
||||
/// </summary>
|
||||
|
||||
namespace EmberNs
|
||||
{
|
||||
/// <summary>
|
||||
/// When iterating, everything is positioned in terms of a carteseian plane with 0,0 in the center like so:
|
||||
/// [-1,1] [1,1]
|
||||
/// [-1,-1] [1,-1]
|
||||
/// However, when accumulating to the histogram, the data is stored in the traditional raster coordinate system
|
||||
/// of 0,0 at the top left and x,y at the bottom right. This class provides functionality to convert from one
|
||||
/// to the other and is used when accumulating a sub batch of iteration results to the histogram.
|
||||
/// Note the functions use reference arguments for the converted values because they are slightly faster than returning a value.
|
||||
/// Template argument expected to be float or double.
|
||||
/// </summary>
|
||||
template <typename T>
|
||||
class EMBER_API CarToRas
|
||||
{
|
||||
public:
|
||||
/// <summary>
|
||||
/// Empty constructor. This class should never be used unless it's been properly constructed with the constructor that takes arguments.
|
||||
/// </summary>
|
||||
CarToRas()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that takes arguments to set up the bounds and passes them to Init().
|
||||
/// </summary>
|
||||
/// <param name="carLlX">The lower left x of the cartesian plane</param>
|
||||
/// <param name="carLlY">The lower left y of the cartesian plane</param>
|
||||
/// <param name="carUrX">The upper right x of the cartesian plane</param>
|
||||
/// <param name="carUrY">The upper right y of the cartesian plane</param>
|
||||
/// <param name="rasW">The width in pixels of the raster image/histogram</param>
|
||||
/// <param name="rasH">The height in pixels of the raster image/histogram</param>
|
||||
/// <param name="aspectRatio">The aspect ratio, generally 1</param>
|
||||
CarToRas(T carLlX, T carLlY, T carUrX, T carUrY, unsigned int rasW, unsigned int rasH, T aspectRatio)
|
||||
{
|
||||
Init(carLlX, carLlY, carUrX, carUrY, rasW, rasH, aspectRatio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default copy constructor.
|
||||
/// </summary>
|
||||
/// <param name="carToRas">The CarToRas object to copy</param>
|
||||
CarToRas(const CarToRas<T>& carToRas)
|
||||
{
|
||||
CarToRas<T>::operator=<T>(carToRas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor to copy a CarToRas object of type U.
|
||||
/// </summary>
|
||||
/// <param name="carToRas">The CarToRas object to copy</param>
|
||||
template <typename U>
|
||||
CarToRas(const CarToRas<U>& carToRas)
|
||||
{
|
||||
CarToRas<T>::operator=<U>(carToRas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default assignment operator.
|
||||
/// </summary>
|
||||
/// <param name="carToRas">The CarToRas object to copy</param>
|
||||
CarToRas<T>& operator = (const CarToRas<T>& carToRas)
|
||||
{
|
||||
if (this != &carToRas)
|
||||
CarToRas<T>::operator=<T>(carToRas);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assignment operator to assign a CarToRas object of type U.
|
||||
/// </summary>
|
||||
/// <param name="carToRas">The CarToRas object to copy.</param>
|
||||
/// <returns>Reference to updated self</returns>
|
||||
template <typename U>
|
||||
CarToRas<T>& operator = (const CarToRas<U>& carToRas)
|
||||
{
|
||||
m_RasWidth = carToRas.RasWidth();
|
||||
m_RasHeight = carToRas.RasHeight();
|
||||
m_OneRow = T(carToRas.OneRow());
|
||||
m_OneCol = T(carToRas.OneCol());
|
||||
m_PixPerImageUnitW = T(carToRas.PixPerImageUnitW());
|
||||
m_RasLlX = T(carToRas.RasLlX());
|
||||
m_PixPerImageUnitH = T(carToRas.PixPerImageUnitH());
|
||||
m_RasLlY = T(carToRas.RasLlY());
|
||||
m_CarLlX = T(carToRas.CarLlX());
|
||||
m_CarLlY = T(carToRas.CarLlY());
|
||||
m_CarUrX = T(carToRas.CarUrX());
|
||||
m_CarUrY = T(carToRas.CarUrY());
|
||||
m_PadCarLlX = T(carToRas.PadCarLlX());
|
||||
m_PadCarLlY = T(carToRas.PadCarLlY());
|
||||
m_PadCarUrX = T(carToRas.PadCarUrX());
|
||||
m_PadCarUrY = T(carToRas.PadCarUrY());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the dimensions with the specified bounds.
|
||||
/// </summary>
|
||||
/// <param name="carLlX">The lower left x of the cartesian plane</param>
|
||||
/// <param name="carLlY">The lower left y of the cartesian plane</param>
|
||||
/// <param name="carUrX">The upper right x of the cartesian plane</param>
|
||||
/// <param name="carUrY">The upper right y of the cartesian plane</param>
|
||||
/// <param name="rasW">The width in pixels of the raster image/histogram</param>
|
||||
/// <param name="rasH">The height in pixels of the raster image/histogram</param>
|
||||
/// <param name="aspectRatio">The aspect ratio, generally 1</param>
|
||||
void Init(T carLlX, T carLlY, T carUrX, T carUrY, unsigned int rasW, unsigned int rasH, T aspectRatio)
|
||||
{
|
||||
m_RasWidth = rasW;
|
||||
m_RasHeight = rasH;
|
||||
|
||||
m_CarLlX = carLlX;
|
||||
m_CarLlY = carLlY;
|
||||
m_CarUrX = carUrX;
|
||||
m_CarUrY = carUrY;
|
||||
|
||||
T carW = m_CarUrX - m_CarLlX;//Right minus left.
|
||||
T carH = m_CarUrY - m_CarLlY;//Top minus bottom.
|
||||
T invSizeW = T(1.0) / carW;
|
||||
T invSizeH = T(1.0) / carH;
|
||||
|
||||
m_PixPerImageUnitW = (T)rasW * invSizeW;
|
||||
m_RasLlX = m_PixPerImageUnitW * carLlX;
|
||||
|
||||
m_PixPerImageUnitH = (T)rasH * invSizeH;
|
||||
m_RasLlY = m_PixPerImageUnitH * carLlY;
|
||||
|
||||
T m_OneRow = abs(m_CarUrY - m_CarLlY) / m_RasHeight;
|
||||
T m_OneCol = abs(m_CarUrX - m_CarLlX) / m_RasWidth;
|
||||
|
||||
m_PadCarLlX = m_CarLlX + m_OneCol;
|
||||
m_PadCarUrX = m_CarUrX - m_OneCol;
|
||||
|
||||
m_PadCarLlY = m_CarLlY + m_OneRow;
|
||||
m_PadCarUrY = m_CarUrY - m_OneRow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a cartesian x, y coordinate to a raster x, y coordinate.
|
||||
/// This will flip the Y coordinate, so points that hit the bottom of the cartesian plane will
|
||||
/// be mapped to the top of the histogram and vice versa.
|
||||
/// There is a very slim chance that a point will be right on the border and will technically be in bounds, passing the InBounds() test,
|
||||
/// but ends up being mapped to a histogram bucket that is out of bounds due to roundoff error. Perform an additional check after this call to make sure the
|
||||
/// mapped point is in bounds.
|
||||
/// </summary>
|
||||
/// <param name="cartX">The cartesian x</param>
|
||||
/// <param name="cartY">The cartesian y</param>
|
||||
/// <param name="rasX">The converted raster x</param>
|
||||
/// <param name="rasY">The converted raster y</param>
|
||||
inline void Convert(T cartX, T cartY, unsigned int& rasX, unsigned int& rasY)
|
||||
{
|
||||
rasX = (unsigned int)(m_PixPerImageUnitW * cartX - m_RasLlX);
|
||||
rasY = (unsigned int)(m_RasLlY - (m_PixPerImageUnitH * cartY));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a cartesian x, y coordinate to a single raster buffer index.
|
||||
/// This will flip the Y coordinate, so points that hit the bottom of the cartesian plane will
|
||||
/// be mapped to the top of the histogram and vice versa.
|
||||
/// There is a very slim chance that a point will be right on the border and will technically be in bounds, passing the InBounds() test,
|
||||
/// but ends up being mapped to a histogram bucket that is out of bounds due to roundoff error. Perform an additional check after this call to make sure the
|
||||
/// mapped point is in bounds.
|
||||
/// </summary>
|
||||
/// <param name="cartX">The cartesian x</param>
|
||||
/// <param name="cartY">The cartesian y</param>
|
||||
/// <param name="singleBufferIndex">The converted single raster buffer index</param>
|
||||
inline void Convert(T cartX, T cartY, unsigned int& singleBufferIndex)
|
||||
{
|
||||
singleBufferIndex = (unsigned int)(m_PixPerImageUnitW * cartX - m_RasLlX) + (m_RasWidth * (unsigned int)(m_PixPerImageUnitH * cartY - m_RasLlY));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a cartesian x, y point to a single raster buffer index.
|
||||
/// This will flip the Y coordinate, so points that hit the bottom of the cartesian plane will
|
||||
/// be mapped to the top of the histogram and vice versa.
|
||||
/// This is the most efficient possible way of converting, consisting of only
|
||||
/// a multiply and subtract per coordinate element.
|
||||
/// There is a very slim chance that a point will be right on the border and will technically be in bounds, passing the InBounds() test,
|
||||
/// but ends up being mapped to a histogram bucket that is out of bounds due to roundoff error. Perform an additional check after this call to make sure the
|
||||
/// mapped point is in bounds.
|
||||
/// </summary>
|
||||
/// <param name="point">The cartesian y</param>
|
||||
/// <param name="singleBufferIndex">The converted single raster buffer index</param>
|
||||
inline void Convert(Point<T>& point, unsigned int& singleBufferIndex)
|
||||
{
|
||||
singleBufferIndex = (unsigned int)(m_PixPerImageUnitW * point.m_X - m_RasLlX) + (m_RasWidth * (unsigned int)(m_PixPerImageUnitH * point.m_Y - m_RasLlY));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if a point in the cartesian plane can be converted to a point within the raster plane.
|
||||
/// There is a very slim chance that a point will be right on the border and will technically be in bounds, passing the InBounds() test,
|
||||
/// but ends up being mapped to a histogram bucket that is out of bounds due to roundoff error. Perform an additional check after this call to make sure the
|
||||
/// mapped point is in bounds.
|
||||
/// </summary>
|
||||
/// <param name="point">The point to test</param>
|
||||
/// <returns>True if within bounds, else false</returns>
|
||||
inline bool InBounds(Point<T>& point)
|
||||
{
|
||||
//Debug check for hitting the very first pixel in the image.
|
||||
//if (point.m_Y > m_CarLlY && point.m_Y <= m_PadCarLlY && //Mapped to top row...
|
||||
// point.m_X > m_CarLlX && point.m_X <= m_PadCarLlX)//...first col.
|
||||
//{
|
||||
// cout << "First pixel hit." << endl;
|
||||
//}
|
||||
|
||||
return point.m_X >= m_CarLlX &&
|
||||
point.m_X < m_CarUrX &&
|
||||
point.m_Y < m_CarUrY &&
|
||||
point.m_Y >= m_CarLlY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accessors.
|
||||
/// </summary>
|
||||
inline unsigned int RasWidth() const { return m_RasWidth; }
|
||||
inline unsigned int RasHeight() const { return m_RasHeight; }
|
||||
inline T OneRow() const { return m_OneRow; }
|
||||
inline T OneCol() const { return m_OneCol; }
|
||||
inline T PixPerImageUnitW() const { return m_PixPerImageUnitW; }
|
||||
inline T RasLlX() const { return m_RasLlX; }
|
||||
inline T PixPerImageUnitH() const { return m_PixPerImageUnitH; }
|
||||
inline T RasLlY() const { return m_RasLlY; }
|
||||
inline T CarLlX() const { return m_CarLlX; }
|
||||
inline T CarLlY() const { return m_CarLlY; }
|
||||
inline T CarUrX() const { return m_CarUrX; }
|
||||
inline T CarUrY() const { return m_CarUrY; }
|
||||
inline T PadCarLlX() const { return m_PadCarLlX; }
|
||||
inline T PadCarLlY() const { return m_PadCarLlY; }
|
||||
inline T PadCarUrX() const { return m_PadCarUrX; }
|
||||
inline T PadCarUrY() const { return m_PadCarUrY; }
|
||||
|
||||
private:
|
||||
unsigned int m_RasWidth, m_RasHeight;//The width and height of the raster image.
|
||||
T m_OneRow;//The distance that one raster row represents in the cartesian plane.
|
||||
T m_OneCol;//The distance that one raster column represents in the cartesian plane.
|
||||
T m_PixPerImageUnitW;//The number of columns in the raster plane that a horizontal distance of 1 in the cartesian plane represents. The higher the number, the more zoomed in.
|
||||
T m_RasLlX;//The lower left x of the raster image plane.
|
||||
T m_PixPerImageUnitH;//The number of rows in the raster plane that a vertical distance of 1 in the cartesian plane represents. The higher the number, the more zoomed in.
|
||||
T m_RasLlY;//The lower left y of the raster image plane.
|
||||
T m_CarLlX, m_CarLlY, m_CarUrX, m_CarUrY;//The bounds of the cartesian plane.
|
||||
T m_PadCarLlX, m_PadCarLlY, m_PadCarUrX, m_PadCarUrY;//The bounds of the cartesian plane padded by one raster row and column on each side.
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user