src/canvas.cpp

changeset 1181
ca6d0ef9aadb
parent 1178
3a88e7a60b63
child 1182
813d020f92d4
equal deleted inserted replaced
1180:2005e4147ad6 1181:ca6d0ef9aadb
93 /* 93 /*
94 * Assuming we're currently viewing from a fixed camera, draw a backdrop into it. Currently this means drawing the grid. 94 * Assuming we're currently viewing from a fixed camera, draw a backdrop into it. Currently this means drawing the grid.
95 */ 95 */
96 void Canvas::drawFixedCameraBackdrop() 96 void Canvas::drawFixedCameraBackdrop()
97 { 97 {
98 static const enum { Cartesian, Polar } gridType = Cartesian;
99
98 // Find the top left corner of the grid 100 // Find the top left corner of the grid
99 Vertex topLeft = currentCamera().idealize(currentCamera().convert2dTo3d({0, 0})); 101 Vertex topLeft = currentCamera().idealize(currentCamera().convert2dTo3d({0, 0}));
100 Vertex bottomRight = currentCamera().idealize(currentCamera().convert2dTo3d({width(), height()})); 102 Vertex bottomRight = currentCamera().idealize(currentCamera().convert2dTo3d({width(), height()}));
101 qreal gridSize = grid()->coordinateSnap(); 103 qreal gridSize = grid()->coordinateSnap();
102 qreal x0 = sign(topLeft.x()) * (fabs(topLeft.x()) - fmod(fabs(topLeft.x()), gridSize));
103 qreal y0 = sign(topLeft.y()) * (fabs(topLeft.y()) - fmod(fabs(topLeft.y()), gridSize));
104 glEnable(GL_LINE_STIPPLE); 104 glEnable(GL_LINE_STIPPLE);
105 glBegin(GL_LINES); 105 glBegin(GL_LINES);
106 106
107 static const auto prepareGridLine = [](qreal value) -> bool 107 if (gridType == Cartesian)
108 { 108 {
109 if (not isZero(value)) 109 qreal x0 = sign(topLeft.x()) * (fabs(topLeft.x()) - fmod(fabs(topLeft.x()), gridSize));
110 { 110 qreal y0 = sign(topLeft.y()) * (fabs(topLeft.y()) - fmod(fabs(topLeft.y()), gridSize));
111 if (isZero(fmod(value, 10.0))) 111
112 glColor4f(0, 0, 0, 0.6); 112 static const auto prepareGridLine = [](qreal value) -> bool
113 {
114 if (not isZero(value))
115 {
116 if (isZero(fmod(value, 10.0)))
117 glColor4f(0, 0, 0, 0.6);
118 else
119 glColor4f(0, 0, 0, 0.25);
120
121 return true;
122 }
113 else 123 else
114 glColor4f(0, 0, 0, 0.25); 124 {
115 125 return false;
116 return true; 126 }
117 } 127 };
118 else 128
119 { 129 for (qreal x = x0; x < bottomRight.x(); x += gridSize)
120 return false; 130 {
121 } 131 if (prepareGridLine(x))
122 }; 132 {
123 133 glVertex(currentCamera().realize({x, -10000, 999}));
124 for (qreal x = x0; x < bottomRight.x(); x += gridSize) 134 glVertex(currentCamera().realize({x, 10000, 999}));
125 { 135 }
126 if (prepareGridLine(x)) 136 }
127 { 137
128 glVertex(currentCamera().realize({x, -10000, 999})); 138 for (qreal y = y0; y < bottomRight.y(); y += gridSize)
129 glVertex(currentCamera().realize({x, 10000, 999})); 139 {
130 } 140 if (prepareGridLine(y))
131 } 141 {
132 142 glVertex(currentCamera().realize({-10000, y, 999}));
133 for (qreal y = y0; y < bottomRight.y(); y += gridSize) 143 glVertex(currentCamera().realize({10000, y, 999}));
134 { 144 }
135 if (prepareGridLine(y)) 145 }
136 { 146 }
137 glVertex(currentCamera().realize({-10000, y, 999})); 147 else
138 glVertex(currentCamera().realize({10000, y, 999})); 148 {
149 const QPointF pole = grid()->pole();
150 const qreal size = grid()->coordinateSnap();
151 Vertex topLeft = currentCamera().idealize(currentCamera().convert2dTo3d({0, 0}));
152 Vertex bottomRight = currentCamera().idealize(currentCamera().convert2dTo3d({width(), height()}));
153 QPointF topLeft2d {topLeft.x(), topLeft.y()};
154 QPointF bottomLeft2d {topLeft.x(), bottomRight.y()};
155 QPointF bottomRight2d {bottomRight.x(), bottomRight.y()};
156 QPointF topRight2d {bottomRight.x(), topLeft.y()};
157 qreal smallestRadius = distanceFromPointToRectangle(pole, QRectF{topLeft2d, bottomRight2d});
158 qreal largestRadius = max(QLineF {topLeft2d, pole}.length(),
159 QLineF {bottomLeft2d, pole}.length(),
160 QLineF {bottomRight2d, pole}.length(),
161 QLineF {topRight2d, pole}.length());
162
163 // Snap the radii to the grid.
164 smallestRadius = round(smallestRadius / size) * size;
165 largestRadius = round(largestRadius / size) * size;
166
167 // Is the pole at (0, 0)? If so, then don't render the polar axes above the real ones.
168 bool poleIsOrigin = isZero(pole.x()) and isZero(pole.y());
169 glColor4f(0, 0, 0, 0.25);
170
171 // Render the axes
172 for (int i = 0; i < grid()->polarDivisions() / 2; ++i)
173 {
174 qreal azimuth = (2.0 * pi) * i / grid()->polarDivisions();
175
176 if (not poleIsOrigin or not isZero(fmod(azimuth, pi / 4)))
177 {
178 QPointF extremum = {cos(azimuth) * 10000, sin(azimuth) * 10000};
179 QPointF A = pole + extremum;
180 QPointF B = pole - extremum;
181 glVertex(currentCamera().realize({A.x(), A.y(), 999}));
182 glVertex(currentCamera().realize({B.x(), B.y(), 999}));
183 }
184 }
185
186 for (qreal radius = smallestRadius; radius <= largestRadius; radius += size)
187 {
188 if (not isZero(radius))
189 {
190 Vertex points[48];
191
192 for (int i = 0; i < grid()->polarDivisions(); ++i)
193 {
194 qreal azimuth = (2.0 * pi) * i / grid()->polarDivisions();
195 QPointF point = pole + QPointF {radius * cos(azimuth), radius * sin(azimuth)};
196 points[i] = currentCamera().realize({point.x(), point.y(), 999});
197 }
198
199 for (int i = 0; i < grid()->polarDivisions(); ++i)
200 {
201 glVertex(points[i]);
202 glVertex(ring(points, grid()->polarDivisions())[i + 1]);
203 }
204 }
139 } 205 }
140 } 206 }
141 207
142 glEnd(); 208 glEnd();
143 glDisable(GL_LINE_STIPPLE); 209 glDisable(GL_LINE_STIPPLE);

mercurial