java - 将图像上的两个点映射到另一个点

标签 java javafx geometry javafx-8

我试图将一个图像上的两个点映射到原始图像上的两个点,所以我将工作分为三个主要操作,首先缩放 n 旋转,然后在所有内容之后进行平移,但无法正确定位它们,缩放工作正常和平移如果我不缩放图像,那么旋转也能完美地工作,只有当我围绕自定义点旋转时旋转才能完美地工作,但图像会失真

        Rotate rotation = new Rotate();
        rotation.setPivotX(proj.s2[0]);
        rotation.setPivotY(proj.s2[1]);
        MainView1.getTransforms().add(rotation);
        MainView1.setManaged(false);
        rotation.setAngle(Angle);

original image second image 这是没有自定义旋转的代码

guidebutton.setOnMouseClicked(event->{
        if (!first_rot) {
            proj.f2[0]=Lball.getCenterX();
            proj.f2[1]= Lball.getCenterY();
            proj.f1[0]=Rball.getCenterX();
            proj.f1[1]= Rball.getCenterY();
            MainView.setStyle("-fx-opacity  : 0.0;");
            guidetext.setText("now position them on the second image and click done");
            first_rot=true;
        }else {
            proj.s2[0]=Lball.getCenterX();
            proj.s2[1]= Lball.getCenterY();
            proj.s1[0]=Rball.getCenterX();
            proj.s1[1]= Rball.getCenterY();
            //fixing the image first then fixing the points
            // fixing the image
            //adjusting the scale 
            double f[]=tranformations.dis_vec_d(proj.f1, proj.f2);//get the distance between the two points on the first image
            double s[]=tranformations.dis_vec_d(proj.s1, proj.s2);//get the distance between the two points on the secondimage
            double facx=f[0]/s[0];//factor of scale in x direction
            double facy=f[1]/s[1];//factor of scale in y direction
            //getting the position of second image inside the window
            Bounds bounds = MainView1.getBoundsInLocal();
            Bounds screenBounds = MainView1.localToScreen(bounds);
            double x = screenBounds.getMinX();
            double y =  screenBounds.getMinY();

           MainView1.setScaleX(facx);
           // get the new position of image after scaling to adjust the position

            bounds = MainView1.getBoundsInLocal();
            screenBounds = MainView1.localToScreen(bounds);
            double nx = screenBounds.getMinX();
            double ny =  screenBounds.getMinY();
            double nmx = screenBounds.getMaxX()-nx;
            double nmy =  screenBounds.getMaxY()-ny;
            MainView1.setTranslateX(x-nx);
            MainView1.setTranslateY(y-ny);
            double[]orig={nmx/2,nmy/2};


            //adjusting rotation
              //calculating the angle between the two line to adjust the rotation
            double Angle=tranformations.angle_d(proj.s1, proj.s2);
            Angle-=tranformations.angle_d(proj.f1, proj.f2);
            //Add the Rotate to the ImageView's Transforms
            MainView1.setRotate(Angle);
            MainView1.setTranslateX(MainView.getTranslateX()+proj.f2[0]-proj.s2[0]);
            MainView1.setTranslateY(MainView.getTranslateY()+proj.f2[1]-proj.s2[1]);

        }
    });

非托管组中的 View 和点都“绘制”当我完成所有工作时它会下降当我在第二张图像上定位点时使用缩放 我使用此代码使用鼠标滚轮进行缩放

    final double SCALE_DELTA = 1.1;
    draw.setOnScroll(event->{
        event.consume();

        if (event.getDeltaY() == 0) {
          return;
        }

        double scaleFactor =(event.getDeltaY() > 0)? SCALE_DELTA: 1/SCALE_DELTA;

        draw.setScaleX(draw.getScaleX() * scaleFactor);
        draw.setScaleY(draw.getScaleY() * scaleFactor);

    });

编辑以解释更多问题我有这两张单独的图像,我使用灯上的两个红点将它们正确定位在彼此之上,以便它们可以形成新图像完整图像 top bottom image

complete image

最佳答案

首先使用平移对齐其中一个点,然后使用对齐点的坐标作为轴心进行缩放,最后使用相同的轴心点执行旋转对齐其他点。

以下示例使用每个包含 2 个圆圈的组,但它应该足够简单,可以将 centerX/centerY 替换为点的图像坐标:

@Override
public void start(Stage primaryStage) throws Exception {
    // create group containing scene that remains in place
    Circle target1 = new Circle(100, 200, 20, Color.RED);
    Circle target2 = new Circle(150, 100, 20, Color.RED);
    Group targetGroup = new Group(target1, target2);

    // create group that will be transformed
    Circle c1 = new Circle(30, 30, 20, Color.BLUE);
    Circle c2 = new Circle(400, 400, 20, Color.BLUE);
    Group g = new Group(c1, c2);

    Scene scene = new Scene(new Pane(targetGroup, g), 500, 500);

    // register handler for swapping between transformed/untransformed scene on button click
    scene.setOnMouseClicked(new EventHandler<MouseEvent>() {

        boolean transformed;
        final Translate translate = new Translate();
        final Scale scale = new Scale();
        final Rotate rotate = new Rotate();

        {
            // add transforms to transformation target            
            g.getTransforms().addAll(rotate, scale, translate);
        }

        @Override
        public void handle(MouseEvent event) {
            if (transformed) {
                // reset transforms to identity
                translate.setX(0);
                translate.setY(0);
                scale.setX(1);
                scale.setY(1);
                rotate.setAngle(0);
            } else {
                // align c1 and target1
                translate.setX(target1.getCenterX() - c1.getCenterX());
                translate.setY(target1.getCenterY() - c1.getCenterY());

                // scale
                double scaleFactor = Math.hypot(target1.getCenterX() - target2.getCenterX(), target1.getCenterY() - target2.getCenterY())
                        / Math.hypot(c1.getCenterX() - c2.getCenterX(), c1.getCenterY() - c2.getCenterY());
                scale.setPivotX(target1.getCenterX());
                scale.setPivotY(target1.getCenterY());
                scale.setX(scaleFactor);
                scale.setY(scaleFactor);

                // rotate
                rotate.setPivotX(target1.getCenterX());
                rotate.setPivotY(target1.getCenterY());
                rotate.setAngle(Math.toDegrees(Math.atan2(target2.getCenterY() - target1.getCenterY(), target2.getCenterX() - target1.getCenterX())
                        - Math.atan2(c2.getCenterY() - c1.getCenterY(), c2.getCenterX() - c1.getCenterX())));

            }
            transformed = !transformed;
        }
    });
    primaryStage.setScene(scene);
    primaryStage.show();

}

关于java - 将图像上的两个点映射到另一个点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48886011/

相关文章:

algorithm - 在 C++ 中查找所有对欧几里德距离的更快方法

python - OpenCV霍夫圆变换不起作用

java - 计算沿相对对角线的点偏移

java - 将 spring api 文档附加到 eclipse

java - 在 Eclipse 中将对象实例分配给整数 var

java-8 - 当我在 Ubuntu 上构建 OpenJDK9 时,运行 "configure"并发现大量缺少的依赖项,这有关系吗?

java - 如何在Translate Transition(JavaFX中)中实现碰撞检测?

java - HashMap Java 8 实现

java - Derby 的另一个实例可能已经使用嵌入式数据库启动了数据库

Java(FX) - 只允许 1 个类从单例类调用方法