Gerade schneidet Kreis

outregs

Grünschnabel
Hallo,
hab ein kleines Programm gebastelt, in dem der Schnittpunkt zwischen einer Geraden und einem Kreis dargestellt werden soll.

Gerade: bestimmt durch Kreismittelpunkt und Mauszeiger

Problem: die Determinante bei der Schnittpunktberechnung kann < 0 werden, obwohl die Gerade den Kreis immer schneidet!

Code:
    public void mouseMoved(MouseEvent me) {
        int mousePosX = me.getX();
        int mousePosY = me.getY();
        
        this.intersection.setMousePos(mousePosX, mousePosY);
        
        int intersectionY = 0;
        int intersectionX = 0;

        if(mousePosY >= Settings.kreismittelpunktY){
            intersectionY = Settings.kreismittelpunktY;
            if(mousePosX < Settings.kreismittelpunktX){
                intersectionX = Settings.kreismittelpunktX - Settings.radius;
            }else{
                intersectionX = Settings.kreismittelpunktX + Settings.radius;
            }
        }else if(mousePosX - Settings.kreismittelpunktX == 0){
            intersectionX = Settings.kreismittelpunktX;
            intersectionY = Settings.kreismittelpunktY - Settings.radius;
        } else {
   // eigentliche Schnittpunktberechnung
            // Gerade: y = g_m * x + g_b             Kreis: (x - xm)^2 + (y - ym)^2 = r^2
            double g_m = (mousePosY - Settings.kreismittelpunktY)
                    / (mousePosX - Settings.kreismittelpunktX);
            double g_b = mousePosY - (g_m * mousePosX);

            double a = 1 + Math.pow(g_m, 2.0);
            double b = (2.0 * g_m * g_b)
                    - (2.0 * g_m * Settings.kreismittelpunktY)
                    - (2.0 * Settings.kreismittelpunktX);
            double c = Math.pow(g_b, 2.0)
                    - (2.0 * g_b * Settings.kreismittelpunktY)
                    + Math.pow(Settings.kreismittelpunktY, 2.0)
                    - Math.pow(Settings.radius, 2.0)
                    + Math.pow(Settings.kreismittelpunktX, 2.0);
            
            System.out.println(" Determinante:"+Math.sqrt(Math.pow(b, 2.0)- (4 * a * c)));

            // Schnittpunkt:   nur den SP in der oberen Kreishälfte anzeigen
            if (mousePosX < Settings.kreismittelpunktX) {
                intersectionX = (int) Math.min(((b * (-1) - Math.sqrt(Math.pow(
                        b, 2.0)
                        - (4 * a * c))) / (2 * a)), ((b * (-1) + Math.sqrt(Math
                        .pow(b, 2.0)
                        - (4 * a * c))) / (2 * a)));
            } else if (mousePosX > Settings.kreismittelpunktX) {
                intersectionX = (int) Math.max(((b * (-1) - Math.sqrt(Math.pow(
                        b, 2.0)
                        - (4 * a * c))) / (2 * a)), ((b * (-1) + Math.sqrt(Math
                        .pow(b, 2.0)
                        - (4 * a * c))) / (2 * a)));
            }
            // r^2 - (x - kreismittelpunktX)^2
            double circlePart = Math.pow(Settings.radius, 2.0)
                    - Math.pow((kreismittelpunktX - Settings.kreismittelpunktX), 2.0);
            intersectionY = (int) Math.min((Settings.kreismittelpunktY + Math
                    .sqrt(circlePart)), (Settings.kreismittelpunktY - Math
                    .sqrt(circlePart)));
        }
        
        System.out.println(" x:"+intersectionX+" y:"+intersectionY);
        this.intersection.setIntersectionPos(intersectionX, intersectionY);
    }
außerdem sind die berechneten Schnittpunkte fast nie identisch mit der eigentlichen Geraden und dem Kreis. ? Rundungsfehler ?
 
Zuletzt bearbeitet:
ok, habs doch noch selbst rausgefunden:

ich musste alle Integerwerte in Doublewerte umwandeln...
Code:
int kreisXint = this.gui.getKreisX();
        int kreisYint = this.gui.getKreisY();
        int radiusint = this.gui.getRadius();
        int mouseXint = this.gui.getMousePosX();
        int mouseYint = this.gui.getMousePosY();
        
        double kreisX = Double.valueOf(Integer.toString(kreisXint));
        double kreisY = Double.valueOf(Integer.toString(kreisYint));
        double radius = Double.valueOf(Integer.toString(radiusint));
        double mouseX = Double.valueOf(Integer.toString(mouseXint));
        double mouseY = Double.valueOf(Integer.toString(mouseYint));

geht das auch einfacher ? ich hab die Vermutung, dass mir das noch öfter passiert, wie umgeh ich solche Fehler ?

vollständiger Code:
Code:
public class Schnittpunkte extends JPanel implements MouseMotionListener{
	
	private Gui gui = new Gui();

	public Schnittpunkte(){
		this.add(gui);
		this.addMouseMotionListener(this);
	}

	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void mouseMoved(MouseEvent me) {
		this.gui.setMousePos(me.getX(), me.getY());
		
		calculateIntersection();
		this.gui.repaint();
	}
	
	private void calculateIntersection(){
		int kreisXint = this.gui.getKreisX();
		int kreisYint = this.gui.getKreisY();
		int radiusint = this.gui.getRadius();
		int mouseXint = this.gui.getMousePosX();
		int mouseYint = this.gui.getMousePosY();
		
		double kreisX = Double.valueOf(Integer.toString(kreisXint));
		double kreisY = Double.valueOf(Integer.toString(kreisYint));
		double radius = Double.valueOf(Integer.toString(radiusint));
		double mouseX = Double.valueOf(Integer.toString(mouseXint));
		double mouseY = Double.valueOf(Integer.toString(mouseYint));
		
		// es gibt immer 2 Schnittpunkte
		double schnittX1 = 0.0;
		double schnittY1 = 0.0;
		double schnittX2 = 0.0;
		double schnittY2 = 0.0;
		
		// Steigung g_m
		double g_m = 0.0;
		if(mouseX - kreisX == 0){
			g_m = 1f;
		}else{
			g_m = (mouseY - kreisY) / (mouseX - kreisX);
		}
		// g_b aus Geradengleichung y = m*x + b
		double g_b = kreisY - (g_m * kreisX);
		
		// gleichsetzen mit Kreisgleichung: m*x + b = yK + sqrt(r^2 - (x - xK)^2
		// a, b, c der MNF: x^2 * (1 + m^2) + x * (2*m*b - 2*m*yK - 2*xK) + b^2 - 2*b*yK + yK^2 - r^2 + xK^2 = 0
		double a = 1 + (g_m * g_m);
		double b = (2 * g_m * g_b) - (2 * g_m * kreisY) - (2 * kreisX);
		double c = (g_b * g_b) - (2 * g_b * kreisY) + (kreisY * kreisY) - (radius * radius) + (kreisX * kreisX);
		
		// MNF der Schnittpunkte 1 und 2
		schnittX1 = (-b + Math.sqrt((b*b) - (4*a*c))) / (2*a);
		schnittX2 = (-b - Math.sqrt((b*b) - (4*a*c))) / (2*a);
		
		schnittY1 = (g_m * schnittX1) + g_b;
		schnittY2 = (g_m * schnittX2) + g_b;
		
		this.gui.setIntersection1Pos((int)schnittX1, (int)schnittY1);
		this.gui.setIntersection2Pos((int)schnittX2, (int)schnittY2);
		
	}
}
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück