【问题标题】:Prevent dragged circle from overlapping防止拖动的圆圈重叠
【发布时间】:2017-01-22 17:41:05
【问题描述】:

正如标题中提到的,我有两个 Circle 的第一个是可拖动的,第二个是固定的,我会围绕第二个旋转(拖动)第一个 没有重叠,但我的Circle 反应奇怪,我确定错误来自拖动条件,但我不知道如何解决它,这就是为什么我需要你的帮助,这是一个最小的和可测试代码:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Collision extends Application{

private Pane root = new Pane();
private Scene scene;
private Circle CA = new Circle(20);
private Circle CB = new Circle(20);
private double xOffset = 0;
private double yOffset = 0;

@Override
public void start(Stage stage) throws Exception{

    initCircles();
    scene = new Scene(root,500,500);
    stage.setScene(scene);
    stage.show();

}

private void initCircles(){

    CA.setCenterX(100);
    CA.setCenterY(100);
    CA.setFill(Color.rgb(255, 0, 0,0.2));
    CA.setStroke(Color.BLACK);

    CB.setCenterX(250);
    CB.setCenterY(200); 
    CB.setFill(Color.rgb(255, 0, 0,0.2)); 
    CB.setStroke(Color.BLACK);

    CA.setOnMousePressed(evt->{

        xOffset = CA.getCenterX() - evt.getSceneX();
        yOffset = CA.getCenterY() - evt.getSceneY();

    });

    CA.setOnMouseDragged(evt->{

        //get Scene coordinate from MouseEvent
        drag(evt.getSceneX(),evt.getSceneY()); 

    });

    root.getChildren().addAll(CA,CB);

}

private void drag(double x, double y){

    /* calculate the distance between 
     * the center of the first and the second circle
     */
    double distance = Math.sqrt (Math.pow(CA.getCenterX() - CB.getCenterX(),2) + Math.pow(CA.getCenterY() - CB.getCenterY(),2));

    if (!(distance < (CA.getRadius() + CB.getRadius()))){

        CA.setCenterX(x + xOffset);
        CA.setCenterY(y + yOffset);

    }else{


        /**************THE PROBLEM :Condition to drag************/

        CA.setCenterX(CA.getCenterX() - (CB.getCenterX()-CA.getCenterX()));
        CA.setCenterY(CA.getCenterY() - (CB.getCenterY()-CA.getCenterY()));

        /*What condition must be established for the 
         * circle to behave correctly
         */
        /********************************************************/

    }

}    
public static void main(String[] args) {
    launch(args); 
}

}

这里是一个简短的概述:

注意: 为了我的辩护,我搜索并找到了几个与我接近但没有精确或确切解决方案的主题,其中:

-The circle remains blocked at the time of the collision

-Two circle that push each other

-JavaScript, Difficult to understand and convert to java

感谢您的帮助!

【问题讨论】:

    标签: javafx


    【解决方案1】:

    Point2D 可以解释为 2D 向量,并且具有从中创建新向量的有用方法等。您可以这样做:

    private void drag(double x, double y){
    
        // place drag wants to move circle to:
        Point2D newCenter = new Point2D(x + xOffset, y+yOffset);
    
        // center of fixed circle:
        Point2D fixedCenter = new Point2D(CB.getCenterX(), CB.getCenterY());
    
        // minimum distance between circles:
        double minDistance = CA.getRadius() + CB.getRadius() ;
    
        // if they overlap, adjust newCenter:
        if (newCenter.distance(fixedCenter) < minDistance) {
    
            // vector between fixedCenter and newCenter:
            Point2D newDelta = newCenter.subtract(fixedCenter);
    
            // adjust so that length of delta is distance between two centers:
            Point2D adjustedDelta = newDelta.normalize().multiply(minDistance);
    
            // move newCenter to match adjusted delta:
            newCenter = fixedCenter.add(adjustedDelta);
        }
    
        CA.setCenterX(newCenter.getX());
        CA.setCenterY(newCenter.getY());
    
    }   
    

    显然,您可以在不使用 Point2D 并只进行计算的情况下完成所有这些操作,但我认为 API 调用使代码更易于理解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 2016-07-23
      • 2016-07-16
      • 1970-01-01
      相关资源
      最近更新 更多