使用C++标准库-复数实现二维笛卡尔坐标系的坐标变换

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-28 00:12   1032   0

二维笛卡尔坐标系旋转问题可以描述如下:有两套笛卡尔坐标系,分别是XOYX'O'Y'X'O'Y'相对于XOY坐标系进行了平移(x_shift, y_shift)和旋转angle(弧度)变换,一个点在XOY坐标系中的坐标为:(x, y),计算该点在X'O'Y'坐标系中的坐标:(x_prime, y_prime),并计算转化时间。

对于笛卡尔坐标系的转换,通过C++标准库<cmath>中的三角函数可以实现平移和旋转,现提供一种方法-使用C++中复数模板模板complex<>实现。核心思想是将笛卡尔坐标系转换为极坐标系,然后调用模板算法很容易就能实现,废话少说,核心代码:

typedefstruct_DC_COORD {

double x;

double y;

}ST_DC_COORD, *PST_DC_COORD;

typedefstruct_RT_DC_COORD {

double x_shift;

double y_shift;

double angle;

}ST_RT_DC_COORD,*PST_RT_DC_COORD;

CoordTf(ST_RT_DC_COORD coordRt, ST_DC_COORD &coord,double &timeSpend){

complex<double> cCoord(coord.x, -coord.y);//将坐标转换为极坐标

complex<double> cShift(coordRt.x_shift, -coordRt.y_shift);//平移极坐标

auto f_shift = [](complex<double> source, complex<double> shift) {return (source-shift); };//定义平移lambda表达式

auto start =chrono::system_clock::now();

cCoord = f_shift(cCoord, cShift);

complex<double> cRotateRes = polar(abs(cCoord),arg(cCoord) + coordRt.angle);

//重新生成新的极坐标,模不变为abs(cCoord),角度变化量仍为旋转角度

coord.x = cRotateRes.real();

coord.y =-cRotateRes.imag();

//分别提取实部和虚部得到新的笛卡尔坐标

auto end = chrono::system_clock::now();

auto duration =chrono::duration_cast<chrono::microseconds>(end- start);

double temp = double(duration.count()) * chrono::nanoseconds::period::num / chrono::seconds::period::den;//使用chrono计算转换时间

timeSpend = temp;//ns

returntrue;

}

随机生成10个坐标进行验证,初始坐标x,y值范围均为[-100,100], VS环境下完整代码如下:

Coord.h文件:

#ifndef COORD_H_

#defineCOORD_H_

#include<vector>

typedefstruct_DC_COORD {

double x;

double y;

}ST_DC_COORD, *PST_DC_COORD;

typedefstruct_RT_DC_COORD {

double x_shift;

double y_shift;

double angle;

}ST_RT_DC_COORD,*PST_RT_DC_COORD;

classCoord

{

public:

Coord();

~Coord();

public:

bool CoordTf(ST_RT_DC_COORD coordRt, ST_DC_COORD &coord,double &timeSpend);

bool CoordGeneration(double rangeMin, double rangeMax, int num);

int GetCoordPointsNum();

bool GetCoordPoint(int id, ST_DC_COORD &coord);

protected:

void GetRandData(double rangeMin, double rangeMax, int num, double* pData);

private:

std::vector<ST_DC_COORD> coordVector;

};

#endif

Coord.cpp文件:

#include"Coord.h"

#include<iostream>

#include<vector>

#include<algorithm>

#include<functional>

#include<complex>

#include<random>

#include<chrono>

#include<ctime>

#include<cmath>

usingnamespace std;

Coord::Coord()

{

this->coordVector.clear();

}

Coord::~Coord()

{

this->coordVector.clear();

}

boolCoord::CoordTf(ST_RT_DC_COORD coordRt, ST_DC_COORD &coord,double &timeSpend){

complex<double> cCoord(coord.x, -coord.y);

complex<double> cShift(coordRt.x_shift, -coordRt.y_shift);

auto f_shift = [](complex<double> source, complex<double> shift) {return (source-shift); };

auto start =chrono::system_clock::now();

cCoord = f_shift(cCoord, cShift);

complex<double> cRotateRes = polar(abs(cCoord),arg(cCoord) + coordRt.angle);

coord.x =cRotateRes.real();

coord.y =-cRotateRes.imag();

auto end = chrono::system_clock::now();

auto duration =chrono::duration_cast<chrono::microseconds>(end- start);

double temp = double(duration.count()) * chrono::nanoseconds::period::num / chrono::seconds::period::den;

timeSpend = temp;//ns

returntrue;

}

boolCoord::CoordGeneration(doublerangeMin, doublerangeMax, intnum){

bool bRet = false;

int i = 0;

ST_DC_COORD coord;

double* pData = NULL;

pData = newdouble[2 * num];

this->GetRandData(rangeMin, rangeMax, 2 * num, pData);

for (i = 0; i < num; i++) {

coord.x = pData[i];

coord.y = pData[num+i];

this->coordVector.push_back(coord);

}

delete[] pData;

if (!this->coordVector.empty()){

bRet = true;

}

return bRet;

}

intCoord::GetCoordPointsNum(){

returnthis->coordVector.size();

}

boolCoord::GetCoordPoint(intid, ST_DC_COORD &coord) {

if (id >= this->GetCoordPointsNum()) {

returnfalse;

}

coord=this->coordVector[id];

returntrue;

}

voidCoord::GetRandData(doublerangeMin, doublerangeMax,intnum,double* pData) {

int i = 0;

default_random_engine generator(time(NULL));

uniform_real_distribution<double> dist(rangeMin, rangeMax);

for (i = 0; i < num; i++){

auto temp = dist(generator);

pData[i] = static_cast<double>(temp);

}

}

App.cpp文件:

#include"Coord.h"

#include<iostream>

void TaskTest();

int main()

{

while (1) {

TaskTest();

}

return 0;

}

void TaskTest()

{

int i = 0;

bool bRet = false;

Coord* pCoord = new Coord;

ST_DC_COORD coord,tempCoord;

double timeSpend = 0;

ST_RT_DC_COORD coordRf;

std::cout <<"please input x_shift:"<< std::endl;

std::cin >> coordRf.x_shift;

std::cout <<"please input y_shift:"<< std::endl;

std::cin >> coordRf.y_shift;

std::cout <<"please input angle:"<< std::endl;

std::cin >> coordRf.angle;

if(pCoord->CoordGeneration(-100, 100, 10)) {

int tempNum = pCoord->GetCoordPointsNum();

for (i = 0; i < tempNum; i++) {

if (pCoord->GetCoordPoint(i, coord)) {

tempCoord = coord;

bRet =pCoord->CoordTf(coordRf, coord, timeSpend);

if (bRet) {

std::cout <<"the "<< i+1 <<"th "<<"result:"<< std::endl;

std::cout <<"initial coord(x,y):"<<"("<< tempCoord.x <<","<< tempCoord.y <<")"<<std::endl;

std::cout <<"final coord(x,y) :"<<"("<< coord.x <<","<< coord.y <<")"<< std::endl;

std::cout <<"it spends time:"<< timeSpend <<"ns"<< std::endl;

}

}

}

}

delete pCoord;

}

设置平移坐标(1,1),旋转角度为45度,进行Debug,运行结果如下

please input x_shift:

1

please input y_shift:

1

please input angle:

0.78539816

the1th result:

initial coord(x,y):(-38.3971,-35.8599)

final coord(x,y) :(-53.9218,1.79406)

it spends time:14ns

the 2th result:

initial coord(x,y):(-39.8357,84.4626)

final coord(x,y) :(30.1418,87.8922)

it spends time:2ns

the 3th result:

initial coord(x,y):(17.5412,-66.5742)

final coord(x,y) :(-36.0858,-59.4786)

it spends time:1ns

the 4th result:

initial coord(x,y):(58.8106,-65.6458)

final coord(x,y) :(-6.24741,-88.004)

it spends time:1ns

the 5th result:

initial coord(x,y):(-14.0353,37.6078)

final coord(x,y) :(15.2541,36.5172)

it spends time:1ns

the 6th result:

initial coord(x,y):(-73.222,50.5119)

final coord(x,y) :(-17.4726,87.4931)

it spends time:1ns

the 7th result:

initial coord(x,y):(30.4505,81.4555)

final coord(x,y) :(77.7153,36.0659)

it spends time:3ns

the 8th result:

initial coord(x,y):(-58.4805,65.981)

final coord(x,y) :(3.88944,88.0076)

it spends time:2ns

the 9th result:

initial coord(x,y):(53.6765,-52.5575)

final coord(x,y) :(-0.622969,-75.1188)

it spends time:2ns

the10th result:

initial coord(x,y):(5.31381,8.17389)

final coord(x,y) :(8.12303,2.02238)

it spends time:2ns

please input x_shift:

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP