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

时间:2018-02-20 13:07:44

标签: 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]);

        }
    });

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

    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 {{3 }}

bottom image

2 个答案:

答案 0 :(得分:2)

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

以下示例使用每个包含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();

}

答案 1 :(得分:1)

使用复数时,这一点特别简单。

可以编写任意相似变换

Z = a.z + b

其中a的模数是比例因子,a的参数是旋转角度,b是翻译。

通过通常的两点插值公式

可以很容易地从已知的点对获得这些系数
Z = Z0 + (z - z0).(Z1 - Z0)/(z1 - z0)

a = (Z1 - Z0)/(z1 - z0)
b = Z0 - a.z0 

您可以选择使用复杂数据类型,也可以根据实部/虚部重新编写公式。