summaryrefslogtreecommitdiffstats
path: root/doc/src/qline3d-math.qdoc
blob: beacf1b21cb650bd463bdde3ce406987711697f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtQuick3D documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \ingroup qt3d
    \ingroup qt3d::math
    \since 4.8
    \title 3D Math Basis
    \page qt3d-math-basis.html
    \keyword 3D Math Basis
    \brief Math foundations for the Qt3D math classes.

    The math classes provide basic operations in 3-space useful for graphics:
    \list
    \o QLine3D
    \o QLineSegment3D
    \o QPlane3D
    \o QTriangle3D
    \o QBox3D
    \endlist

    This is a basic discussion of the mathematics behind these classes.

    \section1 Vectors and Points

    There are two important building blocks in 3D: the \bold vector and the
    \bold point in cartesian 3-space.

    Both are comprised by 3 values in \bold R, the real numbers.

    So programatically in Qt both vectors and points are stored in a QVector3D instance,
    since that class can store 3 qreal values.

    But there are important differences between points and vectors:
    \list
    \o a point \bold P is a 3D \i location, and makes sense in terms of a 3D cartesian
        coordinate system.  A real-world example is a map-location given in terms
        of a map cross-reference.  The location has no inherent magnitude, unless you
        provide another location and find the distance between the two.
    \o a vector \bold v is a 3D \i direction and magnitude.  It makes no sense to talk
        about a vector being located somewhere.  A vector can represent for example
        some directions like "go 3 north-west 3 kilometers", but this can be done from
        \bold {anywhere on the map} - it is not anchored like the point is.
    \endlist

    In 3D math points and vectors are represented by column vectors:

    \image vector-point.png

    In normal text where the over-arrow symbol is not available the vector is just a
    bolded lower-case letter.  A point is a capital letter, non-bolded.

    The fourth element in the column vectors above, w = 1 for points and w = 0 for vectors
    means that vectors are not altered by certain affine transformations such
    as \c{translate()}.

    \image affine-transform.png

    This affine transform T comprises a rotation and a translation.  Remember that applying
    the transform is done by the
    \l{http://www.intmath.com/Matrices-determinants/4_Multiplying-matrices.php}{matrix multiplication}
    \c{P * T = P'}.

    Notice how the 1 in the column for the translation multiplies out to zero against
    the vectors last 0 value, so the vector is "immune" to the translation.

    In the case of the point the w = 1 "triggers" the translation values in the matrix.

    So the take away principle is that points and vectors, while represented by the same
    data structure are different and behave differently in 3D math.

    \section2 Vector Magnitude and Normal Vectors

    Another important difference between points and vectors is that a vector has a magnitude,
    whereas a point does not.

    Consider the vector v = (v0, v1, v2) to be rooted at
    the origin O = (0, 0, 0) and pointing to the point P = (v0, v1, v2), then
    its magnitude is the length of the line O to P.  Magnitude is represented by
    vertical bars and is found by this formula:

    \image vector-mag.png

    Unit vectors are those with a magnitude of exactly 1.  The math notation is a "hat"
    (or circumflex) over the bolded vector symbol.

    A unit vector parallel to one of the axes is easy to form without any division:
    \raw HTML
    <center><b>&#238;</b> = (1, 0, 0)</center>
    \endraw

    More typically such a vector is found by dividing by its own length:

    \image vector-normalized.png

    Vectors used for 3D normals are usually normalized to unit length.  Confusingly
    enough, since that is two different uses of the word "normal".

    A \i normal is simply a vector perpendicular to something.  For example a plane normal is
    perpendicular to the plane.

    Typically a normal vector is unit length, for convenience in 3D applications (but
    there is nothing mathematically to say a normal vector has to be unit length).

    A vertex normal is perpendicular to the surface modelled by the vertex, and is used
    in lighting calculations.

    \section1 Reviewing Operations on Vectors

    The QVector3D class provides two very useful functions - the vector dot-product and the
    vector cross-product.  Here's a quick review of their uses:
    \list
    \o QVector3D::crossProduct(const QVector3D &, const QVector3D &)
        \list
        \o The cross-product of two vectors produces a \i vector as a result and is
        written \bold w = \bold u x \bold v. The result \bold w is perpendicular to both
        \bold u and \bold v.  Consider a plane N containing point P, with the tails of \bold u
        and \bold v at P, and both lying in N, then \bold u x \bold v is a normal to N.
        \endlist
    \o QVector3D::dotProduct(const QVector3D &, const QVector3D &)
        \list
        \o The dot-product of two vectors produces a \i scalar as a result and is written
        \c{t = \bold u . \bold v}.  The result t = |u| |v| cos(A), where A is the angle
        between u and v.  When \bold u and \bold v have magnitude 1, they are called
        unit vectors, and \bold u . \bold v = cos(A).
        \endlist
    \endlist

    A vector has the following operations defined on it in 3-space
    \list
    \o multiplication by a scalar, eg v' = s * \bold v
    \o addition with another vector, eg \bold u = \bold v + \bold w
    \endlist

    Multiplying and dividing by vectors is not defined - these operations make no sense in
    3-D space.

    Although you cannot add a vector to a point as such, you can consider the vector from the
    origin to the point, and add the vector to that.  Thus rather than out-lawing adding a
    vector to a point it is simply defined as such.  This allows the convenient notation for
    lines and planes introduced in the next section.

    \section1 Representing Lines and Planes

    The QLine3D is represented by a point and a vector: the point anchors the line in
    cartesian 3-space; and the vector is the direction the line is oriented in through that
    point.  The line is infinite.

    The QPlane3D is represented also by a point and a vector.  Again the point anchors the line
    in cartesian 3-space; but the vector this time is a normal to the plane.  The plane is
    infinite.

    This representation turns out to make many types of calculations required for 3D graphics
    very straight forward.

    For example to find if a point P lies on a plane take the vector \bold p from the point to
    the planes origin, and find the dot-product with the planes normal \bold n.

    If \bold {p . n} is zero, then \bold p is perpendicular to \bold n, and P is on the plane.

    \target vector-and-point-arithmetic
    \section1 Vector and Point Arithmetic

    Slightly more complex arithmetic with the components of QLine3D and QPlane3D is possible,
    with some care about what operations can be performed.

    As an example look at the implementation for QLine3D::intersection(const QLine3D &) : the
    two lines are defined as:

    \image line-int-1.png

    If the two lines intersect then P(t) == Q(s) and for some ordered pair \bold s, \bold t
    is a solution to the equations for both lines.

    The aim is to solve for \bold s and \bold t.

    The equations can be rearranged algebraically as shown in the last line above.

    But since dividing by a vector is not defined, tempting options such as dividing by \bold v
    to solve for t are not possible.  In the implementation the next step is breaking the points
    and vectors down into their x, y and z components giving 3 simultaneous equations:

    \image line-int-2.png

    This can be readily solved using gaussian elimination to get a solution for s, and
    substituting back gives t.
*/