需求:
在CAD内實作兩個坐标系的轉換。
轉換方式為檔案内的所有圖形從一個坐标系下的坐标,轉換到另一個坐标系下的坐标。
進行坐标轉換後,僅僅是坐标發生改變,圖層、樣式等等不會發生變化。
示例:如圖一、二

圖 1 國家2000坐标系
轉換後坐标:
圖 2 廣州城建坐标系
坐标轉換:
空間實體的位置描述,從一種坐标系統變換到另一種坐标系統的過程。通過建立兩個坐标系統之間一一對應關系來實作。是各種比例尺地圖測量和編繪中建立地圖數學基礎必不可少的步驟。兩個及以上的坐标轉換時由極坐标相對參照确定維數空間。
一個點在一個坐标系的(一組)坐标,到新坐标系的(另一組)坐标的改變。新坐标系可以是與原坐标系同類型的(通過坐标軸的平移或旋轉等得出);也可以是不同類型的(例如由直角坐标系變為極坐标系等)。
X1與Y1代表原平面坐标下的坐标, X2與Y2代表目标平面坐标下的坐标,二者轉換需要四個參數,分别為x、y兩個坐标的偏移,以及旋轉角度和尺度因子等。
,
通常平面直角坐标系轉換,需要兩步:
- 計算四參數
- 通過四參數計算轉換後的坐标
第一步中四參數我們會提供,可以不用計算,提供的四參數有兩套。
需要利用程式設計實作的就是第二步,即利用四參數計算坐标。
頁面布局:
圖 3 頁面布局
選擇國家2000轉廣州城建的單選框時,左邊顯示出四參數,但是不可更改。
選擇廣州城建轉國家2000的單選框時,左邊顯示出四參數,但是不可更改。
選擇自定義單選框時,左邊四參數可輸入。
參考資料:坐标轉換 - 四參數求解_四參數轉換_塵埃裡的邂逅的部落格-CSDN部落格
結果:
源碼:
Form1.Cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Closebtn_Click(object sender, EventArgs e)
{
this.Close();
}
private void button1_Click_1(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
}
//自定義參數
private void mybtn_Click(object sender, EventArgs e)
{
x = 386471.785949509;
y = -2529992.86170142;
m = -0.00483892522831;
alpha = 1.00002783953692;
// this.textBoxX.Text = " ";
// this.textBoxY.Text = " ";
// this.textBoxm.Text = " ";
// this.textBoxAlpha.Text = " ";
this.textBoxX.ReadOnly = false;
this.textBoxY.ReadOnly = false;
this.textBoxm.ReadOnly = false;
this.textBoxAlpha.ReadOnly = false;
//輸入參數
string strX = this.textBoxX.Text;
x = double.Parse(strX);//将輸入的參數傳給變量
string strY = this.textBoxY.Text;
y = double.Parse(strX);//将輸入的參數傳給變量
string strm = this.textBoxm.Text;
m = double.Parse(strm);//将輸入的參數傳給變量
string strAlpha = this.textBoxAlpha.Text;
alpha = double.Parse(strAlpha);//将輸入的參數傳給變量
//坐标轉換公式:
// X2 = x + m * cos(alpha) * X1 - m * sin(alpha) * Y1
// Y2 = x + m * sin(alpha) * X1 - m * cos(alpha) * Y1
//坐标轉換
double X1 = 1, X2, Y1 = 1, Y2;
//設定原坐标:X1,Y1
string strx = this.textBoxX1.Text;
X1 = double.Parse(strx);
string stry = this.textBoxY1.Text;
Y1 = double.Parse(stry);
X2 = x + m * Math.Cos(alpha) * X1 - m * Math.Sin(alpha) * Y1;
Y2 = x + m * Math.Sin(alpha) * X1 - m * Math.Cos(alpha) * Y1;
string str = "X:" + X2.ToString() + " Y:" + Y2.ToString();
string strxy1 = "X:" + X1.ToString() + " Y:" + Y1.ToString();
this.textBoxXY1.Text = strxy1;
this.textBoxXY.Text = str;
}
private void Guangzhoubtn_Click(object sender, EventArgs e)
{
//設定廣州城建參數
x = 386471.785949509;
y = -2529992.86170142;
m = -0.00483892522831;
alpha = 1.00002783953692;
this.textBoxX.Text = " ";
this.textBoxY.Text = " ";
this.textBoxm.Text = " ";
this.textBoxAlpha.Text = " ";
this.textBoxX.ReadOnly = true;
this.textBoxY.ReadOnly = true;
this.textBoxm.ReadOnly = true;
this.textBoxAlpha.ReadOnly = true;
this.textBoxXY.ReadOnly = true;
this.textBoxX.Text = "386471.785949509";
this.textBoxY.Text = "-2529992.86170142";
this.textBoxm.Text = "-0.00483892522831";
this.textBoxAlpha.Text = " 1.00002783953692";
//坐标轉換公式:
// X2 = x + m * cos(alpha) * X1 - m * sin(alpha) * Y1
// Y2 = x + m * sin(alpha) * X1 - m * cos(alpha) * Y1
//坐标轉換
double X1 = 1, X2, Y1 = 1, Y2;
//設定原坐标:X1,Y1
string strx = this.textBoxX1.Text;
X1 = double.Parse(strx);
string stry = this.textBoxY1.Text;
Y1 = double.Parse(stry);
X2 = x + m * Math.Cos(alpha) * X1 - m * Math.Sin(alpha) * Y1;
Y2 = x + m * Math.Sin(alpha) * X1 - m * Math.Cos(alpha) * Y1;
string str = "X:"+X2.ToString()+" Y:"+Y2.ToString();
string strxy1 = "X:" + X1.ToString() + " Y:" + Y1.ToString();
this.textBoxXY1.Text = strxy1;
this.textBoxXY.Text = str;
}
//國家2000單選框
private void Guojiabtn_Click(object sender, EventArgs e)
{
//國家參數
x = -374214.444824699;
y = -2531762.85922438;
m = 0.00483892522819;
alpha = 0.99997216121273;
this.textBoxX.Text = " ";
this.textBoxY.Text = " ";
this.textBoxm.Text = " ";
this.textBoxAlpha.Text = " ";
this.textBoxX.ReadOnly = true;
this.textBoxY.ReadOnly = true;
this.textBoxm.ReadOnly = true;
this.textBoxAlpha.ReadOnly = true;
this.textBoxX.Text = "-386471.785949509";
this.textBoxY.Text = "-2531762.85922438";
this.textBoxm.Text = "0.00483892522819";
this.textBoxAlpha.Text = "0.99997216121273";
//坐标轉換
double X1 = 1, X2, Y1 = 1, Y2;
//設定原坐标:X1,Y1
string strx = this.textBoxX1.Text;
X1 = double.Parse(strx);
string stry = this.textBoxY1.Text;
Y1 = double.Parse(stry);
X2 = x + m * Math.Cos(alpha) * X1 - m * Math.Sin(alpha) * Y1;
Y2 = x + m * Math.Sin(alpha) * X1 - m * Math.Cos(alpha) * Y1;
string str = "X:" + X2.ToString() + " Y:" + Y2.ToString();
string strxy1 = "X:" + X1.ToString() + " Y:" + Y1.ToString();
this.textBoxXY1.Text = strxy1;
this.textBoxXY.Text = str;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
Form1.Desiger.cs:
namespace WindowsFormsApp1
{
partial class Form1
{
/// <summary>
/// 必需的設計器變量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
/// <param name="disposing">如果應釋放托管資源,為 true;否則為 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
//預設國家2000轉廣州城建參數
public double x = -374214.444824699;
public double y = -2531762.85922438;
public double m = 0.00483892522819;
public double alpha = 0.99997216121273;
#region Windows 窗體設計器生成的代碼
/// <summary>
/// 設計器支援所需的方法 - 不要修改
/// 使用代碼編輯器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.labX = new System.Windows.Forms.Label();
this.Closebtn = new System.Windows.Forms.Button();
this.Guobtn = new System.Windows.Forms.Button();
this.Guangbtn = new System.Windows.Forms.Button();
this.button = new System.Windows.Forms.Button();
this.Guojiabtn = new System.Windows.Forms.Button();
this.Guangzhoubtn = new System.Windows.Forms.Button();
this.mybtn = new System.Windows.Forms.Button();
this.labm = new System.Windows.Forms.Label();
this.labY = new System.Windows.Forms.Label();
this.labAlpha = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.textBoxAlpha = new System.Windows.Forms.TextBox();
this.textBoxm = new System.Windows.Forms.TextBox();
this.textBoxY = new System.Windows.Forms.TextBox();
this.textBoxX = new System.Windows.Forms.TextBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.textBoxXY1 = new System.Windows.Forms.TextBox();
this.textBoxY1 = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.textBoxX1 = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.textBoxXY = new System.Windows.Forms.TextBox();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
// labX
//
this.labX.AutoSize = true;
this.labX.Location = new System.Drawing.Point(23, 36);
this.labX.Name = "labX";
this.labX.Size = new System.Drawing.Size(17, 12);
this.labX.TabIndex = 0;
this.labX.Text = "X:";
//
// Closebtn
//
this.Closebtn.AutoSize = true;
this.Closebtn.Location = new System.Drawing.Point(501, 240);
this.Closebtn.Name = "Closebtn";
this.Closebtn.Size = new System.Drawing.Size(77, 22);
this.Closebtn.TabIndex = 1;
this.Closebtn.Text = "Close";
this.Closebtn.UseVisualStyleBackColor = true;
this.Closebtn.Click += new System.EventHandler(this.Closebtn_Click);
//
// Guobtn
//
this.Guobtn.Location = new System.Drawing.Point(269, 62);
this.Guobtn.Name = "Guobtn";
this.Guobtn.Size = new System.Drawing.Size(183, 23);
this.Guobtn.TabIndex = 2;
this.Guobtn.Text = "國家2000轉廣州城建";
this.Guobtn.UseVisualStyleBackColor = true;
this.Guobtn.Click += new System.EventHandler(this.button1_Click_1);
//
// Guangbtn
//
this.Guangbtn.Location = new System.Drawing.Point(269, 107);
this.Guangbtn.Name = "Guangbtn";
this.Guangbtn.Size = new System.Drawing.Size(183, 23);
this.Guangbtn.TabIndex = 3;
this.Guangbtn.Text = "廣州城建轉國家2000";
this.Guangbtn.UseVisualStyleBackColor = true;
this.Guangbtn.Click += new System.EventHandler(this.button2_Click);
//
// button
//
this.button.Location = new System.Drawing.Point(269, 149);
this.button.Name = "button";
this.button.Size = new System.Drawing.Size(183, 23);
this.button.TabIndex = 4;
this.button.Text = "自定義";
this.button.UseVisualStyleBackColor = true;
this.button.Click += new System.EventHandler(this.button3_Click);
//
// Guojiabtn
//
this.Guojiabtn.Location = new System.Drawing.Point(480, 62);
this.Guojiabtn.Name = "Guojiabtn";
this.Guojiabtn.Size = new System.Drawing.Size(101, 23);
this.Guojiabtn.TabIndex = 5;
this.Guojiabtn.Text = "國家轉廣州結果";
this.Guojiabtn.UseVisualStyleBackColor = true;
this.Guojiabtn.Click += new System.EventHandler(this.Guojiabtn_Click);
//
// Guangzhoubtn
//
this.Guangzhoubtn.Location = new System.Drawing.Point(480, 102);
this.Guangzhoubtn.Name = "Guangzhoubtn";
this.Guangzhoubtn.Size = new System.Drawing.Size(101, 23);
this.Guangzhoubtn.TabIndex = 6;
this.Guangzhoubtn.Text = "廣州轉國家結果";
this.Guangzhoubtn.UseVisualStyleBackColor = true;
this.Guangzhoubtn.Click += new System.EventHandler(this.Guangzhoubtn_Click);
//
// mybtn
//
this.mybtn.Location = new System.Drawing.Point(480, 152);
this.mybtn.Name = "mybtn";
this.mybtn.Size = new System.Drawing.Size(98, 23);
this.mybtn.TabIndex = 7;
this.mybtn.Text = "自定義轉換結果";
this.mybtn.UseVisualStyleBackColor = true;
this.mybtn.Click += new System.EventHandler(this.mybtn_Click);
//
// labm
//
this.labm.AutoSize = true;
this.labm.Location = new System.Drawing.Point(17, 125);
this.labm.Name = "labm";
this.labm.Size = new System.Drawing.Size(17, 12);
this.labm.TabIndex = 8;
this.labm.Text = "m:";
//
// labY
//
this.labY.AutoSize = true;
this.labY.Location = new System.Drawing.Point(23, 80);
this.labY.Name = "labY";
this.labY.Size = new System.Drawing.Size(17, 12);
this.labY.TabIndex = 9;
this.labY.Text = "Y:";
//
// labAlpha
//
this.labAlpha.AutoSize = true;
this.labAlpha.Location = new System.Drawing.Point(17, 168);
this.labAlpha.Name = "labAlpha";
this.labAlpha.Size = new System.Drawing.Size(23, 12);
this.labAlpha.TabIndex = 10;
this.labAlpha.Text = "α:";
//
// groupBox1
//
this.groupBox1.Controls.Add(this.textBoxAlpha);
this.groupBox1.Controls.Add(this.textBoxm);
this.groupBox1.Controls.Add(this.textBoxY);
this.groupBox1.Controls.Add(this.textBoxX);
this.groupBox1.Controls.Add(this.labX);
this.groupBox1.Controls.Add(this.labm);
this.groupBox1.Controls.Add(this.labY);
this.groupBox1.Controls.Add(this.labAlpha);
this.groupBox1.Location = new System.Drawing.Point(33, 38);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(230, 192);
this.groupBox1.TabIndex = 19;
this.groupBox1.TabStop = false;
//
// textBoxAlpha
//
this.textBoxAlpha.Location = new System.Drawing.Point(47, 159);
this.textBoxAlpha.Name = "textBoxAlpha";
this.textBoxAlpha.Size = new System.Drawing.Size(139, 21);
this.textBoxAlpha.TabIndex = 14;
this.textBoxAlpha.Text = "1";
//
// textBoxm
//
this.textBoxm.Location = new System.Drawing.Point(47, 116);
this.textBoxm.Name = "textBoxm";
this.textBoxm.Size = new System.Drawing.Size(139, 21);
this.textBoxm.TabIndex = 13;
this.textBoxm.Text = "1";
//
// textBoxY
//
this.textBoxY.Location = new System.Drawing.Point(47, 71);
this.textBoxY.Name = "textBoxY";
this.textBoxY.Size = new System.Drawing.Size(139, 21);
this.textBoxY.TabIndex = 12;
this.textBoxY.Text = "1";
//
// textBoxX
//
this.textBoxX.Location = new System.Drawing.Point(47, 26);
this.textBoxX.Name = "textBoxX";
this.textBoxX.Size = new System.Drawing.Size(139, 21);
this.textBoxX.TabIndex = 11;
this.textBoxX.Text = "1";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.textBoxXY1);
this.groupBox2.Controls.Add(this.textBoxY1);
this.groupBox2.Controls.Add(this.label3);
this.groupBox2.Controls.Add(this.label4);
this.groupBox2.Controls.Add(this.textBoxX1);
this.groupBox2.Controls.Add(this.label2);
this.groupBox2.Controls.Add(this.label1);
this.groupBox2.Controls.Add(this.textBoxXY);
this.groupBox2.Controls.Add(this.groupBox1);
this.groupBox2.Controls.Add(this.Closebtn);
this.groupBox2.Controls.Add(this.Guobtn);
this.groupBox2.Controls.Add(this.mybtn);
this.groupBox2.Controls.Add(this.Guangbtn);
this.groupBox2.Controls.Add(this.Guangzhoubtn);
this.groupBox2.Controls.Add(this.button);
this.groupBox2.Controls.Add(this.Guojiabtn);
this.groupBox2.Location = new System.Drawing.Point(58, 33);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(599, 321);
this.groupBox2.TabIndex = 20;
this.groupBox2.TabStop = false;
//
// textBoxXY1
//
this.textBoxXY1.Location = new System.Drawing.Point(80, 246);
this.textBoxXY1.Name = "textBoxXY1";
this.textBoxXY1.Size = new System.Drawing.Size(283, 21);
this.textBoxXY1.TabIndex = 24;
//
// textBoxY1
//
this.textBoxY1.Location = new System.Drawing.Point(340, 203);
this.textBoxY1.Name = "textBoxY1";
this.textBoxY1.Size = new System.Drawing.Size(138, 21);
this.textBoxY1.TabIndex = 23;
this.textBoxY1.Text = "1";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(269, 184);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(65, 12);
this.label3.TabIndex = 21;
this.label3.Text = "原X 坐 标:";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(269, 206);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(65, 12);
this.label4.TabIndex = 22;
this.label4.Text = "原Y 坐 标:";
//
// textBoxX1
//
this.textBoxX1.Location = new System.Drawing.Point(340, 175);
this.textBoxX1.Name = "textBoxX1";
this.textBoxX1.Size = new System.Drawing.Size(138, 21);
this.textBoxX1.TabIndex = 21;
this.textBoxX1.Text = "1";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(14, 250);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(59, 12);
this.label2.TabIndex = 20;
this.label2.Text = "原 坐 标:";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(6, 282);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(71, 12);
this.label1.TabIndex = 15;
this.label1.Text = "轉換後坐标:";
//
// textBoxXY
//
this.textBoxXY.Location = new System.Drawing.Point(80, 273);
this.textBoxXY.Name = "textBoxXY";
this.textBoxXY.Size = new System.Drawing.Size(283, 21);
this.textBoxXY.TabIndex = 16;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(763, 412);
this.Controls.Add(this.groupBox2);
this.Name = "Form1";
this.Text = "Form1";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label labX;
private System.Windows.Forms.Button Closebtn;
private System.Windows.Forms.Button Guobtn;
private System.Windows.Forms.Button Guangbtn;
private System.Windows.Forms.Button button;
private System.Windows.Forms.Button Guojiabtn;
private System.Windows.Forms.Button Guangzhoubtn;
private System.Windows.Forms.Button mybtn;
private System.Windows.Forms.Label labm;
private System.Windows.Forms.Label labY;
private System.Windows.Forms.Label labAlpha;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.TextBox textBoxAlpha;
private System.Windows.Forms.TextBox textBoxm;
private System.Windows.Forms.TextBox textBoxY;
private System.Windows.Forms.TextBox textBoxX;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBoxXY;
private System.Windows.Forms.TextBox textBoxX1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox textBoxXY1;
private System.Windows.Forms.TextBox textBoxY1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
}
}
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
static class Program
{
/// <summary>
/// 應用程式的主入口點。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}