agg_span_interpolator_persp.h

来自「这是VCF框架的代码」· C头文件 代码 · 共 463 行 · 第 1/2 页

H
463
字号
//----------------------------------------------------------------------------// Anti-Grain Geometry - Version 2.4// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)//// Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied// warranty, and with no claim as to its suitability for any purpose.////----------------------------------------------------------------------------// Contact: mcseem@antigrain.com//          mcseemagg@yahoo.com//          http://www.antigrain.com//----------------------------------------------------------------------------#ifndef AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED#define AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED#include "agg_trans_perspective.h"#include "agg_dda_line.h"namespace agg{    //===========================================span_interpolator_persp_exact    template<unsigned SubpixelShift = 8>     class span_interpolator_persp_exact    {    public:        typedef trans_perspective trans_type;        typedef trans_perspective::iterator_x iterator_type;        enum subpixel_scale_e        {            subpixel_shift = SubpixelShift,            subpixel_scale = 1 << subpixel_shift        };        //--------------------------------------------------------------------        span_interpolator_persp_exact() {}        //--------------------------------------------------------------------        // Arbitrary quadrangle transformations        span_interpolator_persp_exact(const double* src, const double* dst)         {            quad_to_quad(src, dst);        }        //--------------------------------------------------------------------        // Direct transformations         span_interpolator_persp_exact(double x1, double y1,                                       double x2, double y2,                                       const double* quad)        {            rect_to_quad(x1, y1, x2, y2, quad);        }        //--------------------------------------------------------------------        // Reverse transformations         span_interpolator_persp_exact(const double* quad,                                       double x1, double y1,                                       double x2, double y2)        {            quad_to_rect(quad, x1, y1, x2, y2);        }        //--------------------------------------------------------------------        // Set the transformations using two arbitrary quadrangles.        void quad_to_quad(const double* src, const double* dst)        {            m_trans_dir.quad_to_quad(src, dst);            m_trans_inv.quad_to_quad(dst, src);        }        //--------------------------------------------------------------------        // Set the direct transformations, i.e., rectangle -> quadrangle        void rect_to_quad(double x1, double y1, double x2, double y2,                           const double* quad)        {            double src[8];            src[0] = src[6] = x1;            src[2] = src[4] = x2;            src[1] = src[3] = y1;            src[5] = src[7] = y2;            quad_to_quad(src, quad);        }        //--------------------------------------------------------------------        // Set the reverse transformations, i.e., quadrangle -> rectangle        void quad_to_rect(const double* quad,                           double x1, double y1, double x2, double y2)        {            double dst[8];            dst[0] = dst[6] = x1;            dst[2] = dst[4] = x2;            dst[1] = dst[3] = y1;            dst[5] = dst[7] = y2;            quad_to_quad(quad, dst);        }        //--------------------------------------------------------------------        // Check if the equations were solved successfully        bool is_valid() const { return m_trans_dir.is_valid(); }        //----------------------------------------------------------------        void begin(double x, double y, unsigned len)        {            m_iterator = m_trans_dir.begin(x, y, 1.0);            double xt = m_iterator.x;            double yt = m_iterator.y;            double dx;            double dy;            const double delta = 1/double(subpixel_scale);            dx = xt + delta;            dy = yt;            m_trans_inv.transform(&dx, &dy);            dx -= x;            dy -= y;            int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;            dx = xt;            dy = yt + delta;            m_trans_inv.transform(&dx, &dy);            dx -= x;            dy -= y;            int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;            x += len;            xt = x;            yt = y;            m_trans_dir.transform(&xt, &yt);            dx = xt + delta;            dy = yt;            m_trans_inv.transform(&dx, &dy);            dx -= x;            dy -= y;            int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;            dx = xt;            dy = yt + delta;            m_trans_inv.transform(&dx, &dy);            dx -= x;            dy -= y;            int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;            m_scale_x = dda2_line_interpolator(sx1, sx2, len);            m_scale_y = dda2_line_interpolator(sy1, sy2, len);        }        //----------------------------------------------------------------        void resynchronize(double xe, double ye, unsigned len)        {            // Assume x1,y1 are equal to the ones at the previous end point             int sx1 = m_scale_x.y();            int sy1 = m_scale_y.y();            // Calculate transformed coordinates at x2,y2             double xt = xe;            double yt = ye;            m_trans_dir.transform(&xt, &yt);            const double delta = 1/double(subpixel_scale);            double dx;            double dy;            // Calculate scale by X at x2,y2            dx = xt + delta;            dy = yt;            m_trans_inv.transform(&dx, &dy);            dx -= xe;            dy -= ye;            int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;            // Calculate scale by Y at x2,y2            dx = xt;            dy = yt + delta;            m_trans_inv.transform(&dx, &dy);            dx -= xe;            dy -= ye;            int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;            // Initialize the interpolators            m_scale_x = dda2_line_interpolator(sx1, sx2, len);            m_scale_y = dda2_line_interpolator(sy1, sy2, len);        }        //----------------------------------------------------------------        void operator++()        {            ++m_iterator;            ++m_scale_x;            ++m_scale_y;        }        //----------------------------------------------------------------        void coordinates(int* x, int* y) const        {            *x = iround(m_iterator.x * subpixel_scale);            *y = iround(m_iterator.y * subpixel_scale);        }        //----------------------------------------------------------------        void local_scale(int* x, int* y)        {            *x = m_scale_x.y();            *y = m_scale_y.y();        }        //----------------------------------------------------------------        void transform(double* x, double* y) const        {            m_trans_dir.transform(x, y);        }            private:        trans_type             m_trans_dir;        trans_type             m_trans_inv;        iterator_type          m_iterator;        dda2_line_interpolator m_scale_x;        dda2_line_interpolator m_scale_y;    };

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?