如何解决使用 Rotate 围绕其中心旋转多边形
我想在转换后在 Polygon 类中跟踪我的点。我在使用 JavaFX 中的 Rotate
类时遇到的问题是通过在 Piece
类中执行以下操作来获取旋转后的点位置:
double x = this.getPoints().get(0) + this.getLocalToParentTransform().getTx()
double y = this.getPoints().get(1) + this.getLocalToParentTransform().getTy()
它使用 Translate
类工作,但是当我旋转时,坐标会随着旋转而旋转,并带有一个奇怪的枢轴点,并且根本不跟随多边形,除非它旋转了 360 度。 Piece
是 Polygon
的子类。
private double originalX;
private double originalY;
private double centerX;
private double centerY;
private void initializePiece(Piece piece,Pane pane,int i) {
piece.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
originalX = event.getSceneX();
originalY = event.getSceneY();
centerX = piece.getCenterX();
centerY = piece.getCenterY();
}
});
piece.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.getButton() == MouseButton.PRIMARY) {
// Position of piece wrt. picked up position
double deltaX = event.getSceneX() - originalX;
double deltaY = event.getSceneY() - originalY;
Translate translate = new Translate();
translate.setX(deltaX);
translate.setY(deltaY);
piece.getTransforms().addAll(translate);
originalX = event.getSceneX();
originalY = event.getSceneY();
}
if (event.getButton() == MouseButton.SECONDARY) {
double deltaY = event.getSceneY() - originalY;
Rotate rotation = new Rotate(deltaY,centerX,centerY);
piece.getTransforms().add(rotation);
originalY = event.getSceneY();
}
}
});
}
这是 Piece
类的片段。
public double getCenterX() {
double avg = 0;
for (int i = 0; i < this.getPoints().size(); i += 2) {
avg += this.getPoints().get(i) + this.getLocalToParentTransform().getTx();
}
avg = avg / (this.getPoints().size() / 2);
return avg;
}
public double getCenterY() {
double avg = 0;
for (int i = 1; i < this.getPoints().size(); i += 2) {
avg += this.getPoints().get(i) + this.getLocalToParentTransform().getTy();
}
avg = avg / (this.getPoints().size() / 2);
return avg;
}
解决方法
所有变换都在局部坐标中应用,因此轴心点应在多边形的局部坐标系中给出,而多边形“不知道”应用于它的变换。 IE。您应该只在多边形自己的坐标系中计算多边形的中心,而不是在其父坐标系中。
鼠标事件的 getX()
和 getY()
方法将给出事件源节点坐标系中的坐标,因此使用这些方法可以使计算相对容易。这是一个简单的例子(我计算了当前鼠标按下和多边形中心之间的角度,然后拖动时角度的变化,而不是仅仅使用 y 坐标;这感觉更自然。)
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class DraggingTransforms extends Application {
public static void main(String[] args) {
Application.launch(args);
}
private double pressX ;
private double pressY ;
private double angle ;
@Override
public void start(Stage stage) throws Exception {
Polygon poly = new Polygon(10,10,50,70,20,40,30,10);
poly.setFill(Color.web("#00b140"));
Pane root = new Pane(poly);
poly.setOnMousePressed(e -> {
pressX = e.getX();
pressY = e.getY();
angle = computeAngle(poly,e);
});
poly.setOnMouseDragged(e -> {
if (e.getButton() == MouseButton.PRIMARY) {
poly.getTransforms().add(new Translate(e.getX() - pressX,e.getY()-pressY));
} else {
double delta = computeAngle(poly,e) - angle;
Rotate rotation = new Rotate(delta,computeCenterX(poly),computeCenterY(poly));
poly.getTransforms().add(rotation);
}
});
Scene scene = new Scene(root,800,800);
stage.setScene(scene);
stage.show();
}
private double computeAngle(Polygon poly,MouseEvent e) {
return new Point2D(computeCenterX(poly),computeCenterY(poly))
.angle(new Point2D(e.getX(),e.getY()));
}
private double computeCenter(int offset,Polygon poly) {
double total = 0 ;
for (int i = offset ; i < poly.getPoints().size(); i+=2) {
total += poly.getPoints().get(i);
}
return total / (poly.getPoints().size() / 2);
}
private double computeCenterX(Polygon poly) {
return computeCenter(0,poly);
}
private double computeCenterY(Polygon poly) {
return computeCenter(1,poly);
}
}
请注意,如果您确实需要将形状中某个点的坐标转换为父坐标系,那么您只需要做的就是,例如
poly.getLocalToParentTransform()
.transform(
poly.getPoints().get(0),poly.getPoints().get(1)
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。