使用QPainter画一个3D正方体

本文实例为大家分享了QPainter画一个3D正的具体代码,供大家参考,具体内容如下

My3DBox .h

#include <Eigen/Geometry>using namespace Eigen;#define SQUARE_LENGTH 200//是一个边长200的正方体#define CAMERA_DISTANCE 300//视点距离class My3DBox : public QWidget{  Q_OBJECTpublic:  explicit My3DBox(QWidget *parent = 0);protected:  QPoint m_mousePos;  Vector3d m_vector[8];//正方形8个点坐标  void mouseMoveEvent(QMouseEvent *);  void paintEvent(QPaintEvent *);  void drawPlane(const QPoint *points,QPainter &painter);  Matrix3d getMartix();  QPoint ToPoint(Vector3d vector);  void drawUp(QPoint *points,QPainter &painter);//正方体面的绘制  void drawDown(QPoint *points,QPainter &painter);  void drawLeft(QPoint *points,QPainter &painter);  void drawRight(QPoint *points,QPainter &painter);};

My3DBox .cpp

#include "widget.h"#define PI 3.1415926My3DBox::My3DBox(QWidget *parent) :  QWidget(parent),m_mousePos(0,0){  setMouseTracking(true);//在任何情况下启用mouseMoveEvent  setGeometry(400,200,500,500);  m_vector[0] << -100,100,100;//设置正方体顶点初始位置  m_vector[1] << 100,100,100;  m_vector[2] << -100,-100,100;  m_vector[3] << 100,-100,100;  m_vector[4] << -100,100,-100;  m_vector[5] << 100,100,-100;  m_vector[6] << -100,-100,-100;  m_vector[7] << 100,-100,-100;}void My3DBox::mouseMoveEvent(QMouseEvent *e)//此处把坐标原点从左上角变换至屏幕中心{  if(e->pos().x() < 0)    m_mousePos.setX(-width()/2);  else if(e->pos().x() > width())    m_mousePos.setX(width()/2);  else    m_mousePos.setX(e->pos().x() - width()/2);  if(e->pos().y() < 0)    m_mousePos.setY(height()/2);  else if(e->pos().y() > height())    m_mousePos.setY(-height()/2);  else    m_mousePos.setY(-e->pos().y() + height()/2);  update();}void My3DBox::paintEvent(QPaintEvent *){  QPainter painter(this);  painter.setRenderHint(QPainter::Antialiasing);  painter.setRenderHint(QPainter::SmoothPixmapTransform);  painter.setPen(Qt::NoPen);  painter.fillRect(rect(),QColor(3,22,52));  Vector3d vector[8];  Matrix3d matrix = getMartix();//获取变换矩阵  QPoint points[8];//正面0123 左面4062 右面1537 上面4501 下面 2367(以观察者的方向为主)  for(int i = 0;i < 8;++i)//计算变换后坐标  {    vector[i] = matrix*m_vector[i];    points[i] = ToPoint(vector[i]);    points[i].setX(points[i].x()+width()/2);//将坐标系原点变换至左上角    points[i].setY(-points[i].y()+height()/2);  }  //一共要画5个面,最后画正面  if(qAbs(m_mousePos.x()) > qAbs(m_mousePos.y()))  {    if(m_mousePos.x() > 0)    {      if(m_mousePos.y() > 0)        drawDown(points,painter);      else        drawUp(points,painter);      drawLeft(points,painter);    }    else    {      if(m_mousePos.y() > 0)        drawDown(points,painter);      else        drawUp(points,painter);      drawRight(points,painter);    }  }  else  {    if(m_mousePos.y() > 0)    {      if(m_mousePos.x() > 0)        drawLeft(points,painter);      else        drawRight(points,painter);      drawDown(points,painter);    }    else    {      if(m_mousePos.x() > 0)        drawLeft(points,painter);      else        drawRight(points,painter);      drawUp(points,painter);    }  }  //画正面  QPoint point[4] =  {    points[0],    points[1],    points[3],    points[2]  };  drawPlane(point,painter);}void My3DBox::drawPlane(const QPoint *points,QPainter &painter){  QLinearGradient linearGradient(points[1],points[3]);//设置渐变色  linearGradient.setColorAt(0.0,QColor(150,150,250));  linearGradient.setColorAt(1.0,QColor(170,170,255));  painter.setBrush(QBrush(linearGradient));  painter.drawConvexPolygon(points,4);}Matrix3d My3DBox::getMartix(){  double unit_x = 0;//同方向单位向量的x和y  double unit_y = 0;  double z = 0;  if(m_mousePos.x() != 0 || m_mousePos.y() != 0)  {    unit_x = m_mousePos.x()/qSqrt(m_mousePos.x()*m_mousePos.x() + m_mousePos.y()*m_mousePos.y());    unit_y = m_mousePos.y()/qSqrt(m_mousePos.x()*m_mousePos.x() + m_mousePos.y()*m_mousePos.y());    z = qSqrt(m_mousePos.x()*m_mousePos.x() + m_mousePos.y()*m_mousePos.y())/qSqrt(width()*width()/4 + height()*height()/4);  }  Matrix3d M_Z;  if(unit_x == 0 && unit_y == 0)    M_Z << 1,0,0,        0,1,0,        0,0,1;  else    M_Z << unit_y,-unit_x,0,        unit_x,unit_y,0,        0,0,1;  Matrix3d M_X;  if(z == 0)    M_X << 1,0,0,        0,1,0,        0,0,1;  else    M_X << 1,0,0,        0,cos(z*PI/2.6),sin(z*PI/2.6),        0,-sin(z*PI/2.6),cos(z*PI/2.6);//为什么PI/2大于90度?因为没画背面所以必须小于90度(偷懒)  return M_Z.inverse()*M_X*M_Z;}QPoint My3DBox::ToPoint(Vector3d vector)//将3d坐标投影至平面上{  QPoint point;  point.setX(CAMERA_DISTANCE*vector[0]/(CAMERA_DISTANCE-vector[2]));  point.setY(CAMERA_DISTANCE*vector[1]/(CAMERA_DISTANCE-vector[2]));  return point;}void My3DBox::drawUp(QPoint *points,QPainter &painter){  QPoint point[4] =  {    points[4],    points[5],    points[1],    points[0]  };  drawPlane(point,painter);}void My3DBox::drawDown(QPoint *points,QPainter &painter){  QPoint point[4] =  {    points[2],    points[3],    points[7],    points[6]  };  drawPlane(point,painter);}void My3DBox::drawLeft(QPoint *points,QPainter &painter){  QPoint point[4] =  {    points[4],    points[0],    points[2],    points[6]  };  drawPlane(point,painter);}void My3DBox::drawRight(QPoint *points,QPainter &painter){  QPoint point[4] =  {    points[1],    points[5],    points[7],    points[3]  };  drawPlane(point,painter);}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

也只有懂的接受自己的失败,才能更好的去发挥自身优势,也才能够更好的去实现自我;

使用QPainter画一个3D正方体

相关文章:

  • 【算法】直接插入排序C语言实现
  • 嵌入式 FAAC1.28 在海思HI3518C/HI3518A平台linux中的编译优化
  • 你感兴趣的文章:

    标签云:

    亚洲高清电影在线, 免费高清电影, 八戒影院夜间, 八戒电影最新大片, 出轨在线电影, 午夜电影院, 在线影院a1166, 在线电影院, 在线观看美剧下载, 日本爱情电影, 日韩高清电影在线, 电影天堂网, 直播盒子app, 聚合直播, 高清美剧, 高清美剧在线观看 EhViewer-E站, E站, E站绿色版, qqmulu.com, qq目录网, qq网站目录,