Hi,
мне надоело постоянно писать p = Point3D(0, 0, 1), q = Point2D(ax, ay), и т.п. и захотелось велосипеда на котором можно было бы ехать в стиле p = Z, q = a*X + b*Y где X,Y,Z — компоненты вектора. В результате появился велосипед который может работать с векторами любой размерности и типа. т.е. Point<3,double> p = 3.14*Z (плавающая точка) или Point<2,int> p = 3*X + 6*Y (целочисленые координаты); Поддерживается весь разумный набор операций:
сложение/разность векторов (X + 5*Y — Z) + (X — Y) — Z
умножение/деление вектора на число a*(X +5*Y — Z) + (X — Y)/3.14 — Z*7;
Подключить можно к любой готовой библиотеке определив в своем классе вектора конструктор, опреатор присваивания и оператор [] для доступа к компонентам вектора.
В качестве компонентов координат можно тоже использовать свой обозначения _X, Y_ и т.п.
пример:
#include "cordex.h"
template <class T>
class Point<3,T>
{
public:
T x;
T y;
T z;
public: // конструктор
template <class U>
Point(const cordex::Wrapper<U> &w)
{
*this = w.eval<Point>();
}
public: // оператор присваивания
template <class U> Point&
operator = (const cordex::Wrapper<U> &w)
{
return (*this = w.eval<Point>());
}
public: // обращение к компонентам по индексу
T&
operator [] ( int idx )
{
return (&x)[idx];
}
Компоненты вектора декларируются так
#include "cordex.h"
static cordex::CoordX X;
static cordex::CoordY Y;
static cordex::CoordZ Z;
Сам велосипед
http://files.rsdn.ru/16157/cordex.h
#pragma once
namespace cordex
{
//=========================================================
template <int I>
struct Component
{
template <class R> R
eval() const
{
R r;
r[I] = 1;
return r;
}
// vs2010 runtime checks workaround
#ifdef _DEBUG
char dummy;
Component()
{
dummy = 0;
}
#endif
};
//=========================================================
template <class A, class T>
struct Scale
{
A a;
T t;
template <class R> R
eval() const
{
return a.eval<R>()*t;
}
};
//=========================================================
template <class A, class T>
struct Div
{
A a;
T t;
template <class R> R
eval() const
{
return a.eval<R>()/t;
}
};
//=========================================================
template <class A, class B>
struct Sum
{
A a;
B b;
template <class R> R
eval() const
{
return a.eval<R>() + b.eval<R>();
}
};
//=========================================================
template <class A, class B>
struct Diff
{
A a;
B b;
template <class R> R
eval() const
{
return a.eval<R>() - b.eval<R>();
}
};
//=========================================================
template <class Ex>
struct Wrapper
{
Ex ex;
template <class R> R
eval() const
{
return ex.eval<R>();
}
};
typedef Wrapper<Component<0>> CoordX;
typedef Wrapper<Component<1>> CoordY;
typedef Wrapper<Component<2>> CoordZ;
template <class A, class T> Wrapper<Div<A,T>>
operator / (const Wrapper<A> &a, const T &t)
{
Wrapper<Div<A,T>> w;
w.ex.t = t;
w.ex.a = a.ex;
return w;
}
template <class A, class T> Wrapper<Scale<A,T>>
operator * (const Wrapper<A> &a, const T &t)
{
Wrapper<Scale<A,T>> w;
w.ex.t = t;
w.ex.a = a.ex;
return w;
}
template <class A, class T> Wrapper<Scale<A,T>>
operator * (const T &t, const Wrapper<A> &a)
{
Wrapper<Scale<A,T>> w;
w.ex.t = t;
w.ex.a = a.ex;
return w;
}
template <class A, class B> Wrapper<Sum<A,B>>
operator + (const Wrapper<A> &a, const Wrapper<B> &b)
{
Wrapper<Sum<A,B>> w;
w.ex.a = a.ex;
w.ex.b = b.ex;
return w;
}
template <class A, class B> Wrapper<Diff<A,B>>
operator - (const Wrapper<A> &a, const Wrapper<B> &b)
{
Wrapper<Diff<A,B>> w;
w.ex.a = a.ex;
w.ex.b = b.ex;
return w;
}
}