复变用于图片映射
复变用于图片映射,简单说,就是把复变函数定义域的图像剪切并映射到值域相应位置。
有什么实际用途吗?目前已经发现的用途:让我开心。哈哈哈哈哈
如图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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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;
有的时候比较眼红外国人,各种厉害的软件都是他们做的,为啥我们国人自己不可以做呢?(结尾牢骚)
还有一个很重要的!!如果你觉得这篇短稿有价值,请点击推荐一下吧!非常感谢!!