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

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

对于笛卡尔坐标系的转换,通过C++标准库中的三角函数可以实现平移和旋转,现提供一种方法-使用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_castmicroseconds>(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

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

#include

#include

#include

#include

#include

#include

#include 

#include

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_castmicroseconds>(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

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:

你可能感兴趣的:(使用C++标准库-复数实现二维笛卡尔坐标系的坐标变换)