📄 axes.cpp
字号:
if(Ticks && NumTicks) for(i = 0; i < NumTicks; i++){
if(Ticks[i] && Ticks[i]->Command(cmd, tmpl, o))
return parent->Command(CMD_REDRAW, 0L, o);
}
break;
case CMD_MUTATE:
if(!parent || !(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
if(axisLabel == tmpPlots[0]) {
Undo.MutateGO(&axisLabel, tmpPlots[1], 0L, o);
return true;
}
break;
case CMD_REPL_GO:
if(!(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
if(Ticks) for(i = 0; i < NumTicks; i++) if(Ticks[i] && Ticks[i] == tmpPlots[0]){
return bModified = ReplaceGO((GraphObj**)&Ticks[i], tmpPlots);
}
if(axisLabel && axisLabel == tmpPlots[0])
return bModified = ReplaceGO((GraphObj**)&axisLabel, tmpPlots);
return false;
case CMD_UPDATE:
UpdateTicks();
case CMD_SETSCROLL:
cmd = CMD_REDRAW;
case CMD_REDRAW:
bModified = true;
case CMD_SET_GO3D:
if(parent) return parent->Command(cmd, tmpl, o);
return false;
case CMD_RESET_LINE:
return o->SetLine(&axline);
case CMD_FLUSH:
if(Ticks) {
for(i = 0; i < NumTicks; i++) if(Ticks[i]) DeleteGO(Ticks[i]);
free(Ticks); NumTicks = 0; Ticks = 0L;
}
if(l_segs){
for (i = 0; i < nl_segs; i++) if(l_segs[i]) delete(l_segs[i]);
free(l_segs); l_segs = 0L; nl_segs = 0;
}
if(scaleOut) delete(scaleOut);
scaleOut = drawOut = 0L;
axis->Start = axis->min;
return true;
case CMD_AUTOSCALE: //we receive this command to update ticks after rescaling
if(axis && (AxisDEF*)tmpl == axis && (axis->flags & AXIS_AUTOSCALE) &&
(axis->flags & AXIS_AUTOTICK)) return Command(CMD_FLUSH, tmpl, o);
break;
case CMD_SAVE_TICKS:
SavVarInit(200 * NumTicks);
if(Ticks) for(i = 0; i < NumTicks; i++) {
if(Ticks[i]) Ticks[i]->FileIO(SAVE_VARS);
}
sv_ptr = SavVarFetch();
Undo.SavVarBlock(this, &sv_ptr, 0);
if(axis->flags & AXIS_AUTOTICK){
Undo.ValDword(this, &axis->flags, UNDO_CONTINUE);
axis->flags &= ~(AXIS_AUTOTICK | AXIS_AUTOSCALE);
}
bModified = true;
return true;
}
return false;
}
void
Axis::SetTick(long idx, double val, DWORD flags, char *txt)
{
char *l;
if((flags & AXIS_ANGULAR) && !(flags & 0x03)) flags |= AXIS_POSTICKS;
Ticks[idx] = new Tick(this, data, val, flags);
if(!txt) {
WriteNatFloatToBuff(TmpTxt, val);
l = strdup(TmpTxt+1);
}
else l = strdup(txt);
if(!gl_type) {
}
if(Ticks[idx]) {
Ticks[idx]->Command(CMD_SET_GRIDTYPE, (void*) &gl_type, 0L);
if(l) Ticks[idx]->Command(CMD_SETTEXT, l, 0L);
Ticks[idx]->Command(CMD_TLB_TXTDEF, &tlbdef, 0L);
if(flags & AXIS_GRIDLINE) Ticks[idx]->Command(CMD_SET_GRIDLINE, &GridLine, 0L);
Ticks[idx]->SetSize(SIZE_TICK_ANGLE, tick_angle);
Ticks[idx]->SetSize(SIZE_AXIS_TICKS, sizAxTick);
Ticks[idx]->Command(CMD_TICK_TYPE, &tick_type, 0L);
}
if(l) free(l);
}
void
Axis::CreateTicks()
{
int i, n, nstep;
char *format;
double fVal, tmp;
DWORD flags;
Command(CMD_FLUSH, 0L, 0L);
if((axis->flags & 0xf000) == AXIS_LOG) { //log-axis
if(axis->Start > defs.min4log) tmp = log10(axis->Start);
else switch (type){
case 1: //x axis
case 2: //y axis
case 3: //z axis
axis->Start = tmp = log10(base4log(axis, type-1));
if(axis->Start <= 0.0) axis->Start = 1.0;
break;
default: return;
}
n = (int)(log10(axis->max) - tmp);
Ticks = (Tick**)calloc(100, sizeof(Tick*));
for(NumTicks=0, i=(int)floor(tmp); NumTicks <90; i++){
SetTick(NumTicks++, pow(10.0, i), axis->flags, 0L);
if(n < 5) {
flags = n ? axis->flags | AXIS_MINORTICK : axis->flags;
SetTick(NumTicks++, 5.0*pow(10.0, i), axis->flags, 0L);
SetTick(NumTicks++, 3.0*pow(10.0, i), flags, 0L);
SetTick(NumTicks++, 4.0*pow(10.0, i), flags, 0L);
SetTick(NumTicks++, 6.0*pow(10.0, i), flags, 0L);
SetTick(NumTicks++, 7.0*pow(10.0, i), flags, 0L);
SetTick(NumTicks++, 8.0*pow(10.0, i), flags, 0L);
SetTick(NumTicks++, 9.0*pow(10.0, i), flags, 0L);
if(n < 3) SetTick(NumTicks++, 2.0*pow(10.0, i), axis->flags, 0L);
else SetTick(NumTicks++, 2.0*pow(10.0, i), axis->flags | AXIS_MINORTICK, 0L);
}
else {
SetTick(NumTicks++, 5.0*pow(10.0, i), axis->flags | AXIS_MINORTICK, 0L);
}
}
}
else { //linear axis
if((axis->flags & 0xf000) == AXIS_RECI) {
NiceStep(axis, 8);
format = GetNumFormat(floor(log10(axis->Step)));
fVal = axis->Start;
}
else {
NiceStep(axis, 4);
format = GetNumFormat(floor(log10(fabs(axis->max - axis->min))));
fVal = axis->Start;
}
nstep = 1+(int)((axis->max-axis->min)/axis->Step);
Ticks = (Tick**)calloc(nstep+2, sizeof(Tick*));
if(!Ticks) return;
for(NumTicks = 0; NumTicks < nstep && fVal <= axis->max;
NumTicks++, fVal += axis->Step) {
sprintf(TmpTxt, format, fVal);
SetTick(NumTicks, fVal, axis->flags, TmpTxt);
}
}
}
void
Axis::ManuTicks(double sa, double st, int n, DWORD flags)
{
int j, m;
char *format;
double fVal, mival, mist;
Command(CMD_FLUSH, 0L, 0L);
mist = st/(double)(n+1);
m = (int)(((axis->max-axis->min) / st)*(double)(n+1))+n+2;
format = GetNumFormat(floor(log10(st)));
Ticks = (Tick**)calloc(m, sizeof(Tick*));
for(NumTicks = 0, fVal = sa; NumTicks < m && fVal <= axis->max; NumTicks++) {
sprintf(TmpTxt, format, fVal);
SetTick(NumTicks, fVal, flags, TmpTxt);
for(j = 0; j < n; j++) {
mival = fVal+mist*(double)j +mist;
if(mival < axis->max) {
sprintf(TmpTxt, format, mival);
NumTicks++;
SetTick(NumTicks, mival, flags | AXIS_MINORTICK, TmpTxt);
}
}
fVal += st;
}
}
bool
Axis::GetValuePos(double val, double *fix, double *fiy, double *fiz, anyOutput *op)
{
double tmp1;
int i;
bool bRet = true;
anyOutput *o;
fPOINT3D p1, p2;
lfPOINT fdp, fip;
*fix = *fiy = *fiz = 0.0;
if(!op || !parent || (val < axis->min && val < axis->max) ||
(val > axis->min && val > axis->max)) return false;
for(i = 0; i < axis->nBreaks && bRet; i++)
if((val >= axis->breaks[i].fx && val <= axis->breaks[i].fy) ||
(val <= axis->breaks[i].fx && val >= axis->breaks[i].fy)) bRet = false;
if(axis->owner == this && scaleOut) o = scaleOut;
else o = op;
if(axis->flags & AXIS_3D) {
p1.fx = GetSize(SIZE_XPOS); p1.fy = GetSize(SIZE_YPOS); p1.fz = GetSize(SIZE_ZPOS);
tmp1 = defs.cUnits == 1 ? 2.54 : defs.cUnits == 2 ? 1.0 : 25.4;
tmp1 /= op->VPscale;
switch(type) {
case 1: p1.fx += (tmp1 * (op->fx2fix(val)- op->Box1.Xmin)/op->hres); break;
case 2: p1.fy += (tmp1 * (op->fy2fiy(val)- op->Box1.Ymax)/op->vres); break;
case 3: p1.fz += (tmp1 * (op->fz2fiz(val)- op->Box1z.fx)/op->hres); break;
default: return false;
}
op->cvec2ivec(&p1, &p2);
*fix = p2.fx; *fiy = p2.fy; *fiz = p2.fz;
if((p2.fx < (flim[0].fx-1) && p2.fx < (flim[1].fx-1)) ||
(p2.fx > (flim[0].fx+1) && p2.fx > (flim[1].fx+1)) ||
(p2.fy < (flim[0].fy-1) && p2.fy < (flim[1].fy-1)) ||
(p2.fy > (flim[0].fy+1) && p2.fy > (flim[1].fy+1)) ||
(p2.fz < (flim[0].fz-1) && p2.fz < (flim[1].fz-1)) ||
(p2.fz > (flim[0].fz+1) && p2.fz > (flim[1].fz+1))) bRet = false;
return bRet;
}
else if(axis->flags & AXIS_ANGULAR) {
fdp.fx = val; fdp.fy = parent->GetSize(SIZE_BOUNDS_TOP);
op->fp2fip(&fdp, &fip); *fix = fip.fx; *fiy = fip.fy;
return bRet;
}
else if(type == 1 && fabs(flim[1].fx-flim[0].fx)>10.0) { //x dominant
tmp1 = (o->fx2fix(val)-flim[0].fx)/(flim[1].fx-flim[0].fx);
*fix = flim[0].fx - tmp1*(flim[0].fx - flim[1].fx);
*fiy = flim[0].fy - tmp1*(flim[0].fy - flim[1].fy);
}
else if(type == 2 && fabs(flim[1].fy-flim[0].fy)>10.0){ //y dominant
tmp1 = (o->fy2fiy(val)-flim[1].fy)/(flim[0].fy-flim[1].fy);
*fix = flim[1].fx + tmp1*(flim[0].fx - flim[1].fx);
*fiy = flim[1].fy + tmp1*(flim[0].fy - flim[1].fy);
}
if(tmp1 < -.005f || tmp1 > 1.005) return false;
return bRet;
}
void
Axis::BreakSymbol(POINT3D *p1, double dsi, double dcsi, bool connect, anyOutput *o)
{
POINT *sym = 0L, *csym = 0L;
static POINT lp;
int j, n = 0;
double tmp;
switch (brksym){
case 2:
n = o->un2ix(brksymsize);
if(!(sym = (POINT*)calloc(2, sizeof(POINT))))return;
if(!(csym = (POINT*)calloc(2, sizeof(POINT)))){
free(sym);
return;
}
sym[0].x = (int)((-(n>>1))*dsi) + (int)((n>>2)*dcsi);
sym[0].y = (int)((-(n>>1))*dcsi) + (int)((n>>2)*dsi);
sym[1].x = (int)((n>>1)*dsi) - (int)((n>>2)*dcsi);
sym[1].y = (int)((n>>1)*dcsi) - (int)((n>>2)*dsi);
n = 2;
break;
case 3:
n = o->un2ix(brksymsize);
if(!(sym = (POINT*)calloc(2, sizeof(POINT))))return;
if(!(csym = (POINT*)calloc(2, sizeof(POINT)))){
free(sym);
return;
}
sym[0].x = (int)((-(n>>1))*dsi);
sym[0].y = (int)((-(n>>1))*dcsi);
sym[1].x = (int)((n>>1)*dsi);
sym[1].y = (int)((n>>1)*dcsi);
n = 2;
break;
case 4:
n = o->un2ix(brksymsize);
if(!(sym = (POINT*)calloc(n, sizeof(POINT))))return;
if(!(csym = (POINT*)calloc(n, sizeof(POINT)))){
free(sym);
return;
}
for(j = 0; j< n; j++) {
tmp = (double)j*6.283185307/(double)n;
tmp = sin(tmp)*(double)n/6.0;
sym[j].x = (int)((j-(n>>1))*dsi) + (int)(tmp*dcsi);
sym[j].y = (int)((j-(n>>1))*dcsi) + (int)(tmp*dsi);
}
break;
}
if(sym && csym && n) {
if(brksym == 3 && connect) {
csym[0].x = lp.x; csym[0].y = lp.y;
csym[1].x = sym[0].x + p1->x; csym[1].y = sym[0].y + p1->y;
o->oPolyline(csym, 2);
}
for(j = 0; j < n; j++) {
csym[j].x = sym[j].x + p1->x;
csym[j].y = sym[j].y + p1->y;
}
o->oPolyline(csym, n);
lp.x = csym[n-1].x; lp.y = csym[n-1].y;
}
if(sym) free(sym); if(csym) free(csym);
}
void
Axis::DrawBreaks(anyOutput *o)
{
fPOINT3D *pts, np, tmp_p;
double dx, dy, dz, d, dn, da, lsi, lcsi;
POINT pbs[2];
int i, j;
dx = flim[0].fx > flim[1].fx ? flim[1].fx : flim[0].fx;
dy = flim[0].fy > flim[1].fy ? flim[1].fy : flim[0].fy;
dz = flim[0].fz > flim[1].fz ? flim[0].fz + (flim[0].fz - flim[1].fz)*50.0 :
flim[1].fz + (flim[1].fz - flim[0].fz)*50.0;
if(axis->flags & AXIS_3D){
if(!(l_segs = (line_segment**)calloc(2+axis->nBreaks, sizeof(line_segment*))))return;
nl_segs = 0;
}
if(!(pts = (fPOINT3D*)calloc(2+axis->nBreaks, sizeof(fPOINT3D))))return;
memcpy(pts, &flim[0], sizeof(fPOINT3D));
for (i = 1; i < (2+axis->nBreaks); i++) {
switch (i) {
case 1:
memcpy(&np, &flim[1], sizeof(fPOINT3D));
break;
default:
GetValuePos(axis->breaks[i-2].fx, &np.fx, &np.fy, &np.fz, o);
break;
}
for(j = 0; j < i; j++) {
dn = (d = np.fx-dx) * d; dn += ((d = np.fy-dy) * d);
dn += ((d = np.fz-dz) * d); da = (d = pts[j].fx-dx) * d;
da += ((d = pts[j].fy-dy)*d); da += ((d = pts[j].fz-dz)*d);
if(dn < da) {
memcpy(&tmp_p, &pts[j], sizeof(fPOINT3D));
memcpy(&pts[j], &np, sizeof(fPOINT3D));
memcpy(&np, &tmp_p, sizeof(fPOINT3D));
}
}
memcpy(&pts[i], &np, sizeof(fPOINT3D));
}
for(i = 1; i < (2+axis->nBreaks); i++) {
dn = (d = pts[i].fx-pts[i-1].fx) * d; dn += ((d = pts[i].fy-pts[i-1].fy) * d);
dn += ((d = pts[i].fz-pts[i-1].fz) * d); dn = sqrt(dn);
da = o->un2fix(brkgap/2.0);
if(dn > 0.01) {
np.fx = da * (pts[i].fx-pts[i-1].fx)/dn;
np.fy = da * (pts[i].fy-pts[i-1].fy)/dn;
np.fz = da * (pts[i].fz-pts[i-1].fz)/dn;
d = (pts[i].fx - pts[i-1].fx) * (pts[i].fx - pts[i-1].fx);
d += ((pts[i].fy - pts[i-1].fy) * (pts[i].fy - pts[i-1].fy));
d = sqrt(d); if(d < 1.0) d = 1.0;
lsi = (pts[i].fy - pts[i-1].fy)/d;
lcsi = (pts[i].fx -pts[i-1].fx)/d;
if(i == 1) {
pts3D[0].x = pbs[0].x = iround(pts[i-1].fx);
pts3D[0].y = pbs[0].y = iround(pts[i-1].fy);
pts3D[0].z = iround(pts[i-1].fz);
}
else {
pts3D[0].x = pbs[0].x = iround(pts[i-1].fx + np.fx);
pts3D[0].y = pbs[0].y = iround(pts[i-1].fy + np.fy);
pts3D[0].z = iround(pts[i-1].fz + np.fz);
BreakSymbol(&pts3D[0], lsi, -lcsi, true, o);
}
if(i == (1+axis->nBreaks)) {
pts3D[1].x = pbs[1].x = iround(pts[i].fx);
pts3D[1].y = pbs[1].y = iround(pts[i].fy);
pts3D[1].z = iround(pts[i].fz);
}
else {
pts3D[1].x = pbs[1].x = iround(pts[i].fx - np.fx);
pts3D[1].y = pbs[1].y = iround(pts[i].fy - np.fy);
pts3D[1].z = iround(pts[i].fz - np.fz);
BreakSymbol(&pts3D[1], lsi, -lcsi, false, o);
}
if(axis->flags & AXIS_3D) {
if(l_segs[nl_segs] = new line_segment(this, data, &axline, &pts3D[0], &pts3D[1])){
l_segs[nl_segs]->DoPlot(o); nl_segs++;
}
}
else o->oSolidLine(pbs);
}
}
free(pts);
}
void
Axis::UpdateTicks()
{
int i, j, k, l;
double tmpval;
AccRange *rT=0L, *rL=0L, *rMT=0L;
if(!ssMATval || !(rT = new AccRange(ssMATval))) return;
if(Ticks) {
Undo.DropListGO(this, (GraphObj***)&Ticks, &NumTicks, 0L);
}
if(ssMATlbl) rL = new AccRange(ssMATlbl);
if(ssMITval) rMT = new AccRange(ssMITval);
if(!(Ticks = ((Tick**)calloc(rT->CountItems()+ (( rMT != 0L) ? rMT->CountItems() : 0) +4,
sizeof(Tick*))))) return;
rT->GetFirst(&i, &j); if(!(rT->GetNext(&i, &j)))return;
if(rL) rL->GetFirst(&k, &l);
NumTicks =0;
do{
if(rL) rL->GetNext(&k, &l);
if(data->GetValue(j, i, &tmpval)) {
if(!(Ticks[NumTicks] = new Tick(this, data, tmpval, axis->flags)))return;
if(rL) {
if(Ticks[NumTicks] && data->GetText(l, k, TmpTxt, TMP_TXT_SIZE))
Ticks[NumTicks]->Command(CMD_SETTEXT, TmpTxt, 0L);
}
Ticks[NumTicks]->SetSize(SIZE_TICK_ANGLE, tick_angle);
Ticks[NumTicks]->Command(CMD_TICK_TYPE, &tick_type, 0L);
}
NumTicks++;
}while(rT->GetNext(&i, &j));
if(rMT) {
if(rMT->GetFirst(&i, &j) && rMT->GetNext(&i, &j)) do {
if(data->GetValue(j, i, &tmpval) && 0L!=(Ticks[NumTicks] = new Tick(this, data,
tmpval, axis->flags | AXIS_MINORTICK))) {
Ticks[NumTicks]->SetSize(SIZE_TICK_ANGLE, tick_angle);
Ticks[NumTicks]->Command(CMD_TICK_TYPE, &tick_type, 0L);
NumTicks++;
}
}while(rMT->GetNext(&i, &j));
}
Command(CMD_TLB_TXTDEF, &tlbdef, 0L); SetSize(SIZE_TLB_XDIST, tlbdist.fx);
SetSize(SIZE_TLB_YDIST, tlbdist.fy);
if(rT) delete(rT); if(rL) delete(rL); if(rMT) delete(rMT);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -