复变用于图片映射

复变用于图片映射,简单说,就是把复变函数定义域的图像剪切并映射到值域相应位置。

有什么实际用途吗?目前已经发现的用途:让我开心。哈哈哈哈哈

如图e的z次方映射

用一个工具用途的类来操作,专门用来映射图像,自动识别并适应图像大小,生成图像的大小可调,其他细节修饰方面的有待优化。

因为功能刚刚出炉,所以各方面都比较槽一点,但保证绝对完全可以用,基于QT5.7.1, 下面是代码,如果它能帮到你,就拿走吧!

//    grid_view.h
#ifndef GRID_VIEW_H
#define GRID_VIEW_H
#include "cplx_core.h"
#include <QImage>

class grid_view
{
public:
    typedef QImage Img;
    typedef region_const<Cplx> RegCplx;
    typedef region_const<QImage> RegImg;
    typedef _geometry<creal> Geometry;
    typedef mapping_refer<_cplx<creal>>::fun_type funlp;

    grid_view();
    void set(RegCplx seed, RegCplx field = RegCplx(), Img src = Img(), funlp fun = nullptr);  //
    void setSeed(RegCplx seed); //设置定义域
    void setFun(funlp fun);     //  映射函数
    void setImg(Img img);       //

    //
    void mapping();         //  映射动作
    void clipImg(void);     //  裁剪动作
    Img pasteImg(creal scl = 1);//  粘贴动作

    //
    Geometry seedGeometry();    //  计算seed范围
    Geometry fieldGeometry();   //  计算field范围
    void saveImgClip(QString path); //  保存所有裁剪到本地路径

public:
    RegCplx seed;
    RegCplx field;
    RegImg img_clip;
    Img  src;
    funlp fun;  //  映射函数指针

};

#endif // GRID_VIEW_H





//        grid_view.cpp
#include "grid_view.h"
#include <QPainter>
#include <QDebug>

QString qqstring(const QTransform& trans)
{
    QString str("QTransform >>  (");
    str += QString::number(trans.m11()) + "  ";
    str += QString::number(trans.m12()) + "  ";
    str += QString::number(trans.m13()) + "),  (";
    str += QString::number(trans.m21()) + "  ";
    str += QString::number(trans.m22()) + "  ";
    str += QString::number(trans.m23()) + "),  (";
    str += QString::number(trans.m31()) + "  ";
    str += QString::number(trans.m32()) + "  ";
    str += QString::number(trans.m33()) + "); ";

    return str;
}
grid_view::grid_view()
{

}

void grid_view::set(grid_view::RegCplx seed, grid_view::RegCplx field, grid_view::Img src, grid_view::funlp fun)
{
    this->seed = seed;
    this->field= field;
    this->src  = src;
    this->fun= fun;
    this->img_clip = RegImg(seed.rows, seed.cols);
}
void grid_view::setSeed(grid_view::RegCplx seed)
{
    this->seed = seed;
}
void grid_view::setFun(grid_view::funlp fun)
{
    this->fun = fun;
}
void grid_view::setImg(grid_view::Img img)
{
    this->src = img;
}
void grid_view::mapping()
{
    mappingMapped(seed, field, fun);
}

void grid_view::clipImg(void)
{// 所用资源:图片、seed、img_clip
    auto geo = seedGeometry();
    //  保形划分
    creal rate/*局部伸扭的放大倍数*/ = (creal)geo.width / src.width() > (creal)geo.height / src.height()
            ? (creal)src.width()/geo.width
            : (creal)src.height()/geo.height;

    Img tmp;
    QPainter paint;
    Coor tl,
            br;
    creal side,
            rad;
    img_clip = RegImg(seed.rows-1, seed.cols-1).clone();/*网格数为锚点数-1*/    /*warning! 数据结构的operator=未释放之前内存*/
    for(int r = 0; r<img_clip.rows; ++r){
        for(int c = 0; c<img_clip.cols; ++c){
        /*对顶点坐标*/tl = cto_coor(seed(r, c));
                    br = cto_coor(seed(r+1, c+1));
        /*边长*/side = (abs(br.x-tl.x) + abs(br.y-tl.y))/2;/*取边长平均值*/
        /*旋转角度*/rad = cradian(br - tl) + Pi/4;
        tmp = QImage(rate*side+1, rate*side+1, QImage::Format_RGB16);   //  拒绝四舍五入
//        qDebug() << "ting jian ni de sy" << tmp.size() << side << rate;
        paint.begin(&tmp);paint.save();
        paint.setTransform(QTransform(
                               1,                    0,               0,
                               0,                    1,               0,
                               0,                    0,               1
                               )*QTransform(
                               cos(rad), -sin(rad),
                               sin(rad), cos(rad),
                               (-tl.x+geo.x)*rate,        (tl.y-geo.y)*rate
                               ));

        paint.drawImage(0, 0, src);
        img_clip(r, c) = tmp.copy();
        paint.restore();paint.end();
        }
    }
}
grid_view::Img grid_view::pasteImg(creal scl)
{
    auto geo = seedGeometry(),
            geoField = fieldGeometry();
    //  保形划分
    creal rate/*总放大倍数*/ = (creal)geo.width / src.width() > (creal)geo.height / src.height()
            ? (creal)src.width()/geo.width
            : (creal)src.height()/geo.height;

    Img dst(geoField.width*rate/scl, geoField.height*rate/scl, QImage::Format_RGB16);
    qDebug() << rate << geoField.width << geoField.height << dst;
    if(dst.isNull())
        return dst;
    QPainter paint(&dst);
    Coor tl,
            br,
            stl,
            sbr;
    creall sidex,
            sidey,
            rad;
    for(int r = 0; r<img_clip.rows; ++r){
        for(int c = 0; c<img_clip.cols; ++c){
            /*象点坐标*/tl = cto_coor(field(r, c)),
                       br = cto_coor(field(r+1, c+1)),
            /*原象坐标*/stl = cto_coor(seed(r, c)),
                       sbr = cto_coor(seed(r+1, c+1));
            /*边长*/sidex = abs(br.x-tl.x),
                    sidey = abs(br.y-tl.y);/*取边长平均值*/
            /*旋转角度*/rad = cradian(br - tl) + Pi/4;
            paint.setTransform(QTransform(
                                    (creall)cos(rad)*sidex/abs(stl.x-sbr.x),    sin(rad),                                   0,
                                    -sin(rad),                                  (creall)cos(rad)*sidey/abs(stl.y-sbr.y),    0,
                                    (creall)(tl.x-geoField.x)*rate,                  (creall)(-tl.y+geoField.y)*rate,                 scl
                                   ));
            paint.drawImage(0, 0, img_clip(r, c));
        }
    }
    paint.end();
    return dst;
}

grid_view::Geometry grid_view::seedGeometry()
{
    return geometry(seed);
}
grid_view::Geometry grid_view::fieldGeometry()
{
    return geometry(field);
}

void grid_view::saveImgClip(QString path)
{
    //  save img
    int amount = img_clip.amount();
    for(int i = 0; i<amount; ++i){
        img_clip.data[i].save(path + QString::number(i) + ".jpg");
//        qDebug() << path + QString::number(i) + ".jpg" << img_clip.data[i].size();
    }
}


    

当然仅有上面的还不可以直接运行,我写了一个复变操作的cplx_core基本库,上面的代码需要这个core的支持,当然这个本身是我自己写的所以使用中可能会有一些问题(目前我没发现),比如我的复数存储用的是radius和radian的值,直接导致很多运算耗时变高(比如+-),如果你有什么好的建议的话,欢迎和我交流qq2930007061

   1 /*    复数操作的核心模块(2018-03-03)
   2 *
   3 *    定义内容包括:
   4 *                基本复数、复数容器对象
   5 *                复函数对象
   6 *                2\3维函数定义域对象
   7 *
   8 *
   9 *    已使用及可兼容的接口包括:
  10 *
  11 *
  12 *
  13 *
  14 *
  15 *    dusty-cjh@qq.com
  16 */
  17 #ifndef CPLX_CORE
  18 #define CPLX_CORE
  19 #include <initializer_list>
  20 #include <stdexcept>
  21 #include <math.h>
  22 #include <string>
  23 
  24 #ifdef QT_CORE_LIB
  25 #include <QString>
  26 #include <QDebug>
  27 #endif
  28 
  29 using std::runtime_error;
  30 using std::initializer_list;
  31 using std::string;
  32 
  33 
  34 #define Pi 3.14159265358979323846
  35 #define E  2.71828182845904523536
  36 #define Cir (2*Pi)
  37 #define ROUND 360
  38 #define C_ANY_POINT    void*
  39 
  40 #define C_MOVE(x) (std::move((x)))
  41 #define RADIAN(x, y) std::atan2(y, x);
  42 #define ANGLE(rad)  (rad)/Cir*ROUND
  43 
  44 
  45 //    前置
  46 template<typename T> class cplx;
  47 template<typename _Tp> struct _cplx;
  48 template<typename _Ty> struct _coor;
  49 template<typename _Df> class region_mult;
  50 template<typename _Df> class region_const;
  51 
  52 
  53 
  54 //    type
  55 typedef double creal;
  56 typedef long double creall;
  57 typedef _cplx<creal> Cplx;    /*complex*/
  58 typedef _coor<creal> Coor;  /*cooridation*/
  59 typedef region_mult<creal> RegionMult;
  60 typedef region_const<creal> RegionConst;
  61 
  62 
  63 
  64 enum CBusiness{
  65     Row = 1,
  66     Col = 2
  67 };
  68 
  69 
  70 /*定义域参数方程 point type */
  71 template<typename _T> struct defintion_refer{
  72     typedef _cplx<_T>(*fun_type)(_T);
  73 };
  74 #define DEFINE_FUN(type)    static_cast<defintion_refer<type>::fun_type>
  75 /*映射函数 point type */
  76 template<typename _T> struct mapping_refer{
  77     typedef _T(*fun_type)(_T);
  78 };
  79 #define MAPPING_FUN(type)    static_cast<mapping_refer<type>::fun_type>
  80 
  81 
  82 
  83 
  84 
  85 
  86 //    base
  87 template<typename _Tp = creal>
  88 struct _cplx
  89 {
  90     _Tp r;    //    radius
  91     _Tp a;    //    radian
  92     inline _cplx operator*(const _cplx& c1)const{
  93         return{
  94             r*c1.r,
  95             a + c1.a
  96         };
  97     }
  98     inline _cplx operator*(_Tp x)const{
  99         return{
 100             r*x,
 101             a
 102         }
 103     }
 104     inline _cplx operator/(const _cplx& c1)const{
 105         return{
 106             r / c1.r,
 107             a - c1.a
 108         }
 109     };
 110     inline _cplx operator/(_Tp x)const{
 111         return{
 112             r / x,
 113             a
 114         }
 115     };
 116     inline _cplx operator+(const _cplx& c1)const{
 117         //    lose some radian
 118         _coor<_Tp> co = {
 119             r*cos(a) + c1.r*cos(c1.a),
 120             r*sin(a) + c1.r*sin(c1.a)
 121         };
 122 
 123         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 124         return{
 125             mold,
 126             (0 == mold ? 0 : asin(co.y / mold))
 127         };
 128     }
 129     inline _cplx operator+(_Tp x)const{
 130         //    lose some radian
 131         _coor<_Tp> co = {
 132             r*cos(a) + x,
 133             r*sin(a)
 134         };
 135 
 136         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 137         return{
 138             mold,
 139             (0 == mold ? 0 : asin(co.y / mold))
 140         };
 141     }
 142     inline _cplx operator-(const _cplx& c1)const{
 143         //    lose some radian
 144         _coor<_Tp> co = {
 145             r*cos(a) - c1.r*cos(c1.a),
 146             r*sin(a) - c1.r*sin(c1.a)
 147         };
 148 
 149         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 150         return{
 151             mold,
 152             (0 == mold ? 0 : asin(co.y / mold))
 153         };
 154     }
 155     inline _cplx operator-(_Tp x)const{
 156         //    lose some radian
 157         _coor<_Tp> co = {
 158             r*cos(a) - x,
 159             r*sin(a)
 160         };
 161 
 162         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 163         return{
 164             mold,
 165             (0 == mold ? 0 : asin(co.y / mold))
 166         };
 167     }
 168     inline _cplx& operator+=(const _cplx& c1){
 169         //    lose some radian
 170         _coor<_Tp> co = {
 171             r*cos(a) + c1.r*cos(c1.a),
 172             r*sin(a) + c1.r*sin(c1.a)
 173         };
 174 
 175         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 176         r = mold;
 177         a = (0 == mold ? 0 : asin(co.y / mold));
 178         return *this;
 179     }
 180     inline _cplx& operator+=(_Tp x){
 181         //    lose some radian
 182         _coor<_Tp> co = {
 183             r*cos(a) + x,
 184             r*sin(a)
 185         };
 186 
 187         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 188         r = mold;
 189         a = (0 == mold ? 0 : asin(co.y / mold));
 190         return *this;
 191     }
 192     inline _cplx& operator-=(const _cplx& c1){
 193         //    lose some radian
 194         _coor<_Tp> co = {
 195             r*cos(a) - c1.r*cos(c1.a),
 196             r*sin(a) - c1.r*sin(c1.a)
 197         };
 198 
 199         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 200         r = mold;
 201         a = (0 == mold ? 0 : asin(co.y / mold));
 202         return *this;
 203     }
 204     inline _cplx& operator-=(_Tp x){
 205         //    lose some radian
 206         _coor<_Tp> co = {
 207             r*cos(a) - x,
 208             r*sin(a)
 209         };
 210 
 211         _Tp mold = sqrt(pow(co.x, 2) + pow(co.y, 2));
 212         r = mold;
 213         a = (0 == mold ? 0 : asin(co.y / mold));
 214         return *this;
 215     }
 216     inline _cplx& operator*=(const _cplx& c1){
 217         r *= c1.r;
 218         a += c1.a;
 219 
 220         return *this;
 221     }
 222     inline _cplx& operator*=(_Tp x){
 223         r *= x;
 224 
 225         return *this;
 226     }
 227     inline _cplx& operator/=(const _cplx& c1){
 228         r /= c1.r;
 229         a -= c1.a;
 230 
 231         return *this;
 232     }
 233     inline _cplx& operator/=(_Tp x){
 234         r /= x;
 235 
 236         return *this;
 237     }
 238     inline bool operator==(const _cplx& c1)const{
 239         return (r == c1.r) && (a == c1.a);
 240     }
 241     inline bool operator!=(const _cplx& c1)const{
 242         return (r != c1.r) || (a != c1.a);
 243     }
 244 
 245     operator cplx<_Tp>(){
 246         return cplx<_Tp>(r, a);
 247     }
 248 
 249 };
 250 template<typename _Ty = creal>
 251 struct _coor
 252 {
 253     _Ty x;
 254     _Ty y;
 255     _coor& operator+=(const _coor&co){
 256         this->x += co.x;
 257         this->y += co.y;
 258 
 259         return *this;
 260     }
 261     _coor& operator-=(const _coor&co){
 262         this->x -= co.x;
 263         this->y -= co.y;
 264 
 265         return *this;
 266     }
 267 
 268     _coor operator+(const _coor&co)const{
 269         _coor Tmp = *this;
 270         Tmp += co;
 271 
 272         return Tmp;
 273     }
 274     _coor operator-(const _coor&co)const{
 275         _coor Tmp = *this;
 276         Tmp -= co;
 277 
 278         return Tmp;
 279     }
 280 
 281     operator string(){
 282         string cplx_str = string("coordinate(X:") + std::to_string(x)
 283             + string(", Y:") + std::to_string(y) + string(") ");
 284 
 285         return cplx_str;
 286     }
 287 #ifdef QT_CORE_LIB
 288     operator QString(){
 289         return QString("coordinate(X:") + QString::number(x) + QString(", Y:")
 290             + QString::number(y) + QString(") ");
 291     }
 292 #endif
 293 
 294 };
 295 template<typename _Geo>
 296 struct _geometry
 297 {
 298     _Geo x;
 299     _Geo y;
 300     _Geo width;
 301     _Geo height;
 302 };
 303 
 304 
 305 //    base function
 306 template<typename _T> _cplx<_T> cto_cplx(const _coor<_T>& c1){
 307     //    lose some radian
 308     _cplx<_T> cp;
 309     _T mold = sqrt(pow(c1.x, 2) + pow(c1.y, 2));
 310     cp.r = mold;
 311     cp.a = RADIAN(c1.x, c1.y);
 312 
 313     return cp;
 314 }
 315 template<typename _T> region_const<_cplx<_T>> cto_cplx(const region_const<_coor<_T>>& reg)
 316 {
 317     //    lose precision
 318     region_const<_cplx<_T>> dst = reg.clone();
 319     for (int i = 0; i < reg.rows*reg.cols; ++i)
 320         dst.data[i] = cto_cplx(reg.data[i]);
 321 
 322     return dst;
 323 }
 324 template<typename _T> _coor<_T>&& cto_coor(const _cplx<_T>& c1){
 325     //    lose some radian
 326     _coor<_T> co;
 327     co.x = c1.r*cos(c1.a);
 328     co.y = c1.r*sin(c1.a);
 329 
 330     return std::move(co);
 331 }
 332 template<typename _T> region_const<_coor<_T>> cto_coor(const region_const<_cplx<_T>>& reg)
 333 {
 334     //    lose precision
 335     region_const<_coor<_T>> dst = reg.clone();
 336     for (int i = 0; i < reg.rows*reg.cols; ++i)
 337         dst.data[i] = cto_coor(reg.data[i]);
 338 
 339     return dst;
 340 }
 341 /* @模 */
 342 template<typename _T> inline _T cmold(const _coor<_T>& c1){
 343     return sqrt(pow(c1.x, 2) + pow(c1.y, 2));
 344 }
 345 template<typename _T> inline _T cmold(const _cplx<_T>& c1){
 346     return c1.r;
 347 }
 348 /* @角度 */
 349 template<typename _T> inline _T cangle(const _coor<_T>& c1){
 350     return RADIAN(c1.x, c1.y) / Cir * 360;
 351 }
 352 template<typename _T> inline _T cangle(const _cplx<_T>& c1){
 353     return c1.a / Cir * ROUND;
 354 }
 355 /* @弧度 */
 356 template<typename _T> inline _T cradian(const _coor<_T>& c1){
 357     return RADIAN(c1.x, c1.y);
 358 }
 359 template<typename _T> inline _T cradian(const _cplx<_T>& c1){
 360     return c1.a;
 361 }
 362 /* @点乘 */
 363 template<typename _T> inline _T cdot(const _coor<_T>& c1, const _coor<_T>& c2){
 364     return c1.x*c2.x + c1.y*c2.y;
 365 }
 366 template<typename _T> inline _T cdot(const _cplx<_T>& c1, const _cplx<_T>& c2){
 367     _coor<_T> co1 = cto_coor(c1),
 368         co2 = cto_coor(c2);
 369 
 370     return co1.x*co2.x + co1.y*co2.y;
 371 }
 372 /* @叉乘 */
 373 template<typename _T> inline _T ccross(const _coor<_T>& c1, const _coor<_T>& c2){
 374     //    cross(c1,c2)  equal  x1*y2-x2*y1
 375     return c1.x*c2.y - c1.y*c2.x;
 376 }
 377 template<typename _T> inline _T ccross(const _cplx<_T>& c1, const _cplx<_T>& c2){
 378     //    cross(c1,c2)  equal  x1*y2-x2*y1
 379     _coor<_T> co1 = cto_coor(c1),
 380         co2 = cto_coor(c2);
 381 
 382     return co1.x*co2.y - co1.y*co2.x;
 383 }
 384 
 385 /* @复数对象 */
 386 template<typename _T = creal>
 387 class cplx : public _cplx<_T>
 388 {
 389 public:
 390     typedef _T            refer;
 391     typedef const _T&    const_refer;
 392     typedef _T&&        move_refer;
 393     typedef _cplx<_T>        base_refer;
 394     typedef const _cplx<_T>    const_base_refer;
 395     typedef _cplx<_T>&&        move_base_refer;
 396     cplx(refer x = 0)
 397         :_cplx({ x, 0 })
 398     {}
 399     cplx(refer r, refer a)
 400         :_cplx({ r, a })
 401     {}
 402     cplx(const_base_refer c1)
 403         :_cplx(c1)
 404     {}
 405     cplx(move_base_refer c1)
 406         :_cplx(std::move(c1))
 407     {}
 408     cplx& operator=(_cplx<_T>&& c1){
 409         this->a = C_MOVE(c1.a);
 410         this->r = C_MOVE(c1.r);
 411 
 412         return *this;
 413     }
 414     cplx& operator=(const cplx<_T>& c1){
 415         this->a = c1.a;
 416         this->r = c1.r;
 417 
 418         return *this;
 419     }
 420     cplx& operator=(cplx<_T>&& c1){
 421         this->a = std::move(c1.a);
 422         this->r = std::move(c1.r);
 423 
 424         return *this;
 425     }
 426 
 427 
 428     void set_coor(refer x, refer y){
 429         this->r = sqrt(pow(x, 2) + pow(y, 2));
 430         this->a = asin(y / this->r);
 431     }
 432     int arg(void)const{
 433         return static_cast<int>(a / Cir);
 434     }
 435 
 436     string to_string(void){
 437         string cplx_str = string("complex(Radius:") + std::to_string(r)
 438             + string(", Angle:") + std::to_string(a / Cir * 360) + string(") ");
 439 
 440         return cplx_str;
 441     }
 442 #ifdef QT_CORE_LIB
 443     QString to_qstring(void){
 444         return QString("complex(Radius:") + QString::number(r) + QString(", Angle:")
 445             + QString::number(a / Cir * 360) + QString(") ");
 446     }
 447 #endif
 448 
 449 
 450     static const_base_refer i;
 451 };
 452 template<typename _T> const _cplx<_T> cplx<_T>::i = { 1, Pi / 2 };
 453 
 454 
 455 //--------------------------------------- defintion ---------------------------------------------
 456 
 457 
 458 template<typename T>
 459 struct twist_stretch
 460 {
 461     T x;
 462     T y;
 463     T rotate;
 464     T x_scale;
 465     T y_scale;
 466     T prec;
 467 };
 468 typedef twist_stretch<creal> Twitch;
 469 
 470 
 471 
 472 //    regulrary
 473 template<typename _T> std::string cto_string(_T& c)
 474 {
 475     return std::to_string(c);
 476 }
 477 template<typename _T> std::string cto_string(_cplx<_T>& c)
 478 {
 479     _coor<_T> co = cto_coor(c);
 480     string cplx_str = string("complex(X:") + std::to_string(co.x)
 481         + string(", Y:") + std::to_string(co.y) + string(") ");
 482 
 483     return cplx_str;
 484 }
 485 template<typename _T> std::string cto_string(region_const<_T>& reg)
 486 {
 487     string str;
 488     for (int r = 0; r < reg.rows; ++r){
 489         for (int c = 0; c < reg.cols; ++c){
 490             str += "\t";
 491             str += std::to_string(reg(r, c));
 492         }
 493         str += '\n';
 494     }
 495 
 496     return str;
 497 }
 498 template<typename _T> std::string cto_string(region_const<_cplx<_T>>& reg)
 499 {
 500     string str;
 501     for (int r = 0; r < reg.rows; ++r){
 502         for (int c = 0; c < reg.cols; ++c){
 503             str += "\t";
 504             str += cto_string(reg(r, c));
 505         }
 506         str += '\n';
 507     }
 508 
 509     return str;
 510 }
 511 #ifdef QT_CORE_LIB
 512 template<typename _T> QString cto_qstring(region_const<_T>& reg)
 513 {
 514     QString str;
 515     for (int r = 0; r < reg.rows; ++r){
 516         for (int c = 0; c < reg.cols; ++c){
 517             str += '\t';
 518             str += QString::number(reg(r, c));
 519         }
 520         str += '\n';
 521     }
 522 
 523     return str;
 524 }
 525 template<typename _T> QString cto_qstring(region_const<_cplx<_T>>& reg)
 526 {
 527     QString str;
 528     for (int r = 0; r < reg.rows; ++r){
 529         for (int c = 0; c < reg.cols; ++c){
 530             str += "\t";
 531             str += cto_qstring(reg(r, c));
 532             str += cto_qstring(reg(r, c));
 533         }
 534         str += '\n';
 535     }
 536 
 537     return str;
 538 }
 539 template<typename _T> QString cto_qstring(_T& c)
 540 {
 541     return QString::number(c);
 542 }
 543 template<typename _T> QString cto_qstring(_cplx<_T>& c)
 544 {
 545     _coor<_T> co = cto_coor(c);
 546     QString cplx_str = QString("complex(X:") + QString::number(co.x)
 547         + QString(", Y:") + QString::number(co.y) + QString(") ");
 548 
 549     return cplx_str;
 550 }
 551 #endif
 552 
 553 
 554 
 555 
 556 //    defintion
 557 /*! 网格定义域 */
 558 template<typename _T> region_const<_cplx<_T>> grid_region(_coor<_T> tl, _coor<_T> br, _T prec = 0.01){
 559     //                        网格区域 grid_region(左上顶点坐标, 右下顶点坐标, 精度 = 0.01)
 560     int r = static_cast<int>(abs(tl.y - br.y) / prec)+1,
 561         c = static_cast<int>(abs(tl.x - br.x) / prec)+1;
 562 
 563 
 564     region_const<_cplx<_T>> region(r, c);
 565     _cplx<_T>* p = region.data;
 566     for (int i = 0; i < r; ++i){
 567         for (int j = 0; j < c; ++j){
 568             *p++ = cto_cplx(_coor<_T>{ tl.x + j*prec, tl.y - i*prec });
 569         }
 570     }
 571 
 572     return region;
 573 }
 574 /*! 椭圆定义域 */
 575 template<typename _T> region_const<_cplx<_T>> ellipse_region(_T a, _T b, _T angle_prec = 0.01, _T len_prec = 0.1)
 576 {//                        椭圆网格区域    ellipse_region (长轴,    短轴,    精度  =  0.01 );
 577     region_const<_cplx<_T>> reg(Cir / angle_prec, (a > b ? b : a) / len_prec);
 578     _T  a_step = a / reg.cols,
 579         b_step = b / reg.cols;
 580     for (int r = 0; r<reg.rows; ++r){
 581         for (int c = 0; c<reg.cols; ++c){
 582             reg(r, c) = cto_cplx(_coor<_T>{
 583                 a_step*c*cos(angle_prec*r),
 584                     b_step*c*sin(angle_prec*r)
 585             });
 586         }
 587     }
 588 
 589     return reg;
 590 }
 591 
 592 
 593 
 594 
 595 //info
 596 template<typename _T> _geometry<_T> geometry(region_const<_cplx<_T>>& reg){
 597     _coor<_T> co = cto_coor(reg.data[0]);
 598     _T      x_min = co.x,
 599             x_max = co.x,
 600             y_min = co.y,
 601             y_max = co.y;
 602     for(int i = 0; i<reg.rows*reg.cols; ++i){
 603         co = cto_coor(reg.data[i]);
 604         if(co.x > x_max)
 605             std::swap(co.x, x_max);
 606         else if(co.x < x_min)
 607             std::swap(co.x, x_min);
 608         if(co.y > y_max)
 609             std::swap(co.y, y_max);
 610         else if(co.y < y_min)
 611             std::swap(co.y, y_min);
 612     }
 613 
 614     _geometry<_T> g = {
 615         x_min,
 616         y_max,
 617         abs(x_max-x_min),
 618         abs(y_max - y_min)
 619     };
 620     return g;
 621 }
 622 
 623 
 624 
 625 
 626 
 627 template<typename _Cnt>
 628 class _vec
 629 {
 630 public:
 631     typedef _Cnt        refer;
 632     typedef _Cnt&        using_refer;
 633     typedef const _Cnt& const_refer;
 634     typedef _Cnt&&        move_refer;
 635     explicit _vec(int length = 0, refer* d = nullptr)
 636         :len(length),
 637         data(d)
 638     {
 639         if (d)
 640             d = nullptr;
 641         else
 642             data = length ? new refer[static_cast<int>(length)] : nullptr;
 643         raise = 0;
 644     }
 645     _vec(_vec&& v)
 646         :len(std::move(v.len)),
 647         data(std::move(v.data)),
 648         raise(std::move(v.raise))
 649     {}
 650     _vec(const _vec&) = delete;
 651     _vec(initializer_list<refer> il){
 652         data = nullptr;
 653         this->operator =(il);
 654     }
 655     ~_vec(){
 656         delete []data;
 657     }
 658 
 659     _vec& operator=(_vec&& v){
 660         len = std::move(v.len);
 661         data = std::move(v.data);
 662         raise = std::move(v.raise);
 663 
 664         return *this;
 665     }
 666     _vec& operator=(const _vec& v){
 667         this->len = v.len;
 668         this->raise = v.raise;
 669 
 670         if (data)
 671             delete[]data;
 672         data = new refer[len + raise];
 673         for (int i = 0; i < len; ++i)
 674             data[i] = v.data[i];
 675 
 676         return *this;
 677     }
 678     _vec& operator=(initializer_list<refer> il){
 679         resize(il.size());
 680         refer* p = data;
 681         for (auto beg = il.begin(); beg != il.end(); ++beg, ++p)
 682             *p = *beg;
 683 
 684         return *this;
 685     }
 686 
 687 
 688 
 689     const_refer at(int i)const{
 690         return data[i];
 691     }
 692     refer* atP(int i){
 693         return &data[i];
 694     }
 695     using_refer operator[](int i){
 696         return data[i];
 697     }
 698 
 699     //    move
 700     void append(const _vec& v){
 701         if (v.len > raise){
 702             int length = (int)(len + v.len);
 703             raise = static_cast<int>(length*0.5);
 704 
 705             refer* d = new refer[length + raise];
 706             for (int i = 0; i < length; ++i){
 707                 d[i] = data[i];
 708             }
 709             for (int i = len; i < len + v.len; ++i){
 710                 d[i] = v.data[i - len];
 711             }
 712 
 713             delete []data;
 714             data = d;
 715             len = length;
 716         }
 717         else{
 718             for (int i = len; i < len + v.len; ++i){
 719                 data[i] = v.data[i - len];
 720             }
 721             raise -= v.len;
 722         }
 723     }
 724     void append(const refer& c){
 725         if (1 > raise){
 726             raise = static_cast<int>((1+len)*0.5);
 727 
 728             refer* d = new refer[len + 1 + raise];
 729             for (int i = 0; i < len; ++i){
 730                 d[i] = data[i];
 731             }
 732             d[len] = c;
 733 
 734             delete[]data;
 735             data = d;
 736             ++len;
 737         }
 738         else{
 739             data[len] = c;
 740             raise -= 1;
 741         }
 742     }
 743     void remove(int front, int endafter){
 744         if (endafter < len){
 745             for (int i = endafter; i < len; ++i){
 746                 data[front + i - endafter] = data[i];
 747             }
 748             len -= endafter - front;
 749             raise += endafter - front;
 750         }
 751         else{
 752             len = front;
 753             raise += endafter - front;
 754         }
 755     }
 756     void insert(int before, const _vec& v){
 757         int length = static_cast<int>(len + v.len);
 758         refer* d = new refer[static_cast<int>(length*1.5)];
 759         for (int i = 0; i < before; ++i){
 760             d[i] = data[i];
 761         }
 762         for (int i = 0; i < v.len; ++i){
 763             d[before + i] = v.data[i];
 764         }
 765         for (int i = 0; i < len - before; ++i){
 766             d[before + v.len + i] = data[before + i];
 767         }
 768 
 769         delete []data;
 770         data = d;
 771         len = length;
 772         raise = static_cast<int>(length*0.5);
 773     }
 774 
 775 
 776     //    redo
 777     void clear(void){
 778         len = raise = 0;
 779         delete []data;
 780         data = nullptr;
 781     }
 782     void resize(int size){
 783         len = size;
 784         raise = 0;
 785         delete []data;
 786         data = new refer[size];
 787     }
 788     _vec clone(void){
 789         _vec cln(this->len);
 790         for (int i = 0; i < len; ++i){
 791             cln[i] = (*this)[i];
 792         }
 793     }
 794 
 795 public:
 796     refer* data;
 797     int len;
 798     int raise;
 799 
 800 };
 801 
 802 template<typename _Df>
 803 class region_mult
 804 {
 805 public:
 806     friend class region_const<_Df>;
 807     typedef _Df            refer;
 808     typedef _Df&        using_refer;
 809     typedef const _Df&    const_refer;
 810     typedef _Df&&        move_refer;
 811     typedef _vec<_vec<_Df>>    vec_type;
 812     typedef _vec<_Df>&        row_refer;
 813 
 814 
 815     //  iter
 816     class row_mult
 817     {
 818     public:
 819         explicit row_mult(int r, region_mult& reg)
 820             :row(r),
 821             reg(reg)
 822         {}
 823         row_mult(const row_mult& rows)
 824             :row(rows.row),
 825             reg(rows.reg)
 826         {}
 827         row_mult(const region_mult& reg){
 828             setValue(reg);
 829         }
 830         ~row_mult(){
 831 
 832         }
 833 
 834         using_refer operator[](int i){
 835             return reg(row, i);
 836         }
 837         row_mult& operator=(const row_mult& rows){
 838             this->row = rows.row;
 839             this->reg = rows.reg;
 840         }
 841         row_mult& operator=(const region_mult& reg){
 842             setValue(reg);
 843         }
 844         row_mult& operator*=(refer n){
 845             for (int i = 0; i<reg.cols; ++i){
 846                 (*this)[i] *= n;
 847             }
 848         }
 849         row_mult& operator/=(refer n){
 850             for (int i = 0; i<reg.cols; ++i){
 851                 (*this)[i] /= n;
 852             }
 853         }
 854         row_mult& operator+=(refer n){
 855             for (int i = 0; i<reg.cols; ++i){
 856                 (*this)[i] += n;
 857             }
 858         }
 859         row_mult& operator-=(refer n){
 860             for (int i = 0; i<reg.cols; ++i){
 861                 (*this)[i] -= n;
 862             }
 863         }
 864         void setValue(const row_mult& rows){
 865             for (int i = 0; i<reg.cols; ++i)
 866                 (*this)[i] = rows[i];
 867         }
 868         void setValue(const region_mult& reg){
 869             if (reg.rows != 1 || reg.cols != this->reg.cols)
 870                 throw(runtime_error("region_mult is not confitrable for row_mult"));
 871             for (int i = 0; i<reg.cols; ++i)
 872                 (*this)[i] = reg(0, i);
 873         }
 874 
 875 
 876     public:
 877         int row;
 878         region_mult& reg;
 879     };
 880     class col_mult
 881     {
 882     public:
 883         explicit col_mult(int r, region_mult& reg)
 884             :col(r),
 885             reg(reg)
 886         {}
 887         col_mult(const col_mult& cols)
 888             :col(cols.col),
 889             reg(cols.reg)
 890         {}
 891 
 892     public:
 893         int col;
 894         region_mult& reg;
 895     };
 896 
 897 
 898 
 899 
 900 
 901 
 902     explicit region_mult(int rows = 0, int cols = 0)
 903     {
 904         resize(rows, cols);
 905     }
 906 
 907     //    read
 908     using_refer operator()(int r, int c){
 909         return v.data[r].data[c];
 910     }
 911     const_refer at(int r, int c){
 912         return v.data[r].data[c];
 913     }
 914 
 915     //
 916     void resize(int r, int c){
 917         v.resize(r);
 918         for (int i = 0; i < v.len; ++i)
 919             v.data[i].resize(c);
 920         rows = r;
 921         cols = c;
 922     }
 923     region_mult rowClone(int r){
 924         region_mult<_Df> reg(1, cols);
 925         reg.v = v[r].clone();
 926 
 927         return reg;
 928     }
 929     region_mult colClone(int c){
 930         region_mult<_Df> reg(rows, 1);
 931         for (int i = 0; i<rows; ++i){
 932             reg[i] = this->operator ()(i, c);
 933         }
 934 
 935         return reg;
 936     }
 937     row_mult row(int r){
 938         return row_mult(r, *this);
 939     }
 940     col_mult col(int c){
 941         return col_mult(c, *this);
 942     }
 943 
 944 public:
 945     int rows;
 946     int cols;
 947     _vec<_vec<_Df>> v;
 948 
 949 };
 950 
 951 template<typename _Df>
 952 class region_const
 953 {
 954 public:
 955     friend class region_mult<_Df>;
 956     typedef _Df            refer;
 957     typedef refer*        pointer;
 958     typedef refer&        using_refer;
 959     typedef const refer&const_refer;
 960     typedef refer&&        move_refer;
 961 
 962 
 963     //    row iterator
 964     class row_iter
 965     {
 966     public:
 967         explicit row_iter(int r, region_const& vec)
 968             :row(r),
 969             vec(vec),
 970             it(&vec.data[r*vec.cols])
 971         {}
 972         row_iter(const row_iter& iter)
 973             :row(iter.row),
 974             it(iter.it),
 975             vec(iter.vec)
 976         {}
 977         row_iter(row_iter&& iter)
 978             :row(C_MOVE(iter.row)),
 979             it(C_MOVE(iter.it)),
 980             vec(C_MOVE(iter.vec))
 981         {}
 982         row_iter& operator=(const row_iter& iter){
 983             row = iter.row;
 984             it = iter.it;
 985             vec = iter.vec;
 986         }
 987         row_iter& operator=(row_iter&& iter){
 988             row = std::move(iter.row);
 989             it = std::move(iter.it);
 990             vec = std::move(iter.vec);
 991         }
 992 
 993         row_iter& operator+=(int i){
 994             it += i;
 995 
 996             return *this;
 997         }
 998         row_iter& operator-=(int i){
 999             it -= i;
1000 
1001             return *this;
1002         }
1003         row_iter operator+(int i){
1004             row_iter Tmp = *this;
1005             Tmp += i;
1006 
1007             return Tmp;
1008         }
1009         row_iter operator-(int i){
1010             row_iter Tmp = *this;
1011             Tmp -= i;
1012 
1013             return Tmp;
1014         }
1015         row_iter& operator++(void){
1016             *this += 1;
1017 
1018             return *this;
1019         }
1020         row_iter operator++(int){
1021             row_iter Tmp = *this;
1022             *this += 1;
1023 
1024             return Tmp;
1025         }
1026         row_iter& operator--(void){
1027             *this -= 1;
1028 
1029             return *this;
1030         }
1031         row_iter operator--(int){
1032             row_iter Tmp = *this;
1033             *this -= 1;
1034 
1035             return Tmp;
1036         }
1037 
1038         using_refer operator*(void){
1039             return *it;
1040         }
1041         using_refer operator[](int i){
1042             return vec(row, i);
1043         }
1044         bool operator==(const row_iter& iter){
1045             return (it == iter.it);
1046         }
1047         bool operator!=(const row_iter& iter){
1048             return (it != iter.it);
1049         }
1050 
1051 
1052     private:
1053         int row;
1054         pointer it;
1055         region_const& vec;
1056 
1057     };
1058     //    col iterator
1059     class col_iter
1060     {
1061     public:
1062         explicit col_iter(int c, region_const& vec)
1063             :col(c),
1064             vec(vec),
1065             it(&vec.data[c])
1066         {}
1067         col_iter(const col_iter& iter)
1068             :col(iter.col),
1069             it(iter.it),
1070             vec(iter.vec)
1071         {}
1072         col_iter(col_iter&& iter)
1073             :col(C_MOVE(iter.col)),
1074             it(C_MOVE(iter.it)),
1075             vec(C_MOVE(iter.vec))
1076         {}
1077         col_iter& operator=(const col_iter& iter){
1078             col = iter.col;
1079             it = iter.it;
1080             vec = iter.vec;
1081         }
1082         col_iter& operator=(col_iter&& iter){
1083             col = std::move(iter.col);
1084             it = std::move(iter.it);
1085             vec = std::move(iter.vec);
1086         }
1087 
1088         col_iter& operator+=(int i){
1089             it += vec.cols*i;
1090 
1091             return *this;
1092         }
1093         col_iter& operator-=(int i){
1094             it -= vec.cols*i;
1095 
1096             return *this;
1097         }
1098         col_iter operator+(int i){
1099             col_iter Tmp = *this;
1100             Tmp += i;
1101 
1102             return Tmp;
1103         }
1104         col_iter operator-(int i){
1105             col_iter Tmp = *this;
1106             Tmp -= i;
1107 
1108             return Tmp;
1109         }
1110         col_iter& operator++(void){
1111             *this += 1;
1112 
1113             return *this;
1114         }
1115         col_iter operator++(int){
1116             col_iter Tmp = *this;
1117             *this += 1;
1118 
1119             return Tmp;
1120         }
1121         col_iter& operator--(void){
1122             *this -= 1;
1123 
1124             return *this;
1125         }
1126         col_iter operator--(int){
1127             col_iter Tmp = *this;
1128             *this -= 1;
1129 
1130             return Tmp;
1131         }
1132 
1133         using_refer operator*(void){
1134             return *it;
1135         }
1136         using_refer operator[](int i){
1137             return vec(i, col);
1138         }
1139         bool operator==(const col_iter& iter){
1140             return (it == iter.it);
1141         }
1142         bool operator!=(const col_iter& iter){
1143             return (it != iter.it);
1144         }
1145 
1146 
1147     private:
1148         int col;
1149         pointer it;
1150         region_const& vec;
1151 
1152     };
1153 
1154 
1155     explicit region_const(int r = 0, int c = 0, pointer d = nullptr)
1156         :rows(r),
1157         cols(c),
1158         data(d)
1159     {
1160         //    row first
1161         if (nullptr == data)
1162             data = new refer[r*c];
1163     }
1164     region_const(region_const& reg)
1165         :rows(reg.rows),
1166         cols(reg.cols),
1167         data(reg.data)
1168     {
1169         if (nullptr == data)
1170             data = new refer[rows*cols];
1171         else{
1172             reg.data = nullptr;
1173             reg.rows = reg.cols = 0;
1174         }
1175     }
1176     region_const(const initializer_list<_Df>& il){
1177         rows = il.size();
1178         cols = 1;
1179         data = new refer[rows];
1180         pointer p = data;
1181         for (auto beg = il.begin(); beg != il.end(); ++beg){
1182             *p++ = *beg;
1183         }
1184 
1185     }
1186     region_const(const initializer_list<initializer_list<_Df>>& il){
1187         rows = il.size();
1188         cols = il.begin()->size();
1189         data = new refer[rows*cols];
1190         pointer it = data;
1191         for (auto beg = il.begin(); beg != il.end(); ++beg){
1192             if (beg->size() != cols)
1193                 throw runtime_error("region initlizer should be squire");
1194             for (auto b = beg->begin(); b != beg->end(); ++b){
1195                 *it = *b;
1196                 ++it;
1197             }
1198         }
1199 
1200     }
1201     ~region_const(){
1202         delete []data;
1203     }
1204     region_const& operator=(region_const& reg){
1205         delete []data;
1206         rows = reg.rows;
1207         cols = reg.cols;
1208         data = reg.data;
1209 
1210         if (nullptr == data)
1211             data = new refer[rows*cols];
1212         else{
1213             reg.data = nullptr;
1214             reg.rows = reg.cols = 0;
1215         }
1216 
1217         return *this;
1218     }
1219     region_const& operator=(const initializer_list<_Df>& il){
1220         rows = il.size();
1221         cols = 1;
1222         delete []data;
1223         data = new refer[rows];
1224         pointer p = data;
1225         for (auto beg = il.begin(); beg != il.end(); ++beg){
1226             *p++ = *beg;
1227         }
1228 
1229     }
1230     region_const& operator=(const initializer_list<initializer_list<_Df>>& il){
1231         rows = il.size();
1232         cols = il.begin()->size();
1233         delete []data;
1234         data = new refer[rows*cols];
1235         pointer it = data;
1236         for (auto beg = il.begin(); beg != il.end(); ++beg){
1237             if (beg->size() != cols)
1238                 throw runtime_error("region initlizer should be squire");
1239             for (auto b = beg->begin(); b != beg->end(); ++b){
1240                 *it++ = *b;
1241             }
1242         }
1243 
1244     }
1245 
1246     using_refer operator()(int r, int c){
1247         return data[r*cols + c];
1248     }
1249     const_refer at(int r, int c){
1250         return data[r*rows + c];
1251     }
1252     row_iter row(int r){
1253         return row_iter(r, *this);
1254     }
1255     col_iter col(int c){
1256         return col_iter(c, *this);
1257     }
1258 
1259     region_const clone(void){
1260         pointer p = new refer[rows*cols];
1261         for (int i = 0; i < rows*cols; ++i)
1262             p[i] = data[i];
1263 
1264         return region_const(rows, cols, p);
1265     }
1266     inline int amount()const{
1267         return rows*cols;
1268     }
1269 
1270 public:
1271     refer *data;
1272     int rows;
1273     int cols;
1274 
1275 };
1276 
1277 
1278 //------------------------------------------- mapping function -----------------------------------------
1279 
1280 /*必须实例化并指定_info*/
1281 struct _info
1282 {
1283     C_ANY_POINT defintionIp;    //    定义域指针
1284     C_ANY_POINT    RangeIp;        //    值域指针
1285 };
1286 
1287 
1288 
1289 /*! 参数方程初始化定义域 */
1290 template<typename _T>
1291 void defintionMapped(region_const<_T>& seed, region_const<_cplx<_T>>& field, C_ANY_POINT fun = nullptr)
1292 {//                    seed:参数路径                    field:值域对象            fun:映射函数,默认为_info的全局实例对象的指针
1293     int seg = seed.rows*seed.cols,
1294         fig = field.rows*field.cols;
1295 
1296     //    异常处理
1297     try{
1298         if (seg != fig)
1299             throw runtime_error("seed and field must be the same size.");
1300         if (nullptr == fun)
1301             throw runtime_error("function point is nullptr.");
1302     }
1303     catch (int){
1304         //    do noting
1305     }
1306 
1307     for (int i = 0; i < seg; ++i){
1308         field.data[i] = DEFINE_FUN(_T)(fun)(seed.data[i]);
1309     }
1310 
1311     return;
1312 }
1313 /*! 复变函数映射 */
1314 template<typename _T>
1315 void mappingMapped(region_const<_T>& seed, region_const<_T>& field, C_ANY_POINT fun = nullptr)
1316 {//                    seed:原象路径                    field:值域对象            fun:映射函数,默认为_info的全局实例对象的指针
1317     try{
1318         if (seed.rows*seed.cols != field.rows*field.cols)
1319             throw runtime_error("seed and field must be the same size.");
1320         if (nullptr == fun)
1321             throw runtime_error("function point is nullptr.");
1322     }
1323     catch (int){
1324         //    do nothing
1325     }
1326 
1327     for (int i = 0; i < seed.rows*seed.cols; ++i){
1328         field.data[i] = MAPPING_FUN(_T)(fun)(seed.data[i]);
1329     }
1330 
1331     return;
1332 }
1333 
1334 
1335 template<typename _Map>
1336 class _mapping
1337 {
1338 public:
1339     typedef region_const<_Map>        region;
1340     typedef region_const<_Map>&        using_region;
1341     typedef region_const<_Map>&&    move_region;
1342     //    函数指针
1343     typedef _cplx<_Map>(*DefintionIp)(_Map&);
1344     typedef _cplx<_Map>(*RangeIp)(_cplx<_Map>&);
1345 
1346     explicit _mapping(using_region seed, using_region field, RangeIp rg_ip = nullptr, DefintionIp df_ip = nullptr)
1347         :seed(seed),
1348         field(field),
1349         dfIp(df_ip),
1350         rgIp(rg_ip)
1351     {}
1352 
1353 
1354 public:
1355     using_region seed;
1356     using_region field;
1357     DefintionIp dfIp;
1358     RangeIp rgIp;
1359 
1360 };
1361 
1362 
1363 #endif    //    CPLX_CORE;
cplx_core.h

有的时候比较眼红外国人,各种厉害的软件都是他们做的,为啥我们国人自己不可以做呢?(结尾牢骚)

 

还有一个很重要的!!如果你觉得这篇短稿有价值,请点击推荐一下吧!非常感谢!!

posted @ 2018-03-18 00:45  蛮三  阅读(582)  评论(0编辑  收藏  举报