坐标转换 您所在的位置:网站首页 购买硬盘主要看哪四个参数 坐标转换

坐标转换

2024-07-13 14:18| 来源: 网络整理| 查看: 265

1.四参数来历 1、平面坐标 - 平面坐标

在坐标转换的过程中,我们我们在小范围内,可以使用四参数就能达到坐标转换的目的,且精度也能达到预定的需求。,四参数计算公式如下 在这里插入图片描述 X1与Y1代表原平面坐标下的坐标, X2与Y2代表目标平面坐标下的坐标,二者转换需要四个参数,分别为x、y两个坐标的偏移,以及旋转角度和尺度因子等 2、四参数求解 四参数求解至少需要两个点对,分别知道其在目标投影坐标和原投影坐标下的坐标点对,我觉得**dibowei2069**写的求解过程就很详细,下面我将贴出其博客的链接,同时为了保持本文丰富性,将其内容进行拿来主义了:

PS:这里的P矩阵写法有问题,自己在计算的过程中发现了致命的问题,P矩阵应该是一个单位矩阵,其维度应为2count✖2count (count为数据点对的个数),因此在公式中,我们可以忽略相应的单位矩阵,得到的结果也不影响最终的答案。 最小二乘求解方程

PS: 想知道更加具体的信息,可以去他博客去了解下,链接为:https://blog.csdn.net/dibowei2069/article/details/106039613 再次表示感谢、感谢、感谢!!!!!

2、四参数求解

1、java写矩阵运算计算 一开始想着自己写矩阵运算,提高自己的码力,也写出来了,但是精度有点问题,我也不知道为啥,在计算的过程中,我都使用了BigDecimal去保留更多的精度,奈何就是精度不够,差距十多米,但是我坚信,自己写的没问题,下面我贴出自己的实现方式,希望大家多多提出意见,看看到底错在那里:同时在此我给出两组数组对,方便大家使用,在下面的代码中,需要的自取,最后,我还会给出一对方便大家验证:下面给出截图,同时为了方便复制,我也将其放在代码块里面 坐标点对,厘米级别

/* **点 X1 Y1 X2 Y2 P1 4312820.897 513670.931 4312816.917 513553.7194 P2 4314058.425 514231.984 4314054.44 514114.7771 P3 4306670.108 511168.332 4306666.154 511051.098** */ //利用两组坐标,求解四参数 public static double [] solveFourParameters(){ Point3D original = new Point3D(4312820.897,513670.931,402.992); Point3D origina2 = new Point3D(4314058.425,514231.984,432.447); Point3D target1 = new Point3D(4312816.917,513553.719,416.183); Point3D target2 = new Point3D(4314054.440,514114.777,445.596); double [][] L = {{target1.getX()-original.getX()}, {target1.getY()-original.getY()}, {target2.getX()- origina2.getX()}, {target2.getY()-origina2.getY()} }; PrintMatrix(L); double [][] P = formUnitMatrix(4); PrintMatrix(P); double [][] B = {{1,0,original.getX(),-original.getY()}, {0,1,original.getY(),original.getX()}, {1,0,origina2.getX(),-origina2.getY()}, {0,1,origina2.getY(),origina2.getX()}}; PrintMatrix(B); double [][] firstPart = matrixInv(matrixMultiply(matrixMultiply(matrixTransposition(B),P),B)); double [][] first = matrixMultiply(matrixTransposition(B),P); PrintMatrix(first); double [][] second = matrixMultiply(first,B); PrintMatrix(second); double [][] third = matrixInv(second); PrintMatrix(third); double [][] fourth = matrixMultiply(third,matrixTransposition(B)); PrintMatrix(fourth); double [][] fifth = matrixMultiply(fourth,P); PrintMatrix(fifth); double [][] finalMatrix = matrixMultiply(fifth,L); PrintMatrix(finalMatrix); // double [][] finalMatrix = matrixMultiply(matrixMultiply(matrixMultiply(firstPart,matrixTransposition(B)),P),L); double m = Math.sqrt(Math.pow(finalMatrix[2][0]+1,2)+ Math.pow(finalMatrix[3][0],2)); double angle = Math.atan(finalMatrix[3][0]/(finalMatrix[2][0]-1)); double [] fourParameter = {finalMatrix[0][0],finalMatrix[1][0],angle,m}; Log.e("anywhere", fourParameter[0]+ "\n"+ fourParameter[1]+"\n"+ fourParameter[2]+"\n"+fourParameter[3]); //得到的四参数进行结算 double[] four_para = fourParameter; Point3D point3D = new Point3D(4306670.108,511168.332,309.157); BigDecimal oldx = BigDecimal.valueOf(point3D.getX()); BigDecimal oldy = BigDecimal.valueOf(point3D.getY()); BigDecimal cos = new BigDecimal(String.valueOf(Math.cos(four_para[2]))); //计算cos BigDecimal sin = new BigDecimal(String.valueOf(Math.sin(four_para[2]))); //计算sin BigDecimal part1= cos.multiply(oldx); BigDecimal part2= oldy.multiply(sin); BigDecimal part3= part1.subtract(part2); BigDecimal part4= BigDecimal.valueOf(four_para[3]).multiply(part3); BigDecimal x= BigDecimal.valueOf(four_para[0]).add(part4); BigDecimal newX =x.setScale(6,BigDecimal.ROUND_HALF_DOWN); BigDecimal y = BigDecimal.valueOf(four_para[1]).add(BigDecimal.valueOf(four_para[3]).multiply(oldx.multiply(sin).add(oldy.multiply(cos)))); BigDecimal newY = y.setScale(6,BigDecimal.ROUND_HALF_DOWN); Log.e("anywhere","newx:"+ newX+"\n"+"newY:"+ newY); return fourParameter; } private static void PrintMatrix(double [][] matrix) { for(int i = 0 ; i builder.append(matrix[i][j]).append(" + "); } Log.e("matrix",builder.toString()+"\n"); } } public static double[][] formUnitMatrix(int dimen) { double [][]temp = new double[dimen][dimen]; for(int i = 0;i if(i==j) temp[i][j]=1; else temp[i][j]=0; } } return temp; } /* 利用java实现矩阵的乘法和转置以及求逆矩阵 */ //转置,必须行列都一样 public static double [][] matrixTransposition( double [][] changedMatrix){ int colums = changedMatrix.length; double targetMatrix [][] = new double[colums][colums]; for(int i = 0; i targetMatrix[i][j] = changedMatrix[j][i]; } } return targetMatrix; } //矩阵的乘法,前一个列数与后一个行数相同 public static double[][] matrixMultiply(double[][] previousMatrix , double [][] laterMatrix){ if(previousMatrix[0].length!= laterMatrix.length){ return null; } int lines = previousMatrix.length; //新的行数 int colums = laterMatrix[0].length; //列数 int commonLines = laterMatrix.length; //前一个的列数与后一个的行数 double[][] targetMatrix = new double[lines][colums]; for(int i = 0; i BigDecimal sum = BigDecimal.valueOf(0.0); for(int k = 0 ;k if(solvMatrix.length!= solvMatrix[0].length) return 0.; if (solvMatrix.length==1) return solvMatrix[0][0]; else if (solvMatrix.length==2) return matrix2Det(solvMatrix); else if (solvMatrix.length==3) return matrix3Det(solvMatrix); else { //可以求解四次的 double sum = 0.0; for (int i = 0; i int lines = matrix.length; int columns = matrix[0].length; double [][] targetMarix = new double[lines-1][columns-1]; int dx=0; for(int i=0;i int dy=0; for (int j=0;j targetMarix[dx][dy++] = matrix[i][j]; } } ++dx; } } return targetMarix; } //求解三阶的行列式值 public static double matrix3Det(double[][] solvMatrix) { if(solvMatrix.length!=solvMatrix[0].length){ return 0.; } double [][] A0 = companionMatrix(solvMatrix,0,0); double [][] A1 = companionMatrix(solvMatrix,0,1); double [][] A2 = companionMatrix(solvMatrix,0,2); BigDecimal Part1 = BigDecimal.valueOf(solvMatrix[0][0]).multiply(BigDecimal.valueOf(matrix2Det(A0))); BigDecimal Part2 = BigDecimal.valueOf(solvMatrix[0][1]).multiply(BigDecimal.valueOf(matrix2Det(A1))); BigDecimal Part3 = BigDecimal.valueOf(solvMatrix[0][2]).multiply(BigDecimal.valueOf(matrix2Det(A2))); BigDecimal part1_2 = Part1.subtract(Part2); BigDecimal final_result = part1_2.add(Part3); return final_result.doubleValue(); } //求解2阶的行列式值 public static double matrix2Det(double[][] solvMatrix) { BigDecimal first = BigDecimal.valueOf(solvMatrix[0][0]).multiply(BigDecimal.valueOf(solvMatrix[1][1])); BigDecimal second = BigDecimal.valueOf(solvMatrix[0][1]).multiply(BigDecimal.valueOf(solvMatrix[1][0])); return first.subtract(second).doubleValue(); } //求逆矩阵 public static double[][] matrixInv(double[][] solveMatrix){ //行数与列数必须相等 if (solveMatrix.length!=solveMatrix[0].length) return null; int lines = solveMatrix.length; int columns = solveMatrix[0].length; double A = matrixValues(solveMatrix); double[][] targetMatrix =new double[lines][columns]; for(int i=0;i double[][] temp= companionMatrix(solveMatrix,i,j); targetMatrix[j][i]=BigDecimal.valueOf(matrixValues(temp)).divide(BigDecimal.valueOf(A),40,BigDecimal.ROUND_DOWN).doubleValue() * Math.pow(-1,i+j); } } return targetMatrix; }

2、jar包闪亮上场 既然自己写的精度存在问题,那么我就想到了jar的方法,去看看大佬们如何写的,然后就网上搜索,看到了一篇关于***commons-math3***的介绍,在此对***HFUT_qianyang***表示感谢、感谢、感谢!!大家也可以去他的博客去看看jar包math3关于矩阵的基本使用,链接位:https://blog.csdn.net/qy20115549/article/details/54604264,同时,我也将自己下载好的math3 jar包上传,希望能帮助到大家。链接在此:https://mp.csdn.net/console/upDetailed

实现流程与上文自己写的类似,就是将矩阵运算替换位jar包中提供的方法,最后结果的截图位: 在这里插入图片描述newX、newY分别为根据计算出的四参数求得的新的转换坐标,本身应该为 X2= 4306666.154 Y2 = 511051.098,误差分别只有3mm与4mm,对于厘米级要求的工程,远远超出其标准。

import java.math.BigDecimal; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.math3.linear.Array2DRowRealMatrix; import org.apache.commons.math3.linear.LUDecomposition; import org.apache.commons.math3.linear.RealMatrix; public class Hero { public static void main(String[] asgs){ //checkRegerx(); calculateFourParameters(); } private static void calculateFourParameters() { Point3D original = new Point3D(4312820.897,513670.931,402.992); Point3D origina2 = new Point3D(4314058.425,514231.984,432.447); Point3D target1 = new Point3D(4312816.917,513553.719,416.183); Point3D target2 = new Point3D(4314054.440,514114.777,445.596); double [][] L1 = {{target1.getX()-original.getX()}, {target1.getY()-original.getY()}, {target2.getX()- origina2.getX()}, {target2.getY()-origina2.getY()} }; double [][] P1 = formUnitMatrix(4); double [][] B1 = {{1,0,original.getX(),-original.getY()}, {0,1,original.getY(),original.getX()}, {1,0,origina2.getX(),-origina2.getY()}, {0,1,origina2.getY(),origina2.getX()}}; //转为我们需要的数组 RealMatrix L = new Array2DRowRealMatrix(L1); RealMatrix P = new Array2DRowRealMatrix(P1); RealMatrix B = new Array2DRowRealMatrix(B1); RealMatrix first = P.multiply(B.transpose()); //Bt*P PrintMatrix(first,"BT*P"); RealMatrix second = first.multiply(B); PrintMatrix(second,"BT*P*B"); RealMatrix third = inverseMatrix(second); PrintMatrix(third,"(BT*B*P)-"); RealMatrix fourth = third.multiply(B.transpose()); PrintMatrix(fourth,"(BT*B*P)-*BT"); RealMatrix fifth = fourth.multiply(P); PrintMatrix(fifth,"(BT*B*P)-BT*P"); RealMatrix sixth = fifth.multiply(L); PrintMatrix(sixth,"(BT*B*P)-BT*P*L"); double [][] finalMatrix = sixth.getData(); double m = Math.sqrt(Math.pow(finalMatrix[2][0]+1,2)+ Math.pow(finalMatrix[3][0],2)); double angle = Math.atan(finalMatrix[3][0]/(finalMatrix[2][0]-1)); double [] fourParameter = {finalMatrix[0][0],finalMatrix[1][0],Math.abs(angle),m}; System.out.print("final: "+ fourParameter[0]+ "\n"+ fourParameter[1]+"\n"+ fourParameter[2]+"\n"+fourParameter[3]); double[] four_para = fourParameter; Point3D point3D = new Point3D(4306670.108,511168.332,309.157); BigDecimal oldx = BigDecimal.valueOf(point3D.getX()); BigDecimal oldy = BigDecimal.valueOf(point3D.getY()); BigDecimal cos = new BigDecimal(String.valueOf(Math.cos(four_para[2]))); //计算cos BigDecimal sin = new BigDecimal(String.valueOf(Math.sin(four_para[2]))); //计算sin BigDecimal part1= cos.multiply(oldx); BigDecimal part2= oldy.multiply(sin); BigDecimal part3= part1.subtract(part2); BigDecimal part4= BigDecimal.valueOf(four_para[3]).multiply(part3); BigDecimal x= BigDecimal.valueOf(four_para[0]).add(part4); BigDecimal newX =x.setScale(6,BigDecimal.ROUND_HALF_DOWN); BigDecimal y = BigDecimal.valueOf(four_para[1]).add(BigDecimal.valueOf(four_para[3]).multiply(oldx.multiply(sin).add(oldy.multiply(cos)))); BigDecimal newY = y.setScale(6,BigDecimal.ROUND_HALF_DOWN); System.out.print("newX:"+ newX+"\n"+"newY:"+ newY); } /* 求逆函数 */ //求逆函数 public static RealMatrix inverseMatrix(RealMatrix A) { RealMatrix result = new LUDecomposition(A).getSolver().getInverse(); return result; } /* 打印信息 */ private static void PrintMatrix(RealMatrix first,String part) { double [][] matrix = first.getData(); for(int i = 0 ; i builder.append(matrix[i][j]).append(" + "); } System.out.print(part + builder.toString()+"\n"); } } /* 单位矩阵 */ private static double[][] formUnitMatrix(int dimen) { double [][]temp = new double[dimen][dimen]; for(int i = 0;i if(i==j) temp[i][j]=1; else temp[i][j]=0; } } return temp; } private static void checkRegerx() { String test = "dz_2dc78"; String regex = "(\\d+)"; //匹配数字 Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(test); while (matcher.find()){ int temp = Integer.valueOf(matcher.group(1))+1; System.out.println( temp); test = test.replace(matcher.group(),String.valueOf(temp)); System.out.println( test); } } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有