前几天看到一道FaceBook的面试题,本来只是想用C语言实现下算法,后来闲着无聊便用Qt绘制了一下效果. FaceBook原题如下:

我用Qt的实现粗略效果,如下

算法思路: 用百分比*360度求出旋转偏移角度α,将判断点与圆心连线,用余弦定理求该点偏移β角度,和α比较。如果α>β,说明黑色的范围可以包含此点 . 如果不允许使用反三角函数库,用幂指多項式[ 用泰勒公式展开cos x = 1-x^2/2!+x^4/4!+~+(-1)^kx^2k/(2k)!+¤(x(2k+1) ]来判断角度大小即可。
/*----------------MyWidget.h---------------------------*/
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QTimer>
class MyWidget : public QWidget
{
Q_OBJECT
public:
int x;int y;
explicit MyWidget(QWidget *parent = 0);
void paintEvent(QPaintEvent *);
static int count;
bool check;
signals:
private slots:
void on_time();
private:
QTimer *timer;
QVector<QPoint> pos;
};
#endif // MYWIDGET_H
/*----------------MyWidget.h---------------------------*/
/*----------------MyWidget.cpp---------------------------*/
#include "MyWidget.h"
#include <QPainter>
#include <QPixmap>
#include <math.h> //后便要用到acos函数和pow函数
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent)
{
check = true;
timer = new QTimer();
timer->setInterval(70);
connect(timer, SIGNAL(timeout()), this, SLOT(on_time()));
}
int MyWidget::count = -1;
void MyWidget::paintEvent(QPaintEvent *)
{
QPixmap *pixmap;//定义图片
QPainter *painter;//定义画图设备
pixmap = new QPixmap (this->size());
pixmap->fill(Qt::white);
painter = new QPainter(pixmap);//加载空图片
painter->setRenderHint(QPainter::Antialiasing);
painter->setPen(QPen(Qt::black, 2, Qt::DashLine));
painter->drawEllipse(QPoint(150, 150), 100, 100);//画圆
painter->drawPoint(150,150);//描点
painter->setFont(QFont("宋体", 15, 20, true));
if(check == true)
{
painter->end();
painter->begin(this);
painter->drawPixmap(0, 0, *pixmap);
timer->start();
check = false;
}else
{
painter->drawText(23, 23, "进度:"+QString::number(count*2)+"%");
//百分比计数,因为是从两边展开,所以乘了2;
QVector<QPoint>::iterator it = pos.begin();
for( ;it != pos.end(); ++it)
{
painter->drawPoint(*it);
}
painter->end();
painter->begin(this);
painter->drawPixmap(0, 0, *pixmap);
pos.clear();
}
}
void MyWidget::on_time()
{
if(count > 49)
timer->stop();
else
{
count++;
for(int x = 0; x < 300; ++x )
{
for(int y = 0; y < 300; ++y )
{
double a = 0.0,b = 0.0,c = 0.0,d = 0.0,tmpd = 0.0;
double per = count
per = per*0.01;
d = pow((x-150.0),2) + pow((y-150.0),2);//求得点(x,y)到圆心距离d^2
tmpd = pow(d,0.5);//d^2开方求得tmpd
c = pow((150.0-x),2) + pow((150+tmpd-y),2);//求得斜边c
b = acos((1.0 - 0.5*(c/d)));//余弦定理求得该点偏移角度b
a = (2*3.141593)*per;//
if ( tmpd >= 0 && tmpd<= 100)
{
if(a >= b)
{
pos.append(QPoint(x,y));
}
}
this->update();//调用paintEvent重新绘制
}
}
}
}
/*----------------MyWidget.cpp---------------------------*/
/*----------------main.cpp---------------------------*/
#include <QApplication>
#include "MyWidget.h"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MyWidget w;
QSize Size(300,300);
w.setFixedSize(Size);
w.show();
return app.exec();
}
/*----------------main.cpp---------------------------*/
备份地址: 【FaceBook面试题: QPainter重绘实现圆形进度条】