Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
462
3party/agg/agg_span_interpolator_persp.h
Normal file
462
3party/agg/agg_span_interpolator_persp.h
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//============================================span_interpolator_persp_lerp
|
||||
template<unsigned SubpixelShift = 8>
|
||||
class span_interpolator_persp_lerp
|
||||
{
|
||||
public:
|
||||
typedef trans_perspective trans_type;
|
||||
enum subpixel_scale_e
|
||||
{
|
||||
subpixel_shift = SubpixelShift,
|
||||
subpixel_scale = 1 << subpixel_shift
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
span_interpolator_persp_lerp() {}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Arbitrary quadrangle transformations
|
||||
span_interpolator_persp_lerp(const double* src, const double* dst)
|
||||
{
|
||||
quad_to_quad(src, dst);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Direct transformations
|
||||
span_interpolator_persp_lerp(double x1, double y1,
|
||||
double x2, double y2,
|
||||
const double* quad)
|
||||
{
|
||||
rect_to_quad(x1, y1, x2, y2, quad);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Reverse transformations
|
||||
span_interpolator_persp_lerp(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)
|
||||
{
|
||||
// Calculate transformed coordinates at x1,y1
|
||||
double xt = x;
|
||||
double yt = y;
|
||||
m_trans_dir.transform(&xt, &yt);
|
||||
int x1 = iround(xt * subpixel_scale);
|
||||
int y1 = iround(yt * subpixel_scale);
|
||||
|
||||
double dx;
|
||||
double dy;
|
||||
const double delta = 1/double(subpixel_scale);
|
||||
|
||||
// Calculate scale by X at x1,y1
|
||||
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;
|
||||
|
||||
// Calculate scale by Y at x1,y1
|
||||
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;
|
||||
|
||||
// Calculate transformed coordinates at x2,y2
|
||||
x += len;
|
||||
xt = x;
|
||||
yt = y;
|
||||
m_trans_dir.transform(&xt, &yt);
|
||||
int x2 = iround(xt * subpixel_scale);
|
||||
int y2 = iround(yt * subpixel_scale);
|
||||
|
||||
// Calculate scale by X at x2,y2
|
||||
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;
|
||||
|
||||
// Calculate scale by Y at x2,y2
|
||||
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;
|
||||
|
||||
// Initialize the interpolators
|
||||
m_coord_x = dda2_line_interpolator(x1, x2, len);
|
||||
m_coord_y = dda2_line_interpolator(y1, y2, len);
|
||||
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 x1 = m_coord_x.y();
|
||||
int y1 = m_coord_y.y();
|
||||
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);
|
||||
int x2 = iround(xt * subpixel_scale);
|
||||
int y2 = iround(yt * subpixel_scale);
|
||||
|
||||
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_coord_x = dda2_line_interpolator(x1, x2, len);
|
||||
m_coord_y = dda2_line_interpolator(y1, y2, len);
|
||||
m_scale_x = dda2_line_interpolator(sx1, sx2, len);
|
||||
m_scale_y = dda2_line_interpolator(sy1, sy2, len);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void operator++()
|
||||
{
|
||||
++m_coord_x;
|
||||
++m_coord_y;
|
||||
++m_scale_x;
|
||||
++m_scale_y;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
void coordinates(int* x, int* y) const
|
||||
{
|
||||
*x = m_coord_x.y();
|
||||
*y = m_coord_y.y();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
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;
|
||||
dda2_line_interpolator m_coord_x;
|
||||
dda2_line_interpolator m_coord_y;
|
||||
dda2_line_interpolator m_scale_x;
|
||||
dda2_line_interpolator m_scale_y;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue