[src] Координатные выражения
От: Kluev  
Дата: 29.08.11 14:38
Оценка:
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;
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.