212 lines
5.1 KiB
C++
212 lines
5.1 KiB
C++
// SharedGeometry.cpp
|
||
#include "SharedGeometry/SharedGeometry.h"
|
||
#include <stdexcept>
|
||
#include <cmath>
|
||
#include <algorithm>
|
||
|
||
// 如果没有定义M_PI,则定义它
|
||
#ifndef M_PI
|
||
#define M_PI 3.14159265358979323846
|
||
#endif
|
||
|
||
// ==================== Vector2D 实现 ====================
|
||
|
||
Vector2D::Vector2D() : X(0.0), Y(0.0) {}
|
||
|
||
Vector2D::Vector2D(double x, double y) : X(x), Y(y) {}
|
||
|
||
Vector2D Vector2D::operator+(const Vector2D &other) const
|
||
{
|
||
return Vector2D(X + other.X, Y + other.Y);
|
||
}
|
||
|
||
Vector2D Vector2D::operator-(const Vector2D &other) const
|
||
{
|
||
return Vector2D(X - other.X, Y - other.Y);
|
||
}
|
||
|
||
Vector2D Vector2D::operator*(double scalar) const
|
||
{
|
||
return Vector2D(X * scalar, Y * scalar);
|
||
}
|
||
|
||
double Vector2D::distanceTo(const Vector2D &other) const
|
||
{
|
||
double dx = X - other.X;
|
||
double dy = Y - other.Y;
|
||
return std::sqrt(dx * dx + dy * dy);
|
||
}
|
||
|
||
double Vector2D::length() const
|
||
{
|
||
return std::sqrt(X * X + Y * Y);
|
||
}
|
||
|
||
Vector2D Vector2D::normalized() const
|
||
{
|
||
double len = length();
|
||
if (len > 0.0)
|
||
{
|
||
return Vector2D(X / len, Y / len);
|
||
}
|
||
return Vector2D(0.0, 0.0);
|
||
}
|
||
|
||
Vector2D Vector2D::Zero()
|
||
{
|
||
return Vector2D(0.0, 0.0);
|
||
}
|
||
|
||
double Vector2D::Distance(const Vector2D &v1, const Vector2D &v2)
|
||
{
|
||
return std::sqrt(std::pow(v2.X - v1.X, 2) + std::pow(v2.Y - v1.Y, 2));
|
||
}
|
||
|
||
double Vector2D::Cross(const Vector2D &other) const
|
||
{
|
||
return X * other.Y - Y * other.X;
|
||
}
|
||
|
||
double Vector2D::Dot(const Vector2D &other) const
|
||
{
|
||
return X * other.X + Y * other.Y;
|
||
}
|
||
|
||
// ==================== Pose7 实现 ====================
|
||
|
||
Pose7::Pose7() : tx(0.0), ty(0.0), tz(0.0), qx(0.0), qy(0.0), qz(0.0), qw(1.0) {}
|
||
|
||
// ==================== PoseCalculator 实现 ====================
|
||
|
||
Pose7 PoseCalculator::CalculatePoseAndQuaternion(const Vector2D &start, const Vector2D &end)
|
||
{
|
||
Pose7 pose;
|
||
pose.tx = start.X;
|
||
pose.ty = start.Y;
|
||
pose.tz = 0.0;
|
||
|
||
Vector2D direction = end - start;
|
||
double length = direction.length();
|
||
|
||
if (length > 0.0)
|
||
{
|
||
direction = direction * (1.0 / length);
|
||
double angle = std::atan2(direction.Y, direction.X);
|
||
|
||
// 转换为四元数(绕Z轴旋转)
|
||
double halfAngle = angle * 0.5;
|
||
pose.qw = std::cos(halfAngle);
|
||
pose.qz = std::sin(halfAngle);
|
||
pose.qx = 0.0;
|
||
pose.qy = 0.0;
|
||
}
|
||
else
|
||
{
|
||
pose.qw = 1.0;
|
||
pose.qx = 0.0;
|
||
pose.qy = 0.0;
|
||
pose.qz = 0.0;
|
||
}
|
||
|
||
return pose;
|
||
}
|
||
|
||
std::vector<double> PoseCalculator::CalculatePoseAndQuaternionArray(double x1, double y1, double x2, double y2)
|
||
{
|
||
double x_D = x1;
|
||
double y_D = y1;
|
||
double x_G = x2;
|
||
double y_G = y2;
|
||
|
||
// 方向向量
|
||
double dx = x_G - x_D;
|
||
double dy = y_G - y_D;
|
||
|
||
double v_norm = std::sqrt(dx * dx + dy * dy);
|
||
|
||
// 使用小的epsilon值而不是直接比较0
|
||
if (std::abs(v_norm) < 1e-10)
|
||
{
|
||
throw std::invalid_argument("两个点位置相同,无法计算姿态。");
|
||
}
|
||
|
||
// 单位化方向向量
|
||
double vx = dx / v_norm;
|
||
double vy = dy / v_norm;
|
||
|
||
// 四元数(绕Z轴旋转)
|
||
double theta = std::atan2(vy, vx);
|
||
double halfTheta = theta / 2.0;
|
||
double qw = std::cos(halfTheta);
|
||
double qx = 0.0;
|
||
double qy = 0.0;
|
||
double qz = std::sin(halfTheta);
|
||
|
||
// 返回长度为7的数组
|
||
return {x_D, y_D, 0.0, qw, qx, qy, qz};
|
||
}
|
||
|
||
double PoseCalculator::MMToM(double MM)
|
||
{
|
||
return Round(MM / 1000.0, 6);
|
||
}
|
||
|
||
double PoseCalculator::Round(double value, int decimals)
|
||
{
|
||
double factor = std::pow(10.0, decimals);
|
||
return std::round(value * factor) / factor;
|
||
}
|
||
|
||
std::string PoseCalculator::ToString(double value, int decimals)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << std::fixed << std::setprecision(decimals) << value;
|
||
return oss.str();
|
||
}
|
||
|
||
C_ObjStates PoseCalculator::CalculatePoseAndQuaternion_C_ObjStates(const std::string &i,
|
||
double x1, double y1,
|
||
double x2, double y2)
|
||
{
|
||
// 如果需要实现这个方法,需要C_ObjStates的定义
|
||
// 这里先抛出一个异常,提醒需要实现
|
||
// throw std::runtime_error("C_ObjStates需要额外的定义,请提供C_ObjStates类的定义");
|
||
|
||
// 示例代码(需要C_ObjStates类):
|
||
|
||
double x_D = MMToM(x1);
|
||
double y_D = MMToM(y1);
|
||
double x_G = MMToM(x2);
|
||
double y_G = MMToM(y2);
|
||
|
||
double dx = x_G - x_D;
|
||
double dy = y_G - y_D;
|
||
double v_norm = std::sqrt(dx * dx + dy * dy);
|
||
|
||
if (std::abs(v_norm) < 1e-10)
|
||
{
|
||
throw std::invalid_argument("两个点位置相同,无法计算姿态。");
|
||
}
|
||
|
||
double vx = dx / v_norm;
|
||
double vy = dy / v_norm;
|
||
double theta = std::atan2(vy, vx);
|
||
double halfTheta = theta / 2.0;
|
||
double qw = std::cos(halfTheta);
|
||
double qx = 0.0;
|
||
double qy = 0.0;
|
||
double qz = std::sin(halfTheta);
|
||
|
||
C_ObjStates c_ObjStates;
|
||
c_ObjStates.i = i;
|
||
c_ObjStates.tx = ToString(x_D);
|
||
c_ObjStates.ty = ToString(y_D);
|
||
c_ObjStates.tz = "0";
|
||
c_ObjStates.qx = ToString(qx);
|
||
c_ObjStates.qy = ToString(qy);
|
||
c_ObjStates.qz = ToString(qz);
|
||
c_ObjStates.qw = ToString(qw);
|
||
|
||
return c_ObjStates;
|
||
}
|