transforms.cpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #include "transforms.h"
  2. #include <algorithm>
  3. #include <cmath>
  4. namespace Render::Geom {
  5. QMatrix4x4 cylinderBetween(const QVector3D &a, const QVector3D &b,
  6. float radius) {
  7. QVector3D mid = (a + b) * 0.5f;
  8. QVector3D dir = b - a;
  9. float len = dir.length();
  10. QMatrix4x4 M;
  11. M.translate(mid);
  12. if (len > 1e-6f) {
  13. QVector3D yAxis(0, 1, 0);
  14. QVector3D d = dir / len;
  15. float dot = std::clamp(QVector3D::dotProduct(yAxis, d), -1.0f, 1.0f);
  16. float angleDeg = std::acos(dot) * 57.2957795131f;
  17. QVector3D axis = QVector3D::crossProduct(yAxis, d);
  18. if (axis.lengthSquared() < 1e-6f) {
  19. if (dot < 0.0f) {
  20. M.rotate(180.0f, 1.0f, 0.0f, 0.0f);
  21. }
  22. } else {
  23. axis.normalize();
  24. M.rotate(angleDeg, axis);
  25. }
  26. M.scale(radius, len, radius);
  27. } else {
  28. M.scale(radius, 1.0f, radius);
  29. }
  30. return M;
  31. }
  32. QMatrix4x4 sphereAt(const QVector3D &pos, float radius) {
  33. QMatrix4x4 M;
  34. M.translate(pos);
  35. M.scale(radius, radius, radius);
  36. return M;
  37. }
  38. QMatrix4x4 coneFromTo(const QVector3D &baseCenter, const QVector3D &apex,
  39. float baseRadius) {
  40. return cylinderBetween(baseCenter, apex, baseRadius);
  41. }
  42. } // namespace Render::Geom