00001
00010 #include "graph.h"
00011 #include "jbxl_state.h"
00012
00013
00025 int get_idat(WSGraph gd, int xx, int yy, int zz)
00026 {
00027 int ret = 0;
00028
00029 if (xx>0&&yy>0&&zz>0&&xx<gd.xs&&yy<gd.ys&&zz<gd.zs) {
00030 ret = gd.gp[zz*gd.xs*gd.ys + yy*gd.xs + xx];
00031 }
00032 return ret;
00033 }
00034
00035
00036
00049 int get_wdat(WSGraph gd, double xx, double yy, double zz, IRBound rb)
00050 {
00051 int ix, iy, iz;
00052 int ret = 0;
00053
00054 if (chk_RZxy()) zz = zz*RZxy;
00055
00056 ix = (int)(xx+0.5) - rb.xmin;
00057 iy = (int)(yy+0.5) - rb.ymin;
00058 iz = (int)(zz+0.5) - rb.zmin;
00059
00060 if (ix>=0&&ix<gd.xs&&iy>=0&&iy<gd.ys&&iz>=0&&iz<gd.zs){
00061 ret = gd.gp[iz*gd.xs*gd.ys + iy*gd.xs + ix];
00062 }
00063 return ret;
00064 }
00065
00066
00067
00079 int get_bdat(BSGraph gd, int xx, int yy, int zz)
00080 {
00081 int ret = 0;
00082
00083 if (xx>0&&yy>0&&zz>0&&xx<gd.xs&&yy<gd.ys&&zz<gd.zs) {
00084 ret = (int)gd.gp[zz*gd.xs*gd.ys + yy*gd.xs + xx];
00085 }
00086 return ret;
00087 }
00088
00089
00090
00101 void set_idat(WSGraph gd, int ix, int iy, int iz, int cc)
00102 {
00103 if (ix>=0&&ix<gd.xs&&iy>=0&&iy<gd.ys&&iz>=0&&iz<gd.zs){
00104 gd.gp[iz*gd.xs*gd.ys + iy*gd.xs + ix] = cc;
00105 }
00106 }
00107
00108
00109
00123 void set_wdat(WSGraph gd, double xx, double yy, double zz, int cc, IRBound rb)
00124 {
00125 int i, j, k;
00126 int x, y, z;
00127 int ix, iy, iz;
00128
00129 if (chk_RZxy()) zz = zz*RZxy;
00130
00131 if (rb.misc==OFF) {
00132 ix = (int)(xx+0.5) - rb.xmin;
00133 iy = (int)(yy+0.5) - rb.ymin;
00134 iz = (int)(zz+0.5) - rb.zmin;
00135
00136 if (ix>=0&&ix<gd.xs&&iy>=0&&iy<gd.ys&&iz>=0&&iz<gd.zs){
00137 gd.gp[iz*gd.xs*gd.ys + iy*gd.xs + ix] = cc;
00138 }
00139 }
00140 else {
00141 x = (int)(xx) - rb.xmin;
00142 y = (int)(yy) - rb.ymin;
00143 z = (int)(zz) - rb.zmin;
00144
00145 for (i=0; i<=1; i++) {
00146 for (j=0; j<=1; j++) {
00147 for (k=0; k<=1; k++) {
00148 ix = i + x;
00149 iy = j + y;
00150 iz = k + z;
00151 if (ix>=0&&ix<gd.xs&&iy>=0&&iy<gd.ys&&iz>=0&&iz<gd.zs){
00152 gd.gp[iz*gd.xs*gd.ys + iy*gd.xs + ix] = cc;
00153 }
00154 }
00155 }
00156 }
00157 }
00158 return;
00159 }
00160
00161
00162
00173 void set_bdat(BSGraph gd, int ix, int iy, int iz, int cc)
00174 {
00175 if (ix>=0&&ix<gd.xs&&iy>=0&&iy<gd.ys&&iz>=0&&iz<gd.zs){
00176 gd.gp[iz*gd.xs*gd.ys + iy*gd.xs + ix] = cc;
00177 }
00178 }
00179
00180
00181
00197 void local2world(WSGraph gd, WSGraph vp, vector ox, vector oz, vector ex, double* pcsf, double* psnf)
00198 {
00199 int x, y, z, cx, cy, cz;
00200 double px, py, pz, xx, yy, zz;
00201 double cst, snt, csf=0.0, snf=1.0;
00202 IRBound rb;
00203
00204 if (pcsf!=NULL && psnf!=NULL) {
00205 csf = *pcsf;
00206 snf = *psnf;
00207 }
00208
00209 rb.xmin = rb.ymin = rb.zmin = 0;
00210 rb.misc = ON;
00211 topola(ex, &cst, &snt, &csf, &snf);
00212
00213 for(z=0; z<vp.zs; z++) {
00214 cz = z*vp.xs*vp.ys;
00215 for(y=0; y<vp.ys; y++) {
00216 cy = cz + y*vp.xs;
00217 for(x=0; x<vp.xs; x++) {
00218 cx = cy + x;
00219 if(vp.gp[cx]!=0) {
00220 px = z - oz.z;
00221 py = oz.x - x;
00222 pz = oz.y - y;
00223 xx = px*snt*csf - py*snf - pz*cst*csf + ox.x;
00224 yy = px*snt*snf + py*csf - pz*cst*snf + ox.y;
00225 zz = px*cst + pz*snt + ox.z;
00226 set_wdat(gd, xx, yy, zz, vp.gp[cx], rb);
00227 }
00228 }
00229 }
00230 }
00231
00232 if (pcsf!=NULL && psnf!=NULL) {
00233 *pcsf = csf;
00234 *psnf = snf;
00235 }
00236 }
00237
00238
00239
00256 void paint(WSGraph vp, int x, int y, int mn, int mx, int c, int m)
00257 {
00258 int i, j, k, cc;
00259
00260 if (c<=mx && c>=mn) {
00261 fprintf(stderr,"PAINT: c = %d. Not be %d< c <%d\n\n",c,mn,mx);
00262 return;
00263 }
00264
00265 cc = vp.gp[y*vp.xs+x];
00266 if (cc>mx || cc<mn) return;
00267
00268 while(x>0) {
00269 if (vp.gp[y*vp.xs+x-1]>mx || vp.gp[y*vp.xs+x-1]<mn) break;
00270 x--;
00271 }
00272 k = x;
00273
00274 while(k<vp.xs) {
00275 if (vp.gp[y*vp.xs+k]>mx || vp.gp[y*vp.xs+k]<mn) break;
00276 vp.gp[y*vp.xs+k] = c;
00277 k++;
00278 }
00279 k--;
00280
00281 for (i=x; i<=k; i++){
00282 if (y-1>=0 && y-1<vp.ys){
00283 j = (y-1)*vp.xs+i;
00284 if (vp.gp[j]<=mx && vp.gp[j]>=mn) {
00285 paint(vp, i, y-1, mn, mx, c, m);
00286 }
00287
00288 if (Xabs(m)==8) {
00289 if (i-1>=0) {
00290 if (vp.gp[j-1]<=mx && vp.gp[j-1]>=mn) {
00291 paint(vp, i-1, y-1, mn, mx, c, m);
00292 }
00293 }
00294 if (i+1<vp.xs) {
00295 if (vp.gp[j+1]<=mx && vp.gp[j+1]>=mn) {
00296 paint(vp, i+1, y-1, mn, mx, c, m);
00297 }
00298 }
00299 }
00300 }
00301
00302 if (y+1>=0 && y+1<vp.ys){
00303 j = (y+1)*vp.xs+i;
00304 if (vp.gp[j]<=mx && vp.gp[j]>=mn) {
00305 paint(vp, i, y+1, mn, mx, c, m);
00306 }
00307
00308 if (Xabs(m)==8) {
00309 if (i-1>=0) {
00310 if (vp.gp[j-1]<=mx && vp.gp[j-1]>=mn) {
00311 paint(vp, i-1, y+1, mn, mx, c, m);
00312 }
00313 }
00314 if (i+1<vp.xs) {
00315 if (vp.gp[j+1]<=mx && vp.gp[j+1]>=mn) {
00316 paint(vp, i+1, y+1, mn, mx, c, m);
00317 }
00318 }
00319 }
00320 }
00321 }
00322 return;
00323 }
00324
00325
00326
00344 void paint3d(WSGraph vp, int x, int y, int z, int mn, int mx, int c, int m)
00345 {
00346 int i;
00347
00348 _paint_3d(vp, x, y, z, mn, mx, SWORDMAX, m);
00349 for (i=0; i<vp.xs*vp.ys*vp.zs; i++) {
00350 if (vp.gp[i]==SWORDMAX) vp.gp[i] = c;
00351 }
00352 }
00353
00354
00355
00361 void _paint_3d(WSGraph vp, int x, int y, int z, int mn, int mx, int c, int m)
00362 {
00363 int i, j, ps, cc;
00364 WSGraph xp;
00365
00366 ps = vp.xs*vp.ys;
00367 xp.xs = vp.xs;
00368 xp.ys = vp.ys;
00369 xp.zs = 1;
00370 xp.gp = &(vp.gp[z*ps]);
00371 xp.state = vp.state;
00372
00373 cc = xp.gp[y*xp.xs+x];
00374 if (cc>mx || cc<mn) return;
00375 paint(xp, x, y, mn, mx, c, m);
00376 if (m<0) {
00377 DEBUG_MODE fprintf(stderr,"_paint_3d: zz = %d\n",z);
00378 }
00379
00380 for (i=0; i<ps; i++) {
00381 if (xp.gp[i]==c) {
00382 x = i%vp.xs;
00383 y = i/vp.xs;
00384 if (z-1>=0) {
00385 j = (z-1)*ps+y*vp.xs+x;
00386 if (vp.gp[j]<=mx && vp.gp[j]>=mn) _paint_3d(vp, x, y, z-1, mn, mx, c, m);
00387 }
00388 if (z+1<vp.zs) {
00389 j = (z+1)*ps+y*vp.xs+x;
00390 if (vp.gp[j]<=mx && vp.gp[j]>=mn) _paint_3d(vp, x, y, z+1, mn, mx, c, m);
00391 }
00392 }
00393 }
00394
00395 return;
00396 }
00397
00398
00399
00416 void bline(BSGraph vp, int x1, int y1, int x2, int y2, int cc)
00417 {
00418 int thresh=0, index;
00419 int xunit=1;
00420 int yunit=1;
00421 int xdiff=x2-x1;
00422 int ydiff=y2-y1;
00423
00424 if (xdiff<0) {
00425 xdiff = -xdiff;
00426 xunit = -1;
00427 }
00428 if (ydiff<0) {
00429 ydiff = -ydiff;
00430 yunit = -1;
00431 }
00432
00433 if (xdiff>ydiff) {
00434 for (index=0; index<xdiff+1; index++) {
00435 set_bdat(vp, x1, y1, 0, cc);
00436 x1 = x1 + xunit;
00437 thresh = thresh + ydiff;
00438 if (thresh>=xdiff) {
00439 thresh = thresh - xdiff;
00440 y1 = y1 + yunit;
00441 }
00442 }
00443 }
00444 else {
00445 for (index=0; index<ydiff+1; index++) {
00446 set_bdat(vp, x1, y1, 0, cc);
00447 y1 = y1 + yunit;
00448 thresh = thresh + xdiff;
00449 if (thresh>=ydiff) {
00450 thresh = thresh - ydiff;
00451 x1 = x1 + xunit;
00452 }
00453 }
00454 }
00455 }
00456
00457
00458
00475 void line(WSGraph vp, int x1, int y1, int x2, int y2, int cc)
00476 {
00477 int thresh=0, index;
00478 int xunit=1;
00479 int yunit=1;
00480 int xdiff=x2-x1;
00481 int ydiff=y2-y1;
00482
00483 if (xdiff<0) {
00484 xdiff = -xdiff;
00485 xunit = -1;
00486 }
00487 if (ydiff<0) {
00488 ydiff = -ydiff;
00489 yunit = -1;
00490 }
00491
00492 if (xdiff>ydiff) {
00493 for (index=0; index<xdiff+1; index++) {
00494 set_idat(vp, x1, y1, 0, cc);
00495 x1 = x1 + xunit;
00496 thresh = thresh + ydiff;
00497 if (thresh>=xdiff) {
00498 thresh = thresh - xdiff;
00499 y1 = y1 + yunit;
00500 }
00501 }
00502 }
00503 else {
00504 for (index=0; index<ydiff+1; index++) {
00505 set_idat(vp, x1, y1, 0, cc);
00506 y1 = y1 + yunit;
00507 thresh = thresh + xdiff;
00508 if (thresh>=ydiff) {
00509 thresh = thresh - ydiff;
00510 x1 = x1 + xunit;
00511 }
00512 }
00513 }
00514 }
00515
00516
00517
00536 void triangle(WSGraph vp, int x1, int y1, int x2, int y2, int x3, int y3, int cc, int mode)
00537 {
00538 line(vp, x1, y1, x2, y2, cc);
00539 line(vp, x2, y2, x3, y3, cc);
00540 line(vp, x3, y3, x1, y1, cc);
00541
00542 if (mode==ON) {
00543 int i, j, minx, miny, maxx, maxy;
00544 minx = maxx = x1;
00545 miny = maxy = y1;
00546 minx = Min(x2, minx);
00547 minx = Min(x3, minx);
00548 miny = Min(y2, miny);
00549 miny = Min(y3, miny);
00550 maxx = Max(x2, maxx);
00551 maxx = Max(x3, maxx);
00552 maxy = Max(y2, maxy);
00553 maxy = Max(y3, maxy);
00554
00555 for (j=miny; j<=maxy; j++) {
00556 for (i=minx; i<=maxx; i++) {
00557 if (isinctri(x1, y1, x2, y2, x3, y3, i, j)) Px(vp, i, j) = cc;
00558 }
00559 }
00560 }
00561 return;
00562 }
00563
00564
00565
00574 int isinctri(int x1, int y1, int x2, int y2, int x3, int y3, int xx, int yy)
00575 {
00576 int cx, cy;
00577
00578 cx = (x1 + x2 + x3)/3;
00579 cy = (y1 + y2 + y3)/3;
00580
00581 if (isCrossLine(x1, y1, x2, y2, xx, yy, cx, cy)<0) return FALSE;
00582 if (isCrossLine(x1, y1, x3, y3, xx, yy, cx, cy)<0) return FALSE;
00583 if (isCrossLine(x2, y2, x3, y3, xx, yy, cx, cy)<0) return FALSE;
00584 return TRUE;
00585 }
00586
00587
00588
00605 void box(WSGraph vp, int x1, int y1, int x2, int y2, int cc, int mode)
00606 {
00607 line(vp, x1, y1, x2, y1, cc);
00608 line(vp, x2, y1, x2, y2, cc);
00609 line(vp, x2, y2, x1, y2, cc);
00610 line(vp, x1, y2, x1, y1, cc);
00611
00612 if (mode==ON) {
00613 paint(vp, (x1+x2)/2, (y1+y2)/2, 0, cc-1, cc, 4);
00614 }
00615 return;
00616 }
00617
00618
00619
00630 void bline3d(BSGraph gd, int x1, int y1, int z1, int x2, int y2, int z2, int cc)
00631 {
00632 int i;
00633 int xx, yy, zz, dx, dy, dz;
00634 int ux=1, uy=1, uz=1;
00635 int sx=0, sy=0, sz=0;
00636
00637 dx = x2 - x1;
00638 dy = y2 - y1;
00639 dz = z2 - z1;
00640
00641 if (dx<0) {
00642 dx = -dx;
00643 ux = -1;
00644 }
00645 if (dy<0) {
00646 dy = -dy;
00647 uy = -1;
00648 }
00649 if (dz<0) {
00650 dz = -dz;
00651 uz = -1;
00652 }
00653
00654 xx = x1;
00655 yy = y1;
00656 zz = z1;
00657
00658 set_bdat(gd, xx, yy, zz, cc);
00659 if (dx>=dy && dx>=dz) {
00660 for (i=1; i<=dx; i++) {
00661 xx = xx + ux;
00662 sy = sy + dy;
00663 sz = sz + dz;
00664 if (sy>dx) {
00665 sy = sy - dx;
00666 yy = yy + uy;
00667 }
00668 if (sz>dx) {
00669 sz = sz - dx;
00670 zz = zz + uz;
00671 }
00672 set_bdat(gd, xx, yy, zz, cc);
00673 }
00674 }
00675 else if (dy>dx && dy>=dz) {
00676 for (i=1; i<=dy; i++) {
00677 yy = yy + uy;
00678 sx = sx + dx;
00679 sz = sz + dz;
00680 if (sx>dy) {
00681 sx = sx - dy;
00682 xx = xx + ux;
00683 }
00684 if (sz>dy) {
00685 sz = sz - dy;
00686 zz = zz + uz;
00687 }
00688 set_bdat(gd, xx, yy, zz, cc);
00689 }
00690 }
00691 else {
00692 for (i=1; i<=dz; i++) {
00693 zz = zz + uz;
00694 sx = sx + dx;
00695 sy = sy + dy;
00696 if (sx>dz) {
00697 sx = sx - dz;
00698 xx = xx + ux;
00699 }
00700 if (sy>dz) {
00701 sy = sy - dz;
00702 yy = yy + uy;
00703 }
00704 set_bdat(gd, xx, yy, zz, cc);
00705 }
00706 }
00707 }
00708
00709
00710
00721 void line3d(WSGraph gd, int x1, int y1, int z1, int x2, int y2, int z2, int cc)
00722 {
00723 int i;
00724 int xx, yy, zz, dx, dy, dz;
00725 int ux=1, uy=1, uz=1;
00726 int sx=0, sy=0, sz=0;
00727
00728 dx = x2 - x1;
00729 dy = y2 - y1;
00730 dz = z2 - z1;
00731
00732 if (dx<0) {
00733 dx = -dx;
00734 ux = -1;
00735 }
00736 if (dy<0) {
00737 dy = -dy;
00738 uy = -1;
00739 }
00740 if (dz<0) {
00741 dz = -dz;
00742 uz = -1;
00743 }
00744
00745 xx = x1;
00746 yy = y1;
00747 zz = z1;
00748
00749 set_idat(gd, xx, yy, zz, cc);
00750 if (dx>=dy && dx>=dz) {
00751 for (i=1; i<=dx; i++) {
00752 xx = xx + ux;
00753 sy = sy + dy;
00754 sz = sz + dz;
00755 if (sy>dx) {
00756 sy = sy - dx;
00757 yy = yy + uy;
00758 }
00759 if (sz>dx) {
00760 sz = sz - dx;
00761 zz = zz + uz;
00762 }
00763 set_idat(gd, xx, yy, zz, cc);
00764 }
00765 }
00766 else if (dy>dx && dy>=dz) {
00767 for (i=1; i<=dy; i++) {
00768 yy = yy + uy;
00769 sx = sx + dx;
00770 sz = sz + dz;
00771 if (sx>dy) {
00772 sx = sx - dy;
00773 xx = xx + ux;
00774 }
00775 if (sz>dy) {
00776 sz = sz - dy;
00777 zz = zz + uz;
00778 }
00779 set_idat(gd, xx, yy, zz, cc);
00780 }
00781 }
00782 else {
00783 for (i=1; i<=dz; i++) {
00784 zz = zz + uz;
00785 sx = sx + dx;
00786 sy = sy + dy;
00787 if (sx>dz) {
00788 sx = sx - dz;
00789 xx = xx + ux;
00790 }
00791 if (sy>dz) {
00792 sy = sy - dz;
00793 yy = yy + uy;
00794 }
00795 set_idat(gd, xx, yy, zz, cc);
00796 }
00797 }
00798 }
00799
00800
00801
00813 void circle(WSGraph gd, int x, int y, int r, int cc, int mode)
00814 {
00815 double yy, dy, dt;
00816 int i, nn, cx;
00817 int ix, iy, ux=1;
00818 int *px, *py;
00819
00820 if (r<=0) return;
00821
00822 px = (int*)malloc(sizeof(int)*(r+1));
00823 py = (int*)malloc(sizeof(int)*(r+1));
00824 if (px==NULL || py==NULL) {
00825 free(px);
00826 free(py);
00827 return;
00828 }
00829
00830 ix = 0;
00831 iy = r;
00832 yy = (double)r;
00833 nn = 0;
00834 px[0] = ix;
00835 py[0] = iy;
00836
00837 cx = (y+iy)*gd.xs + (x+ix);
00838 gd.gp[cx] = cc;
00839 while(iy>=ix) {
00840 ix = ix + ux;
00841 dt = -ux/yy;
00842 dy = ix*dt;
00843 yy = yy + dy;
00844 iy = (int)yy;
00845
00846 set_idat(gd, x+ix, y+iy, 0, cc);
00847 nn++;
00848 px[nn] = ix;
00849 py[nn] = iy;
00850 }
00851
00852 for (i=0; i<=nn; i++) {
00853 ix = py[nn-i];
00854 iy = px[nn-i];
00855 set_idat(gd, x+ix, y+iy, 0, cc);
00856 }
00857
00858 for (i=0; i<=nn; i++) {
00859 ix = py[i];
00860 iy = -px[i];
00861 set_idat(gd, x+ix, y+iy, 0, cc);
00862 }
00863
00864 for (i=0; i<=nn; i++) {
00865 ix = px[nn-i];
00866 iy = -py[nn-i];
00867 set_idat(gd, x+ix, y+iy, 0, cc);
00868 }
00869
00870 for (i=0; i<=nn; i++) {
00871 ix = -px[i];
00872 iy = -py[i];
00873 set_idat(gd, x+ix, y+iy, 0, cc);
00874 }
00875
00876 for (i=0; i<=nn; i++) {
00877 ix = -py[nn-i];
00878 iy = -px[nn-i];
00879 set_idat(gd, x+ix, y+iy, 0, cc);
00880 }
00881
00882 for (i=0; i<=nn; i++) {
00883 ix = -py[i];
00884 iy = px[i];
00885 set_idat(gd, x+ix, y+iy, 0, cc);
00886 }
00887
00888 for (i=0; i<=nn; i++) {
00889 ix = -px[nn-i];
00890 iy = py[nn-i];
00891 set_idat(gd, x+ix, y+iy, 0, cc);
00892 }
00893
00894 if (mode==ON) paint(gd, x, y, 0, cc-1, cc, 4);
00895
00896 free(px);
00897 free(py);
00898 }
00899
00900
00901
00914 void circle3d(WSGraph gd, vector ox, vector ex, int rr, int cc, int mode)
00915 {
00916 vector oz;
00917 WSGraph vp;
00918
00919 vp = make_WSGraph(2*rr+3, 2*rr+3, 1);
00920 if (vp.gp==NULL) return;
00921 circle(vp, rr+1, rr+1, rr, cc, mode);
00922
00923 oz = set_vector((vp.xs-1)/2., (vp.ys-1)/2., 0.0);
00924 ex = unit_vector(ex);
00925 local2world(gd, vp, ox, oz, ex, NULL, NULL);
00926
00927 free(vp.gp);
00928 }
00929
00930
00931
00943 void pool(WSGraph gd, vector a, vector b, int rr, int cc)
00944 {
00945 int i, ll, cz;
00946 vector ox, oz, ev;
00947 WSGraph vp, px;
00948
00949 ox = sub_vector(b, a);
00950 ll = (int)(ox.n + 0.5);
00951 vp = px = make_WSGraph(2*rr+3, 2*rr+3, ll);
00952 if (vp.gp==NULL) return;
00953
00954 for (i=0; i<vp.zs; i++) {
00955 cz = i*vp.xs*vp.ys;
00956 px.gp = &(vp.gp[cz]);
00957 circle(px, rr+1, rr+1, rr, cc, ON);
00958 }
00959
00960 oz = set_vector((vp.xs-1)/2., (vp.ys-1)/2., 0.);
00961 ev = unit_vector(ox);
00962 local2world(gd, vp, a, oz, ev, NULL, NULL);
00963 free(vp.gp);
00964
00965 return;
00966 }
00967
00968
00969
00982 void torus(WSGraph gd, vector ox, vector ex, int rr, int ra, int cc)
00983 {
00984 int i, nn;
00985 double dt, th, xx, yy, zz, sn, cs;
00986 WSGraph vp;
00987 vector ve, vo, vz;
00988
00989 vp = make_WSGraph(2*(rr+ra)+3, 2*(rr+ra)+3, 2*ra+3);
00990 if (vp.gp==NULL) return;
00991 nn = (int)(2*PI*(rr+ra)*2);
00992 dt = 2.0*PI/nn;
00993
00994 zz = (vp.zs-1)/2.;
00995 for (i=0; i<nn; i++) {
00996 th = dt*i;
00997 sn = sin(th);
00998 cs = cos(th);
00999 xx = (vp.xs-1)/2. + rr*cs;
01000 yy = (vp.ys-1)/2. - rr*sn;
01001 vo = set_vector(xx, yy, zz);
01002 ve = set_vector(sn, cs, 0.0);
01003 circle3d(vp, vo, ve, ra, cc, ON);
01004 }
01005 vz = set_vector((vp.xs-1)/2., (vp.ys-1)/2., (vp.zs-1)/2.);
01006 ex = unit_vector(ex);
01007
01008 local2world(gd, vp, ox, vz, ex, NULL, NULL);
01009 free(vp.gp);
01010 return;
01011 }
01012
01013
01014
01029 void sphere(WSGraph vp, vector a, int r, int cc, int mode)
01030 {
01031 int i, j, k, rx, nn, s = 1;
01032 double th, fi, cs, sn, cf, sf, dt;
01033 double xx, yy, zz, zc;
01034 WSGraph xp;
01035 IRBound rb;
01036
01037 memset(&xp, 0, sizeof(WSGraph));
01038
01039 if (mode==1) {
01040 xp.xs = vp.xs;
01041 xp.ys = vp.ys;
01042 xp.zs = 1;
01043
01044 for (k=(int)(a.z-r+0.5); k<=(int)(a.z+r+0.5); k++) {
01045 if (k>=0 && k<vp.zs) {
01046 xp.gp = &vp.gp[k*vp.xs*vp.ys];
01047 rx = (int)(sqrt(r*r-(a.z-k)*(a.z-k))+0.5);
01048 circle(xp, (int)a.x, (int)a.y, rx, cc, ON);
01049 }
01050 }
01051 }
01052 else {
01053 rb.xmin = rb.ymin = rb.zmin = 0;
01054 rb.misc = OFF;
01055
01056 nn = (int)(2*PI*r + 0.5)*2;
01057 dt = PI/nn;
01058 for (i=0; i<=nn; i++) {
01059 th = dt*i;
01060 sn = sin(th);
01061 cs = cos(th);
01062 zz = r*cs + a.z;
01063 zc = zz*RZxy;
01064 if (mode==-1) {
01065 if (zc<s) zz = s/RZxy;
01066 if (zc>vp.zs-s-1) zz = (vp.zs-s-1)/RZxy;
01067 }
01068 for (j=0; j<=2*nn; j++) {
01069 fi = dt*j;
01070 cf = cos(fi);
01071 sf = sin(fi);
01072 xx = r*sn*cf + a.x;
01073 yy = r*sn*sf + a.y;
01074 if (mode==-1) {
01075 if (xx<s) xx = (double)s;
01076 if (yy<s) yy = (double)s;
01077 if (xx>vp.xs-s-1) xx = (double)(vp.xs-s-1);
01078 if (yy>vp.ys-s-1) yy = (double)(vp.ys-s-1);
01079 }
01080 set_wdat(vp, xx, yy, zz, cc, rb);
01081 }
01082 }
01083 }
01084 return;
01085 }
01086
01087
01088
01097 WSGraph x_reverse_wsg(WSGraph vp)
01098 {
01099 int i, j, cy;
01100 WSGraph wp;
01101
01102 wp = make_WSGraph(vp.xs, vp.ys, 1);
01103 if (wp.gp==NULL) {
01104 memset(&wp, 0, sizeof(WSGraph));
01105 wp.state = JBXL_GRAPH_MEMORY_ERROR;
01106 return wp;
01107 }
01108
01109 for (j=0; j<vp.ys; j++) {
01110 cy = j*vp.xs;
01111 for (i=0; i<vp.xs; i++) {
01112 wp.gp[cy +i] = vp.gp[cy + vp.xs - 1 - i];
01113 }
01114 }
01115 return wp;
01116 }
01117
01118
01119
01134 void topola(vector nv, double* cst, double* snt, double* csf, double* snf)
01135 {
01136 if (nv.n>EPS && nv.n!=1.0) {
01137 nv.x = nv.x/nv.n;
01138 nv.y = nv.y/nv.n;
01139 nv.z = nv.z/nv.n;
01140 }
01141
01142 if (nv.z<-1.0) nv.z = -1.0;
01143 if (nv.z> 1.0) nv.z = 1.0;
01144 *cst = nv.z;
01145 *snt = sqrt(1.0-nv.z*nv.z);
01146
01147 if (*snt<EPS) {
01148 *cst = Sign(*cst);
01149 *snt = 0.0;
01150
01151
01152 }
01153 else {
01154 *csf = nv.x / *snt;
01155 *snf = nv.y / *snt;
01156 }
01157 return;
01158 }
01159
01160
01161
01174 WSGraph cut_object(WSGraph vp, int cc, IRBound* rb, int blank)
01175 {
01176 int i, j, k, cx, ax;
01177 WSGraph xp;
01178
01179 init_IRBound(rb);
01180
01181 for (i=0; i<vp.xs; i++)
01182 for (j=0; j<vp.ys; j++)
01183 for (k=0; k<vp.zs; k++) {
01184 cx = vp.xs*vp.ys*k + vp.xs*j + i;
01185 if (vp.gp[cx]>=cc) {
01186 rb->xmax = Max(rb->xmax, i);
01187 rb->ymax = Max(rb->ymax, j);
01188 rb->zmax = Max(rb->zmax, k);
01189 rb->xmin = Min(rb->xmin, i);
01190 rb->ymin = Min(rb->ymin, j);
01191 rb->zmin = Min(rb->zmin, k);
01192 }
01193 }
01194
01195 if (blank!=0) {
01196 rb->xmax += blank;
01197 rb->ymax += blank;
01198 rb->zmax += blank;
01199 rb->xmin -= blank;
01200 rb->ymin -= blank;
01201 rb->zmin -= blank;
01202 rb->xmin = Max(rb->xmin, 0);
01203 rb->ymin = Max(rb->ymin, 0);
01204 rb->zmin = Max(rb->zmin, 0);
01205 rb->zmax = Min(rb->zmax, vp.zs-1);
01206 }
01207
01208 xp.xs = rb->xmax - rb->xmin + 1;
01209 xp.ys = rb->ymax - rb->ymin + 1;
01210 xp.zs = rb->zmax - rb->zmin + 1;
01211 xp = make_WSGraph(xp.xs, xp.ys, xp.zs);
01212 if (xp.gp==NULL) {
01213 xp.state = JBXL_GRAPH_MEMORY_ERROR;
01214 return xp;
01215 }
01216
01217 for (i=0; i<xp.xs; i++) {
01218 for (j=0; j<xp.ys; j++) {
01219 for (k=0; k<xp.zs; k++) {
01220 cx = xp.xs*xp.ys*k + xp.xs*j + i;
01221 ax = vp.xs*vp.ys*(k+rb->zmin) + vp.xs*(j+rb->ymin) + (i+rb->xmin);
01222 if (vp.gp[ax]>=cc) xp.gp[cx] = vp.gp[ax];
01223 }
01224 }
01225 }
01226
01227 return xp;
01228 }
01229
01230
01231
01240 void set_around(WSGraph vp, int cc)
01241 {
01242 int i, px1, px2;
01243
01244 for (i=0; i<vp.xs; i++){
01245 px1 = i;
01246 px2 = (vp.ys-1)*vp.xs + i;
01247 vp.gp[px1] = cc;
01248 vp.gp[px2] = cc;
01249 }
01250 for (i=1; i<vp.ys-1; i++){
01251 px1 = vp.xs*i;
01252 px2 = vp.xs*(i+1) - 1;
01253 vp.gp[px1] = cc;
01254 vp.gp[px2] = cc;
01255 }
01256 }
01257
01258
01259
01271 WSGraph zoom_WSGraph(WSGraph vp, int zm, int mode)
01272 {
01273 WSGraph vx;
01274 int i, j, k, l, m, n;
01275 sWord ws, wt;
01276
01277 memset(&vx, 0, sizeof(WSGraph));
01278 if (zm<1) {
01279 vx.state = JBXL_GRAPH_IVDARG_ERROR;
01280 return vx;
01281 }
01282
01283 vx = make_WSGraph(vp.xs*zm, vp.ys*zm, 1);
01284 if (vx.gp==NULL) {
01285 memset(&vx, 0, sizeof(WSGraph));
01286 vx.state = JBXL_GRAPH_MEMORY_ERROR;
01287 return vx;
01288 }
01289
01290 if (mode==1){
01291 for(j=0; j<vp.ys; j++) {
01292 for(i=0; i<vp.xs; i++) {
01293 m = i + j*vp.xs;
01294 n = (i + j*vx.xs)*zm;
01295 if(i==vp.xs-1) wt = 0;
01296 else wt = (vp.gp[m+1] - vp.gp[m])/zm;
01297 if(j==vp.ys-1) ws = 0;
01298 else ws = (vp.gp[m+vp.xs] - vp.gp[m])/zm;
01299
01300 for(k=0; k<zm; k++) {
01301 for(l=0; l<zm; l++) {
01302 vx.gp[n+l+k*vx.xs] = ws*k + wt*l + vp.gp[m];
01303 }
01304 }
01305 }
01306 }
01307 }
01308 else {
01309 for(j=0; j<vp.ys; j++) {
01310 for(i=0; i<vp.xs; i++) {
01311 m = i + j*vp.xs;
01312 n = (i + j*vx.xs)*zm;
01313 for(k=0; k<zm; k++) {
01314 for(l=0; l<zm; l++) {
01315 vx.gp[n+l+k*vx.xs] = vp.gp[m];
01316 }
01317 }
01318 }
01319 }
01320 }
01321 return vx;
01322 }
01323
01324
01325
01338 WSGraph grab_WSGraph(WSGraph vp, int x1, int y1, int x2, int y2)
01339 {
01340 int i, j, xs, xe, ys, ye, xsize, ysize;
01341 WSGraph xp;
01342
01343 xs = Min(x1, x2);
01344 xe = Max(x1, x2);
01345 xe = Min(xe, vp.xs-1);
01346 ys = Min(y1, y2);
01347 ye = Max(y1, y2);
01348 ye = Min(ye, vp.ys-1);
01349 xsize = xe - xs + 1;
01350 ysize = ye - ys + 1;
01351
01352 xp = make_WSGraph(xsize, ysize, 1);
01353 if (xp.gp==NULL) {
01354 memset(&xp, 0, sizeof(WSGraph));
01355 xp.state = JBXL_GRAPH_MEMORY_ERROR;
01356 return xp;
01357 }
01358
01359 for (j=0; j<ysize; j++) {
01360 for (i=0; i<xsize; i++) {
01361 Px(xp, i, j) = Px(vp, i+xs, j+ys);
01362 }
01363 }
01364
01365 return xp;
01366 }
01367
01368
01369
01380 void copy_WSGraph(WSGraph src, WSGraph dst)
01381 {
01382 int i, ssz, dsz, sz;
01383
01384 if (src.zs<=0) src.zs = 1;
01385 if (dst.zs<=0) dst.zs = 1;
01386 ssz = src.xs*src.ys*src.zs;
01387 dsz = dst.xs*dst.ys*dst.zs;
01388 sz = Min(ssz, dsz);
01389
01390 for (i=0; i<sz; i++) dst.gp[i] = src.gp[i];
01391 for (i=sz; i<dsz; i++) dst.gp[i] = 0;
01392 return;
01393 }
01394
01395
01396