QT6 源,十章绘图(4):线 QLine 与 QLineF 的源代码带注释

(1)本类的继承关系如下 :

在这里插入图片描述

(2)在学习 Qt 的绘图里,需要提前了解,点 QPoint、线 QLine、 矩形 QRect 的知识。因为绘图里会频繁的用到这些最基础的 QT 框架知识。所以熟悉一下直线这个类。本直线类支持流操作运算符

在这里插入图片描述

(3) 本 QLine 的源代码 ,全是内联函数,给出了函数体,不再注释了 :

#ifndef QLINE_H
#define QLINE_H

#include <QtCore/qpoint.h>

QT_BEGIN_NAMESPACE


/*******************************************************************************
 * class QLine
 *******************************************************************************/

/*
The QLine class provides a two-dimensional vector using integer precision.

Detailed Description :
QLine描述二维曲面上的有限长度线(或线段)。直线的起点和终点使用坐标的整数点精度来指定。
使用QLineF构造函数检索浮点副本。

该线条的起点和终点的位置可以通过、p1()、`x1()、y1 (),`p2()、`x2()'和'y2()'函数来获取。
dx()'和`dy ()'函数返回该线条的横向和纵向分量。
使用`isNull()`函数可判断`QLine'是否代表一条有效线条或空线条。

最后,可以使用translate()函数将线平移给定的偏移量。

*/


Q_CORE_EXPORT QDebug        operator<<(QDebug        d, const QLine & p);
Q_CORE_EXPORT QDataStream & operator<<(QDataStream &  , const QLine &  );
Q_CORE_EXPORT QDataStream & operator>>(QDataStream &  ,       QLine &  );

class Q_CORE_EXPORT QLine
{
private:
    QPoint pt1, pt2;

public:
    constexpr inline QLine() { }

    constexpr inline QLine(int x1, int y1, int x2, int y2)
        : pt1(QPoint(x1, y1)), pt2(QPoint(x2, y2)) { }

    constexpr inline QLine(const QPoint & pt1_, const QPoint & pt2_)
        : pt1(   pt1_    )   , pt2(     pt2_     ) { }

    constexpr  inline
    bool     isNull() const { return pt1 == pt2;        }

    constexpr  inline
    QPoint       p1() const { return pt1;               }
    constexpr  inline
    QPoint       p2() const { return pt2;               }

    constexpr inline
    int          x1() const { return pt1.x();           }
    constexpr inline
    int          y1() const { return pt1.y();           }

    constexpr inline
    int          x2() const { return pt2.x();           }
    constexpr inline
    int          y2() const { return pt2.y();           }

    constexpr inline
    int          dx() const { return pt2.x() - pt1.x(); }
    constexpr inline
    int          dy() const { return pt2.y() - pt1.y(); }

    [[nodiscard]] constexpr inline
    QPoint   center() const       //返回本直线的中点
    {
        return   QPoint(int((qint64(pt1.x()) + pt2.x()) / 2),
                      int((qint64(pt1.y()) + pt2.y()) / 2)   );
    }

    constexpr inline
    bool operator==(const QLine & d) const noexcept
    {   return pt1 == d.pt1 && pt2 == d.pt2;    }

    constexpr inline
    bool operator!=(const QLine & d) const noexcept
    {   return !(*this == d); }

    inline
    void      setP1(const QPoint & ap1) { pt1 = aP1; }
    inline
    void      setP2(const QPoint & ap2) { pt2 = aP2; }
    inline
    void  setLine  (int x1, int y1, int x2, int y2)
    {    pt1 = QPoint(x1, y1);    pt2 = QPoint(x2, y2);   }
    inline
    void  setPoints(const QPoint & p1, const QPoint & p2)
    {    pt1 = p1;                pt2 = p2;               }

    inline     //将此线通过给定的偏移量 offset进行偏移。
    void       translate (const QPoint & offset)
    {   pt1 += offset;  pt2 += offset;             }

    inline     //将此线沿由 dx和 dy指定的距离进行平移。
    void       translate (int dx,       int  dy)
    {   this-> translate (QPoint(dx,  dy));        }

    [[nodiscard]] constexpr inline  //返回本直线偏移 offset后得到的直线。
    QLine      translated(const QPoint & offset) const
    {   return QLine(pt1 + offset, pt2 + offset);  }

    [[nodiscard]] constexpr inline  //返回将本直线沿由 dx和 dy指定的距离进行平移后得到的直线。
    QLine      translated(int dx,       int  dy) const
    {   return translated(QPoint(dx, dy));         }


}; //完结 class Q_CORE_EXPORT QLine
Q_DECLARE_TYPEINFO(QLine, Q_RELOCATABLE_TYPE);

QT_END_NAMESPACE

#endif // QLINE_H

(4) QPoint 与 QPointF 没有区别。 但 QLineF 比 QLine 扩充了内容,需要单独记录一下新增的部分的成员函数

在这里插入图片描述

++

在这里插入图片描述

++

在这里插入图片描述

++

在这里插入图片描述

(5)以下是 QPointF 的完整代码

/*******************************************************************************
 * class QLineF
 *******************************************************************************/

/*
The QLineF class provides a two-dimensional vector using floating point precision.

这条线的长度可以通过`length()、函数获取,并通过`setLength()、函数进行修改。
同样,`angle()、和`setAngle()、分别用于获取和改变线的角度。
使用`isNul()、函数可判断`QLineF'是否代表一条有效线或空线。

intersects()、函数用于确定这条线和给定的线之间的相交类型,
而`angleTo()'函数则返回这两条线之间的夹角。
此外,`unitVector()'函数返回一条起点与这条线相同但长度仅为1的线,
而`normalVector()、函数返回一条与这条线垂直且起点和长度相同的线。

最后,可以使用translate()函数将线条平移给定的偏移量,并且可以使用pointAt()函数进行遍历。

*/

class Q_CORE_EXPORT QLineF
{
private:
    QPointF pt1, pt2;

public:
    constexpr inline QLineF();
    constexpr inline QLineF(const QPointF & pt1, const QPointF & pt2);
    constexpr inline QLineF(qreal x1, qreal y1, qreal x2, qreal y2);
    constexpr inline QLineF(const QLine &line) : pt1(line.p1()), pt2(line.p2()) { }

    [[nodiscard]]  //按极坐标的参数方式,构造一条等同的直线,具有直角坐标系。
    static QLineF fromPolar(qreal length, qreal angle);
    //返回一个具有给定长度 length和角度 angle的QLineF。
    //线的第一个点将在原点。角度的正值表示逆时针方向,而负值表示顺时针方向。零度位于三点钟位置。

    constexpr bool isNull() const;

    constexpr inline QPointF p1() const;
    constexpr inline QPointF p2() const;

    constexpr inline qreal   x1() const;
    constexpr inline qreal   y1() const;

    constexpr inline qreal   x2() const;
    constexpr inline qreal   y2() const;

    constexpr inline qreal   dx() const; //distance 距离
    constexpr inline qreal   dy() const;

    constexpr inline bool operator==(const QLineF & d) const;
    constexpr inline bool operator!=(const QLineF & d) const { return !(*this == d); }

    inline void setP1(const QPointF & p1);
    inline void setP2(const QPointF & p2);
    inline void setPoints(const QPointF & p1, const QPointF & p2);
    inline void setLine  (qreal x1, qreal y1, qreal x2, qreal y2);
    
    inline void   translate (const QPointF   & offset);
    inline void   translate (qreal dx, qreal   dy);
    
    [[nodiscard]] constexpr
    inline QLineF translated(const QPointF   & p ) const;
    [[nodiscard]] constexpr
    inline QLineF translated(qreal dx, qreal   dy) const;

    qreal      length()       const; //返回本直线的长度
    void    setLength(qreal length); //将线的长度设定为给定的长度 length。
    //QLineF会将线的端点, p2(), 移动到新的位置从而赋予线其新的长度,
    //除非之前的长度为0,在这种情况下将不会尝试进行缩放.

    //返回线的角度(以度为单位)0。返回值将在 0.0到但不包含 360.0的数值范围内。
    //这些角度是从原点右侧的 x轴上的一点开始逆时针测量的(x>0)。
    qreal      angle  () const;
    void    setAngle  (qreal angle);
    //将线的角度设置为给定的角度 angle(以度为单位)。这将改变线的第二点的位置,使线具有给定的角度。
    //角度的正值表示逆时针方向,而负值表示顺时针方向。零度位置在三点钟的位置。
    qreal      angleTo(const QLineF & line) const;
    //该函数返回从当前线到给定线 line的角度(以度为单位),同时考虑了两条线之间的方向。
    //如果两条线在其范围内没有相交,那么由延伸后的线的交点所构成的点将作为原点
    //  (请参阅QLineF:JnboundedIntersection)。
    //返回值表示您需要向这条线添加多少度,以便使其与给定的线保持相同的角度。逆时针方向为正。

    //返回这条线的单位向量,即从该线相同起点出发且长度为1.0的线段,前提是该线不为空。
    [[nodiscard]]
    QLineF   unitVector() const;  //单位向量
    [[nodiscard]] constexpr inline
    QLineF normalVector() const;  //法向量
    //返回一条与这条线垂直且具有相同起点和长度的线。 (x, y) --> (y, -x)

    constexpr inline
    QPointF     pointAt(qreal t) const; // 0 <= t <= 1
    //返回由有限参数t指定位置的点。如果t=0,函数返回线的起点;如果t=1,函数返回线的终点。

    [[nodiscard]] constexpr inline
    QPointF      center() const;

    constexpr
    QLine        toLine() const;


    enum IntersectionType {       //描述两条线之间的交点。
               NoIntersection,    //表示这些线不相交;即它们是平行的。
          BoundedIntersection,    //这两条线在每条线的起点和终点之间相交。
        UnboundedIntersection     //这两条线相交,但不在由它们的长度所定义的范围内。
        //如果这两条线不平行,就会出现这种情况。
        //如果相交点位于仅一条线的起点和终点范围内,`intersect()'函数也会返回该值。
    };
    using IntersectType = IntersectionType; // deprecated name 此名字不用了,废弃了
    IntersectionType intersects(const   QLineF  & line,
                                        QPointF * intersectionPoint = nullptr) const;
    //返回一个值,指示此线是否与给定的线 line相交。
    //实际的交点会被提取到 intersectionPoint(如果指针有效的话)。
    //如果两条线是平行的,那么交点将是不确定的。


}; //完结 class Q_CORE_EXPORT QLineF
Q_DECLARE_TYPEINFO(QLineF, Q_RELOCATABLE_TYPE);

/*******************************************************************************
 * class QLineF inline members
 *******************************************************************************/

constexpr inline QLineF::QLineF()
{
}

constexpr inline QLineF::QLineF(const QPointF &apt1, const QPointF &apt2)
    : pt1(apt1), pt2(apt2)
{
}

constexpr inline QLineF::QLineF(qreal x1pos, qreal y1pos, qreal x2pos, qreal y2pos)
    : pt1(x1pos, y1pos), pt2(x2pos, y2pos)
{
}

constexpr inline qreal QLineF::x1() const
{
    return pt1.x();
}

constexpr inline qreal QLineF::y1() const
{
    return pt1.y();
}

constexpr inline qreal QLineF::x2() const
{
    return pt2.x();
}

constexpr inline qreal QLineF::y2() const
{
    return pt2.y();
}

constexpr inline bool QLineF::isNull() const
{
    return qFuzzyCompare(pt1.x(), pt2.x()) && qFuzzyCompare(pt1.y(), pt2.y());
}

constexpr inline QPointF QLineF::p1() const
{
    return pt1;
}

constexpr inline QPointF QLineF::p2() const
{
    return pt2;
}

constexpr inline qreal QLineF::dx() const
{
    return pt2.x() - pt1.x();
}

constexpr inline qreal QLineF::dy() const
{
    return pt2.y() - pt1.y();
}

constexpr inline QLineF QLineF::normalVector() const
{
    return QLineF(p1(), p1() + QPointF(dy(), -dx()));
}

inline void QLineF::translate(const QPointF &point)
{
    pt1 += point;
    pt2 += point;
}

inline void QLineF::translate(qreal adx, qreal ady)
{
    this->translate(QPointF(adx, ady));
}

constexpr inline QLineF QLineF::translated(const QPointF &p) const
{
    return QLineF(pt1 + p, pt2 + p);
}

constexpr inline QLineF QLineF::translated(qreal adx, qreal ady) const
{
    return translated(QPointF(adx, ady));
}

constexpr inline QPointF QLineF::center() const
{
    return QPointF(0.5 * pt1.x() + 0.5 * pt2.x(), 0.5 * pt1.y() + 0.5 * pt2.y());
}

inline void QLineF::setLength(qreal len)
{
    Q_ASSERT(qIsFinite(len));
    const qreal oldLength = length();
    Q_ASSERT(qIsFinite(oldLength));
    // Scale len by dx() / length() and dy() / length(), two O(1) quantities,
    // rather than scaling dx() and dy() by len / length(), which might overflow.
    if (oldLength > 0)
        pt2 = QPointF(pt1.x() + len * (dx() / oldLength), pt1.y() + len * (dy() / oldLength));
}

constexpr inline QPointF QLineF::pointAt(qreal t) const
{
    return QPointF(pt1.x() + (pt2.x() - pt1.x()) * t, pt1.y() + (pt2.y() - pt1.y()) * t);
}

constexpr inline QLine QLineF::toLine() const
{
    return QLine(pt1.toPoint(), pt2.toPoint());
}


inline void QLineF::setP1(const QPointF &aP1)
{
    pt1 = aP1;
}

inline void QLineF::setP2(const QPointF &aP2)
{
    pt2 = aP2;
}

inline void QLineF::setPoints(const QPointF &aP1, const QPointF &aP2)
{
    pt1 = aP1;
    pt2 = aP2;
}

inline void QLineF::setLine(qreal aX1, qreal aY1, qreal aX2, qreal aY2)
{
    pt1 = QPointF(aX1, aY1);
    pt2 = QPointF(aX2, aY2);
}


constexpr inline bool QLineF::operator==(const QLineF &d) const
{
    return pt1 == d.pt1 && pt2 == d.pt2;
}



#ifndef QT_NO_DEBUG_STREAM
Q_CORE_EXPORT QDebug operator<<(QDebug d, const QLineF &p);
#endif

#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QLineF &);
Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QLineF &);
#endif

(6)

谢谢

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值