232 { |
232 { |
233 QFont font; |
233 QFont font; |
234 //font.setStyle(QFont::StyleItalic); |
234 //font.setStyle(QFont::StyleItalic); |
235 painter.setFont(font); |
235 painter.setFont(font); |
236 QFontMetrics fontMetrics{font}; |
236 QFontMetrics fontMetrics{font}; |
237 const auto renderText = [&](const QString& text, const geom::PointOnRectagle& intersection) |
237 const auto renderText = [&](const QString& text, const PointOnRectagle& intersection) |
238 { |
238 { |
239 QPointF position = toQPointF(intersection.position); |
239 QPointF position = toQPointF(intersection.position); |
240 const geom::RectangleSide side = intersection.side; |
240 const RectangleSide side = intersection.side; |
241 switch (side) |
241 switch (side) |
242 { |
242 { |
243 case geom::RectangleSide::Top: |
243 case RectangleSide::Top: |
244 position += QPointF{0, static_cast<qreal>(fontMetrics.ascent())}; |
244 position += QPointF{0, static_cast<qreal>(fontMetrics.ascent())}; |
245 break; |
245 break; |
246 case geom::RectangleSide::Left: |
246 case RectangleSide::Left: |
247 break; |
247 break; |
248 case geom::RectangleSide::Bottom: |
248 case RectangleSide::Bottom: |
249 position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; |
249 position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; |
250 break; |
250 break; |
251 case geom::RectangleSide::Right: |
251 case RectangleSide::Right: |
252 position += QPointF{static_cast<qreal>(-fontMetrics.horizontalAdvance(text)), 0}; |
252 position += QPointF{static_cast<qreal>(-fontMetrics.horizontalAdvance(text)), 0}; |
253 break; |
253 break; |
254 } |
254 } |
255 painter.drawText(position, text); |
255 painter.drawText(position, text); |
256 }; |
256 }; |
270 {"-𝑧", {0, 0, -1}}, |
270 {"-𝑧", {0, 0, -1}}, |
271 }; |
271 }; |
272 for (const auto& axis : directions) |
272 for (const auto& axis : directions) |
273 { |
273 { |
274 const QPointF x_p = this->modelToScreenCoordinates(axis.direction); |
274 const QPointF x_p = this->modelToScreenCoordinates(axis.direction); |
275 const auto intersection = geom::rayRectangleIntersection( |
275 const auto intersection = rayRectangleIntersection( |
276 geom::rayFromPoints(toVec2(p1), toVec2(x_p)), |
276 rayFromPoints(toVec2(p1), toVec2(x_p)), |
277 box); |
277 box); |
278 if (intersection.has_value()) |
278 if (intersection.has_value()) |
279 { |
279 { |
280 renderText(axis.text, *intersection); |
280 renderText(axis.text, *intersection); |
281 } |
281 } |
302 painter->drawPolygon(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); |
302 painter->drawPolygon(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); |
303 } |
303 } |
304 |
304 |
305 Winding Canvas::worldPolygonWinding(const std::vector<glm::vec3> &points) const |
305 Winding Canvas::worldPolygonWinding(const std::vector<glm::vec3> &points) const |
306 { |
306 { |
307 return geom::winding(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); |
307 return winding(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); |
308 } |
308 } |
309 |
309 |
310 /** |
310 /** |
311 * @brief Gets the current position of the cursor in the model |
311 * @brief Gets the current position of the cursor in the model |
312 * @return 3D vector |
312 * @return 3D vector |
354 * @param worldPoint Point to render |
354 * @param worldPoint Point to render |
355 */ |
355 */ |
356 void Canvas::drawWorldPoint(QPainter* painter, const glm::vec3& worldPoint) const |
356 void Canvas::drawWorldPoint(QPainter* painter, const glm::vec3& worldPoint) const |
357 { |
357 { |
358 const QPointF center = this->modelToScreenCoordinates(worldPoint); |
358 const QPointF center = this->modelToScreenCoordinates(worldPoint); |
359 painter->drawEllipse(geom::inscribe(geom::CircleF{center, 5})); |
359 painter->drawEllipse(inscribe(CircleF{center, 5})); |
360 } |
360 } |
361 |
361 |
362 /** |
362 /** |
363 * @brief Changes the grid matrix to the one specified. Updates relevant member variables. |
363 * @brief Changes the grid matrix to the one specified. Updates relevant member variables. |
364 * @param newMatrix New matrix to use |
364 * @param newMatrix New matrix to use |
365 */ |
365 */ |
366 void Canvas::setGridMatrix(const glm::mat4& newMatrix) |
366 void Canvas::setGridMatrix(const glm::mat4& newMatrix) |
367 { |
367 { |
368 this->gridMatrix = newMatrix; |
368 this->gridMatrix = newMatrix; |
369 const geom::Triangle triangle { |
369 const Triangle triangle { |
370 this->gridMatrix * glm::vec4{0, 0, 0, 1}, |
370 this->gridMatrix * glm::vec4{0, 0, 0, 1}, |
371 this->gridMatrix * glm::vec4{1, 0, 0, 1}, |
371 this->gridMatrix * glm::vec4{1, 0, 0, 1}, |
372 this->gridMatrix * glm::vec4{0, 1, 0, 1}, |
372 this->gridMatrix * glm::vec4{0, 1, 0, 1}, |
373 }; |
373 }; |
374 this->gridPlane = geom::planeFromTriangle(triangle); |
374 this->gridPlane = planeFromTriangle(triangle); |
375 this->gridProgram->setGridMatrix(this->gridMatrix); |
375 this->gridProgram->setGridMatrix(this->gridMatrix); |
376 this->update(); |
376 this->update(); |
377 } |
377 } |
378 |
378 |
379 /** |
379 /** |