简体   繁体   English

Java:AffineTransform旋转多边形,然后获取其点

[英]Java: AffineTransform rotate Polygon, then get its points

I'd like to draw a Polygon and rotate it with AffineTransform like so. 我想绘制一个多边形,并使用AffineTransform旋转它。

float theta = 90;
Polygon p = new Polygon(new int[]{0, 4, 4, 0}, new int[]{0, 0, 4, 4}, 4);
AffineTransform transform = new AffineTransform();
transform.rotate(Math.toRadians(theta), p.xpoints[0], p.ypoints[0]);
Shape transformed = transform.createTransformedShape(p);
g2.fill(transformed);

However, then I'd like to be able to access the points (transformed.xpoints[0]) in the same way I did as a Polygon. 但是,我希望能够以与多边形相同的方式访问这些点(transformed.xpoints [0])。 One way to look at this would be transforming the Shape into a Polygon--but as far as I know this isn't possible. 一种解决方法是将Shape转换为Polygon,但据我所知这是不可能的。

What's the best option? 最好的选择是什么?

As a sidenote: this is an exercise in creating a fractal tree made of 4-sided Polygons (rectangles). 附带说明:这是创建由4边多边形(矩形)组成的分形树的练习。 I've chosen to use Polygons in order to anchor branches to the top left and top right points, respectively. 我选择使用“多边形”以便分别将分支锚定到左上角和右上角。 If this is needlessly complicated, let me know. 如果这不必要地复杂,请告诉我。

You can use the AffineTransform to transform the individual points as well, like so: 您也可以使用AffineTransform转换单个点,如下所示:

Point2D[] srcPoints = new Point2D[] { new Point(0, 0), new Point(4, 0), new Point(4, 4), new Point(4, 0) };
Point2D[] destPoints = new Point2D[4];
transform.transform(srcPoints, 0, destPoints, 0, 4);

The resulting destPoints array then looks like this: 生成的destPoints数组如下所示:

[Point2D.Float[-0.0, 0.0], Point2D.Float[-0.0, 4.0], Point2D.Float[-4.0, 4.0], Point2D.Float[-0.0, 4.0]]

You can get the coordinates form the path returned by createTransformedShape(...) . 您可以从createTransformedShape(...)返回的路径中获取坐标。

Path2D.Double transformed = (Path2D.Double) transform.createTransformedShape(p);

List<Double> xpointsList = new ArrayList<>();
List<Double> ypointsList = new ArrayList<>();
PathIterator pi = transformed.getPathIterator(null);

while(!pi.isDone()){
    double[] coords = new double[6];
    int type = pi.currentSegment(coords);
    if(type == PathIterator.SEG_MOVETO || type == PathIterator.SEG_LINETO){ // The only types we're interested in given the original shape
        xpointsList.add(coords[0]);
        ypointsList.add(coords[1]);
    }
    pi.next();
}

I haven't done this in a while, there may be an easier way to achieve what you want. 我已经有一段时间没有这样做了,可能有一种更简单的方法来实现您想要的。 Also, the casting to Path2D.Double is not ideal. 另外,对Path2D.Double的转换也不理想。

Its been a while, but I couldn't resist putting this here for those who will have this issue later on. 已经有一段时间了,但是对于那些以后会遇到此问题的人,我忍不住把它放在这里。

So how about we just use a teenie-weenie bit of math instead of AffineTransform? 那么,我们只使用小数位数而不是AffineTransform怎么样?

public class ROTOR {

/**
 * Method for rotating a Point object in the XY plane or in any plane
 * parallel to the XY plane. The Point object to be rotated and the one
 * about which it is rotating must have the same Z coordinates.
 *
 * @param p a Point object in the xy plane The z coordinates of both Point
 * objects must be either the same or must both be zero.
 * @param cen a Point object about which the rotation of the first Point
 * object will occur.
 * @param angle the angle of rotation
 * @return
 */
     public static Point planarXYRotate(Point p,Point cen,double angle){

    double sin = Math.sin(angle);
    double cos = Math.cos(angle);
    double X = p.x*cos-p.y*sin+cen.x*(1-cos)+cen.y*sin;
    double Y = p.x*sin+p.y*cos+cen.y*(1-cos)-cen.x*sin;
    return new Point( (int) X, (int) Y );


    }//end method



/**
 * 
 * @param polygon The polygon to rotate
 * @param origin The point about which to rotate it.
 * @param angle The angle of rotation.
 * @return a new Polygon rotated through the specified angle and about the said point.
 */
public static Polygon rotate(Polygon polygon , Point origin , double angle){

    Point cen = new Point(origin.x , origin.y);
    Polygon newPolygon = new Polygon();

    for(int i=0;i<polygon.npoints;i++){
        Point p = new Point( polygon.xpoints[i] , polygon.ypoints[i] );
        Point point = ROTOR.planarXYRotate(p, cen, angle);
        newPolygon.addPoint((int) point.x, (int) point.y);

    }

    return newPolygon;
}

}

You may then easily obtain your rotated polygon and get its points as you wish, using: 然后,您可以使用以下方法轻松获取旋转的多边形并获取所需的点:

Polygon rotatedPolygon = ROTOR.rotate(polygon, origin, angle);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM