繪制函數圖像一個重要的問題,就是處理函數圖像的坐标,如何在物理繪圖設備(如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)點。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!