/* * Copyright (C) 2011-2015, Peter Abeles. All Rights Reserved. * * This file is part of Geometric Regression Library (GeoRegression). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package georegression.transform.se; import georegression.geometry.GeometryMath_F32; import georegression.struct.point.Point2D_F32; import georegression.struct.point.Point3D_F32; import georegression.struct.point.Vector3D_F32; import georegression.struct.se.Se2_F32; import georegression.struct.se.Se3_F32; import org.ejml.data.DenseMatrix64F; import java.util.List; /** * @author Peter Abeles */ public class SePointOps_F32 { /** * Applies a 2D special euclidean transform to the point and stores the results in another * variable. * * @param se The transform. * @param orig Original point being transformed. Not modified. * @param result Where the results are stored. Can be the same as orig. If null a new * instance is created. Modified. * @return Transformed point. */ public static Point2D_F32 transform( Se2_F32 se, Point2D_F32 orig, Point2D_F32 result ) { if( result == null ) { result = new Point2D_F32(); } final float c = se.getCosineYaw(); final float s = se.getSineYaw(); // copy the values so that no errors happen if orig and result are the same instance float x = orig.x; float y = orig.y; result.x = se.getX() + x * c - y * s; result.y = se.getY() + x * s + y * c; return result; } public static Point2D_F32 transform( Se2_F32 se, float x, float y, Point2D_F32 result ) { if( result == null ) { result = new Point2D_F32(); } final float c = se.getCosineYaw(); final float s = se.getSineYaw(); result.x = se.getX() + x * c - y * s; result.y = se.getY() + x * s + y * c; return result; } public static Point2D_F32 transformReverse( Se2_F32 se, Point2D_F32 orig, Point2D_F32 result ) { if( result == null ) { result = new Point2D_F32(); } final float c = se.getCosineYaw(); final float s = se.getSineYaw(); // copy the values so that no errors happen if orig and result are the same instance float x = orig.x - se.getX(); float y = orig.y - se.getY(); result.x = x * c + y * s; result.y = -x * s + y * c; return result; } /** * Applies a 2D special euclidean transform to an array of points. * * @param se The transform. * @param points Array of points which are to be transformed. Modified. * @param length The number of elements in the array that are to be processed. */ public static void transform( Se2_F32 se, Point2D_F32 points[], int length ) { float tranX = se.getX(); float tranY = se.getY(); final float c = se.getCosineYaw(); final float s = se.getSineYaw(); for( int i = 0; i < length; i++ ) { Point2D_F32 pt = points[i]; float x = pt.x; float y = pt.y; pt.x = tranX + x * c - y * s; pt.y = tranY + x * s + y * c; } } /** * Applies a 2D special euclidean transform to a list of points. * * @param se The transform. * @param points List of points which are to be transformed. Modified. */ public static void transform( Se2_F32 se, List<Point2D_F32> points ) { float tranX = se.getX(); float tranY = se.getY(); final float c = se.getCosineYaw(); final float s = se.getSineYaw(); for( Point2D_F32 pt : points ) { float x = pt.x; float y = pt.y; pt.x = tranX + x * c - y * s; pt.y = tranY + x * s + y * c; } } /** * Applies a 3D special euclidean transform to a list of points. * * @param se The transform. * @param points List of points which are to be transformed. Modified. */ public static void transform( Se3_F32 se, Point3D_F32[] points , int start , int length ) { for (int i = 0; i < length; i++) { Point3D_F32 p = points[i+start]; transform(se,p,p); } } /** * Applies a 3D special euclidean transform to a list of points. * * @param se The transform. * @param points List of points which are to be transformed. Modified. */ public static void transform( Se3_F32 se, List<Point3D_F32> points ) { for( Point3D_F32 p : points ) { transform(se,p,p); } } /** * <p>. * Applies the transform specified by SpecialEuclidean to a point.<br> * <br> * p' = R*p + T * </p> * <p> * Both origPt and tranPt can be the same instance. * </p> * * @param se SpecialEuclidean transform. Not modified. * @param origPt Original coordinate of the point. Not modified. * @param tranPt Storage for transformed coordinate of the point. Point declared if null. Modified. * @return Transformed point. */ public static Point3D_F32 transform( Se3_F32 se, Point3D_F32 origPt, Point3D_F32 tranPt ) { if( tranPt == null ) tranPt = new Point3D_F32(); DenseMatrix64F R = se.getR(); Vector3D_F32 T = se.getT(); GeometryMath_F32.mult( R, origPt, tranPt ); GeometryMath_F32.add( tranPt, T, tranPt ); return tranPt; } /** * <p>. * Applies the transform in the reverse direction<br> * <br> * p = R<sup>T</sup>*(p'-T) * </p> * <p> * Both origPt and tranPt can be the same instance. * </p> * * @param se SpecialEuclidean transform. * @param origPt Original coordinate of the point. * @param tranPt Transformed coordinate of the point. */ public static Point3D_F32 transformReverse( Se3_F32 se, Point3D_F32 origPt, Point3D_F32 tranPt ) { if( tranPt == null ) tranPt = new Point3D_F32(); DenseMatrix64F R = se.getR(); Vector3D_F32 T = se.getT(); GeometryMath_F32.sub( origPt, T, tranPt ); GeometryMath_F32.multTran( R, tranPt, tranPt ); return tranPt; } }