多点模拟圆心,并根据模拟圆心旋转角度后模拟的坐标

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <filesystem>
#include<io.h>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
using namespace std;
//#include "demoDLL.h"

struct Point {
    double x, y;
};

const double PI = 3.14159265358979323846;
const double DEG_TO_RAD = PI / 180.0;

int average(int x, int y)   //返回X,Y 的平均值
{
    return (x & y) + ((x ^ y) >> 1);
}

int getCerterOfCircle(double* x, double* y, int n, double* z, double &radius)
{
    double sumX = 0, sumY = 0;
    double sumXX = 0, sumYY = 0, sumXY = 0;
    double sumXXX = 0, sumXXY = 0, sumXYY = 0, sumYYY = 0;

    for (int i =0;i < n; i++)
    {

        sumX += x[i];
        sumY += y[i];
        sumXX += x[i] * x[i];
        sumYY += y[i] * y[i];
        sumXY += x[i] * y[i];
        sumXXX += x[i] * x[i] * x[i];
        sumXXY += x[i] * x[i] * y[i];
        sumXYY += x[i] * y[i] * y[i];
        sumYYY += y[i] * y[i] * y[i];
    }

    double M1 = n * sumXY - sumX * sumY;
    double M2 = n * sumXX - sumX * sumX;
    double M3 = n * (sumXXX + sumXYY) - sumX * (sumXX + sumYY);
    double M4 = n * sumYY - sumY * sumY;
    double M5 = n * (sumYYY + sumXXY) - sumY * (sumXX + sumYY);

    double a = (M1 * M5 - M3 * M4) / (M2 * M4 - M1 * M1);
    double b = (M1 * M3 - M2 * M5) / (M2 * M4 - M1 * M1);
    double c = -(a * sumX + b * sumY + sumXX + sumYY) / n;

    //圆心XY 半径
    double xCenter = -0.5 * a;
    double yCenter = -0.5 * b;
    radius = 0.5 * sqrt(a * a + b * b - 4 * c);
    z[0] = xCenter;
    z[1] = yCenter;
    return 0;
}

void getFileContent(string filePath, double x[], double y[])
{
    
    ifstream infile;
    infile.open(filePath);//打开文件
    if (!infile)
    {
        cout << "无法打开文件!" << endl;
        exit(1);
    }
    char line[15];//字符数组,用于读取,这里假设每次读取的整数不超过15个字符
    int i = 0;
    while (infile.getline(line, 15, '\n'))
    {
        string s;
        s.append(line);
        int index = s.find(',');
        if (index != -1)
        {
            x[i] = stoi(s.substr(0, index));
            if (x[i] > 10000)
            {
                x[i] = x[i] / 1000;
            }
            y[i] = stoi(s.substr(index + 1, s.length()));
            if (y[i] > 10000)
            {
                y[i] = y[i] / 1000;
            }
            i++;
        }
    }
    infile.close();//关闭文件
}

// 计算圆上某点的坐标
Point pointOnCircle(const Point& O, double r, double angle)
{
    return { O.x + r * cos(angle), O.y + r * sin(angle) };
}

// 计算夹角
double angleBetween(const Point& O, const Point& A) {

    if (A.x == O.x)
    {
        if (A.y <= O.y)
        {
            return -PI / 2.0;
        }
        else
        {
            return PI / 2.0;
        }
    }
    
    double cross = (A.y - O.y) / (A.x - O.x);
    
    if (A.x <= O.x)
    {
        return PI + atan(cross);
    }
    return atan(cross);
}

void writefile(const Point& A, const Point& O, double radius, string filepath)
{
    // 计算圆弧的夹角
    double angleAC = angleBetween(O, A);
    //以写模式打开文件
    ofstream outfile;
    outfile.open(filepath);
    outfile << A.x * 1000 << ","<< A.y * 1000 << endl;
    int rotateAngle = 1;//每次旋转1度
    for (int i = 1; i < 359; i++)
    {
        //顺时针旋转后的夹角
        double angleAD = angleAC - rotateAngle * DEG_TO_RAD;
        //旋转后的点坐标
        Point D = pointOnCircle(O, radius, angleAD);
        outfile << D.x * 1000 << "," << D.y * 1000 << endl;
        rotateAngle++;
     }
    outfile.close();
}

void process(string beforeFile, string afterfile, string filepath, int times)
{
    double radius = 0.0;
    int size = 359;
    double x[359], y[359], z[2];
    getFileContent(filepath + beforeFile, x, y);
    getCerterOfCircle(x, y, size, z, radius);
    if (times < 10) {
        cout << "第" << times << "次模拟圆心坐标为:  ";
    }
    else
    {
        cout << "第" << times << "次模拟圆心坐标为: ";
    }
    cout <<"X:" << fixed << setprecision(3) << z[0] << " Y:" << fixed << setprecision(3) << z[1];
    cout << "       " << "radius:" << radius << endl;
    Point A = { x[0], y[0] };
    Point O = { z[0],z[1] };
    writefile(A, O, radius, filepath + afterfile);
}

int main()
{
    
  string filepath = "E:\\doukan\\项目\\旋转DD马达\\";
    cout << "10.8测的6组数据" << endl;
    process("旋转电机抓点20231013094802\\旋转电机抓点20231108095143.txt", "new\\test25.txt", filepath, 25);

    process("旋转电机抓点20231013094802\\旋转电机抓点20231108105927.txt", "new\\test26.txt", filepath, 26);

    process("旋转电机抓点20231013094802\\旋转电机抓点20231108115449.txt", "new\\test27.txt", filepath, 27);

   /* process("旋转电机抓点20231013094802\\旋转电机抓点20231108130215.txt", "new\\test28.txt", filepath, 28);

    process("旋转电机抓点20231013094802\\旋转电机抓点20231108145533.txt", "new\\test29.txt", filepath, 29);*/

    process("旋转电机抓点20231013094802\\旋转电机抓点20231108162446.txt", "new\\test30.txt", filepath, 30);

    process("旋转电机抓点20231013094802\\旋转电机抓点20231108171720.txt", "new\\test31.txt", filepath, 31);

    process("旋转电机抓点20231013094802\\旋转电机抓点20231108182559.txt", "new\\test32.txt", filepath, 32);


    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值