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

📄 rlplot.cpp

📁 Linux/windows 环境下跨平台开发程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
DataLine::Command(int cmd, void *tmpl, anyOutput *o){	MouseEvent *mev;	bool bFound = false;	POINT p1;	int i;	switch (cmd) {	case CMD_MOUSE_EVENT:		mev = (MouseEvent *) tmpl;		switch (mev->Action) {		case MOUSE_LBUP:			if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPntSet <1)				return false; 			if(isPolygon && IsInPolygon(&p1, pts, cp)) bFound = true;			if(bFound || IsCloseToPL(p1,pts,cp)) 				return o->ShowMark(this, MRK_GODRAW);			}		break;	case CMD_SET_DATAOBJ:		Id = isPolygon ? GO_DATAPOLYGON : GO_DATALINE;		data = (DataObj*)tmpl;		return true;
	case CMD_MRK_DIRTY:
		dirty= true;
	case CMD_REDRAW:
		if(parent) return parent->Command(cmd, tmpl, 0L);
		return false;
	case CMD_LEGEND:		if(tmpl && ((GraphObj*)tmpl)->Id == GO_LEGEND) {			if(Id == GO_DATALINE) ((Legend*)tmpl)->HasFill(&LineDef, 0L);			}		break;	case CMD_SET_LINE:		if(tmpl) memcpy(&LineDef, tmpl, sizeof(LineDEF));		return true;	case CMD_UPDATE:
		Undo.DataMem(this, (void**)&Values, nPnt * sizeof(lfPOINT), &nPnt, UNDO_CONTINUE);
		Undo.ValLong(this, &nPntSet, UNDO_CONTINUE);
		SetValues();		return true;	case CMD_AUTOSCALE:		if(nPntSet < 1 || !Values) return false;		if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {			if(dirty) {				min.fx = max.fx = Values[0].fx;	min.fy = max.fy = Values[0].fy;				for (i = 1; i <= nPntSet; i++){					min.fx = Values[i].fx < min.fx ? Values[i].fx : min.fx;					max.fx = Values[i].fx > max.fx ? Values[i].fx : max.fx;					min.fy = Values[i].fy < min.fy ? Values[i].fy : min.fy;					max.fy = Values[i].fy > max.fy ? Values[i].fy : max.fy;					}				}			((Plot*)parent)->CheckBounds(min.fx, min.fy);			((Plot*)parent)->CheckBounds(max.fx, max.fy);			dirty = false;			return true;			}		return false;		}	return false;}voidDataLine::SetValues(){	AccRange *rX, *rY1=0L, *rY2=0L;	int i, j, k, l, m, n;	double x, y;	char *yref1 = 0L, *yref2 = 0L;	lfPOINT *tmpValues = Values;	if(!ssXref || !ssYref) return;	if(!(yref1 = strdup(ssYref)))return;	for(i = 0; yref1[i]; i++) {		if(yref1[i] == ';') {			yref1[i++] = 0;			while(yref1[i] && yref1[i] < 33) i++;			yref2 = strdup(yref1+i);			}		}	nPnt = nPntSet = 0;	min.fx = min.fy = HUGE_VAL;		max.fx = max.fy = -HUGE_VAL;	rX = new AccRange(ssXref);		rY1 = new AccRange(yref1);	if(!rX || !rY1){		if(yref1) free(yref1);		if(yref2) free(yref2);		if(rX) delete(rX);	if(rY1) delete(rY1);		return;		}	if(yref2 &&((nPnt = rX->CountItems()) == (rY1->CountItems()))) {		if(!(Values = (lfPOINT *)realloc(Values, ((nPnt*2+2) * sizeof(lfPOINT))))) return; 		if(!(rY2 = new AccRange(yref2))) {			if(yref1) free(yref1);		if(yref2) free(yref2);			if(rX) delete(rX);	if(rY1) delete(rY1);			return;			}		if(rX->GetFirst(&i, &j) && rY1->GetFirst(&k, &l) && 			rX->GetNext(&i, &j) && rY1->GetNext(&k, &l) &&			rY2->GetFirst(&m, &n) && rY2->GetNext(&m, &n)) do {			if(data->GetValue(j, i, &x)){				if(data->GetValue(l, k, &y)){					Values[nPntSet].fx = x;			Values[nPntSet++].fy = y;					}				if(data->GetValue(n, m, &y)){					Values[nPntSet].fx = x;			Values[nPntSet++].fy = y;					}				}			}while(rX->GetNext(&i, &j) && rY1->GetNext(&k, &l) && rY2->GetNext(&m, &n));		}	else {		if((nPnt = rX->CountItems()) != (rY1->CountItems())) return;		if(!(Values = (lfPOINT *)realloc(Values, (nPnt+2) * sizeof(lfPOINT)))) return; 		if(rX->GetFirst(&i, &j) && rY1->GetFirst(&k, &l) && 			rX->GetNext(&i, &j) && rY1->GetNext(&k, &l)) do {			if(data->GetValue(j, i, &x) && data->GetValue(l, k, &y)){				Values[nPntSet].fx = x;				Values[nPntSet++].fy = y;				}			}while(rX->GetNext(&i, &j) && rY1->GetNext(&k, &l));		}	nPnt = nPntSet;		nPntSet--;	dirty = true;	Command(CMD_AUTOSCALE, 0L, 0L);
	if(tmpValues && Values != tmpValues) Undo.InvalidGO(this);	if(rX) delete(rX);	if(rY1) delete(rY1);	if(rY2) delete(rY2);	if(yref1) free(yref1);	if(yref2) free(yref2);}voidDataLine::LineData(lfPOINT *val, long nval){
	lfPOINT *ov = Values;

	if(!val || nval <2) return;
	if(nval > nPnt && nPnt > 1 && Values){
		if(!(Values = (lfPOINT *)realloc(Values, ((nval*2+2) * sizeof(lfPOINT))))) return; 
		if(ov != Values) Undo.InvalidGO(this);
		}	else if(!Undo.busy) Undo.DataMem(this, (void**)&Values, nPnt * sizeof(lfPOINT), &nPnt, UNDO_CONTINUE);
	memcpy(Values, val, nval * sizeof(lfPOINT));
	if(pts) free(pts);			pts = 0L;				dirty = true;				free(val);					nPnt = nval;				nPntSet = nPnt-1;}
void
DataLine::DrawSpline(anyOutput *target)
{
	int i, j, k, klo, khi, ptsize = 1000;
	double *y2, min, max, x, y, h, b, a;
	POINT pn;
	lfPOINT *scvals;
	
	if(!(y2 = (double*)malloc(sizeof(double)*(nPnt)))) return;
	if(!(scvals = (lfPOINT*)malloc(sizeof(lfPOINT)*(nPnt)))){
		free(y2);
		return;
		}
	if((type & 0x0f) == 9 || (type & 0x0f) == 10) {
		if((type & 0x0f) == 9) for(i = 0; i < nPnt; i++) {
			scvals[i].fx = target->fx2fix(Values[i].fx);
			scvals[i].fy = target->fy2fiy(Values[i].fy);
			}
		else for(i = 0; i < nPnt; i++) {
			scvals[i].fy = target->fx2fix(Values[i].fx);
			scvals[i].fx = target->fy2fiy(Values[i].fy);
			}
		SortFpArray(nPnt, scvals);
		min = scvals[0].fx;			max = scvals[nPnt-1].fx;
		for(i = j = 0; i < (nPnt-1); i++, j++) {
			y = scvals[i].fy;			scvals[j].fx = scvals[i].fx;
			for(k = 1; scvals[i+1].fx == scvals[i].fx; k++) {
				y += scvals[i+1].fy;		i++;
				}
			scvals[j].fy = y/((double)k);
			}
		if(scvals[i].fx > scvals[i-1].fx) {
			scvals[j].fx = scvals[i].fx;	scvals[j].fy = scvals[i].fy;
			j++;
			}
		spline(scvals, j, y2);
		h = scvals[1].fx - scvals[0].fx;	// klo and khi bracket the input value of x
		for(x = min, klo = 0, i = khi = 1; x < max && i < j; x += 1.0) {
			while(x > scvals[i].fx) {
				klo++;		khi++;	i++;
				h = scvals[khi].fx - scvals[klo].fx;
				}
			a = (scvals[khi].fx - x) / h;		b = (x - scvals[klo].fx) / h;
			y = a * scvals[klo].fy + b * scvals[khi].fy + ((a*a*a - a) * y2[klo] + (b*b*b - b) * y2[khi]) * (h*h)/6.0;
			if((type & 0x0f) == 9) {
				pn.x = iround(x);		pn.y = iround(y);
				}
			else {
				pn.x = iround(y);		pn.y = iround(x);
				}
			if(cp >= ptsize) {
				ptsize += 1000;
				pts = (POINT*)realloc(pts, sizeof(POINT)*ptsize); 
				}
			AddToPolygon(&cp, pts, &pn);
			}
		}
	free(y2);	free(scvals);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// DataPolygon is a graphic object based on DataLineDataPolygon::DataPolygon(GraphObj *par, DataObj *d, char *xrange, char *yrange):	DataLine(par, d, xrange, yrange){	lfPOINT *fp = Values;	char *rx = ssXref;	char *ry = ssYref;	FileIO(INIT_VARS);	Values = fp;				//FileIO will just set Values to 0L !	ssXref = rx;			ssYref = ry;	Id = GO_DATAPOLYGON;}DataPolygon::DataPolygon(int src):DataLine(0L, 0){	FileIO(INIT_VARS);	if(src == FILE_READ) {		FileIO(FILE_READ);		}}DataPolygon::~DataPolygon(){	if(Values)free(Values);		Values =0L;	if(pts) free (pts);			pts = 0L;	if(ssXref) free(ssXref);	ssXref = 0L;	if(ssYref) free(ssYref);	ssYref = 0L;	if(mo) DelBitmapClass(mo);	mo = 0L;	if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);}voidDataPolygon::DoPlot(anyOutput *target){	if(!Values || nPntSet < 2) return;	if(mo) DelBitmapClass(mo);	mo = 0L;	DataLine::DoPlot(target);	//no drawing but fill pts only	target->SetLine(&LineDef);	target->SetFill(&pgFill);	target->oPolygon(pts, cp);}voidDataPolygon::DoMark(anyOutput *o, bool mark){	if(pts && cp && o){		if(mark){			memcpy(&mrc, &rDims, sizeof(RECT));			IncrementMinMaxRect(&mrc, 6 + o->un2ix(LineDef.width));			mo = GetRectBitmap(&mrc, o);			InvertPolygon(pts, cp, &LineDef, &pgFill, &mrc, o, mark);			}		else RestoreRectBitmap(&mo, &mrc, o);		}}boolDataPolygon::Command(int cmd, void *tmpl, anyOutput *o){	switch (cmd) {	case CMD_PG_FILL:		if(tmpl) {			memcpy((void*)&pgFill, tmpl, sizeof(FillDEF));			if(pgFill.hatch) memcpy((void*)&pgFillLine, (void*)pgFill.hatch, sizeof(LineDEF));			pgFill.hatch = (LineDEF*)&pgFillLine;			}		return true;	case CMD_LEGEND:		if(tmpl && ((GraphObj*)tmpl)->Id == GO_LEGEND) {			if(Id == GO_DATAPOLYGON) ((Legend*)tmpl)->HasFill(&LineDef, &pgFill);			}		break;	default:		return DataLine::Command(cmd, tmpl, o);		}	return false;}//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Calculate and display a regression line// Ref.: "Biometry" third edition 1995 (ed. R.R. Sokal and F.J. Rohlf),// W.H. Freeman and Company, New York; ISBN 0-7167-2411-1; pp. 451ffRegLine::RegLine(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel):	GraphObj(par, d){	FileIO(INIT_VARS);	type = sel;	Id = GO_REGLINE;	uclip.Xmin = uclip.Ymin = lim.Xmin = lim.Ymin = -1.0;	uclip.Xmax = uclip.Ymax = lim.Xmax = lim.Ymax = 1.0;	Recalc(values, n);}RegLine::RegLine(int src):GraphObj(0L, 0L){	FileIO(INIT_VARS);	if(src == FILE_READ) FileIO(FILE_READ);}RegLine::~RegLine(){	if(pts) free(pts);	pts = 0L;	if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);}doubleRegLine::GetSize(int select){	double a, b;	switch(select) {	case SIZE_MX:		return mx;	case SIZE_MY:		return my;	case SIZE_A:	case SIZE_B:		switch(type & 0x07) {		case 1:		a = l2.fx;	b = l2.fy;	break;		case 2:		a = l3.fx;	b = l3.fy;	break;		case 3:		a = l4.fx;	b = l4.fy;	break;		case 4:		a = l5.fx;	b = l5.fy;	break;		default:	a = l1.fx;	b = l1.fy;	break;			}		if(select == SIZE_A) return a;		else return b;		}	return 0.0;}voidRegLine::DoPlot(anyOutput *o){	int i;	POINT pn, *tmppts;	double x, x1, y, d, a, b;	fRECT cliprc;	bool dValid;	switch (type & 0x70) {	case 0x20:	memcpy(&cliprc, &uclip, sizeof(fRECT));		break;	case 0x10:		if(parent) {			cliprc.Xmin = parent->GetSize(SIZE_BOUNDS_LEFT);			cliprc.Xmax = parent->GetSize(SIZE_BOUNDS_RIGHT);			cliprc.Ymin = parent->GetSize(SIZE_BOUNDS_BOTTOM);			cliprc.Ymax = parent->GetSize(SIZE_BOUNDS_TOP);			break;			}		//no parent: use default	default:	memcpy(&cliprc, &lim, sizeof(fRECT));		break;		}	if(cliprc.Xmax < cliprc.Xmin) {		x = cliprc.Xmax;	cliprc.Xmax = cliprc.Xmin;	cliprc.Xmin = x;		}	if(cliprc.Ymax < cliprc.Ymin) {		y = cliprc.Ymax;	cliprc.Ymax = cliprc.Ymin;	cliprc.Ymin = y;		}	if(cliprc.Xmin == cliprc.Xmax || cliprc.Ymin == cliprc.Ymax) return;	if(pts) free(pts);	if(!(pts = (POINT *)malloc(sizeof(POINT)*200)))return;	switch(type & 0x07) {	case 1:		a = l2.fx;	b = l2.fy;	break;	case 2:		a = l3.fx;	b = l3.fy;	break;	case 3:		a = l4.fx;	b = l4.fy;	break;	case 4:		a = l5.fx;	b = l5.fy;	break;	default:	a = l1.fx;	b = l1.fy;	break;		}	x = cliprc.Xmin;	d = (cliprc.Xmax - cliprc.Xmin)/200.0;	for (cp = i = 0; i <= 200; i++){		dValid = true;		switch(type & 0x700) {		case 0x100:					//logarithmic x			if(dValid = x > defs.min4log) x1 = log10(x);			break;		case 0x200:					//reciprocal x			if(dValid = fabs(x) > defs.min4log) x1 = 1.0/x;			break;		case 0x300:					//square root x			if(dValid = fabs(x) > defs.min4log) x1 = sqrt(x);			break;		default:	x1 = x;	break;		//linear x			}		y = a + b*x1;		if(dValid) switch(type & 0x7000) {		case 0x1000:				//logarithmic y			y = pow(10.0, y);			break;		case 0x2000:				//reciprocal y			if(dValid = fabs(y) >0.0001) y = 1.0/y;			break;		case 0x3000:				//square root y			if(dValid = fabs(y) >0.0001) y = y*y;			break;			}		if(dValid && y >= cliprc.Ymin && y <= cliprc.Ymax) {			pn.x = o->fx2ix(x);	pn.y = o->fy2iy(y);			AddToPolygon(&cp, pts, &pn);			}		x += d;		}	if(cp < 2) return;	o->SetLine(&LineDef);	o->oPolyline(pts, cp);	if(tmppts = (POINT*)realloc(pts, cp *sizeof(POINT))) pts = tmppts;	SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);	for(i = 2; i < cp; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);	i = 2*o->un2ix(LineDef.width);		//increase size of rectangle for marks	IncrementMinMaxRect(&rDims, i);}voidRegLine::DoMark(anyOutput *o, bool mark){	if(pts && cp && o){		if(mark)InvertLine(pts, cp, &LineDef, &rDims, o, mark);		else if(parent) parent->Command(CMD_REDRAW, 0L, o);		}}boolRegLine::Command(int cmd, void *tmpl, anyOutput *o){	MouseEvent *mev;	POINT p1;	switch (cmd) {	case CMD_MOUSE_EVENT:		mev = (MouseEvent *) tmpl;		switch (mev->Action) {		case MOUSE_LBUP:			if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPoints <2)				return false; 			if(IsCloseToPL(p1,pts,cp)) return o->ShowMark(CurrGO= this, MRK_GODRAW);			}		break;	case CMD_SET_DATAOBJ:		Id = GO_REGLINE;		return true;	case CMD_BOUNDS:		if(tmpl) {			memcpy(&lim, tmpl, sizeof(fRECT));			memcpy(&uclip, tmpl, sizeof(fRECT));			}		return true;	case CMD_AUTOSCALE:		if(nPoints < 2) return false;		if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {			((Plot*)parent)->CheckBounds(lim.Xmin, lim.Ymin);			((Plot*)parent)->CheckBounds(lim.Xmax, lim.Ymax);			return true;			}		return false;		}	return false;}voidRegLine::Recalc(lfPOINT *values, long n){	double sx, sy, dx, dy, sxy, sxx, syy;	double a, b, k;	long ic;	sx = sy = 0.0;	if((nPoints = n)<2) return;	for(ic = 0; ic < n; ic++) {		sx += values[ic].fx;		sy += values[ic].fy;		}	mx = sx /((double)nPoints);	my = sy/((double)nPoints);	sxy = sxx = syy = 0.0;	for(ic = 0; ic < n; ic++) {		dx = mx - values[ic].fx;	dy = my - values[ic].fy;		sxx += (dx*dx);	sy

⌨️ 快捷键说明

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