自适应坐标系统

       在动态曲线的绘制过程中,经常会遇动态曲线的数量级变化较大的情况,这是如果坐标系统是一个固定的范围,就会使曲线的对比度过小,或者超出坐标系统的范围的情况,自适应坐标系统可以根据曲线的数值范围,确定一个最佳坐标系统,充分展示曲线的波动。
        基本步骤:
     1.首先,在一段曲线中选定感兴趣区域(ROI)。
     2.在感兴趣区域范围内查找最大,最小值MAX MIN。
     3. 根据最大,最小值计算坐标系统边界,例如,如果想让ROI的曲线范围占在整个坐标系统的3/4,就令Y轴上边界top定为MAX+(MAX-MIN)/8  下边界bottom定为MIN - (MAX-MIN)/8 
     4.确定Y轴坐标刻度 ,设定坐标刻度密度inter_n,表示Y轴显示的刻度总数量
         每两个刻度间隔inter  = (top-bottom)/inter_n,
         此时间隔inter 为一个无限小数 如0.234324。。
         为inter取一位有效数字  0.234324。。->0.2
         根据inter确定坐标刻度
     5.确定坐标轴系统到屏幕的映射。如图1,以A(0,MIN)   B(N,MAX)两点为基准,计算坐标系统到屏幕的映射,其中N表示要显示的曲线的点数。
 
图1
<script src="https://code.csdn.net/snippets/1263296.js"></script>
#include "StdAfx.h"
#include "xaxis.h"

xaxis::xaxis(void)
{

	oy_scale = NULL;  //纵坐标刻度
	ty_scale = NULL;
	tx_scale = NULL;
	y_edn = 6;//初始纵坐标间隔
	oy_scale = new double[(unsigned int)y_edn*10];
}

xaxis::~xaxis(void)
{
}

// 设定映射目标
void xaxis::rectset(CRect temrect)
{
	t_width = temrect.Width();
	t_height = temrect.Height();
}

// 设定原始坐标点
void xaxis::opset(CNiReal64Vector RDdata)
{
#pragma region 坐标点初始化
	num_p = RDdata.GetSize();
	if(RDdata.GetSize() == 0)return;
	double max;
	double min;


	if(num_p <40)
	{
		max = RDdata[0];
		min = RDdata[0];

		for(unsigned int i = 0;i < num_p;i++)
		{
			ox_points[i] = i;
			oy_points[i] = RDdata[i];
			if(max < RDdata[i])
			{
				max = oy_points[i];
			}
			if(min > RDdata[i])
			{
				min = oy_points[i];
			}
		}
	}
	else
	{
		max = RDdata[num_p - 40];
		min = RDdata[num_p - 40];

		for(unsigned int i = num_p - 40,j = 0;i < num_p;i++,j++)
		{
			ox_points[j] = j;
			oy_points[j] = RDdata[i];
			if(max < RDdata[i])
			{
				max = oy_points[j];
			}
			if(min > RDdata[i])
			{
				min = oy_points[j];
			}
		}
		num_p = 40;
	}
#pragma endregion


#pragma region 计算top bottom
	if(min == max)
	{
		top = max * 2;
		bottom = 0;
	}
	else
	{
		top = max + 0.5 * (max - min);
		bottom = min - 0.5 * (max - min);
	}
#pragma endregion

#pragma region 定位坐标刻度

	double inter = (top - bottom) / y_edn;
	int inx = -(int)floor(log10(inter));
	inter = floor(inter * pow(10.0f,inx))* pow(10.0f,-inx);    //间隔
	oy_scale[0] = floor(top * pow(10.0f,inx))* pow(10.0f,-inx);
	n_scale = 0;
	while(oy_scale[n_scale] > bottom)
	{
		oy_scale[n_scale+1] = oy_scale[n_scale] - inter;
		n_scale++;
	}
#pragma endregion


#pragma region 绘图目标映射
//纵坐标映射

	double ya = t_height /(bottom - top);
	double yb = -top * ya;

	double xa = t_width / 45;
	double xb = 5 * xa;

	if(ty_scale == NULL)ty_scale = new int[(unsigned int)y_edn*10];
	if(tx_scale == NULL)tx_scale = new int[8];
	for(unsigned int i = 0;i < num_p;i++)
	{
		tx_points[i] = (int)(xa * ox_points[i] + xb);
		ty_points[i] = (int)(ya * oy_points[i] + yb);
	}
	for(int i = 0; i < n_scale; i++)
	{

		sprintf_s(y_wo[i],100,"%g",oy_scale[i]);
		ty_scale[i] = (int)(ya * oy_scale[i] + yb);
	}
	for(int i = 0; i < 8; i++)
	{
		tx_scale[i] = xa * i * 5 + xb;
	}

#pragma endregion
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值