26 # define finite(x) _finite(x)
48 Lines.append(
new Line(0, 0,
cx, 0, QPen(QPen::black,0)));
49 Lines.append(
new Line(0, 0, 0,
cy, QPen(QPen::black,0)));
50 Lines.append(
new Line(0, 0,
cx/2,
cy/2, QPen(QPen::black,0)));
59 void Rect3DDiagram::calcCoefficients()
61 double rX = double(
rotX) *
M_PI/180.0;
62 double rY = double(
rotY) *
M_PI/180.0;
63 double rZ = double(
rotZ) *
M_PI/180.0;
65 cxy =
sin(rZ); cxx =
cos(rZ);
66 cxz =
sin(rY); rY =
cos(rY);
67 cyz =
sin(rX); czz =
cos(rX);
68 rX = cyz*cxz; rZ = czz*cxz;
69 cyx = czz * cxy + rX * cxx;
70 cyy = czz * cxx - rX * cxy;
71 czx = cyz * cxy - rZ * cxx;
72 czy = cyz * cxx + rZ * cxy;
73 cxx *= rY; cxy *= -rY; cyz *= -rY; czz *= rY;
77 double Rect3DDiagram::calcX_2D(
double x,
double y,
double z)
79 return (cxx * x + cxy * y + cxz * z) * scaleX;
83 double Rect3DDiagram::calcY_2D(
double x,
double y,
double z)
85 return (cyx * x + cyy * y + cyz * z) * scaleY;
89 double Rect3DDiagram::calcZ_2D(
double x,
double y,
double z)
91 return czx * x + czy * y + czz * z;
98 int Rect3DDiagram::calcCross(
int *Xses,
int *Yses)
100 double x3D, y3D, z3D, x2D[8], y2D[8], z2D;
101 double XMIN_2D, XMAX_2D, YMIN_2D, YMAX_2D, ZMIN_2D;
104 scaleX = scaleY = 1.0;
105 XMIN_2D = YMIN_2D = XMAX_2D = YMAX_2D = ZMIN_2D = 0.0;
107 if(z & 1) x3D = 1.0;
else x3D = 0.0;
108 if(z & 2) y3D = 1.0;
else y3D = 0.0;
109 if(z & 4) z3D = 1.0;
else z3D = 0.0;
110 x2D[z] = calcX_2D(x3D, y3D, z3D);
111 y2D[z] = calcY_2D(x3D, y3D, z3D);
112 z2D = calcZ_2D(x3D, y3D, z3D);
114 if(x2D[z] < XMIN_2D) XMIN_2D = x2D[z];
115 if(x2D[z] > XMAX_2D) XMAX_2D = x2D[z];
116 if(y2D[z] < YMIN_2D) YMIN_2D = y2D[z];
117 if(y2D[z] > YMAX_2D) YMAX_2D = y2D[z];
118 if(z2D < ZMIN_2D) { ZMIN_2D = z2D; Center = z; }
121 scaleX = double(
x2) / (XMAX_2D - XMIN_2D);
122 scaleY = double(
y2) / (YMAX_2D - YMIN_2D);
123 xorig = -XMIN_2D * scaleX;
124 yorig = -YMIN_2D * scaleY;
127 *(Xses+z) =
int(x2D[z] * scaleX + 0.5 + xorig);
128 *(Yses+z) =
int(y2D[z] * scaleY + 0.5 + yorig);
136 float *px,
float *py,
Axis*)
138 double x3D = *(zD++);
139 double y3D = *(zD++);
142 z3D =
sqrt(x3D*x3D + y3D*y3D);
149 if(fabs(y3D) > 1
e-250)
150 x3D =
sqrt(x3D*x3D + y3D*y3D);
175 *px = float(calcX_2D(x3D, y3D, z3D)) + xorig;
176 *py = float(calcY_2D(x3D, y3D, z3D)) + yorig;
187 void Rect3DDiagram::calcCoordinate3D(
double x,
double y,
double zr,
double zi,
191 zr =
sqrt(zr*zr + zi*zi);
198 if(fabs(zi) > 1
e-250)
199 zr =
sqrt(zr*zr + zi*zi);
223 p->
x = int(calcX_2D(x, y, zr) + 0.5 + xorig);
224 p->
y = int(calcY_2D(x, y, zr) + 0.5 + yorig);
227 pz->
z = float(calcZ_2D(x, y, zr));
231 bool Rect3DDiagram::isHidden(
int x,
int y,
tBound *Bounds,
char *zBuffer)
234 if( (Bounds+x)->max < y ) (Bounds+
x)->max = y;
235 if( (Bounds+x)->min > y ) (Bounds+x)->min = y;
238 return ( *(zBuffer + (y>>3) + x * ((
y2+7)>>3)) & (1 << (y & 7)) ) != 0;
243 void Rect3DDiagram::enlargeMemoryBlock(
tPoint3D* &MemEnd)
246 int Size = MemEnd - Mem + 256;
249 pMem += Mem - MemEnd;
250 MemEnd = Mem + Size - 5;
262 tBound *Bounds,
char *zBuffer)
265 int x1_ = p->
x, y1_ = p->
y;
266 int x2_ = (p+1)->x, y2_ = (p+1)->y;
268 bool wasHidden = isHidden(x1_, y1_, Bounds, zBuffer);
270 if((p->
done & 1) == 0)
273 int ax_ = 0, ay_ = 0;
274 int ix_, iy_, dx_, dy_, of_;
305 for(
int i=dx_;
i>1;
i--) {
315 if( isHidden(x1_, y1_, Bounds, zBuffer) != wasHidden )
316 if((p->
done & 1) == 0) {
317 wasHidden = !wasHidden;
327 enlargeMemoryBlock(MemEnd);
333 if(isHidden((p+1)->x, (p+1)->y, Bounds, zBuffer))
334 if(((p+1)->done & 1) == 0)
342 int Rect3DDiagram::comparePoint3D(
const void *Point1,
const void *Point2)
346 int Rect3DDiagram::comparePointZ(
const void *Point1,
const void *Point2)
355 void Rect3DDiagram::removeHiddenLines(
char *zBuffer,
tBound *Bounds)
358 double *px, *py, *pz;
362 int i, j, z, dx, dy, Size=0;
380 if(g->
cPointsX.count() < 1)
continue;
392 for(i=g->
countY-1; i>=0; i--) {
393 px = g->
cPointsX.getFirst()->Points;
395 for(j=dx; j>0; j--) {
396 calcCoordinate3D(*(px++), *py, *pz, *(pz+1),
pMem++, zp++);
402 if(dy > 0)
if((i % dy) == 0)
405 (
pMem-1)->done |= 512;
411 for(j=g->
countY/dy; j>0; j--) {
412 for(i=dx; i>0; i--) {
413 for(z=dy; z>0; z--) {
431 (
pMem-1)->done |= 256;
442 for(i=g->
countY-1; i>=0; i--) {
443 if(dy > 0)
if(i % dy) {
444 for(j=dx-1; j>0; j--) {
445 zp->
z += (zp+1)->z + (zp+dx)->z + (zp+dx+1)->z;
454 for(j=dx; j>0; j--) {
470 qDebug(
"##########################################");
471 qDebug(
"Size 1b: Size=%d, %d, %d", Size,
pMem-Mem, zp-zMem);
473 qDebug(
"xyPoints: %d/%d - %d - %d", p->
x, p->
y, p->
No, p->
done);
474 qDebug(
"------------------------------------------");
475 for(
tPointZ *p=zMem; p-zMem<Size; p++)
476 qDebug(
"zPoints: %g - %d", p->z, p->
No);
484 qsort(zMem, Size,
sizeof(
tPointZ), comparePointZ);
487 qDebug(
"--------------------------- z sorting");
488 for(
tPointZ *p=zMem; p-zMem<Size; p++)
489 qDebug(
"zPoints: %g - %d", p->z, p->
No);
495 tPoint3D *MemEnd = Mem + 2*Size - 5;
505 for(
int No = g->
countY/dy * (dx-1)*(dy-1); No>0; No--) {
508 for(i=
x2; i>=0; i--) {
509 (Bounds+
i)->max = INT_MIN;
510 (Bounds+
i)->min = INT_MAX;
515 calcLine(p, MemEnd, Bounds, zBuffer);
518 calcLine(p, MemEnd, Bounds, zBuffer);
521 calcLine(p, MemEnd, Bounds, zBuffer);
524 calcLine(p, MemEnd, Bounds, zBuffer);
527 for(i=
x2-1; i>=0; i--)
528 if( (Bounds+i)->max > INT_MIN) {
529 pc = zBuffer + i * ((
y2+7)>>3);
530 for(j=(Bounds+i)->min; j<=(Bounds+
i)->max; j++)
531 *(pc + (j>>3)) |= (1 << (j & 7));
540 qDebug(
"--------------------------- hidden lines %d", pMem-Mem);
542 qDebug(
"xyPoints: %d/%d - %d - %d", p->
x, p->
y, p->
No, p->
done);
548 qsort(Mem, pMem - Mem,
sizeof(
tPoint3D), comparePoint3D);
551 qDebug(
"--------------------------- last sorting %d", pMem-Mem);
553 qDebug(
"xyPoints: %d/%d - %d - %d", p->
x, p->
y, p->
No, p->
done);
560 void Rect3DDiagram::removeHiddenCross(
int x1_,
int y1_,
int x2_,
int y2_,
561 char *zBuffer,
tBound *Bounds)
578 calcLine(Mem, p, Bounds, zBuffer);
583 if(((p-1)->done & 4) == 0)
584 Lines.append(
new Line((p-1)->x, (p-1)->y, p->
x, p->
y, QPen(QPen::black,0)));
627 int Rect3DDiagram::calcAxis(
Axis *
Axis,
int x,
int y,
628 double xD,
double phi,
bool Right)
630 double GridStep, corr, yD, stepD, GridNum, Expo;
631 double xstepD, ystepD;
636 int count, gx, gy, w;
638 if(phi > 0.0) Expo = phi -
M_PI/2.0;
639 else Expo = phi +
M_PI/2.0;
640 gx = int(5.4 *
cos(Expo) + 0.5);
641 gy = int(5.4 *
sin(Expo) + 0.5);
648 double upD = Axis->
up;
649 if(yD > 1.5*stepD) yD = 10.0*stepD;
657 ystepD = corr *
log10(yD / fabs(Axis->
low));
658 while(ystepD <= xD) {
661 if(Axis->
up < 0.0) tmp =
'-'+tmp;
662 w = metrics.width(tmp);
663 if(maxWidth < w) maxWidth = w;
665 xLen = int(ystepD *
cos(phi) + 0.5) +
x;
666 yLen = int(ystepD *
sin(phi) + 0.5) + y;
668 Texts.append(
new Text(xLen+3+gx, yLen-6+gy, tmp));
670 Texts.append(
new Text(xLen-w-2-gx, yLen-6-gy, tmp));
673 Lines.append(
new Line(xLen-gx, yLen-gy, xLen+gx, yLen+gy,
674 QPen(QPen::black,0)));
682 count = int((xD - yD) / stepD) + 1;
684 xstepD = stepD *
cos(phi);
685 ystepD = stepD *
sin(phi);
686 xD = yD *
cos(phi) + 0.5 + double(x);
687 yD = yD *
sin(phi) + 0.5 + double(y);
689 if(Axis->
up == 0.0) Expo =
log10(fabs(Axis->
up-Axis->
low));
690 else Expo =
log10(fabs(Axis->
up));
692 for(; count>0; count--) {
695 if(fabs(GridNum) < 0.01*
pow(10.0, Expo)) GridNum = 0.0;
698 w = metrics.width(tmp);
699 if(maxWidth < w) maxWidth = w;
701 Texts.append(
new Text(x+3+gx, y-6+gy, tmp));
703 Texts.append(
new Text(x-w-2-gx, y-6-gy, tmp));
707 Lines.append(
new Line(x-gx, y-gy, x+gx, y+gy, QPen(QPen::black,0)));
717 void Rect3DDiagram::createAxis(Axis *Axis,
bool Right,
718 int x1_,
int y1_,
int x2_,
int y2_)
722 double phi, cos_phi, sin_phi;
723 int x, y, z, w, valid, Index = 0;
724 if(Axis == &
yAxis) Index = 1;
731 cos_phi =
sqrt(
double(x*x) +
double(y*y));
732 phi =
atan2(
double(y),
double(x));
734 valid = calcAxis(Axis, x1_, y1_, cos_phi, phi, Right);
739 if(fabs(phi-1
e-5) >
M_PI/2.0) {
740 x1_ = x2_; cos_phi *= -1;
741 y1_ = y2_; sin_phi *= -1;
743 x = x1_ + int(
double(valid)*sin_phi);
744 y = y1_ - int(
double(valid)*cos_phi);
745 if(Axis->
Label.isEmpty()) {
763 x += int(
double(metrics.lineSpacing())*sin_phi);
764 y -= int(
double(metrics.lineSpacing())*cos_phi);
765 w = metrics.width(s);
766 Texts.append(
new Text(x+
int(
double((z-w)>>1)*cos_phi),
767 y+
int(
double((z-w)>>1)*sin_phi),
768 s, pg->
Color, 12.0, cos_phi, sin_phi));
772 x += int(
double(metrics.lineSpacing())*sin_phi);
773 y -= int(
double(metrics.lineSpacing())*cos_phi);
774 w = metrics.width(Axis->
Label);
775 Texts.append(
new Text(x+
int(
double((z-w)>>1)*cos_phi),
776 y+
int(
double((z-w)>>1)*sin_phi),
777 Axis->
Label, Qt::black, 12.0, cos_phi, sin_phi));
788 double GridStep, corr, zD, zDstep, GridNum;
852 Lines.append(
new Line(X[o^1], Y[o^1], X[o^3], Y[o^3], QPen(QPen::black,0)));
853 Lines.append(
new Line(X[o^2], Y[o^2], X[o^3], Y[o^3], QPen(QPen::black,0)));
856 Lines.append(
new Line(X[o^2], Y[o^2], X[o^6], Y[o^6], QPen(QPen::black,0)));
857 Lines.append(
new Line(X[o^4], Y[o^4], X[o^6], Y[o^6], QPen(QPen::black,0)));
860 Lines.append(
new Line(X[o^1], Y[o^1], X[o^5], Y[o^5], QPen(QPen::black,0)));
861 Lines.append(
new Line(X[o^4], Y[o^4], X[o^5], Y[o^5], QPen(QPen::black,0)));
865 if(X[o^1] < X[o^2]) w = 2;
871 createAxis(&
xAxis, w == 2, X[z], Y[z], X[z2], Y[z2]);
876 createAxis(&
yAxis, w == 1, X[z], Y[z], X[z2], Y[z2]);
881 createAxis(&
zAxis,
true, X[z], Y[z], X[z2], Y[z2]);
885 w = (
x2+1) * (
y2/8 + 1);
888 zBuffer = (
char*)malloc(w);
889 memset(zBuffer, 0, w);
896 removeHiddenLines(zBuffer, Bounds);
903 removeHiddenCross(X[o^1], Y[o^1], X[o], Y[o], zBuffer, Bounds);
904 removeHiddenCross(X[o^2], Y[o^2], X[o], Y[o], zBuffer, Bounds);
905 removeHiddenCross(X[o^4], Y[o^4], X[o], Y[o], zBuffer, Bounds);
914 Lines.append(
new Line(X[o], Y[o], X[o^1], Y[o^1], QPen(QPen::black,0)));
915 Lines.append(
new Line(X[o], Y[o], X[o^2], Y[o^2], QPen(QPen::black,0)));
916 Lines.append(
new Line(X[o], Y[o], X[o^4], Y[o^4], QPen(QPen::black,0)));
926 Lines.append(
new Line(0, 0,
x2, 0, QPen(QPen::black,0)));
927 Lines.append(
new Line(0,
y2, 0, 0, QPen(QPen::black,0)));
939 int Size = ((2*(g->
cPointsX.getFirst()->count) + 1) * g->
countY) + 10;
945 float *p = (
float*)malloc( Size*
sizeof(
float) );
952 float dx=0.0, dy=0.0, xtmp=0.0, ytmp=0.0;
953 double Stroke=10.0, Space=10.0;
962 if((pMem-1)->done & 12)
981 }
while(((pMem++)->done & 256) == 0);
986 Stroke = 10.0; Space = 6.0;
989 Stroke = 2.0; Space = 4.0;
992 Stroke = 24.0; Space = 8.0;
1001 if((pMem-1)->done & 12)
1014 }
while(((pMem++)->done & 512) == 0);
1022 double alpha, dist = -Stroke;
1027 if(pMem->done & 4) {
1029 if((pMem-1)->done & 12)
1049 dist +=
sqrt(
double(dx*dx + dy*dy));
1050 if((Flag == 1) && (dist <= 0.0)) {
1056 alpha =
atan2(
double(dy),
double(dx));
1060 *(p++) = xtmp -
float(dist*
cos(alpha));
1061 *(p++) = ytmp -
float(dist*
sin(alpha));
1072 if(*(p-3) < 0) p -= 2;
1085 if(pMem->done & 8) {
1089 if((*(p-2) < 0) || (*(p-1) < 0))
1102 }
while(((pMem++)->done & 256) == 0);
1141 Name = QObject::tr(
"3D-Cartesian");
1142 BitmapFile = (
char *)
"rect3d";