00001
00002 #ifndef __JBXL_CPP_MEMORY_SIMPLE_GRAPH_H_
00003 #define __JBXL_CPP_MEMORY_SIMPLE_GRAPH_H_
00004
00005
00013 #include "Gdata.h"
00014
00015
00016
00017 namespace jbxl {
00018
00019
00020 void rotate_point (int& x, int& y, double sxc, double syc, double dxc, double dyc, double cst, double snt);
00021 void rotate_point_angle(int& x, int& y, double sxc, double syc, double dxc, double dyc, double th);
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00090 template <typename T> Vector<double> dgree_circle_MSGraph(MSGraph<T> vp)
00091 {
00092 Vector<double> vt;
00093 double fac = 1.113757;
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 vt.z = -1.0;
00106 vt.x = count_around_MSGraph(vp);
00107 vt.y = count_area_MSGraph(vp);
00108 if (vt.y!=0) vt.z = (vt.x*vt.x)/(4.*PI*vt.y)/fac;
00109
00110
00111
00112 return vt;
00113 }
00114
00115
00116
00131 template <typename T> Vector<double> object_feature_MSGraph(MSGraph<T> vp, int mn, int mx)
00132 {
00133 int cnt = 0;
00134 int nx, ny;
00135 MSGraph<T> pp;
00136 Vector<double> vt;
00137
00138 pp.mimicry(vp);
00139 for (int i=0; i<pp.xs*pp.ys*pp.zs; i++) pp.gp[i] = vp.gp[i];
00140
00141 MSGraph_Paint(pp, 0, 0, pp.zero, pp.zero, mx+1, 4);
00142
00143 for (int j=0; j<pp.ys; j++) {
00144 ny = pp.xs*j;
00145 for (int i=0; i<pp.xs; i++) {
00146 nx = ny + i;
00147 if (pp.gp[nx]==pp.zero) {
00148 MSGraph_Paint(pp, i, j, pp.zero, pp.zero, mx, 8);
00149 }
00150 }
00151 }
00152
00153 MSGraph_Paint(pp, 0, 0, mx+1, mx+1, pp.zero, 4);
00154
00155 vt = dgree_circle_MSGraph<T>(pp);
00156
00157 for (int j=0; j<pp.ys; j++) {
00158 ny = pp.xs*j;
00159 for (int i=0; i<pp.xs; i++) {
00160 nx = ny + i;
00161 if (pp.gp[nx]>=mn && pp.gp[nx]<=mx) {
00162 MSGraph_Paint(pp, i, j, mn, mx, pp.zero, 8);
00163 cnt++;
00164 }
00165 }
00166 }
00167 pp.free();
00168 vt.x = (double)cnt;
00169
00170 return vt;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 template <typename T> double count_around_MSGraph(MSGraph<T> vp)
00187 {
00188 int i, j, m, n, cc;
00189 bool sflg;
00190 double cnt;
00191 const double qs = 0.70710678118654752440084436210;
00192 MSGraph<T> xp;
00193
00194 xp = zoom_MSGraph(vp, 2, OFF);
00195 if (xp.isNull()) return -1.0;
00196
00197 cnt = 0.0;
00198 for (j=1; j<xp.ys-1; j+=2) {
00199 for (i=1; i<xp.xs-1; i+=2) {
00200 cc = 0;
00201 sflg = false;
00202 for (n=0; n<2; n++) {
00203 for (m=0; m<2; m++) {
00204 if (xp.point(i+m, j+n)!=vp.zero) {
00205 cc++;
00206 if (n>0) if (xp.point(i+(1-m), j)!=vp.zero) sflg = true;
00207 }
00208 }
00209 }
00210
00211 if (cc==1 || cc==3) cnt += qs;
00212 else if (cc==2) {
00213 if (sflg==false) cnt += 1;
00214 else cnt += 2;
00215 }
00216 }
00217 }
00218 xp.free();
00219
00220 return cnt;
00221 }
00222
00223
00224
00230 template <typename T> int count_area_MSGraph(MSGraph<T> xp)
00231 {
00232 int ss = 0;
00233
00234 for (int i=0; i<xp.xs*xp.ys*xp.zs; i++) {
00235 if (xp.gp[i]!=xp.zero) ss++;
00236 }
00237 return ss;
00238 }
00239
00240
00241
00242 template <typename T> int count_object_MSGraph(MSGraph<T> xp, int mn, int mx)
00243 {
00244 int cnt = 0;
00245 int nx, ny;
00246 MSGraph<T> pp;
00247
00248 pp.mimicry(xp);
00249 for (int i=0; i<pp.xs*pp.ys*pp.zs; i++) pp.gp[i] = xp.gp[i];
00250
00251 MSGraph_Paint(pp, 0, 0, pp.zero, pp.zero, mx+1, 4);
00252
00253 for (int j=0; j<pp.ys; j++) {
00254 ny = pp.xs*j;
00255 for (int i=0; i<pp.xs; i++) {
00256 nx = ny + i;
00257 if (pp.gp[nx]==pp.zero) {
00258 MSGraph_Paint(pp, i, j, pp.zero, pp.zero, mx, 8);
00259 }
00260 }
00261 }
00262
00263 MSGraph_Paint(pp, 0, 0, mx+1, mx+1, pp.zero, 4);
00264
00265 for (int j=0; j<pp.ys; j++) {
00266 ny = pp.xs*j;
00267 for (int i=0; i<pp.xs; i++) {
00268 nx = ny + i;
00269 if (pp.gp[nx]>=mn && pp.gp[nx]<=mx) {
00270 MSGraph_Paint(pp, i, j, mn, mx, pp.zero, 8);
00271 cnt++;
00272 }
00273 }
00274 }
00275 pp.free();
00276
00277 return cnt;
00278 }
00279
00280
00281
00305 template <typename T> RBound<int> out_around_MSGraph(MSGraph<T> vp, int x, int y, int mode=8)
00306 {
00307 int i, j, sp, cp, w, ll, ss;
00308 int xx, yy, vx, vy, ix;
00309 bool eflg=false;
00310
00311 int r8[8]={-1, 1, -1, -1, 1, -1, 1, 1};
00312 int r4[8]={ 0, 1, -1, 0, 0, -1, 1, 0};
00313 int* cc;
00314
00315 i = x;
00316
00317 for (j=y; j<vp.ys-1; j++) {
00318 for (i=x; i<vp.xs-1; i++) {
00319 if (vp.gp[i+(j)*vp.xs]!=vp.zero) {
00320 eflg = true;
00321 break;
00322 }
00323 }
00324 if (eflg) break;
00325 }
00326 x = i;
00327 y = j;
00328 eflg = false;
00329
00330 RBound<int> rb(x, x, y, y);
00331 i = y*vp.xs + x;
00332
00333 sp = cp = i;
00334 ss = ll = 0;
00335 vx = 1;
00336 vy = 0;
00337
00338 if (mode==4) {
00339 ix = 4;
00340 cc = r4;
00341 }
00342 else {
00343 ix = 8;
00344 cc = r8;
00345 }
00346
00347 do {
00348 w = abs(vx)+abs(vy);
00349 xx = (vx*cc[0]+vy*cc[1])/w;
00350 yy = (vx*cc[2]+vy*cc[3])/w;
00351 for (j=1; j<=ix; j++) {
00352 if (vp.gp[cp+yy*vp.xs+xx]!=vp.zero) {
00353 vx = xx;
00354 vy = yy;
00355 cp = cp + yy*vp.xs + xx;
00356 xx = cp%vp.xs;
00357 yy = (cp-xx)/vp.xs;
00358 rb.xmax = Max(rb.xmax, xx);
00359 rb.ymax = Max(rb.ymax, yy);
00360 rb.xmin = Min(rb.xmin, xx);
00361 rb.ymin = Min(rb.ymin, yy);
00362 break;
00363 }
00364 else {
00365 if(sp==cp && xx==-1 && yy==vp.zero) {
00366 eflg = true;
00367 break;
00368 }
00369 w = abs(xx)+abs(yy);
00370 vx = (xx*cc[4]+yy*cc[5])/w;
00371 vy = (xx*cc[6]+yy*cc[7])/w;
00372 xx = vx;
00373 yy = vy;
00374 }
00375 }
00376 ll++;
00377 if (abs(vx)+abs(vy)==2) ss++;
00378 } while(!eflg);
00379
00380 if (mode==4) ss = 0;
00381 (rb.xmax)++;
00382 (rb.ymax)++;
00383 (rb.xmin)--;
00384 (rb.ymin)--;
00385 rb.zmax = ss;
00386 rb.zmin = ll;
00387 return rb;
00388 }
00389
00390
00391
00397 template <typename T> RBound<int> get_boundary_MSGraph(MSGraph<T> vp, T mn, T mx)
00398 {
00399 int nx, ny, nz, ps;
00400 RBound<int> rb;
00401
00402 rb.set(vp.xs, 0, vp.ys, 0, vp.zs, 0);
00403
00404 ps = vp.xs*vp.ys;
00405 for (int k=0; k<vp.zs; k++) {
00406 nz = k*ps;
00407 for (int j=0; j<vp.ys; j++) {
00408 ny = j*vp.xs + nz;
00409 for (int i=0; i<vp.xs; i++) {
00410 nx = i + ny;
00411 if (vp.gp[nx]>=mn && vp.gp[nx]<=mx) {
00412 rb.fusion((T)i, (T)j, (T)k);
00413 }
00414 }
00415 }
00416 }
00417
00418 rb.cutdown(vp.rbound);
00419
00420 return rb;
00421 }
00422
00423
00424
00434 template <typename T, typename R> void cat_MSGraph(MSGraph<R> src, MSGraph<T>& dst)
00435 {
00436 if ((void*)src.gp==(void*)dst.gp) return;
00437
00438 int i, x, y, z;
00439 MSGraph<T> vp;
00440 RBound<int> rb;
00441
00442 rb.xmin = Min(src.rbound.xmin, dst.rbound.xmin);
00443 rb.ymin = Min(src.rbound.ymin, dst.rbound.ymin);
00444 rb.zmin = Min(src.rbound.zmin, dst.rbound.zmin);
00445 rb.xmax = Max(src.rbound.xmax, dst.rbound.xmax);
00446 rb.ymax = Max(src.rbound.ymax, dst.rbound.ymax);
00447 rb.zmax = Max(src.rbound.zmax, dst.rbound.zmax);
00448
00449 vp.set(rb.xmax-rb.xmin+1, rb.ymax-rb.ymin+1, rb.zmax-rb.zmin+1, dst.zero, dst.base, dst.RZxy);
00450 if (vp.gp==NULL) return;
00451 vp.rbound = rb;
00452 vp.max = Max((T)src.max, dst.max);
00453 vp.min = Min((T)src.min, dst.min);
00454
00455 for (i=0; i<dst.xs*dst.ys*dst.zs; i++) {
00456 if (dst.gp[i]!=dst.zero) {
00457 x = i%dst.xs + dst.rbound.xmin - rb.xmin;
00458 y = (i/dst.xs)%dst.ys + dst.rbound.ymin - rb.ymin;
00459 z = i/(dst.xs*dst.ys) + dst.rbound.zmin - rb.zmin;
00460 vp.gp[z*vp.xs*vp.ys + y*vp.xs + x] = dst.gp[i];
00461 }
00462 }
00463
00464 for (i=0; i<src.xs*src.ys*src.zs; i++) {
00465 if (src.gp[i]!=src.zero) {
00466 x = i%src.xs + src.rbound.xmin - rb.xmin;
00467 y = (i/src.xs)%src.ys + src.rbound.ymin - rb.ymin;
00468 z = i/(src.xs*src.ys) + src.rbound.zmin - rb.zmin;
00469 vp.gp[z*vp.xs*vp.ys + y*vp.xs + x] = (T)src.gp[i];
00470 }
00471 }
00472
00473 dst.free();
00474 dst = vp;
00475 return;
00476 }
00477
00478
00479
00489 template <typename T, typename R> void cat_MSGraph(MSGraph<R>* src, MSGraph<T>* dst)
00490 {
00491 if (src==NULL || dst==NULL) return;
00492 if ((void*)src->gp==(void*)dst->gp) return;
00493
00494 int i, x, y, z;
00495 MSGraph<T> vp;
00496 RBound<int> rb;
00497
00498 rb.xmin = Min(src->rbound.xmin, dst->rbound.xmin);
00499 rb.ymin = Min(src->rbound.ymin, dst->rbound.ymin);
00500 rb.zmin = Min(src->rbound.zmin, dst->rbound.zmin);
00501 rb.xmax = Max(src->rbound.xmax, dst->rbound.xmax);
00502 rb.ymax = Max(src->rbound.ymax, dst->rbound.ymax);
00503 rb.zmax = Max(src->rbound.zmax, dst->rbound.zmax);
00504
00505 vp.set(rb.xmax-rb.xmin+1, rb.ymax-rb.ymin+1, rb.zmax-rb.zmin+1, dst->zero, dst->base, dst->RZxy);
00506 if (vp.gp==NULL) return;
00507 vp.rbound = rb;
00508 vp.max = Max((T)src->max, dst->max);
00509 vp.min = Min((T)src->min, dst->min);
00510
00511 for (i=0; i<dst->xs*dst->ys*dst->zs; i++) {
00512 if (dst->gp[i]!=dst->zero) {
00513 x = i%dst->xs + dst->rbound.xmin - rb.xmin;
00514 y = (i/dst->xs)%dst->ys + dst->rbound.ymin - rb.ymin;
00515 z = i/(dst->xs*dst->ys) + dst->rbound.zmin - rb.zmin;
00516 vp.gp[z*vp.xs*vp.ys + y*vp.xs + x] = dst->gp[i];
00517 }
00518 }
00519
00520 for (i=0; i<src->xs*src->ys*src->zs; i++) {
00521 if (src->gp[i]!=src->zero) {
00522 x = i%src->xs + src->rbound.xmin - rb.xmin;
00523 y = (i/src->xs)%src->ys + src->rbound.ymin - rb.ymin;
00524 z = i/(src->xs*src->ys) + src->rbound.zmin - rb.zmin;
00525 vp.gp[z*vp.xs*vp.ys + y*vp.xs + x] = (T)src->gp[i];
00526 }
00527 }
00528
00529 dst->free();
00530 *dst = vp;
00531 return;
00532 }
00533
00534
00535
00545 template <typename R, typename T> void copy_MSGraph(MSGraph<R> src, MSGraph<T>& dst)
00546 {
00547 if ((void*)src.gp==(void*)dst.gp) return;
00548
00549 MSGraph<T> vp;
00550
00551 vp.getm(src.xs, src.ys, src.zs, (T)src.zero);
00552 if (vp.gp==NULL) {
00553 dst.free();
00554 dst.gp = NULL;
00555 dst.state = JBXL_GRAPH_MEMORY_ERROR;
00556 return;
00557 }
00558
00559 vp.max = (T)src.max;
00560 vp.min = (T)src.min;
00561 vp.base = (T)src.base;
00562 vp.color = src.color;
00563 vp.state = src.state;
00564 for (int i=0; i<vp.xs*vp.ys*vp.zs; i++) vp.gp[i] = (T)src.gp[i];
00565
00566 dst.free();
00567 dst = vp;
00568 return;
00569 }
00570
00571
00581 template <typename R, typename T> void copy_MSGraph(MSGraph<R>* src, MSGraph<T>* dst)
00582 {
00583 if (src==NULL || dst==NULL) return;
00584 if ((void*)src->gp==(void*)dst->gp) return;
00585
00586 MSGraph<T> vp;
00587
00588 vp.getm(src->xs, src->ys, src->zs, (T)src->zero);
00589 if (vp.gp==NULL) {
00590 dst->free();
00591 dst->gp = NULL;
00592 dst->state = JBXL_GRAPH_MEMORY_ERROR;
00593 return;
00594 }
00595
00596 vp.max = (T)src->max;
00597 vp.min = (T)src->min;
00598 vp.base = (T)src->base;
00599 vp.color = src->color;
00600 vp.state = src->state;
00601 for (int i=0; i<vp.xs*vp.ys*vp.zs; i++) vp.gp[i] = (T)src->gp[i];
00602
00603 dst->free();
00604 *dst = vp;
00605 return;
00606 }
00607
00608
00609
00618 template <typename T> MSGraph<T> dup_MSGraph(MSGraph<T> src)
00619 {
00620 MSGraph<T> vp;
00621
00622 vp.init();
00623 if (src.isNull()) {
00624 vp.state = JBXL_GRAPH_NODATA_ERROR;
00625 return vp;
00626 }
00627
00628 vp = src;
00629 vp.getm(src.xs, src.ys, src.zs, src.zero);
00630 if (vp.gp==NULL) {
00631 vp.init();
00632 vp.state = JBXL_GRAPH_MEMORY_ERROR;
00633 return vp;
00634 }
00635
00636 for (int i=0; i<vp.xs*vp.ys*vp.zs; i++) vp.gp[i] = src.gp[i];
00637
00638 return vp;
00639 }
00640
00641
00642
00651 template <typename T> MSGraph<T>* dup_MSGraph(MSGraph<T>* src)
00652 {
00653 if (src==NULL) return NULL;
00654 MSGraph<T>* vp = new MSGraph<T>();
00655
00656 vp->init();
00657 if (src->isNull()) {
00658 vp->state = JBXL_GRAPH_NODATA_ERROR;
00659 return vp;
00660 }
00661
00662 *vp = *src;
00663 vp->getm(src->xs, src->ys, src->zs, src->zero);
00664 if (vp->gp==NULL) {
00665 vp->init();
00666 vp->state = JBXL_GRAPH_MEMORY_ERROR;
00667 return vp;
00668 }
00669
00670 for (int i=0; i<vp->xs*vp->ys*vp->zs; i++) vp->gp[i] = src->gp[i];
00671
00672 return vp;
00673 }
00674
00675
00676
00692 template <typename T> void ToPola(Vector<T> nv, double& cst, double& snt, double& csf, double& snf, double pcsf=0.0, double psnf=1.0)
00693 {
00694 if (nv.n!=1.0) nv.normalize();
00695 if (nv.z<-1.0) nv.z = -1.0;
00696 if (nv.z> 1.0) nv.z = 1.0;
00697 cst = nv.z;
00698 snt = sqrt(1.0-nv.z*nv.z);
00699
00700 if (snt<Sin_Tolerance) {
00701 cst = Sign(cst);
00702 snt = 0.0;
00703 csf = pcsf;
00704 snf = psnf;
00705 }
00706 else {
00707 csf = nv.x/snt;
00708 snf = nv.y/snt;
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 return;
00727 }
00728
00729
00730
00748 template <typename T, typename R>
00749 void Local2World(MSGraph<T> gd, MSGraph<T> vp, Vector<R> oq, Vector<R> op, Vector<R> ex, double* pcsf=NULL, double* psnf=NULL)
00750 {
00751 int x, y, z, cx, cy, cz;
00752 double px, py, pz, xx, yy, zz;
00753 double cst, snt, csf=0.0, snf=1.0;
00754
00755 if (pcsf!=NULL && psnf!=NULL) {
00756 csf = *pcsf;
00757 snf = *psnf;
00758 }
00759
00760 ToPola(ex, cst, snt, csf, snf, csf, snf);
00761
00762 for (z=0; z<vp.zs; z++) {
00763 cz = z*vp.xs*vp.ys;
00764 for (y=0; y<vp.ys; y++) {
00765 cy = cz + y*vp.xs;
00766 for (x=0; x<vp.xs; x++) {
00767 cx = cy + x;
00768 if (vp.gp[cx]!=vp.zero) {
00769 px = z - op.z;
00770 py = op.x - x;
00771 pz = op.y - y;
00772 xx = px*snt*csf - py*snf - pz*cst*csf + oq.x;
00773 yy = px*snt*snf + py*csf - pz*cst*snf + oq.y;
00774 zz = px*cst + pz*snt + oq.z;
00775 gd.set_vPoint(xx, yy, zz, vp.gp[cx], ON);
00776 }
00777 }
00778 }
00779 }
00780
00781 if (pcsf!=NULL && psnf!=NULL) {
00782 *pcsf = csf;
00783 *psnf = snf;
00784 }
00785 }
00786
00787
00788
00789 template <typename T> void MSGraph_changeColor(MSGraph<T> vp, int f, int t)
00790 {
00791 for (int i=0; i<vp.xs*vp.ys*vp.zs; i++) {
00792 if (vp.gp[i]==(T)f) vp.gp[i] = (T)t;
00793 }
00794 }
00795
00796
00797
00814 template <typename T> int MSGraph_Paint(MSGraph<T> vp, int x, int y, int mn, int mx, int cc, int mode=8)
00815 {
00816 int i, j, k, ss;
00817
00818 if (cc<=mx && cc>=mn) {
00819 DEBUG_MODE PRINT_MESG("MSGRAPH_PAINT: WARNING: c = %d. Not be %d< c <%d\n", cc, mn, mx);
00820 return 0;
00821 }
00822
00823 if (x<0 || x>=vp.xs || y<0 || y>=vp.ys) return 0;
00824 if (vp.gp[y*vp.xs+x]>(T)mx || vp.gp[y*vp.xs+x]<(T)mn) return 0;
00825
00826 while(x>0) {
00827 if (vp.gp[y*vp.xs+x-1]>(T)mx || vp.gp[y*vp.xs+x-1]<(T)mn) break;
00828 x--;
00829 }
00830 k = x;
00831
00832 ss = 0;
00833 while(k<vp.xs) {
00834 if (vp.gp[y*vp.xs+k]>(T)mx || vp.gp[y*vp.xs+k]<(T)mn) break;
00835 vp.gp[y*vp.xs+k] = (T)cc;
00836 ss++;
00837 k++;
00838 }
00839 k--;
00840
00841 for (i=x; i<=k; i++){
00842 if (y-1>=0 && y-1<vp.ys){
00843 j = (y-1)*vp.xs+i;
00844 if (vp.gp[j]<=(T)mx && vp.gp[j]>=(T)mn) {
00845 ss += MSGraph_Paint(vp, i, y-1, mn, mx, cc, mode);
00846 }
00847
00848 if (Xabs(mode)==8) {
00849 if (i-1>=0) {
00850 if (vp.gp[j-1]<=(T)mx && vp.gp[j-1]>=(T)mn) {
00851 ss += MSGraph_Paint(vp, i-1, y-1, mn, mx, cc, mode);
00852 }
00853 }
00854 if (i+1<vp.xs) {
00855 if (vp.gp[j+1]<=(T)mx && vp.gp[j+1]>=(T)mn) {
00856 ss += MSGraph_Paint(vp, i+1, y-1, mn, mx, cc, mode);
00857 }
00858 }
00859 }
00860 }
00861
00862 if (y+1>=0 && y+1<vp.ys){
00863 j = (y+1)*vp.xs+i;
00864 if (vp.gp[j]<=(T)mx && vp.gp[j]>=(T)mn) {
00865 ss += MSGraph_Paint(vp, i, y+1, mn, mx, cc, mode);
00866 }
00867
00868 if (Xabs(mode)==8) {
00869 if (i-1>=0) {
00870 if (vp.gp[j-1]<=(T)mx && vp.gp[j-1]>=(T)mn) {
00871 ss += MSGraph_Paint(vp, i-1, y+1, mn, mx, cc, mode);
00872 }
00873 }
00874 if (i+1<vp.xs) {
00875 if (vp.gp[j+1]<=(T)mx && vp.gp[j+1]>=(T)mn) {
00876 ss += MSGraph_Paint(vp, i+1, y+1, mn, mx, cc, mode);
00877 }
00878 }
00879 }
00880 }
00881 }
00882 return ss;
00883 }
00884
00885
00886
00905 template <typename T> int MSGraph_Paint3D(MSGraph<T> vp, int x, int y, int z, int mn, int mx, int cc, int mode=8)
00906 {
00907 int i, j, ps, ss;
00908 MSGraph<T> xp;
00909
00910 ss = 0;
00911 ps = vp.xs*vp.ys;
00912 xp = vp;
00913 xp.zs = 1;
00914 xp.gp = &(vp.gp[z*ps]);
00915
00916 if (xp.gp[y*xp.xs+x]>(T)mx || xp.gp[y*xp.xs+x]<(T)mn) return 0;
00917 ss += MSGraph_Paint(xp, x, y, mn, mx, cc, mode);
00918 if (mode<0) {
00919 DEBUG_MODE PRINT_MESG("MSGRAPH_PAINT3D: zz = %d\n", z);
00920 }
00921
00922 for (i=0; i<ps; i++) {
00923 if (xp.gp[i]==(T)cc) {
00924 x = i%vp.xs;
00925 y = i/vp.xs;
00926 if (z-1>=0) {
00927 j = (z-1)*ps+y*vp.xs+x;
00928 if (vp.gp[j]<=(T)mx && vp.gp[j]>=(T)mn) {
00929 ss += MSGraph_Paint3D(vp, x, y, z-1, mn, mx, cc, mode);
00930 }
00931 }
00932 if (z+1<vp.zs) {
00933 j = (z+1)*ps+y*vp.xs+x;
00934 if (vp.gp[j]<=(T)mx && vp.gp[j]>=(T)mn) {
00935 ss += MSGraph_Paint3D(vp, x, y, z+1, mn, mx, cc, mode);
00936 }
00937 }
00938 }
00939 }
00940
00941 return ss;
00942 }
00943
00944
00945
00962 template <typename T> void MSGraph_Line(MSGraph<T> vp, int x1, int y1, int x2, int y2, int cc)
00963 {
00964 int thresh=0, index;
00965 int xunit=1;
00966 int yunit=1;
00967 int xdiff=x2-x1;
00968 int ydiff=y2-y1;
00969
00970 if (xdiff<0) {
00971 xdiff = -xdiff;
00972 xunit = -1;
00973 }
00974 if (ydiff<0) {
00975 ydiff = -ydiff;
00976 yunit = -1;
00977 }
00978
00979 if (xdiff>ydiff) {
00980 for (index=0; index<xdiff+1; index++) {
00981 if (x1>=0 && x1<vp.xs && y1>=0 && y1<vp.ys) {
00982 vp.point(x1, y1) = (T)cc;
00983 }
00984 x1 = x1 + xunit;
00985 thresh = thresh + ydiff;
00986 if (thresh>=xdiff) {
00987 thresh = thresh - xdiff;
00988 y1 = y1 + yunit;
00989 }
00990 }
00991 }
00992 else {
00993 for (index=0; index<ydiff+1; index++) {
00994 if (x1>=0 && x1<vp.xs && y1>=0 && y1<vp.ys) {
00995 vp.point(x1, y1) = (T)cc;
00996 }
00997 y1 = y1 + yunit;
00998 thresh = thresh + xdiff;
00999 if (thresh>=ydiff) {
01000 thresh = thresh - ydiff;
01001 x1 = x1 + xunit;
01002 }
01003 }
01004 }
01005 }
01006
01007
01008
01031 template <typename T> void MSGraph_Triangle(MSGraph<T> vp, int x1, int y1, int x2, int y2, int x3, int y3, int cc, int mode=OFF)
01032 {
01033 MSGraph_Line(vp, x1, y1, x2, y2, cc);
01034 MSGraph_Line(vp, x2, y2, x3, y3, cc);
01035 MSGraph_Line(vp, x3, y3, x1, y1, cc);
01036
01037 if (mode==ON) {
01038 MSGraph_Paint(vp, (x1+x2+x3)/3, (y1+y2+y3)/3, (int)vp.zero, cc-1, cc, 4);
01039 }
01040 return;
01041 }
01042
01043
01044
01061 template <typename T> void MSGraph_Box(MSGraph<T> vp, int x1, int y1, int x2, int y2, int cc, int mode=OFF)
01062 {
01063 MSGraph_Line(vp, x1, y1, x2, y1, cc);
01064 MSGraph_Line(vp, x2, y1, x2, y2, cc);
01065 MSGraph_Line(vp, x2, y2, x1, y2, cc);
01066 MSGraph_Line(vp, x1, y2, x1, y1, cc);
01067
01068 if (mode==ON) {
01069 MSGraph_Paint(vp, (x1+x2)/2, (y1+y2)/2, (int)vp.zero, cc-1, cc, 4);
01070 }
01071 return;
01072 }
01073
01074
01075
01087 template <typename T> void MSGraph_Line3D(MSGraph<T> vp, int x1, int y1, int z1, int x2, int y2, int z2, int cc)
01088 {
01089 int i;
01090 int xx, yy, zz, dx, dy, dz;
01091 int ux=1, uy=1, uz=1;
01092 int sx=0, sy=0, sz=0;
01093
01094 dx = x2 - x1;
01095 dy = y2 - y1;
01096 dz = z2 - z1;
01097
01098 if (dx<0) {
01099 dx = -dx;
01100 ux = -1;
01101 }
01102 if (dy<0) {
01103 dy = -dy;
01104 uy = -1;
01105 }
01106 if (dz<0) {
01107 dz = -dz;
01108 uz = -1;
01109 }
01110
01111 xx = x1;
01112 yy = y1;
01113 zz = z1;
01114
01115 if (xx>=0 && xx<vp.xs && yy>=0 && yy<vp.ys && zz>=0 && zz<vp.zs) {
01116 vp.point(xx, yy, zz) = (T)cc;
01117 }
01118 if (dx>=dy && dx>=dz) {
01119 for (i=1; i<=dx; i++) {
01120 xx = xx + ux;
01121 sy = sy + dy;
01122 sz = sz + dz;
01123 if (sy>dx) {
01124 sy = sy - dx;
01125 yy = yy + uy;
01126 }
01127 if (sz>dx) {
01128 sz = sz - dx;
01129 zz = zz + uz;
01130 }
01131 if (xx>=0 && xx<vp.xs && yy>=0 && yy<vp.ys && zz>=0 && zz<vp.zs) {
01132 vp.point(xx, yy, zz) = (T)cc;
01133 }
01134 }
01135 }
01136 else if (dy>dx && dy>=dz) {
01137 for (i=1; i<=dy; i++) {
01138 yy = yy + uy;
01139 sx = sx + dx;
01140 sz = sz + dz;
01141 if (sx>dy) {
01142 sx = sx - dy;
01143 xx = xx + ux;
01144 }
01145 if (sz>dy) {
01146 sz = sz - dy;
01147 zz = zz + uz;
01148 }
01149 if (xx>=0 && xx<vp.xs && yy>=0 && yy<vp.ys && zz>=0 && zz<vp.zs) {
01150 vp.point(xx, yy, zz) = (T)cc;
01151 }
01152 }
01153 }
01154 else {
01155 for (i=1; i<=dz; i++) {
01156 zz = zz + uz;
01157 sx = sx + dx;
01158 sy = sy + dy;
01159 if (sx>dz) {
01160 sx = sx - dz;
01161 xx = xx + ux;
01162 }
01163 if (sy>dz) {
01164 sy = sy - dz;
01165 yy = yy + uy;
01166 }
01167 if (xx>=0 && xx<vp.xs && yy>=0 && yy<vp.ys && zz>=0 && zz<vp.zs) {
01168 vp.point(xx, yy, zz) = (T)cc;
01169 }
01170 }
01171 }
01172 }
01173
01174
01175
01187 template <typename T> void MSGraph_Circle(MSGraph<T> vp, int x, int y, int r, int cc, int mode=OFF)
01188 {
01189 double yy, dy, dt;
01190 int i, nn, cx;
01191 int ix, iy, ux=1;
01192 int *px, *py;
01193
01194 if (r<=0) return;
01195
01196 px = (int*)malloc(sizeof(int)*(r+1));
01197 py = (int*)malloc(sizeof(int)*(r+1));
01198 if (px==NULL || py==NULL) {
01199 free(px);
01200 free(py);
01201 return;
01202 }
01203
01204 ix = 0;
01205 iy = r;
01206 yy = (double)r;
01207 nn = 0;
01208 px[0] = ix;
01209 py[0] = iy;
01210
01211 cx = (y+iy)*vp.xs + (x+ix);
01212 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.gp[cx] = (T)cc;
01213 while(iy>=ix) {
01214 ix = ix + ux;
01215 dt = -ux/yy;
01216 dy = ix*dt;
01217 yy = yy + dy;
01218 iy = (int)yy;
01219
01220 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01221 nn++;
01222 px[nn] = ix;
01223 py[nn] = iy;
01224 }
01225
01226 for (i=0; i<=nn; i++) {
01227 ix = py[nn-i];
01228 iy = px[nn-i];
01229 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01230 }
01231
01232 for (i=0; i<=nn; i++) {
01233 ix = py[i];
01234 iy = -px[i];
01235 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01236 }
01237
01238 for (i=0; i<=nn; i++) {
01239 ix = px[nn-i];
01240 iy = -py[nn-i];
01241 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01242 }
01243
01244 for (i=0; i<=nn; i++) {
01245 ix = -px[i];
01246 iy = -py[i];
01247 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01248 }
01249
01250 for (i=0; i<=nn; i++) {
01251 ix = -py[nn-i];
01252 iy = -px[nn-i];
01253 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01254 }
01255
01256 for (i=0; i<=nn; i++) {
01257 ix = -py[i];
01258 iy = px[i];
01259 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01260 }
01261
01262 for (i=0; i<=nn; i++) {
01263 ix = -px[nn-i];
01264 iy = py[nn-i];
01265 if (x+ix>=0 && x+ix<vp.xs && y+iy>=0 && y+iy<vp.ys) vp.point(x+ix, y+iy) = (T)cc;
01266 }
01267
01268 if (mode==ON) MSGraph_Paint(vp, x, y, (int)vp.zero, cc-1, cc, 4);
01269
01270 free(px);
01271 free(py);
01272 }
01273
01274
01275
01289 template <typename T> void MSGraph_Circle3D(MSGraph<T> vp, Vector<> ox, Vector<> ex, int rr, int cc, int mode=OFF)
01290 {
01291 MSGraph<T> xp(2*rr+3, 2*rr+3);
01292 if (xp.gp==NULL) return;
01293
01294 Vector<> oz((xp.xs-1)/2., (xp.ys-1)/2., 0.0);
01295
01296 MSGraph_Circle(xp, rr+1, rr+1, rr, cc, mode);
01297 Local2World(vp, xp, ox, oz, ex);
01298 xp.free();
01299 }
01300
01301
01302
01314 template <typename T> void MSGraph_Pool(MSGraph<T> vp, Vector<> a, Vector<> b, int rr, int cc)
01315 {
01316 int i, cz;
01317 Vector<> ox, oz;
01318 MSGraph<T> xp, pp;
01319
01320 ox = a - b;
01321 ox.norm();
01322 xp.set(2*rr+3, 2*rr+3, (int)(ox.n + 0.5));
01323 if (xp.gp==NULL) return;
01324
01325 pp = xp;
01326 for (i=0; i<xp.zs; i++) {
01327 cz = i*xp.xs*xp.ys;
01328 pp.gp = &(xp.gp[cz]);
01329 MSGraph_Circle(pp, rr+1, rr+1, rr, cc, ON);
01330 }
01331
01332 oz.set((xp.xs-1)/2.0, (xp.ys-1)/2.0, (xp.zs-1)/2.0);
01333 Local2World(vp, xp, (a+b)/2.0, oz, ox);
01334 xp.free();
01335 return;
01336 }
01337
01338
01339
01353 template <typename T>
01354 void MSGraph_Torus(MSGraph<T> vp, Vector<> ox, Vector<> ex, int rr, int ra, int cc)
01355 {
01356 int i, nn;
01357 double dt, th, xx, yy, zz, sn, cs;
01358 MSGraph<T> xp;
01359 Vector<> ve, vo, vz;
01360
01361 xp.set(2*(rr+ra)+3, 2*(rr+ra)+3, 2*ra+3);
01362 if (xp.gp==NULL) return;
01363 nn = (int)(2.0*PI*(rr+ra)*2 + 0.5);
01364 dt = 2.0*PI/nn;
01365
01366 zz = (xp.zs-1)/2.0;
01367 for (i=0; i<nn; i++) {
01368 th = dt*i;
01369 sn = sin(th);
01370 cs = cos(th);
01371 xx = (xp.xs-1)/2.0 + rr*cs;
01372 yy = (xp.ys-1)/2.0 - rr*sn;
01373 vo.set(xx, yy, zz);
01374 ve.set(sn, cs, 0.0);
01375 MSGraph_Circle3D(xp, vo, ve, ra, cc, ON);
01376 }
01377 vz.set((xp.xs-1)/2., (xp.ys-1)/2., (xp.zs-1)/2.);
01378
01379 Local2World(vp, xp, ox, vz, ex);
01380 xp.free();
01381
01382 return;
01383 }
01384
01385
01386
01401 template <typename T> void MSGraph_Sphere(MSGraph<T> vp, Vector<> a, int r, int cc, int mode=1)
01402 {
01403 int i, j, k, rx, nn, s=1;
01404 double th, fi, cs, sn, cf, sf, dt;
01405 double xx, yy, zz;
01406 MSGraph<T> xp;
01407
01408 if (mode==1) {
01409 xp = vp;
01410 for (k=(int)(a.z-r+0.5); k<=(int)(a.z+r+0.5); k++) {
01411 if (k>=0 && k<vp.zs) {
01412 xp.gp = &vp.gp[k*vp.xs*vp.ys];
01413 rx = (int)(sqrt(r*r-(a.z-k)*(a.z-k))+0.5);
01414 MSGraph_Circle(xp, (int)(a.x+0.5), (int)(a.y+0.5), rx, cc, ON);
01415 }
01416 }
01417 }
01418 else {
01419 nn = (int)(2*PI*r + 0.5)*2;
01420 dt = PI/nn;
01421 for (i=0; i<=nn; i++) {
01422 th = dt*i;
01423 sn = sin(th);
01424 cs = cos(th);
01425 zz = r*cs + a.z;
01426 if (mode==-1) {
01427 if (zz<s) zz = s;
01428 if (zz>vp.zs-s-1) zz = vp.zs - s - 1;
01429 }
01430 for (j=0; j<=2*nn; j++) {
01431 fi = dt*j;
01432 cf = cos(fi);
01433 sf = sin(fi);
01434 xx = r*sn*cf + a.x;
01435 yy = r*sn*sf + a.y;
01436 if (mode==-1) {
01437 if (xx<s) xx = s;
01438 if (yy<s) yy = s;
01439 if (xx>vp.xs-s-1) xx = vp.xs - s - 1;
01440 if (yy>vp.ys-s-1) yy = vp.ys - s - 1;
01441 }
01442 vp.set_vPoint(xx, yy, zz, (T)cc, ON);
01443 }
01444 }
01445 }
01446 return;
01447 }
01448
01449
01450
01464 template <typename T> MSGraph<T> cut_object_MSGraph(MSGraph<T> vp, int mn, int mx, int blank=BOUNDARY_BLANK, bool ecnt=false)
01465 {
01466 int i, j, k, n;
01467 int cx, cy, cz, cp;
01468 int ax, ay, az, ap;
01469 MSGraph<T> xp;
01470
01471 xp.init();
01472 RBound<int> rb(vp.xs-1, 0, vp.ys-1, 0, vp.zs-1, 0);
01473 RBound<int> rx(0, vp.xs-1, 0, vp.ys-1, 0, vp.zs-1);
01474 CVCounter* counter = NULL;
01475
01476 if (ecnt) counter = GetUsableGlobalCounter();
01477 if (counter!=NULL) {
01478 if (counter->isCanceled()) {
01479 xp.state = JBXL_GRAPH_CANCEL;
01480 return xp;
01481 }
01482 counter->SetMax(vp.zs*2);
01483 }
01484
01485 ap = vp.xs*vp.ys;
01486 n = 0;
01487 for (k=0; k<vp.zs; k++) {
01488 az = ap*k;
01489 for (j=0; j<vp.ys; j++) {
01490 ay = az + vp.xs*j;
01491 for (i=0; i<vp.xs; i++) {
01492 ax = ay + i;
01493 if (vp.gp[ax]>=(T)mn && vp.gp[ax]<=(T)mx) {
01494 n++;
01495 rb.fusion(i, j, k);
01496 }
01497 }
01498 }
01499
01500
01501 if (counter!=NULL) {
01502 counter->StepIt();
01503 if (counter->isCanceled()) {
01504 xp.state = JBXL_GRAPH_CANCEL;
01505 return xp;
01506 }
01507 }
01508 }
01509
01510 if (n==0) {
01511 xp.state = JBXL_GRAPH_NODATA_ERROR;
01512 return xp;
01513 }
01514
01515 if (blank>0) rb.enlarge(blank);
01516 rb.commonarea(rx);
01517
01518 xp.set(rb.xmax-rb.xmin+1, rb.ymax-rb.ymin+1, rb.zmax-rb.zmin+1, vp.zero, vp.base, vp.RZxy);
01519 if (xp.isNull()) {
01520 xp.state = JBXL_GRAPH_MEMORY_ERROR;
01521 return xp;
01522 }
01523 xp.rbound = rb;
01524 xp.min = (T)mx;
01525 xp.max = (T)mn;
01526 xp.color = vp.color;
01527
01528 cp = xp.xs*xp.ys;
01529 for (k=0; k<xp.zs; k++) {
01530 cz = cp*k;
01531 az = ap*(k+rb.zmin);
01532 for (j=0; j<xp.ys; j++) {
01533 cy = cz + xp.xs*j;
01534 ay = az + vp.xs*(j+rb.ymin);
01535 for (i=0; i<xp.xs; i++) {
01536 cx = cy + i;
01537 ax = ay + (i+rb.xmin);
01538 if (vp.gp[ax]>=(T)mn && vp.gp[ax]<=(T)mx) {
01539 xp.gp[cx] = vp.gp[ax];
01540 xp.max = Max(xp.max, xp.gp[cx]);
01541 xp.min = Min(xp.min, xp.gp[cx]);
01542 }
01543 }
01544 }
01545
01546
01547 if (counter!=NULL) {
01548 counter->StepIt();
01549 if (counter->isCanceled()) {
01550 xp.state = JBXL_GRAPH_CANCEL;
01551 return xp;
01552 }
01553 }
01554 }
01555
01556 xp.rbound.cutdown(vp.rbound);
01557
01558 return xp;
01559 }
01560
01561
01562
01577 template <typename T> MSGraph<T> cut_object_MSGraph(MSGraph<T> vp, int mn, int mx, RBound<int> rbound, int blank=BOUNDARY_BLANK, bool ecnt=false)
01578 {
01579 int i, j, k, n;
01580 int cx, cy, cz, cp;
01581 int ax, ay, az, ap;
01582 MSGraph<T> xp;
01583
01584 xp.init();
01585 RBound<int> rb(vp.xs-1, 0, vp.ys-1, 0, vp.zs-1, 0);
01586 RBound<int> rx(0, vp.xs-1, 0, vp.ys-1, 0, vp.zs-1);
01587 CVCounter* counter = NULL;
01588
01589 if (ecnt) counter = GetUsableGlobalCounter();
01590 if (counter!=NULL) {
01591 if (counter->isCanceled()) {
01592 xp.state = JBXL_GRAPH_CANCEL;
01593 return xp;
01594 }
01595 counter->SetMax(vp.zs*2);
01596 }
01597
01598 rbound.commonarea(rx);
01599 ap = vp.xs*vp.ys;
01600 n = 0;
01601 for (k=rbound.zmin; k<=rbound.zmax; k++) {
01602 az = ap*k;
01603 for (j=rbound.ymin; j<=rbound.ymax; j++) {
01604 ay = az + vp.xs*j;
01605 for (i=rbound.xmin; i<=rbound.xmax; i++) {
01606 ax = ay + i;
01607 if (vp.gp[ax]>=(T)mn && vp.gp[ax]<=(T)mx) {
01608 n++;
01609 rb.fusion(i, j, k);
01610 }
01611 }
01612 }
01613
01614
01615 if (counter!=NULL) {
01616 counter->StepIt();
01617 if (counter->isCanceled()) {
01618 xp.state = JBXL_GRAPH_CANCEL;
01619 return xp;
01620 }
01621 }
01622 }
01623
01624 if (n==0) {
01625 xp.state = JBXL_GRAPH_NODATA_ERROR;
01626 return xp;
01627 }
01628
01629 if (blank>0) rb.enlarge(blank);
01630 rb.commonarea(rbound);
01631
01632 xp.set(rb.xmax-rb.xmin+1, rb.ymax-rb.ymin+1, rb.zmax-rb.zmin+1, vp.zero, vp.base, vp.RZxy);
01633 if (xp.isNull()) {
01634 xp.state = JBXL_GRAPH_MEMORY_ERROR;
01635 return xp;
01636 }
01637 xp.rbound = rb;
01638 xp.min = (T)mx;
01639 xp.max = (T)mn;
01640 xp.color = vp.color;
01641
01642 cp = xp.xs*xp.ys;
01643 for (k=0; k<xp.zs; k++) {
01644 cz = cp*k;
01645 az = ap*(k+rb.zmin);
01646 for (j=0; j<xp.ys; j++) {
01647 cy = cz + xp.xs*j;
01648 ay = az + vp.xs*(j+rb.ymin);
01649 for (i=0; i<xp.xs; i++) {
01650 cx = cy + i;
01651 ax = ay + i + rb.xmin;
01652 if (vp.gp[ax]>=(T)mn && vp.gp[ax]<=(T)mx) {
01653 xp.gp[cx] = vp.gp[ax];
01654 xp.max = Max(xp.max, xp.gp[cx]);
01655 xp.min = Min(xp.min, xp.gp[cx]);
01656 }
01657 }
01658 }
01659
01660
01661 if (counter!=NULL) {
01662 counter->StepIt();
01663 if (counter->isCanceled()) {
01664 xp.state = JBXL_GRAPH_CANCEL;
01665 return xp;
01666 }
01667 }
01668 }
01669 xp.rbound.cutdown(vp.rbound);
01670
01671 return xp;
01672 }
01673
01674
01675
01687 template <typename T> MSGraph<T> cut_object_MSGraph(MSGraph<T> vp, RBound<int> rb, bool ecnt=false)
01688 {
01689 int i, j, k;
01690 int cx, cy, cz, cp;
01691 int ax, ay, az, ap;
01692 MSGraph<T> xp;
01693
01694 xp.init();
01695 RBound<int> rx(0, vp.xs-1, 0, vp.ys-1, 0, vp.zs-1);
01696 CVCounter* counter = NULL;
01697
01698 if (ecnt) counter = GetUsableGlobalCounter();
01699 if (counter!=NULL) {
01700 if (counter->isCanceled()) {
01701 xp.state = JBXL_GRAPH_CANCEL;
01702 return xp;
01703 }
01704 counter->SetMax(vp.zs*2);
01705 }
01706
01707 rb.commonarea(rx);
01708 xp.set(rb.xmax-rb.xmin+1, rb.ymax-rb.ymin+1, rb.zmax-rb.zmin+1, vp.zero, vp.base, vp.RZxy);
01709 if (xp.isNull()) {
01710 xp.state = JBXL_GRAPH_MEMORY_ERROR;
01711 return xp;
01712 }
01713 xp.rbound = rb;
01714 xp.color = vp.color;
01715
01716 ap = vp.xs*vp.ys;
01717 cp = xp.xs*xp.ys;
01718
01719 for (k=0; k<xp.zs; k++) {
01720 cz = cp*k;
01721 az = ap*(k+rb.zmin);
01722 for (j=0; j<xp.ys; j++) {
01723 cy = cz + xp.xs*j;
01724 ay = az + vp.xs*(j+rb.ymin);
01725 for (i=0; i<xp.xs; i++) {
01726 cx = cy + i;
01727 ax = ay + i + rb.xmin;
01728 xp.gp[cx] = vp.gp[ax];
01729
01730 if (cx==0) xp.max = xp.min = xp.gp[cx];
01731 else {
01732 xp.max = Max(xp.max, xp.gp[cx]);
01733 xp.min = Min(xp.min, xp.gp[cx]);
01734 }
01735 }
01736 }
01737
01738
01739 if (counter!=NULL) {
01740 counter->StepIt();
01741 if (counter->isCanceled()) {
01742 xp.state = JBXL_GRAPH_CANCEL;
01743 return xp;
01744 }
01745 }
01746 }
01747 xp.rbound.cutdown(vp.rbound);
01748
01749 return xp;
01750 }
01751
01752
01753
01765 template <typename T> MSGraph<T> zoom_MSGraph(MSGraph<T> vp, double zm, int mode=ON)
01766 {
01767 int xss, yss, ps, pz, py;
01768 MSGraph<T> vx;
01769
01770 vx.init();
01771
01772 if (vp.gp==NULL) {
01773 vx.state = JBXL_GRAPH_NODATA_ERROR;
01774 return vx;
01775 }
01776 if (zm==0.0) {
01777 vx.state = JBXL_GRAPH_IVDARG_ERROR;
01778 return vx;
01779 }
01780 else if (zm<0.0) zm = -zm;
01781
01782 xss = (int)(vp.xs*zm) + 1;
01783 yss = (int)(vp.ys*zm) + 1;
01784
01785 vx.set(xss, yss, vp.zs);
01786 if (vx.isNull()) return vx;
01787 vx.color = vp.color;
01788
01789 ps = xss*yss;
01790
01791 if (mode==ON) {
01792 int ii, jj, kk, ll;
01793 double xx, yy, al, bt;
01794
01795 for(int k=0; k<vx.zs; k++) {
01796 pz = k*ps;
01797 for(int j=0; j<yss; j++) {
01798 py = pz + j*xss;
01799 for(int i=0; i<xss; i++) {
01800 xx = i/zm;
01801 yy = j/zm;
01802 ii = (int)xx;
01803 jj = (int)yy;
01804 if (ii>=vp.xs) ii = vp.xs - 1;
01805 if (jj>=vp.ys) jj = vp.ys - 1;
01806
01807 kk = ii + 1;
01808 ll = jj + 1;
01809 if (kk>=vp.xs) kk = vp.xs - 1;
01810 if (ll>=vp.ys) ll = vp.ys - 1;
01811
01812 if (xx>=0.) al = xx - ii;
01813 else al = 0.;
01814 if (yy>=0.) bt = yy - jj;
01815 else bt = 0.;
01816
01817 vx.gp[py+i] = (T)((1.-al)*(1.-bt)*vp.point(ii, jj, k) + al*(1.-bt)*vp.point(kk, jj, k)
01818 + (1.-al)*bt*vp.point(ii, ll, k) + al*bt*vp.point(kk, ll, k) + 0.5);
01819 }
01820 }
01821 }
01822 }
01823
01824 else {
01825 int ii, jj;
01826
01827 for(int k=0; k<vx.zs; k++) {
01828 pz = k*ps;
01829 for(int j=0; j<yss; j++) {
01830 py = pz + j*xss;
01831 for(int i=0; i<xss; i++) {
01832 ii = (int)(i/zm);
01833 jj = (int)(j/zm);
01834 vx.gp[py+i] = vp.point(ii, jj, k);
01835 }
01836 }
01837 }
01838 }
01839
01840 return vx;
01841 }
01842
01843
01844
01847 template <typename T> MSGraph<T> reduce_MSGraph(MSGraph<T> vp, double rc, int mode=ON)
01848 {
01849 int xss, yss, ps, pz, py;
01850 MSGraph<T> vx;
01851
01852 vx.init();
01853
01854 if (vp.gp==NULL) {
01855 vx.state = JBXL_GRAPH_NODATA_ERROR;
01856 return vx;
01857 }
01858 if (rc==0.0) {
01859 vx.state = JBXL_GRAPH_IVDARG_ERROR;
01860 return vx;
01861 }
01862 else if (rc<0.0) rc = -rc;
01863
01864 xss = (int)(vp.xs/rc);
01865 yss = (int)(vp.ys/rc);
01866
01867 vx.set(xss, yss, vp.zs);
01868 if (vx.isNull()) return vx;
01869 vx.color = vp.color;
01870
01871 ps = xss*yss;
01872
01873 if (mode==ON) {
01874 int ii, jj, kk, ll, ss, nn;
01875
01876 for(int z=0; z<vx.zs; z++) {
01877 pz = z*ps;
01878 for(int j=0; j<yss; j++) {
01879 py = pz + j*xss;
01880 for(int i=0; i<xss; i++) {
01881 ii = (int)(i*rc);
01882 jj = (int)(j*rc);
01883 if (ii>=vp.xs) ii = vp.xs - 1;
01884 if (jj>=vp.ys) jj = vp.ys - 1;
01885
01886 ss = nn = 0;
01887 for(int l=jj; l<jj+(int)rc; l++) {
01888 ll = l;
01889 if (ll>=vp.ys) ll = vp.ys - 1;
01890 for(int k=ii; k<ii+(int)rc; k++) {
01891 kk = k;
01892 if (kk>=vp.xs) kk = vp.xs - 1;
01893 ss += vp.point(kk, ll, z);
01894 nn++;
01895 }
01896 }
01897 vx.gp[py+i] = ss/nn;
01898 }
01899 }
01900 }
01901 }
01902
01903 else {
01904 int ii, jj;
01905
01906 for(int k=0; k<vx.zs; k++) {
01907 pz = k*ps;
01908 for(int j=0; j<yss; j++) {
01909 py = pz + j*xss;
01910 for(int i=0; i<xss; i++) {
01911 ii = (int)(i*rc);
01912 jj = (int)(j*rc);
01913 if (ii>=vp.xs) ii = vp.xs - 1;
01914 if (jj>=vp.ys) jj = vp.ys - 1;
01915 vx.gp[py+i] = vp.point(ii, jj, k);
01916 }
01917 }
01918 }
01919 }
01920
01921 return vx;
01922 }
01923
01924
01925
01931 template <typename T> MSGraph<T> rotate_MSGraph(MSGraph<T> vp, int xs, int ys, double cst, double snt, int mode=ON)
01932 {
01933 MSGraph<T> vs;
01934 T pt;
01935 int i, j, m, n;
01936 int ps, px, pz;
01937 double u, t, x, y, a, b;
01938
01939 vs.set(xs, ys, vp.zs, vp.zero, vp.base);
01940 if (vs.isNull()) return vs;
01941 vs.color = vp.color;
01942
01943 ps = vs.xs*vs.ys;
01944
01945 for (int k=0; k<vs.zs; k++) {
01946 pz = k*ps;
01947 for (int jj=0; jj<vs.ys; jj++) {
01948 px = pz + jj*vs.xs;
01949 for (int ii=0; ii<vs.xs; ii++) {
01950 u = ii - (vs.xs-1)/2.;
01951 t = (vs.ys-1)/2. - jj;
01952 x = u*cst + t*snt;
01953 y = - u*snt + t*cst;
01954 a = x + (vp.xs-1)/2.;
01955 b = (vp.ys-1)/2. - y;
01956 i = (int)a;
01957 j = (int)b;
01958
01959 if (i<0 || i>=vp.xs || j<0 || j>=vp.ys) {
01960 pt = vs.zero;
01961 }
01962 else {
01963 if (mode==ON) {
01964 if (a>=0.) a = a - i;
01965 else a = 0.;
01966 if (b>=0.) b = b - j;
01967 else b = 0.;
01968
01969 m = i + 1;
01970 n = j + 1;
01971 if (m>=vp.xs) m = vp.xs - 1;
01972 if (n>=vp.ys) n = vp.ys - 1;
01973 pt = (T)((1.-a)*(1.-b)*vp.point(i, j, k) + (1.-a)*b*vp.point(i, n, k)
01974 + a*(1.-b)*vp.point(m, j, k) + a*b*vp.point(m, n, k) + 0.5);
01975 }
01976 else {
01977 pt = vp.point(i, j, k);
01978 }
01979 }
01980 vs.gp[px+ii] = pt;
01981 }
01982 }
01983 }
01984
01985 return vs;
01986 }
01987
01988
01989
01992 template <typename T> MSGraph<T> rotate_MSGraph(MSGraph<T> vp, double th, int mode=ON)
01993 {
01994 MSGraph<T> vs;
01995 double cst = cos(th);
01996 double snt = cos(th);
01997 int xys = (int)sqrt(vp.xs*vp.xs+vp.ys*vp.ys) + 1;
01998
01999 vs = rotate_MSGraph<T>(vp, xys, xys, cst, snt, mode);
02000 return vs;
02001 }
02002
02003
02004
02015 template <typename T> MSGraph<T> x_reverse_MSGraph(MSGraph<T> vp, bool ecnt=false)
02016 {
02017 int i, j, k, cy, cz;
02018 MSGraph<T> wp;
02019 CVCounter* counter = NULL;
02020
02021 wp.init();
02022
02023 if (ecnt) counter = GetUsableGlobalCounter();
02024 if (counter!=NULL) {
02025 if (counter->isCanceled()) {
02026 wp.state = JBXL_GRAPH_CANCEL;
02027 return wp;
02028 }
02029 counter->SetMax(vp.zs);
02030 }
02031
02032 wp.set(vp.xs, vp.ys, vp.zs, vp.zero, vp.base, vp.RZxy);
02033 if (wp.isNull()) return wp;
02034 wp.color = vp.color;
02035
02036 for (k=0; k<vp.zs; k++) {
02037 cz = k*vp.xs*vp.ys;
02038 for (j=0; j<vp.ys; j++) {
02039 cy = cz + j*vp.xs;
02040 for (i=0; i<vp.xs; i++) {
02041 wp.gp[cy + i] = vp.gp[cy + vp.xs - 1 - i];
02042 }
02043 }
02044
02045
02046 if (counter!=NULL) {
02047 counter->StepIt();
02048 if (counter->isCanceled()) {
02049 wp.state = JBXL_GRAPH_CANCEL;
02050 return wp;
02051 }
02052 }
02053 }
02054
02055 return wp;
02056 }
02057
02058
02059
02069 template <typename T> void set_around_MSGraph(MSGraph<T> vp, int cc=0, int size=1)
02070 {
02071 int i, j, px1, px2;
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087 for(j=0; j<vp.ys; j++) {
02088 px1 = j*vp.xs;
02089 px2 = (j+1)*vp.xs-size;
02090 for(i=0; i<size; i++) {
02091 vp.gp[i+px1] = (T)cc;
02092 vp.gp[i+px2] = (T)cc;
02093 }
02094 }
02095
02096 for(j=0; j<size; j++) {
02097 px1 = j*vp.xs;
02098 px2 = (j+vp.ys-size)*vp.xs;
02099 for(i=0; i<vp.xs; i++) vp.gp[i+px1] = (T)cc;
02100 for(i=0; i<vp.xs; i++) vp.gp[i+px2] = (T)cc;
02101 }
02102
02103 }
02104
02105
02106
02119 template <typename T> MSGraph<T> grab_MSGraph(MSGraph<T> vp, int x1, int y1, int x2, int y2, int zs=0, int ze=0)
02120 {
02121 int i, j, k;
02122 int xs, xe, ys, ye;
02123 int xsize, ysize, zsize;
02124 MSGraph<T> xp;
02125
02126 xp.init();
02127 xs = Min(x1, x2);
02128 xe = Max(x1, x2);
02129 xs = Max(xs, 0);
02130 xe = Min(xe, vp.xs-1);
02131 ys = Min(y1, y2);
02132 ye = Max(y1, y2);
02133 ys = Max(ys, 0);
02134 ye = Min(ye, vp.ys-1);
02135 zs = Max(zs, 0);
02136 ze = Min(ze, vp.zs-1);
02137
02138 xsize = xe - xs + 1;
02139 ysize = ye - ys + 1;
02140 zsize = ze - zs + 1;
02141
02142 xp.set(xsize, ysize, zsize, vp.zero, vp.base);
02143 if (xp.isNull()) return xp;
02144 xp.color = vp.color;
02145
02146 xp.max = vp.point(xs, ys, zs);
02147 xp.min = xp.max;
02148
02149 for (k=0; k<zsize; k++) {
02150 for (j=0; j<ysize; j++) {
02151 for (i=0; i<xsize; i++) {
02152 T point = vp.point(xs+i, ys+j, zs+k);
02153 xp.point(i, j, k) = point;
02154 if (point>xp.max) xp.max = point;
02155 else if (point<xp.min) xp.min = point;
02156 }
02157 }
02158 }
02159
02160 xp.rbound.xmin = vp.rbound.xmin + xs;
02161 xp.rbound.xmax = vp.rbound.xmin + xe;
02162 xp.rbound.ymin = vp.rbound.ymin + ys;
02163 xp.rbound.ymax = vp.rbound.ymin + ye;
02164 xp.rbound.zmin = vp.rbound.zmin + zs;
02165 xp.rbound.zmax = vp.rbound.zmin + ze;
02166 return xp;
02167 }
02168
02169
02170
02184 template <typename T> MSGraph<T>* grab_MSGraph(MSGraph<T>* vp, int x1, int y1, int x2, int y2, int zs=0, int ze=0)
02185 {
02186 int i, j, k;
02187 int xs, xe, ys, ye;
02188 int xsize, ysize, zsize;
02189 MSGraph<T>* xp = new MSGraph<T>();
02190
02191 xp->init();
02192 xs = Min(x1, x2);
02193 xe = Max(x1, x2);
02194 xs = Max(xs, 0);
02195 xe = Min(xe, vp->xs-1);
02196 ys = Min(y1, y2);
02197 ye = Max(y1, y2);
02198 ys = Max(ys, 0);
02199 ye = Min(ye, vp->ys-1);
02200 zs = Max(zs, 0);
02201 ze = Min(ze, vp->zs-1);
02202
02203 xsize = xe - xs + 1;
02204 ysize = ye - ys + 1;
02205 zsize = ze - zs + 1;
02206
02207 xp->set(xsize, ysize, zsize, vp->zero, vp->base);
02208 xp->color = vp->color;
02209
02210 xp->max = vp->point(xs, ys, zs);
02211 xp->min = xp->max;
02212
02213 for (k=0; k<zsize; k++) {
02214 for (j=0; j<ysize; j++) {
02215 for (i=0; i<xsize; i++) {
02216 T point = vp->point(xs+i, ys+j, zs+k);
02217 xp->point(i, j, k) = point;
02218 if (point>xp->max) xp->max = point;
02219 else if (point<xp->min) xp->min = point;
02220 }
02221 }
02222 }
02223
02224 xp->rbound.xmin = vp->rbound.xmin + xs;
02225 xp->rbound.xmax = vp->rbound.xmin + xe;
02226 xp->rbound.ymin = vp->rbound.ymin + ys;
02227 xp->rbound.ymax = vp->rbound.ymin + ye;
02228 xp->rbound.zmin = vp->rbound.zmin + zs;
02229 xp->rbound.zmax = vp->rbound.zmin + ze;
02230 return xp;
02231 }
02232
02233
02234
02254 template <typename T> int addPaint_MSGraph(MSGraph<T> xp, int x, int y, int mn, int mx, int add, int mode=8)
02255 {
02256 int i, k, cc, cx, st, ed, num=0;
02257
02258 if (x<0 || x>=xp.xs || y<0 || y>=xp.ys) return 0;
02259
02260
02261 cc = (int)xp.point(x, y);
02262 while(x>0) {
02263 cx = (int)xp.point(x-1, y);
02264 if (cx>mx || cx<mn) break;
02265 cc = cx;
02266 x--;
02267 }
02268 st = k = x;
02269
02270
02271 while(k<xp.xs) {
02272 cx = (int)xp.point(k, y);
02273 if (cx>mx || cx<mn) break;
02274 xp.point(k, y) += add;
02275 cc = cx;
02276 num++;
02277 k++;
02278 }
02279 ed = k - 1;
02280
02281
02282 for (i=st; i<=ed; i++){
02283 cc = (int)xp.point(i, y) - add;
02284
02285
02286 if (y-1>=0 && y-1<xp.ys){
02287 cx = (int)xp.point(i, y-1);
02288 if (cx<=mx && cx>=mn) {
02289 num += addPaint_MSGraph(xp, i, y-1, mn, mx, add, mode);
02290 }
02291 if (mode>=8) {
02292 if (i-1>=0) {
02293 cx = (int)xp.point(i-1, y-1);
02294 if (cx<=mx && cx>=mn) {
02295 num += addPaint_MSGraph(xp, i-1, y-1, mn, mx, add, mode);
02296 }
02297 }
02298 if (i+1<xp.xs) {
02299 cx = (int)xp.point(i+1, y-1);
02300 if (cx<=mx && cx>=mn) {
02301 num += addPaint_MSGraph(xp, i+1, y-1, mn, mx, add, mode);
02302 }
02303 }
02304 }
02305 }
02306
02307
02308 if (y+1>=0 && y+1<xp.ys){
02309 cx = (int)xp.point(i, y+1);
02310 if (cx<=mx && cx>=mn) {
02311 num += addPaint_MSGraph(xp, i, y+1, mn, mx, add, mode);
02312 }
02313 if (mode>=8) {
02314 if (i-1>=0) {
02315 cx = (int)xp.point(i-1, y+1);
02316 if (cx<=mx && cx>=mn) {
02317 num += addPaint_MSGraph(xp, i-1, y+1, mn, mx, add, mode);
02318 }
02319 }
02320 if (i+1<xp.xs) {
02321 cx = (int)xp.point(i+1, y+1);
02322 if (cx<=mx && cx>=mn) {
02323 num += addPaint_MSGraph(xp, i+1, y+1, mn, mx, add, mode);
02324 }
02325 }
02326 }
02327 }
02328 }
02329
02330 return num;
02331 }
02332
02333
02334
02351 template <typename T> MSGraph<T> Density_Mask(MSGraph<T> vp, double rate, int mode=8, int work_color=0)
02352 {
02353 MSGraph<T> pp;
02354 int ps = vp.xs*vp.ys;
02355
02356 if (work_color==0) {
02357 if (vp.max==0 || vp.max==vp.zero) vp.get_minmax();
02358 work_color = vp.max + 1;
02359 }
02360 pp.mimicry(vp);
02361
02362 if ((int)(ps*rate+0.5)==ps) {
02363 int eflg = OFF;
02364 for (int i=0; i<ps; i++) {
02365 if (vp.gp[i]==vp.zero) {
02366 pp.state = 0;
02367 eflg = ON;
02368 break;
02369 }
02370 }
02371 if (eflg==OFF) {
02372 for (int i=0; i<ps; i++) pp.gp[i] = vp.gp[i];
02373 pp.state = ps;
02374 }
02375 return pp;
02376 }
02377
02378 MSGraph<T> xp;
02379 xp.set(vp.xs+2, vp.ys+2, 1, vp.zero, vp.base, vp.RZxy);
02380 xp.color = vp.color;
02381
02382 for (int j=0; j<vp.ys; j++) {
02383 for (int i=0; i<vp.xs; i++) {
02384 xp.gp[(j+1)*xp.xs+i+1] = vp.gp[j*vp.xs+i];
02385 }
02386 }
02387 set_around_MSGraph(xp, xp.zero+1);
02388 MSGraph_Paint(xp, 0, 0, xp.zero+1, work_color-1, work_color, mode);
02389
02390 int nn = 0;
02391 for (int j=0; j<vp.ys; j++) {
02392 for (int i=0; i<vp.xs; i++) {
02393 if (xp.gp[(j+1)*xp.xs+i+1]==work_color) {
02394 pp.gp[j*pp.xs+i] = vp.gp[j*vp.xs+i];
02395 nn++;
02396 }
02397 }
02398 }
02399 pp.state = nn;
02400
02401 if ((int)(ps*rate+0.5)>nn) {
02402 pp.state = 0;
02403 pp.clear();
02404 }
02405
02406 xp.free();
02407 return pp;
02408 }
02409
02410
02411
02426 template <typename T> MSGraph<T> Density_Filter(MSGraph<T> vp, int size, double rate, int mode=8, int work_color=0)
02427 {
02428 MSGraph<T> pp, xp, wp;
02429 int hsize = size/2;
02430
02431 if (work_color==0) {
02432 if (vp.max==0 || vp.max==vp.zero) vp.get_minmax();
02433 work_color = vp.max + 1;
02434 }
02435
02436 if (hsize==0) hsize = 1;
02437 size = hsize*2 + 1;
02438 pp.set(size, size, 1, vp.zero, vp.base);
02439 wp.mimicry(vp);
02440
02441 for (int j=hsize; j<vp.ys-hsize; j++) {
02442 for (int i=hsize; i<vp.xs-hsize; i++) {
02443
02444 for (int m=-hsize; m<=hsize; m++) {
02445 int vx = (m+j)*vp.xs + i;
02446 int px = (m+hsize)*pp.xs + hsize;
02447
02448 for (int n=-hsize; n<=hsize; n++) {
02449 pp.gp[px+n] = vp.gp[vx+n];
02450 }
02451 }
02452
02453 xp = Density_Mask<T>(pp, rate, mode, work_color);
02454
02455 if (xp.state!=0) {
02456 for (int m=-hsize; m<=hsize; m++) {
02457 int wx = (m+j)*wp.xs + i;
02458 int xx = (m+hsize)*xp.xs + hsize;
02459
02460 for (int n=-hsize; n<=hsize; n++) {
02461 if (xp.gp[xx+n]!=vp.zero) {
02462 wp.gp[wx+n] = xp.gp[xx+n];
02463 }
02464 }
02465 }
02466 }
02467 xp.free();
02468 }
02469 }
02470
02471 pp.free();
02472 return wp;
02473 }
02474
02475
02476
02484 template <typename T> void delete_noise_MSGraph(MSGraph<T> vp, int size, int mode=8, int work_color=0)
02485 {
02486 int i, j, k;
02487 int num, ps ,pp;
02488
02489 ps = vp.xs*vp.ys;
02490 if (work_color==0) {
02491 if (vp.max==0 || vp.max==vp.zero) vp.get_minmax();
02492 work_color = vp.max + 1;
02493 }
02494
02495 for(j=0; j<vp.ys; j++) {
02496 pp = j*vp.xs;
02497 for(i=0; i<vp.xs; i++) {
02498 if (vp.gp[i+pp]>vp.zero && vp.gp[i+pp]<work_color) {
02499 num = addPaint_MSGraph(vp, i, j, 1, work_color-1, work_color, mode);
02500 if (num<=size) {
02501 int n = 0;
02502 for (k=i+pp; k<ps; k++) {
02503 if (vp.gp[k]>=work_color) {
02504 vp.gp[k] = vp.zero;
02505 n++;
02506 if (n>=num) break;
02507 }
02508 }
02509 }
02510 else {
02511 int n = 0;
02512 for (k=i+pp; k<ps; k++) {
02513 if (vp.gp[k]>=work_color) {
02514 vp.gp[k] = -vp.gp[k];
02515 n++;
02516 if (n>=num) break;
02517 }
02518 }
02519 }
02520 }
02521 }
02522 }
02523
02524 for (i=0; i<ps; i++) {
02525 if (vp.gp[i]<vp.zero) vp.gp[i] = - vp.gp[i] - work_color;
02526 }
02527 }
02528
02529
02530 }
02531
02532
02533 #endif
02534