matrix.java
字号:
public static Matrix fromPerspective(double width, double height, double near, double far) { if (width <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", width); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (height <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", height); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (near <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", near); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (far <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", far); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (far <= near) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", far); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } return new Matrix( 2.0 / width, 0.0, 0.0, 0.0, 0.0, (2.0 * near) / height, 0.0, 0.0, 0.0, 0.0, -(far + near) / (far - near), -(2.0 * far * near) / (far - near), 0.0, 0.0, -1.0, 0.0); } public static Matrix fromOrthographic(double width, double height, double near, double far) { if (width <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", width); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (height <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", height); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (near <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", near); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (far <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", far); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (far <= near) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", far); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } return new Matrix( 2.0 / width, 0.0, 0.0, 0.0, 0.0, 2.0 / height, 0.0, 0.0, 0.0, 0.0, -2.0 / (far - near), -(far + near) / (far - near), 0.0, 0.0, 0.0, 1.0); } public static Matrix fromOrthographic2D(double width, double height) { if (width <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", width); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (height <= 0.0) { String msg = Logging.getMessage("generic.ArgumentOutOfRange", height); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } return new Matrix( 2.0 / width, 0.0, 0.0, 0.0, 0.0, 2.0 / height, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0); } /** * Computes a <code>Matrix</code> that will map a aligned 2D grid coordinates to geographic coordinates in degrees. * It is assumed that the destination grid is parallel with lines of latitude and longitude, and has its origin * in the upper left hand corner. * * @param sector the grid sector. * @param imageWidth the grid width. * @param imageHeight the grid height. * * @return <code>Matrix</code> that will map from grid coordinates to geographic coordinates in degrees. * @throws IllegalArgumentException if <code>sector</code> is null, or if either <code>width</code> or * <code>height</code> are less than 1. */ public static Matrix fromImageToGeographic(int imageWidth, int imageHeight, Sector sector) { if (imageWidth < 1 || imageHeight < 1) { String message = Logging.getMessage("generic.InvalidImageSize", imageWidth, imageHeight); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Transform from grid coordinates to geographic coordinates. Since the grid is parallel with lines of latitude // and longitude, this is a simple scale and translation. double sx = sector.getDeltaLonDegrees() / imageWidth; double sy = -sector.getDeltaLatDegrees() / imageHeight; double tx = sector.getMinLongitude().degrees; double ty = sector.getMaxLatitude().degrees; return new Matrix( sx, 0.0, tx, 0.0, 0.0, sy, ty, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0); } public static Matrix fromImageToGeographic(AVList worldFileParams) { if (worldFileParams == null) { String message = Logging.getMessage("nullValue.ParamsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Transform from geographic coordinates to source grid coordinates. Start with the following system of // equations. The values a-f are defined by the world file, which construct and affine transform mapping grid // coordinates to geographic coordinates. We can simply plug these into the upper 3x3 values of our matrix. // // | a b c | | x | | lon | // | d e f | * | y | = | lat | // | 0 0 1 | | 1 | | 1 | Double a = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_X_PIXEL_SIZE); Double d = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_Y_COEFFICIENT); Double b = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_X_COEFFICIENT); Double e = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_Y_PIXEL_SIZE); Double c = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_X_LOCATION); Double f = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_Y_LOCATION); if (a == null || b == null || c == null || d == null || e == null || f == null) { return null; } return new Matrix( a, b, c, 0.0, d, e, f, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0); } public static Matrix fromGeographicToImage(AVList worldFileParams) { if (worldFileParams == null) { String message = Logging.getMessage("nullValue.ParamsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Transform from geographic coordinates to source grid coordinates. Start with the following system of // equations. The values a-f are defined by the world file, which construct and affine transform mapping grid // coordinates to geographic coordinates. We want to find the transform that maps geographic coordinates to // grid coordinates. // // | a b c | | x | | lon | // | d e f | * | y | = | lat | // | 0 0 1 | | 1 | | 1 | // // Expanding the matrix multiplication: // // a*x + b*y + c = lon // d*x + e*y + f = lat // // Then solving for x and y by eliminating variables: // // x0 = d - (e*a)/b // y0 = e - (d*b)/a // (-e/(b*x0))*lon + (1/x0)*lat + (e*c)/(b*x0) - f/x0 = x // (-d/(a*y0))*lon + (1/y0)*lat + (d*c)/(a*y0) - f/y0 = y // // And extracting new the matrix coefficients a'-f': // // a' = -e/(b*x0) // b' = 1/x0 // c' = (e*c)/(b*x0) - f/x0 // d' = -d/(a*y0) // e' = 1/y0 // f' = (d*c)/(a*y0) - f/y0 // // If b==0 and d==0, then we have the equation simplifies to: // // (1/a)*lon + (-c/a) = x // (1/e)*lat + (-f/e) = y // // And and the new matrix coefficients will be: // // a' = 1/a // b' = 0 // c' = -c/a // d' = 0 // e' = 1/e // f' = -f/e Double a = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_X_PIXEL_SIZE); Double d = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_Y_COEFFICIENT); Double b = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_X_COEFFICIENT); Double e = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_Y_PIXEL_SIZE); Double c = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_X_LOCATION); Double f = AVListImpl.getDoubleValue(worldFileParams, WorldFile.WORLD_FILE_Y_LOCATION); if (a == null || b == null || c == null || d == null || e == null || f == null) { return null; } if (b == 0.0 && d == 0.0) { return new Matrix( 1.0/a, 0.0, (-c/a), 0.0, 0.0, 1.0/e, (-f/e), 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0); } else { double x0 = d - (e*a)/b; double ap = -e/(b*x0); double bp = 1.0/x0; double cp = (e*c)/(b*x0) - f/x0; double y0 = e - (d*b)/a; double dp = -d/(a*y0); double ep = 1.0/y0; double fp = (d*c)/(a*y0) - f/y0; return new Matrix( ap, bp, cp, 0.0, dp, ep, fp, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0); } } /** * Computes a <code>Matrix</code> that will map constrained 2D grid coordinates to geographic coordinates in * degrees. The grid is defined by three control points. Each control point maps a location in the source grid to a * geographic location. * * @param imagePoints three control points in the source grid. * @param geoPoints three geographic locations corresponding to each grid control point. * * @return <code>Matrix</code> that will map from geographic coordinates to grid coordinates in degrees. * @throws IllegalArgumentException if either <code>imagePoints</code> or <code>geoPoints</code> is null or * have length less than 3. */ public static Matrix fromImageToGeographic(java.awt.geom.Point2D[] imagePoints, LatLon[] geoPoints) { if (imagePoints == null) { String message = Logging.getMessage("nullValue.ImagePointsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (geoPoints == null) { String message = Logging.getMessage("nullValue.GeoPointsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (imagePoints.length < 3) { String message = Logging.getMessage("generic.ArrayInvalidLength", "imagePoints.length < 3"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (geoPoints.length < 3) { String message = Logging.getMessage("generic.ArrayInvalidLength", "geoPoints.length < 3"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Transform from geographic coordinates to source grid coordinates. Start with the following system of // equations. The values a-f are the unknown coefficients we want to derive, The (lat,lon) and (x,y) // coordinates are constants defined by the caller via geoPoints and imagePoints, respectively. // // | a b c | | x1 x2 x3 | | lon1 lon2 lon3 | // | d e f | * | y1 y2 y3 | = | lat1 lat2 lat3 | // | 0 0 1 | | 1 1 1 | | 1 1 1 | // // Expanding the matrix multiplication: // // a*x1 + b*y1 + c = lon1 // a*x2 + b*y2 + c = lon2 // a*x3 + b*y3 + c = lon3 // d*x1 + e*y1 + f = lat1 // d*x2 + e*y2 + f = lat2 // d*x3 + e*y3 + f = lat3 // // Then solving for a-c, and d-f by repeatedly eliminating variables: // // a0 = (x3-x1) - (x2-x1)*(y3-y1)/(y2-y1) // a = (1/a0) * [(lon3-lon1) - (lon2-lon1)*(y3-y1)/(y2-y1)] // b = (lon2-lon1)/(y2-y1) - a*(x2-x1)/(y2-y1) // c = lon1 - a*x1 - b*y1 // // d0 = (x3-x1) - (x2-x1)*(y3-y1)/(y2-y1) // d = (1/d0) * [(lat3-lat1) - (lat2-lat1)*(y3-y1)/(y2-y1)] // e = (lat2-lat1)/(y2-y1) - d*(x2-x1)/(y2-y1) // f = lat1 - d*x1 - e*y1 double lat1 = geoPoints[0].getLatitude().degrees; double lat2 = geoPoints[1].getLatitude().degrees; double lat3 = geoPoints[2].getLatitude().degrees; double lon1 = geoPoints[0].getLongitude().degrees; double lon2 = geoPoints[1].getLongitude().degrees; double lon3 = geoPoints[2].getLongitude().degrees; double x1 = imagePoints[0].getX(); double x2 = imagePoints[1].getX(); double x3 = imagePoints[2].getX(); double y1 = imagePoints[0].getY(); double y2 = imagePoints[1].getY(); double y3 = imagePoints[2].getY(); double a0 = (x3-x1) - (x2-x1)*(y3-y1)/(y2-y1); double a = (1/a0) * ((lon3-lon1) - (lon2-lon1)*(y3-y1)/(y2-y1)); double b = (lon2-lon1)/(y2-y1) - a*(x2-x1)/(y2-y1); double c = lon1 - a*x1 - b*y1; double d0 = (x3-x1) - (x2-x1)*(y3-y1)/(y2-y1); double d = (1/d0) * ((lat3-lat1) - (lat2-lat1)*(y3-y1)/(y2-y1)); double e = (lat2-lat1)/(y2-y1) - d*(x2-x1)/(y2-y1); double f = lat1 - d*x1 - e*y1; return new Matrix( a, b, c, 0.0, d, e, f, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0); } public static Matrix fromGeographicToImage(java.awt.geom.Point2D[] imagePoints, LatLon[] geoPoints) { if (imagePoints == null) { String message = Logging.getMessage("nullValue.ImagePointsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (geoPoints == null) { String message = Logging.getMessage("nullValue.GeoPointsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (imagePoints.length < 3) { String message = Logging.getMessage("generic.ArrayInvalidLength", "imagePoints.length < 3"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (geoPoints.length < 3) { String message = Logging.getMessage("generic.ArrayInvalidLength", "geoPoints.length < 3"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Transform from geographic coordinates to source grid coordinates. Start with the following system of // equations. The values a-f are the unknown coefficients we want to derive, The (lat,lon) and (x,y) // coordinates are constants defined by the caller via geoPoints and imagePoints, respectively. // // | a b c | | lon1 lon2 lon3 | | x1 x2 x3 | // | d e f | * | lat1 lat2 lat3 | = | y1 y2 y3 | // | 0 0 1 | | 1 1 1 | | 1 1 1 | // // Expanding the matrix multiplication: // // a*lon1 + b*lat1 + c = x1 // a*lon2 + b*lat2 + c = x2 // a*lon3 + b*lat3 + c = x3 // d*lon1 + e*lat1 + f = y1 // d*lon2 + e*lat2 + f = y2 // d*lon3 + e*lat3 + f = y3 // // Then solving for a-c, and d-f by repeatedly eliminating variables: // // a0 = (lon3-lon1) - (lon2-lon1)*(lat3-lat1)/(lat2-lat1) // a = (1/a0) * [(x3-x1) - (x2-x1)*(lat3-lat1)/(lat2-lat1)]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -