绘制函数图像一个重要的问题,就是处理函数图像的坐标,如何在物理绘图设备(如QWidget)放大。
QWidget是以像素为单位,而函数值的定义域和值域,往往和窗口的大小(像素为单位)不匹配。
要想函数图像在窗体上正确呈现,就需要对数学函数图像,进行放大。
窗体的宽度与函数定义域之比,大致上可以用做放大倍数scale。
QPointF( )*scale,就是放大后的点的坐标,这是QPointF类的一个性质。
本例中,反比例函数取[0.1, 10]区间,和[-10, -0.1 ]进行函数图像绘制。
void Widget::inverseProportionFunction()
{
QPainter painter(this); //创建画家
painter.setRenderHint(QPainter::Antialiasing,true); //反走样
painter.translate(width()/2,height()/2); //原点平移到窗体中心位置
QPen axisPen; //创建画笔
axisPen.setWidth(4);
painter.setPen(axisPen);
//绘制坐标轴
painter.drawLine(0,height()/2.0,0,-height()/2.0);
painter.drawLine(-width()/2.0,0,width()/2.0,0);
//绘制x>0区间上的反比例函数图像
QVector<qreal> domainSet; //函数的定义域(离散值)
QVector<qreal> rangeSet; //值域(离散值)
QVector<QPointF> graphSet; //函数图像各点的代数值坐标
#define numPoints 50 //反比例函数半边图像所分的线段数
qreal domainBegin=0.1, domainEnd=10; //绘制区间[0.1, 10]
//绘图窗体宽度(像素数),与函数定义域边界值之比,即图像的放大倍数
qreal scale = (this->width()/2.0)/domainEnd;
qreal step = (domainEnd-domainBegin)/(float)numPoints;//曲线绘制的步长
for(int i= 1;i<= numPoints;i )
{
qreal x = domainBegin i*step;
qreal y = pow(x,-1); //计算反比例函数值
domainSet.push_back(x); //获取定义域内的若干值,组成一个向量
rangeSet.push_back(y); //获取值域内的对应值,组成一个向量
graphSet.push_back(QPointF(x,y)); //将获取的定义域和值域,组成一个点的向量
}
painter.scale(1,-1); //Y轴向上为正
QPainterPath path;
QPen pen(Qt::red);
pen.setWidth(3);
painter.setPen(pen);
//往绘制路径中添加轨迹
path.moveTo(domainBegin*scale,pow(domainBegin,-1)*scale);
for(int i=1;i<= numPoints;i )
{
path.lineTo(graphSet.at(i-1)*scale); //注意:对坐标进行了放大
}
painter.drawPath(path); //绘制函数图像
//通过旋转坐标系,绘制x<0区间的图像(两部分的图像关于原点中心对称)
painter.rotate(180);
painter.drawPath(path);
}
反比例函数 y= 1/x 图像
图中的绿色格子,代表长度为1的正方形。可以看到,反比例函数图像经过(1,1)点。
,版权声明:xxxxxxxxx;
工作时间:8:00-18:00
客服电话
电子邮件
扫码二维码
获取最新动态