Blender V5.0
COM_utilities_diagonals.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
7#include "BLI_math_base.hh"
9
10namespace blender::compositor {
11
12/* Computes the number of diagonals in the matrix of the given size, where the diagonals are
13 * indexed from the upper left corner to the lower right corner such that their start is at the
14 * left and bottom edges of the matrix as shown in the diagram below. The numbers in the diagram
15 * denote the index of the diagonal. The number of diagonals is then intuitively the number of
16 * values on the left and bottom edges, which is equal to:
17 *
18 * Number Of Diagonals => width + height - 1
19 *
20 * Notice that the minus one is due to the shared value in the corner.
21 *
22 * Width = 6
23 * +---+---+---+---+---+---+
24 * | 0 | 1 | 2 | 3 | 4 | 5 |
25 * +---+---+---+---+---+---+
26 * | 1 | 2 | 3 | 4 | 5 | 6 | Height = 3
27 * +---+---+---+---+---+---+
28 * | 2 | 3 | 4 | 5 | 6 | 7 |
29 * +---+---+---+---+---+---+
30 */
32{
33 return size.x + size.y - 1;
34}
35
36/* Computes the number of values in the diagonal of the given index in the matrix with the given
37 * size, where the diagonals are indexed from the upper left corner to the lower right corner such
38 * that their start is at the left and bottom edges of the matrix as shown in the diagram below.
39 * The numbers in the diagram denote the index of the diagonal and its length.
40 *
41 * Width = 6
42 * +---+---+---+---+---+---+
43 * 1 | 0 | 1 | 2 | 3 | 4 | 5 |
44 * +---+---+---+---+---+---+
45 * 2 | 1 | 2 | 3 | 4 | 5 | 6 | Height = 3
46 * +---+---+---+---+---+---+
47 * | 2 | 3 | 4 | 5 | 6 | 7 |
48 * +---+---+---+---+---+---+
49 * 3 3 3 3 2 1
50 *
51 * To derive the length of the diagonal from the index, we note that the lengths of the diagonals
52 * start at 1 and linearly increase up to the length of the longest diagonal, then remain constant
53 * until it linearly decrease to 1 at the end. The length of the longest diagonal is intuitively
54 * the smaller of the width and height of the matrix. The linearly increasing and constant parts of
55 * the sequence can be described using the following compact equation:
56 *
57 * Length => min(Longest Length, index + 1)
58 *
59 * While the constant and deceasing end parts of the sequence can be described using the following
60 * compact equation:
61 *
62 * Length => min(Longest Length, Number Of Diagonals - index)
63 *
64 * All three parts of the sequence can then be combined using the minimum operation because they
65 * all share the same maximum value, that is, the longest length:
66 *
67 * Length => min(Longest Length, index + 1, Number Of Diagonals - index)
68 */
69inline int compute_diagonal_length(const int2 &size, const int diagonal_index)
70{
71 int length_of_longest_diagonal = math::min(size.x, size.y);
72 int start_sequence = diagonal_index + 1;
73 int end_sequence = compute_number_of_diagonals(size) - diagonal_index;
74 return math::min(length_of_longest_diagonal, math::min(start_sequence, end_sequence));
75}
76
77/* Computes the position of the start of the diagonal of the given index in the matrix with the
78 * given size, where the diagonals are indexed from the upper left corner to the lower right corner
79 * such that their start is at the left and bottom edges of the matrix as shown in the diagram
80 * below. The numbers in the diagram denote the index of the diagonal and the position of its
81 * start.
82 *
83 * Width = 6
84 * +-----+-----+-----+-----+-----+-----+
85 * (0, 2) | 0 | 1 | 2 | 3 | 4 | 5 |
86 * +-----+-----+-----+-----+-----+-----+
87 * (0, 1) | 1 | 2 | 3 | 4 | 5 | 6 | Height = 3
88 * +-----+-----+-----+-----+-----+-----+
89 * | 2 | 3 | 4 | 5 | 6 | 7 |
90 * +-----+-----+-----+-----+-----+-----+
91 * (0, 0) (1,0) (2,0) (3,0) (4,0) (5,0)
92 *
93 * To derive the start position from the index, we consider each axis separately. For the X
94 * position, indices up to (height - 1) have zero x positions, while other indices linearly
95 * increase from (height) to the end. Which can be described using the compact equation:
96 *
97 * X => max(0, index - (height - 1))
98 *
99 * For the Y position, indices up to (height - 1) linearly decrease from (height - 1) to zero,
100 * while other indices are zero. Which can be described using the compact equation:
101 *
102 * Y => max(0, (height - 1) - index)
103 */
104inline int2 compute_diagonal_start(const int2 &size, const int index)
105{
106 return int2(math::max(0, index - (size.y - 1)), math::max(0, (size.y - 1) - index));
107}
108
109/* Computes a direction vector such that when added to the position of a value in a matrix will
110 * yield the position of the next value in the same diagonal. According to the choice of the start
111 * of the diagonal in compute_diagonal_start, this is (1, 1). */
113{
114 return int2(1);
115}
116
117/* Computes the number of values in the anti diagonal of the given index in the matrix with the
118 * given size, where the anti diagonals are indexed from the lower left corner to the upper right
119 * corner such that their start is at the bottom and right edges of the matrix as shown in the
120 * diagram below. The numbers in the diagram denote the index of the anti diagonal and its length.
121 *
122 * Width = 6
123 * +---+---+---+---+---+---+
124 * | 2 | 3 | 4 | 5 | 6 | 7 | 1
125 * +---+---+---+---+---+---+
126 * Height = 3 | 1 | 2 | 3 | 4 | 5 | 6 | 2
127 * +---+---+---+---+---+---+
128 * | 0 | 1 | 2 | 3 | 4 | 5 |
129 * +---+---+---+---+---+---+
130 * 1 2 3 3 3 3
131 *
132 * The length of the anti diagonal is identical to the length of the diagonal of the same index, as
133 * can be seen by comparing the above diagram with the one in the compute_diagonal_length function,
134 * since the anti diagonals are merely flipped diagonals. */
135inline int compute_anti_diagonal_length(const int2 &size, const int diagonal_index)
136{
137 return compute_diagonal_length(size, diagonal_index);
138}
139
140/* Computes the position of the start of the anti diagonal of the given index in the matrix with
141 * the given size, where the anti diagonals are indexed from the lower left corner to the upper
142 * right corner such that their start is at the bottom and right edges of the matrix as shown in
143 * the diagram below. The numbers in the diagram denote the index of the anti diagonal and the
144 * position of its start.
145 *
146 * Width = 6
147 * +-----+-----+-----+-----+-----+-----+
148 * | 2 | 3 | 4 | 5 | 6 | 7 | (5,2)
149 * +-----+-----+-----+-----+-----+-----+
150 * Height = 3 | 1 | 2 | 3 | 4 | 5 | 6 | (5,1)
151 * +-----+-----+-----+-----+-----+-----+
152 * | 0 | 1 | 2 | 3 | 4 | 5 |
153 * +-----+-----+-----+-----+-----+-----+
154 * (0,0) (1,0) (2,0) (3,0) (4,0) (5,0)
155 *
156 * To derive the start position from the index, we consider each axis separately. For the X
157 * position, indices up to (width - 1) linearly increase from zero, while other indices are all
158 * (width - 1). Which can be described using the compact equation:
159 *
160 * X => min((width - 1), index)
161 *
162 * For the Y position, indices up to (width - 1) are zero, while other indices linearly increase
163 * from zero to (height - 1). Which can be described using the compact equation:
164 *
165 * Y => max(0, index - (width - 1))
166 */
167inline int2 compute_anti_diagonal_start(const int2 &size, const int index)
168{
169 return int2(math::min(size.x - 1, index), math::max(0, index - (size.x - 1)));
170}
171
172/* Computes a direction vector such that when added to the position of a value in a matrix will
173 * yield the position of the next value in the same anti diagonal. According to the choice of the
174 * start of the anti diagonal in compute_anti_diagonal_start, this is (-1, 1). */
176{
177 return int2(-1, 1);
178}
179
180} // namespace blender::compositor
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
int compute_diagonal_length(const int2 &size, const int diagonal_index)
int2 compute_anti_diagonal_start(const int2 &size, const int index)
int compute_anti_diagonal_length(const int2 &size, const int diagonal_index)
int compute_number_of_diagonals(const int2 &size)
int2 compute_diagonal_start(const int2 &size, const int index)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
VecBase< int32_t, 2 > int2