大地四边形类设计C++代码

一、程序内容

    设计一个大地四边形类,注意大地四边形的基本属性,功能上只要求能够设置和返回已知点坐标、8个观测角度、闭合差以及待定点近似坐标的计算(采用条件平差进行计算,要求采用前方交会的方法计算C和D点的近似坐标)。

二、设计思路

1.新建一个C++类CGeoQuadrangle,在类的上方定义一个坐标结构体Point2D。

2.在类中声明私有访问类型的数据成员:已知点A,B;8个观测角(用一维数组存储)。

3.声明共有访问类型的成员函数:构造函数重载函数,获取数据成员的get函数,设置数据成员的set函数,能够计算C,D点坐标的前方交会函数,计算闭合差的函数。然后在类的.cpp文件中完成函数的定义。

4.设计简单的界面测试大地四边形类的功能。

三、主要代码

//CGeoQuadrangle.h;头文件
#pragma once
//定义二维坐标结构体
struct Point2D                                     
{
        double X;
        double Y;
};
class CGeoQuadrangle
{
public:
        CGeoQuadrangle(void);
        ~CGeoQuadrangle(void);
        CGeoQuadrangle(Point2D A,Point2D B,double p[8]);//重载构造函数
private:
        Point2D PA;
        Point2D PB;
        double Angle[8];
public:
        double Dms_TO_Rad(double dDms);                 //度分秒转化为弧度
        double Rad_TO_Dms(double dRad);                 //弧度转化为度分秒
        double Dms_TO_Deg(double dDms);                 //度分秒转化为十进制度
        void SetKnownPointA(Point2D &A);                //设置已知点A坐标
        void SetKnownPointB(Point2D &B);                //设置已知点A坐标
        struct Point2D GetKnownPointA(void);            //返回已知点A坐标
        struct Point2D GetKnownPointB(void);            //返回已知点B坐标
        void SetAngle(double p[8]);                     //设置个角度观测值
        void GetAngle(double p[8]);                     //返回个角度观测值
        struct Point2D ForwardIntersection(double Alpha,double Betta);     //前方交会(Alpha,Betta为弧度制)
        void CAL_CD(Point2D &C,Point2D &D);             //求CD点坐标
        void ClosingError_A(double &Omega1,double &Omega2,double &Omega3); //三角形闭合差
        double ClosingError_D(void);                    //极条件闭合差
        
};
//GeoQuadrangle.cpp:实现文件
#include "StdAfx.h"
#include "GeoQuadrangle.h"
#include "math.h"
const double PI=4.0*atan(1.0);
const double rho=180/PI*3600;    //弧秒值
CGeoQuadrangle::CGeoQuadrangle(void)
{
        PA.X=0;
        PA.Y=0;
        PB.X=0;
        PB.Y=0;
        for (int i=0;i<8;i++)
        {
                Angle[i]=0;
        }
}
 
CGeoQuadrangle::~CGeoQuadrangle(void)
{
}
//构造函数重载
CGeoQuadrangle::CGeoQuadrangle(Point2D A,Point2D B,double p[8])
{
        Point2D PA=A;
        Point2D PB=B;
        for (int i=0;i<8;i++)
        {
                Angle[i]=p[i];
        }
}
double CGeoQuadrangle::Dms_TO_Rad(double dDms)
{
        //return 0;
        return Dms_TO_Deg(dDms)/180*PI;
}
double CGeoQuadrangle::Rad_TO_Dms(double dRad)
{
        //return 0;
        dRad=dRad/PI*180;
        int iDegree,iMin;
        double dSec;
        double dTmp;
        double dDms;
        iDegree=int(dRad);
        dTmp=(dRad-iDegree)*60;
        iMin=int(dTmp);
        dSec=(dTmp-iMin)*60;
        dDms=iDegree+double(iMin)/100+dSec/10000;
        return dDms;
}
double CGeoQuadrangle::Dms_TO_Deg(double dDms)
{
        //return 0;
        double dDeg;
        int iDegree,iMin;
        double dSec;
        iDegree=int(dDms);
        iMin=int((dDms-iDegree)*100);
        dSec=((dDms-iDegree)*100-iMin)*100;
        dDeg=iDegree+double(iMin)/60+dSec/3600;
        return dDeg;        
}
void CGeoQuadrangle::SetKnownPointA(Point2D &A)
{
        PA=A;
}
void CGeoQuadrangle::SetKnownPointB(Point2D &B)
{
        PB=B;
}
struct Point2D CGeoQuadrangle::GetKnownPointA(void)
{
        return PA;
}
struct Point2D CGeoQuadrangle::GetKnownPointB(void)
{
        return PB;
}
void CGeoQuadrangle::SetAngle(double p[8])
{
        for (int i=0;i<8;i++)
        {
                Angle[i]=p[i];
        }
}
void CGeoQuadrangle::GetAngle(double p[8])
{
        for (int i=0;i<8;i++)
        {
                p[i]=Angle[i];
        }
}
struct Point2D CGeoQuadrangle::ForwardIntersection(double Alpha,double Betta)
{
        struct Point2D P;
        //计算A,B角余切值
        double dCotA=1/tan(Alpha);
        double dCotB=1/tan(Betta);
        //计算前方交会定位值
        P.X=((PA.X*dCotB+PB.X*dCotA)+(PB.Y-PA.Y))/(dCotA+dCotB);
        P.Y=((PA.Y*dCotB+PB.Y*dCotA)+(PA.X-PB.X))/(dCotA+dCotB);
        return P;
}
void CGeoQuadrangle::CAL_CD(Point2D &C,Point2D &D)
{
        double angle[8];
        GetAngle(angle);                  //得到8个观测角度
        for (int i=0;i<8;i++)
        {
                angle[i]=Dms_TO_Rad(angle[i]);
        }
        double Alpha1=angle[1]+angle[2];
        double Betta1=angle[0];
        double Alpha2=angle[1];
        double Betta2=angle[0]+angle[7];
        C=ForwardIntersection(Alpha1,Betta1);
        D=ForwardIntersection(Alpha2,Betta2);
}
void CGeoQuadrangle::ClosingError_A(double &Omega1,double &Omega2,double &Omega3)
{
        double angle[8];
        for (int i=0;i<8;i++)
        {
                angle[i]=Dms_TO_Rad(Angle[i]);
        }
        Omega1=(angle[4]+angle[5]+angle[6]+angle[7]-PI)*rho;//用秒存储
        Omega2=(angle[0]+angle[1]+angle[2]+angle[3]-PI)*rho;
        Omega3=(angle[0]+angle[1]+angle[6]+angle[7]-PI)*rho;
}
double CGeoQuadrangle::ClosingError_D(void)
{
        //return 0;
        double angle[8];
        for (int i=0;i<8;i++)
        {
                angle[i]=Dms_TO_Rad(Angle[i]);
        }
        double a=sin(angle[0])*sin(angle[6])*sin(angle[3]+angle[4]);
        double b=sin(angle[3])*sin(angle[0]+angle[7])*sin(angle[5]);
        double Omega_d=(1-a/b);
        Omega_d=Omega_d*rho;                                 //用秒存储
        return Omega_d;
}
// RS_120_ZQL_EX5_1Dlg.h : 头文件
class CRS_120_ZQL_EX5_1Dlg : public CDialog
{
public:        
        CString strResult;                //显示计算结果
        afx_msg void OnBnClickedBtnCal(); //计算
        afx_msg void OnBnClickedCancel(); //退出
};
// RS_120_ZQL_EX5_1Dlg.cpp : 实现文件
#include "GeoQuadrangle.h"
void CRS_120_ZQL_EX5_1Dlg::OnBnClickedBtnCal()
{
        UpdateData(TRUE);
        strResult=_T("");
        // TODO: 在此添加控件通知处理程序代码
 
        Point2D A;
        A.X=354.87;
        A.Y=648.12;
        Point2D B;
        B.X=1601.23;
        B.Y=807.83;
        double p[8];
        p[0]= 50.2930;
        p[1]= 72.2907;
        p[2]= 28.0856;
        p[3]= 28.5218;
        p[4]= 76.1911;
        p[5]= 46.3930;
        p[6]= 27.3948;
        p[7]= 29.2116;
 
        用构造函数初始化
        //CGeoQuadrangle GQ(A,B,p);
 
        //用set函数初始化
        CGeoQuadrangle GQ;
        GQ.SetKnownPointA(A);
        GQ.SetKnownPointB(B);
        GQ.SetAngle(p);
 
        //求C,D点的坐标
        Point2D C,D;
        GQ.CAL_CD(C,D);
 
        //求三角形闭合差
        double omega1,omega2,omega3;
        GQ.ClosingError_A(omega1,omega2,omega3);
 
        //极条件闭合差
        double omega_d;
        omega_d=GQ.ClosingError_D();
 
        //将计算结果显示在编辑框
        strResult.Format(_T("%s%f%s%f\r\n%s%f%s%f\r\n%s%f%s%f%s%f%s\r\n%s%f%s"),
                _T("C点坐标:"),C.X,_T(","),C.Y,
                _T("D点坐标:"),D.X,_T(","),D.Y,
                _T("三角形闭合差:"),omega1,_T("秒,"),omega2,_T("秒,"),omega3,_T("秒"),
                _T("极条件闭合差:"),omega_d,_T("秒"));
        UpdateData(FALSE);
}
 
void CRS_120_ZQL_EX5_1Dlg::OnBnClickedCancel()
{
        // TODO: 在此添加控件通知处理程序代码
        OnCancel();
}

四、运行结果



 

这里提供一份基于C语言的四边形网格剖分代码,供参考: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #define SIZE 128 // 网格大小 struct Quad { int x1, y1, x2, y2; }; int quad_count = 0; struct Quad quads[SIZE * SIZE]; void subdivide(int x1, int y1, int x2, int y2) { if ((x2 - x1 <= 1) && (y2 - y1 <= 1)) return; int mx = (x1 + x2) / 2; int my = (y1 + y2) / 2; quads[quad_count++] = (struct Quad){mx, y1, x2, my}; // 右上角 quads[quad_count++] = (struct Quad){x1, y1, mx, my}; // 左上角 quads[quad_count++] = (struct Quad){x1, my, mx, y2}; // 左下角 quads[quad_count++] = (struct Quad){mx, my, x2, y2}; // 右下角 subdivide(x1, y1, mx, my); subdivide(mx, y1, x2, my); subdivide(x1, my, mx, y2); subdivide(mx, my, x2, y2); } int main() { subdivide(0, 0, SIZE, SIZE); printf("Total quads: %d\n", quad_count); for (int i = 0; i < quad_count; i++) { printf("Quad %d: (%d, %d), (%d, %d)\n", i + 1, quads[i].x1, quads[i].y1, quads[i].x2, quads[i].y2); } return 0; } ``` 在代码中,`subdivide()` 函数用于递归地将一个四边形网格划分为四个子网格。`x1` 和 `y1` 分别表示当前四边形网格的左上角坐标,`x2` 和 `y2` 分别表示当前四边形网格的右下角坐标。 每次划分都将当前四边形网格分成四个子网格,并将子网格的坐标存储到 `quads` 数组中。最终输出所有的子网格信息。 代码中使用了一个结构体 `Quad` 来表示一个四边形网格的坐标信息。`quad_count` 表示当前已经划分出的四边形网格数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值