二维坐标系的变换分为旋转变换和平移变换。
一、旋转变换
假设已知基坐标系XOY中的一点P(x,y),坐标原点为O,绕点O旋转θ,可以求得点P在新坐标系X’OY’中坐标值(x’,y’),如下图所示:
求解x’和y’的关键是坚持用已知的边做斜边来求解,结合上图利用三角函数可以求得:
x’=x·cos(θ)+y·sin(θ)
y’=y·cos(θ)-x·sin(θ)
那么点P在X’OY’中的坐标值为(x’,y’)。
同理如果知道P点在坐标系X’OY’中的坐标(x’,y’),可以求得点P在基坐标系XOY中的坐标值:
x=x’·cos(-θ)+y’·sin(-θ)
y=y’·cos(-θ)-x’·sin(-θ)
通过上述两个算式可以知道:已知一个点P在一个坐标系中的坐标值(x,y),那么把坐标系绕坐标原点旋转θ以后,点P在新坐标系中的坐标值x’和y’分别为:
x’=x·cos(θ)+y·sin(θ)
y’=y·cos(θ)-x·sin(θ)
绕坐标原点逆时针旋转θ,上式θ值为正,顺时针旋转θ,上式θ值为负。
二、平移变换
已知基坐标系XOY,把坐标系平移(a,b)得到一个新的坐标系X’O’Y’,如果基坐标系中一点P(x,y),跟随坐标系一起平移,那么此时P点在基坐标系XOY中的坐标为(x+a,y+b)。
根据向量加法可以求得:
OP=OO’+O’P’=T+O’P’
所以向量OP’的坐标为(x+a,y+b)。
三、旋转平移变换
旋转平移变换是以上两种情况的叠加,已知旋转平移后的坐标系X’O’Y’中的一点P’(x’,y’),求P’在基坐标系中的坐标值:
可以先求出P’在坐标系XO’Y中的坐标值,X’O’Y’顺时针旋转θ(此时θ应取负值)可以变换为坐标系XO’Y,然后坐标系XO’Y经过平移(-a,-b)可以变换为坐标系XOY,至此可以求出坐标系X’O’Y’中的一点P’(x’,y’)在基坐标系XOY中的坐标值x,y分别为:
x=x’·cos(θ)+y’·sin(θ)+a
y=y’·cos(θ)-x’·sin(θ)+b
以下是将二维坐标算法转换为代码语言为:
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 t然
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//a,b(第一次m1)cd(第一次m2);gf(已知点);a1,a2(第二次m1);a3;a4(第二次m2)
double a, b, c, d, g, f, a1, a2, a3, a4, pointx, pointy;
private double angleupdate;
private double c1;
private double d1;
private void button1_Click(object sender, EventArgs e)
{
countcoor(g, f);
textBox4.Text = Convert.ToString(pointx);
textBox8.Text = Convert.ToString(pointy);
}
public void countcoor( double coorx,double coory)
{
a = Convert.ToDouble(textBox1.Text);
b = Convert.ToDouble(textBox7.Text);
c = Convert.ToDouble(textBox2.Text);
d = Convert.ToDouble(textBox6.Text);
g = Convert.ToDouble(textBox12.Text);
f = Convert.ToDouble(textBox11.Text);
a1 = Convert.ToDouble(textBox3.Text);
a2 = Convert.ToDouble(textBox5.Text);
a3 = Convert.ToDouble(textBox10.Text);
a4 = Convert.ToDouble(textBox9.Text);
//角度差初始值
double angle1 = anglevalue(a, b, c, d);
double angle2 = anglevalue(a1, a2, a3, a4);
double diffangle1 = angle2 - angle1;
#region 带入初始角度差进行计算
//求解mark1孔位点旋转映射坐标x,y
double sine = Math.Sin(diffangle1 * Math.PI / 180);
double cosine = Math.Cos(diffangle1 * Math.PI / 180);
double x = (a) * cosine - (b) * sine;
double y = (b) * cosine + (a) * sine;
//求偏移量,
double x0 = a1 - x;
double y0 = a2 - y;
//带入其他孔位点c, d
c1 = (c) * cosine - (d) * sine + x0;
d1 = (d) * cosine + (c) * sine + y0;
#endregion
//角度差更新
if((Math.Abs(c1 - a3) >= 2) && (Math.Abs(d1 - a4) >= 2))
{
angleupdate = diffangle1 + 180;
}
else
{
angleupdate = diffangle1;
}
#region 带入新角度差进行计算
double sine1 = Math.Sin(angleupdate * Math.PI / 180);
double cosine1 = Math.Cos(angleupdate * Math.PI / 180);
//求偏移量,
double x01 = a1 - ((a) * cosine1 - (b) * sine1);
double y01 = a2 - ((b) * cosine1 + (a) * sine1);
pointx = (g) * cosine1 - (f) * sine1 + x01;
pointy = (f) * cosine1 + (g) * sine1 + y01;
#endregion
}
public double anglevalue(double a,double b, double c, double d)//返回角度值
{
double tanValue = (d - b) / (c - a);
double rangle = Math.Atan(tanValue);//求弧度值1
double angle= rangle / Math.PI * 180;//求角度1
return (angle);
}
}
}
对应的界面如下: