Нарисуйте повернутое изображение на холсте - PullRequest
0 голосов
/ 26 февраля 2012

Я пытаюсь заменить часть изображения на повернутую версию другой. Источник изображения должен выглядеть таким образом, чтобы origin_source заканчивался на orign_dest в изображении * this. Также источник должен вращаться вокруг origin_source перед заменой пикселей.

Приведенный ниже код работает, когда R является зеркальной матрицей, но если я на самом деле перехожу к матрице вращения, результирующее изображение становится срезанным. Что не так?

void Image::imageApply(const Image& source,const Point& origin_dest,const Point& origin_source,const Point& direction)
{
Matrix22<double> R=transformRotationCreate(direction);
Point source_new_size=sqrt(2)*((Point){source.widthGet(),source.heightGet()});
Point blit_start=origin_dest;
for(unsigned int k=0;k<source_new_size.y;k++)
    {
    for(unsigned int l=0;l<source_new_size.x;l++)
        {
        Point point_source=(Point){l,k};
        Point point_dest=point_source-origin_source;
        point_dest*=R;
        point_dest+=blit_start;

        if(point_source.rectangleInIs((Point){0,0},(Point){source.widthGet(),source.heightGet()})
            &&point_dest.rectangleInIs((Point){0,0},(Point){widthGet(),heightGet()}))
            {
            (*this)(point_dest)=source(point_source);
            }
        }
    }
}

Вот некоторые другие используемые функции:

Т = двойной

template<class T>
struct Matrix22
{
T xx;
T xy;
T yx;
T yy;
};

Направление - нормализованный вектор

inline Matrix22<double> transformRotationCreate(const Vector2d<double>& direction)
{
return (Matrix22<double>){direction.x, -direction.y, direction.y, direction.x};
}

Также

Vector2d<T>& operator*=(const Matrix22<T>& M)
    {
    x=x*M.xx + y*M.xy;
    y=x*M.yx + y*M.yy;
    return *this;
    }

1 Ответ

0 голосов
/ 01 марта 2012

Я решил это

Во-первых, оператор умножения матрицы на вектор был неправильным:

Vector2d<T>& operator*=(const Matrix22<T>& M)
    {
    T x_old=x;  //Need to save old x value (Stupid error but anyone does so sometimes)
    x=x*M.xx + y*M.xy;
    y=x_old*M.yx + y*M.yy;
    return *this;
    }

Финальная процедура "поворота и вставки" выглядит следующим образом:

void Image::imageApply(const Image& source,const Point& origin_dest,const Point& origin_source,const Point& direction)
{
Matrix22<double> R=transformRotationCreate(direction);
Point blit_start=origin_dest-(Point){source.sizeMaxGet(),source.sizeMaxGet()};
Point blit_end=origin_dest+(Point){source.sizeMaxGet(),source.sizeMaxGet()};

for(unsigned int k=blit_start.y;k<blit_end.y;k++)
    {
    for(unsigned int l=blit_start.x;l<blit_end.x;l++)
        {
        Point point_dest=(Point){l,k};
        Point point_source=R*(point_dest - origin_dest) + origin_source;
        if(point_source.rectangleInIs((Point){0,0},(Point){source.widthGet(),source.heightGet()} ))
            {
            float alpha_source=source(point_source).alpha;
            (*this)(point_dest)=(1.0f-alpha_source)*(*this)(point_dest)
                                + alpha_source*source(point_source);
            }
        }
    }
}

Наконец, направление вращения было неправильным, но это просто обмен xy-факторами в преобразовании.

...