• 第六十七课、基础图形绘制(中)------------------狄泰软件学院


    一、基础图形绘制

    1、Qt图形系统中的坐标系

    (1)、物理坐标系(设备坐标系)

    A、原点(0,0)在左上角的位置,单位:像素(点)

    B、x坐标向右增长,y坐标向下增长

    (2)、逻辑坐标系(如数学中的坐标系)

    A、数学模型中的抽象坐标系,单位由具体问题确定

    B、坐标的增长方向由具体问题决定

    2、一些事实

    (1)、QPainter使用逻辑坐标系绘制图形

    (2)、逻辑坐标系中图形点大小和位置经由转换后绘制于具体设备

    (3)、默认情况下逻辑坐标系与物理坐标系完全一致

    3、视口与窗口(站在不同的角度看待同一个矩形)

    (1)、视口:物理坐标系中一个任意指定的矩形

    (2)、窗口:逻辑坐标系下对应到物理坐标系中相同的矩形

    4、深入理解视口与窗口

    (1)、视口与窗口是不同坐标系中的同一个矩形

    (2)、视口与窗口中的坐标点存在一一映射的关系

    (3)、窗口与视口能够通过坐标转换而互相转换

    5、视口与窗口的变换方法

    (1)、定义视口(setViewport):左上角坐标,右下角坐标,计算宽度和高度

    (2)、定义窗口(setWindow):左上角坐标,右下角坐标,计算宽度和高度

    (3)、一般做法时,先挖一个视口出来,然后在挖出来的视口上重新定义坐标系就成为窗口了

    void Widget::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
    
        painter.setViewport(50, 50, width()-100, height()-100);
        painter.setWindow(-10, 2, 20, -4);//这里我取左上角坐标为(-10,2),右下角坐标为(10,-2),就可以算出width=20,height=-4
        painter.fillRect(-10, 2, 20, -4, Qt::black);
    }

     6、正弦波绘图实例

    (1)、定义视口坐标和逻辑坐标系

    (2)、定义画笔并填充窗口底色

    (3)、根据实际问题中的波形函数绘图(drawPoint())

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QPainter>
    
    class Widget : public QWidget
    {
        Q_OBJECT
    private:
        void paintEvent(QPaintEvent *);
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    };
    
    #endif // WIDGET_H
    Widget.h
    #include "Widget.h"
    #include <QPen>
    #include <QPointF>
    #include <qmath.h>
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
    }
    //1.设置画笔属性
    //2.挖出一个视口,并重新定义坐标成为窗口
    //3.画网格
    //4.画波形(不过这样太耗时,可仿照上节课的将波形数据放到一个链表,然后遍历出链表里面的点来画)
    void Widget::paintEvent(QPaintEvent *)//一定要注意只能在paintEvent里面画图
    {
        QPainter painter(this);
        QPen pen;
    
        pen.setColor(Qt::green);
        pen.setStyle(Qt::SolidLine);
        pen.setWidthF(0.03);
    
        painter.setPen(pen);
    
        painter.setViewport(50, 50, width()-100, height()-100);
        painter.setWindow(-10, 2, 20, -4);
        painter.fillRect(-10, 2, 20, -4, Qt::black);
    
        for(float i=-2, j=-10; (j<=10) || (i<=2); i += 0.5, j+=1)
        {
            painter.drawLine(QPointF(-10, i), QPointF(10, i));
            painter.drawLine(QPointF(j, 2), QPointF(j, -2));
        }
    
        for(float x=-10; x<10; x+=0.001)
            {
                float y = qSin(x);
    
                painter.drawPoint(QPointF(x, y));
            }
    }
    Widget::~Widget()
    {
    
    }
    Widget.cpp
    #include "Widget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }
    main.cpp

    二、小结

    (1)、QPainter使用逻辑坐标系进行绘图

    (2)、逻辑坐标系能够变换到物理坐标系

    (3)、视口与窗口指不同坐标系下的同一个矩形

    (4)、窗口用于逻辑坐标系下图形绘制

    (5)、视口用于实际物理设备上的图形显示

     

  • 相关阅读:
    MySQL 快速删除大量数据(千万级别)的几种实践方案——附源码
    Elasticsearch 通过Scroll遍历索引,构造pandas dataframe 【Python多进程实现】
    MySQL LOAD DATA INFILE—从文件(csv、txt)批量导入数据
    【Java】 NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、ArrayIndexOutOfBoundsException、ArrayStoreException、ArithmeticException等没有异常堆栈信息
    技术人“结构化思维”训练的一点想法和实践
    gitlab内存消耗大,频繁出现502错误的解决办法
    Tesseract-OCR 4.1.0 安装和使用— windows及CentOS
    Tika结合Tesseract-OCR 实现光学汉字识别(简体、宋体的识别率百分之百)—附Java源码、测试数据和训练集下载地址
    记一次Elasticsearch OOM(内存溢出)的优化过程—基于segments force merge 和 store type 转为 hybridfs
    ElasticSearch如何一次查询出全部数据——基于Scroll
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6572323.html
Copyright © 2020-2023  润新知