Eigen库实现简单的旋转、平移操作

本来课程要求用GUI界面来实现Eigen的旋转、平移操作的,但是接触GUI编程时间太短,虽然要求很简单,但是做了几天还是没有完成。就把命令行下面的简单的贴一下吧。
main.cpp

#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include "func.h"
#include "Point.h"
#include "Shape.h"

enum Motion {
    Rotate = 1,
    Move,
    Zoom,
};

std::map<std::string, Motion> motion = {
        {"rotate", Motion::Rotate},
        {"move",   Motion::Move},
        {"zoom",   Motion::Zoom},
};

Motion resolveCommand(std::string command) {
    return motion[command];
}

int main() {
    std::string name, pointNum;
    printf("请输入图形的名字:");
    getline(std::cin, name);
    if (name.empty()) {
        name = "T";
        printf("你的输入为空,因此为你的图形命名(T)
");
    }
    printf("请输入图形的端点数量:");
    getline(std::cin, pointNum);
    if (is_number(pointNum)) {
        std::cout << "你输入的是整数
";
    } else {
        std::cout << "你输入的不是整数
";
    }
    int num = atoi(pointNum.c_str());
    Point *shapePoints = new Point[num];

    for (int i = 0; i < num; ++i) {
        double x, y;
        printf("请输入第%d个点横坐标x = ", i + 1);
        scanf("%lf", &x);
        printf("请输入第%d个点纵坐标y = ", i + 1);
        scanf("%lf", &y);
        shapePoints[i].update(x, y);
    }
    std::cout << "你输入图形的名字为:" << name << " " << "你输入的端点数量为:" << pointNum << std::endl;
    Shape *shape = new Shape(shapePoints, num, name.c_str());
    shape->printShape();
    std::string command;
    bool flag = true;
    while (flag) {
        printf("
请输入对图形的操作指令:");
        std::cin.ignore();
        getline(std::cin, command);
        transform(command.begin(),command.end(),command.begin(), ::tolower);  //大小写转换
        switch (resolveCommand(command)) {
            case Motion::Rotate:
                double angle;
                printf("请输入旋转角度,逆时针为正:");
                scanf("%lf", &angle);
                shape->rotateShape(angle);
                break;
            case Motion::Move:
                double mx, my;
                printf("输入X方向移动距离:");
                scanf("%lf", &mx);
                printf("输入Y方向移动距离:");
                scanf("%lf", &my);
                shape->moveShape(mx, my);
                break;
            case Motion::Zoom:
                double zx, zy;
                printf("输入X方向缩放大小:");
                scanf("%lf", &zx);
                printf("输入Y方向缩放大小:");
                scanf("%lf", &zy);
                shape->zoomShape(zx, zy);
                break;
            default:
                flag = false;
        }
        shape->printShape();
    }
    printf("Error!!!你输入的命令有误,已经退出指令模式退出
");

    delete shape;
    delete[] shapePoints;
    shapePoints = NULL;

定义了一个Point点类
point.h

#include "Eigen/Dense"

using namespace Eigen;

class Point {
private:
    double x, y;

public:
    Point();

    Point(double x, double y);

    void update(double x, double y);

    void print();

    void move(double x, double y);

    void rotate(double angle);

    void zoom(double zx, double zy);

    Vector2d pointByMatrix();

    void setByMatrix(Vector2d m);

    ~Point();
};

point.cpp

#include "Point.h"
#include <iostream>

Point::Point() {
    this->x = 0;
    this->y = 0;
}

Point::Point(double x, double y) {
    this->x = x;
    this->y = y;
}

void Point::update(double x, double y) {
    this->x = x;
    this->y = y;
}

void Point::print() {
    std::cout << "(" << this->x << ", " << this->y << ")";
}

Point::~Point() {
    std::cout << "调用Point析构函数" << std::endl;
}

/**
 * 平移
 */
void Point::move(double x, double y) {
    Vector2d a = pointByMatrix();
    Vector2d b(x, y);
    a = a + b;
    setByMatrix(a);
}

/**
 * 旋转变换,angle为角度, 逆时针为正, 顺时针为负
 */
void Point::rotate(double angle) {
    MatrixXd T(2, 2);
    angle = angle / 180 * M_PI;
    T(0, 0) = cos(angle);
    T(0, 1) = sin(angle);
    T(1, 0) = -sin(angle);
    T(1, 1) = cos(angle);
    std::cout << "旋转矩阵T = " << std::endl << T << std::endl;
    Vector2d m = this->pointByMatrix();
    m = T * m;  //貌似只能T * m
    this->setByMatrix(m);
}

/**
 * 缩放(比例变换), zx分别表示x轴缩放比例,zy表示y轴缩放比例
 */
void Point::zoom(double zx, double zy) {
    Matrix2d T;
    T << zx, 0, 0, zy;
    Vector2d result = T * this->pointByMatrix();
    this->setByMatrix(result);
}

Vector2d Point::pointByMatrix() {
    Vector2d a(this->x, this->y);
    return a;
}

void Point::setByMatrix(Vector2d m) {
    this->x = m(0);
    this->y = m(1);
}

定义了一个简单的Shape图形类。
shape.h

#include "Point.h"

class Shape {
private:
    const char *shapeName;
    int pointNum;
    Point *pointArr;
public:
    Shape(Point *arr, int num, const char *name);

    void printShape();

    void rotateShape(double angle);

    void moveShape(double x, double y);

    void zoomShape(double zx, double zy);

    ~Shape();
};

shape.cpp

#include "Shape.h"

Shape::Shape(Point *arr, int num, const char *name) {
    this->pointArr = arr;
    this->pointNum = num;
    this->shapeName = name;
}

void Shape::moveShape(double x, double y) {
    printf("你输入的指令为 move, 移动距离: (%lf, %lf)
", x, y);
    for (int i = 0; i < this->pointNum; ++i) {
        this->pointArr[i].move(x, y);
    }
}

void Shape::rotateShape(double angle) {
    printf("你输入的指令为 rotate, 旋转角度: %lf
", angle);
    for (int i = 0; i < this->pointNum; ++i) {
        this->pointArr[i].rotate(angle);
    }
}

void Shape::zoomShape(double zx, double zy) {
    printf("你输入的指令为 zoom, 缩放比例为: (%lf, %lf)
", zx, zy);
    for (int i = 0; i < this->pointNum; ++i) {
        this->pointArr[i].zoom(zx, zy);
    }
}

void Shape::printShape() {
    printf("图形%s的%d个点坐标分别为", this->shapeName, this->pointNum);
    for (int i = 0; i < this->pointNum - 1; ++i) {
        this->pointArr[i].print();
        printf(",");
    }
    this->pointArr[(this->pointNum - 1)].print();
    printf("
");
}

Shape::~Shape() {
    printf("调用Helper析构函数
");
}

运行结果为:

源码提交Github

原文地址:https://www.cnblogs.com/lvzwq/p/5006862.html