⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 axes.cpp

📁 Linux/windows 环境下跨平台开发程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//Axes.cpp, Copyright 2000, 2001, 2002, 2003, 2004 R.Lackner
//
//    This file is part of RLPlot.
//
//    RLPlot is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//    RLPlot is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with RLPlot; if not, write to the Free Software
//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// This module contains most of the axis-object and related stuff 
//   like ticks and grid lines.
#include "rlplot.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

extern char TmpTxt[];
extern Default defs;
extern GraphObj *CurrGO, *TrackGO;			//Selected Graphic Objects
extern Axis **CurrAxes;
extern UndoObj Undo;


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// define an object for each grid line
GridLine::GridLine(GraphObj *par, DataObj *d, int which, DWORD df):
	GraphObj(par, d)
{
	FileIO(INIT_VARS);
	type = which;
	flags = df;
	if(flags & AXIS_RADIAL) type |= DL_CIRCULAR;	//default to circular grid
	Id = GO_GRIDLINE;
	if(parent) parent->Command(CMD_GET_GRIDLINE, &LineDef, 0L);
	bModified = false;
}

GridLine::GridLine(int src):GraphObj(0L, 0L)
{
	FileIO(INIT_VARS);
	if(src == FILE_READ) {
		FileIO(FILE_READ);
		}
	bModified = false;
}

GridLine::~GridLine()
{
	int i;

	if(bModified) Undo.InvalidGO(this);
	if(cpts) free(cpts);		cpts = 0L;
	if(gl1) free(gl1);			gl1 = 0L;
	if(gl2) free(gl2);			gl2 = 0L;
	if(gl3) free(gl3);			gl3 = 0L;
	if(ls) {
		for(i = 0; i < 3; i++) if(ls[i]) delete(ls[i]);
		free(ls);				ls = 0L;
		}
	if(mo) DelBitmapClass(mo);	mo = 0L;
}

void
GridLine::DoPlot(anyOutput *o)
{
	int tmp, ix, iy, ir;
	AxisDEF *axdef;

	if(!parent || !o) return;
	o->SetLine(&LineDef);
	if(mo) DelBitmapClass(mo);	mo = 0L;
	if(!type) type = DL_LEFT | DL_BOTTOM;
	if(type & DL_CIRCULAR) {
		axdef = (AxisDEF*)((Axis*)(parent->parent))->GetAxis();
		ix = o->co2ix(axdef->Center.fx + parent->GetSize(SIZE_GRECT_LEFT));
		iy = o->co2iy(axdef->Center.fy + parent->GetSize(SIZE_GRECT_TOP));
		ir = abs((int)(parent->GetSize(SIZE_YBASE))-iy);
		ncpts = 0;
		cpts = MakeArc(ix, iy, ir, 0x0f, &ncpts);
		SetMinMaxRect(&rDims, ix-ir, iy-ir, ix+ir, iy+ir);
		IncrementMinMaxRect(&rDims, 3);
		o->oPolyline(cpts, (int)ncpts);
		return;
		}
	if(parent && parent->Id == GO_TICK) {
		pts[0].x = pts[1].x = pts[2].x = pts[3].x = (long)parent->GetSize(SIZE_XBASE);
		pts[0].y = pts[1].y = pts[2].y = pts[3].y = (long)parent->GetSize(SIZE_YBASE);
		if(type & DL_LEFT) {
			tmp = o->fx2ix(parent->GetSize(SIZE_BOUNDS_LEFT));
			if(tmp < pts[0].x) pts[0].x = tmp;
			if(tmp > pts[1].x) pts[1].x = tmp;
			}
		if(type & DL_RIGHT) {
			tmp = o->fx2ix(parent->GetSize(SIZE_BOUNDS_RIGHT));
			if(tmp < pts[0].x) pts[0].x = tmp;
			if(tmp > pts[1].x) pts[1].x = tmp;
			}
		if(type & DL_YAXIS) {
			tmp = iround(parent->GetSize(SIZE_YAXISX));
			if(tmp < pts[0].x) pts[0].x = tmp;
			if(tmp > pts[1].x) pts[1].x = tmp;
			}
		if(type & DL_TOP) {
			tmp = o->fy2iy(parent->GetSize(SIZE_BOUNDS_TOP));
			if(tmp < pts[2].y) pts[2].y = tmp;
			if(tmp > pts[3].y) pts[3].y = tmp;
			}
		if(type & DL_BOTTOM) {
			tmp = o->fy2iy(parent->GetSize(SIZE_BOUNDS_BOTTOM));
			if(tmp < pts[2].y) pts[2].y = tmp;
			if(tmp > pts[3].y) pts[3].y = tmp;
			}
		if(type & DL_XAXIS) {
			tmp = iround(parent->GetSize(SIZE_XAXISY));
			if(tmp < pts[2].y) pts[2].y = tmp;
			if(tmp > pts[3].y) pts[3].y = tmp;
			}
		SetMinMaxRect(&rDims, pts[0].x, pts[2].y, pts[1].x, pts[3].y);
		IncrementMinMaxRect(&rDims, 3);
		if(pts[0].x != pts[1].x || pts[0].y != pts[1].y) o->oPolyline(pts, 2);
		if(pts[2].x != pts[3].x || pts[2].y != pts[3].y) o->oPolyline(pts+2, 2);
		}
}

void
GridLine::DoMark(anyOutput *o, bool mark)
{
	if(cpts && mark){
		InvertLine(cpts, ncpts, &LineDef, &rDims, o, mark);
		}
	else if(cpts) {
		InvertLine(cpts, ncpts, &LineDef, &rDims, o, mark);
		}

}

bool
GridLine::Command(int cmd, void *tmpl, anyOutput *o)
{
	MouseEvent *mev;
	POINT p1;

	switch(cmd){
	case CMD_SET_DATAOBJ:
		Id = GO_GRIDLINE;
		return true;
	case CMD_SETSCROLL:
	case CMD_SET_GO3D:
	case CMD_REDRAW:
		if(parent) return parent->Command(cmd, tmpl, o);
		return false;
	case CMD_SET_GRIDLINE:
		if(tmpl) memcpy(&LineDef, tmpl, sizeof(LineDEF));
		return true;
	case CMD_SET_GRIDTYPE:
		if(tmpl)type = *((int*)tmpl);
		return true;
	case CMD_MOUSE_EVENT:
		mev = (MouseEvent *) tmpl;
		switch (mev->Action) {
		case MOUSE_LBUP:
			if(IsInRect(&rDims, p1.x = mev->x, p1.y = mev->y)) {
				if(cpts && (type & DL_CIRCULAR) && IsCloseToPL(p1, cpts, ncpts)) {
					o->ShowMark(this, MRK_GODRAW);
					return true;
					}
				else if(!(type & DL_CIRCULAR)){
					o->ShowMark(&rDims, MRK_INVERT);
					CurrGO = this;
					return true;
					}
				}
			break;
			}
		return false;
		}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Gridline for axes and plots in 3D space
GridLine3D::GridLine3D(GraphObj *par, DataObj *d, int which, DWORD df):
	GridLine(par, d, which, df)
{
	Id = GO_GRIDLINE3D;
}

GridLine3D::GridLine3D(int src):GridLine(src)
{
}

GridLine3D::~GridLine3D()
{
	int i;

	if(cpts) free(cpts);		cpts = 0L;
	if(gl1) free(gl1);			gl1 = 0L;
	if(gl2) free(gl2);			gl2 = 0L;
	if(gl3) free(gl3);			gl3 = 0L;
	if(ls) {
		for(i = 0; i < 6; i++) if(ls[i]) delete(ls[i]);
		free(ls);				ls = 0L;
		}
	if(mo) DelBitmapClass(mo);	mo = 0L;
}

void
GridLine3D::DoMark(anyOutput *o, bool mark)
{
	int i;
	POINT3D *gl;

	if(mark){
		if(ls){
			memcpy(&mrc, &rDims, sizeof(RECT));
			IncrementMinMaxRect(&mrc, 6 + o->un2ix(LineDef.width));
			mo = GetRectBitmap(&mrc, o);
			for(i = 0; i < 6; i++) if(ls[i]) { 
				switch(i) {
				case 0:				case 1:
					gl = gl1;		break;
				case 2:		case 3:
					gl = gl2;		break;
				case 4:		case 5:
					gl = gl3;		break;
					}
				if(gl) {
					if(gl[0].x && gl[0].y && gl[1].x && gl[1].y) {
						pts[0].x = gl[0].x;		pts[1].x = gl[1].x;
						pts[0].y = gl[0].y;		pts[1].y = gl[1].y;
						InvertLine(pts, 2, &LineDef, &mrc, o, mark);
						}
					if(gl[2].x && gl[2].y && gl[3].x && gl[3].y) {
						pts[0].x = gl[2].x;		pts[1].x = gl[3].x;
						pts[0].y = gl[2].y;		pts[1].y = gl[3].y;
						InvertLine(pts, 2, &LineDef, &mrc, o, mark);
						}
					}
				}
			}
		}
	else if(mo)	RestoreRectBitmap(&mo, &mrc, o);
}


void
GridLine3D:: DoPlot(anyOutput *o)
{
	fPOINT3D p1, p2, pn;
	int i;

	if(!parent || !o) return;
	if(mo) DelBitmapClass(mo);	mo = 0L;
	if(!gl1) gl1 = (POINT3D*)calloc(4, sizeof(POINT3D));
	if(!gl2) gl2 = (POINT3D*)calloc(4, sizeof(POINT3D));
	if(!gl3) gl3 = (POINT3D*)calloc(4, sizeof(POINT3D));
	if(!ls) ls = (line_segment**)calloc(6, sizeof(line_segment*));
	o->ActualSize(&rDims);
	Swap(rDims.left, rDims.right);	Swap(rDims.top, rDims.bottom);
	if(gl1 && gl2 && gl3 && ls) {
		for(i = 0; i < 6; i++) if(ls[i]) {
			delete(ls[i]);		ls[i] = 0L;
			}
		if(type & 0x01) {
			pn.fx = parent->GetSize(SIZE_BOUNDS_XMIN);	pn.fy = parent->GetSize(SIZE_BOUNDS_YMIN);
			pn.fz = parent->GetSize(SIZE_MINE);			o->fvec2ivec(&pn, &p1);
			pn.fx = parent->GetSize(SIZE_BOUNDS_XMAX);	o->fvec2ivec(&pn, &p2);
			gl1[0].x = iround(p1.fx);					gl1[0].y = iround(p1.fy);
			gl1[1].x = iround(p2.fx);					gl1[1].y = iround(p2.fy);
			gl1[0].z = iround(p1.fz);					gl1[1].z = iround(p2.fz);
			if(ls[0] = new line_segment(this, data, &LineDef, &gl1[0], &gl1[1]))
				ls[0]->DoPlot(o);
			UpdateMinMaxRect(&rDims, gl1[0].x, gl1[0].y);
			UpdateMinMaxRect(&rDims, gl1[1].x, gl1[1].y);
			}
		if(type & 0x02) {
			pn.fx = parent->GetSize(SIZE_BOUNDS_XMIN);	pn.fy = parent->GetSize(SIZE_BOUNDS_YMIN);
			pn.fz = parent->GetSize(SIZE_MINE);			o->fvec2ivec(&pn, &p1);
			pn.fy = parent->GetSize(SIZE_BOUNDS_YMAX);	o->fvec2ivec(&pn, &p2);
			gl1[2].x = iround(p1.fx);					gl1[2].y = iround(p1.fy);
			gl1[3].x = iround(p2.fx);					gl1[3].y = iround(p2.fy);
			gl1[2].z = iround(p1.fz);					gl1[3].z = iround(p2.fz);
			if(ls[1] = new line_segment(this, data, &LineDef, &gl1[2], &gl1[3]))
				ls[1]->DoPlot(o);
			UpdateMinMaxRect(&rDims, gl1[2].x, gl1[2].y);
			UpdateMinMaxRect(&rDims, gl1[3].x, gl1[3].y);
			}
		if(type & 0x04) {
			pn.fx = parent->GetSize(SIZE_BOUNDS_XMIN);	pn.fy = parent->GetSize(SIZE_MINE);
			pn.fz = parent->GetSize(SIZE_BOUNDS_ZMIN);	o->fvec2ivec(&pn, &p1);
			pn.fx = parent->GetSize(SIZE_BOUNDS_XMAX);	o->fvec2ivec(&pn, &p2);
			gl2[0].x = iround(p1.fx);					gl2[0].y = iround(p1.fy);
			gl2[1].x = iround(p2.fx);					gl2[1].y = iround(p2.fy);
			gl2[0].z = iround(p1.fz);					gl2[1].z = iround(p2.fz);
			if(ls[2] = new line_segment(this, data, &LineDef, &gl2[0], &gl2[1]))
				ls[2]->DoPlot(o);
			UpdateMinMaxRect(&rDims, gl2[0].x, gl2[0].y);
			UpdateMinMaxRect(&rDims, gl2[1].x, gl2[1].y);
			}
		if(type & 0x08) {
			pn.fx = parent->GetSize(SIZE_BOUNDS_XMIN);	pn.fy = parent->GetSize(SIZE_MINE);
			pn.fz = parent->GetSize(SIZE_BOUNDS_ZMIN);	o->fvec2ivec(&pn, &p1);
			pn.fz = parent->GetSize(SIZE_BOUNDS_ZMAX);	o->fvec2ivec(&pn, &p2);
			gl2[2].x = iround(p1.fx);					gl2[2].y = iround(p1.fy);
			gl2[3].x = iround(p2.fx);					gl2[3].y = iround(p2.fy);
			gl2[2].z = iround(p1.fz);					gl2[3].z = iround(p2.fz);
			if(ls[3] = new line_segment(this, data, &LineDef, &gl2[2], &gl2[3]))
				ls[3]->DoPlot(o);
			UpdateMinMaxRect(&rDims, gl2[2].x, gl2[2].y);
			UpdateMinMaxRect(&rDims, gl2[3].x, gl2[3].y);
			}
		if(type & 0x10) {
			pn.fx = parent->GetSize(SIZE_MINE);			pn.fy = parent->GetSize(SIZE_BOUNDS_YMIN);
			pn.fz = parent->GetSize(SIZE_BOUNDS_ZMIN);	o->fvec2ivec(&pn, &p1);
			pn.fy = parent->GetSize(SIZE_BOUNDS_YMAX);	o->fvec2ivec(&pn, &p2);
			gl3[0].x = iround(p1.fx);					gl3[0].y = iround(p1.fy);
			gl3[1].x = iround(p2.fx);					gl3[1].y = iround(p2.fy);
			gl3[0].z = iround(p1.fz);					gl3[1].z = iround(p2.fz);
			if(ls[4] = new line_segment(this, data, &LineDef, &gl3[0], &gl3[1]))
				ls[4]->DoPlot(o);
			UpdateMinMaxRect(&rDims, gl3[0].x, gl3[0].y);
			UpdateMinMaxRect(&rDims, gl3[1].x, gl3[1].y);
			}
		if(type & 0x20) {
			pn.fx = parent->GetSize(SIZE_MINE);			pn.fy = parent->GetSize(SIZE_BOUNDS_YMIN);
			pn.fz = parent->GetSize(SIZE_BOUNDS_ZMIN);	o->fvec2ivec(&pn, &p1);
			pn.fz = parent->GetSize(SIZE_BOUNDS_ZMAX);	o->fvec2ivec(&pn, &p2);
			gl3[2].x = iround(p1.fx);					gl3[2].y = iround(p1.fy);
			gl3[3].x = iround(p2.fx);					gl3[3].y = iround(p2.fy);
			gl3[2].z = iround(p1.fz);					gl3[3].z = iround(p2.fz);
			if(ls[5] = new line_segment(this, data, &LineDef, &gl3[2], &gl3[3]))
				ls[5]->DoPlot(o);
			UpdateMinMaxRect(&rDims, gl3[2].x, gl3[2].y);
			UpdateMinMaxRect(&rDims, gl3[3].x, gl3[3].y);
			}
		}
	IncrementMinMaxRect(&rDims, 4);
}

bool
GridLine3D::Command(int cmd, void *tmpl, anyOutput *o)
{
	int i;

	switch(cmd) {
	case CMD_SET_DATAOBJ:
		Id = GO_GRIDLINE3D;
		return true;
	case CMD_MOUSE_EVENT:
		if(tmpl && ls) switch (((MouseEvent *)tmpl)->Action) {
		case MOUSE_LBUP:
			for(i = 0; i < 6; i++) if(ls[i] && 
				ls[i]->ObjThere(((MouseEvent *)tmpl)->x, ((MouseEvent *)tmpl)->y)) {
				o->ShowMark(this, MRK_GODRAW);
				return true;
				}
			}
		break;
	default:
		return GridLine::Command(cmd, tmpl, o);
		}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Radial Gridline for polar plots: spokes for the plot
GridRadial::GridRadial(GraphObj *par, DataObj *d, int which, DWORD df):
	GridLine(par, d, which, df)
{
	Id = GO_GRIDRADIAL;
}

GridRadial::GridRadial(int src):GridLine(src)
{
}

GridRadial::~GridRadial()
{
	if(mo) DelBitmapClass(mo);	mo = 0L;
}

void
GridRadial::DoPlot(anyOutput *o)
{
	AxisDEF *axdef;

	if(!parent || !o) return;
	if(mo) DelBitmapClass(mo);	mo = 0L;
	o->SetLine(&LineDef);
	if(parent->Id == GO_TICK && parent->parent && parent->parent->Id == GO_AXIS) {
		axdef = (AxisDEF*)((Axis*)(parent->parent))->GetAxis();
		pts[0].x = iround(parent->GetSize(SIZE_XBASE));
		pts[0].y = iround(parent->GetSize(SIZE_YBASE));
		pts[1].x = o->co2ix(axdef->Center.fx + parent->GetSize(SIZE_GRECT_LEFT));
		pts[1].y = o->co2iy(axdef->Center.fy + parent->GetSize(SIZE_GRECT_TOP));
		SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
		IncrementMinMaxRect(&rDims, 3);
		o->oPolyline(pts, 2);
		}
}

void
GridRadial::DoMark(anyOutput *o, bool mark)
{
	if(mark) {
		memcpy(&mrc, &rDims, sizeof(RECT));
		IncrementMinMaxRect(&mrc, 6 + o->un2ix(LineDef.width));
		mo = GetRectBitmap(&mrc, o);
		InvertLine(pts, 2, &LineDef, &rDims, o, mark);
		}
	else if(mo)	RestoreRectBitmap(&mo, &mrc, o);
}

bool
GridRadial::Command(int cmd, void *tmpl, anyOutput *o)
{
	POINT p1;

	switch(cmd) {
	case CMD_SET_DATAOBJ:
		Id = GO_GRIDRADIAL;
		return true;
	case CMD_MOUSE_EVENT:
		if(tmpl) switch (((MouseEvent *)tmpl)->Action) {
		case MOUSE_LBUP:
			if(IsInRect(&rDims, p1.x=((MouseEvent *)tmpl)->x, p1.y=((MouseEvent *)tmpl)->y)){
				if(IsCloseToPL(p1, pts, 2)) {
					o->ShowMark(this, MRK_GODRAW);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -