/******************************************************************************
Online C++ Compiler.
Code, Compile, Run and Debug C++ program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <iostream>
#include <cstring>
#include <assert.h>
#include <math.h>
#include <cmath>
#include <sstream>
using namespace std;
class Vector2
{
public:
float x;
float y;
public:
//----------------[ constructors ]--------------------------
/**
* Creates and sets to (0,0)
*/
Vector2()
: x(0), y(0)
{
}
/**
* Creates and sets to (x,y)
* @param nx initial x-coordinate value
* @param ny initial y-coordinate value
*/
Vector2(float _x, float _y)
: x(_x), y(_y)
{
}
//---------------[ vector arithmetic operator ]--------------
/**
* Addition operator
* @param rhs Right hand side argument of binary operator.
*/
Vector2 operator+(const Vector2& rhs) const
{
return Vector2(x + rhs.x, y + rhs.y);
}
/**
* Subtraction operator
* @param rhs Right hand side argument of binary operator.
*/
Vector2 operator-(const Vector2& rhs) const
{
return Vector2(x - rhs.x, y - rhs.y);
}
/**
* Multiplication operator
* @param rhs Right hand side argument of binary operator.
*/
Vector2 operator*(const Vector2& rhs) const
{
return Vector2(x * rhs.x, y * rhs.y);
}
/**
* Division operator
* @param rhs Right hand side argument of binary operator.
*/
Vector2 operator/(const Vector2& rhs) const
{
return Vector2(x / rhs.x, y / rhs.y);
}
/**
* Copy operator
* @param rhs Right hand side argument of binary operator.
*/
Vector2& operator=(const Vector2& rhs)
{
x = rhs.x;
y = rhs.y;
return *this;
}
/**
* Array access operator
* @param n Array index
* @return For n = 0, reference to x coordinate, else reference to y
* y coordinate.
*/
float& operator[](int n)
{
static_assert(sizeof(*this) == sizeof(float[2]), "");
assert(n >= 0 && n < 2);
return (&x)[n];
}
/**
* Constant array access operator
* @param n Array index
* @return For n = 0, reference to x coordinate, else reference to y
* y coordinate.
*/
const float& operator[](int n) const
{
static_assert(sizeof(*this) == sizeof(float[2]), "");
assert(n >= 0 && n < 2);
return (&x)[n];
}
};
class Vector3
{
public:
float x;
float y;
float z;
public:
//----------------[ constructors ]--------------------------
/**
* Creates and sets to (0,0)
*/
Vector3()
: x(0), y(0), z(0)
{
}
/**
* Creates and sets to (x,y)
* @param nx initial x-coordinate value
* @param ny initial y-coordinate value
*/
Vector3(float _x, float _y, float _z)
: x(_x), y(_y), z(_z)
{
}
//---------------[ vector arithmetic operator ]--------------
/**
* Addition operator
* @param rhs Right hand side argument of binary operator.
*/
Vector3 operator+(const Vector3& rhs) const
{
return Vector3(x + rhs.x, y + rhs.y, z + rhs.z);
}
/**
* Subtraction operator
* @param rhs Right hand side argument of binary operator.
*/
Vector3 operator-(const Vector3& rhs) const
{
return Vector3(x - rhs.x, y - rhs.y, z + rhs.z);
}
/**
* Multiplication operator
* @param rhs Right hand side argument of binary operator.
*/
Vector3 operator*(const Vector3& rhs) const
{
return Vector3(x * rhs.x, y * rhs.y, z * rhs.z);
}
/**
* Division operator
* @param rhs Right hand side argument of binary operator.
*/
Vector3 operator/(const Vector3& rhs) const
{
return Vector3(x / rhs.x, y / rhs.y, z / rhs.z);
}
//----------------[ access operators ]-------------------
/**
* Copy operator
* @param rhs Right hand side argument of binary operator.
*/
Vector3& operator=(const Vector3& rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
return *this;
}
/**
* Array access operator
* @param n Array index
* @return For n = 0, reference to x coordinate, else reference to y
* y coordinate.
*/
float& operator[](int n)
{
static_assert(sizeof(*this) == sizeof(float[3]), "");
assert(n >= 0 && n < 3);
return (&x)[n];
}
/**
* Constant array access operator
* @param n Array index
* @return For n = 0, reference to x coordinate, else reference to y
* y coordinate.
*/
const float& operator[](int n) const
{
static_assert(sizeof(*this) == sizeof(float[3]), "");
assert(n >= 0 && n < 3);
return (&x)[n];
}
};
class Matrix3x3
{
private:
//-------------------- Attributes --------------------//
union
{
float mData[9];
Vector3 mRows[3];
};
public :
/**
* Default constructor.
*
* Constructs the identity matrix.
*/
Matrix3x3()
: mData{1.0f, 0.0f, 0.0f ,
0.0f, 1.0f, 0.0f ,
0.0f, 0.0f, 1.0f}
{
// Nothing to do.
}
/**
* Constructor.
*
* Constructs the matrix from the passed array.
*
* @param arr Array of floating point values in row-major order.
*/
Matrix3x3(const float arr[9])
{
std::memcpy(mData, arr, 9 * sizeof(float));
}
/**
* Copy casting constructor.
* @param src Data source for new created instance of IMatrix3x3
*/
Matrix3x3(float a1, float a2, float a3,
float b1, float b2, float b3,
float c1, float c2, float c3)
{
mRows[0] = Vector3(a1, a2, a3);
mRows[1] = Vector3(b1, b2, b3);
mRows[2] = Vector3(c1, c2, c3);
}
/**
* Matrix entry accessor operator.
*
* @note Entry indicies are in the range 0 <= `index` <= 8.
*
* @param index Index for the entry to return.
* @return Entry at position `index`.
*/
float operator[](std::size_t index) const
{
assert(index < 9);
return mData[index];
}
/**
* Matrix addition operator.
*
* @note Matrix addition is commutative.
*
* @param A The first matrix.
* @param B The second matrix.
* @return The matrix equal to the sum of `A` and `B`.
*/
Matrix3x3 operator+(const Matrix3x3& rhs) const
{
Matrix3x3 ret;
for (int i = 0; i < 3; i++) ret.mRows[i] = mRows[i] + rhs.mRows[i];
return ret;
}
/**
* Matrix subtraction operator.
*
* @note Matrix subtraction is not commutative.
*
* @param lhs The left hand side matrix.
* @param rhs The right hand side matrix.
* @return The matrix equal to the `rhs` matrix subtracted from the `lhs`
* matrix.
*/
Matrix3x3 operator-(const Matrix3x3& rhs) const
{
Matrix3x3 ret;
for (int i = 0; i < 3; i++) ret.mRows[i] = mRows[i] - rhs.mRows[i];
return ret;
}
/**
* Matrix negation operator.
*
* @param A The matrix to negate.
* @return The additive inverse of the matrix `A`.
*/
friend Matrix3x3 operator-(const Matrix3x3 &A)
{
return Matrix3x3( -A[0], -A[1], -A[2] ,
-A[3], -A[4], -A[5] ,
-A[6], -A[7], -A[8] );
}
/**
* Scalar multiplication operator.
*
* Multiplies each entry of a matrix by a given scalar value.
*
* @param A The matrix to be multiplied by the given scalar.
* @param s The scalar value.
* @return The matrix `A` multiplied by the scalar `s`.
*/
friend Matrix3x3 operator*(const Matrix3x3& matrix, const float nb)
{
return Matrix3x3(matrix.mRows[0][0] * nb, matrix.mRows[0][1] * nb, matrix.mRows[0][2] * nb,
matrix.mRows[1][0] * nb, matrix.mRows[1][1] * nb, matrix.mRows[1][2] * nb,
matrix.mRows[2][0] * nb, matrix.mRows[2][1] * nb, matrix.mRows[2][2] * nb);
}
/**
* Scalar multiplication operator.
*
* Multiplies each entry of a matrix by a given scalar value.
*
* @param s The scalar value.
* @param A The matrix to be multiplied by the given scalar.
* @return The matrix `A` multiplied by the scalar `s`.
*/
friend Matrix3x3 operator*(const float s, const Matrix3x3& A)
{
return A * s;
}
/// Overloaded operator for inveret multiplication with a number
friend Matrix3x3 operator/(float nb, const Matrix3x3& matrix)
{
return Matrix3x3(matrix.mRows[0][0] / nb, matrix.mRows[0][1] / nb, matrix.mRows[0][2] / nb,
matrix.mRows[1][0] / nb, matrix.mRows[1][1] / nb, matrix.mRows[1][2] / nb,
matrix.mRows[2][0] / nb, matrix.mRows[2][1] / nb, matrix.mRows[2][2] / nb);
}
/// Overloaded operator for inveret multiplication with a matrix
friend Matrix3x3 operator/(const Matrix3x3& matrix, float nb)
{
return nb / matrix;
}
/**
* Vector multiplication operator.
*
* Multiplies the matrix `rhs` on the left by the row vector `lhs`,
* returning the resulting vector.
*
* @param lhs The matrix.
* @param rhs The row vector.
* @return The vector `lhs` multiplied by the matrix `rhs` on the right.
*/
friend Vector3 operator*(const Vector3& rhs, const Matrix3x3& lhs)
{
return lhs * rhs;
}
/**
* Vector multiplication operator.
*
* Multiplies the column vector `rhs` on the left by the matrix `lhs`,
* returning the resulting vector.
*
* @param lhs The matrix.
* @param rhs The column vector.
* @return The vector `rhs` multiplied by the matrix `lhs` on the left.
*/
Vector3 operator*(const Vector3& rhs) const
{
float fX = rhs.x;
float fY = rhs.y;
float fZ = rhs.z;
Vector3 Point;
Point.x = ( fX * mRows[0][0] + fY * mRows[0][1] + fZ * mRows[0][2]);
Point.y = ( fX * mRows[1][0] + fY * mRows[1][1] + fZ * mRows[1][2]);
Point.z = ( fX * mRows[2][0] + fY * mRows[2][1] + fZ * mRows[2][2]);
return Point;
}
/**
* Matrix multiplication operator.
*
* @note Matrix multiplication is not commutative.
*
* @param lhs The left hand side matrix.
* @param rhs The right hand side matrix.
* @return The matrix equal to the product `lhs` x `rhs`.
*/
Matrix3x3 operator*(Matrix3x3 rhs) const
{
Matrix3x3 w;
for(int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
float n = 0;
for (int k = 0; k < 3; k++)
{
n += rhs.mRows[i][k] * mRows[k][j];
}
w.mRows[i][j] = n;
}
}
return w;;
}
//----------[ output operator ]----------------------------
/**
* Output to stream operator
* @param lhs Left hand side argument of operator (commonly ostream instance).
* @param rhs Right hand side argument of operator.
* @return Left hand side argument - the ostream object passed to operator.
*/
friend std::ostream& operator <<(std::ostream& lhs, const Matrix3x3& rhs)
{
for (int i = 0; i < 3; i++)
{
lhs << "|\t";
for (int j = 0; j < 3; j++)
{
lhs << rhs.mRows[i][j] << "\t";
}
lhs << "|" << std::endl;
}
return lhs;
}
/**
* Gets string representation.
*/
std::string toString() const
{
std::ostringstream oss;
oss << *this;
return oss.str();
}
};
Vector2 intersect( const Vector2& point1 , const Vector2& point2 ,
const Vector2& point3 , const Vector2& point4)
{
float a1, a2, b1, b2, c1, c2;
float x1 = point1.x;
float y1 = point1.y;
float x2 = point2.x;
float y2 = point2.y;
float x3 = point3.x;
float y3 = point3.y;
float x4 = point4.x;
float y4 = point4.y;
// line equation ax + by + c = 0
a1 = y1 - y2;
b1 = x2 - x1;
c1 = x1 * y2 - x2 * y1;
a2 = y3 - y4;
b2 = x4 - x3;
c2 = x3 * y4 - x4 * y3;
float det = a1 * b2 - a2 * b1;
float x = (b1 * c2 - b2 * c1) / det;
float y = (a2 * c1 - a1 * c2) / det;
return Vector2(x , y);
}
Matrix3x3 intersect_Matrix( const Vector2& point1 ,
const Vector2& point2 ,
const Vector2& point3,
const Vector2& point4)
{
float a1, a2, b1, b2, c1, c2;
float x1 = point1.x;
float y1 = point1.y;
float x2 = point2.x;
float y2 = point2.y;
float x3 = point3.x;
float y3 = point3.y;
float x4 = point4.x;
float y4 = point4.y;
// line equation ax + by + c = 0
a1 = y1 - y2;
b1 = x2 - x1;
c1 = x1 * y2 - x2 * y1;
a2 = y3 - y4;
b2 = x4 - x3;
c2 = x3 * y4 - x4 * y3;
float det = a1 * b2 - a2 * b1;
float b_x = (b1 * c2 - b2 * c1) / point4.x; // / det;
float b_y = (a2 * c1 - a1 * c2) / point4.y; // / det;
return Matrix3x3(b_x,0,0,
0,b_y,0,
0,0,det);
}
int main()
{
Vector2 line_point_1(0,10);
Vector2 line_point_2(10,0);
Vector2 point_pos(4,2);
Vector2 light_point_pos(2,0);
cout<< "line_point_1: vec(" << line_point_1.x << "," << line_point_1.y << endl;
cout<< "line_point_2: vec(" << line_point_2.x << "," << line_point_2.y << endl;
cout<< "light_point_pos: vec(" << light_point_pos.x << "," << light_point_pos.y << endl;
cout<< "point_pos: vec(" << point_pos.x << "," << point_pos.y << endl;
//===============================================================//
Vector2 real_intersection_p = intersect(line_point_1,
line_point_2,
light_point_pos,
point_pos);
cout<< "\n Real_intersection_point: vec(" <<
real_intersection_p.x << "," <<
real_intersection_p.y << endl;
//===============================================================//
Matrix3x3 A3x3 = intersect_Matrix( line_point_1,
line_point_2,
light_point_pos,
point_pos );
Vector3 p_intesection_point = A3x3 * Vector3(point_pos.x , point_pos.y , 1.0 );
float _Z = p_intesection_point.z;
cout<< " \n Matrix3x3(A) Projection-in-2D Intersection_point: A*p = vec(" <<
p_intesection_point.x/_Z << "," <<
p_intesection_point.y/_Z <<endl;
cout<< "\n Output: geomorphism matrix-3x3 (A)= " <<endl;
cout<< A3x3 <<endl;
/**/
return 0;
}