Punkt auf Geometrie

Status
Nicht offen für weitere Antworten.
X

xtreme

Gast
Hi ihrs,

wollt mal fragen, ob es außer der Möglichkeit mit contains() zu ermitteln, ob ein Punkt in einer Geometrie liegt, auch eine Möglichkeit gibt zu ermitteln, ob ein Punkt genau auf einer Geometrie liegt, also sowas wie hit().

Denn per Mausklick kann ich zwar mit contains() eine Ellipse oder ein Rechteck markieren, wenn der Punkt darin liegt, aber das muss ja auch irgendwie mit einer Linie zu machen sein. Denn letztendlich will ich die auch markieren und später einmal verschieben oder verändern können.

Danke für Tipps
 

Marco13

Top Contributor
Ob es die in der API vorgefertigt gibt, kannst du selbst nachsehen. Aber wenn nicht: Falls es immer um ein "Shape" oder einen GeneralPath geht, kann man den Pfad natürlich langlaufen, und den Abstand des Punktes zu jedem Liniensegment bestimmen. Wenn der ungefähr 0 ist, hat man die Linie getroffen.
 
X

xtreme

Gast
Falls es immer um ein "Shape" oder einen GeneralPath geht, kann man den Pfad natürlich langlaufen, und den Abstand des Punktes zu jedem Liniensegment bestimmen. Wenn der ungefähr 0 ist, hat man die Linie getroffen.

Mhm aber bei einer Linie liefert doch auch der PathIterator nicht alle Linienpunkte sondern nur Anfangs- und Endpunkt oder?

Code:
Line2D.Double shape = new Line2D.Double(xPoints, yPoints);
		
PathIterator itr = shape.getPathIterator(new AffineTransform());
		
double[] coords = new double[2];
		
while(!itr.isDone()){
	itr.currentSegment(coords);
	System.out.println(coords[0] + ", " + coords[1]);
	itr.next();
}

Will ich nun prüfen, ob der übergebene Punkt drauf liegt, sieht das Ganze so aus:

public boolean Hit(Point pt)
{
boolean hit = false;

PathIterator itr = super.getPath().getPathIterator(new AffineTransform());

double[] coords = new double[2];

while(!itr.isDone()){
itr.currentSegment(coords);
System.out.println(coords[0] + ", " + coords[1]);
if(coords[0] == pt.x && coords[1] == pt.y)
{
hit = true;
break;
}
itr.next();
}

return hit;
}

Das geht allerdings nur bedingt. Denn nur wenn ich auf den ersten und letzten Punkt der Linie klicke, bekomme ich eine TRUE zurück. In coords[0] und coords[1] liegen doch jeweils x und y im jeweiligen Schleifendurchlauf oder nicht? Wie muss ich es sonst anstellen?
 
X

xtreme

Gast
Hi,

danke erstmal für deine Tipps. Irgendwie verhält sich das aber sehr komisch bei mir.

Ich versuche eine Linie zu markieren und sie dann zu bewegen. Bilde ich aus dem Path ein Rechteck, kann ich die Line jederzeit anfassen. Versuche ich es über die ptLineDist kann ich die Line einmal anfassen. Danach geht es nur noch, wenn ich die Linie am unteren Ende anfasse.

Hier mal mein Code:

Code:
    public boolean Hit(Point pt)
    {
        Rectangle rec = super.getPathBounds();
        rec.x -= getPenWidth() + 5;
        rec.y -= getPenWidth() + 5;
        rec.width += 2 * (getPenWidth() + 5);
        rec.height += 2 * (getPenWidth() + 5);

        return rec.contains(pt);
    }

oder eben

Code:
    public boolean Hit(Point pt)
    {        
        Line2D.Double myLine = new Line2D.Double(super.getStart(), super.getEnd());
        int dist = (int)myLine.ptLineDist(pt);
        
        if(dist < 5)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 

Marco13

Top Contributor
Was auch immer "super" im zweiten Fall ist: Diese Linie muss man natürlich nicht nur für EIN Liniensegment des Paths erstellen, sondern für alle Segmente ... also wie du vorher schon angedeutet hattest, mit einem PathIterator durchgehen und jeweils eine Line2D für den vorherigen und den aktuellen Punkt erstellen.
 
X

xtreme

Gast
getStart() und getEnd() stehen für den Start- und Endpunkt der Linie, die ich in einer übergeordneten Klasse (deswegen super) als Member führe. Demnach brauche ich aus dem Path keine Linie für einzelne Segmente bilden, sondern kann die komplette Linie von Anfang bis Ende mit meinen beiden Punkten neubilden.

Aber wie gesagt, so ganz funktioniert es nicht.
 

Marco13

Top Contributor
???:L Wenn man einen Path hat, der die form von einem "U" hat, dann bringt es nichts, wenn man die Linie zwischen dem Start- und dem Endpunkt betrachtet - dort "ist" ja keine linie. Man muss schon die einzelnen Segmente durchgehen.... ???:L
 
X

xtreme

Gast
Versteh ich nicht wirklich.

Ich habe einen Path. Dieser Path ist eine Linie!!! Diese Linie bilde ich aus zwei Punkten. Nun möchte ich schauen, ob ein Mausklick auf eben dieser Linie liegt.

OK man kann den Umweg über den Path vergessen. Nehmen wir einfach an, wir haben eine Linie (keinen Path). Dann habe ich das obige Problem aber immer noch. Ich checke ob mein Punkt in einer bestimmten Distanz zu meiner Linie liegt. Wenn er diese Distanz oder darunter einhält, dann soll diese Linie markiert werden (wie diese Markierung läuft, sei mal egal).

Aber leider kann ich über dtLineDist nur einmal die Distanz abfragen, danach funktioniert es nicht mehr. Aber warum?

Sorry wenns vorher ein wenig unverständlich war, hoffe hiermit gehts besser.
 

Marco13

Top Contributor
Ein Path ist aber im Allgemeinen MEHR als eine Linie. Wenn er nur eine Linie ist, kann man auch gleich Line verwenden. However - kannst du ein compilierbares Codestück posten, wo das Problem auftritt?
 
X

xtreme

Gast
Wie du möchtest. Ist ein wenig lang, aber ich habe schon das meiste herausgenommen bzw. eine kleine Testapi geschrieben. Das Packet habe ich testpaint genannt und die Hauptklasse heißt Main. Achtung: Ich habe alles in eine Datei geschoben und mir daher keine Gedanken über die Übergabe von Parametern gemacht, sondern diese mehr oder wenig auch global benutzt.

Das Problem taucht auch hier auf. Ich kann die Linie einmal verschieben, danach ist sie nur noch verschiebbar, wenn man den unteren linken Punkt geklickt hält.

Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package testpaint;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

/**
 *
 * @author Administrator
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
      DrawingSurface m = new DrawingSurface();
      m.setSize(500, 500);
      m.setLocation(0, 0);
      m.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      m.setVisible(true);
    }

}


class DrawingSurface extends JFrame implements MouseMotionListener, MouseListener
{
   private PaintingComponent paintingComponent = new PaintingComponent(this);
   
   MyLine _geo = new MyLine(new Point(10,10), new Point(100,100));
   
   //Selektiertes Object
   Geometry _selectedGeometry = null;
   
   //Mausposition der Selektion
   private Point _lastMouseLocation;

   public DrawingSurface() {
        getContentPane().add(paintingComponent);
        getContentPane().addMouseMotionListener(this);
        getContentPane().addMouseListener(this);   
   }
   
   public void redraw()
   {
       paintingComponent.repaint();
   }


   
   public void mousePressed(MouseEvent e) {
        //Bei linkem Mausklick wird das Fenster aktiviert und...
        if (this.contains(e.getPoint()) && !e.isMetaDown())
        {
            if (_geo.Hit(e.getPoint()))
            {
                _selectedGeometry = _geo;

                _lastMouseLocation = e.getPoint();
            }
        }
    }
   
   public void mouseDragged(MouseEvent e) {
        if(!e.isMetaDown() && _selectedGeometry != null)
        {
            _selectedGeometry.Move(e.getPoint().x - _lastMouseLocation.x, e.getPoint().y - _lastMouseLocation.y);

            _lastMouseLocation = e.getPoint();

            this.redraw();
        }
    }
   
    public void mouseReleased(MouseEvent e) {
        _selectedGeometry = null;
    }

    public void mouseMoved(MouseEvent e) {
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }
}



class Geometry {
    
    Point _start;
    Point _end;
            
    Path2D.Double _path = new Path2D.Double();
    
    public Geometry(Point start, Point end){
        _start = start;
        _end = end;
    }
    
    public void Move(int deltaX, int deltaY)
    {

        AffineTransform at = new AffineTransform(); 
        at.translate(deltaX, deltaY);
        _path.transform(at);

        //Setzen der neuen Start- und Endpunkte
        _start.x += deltaX;
        _start.x += deltaY;

        _end.x += deltaX;
        _end.y += deltaY;
    }
    
    //Methode zum Zeichnen des Pfades und ggf. des Rahmens
    public void draw(Graphics g)
    {
        Graphics2D g2d = (Graphics2D)g;

        g2d.setColor(Color.black);
        g2d.setStroke(new BasicStroke(1));
        g2d.draw(_path);
    }
    
    public boolean Hit(Point pt)
    {
        return false;
    }
    
    //Methode zum Hinzufügen der Geometry zum Path
    protected void AddToPath() 
    {           
        //Default
        _path = new Path2D.Double(new Line2D.Double(_start, _end));
    }
}


class MyLine extends Geometry{
    public MyLine(Point start, Point end){
        super(start, end);
        AddToPath();
    }
    
    @Override
    public boolean Hit(Point pt)
    {   
        Line2D.Double myLine = new Line2D.Double(super._start, super._end);
        int dist = (int)myLine.ptLineDist(pt);
        
        if(dist < 5)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    @Override protected void AddToPath()
    {
        super._path.append(new Line2D.Double(super._start, super._end), true);
    }
}


class PaintingComponent extends JComponent
{
    private DrawingSurface _surface;
    
    public PaintingComponent(DrawingSurface surface)
    {
        _surface = surface;
    }
    
   public void paintComponent(Graphics g){
       super.paintComponents(g);
       _surface._geo.draw(g);
   }
}
 

Marco13

Top Contributor
Der Code ist als KSKB perfekt: Rauskopieren, in TextPad einfügen, Compilieren, Starten. Kein Zusammenkopieren einzelner Dateien, kein Aufräumen von imports, kein Hinzufügen einer main - so sollten alle KSKBs sein.

Und dann findet man auch schnell eine Lösung.
Code:
class MyLine extends Geometry
{
...
    public void draw(Graphics g)
    {
        super.draw(g);
        g.setColor(Color.RED);
        g.fillOval(super._start.x-2, super._start.y-2, 4,4);
        g.fillOval(super._end.x-2, super._end.y-2, 4,4);
    }
}

Einfügen, starten, Linie verschieben, kurz irritiert gucken, Fehler finden :wink:

(Das mit dem Path und so sieht etwas merkwürdig aus ... aber du wirst schon wissen, was du tust...)
 
X

xtreme

Gast
Oh man, DANKE!

Den Fehler muss man erstmal in seinem im Originial etwas fetteren Code finden!

Aber cool, nun gehts.
 

Loonatic

Mitglied
Hallo zusamen, hab vollgendes Problem ich brauch eine gängige Formel um die Schnittpunkte von einem Kreis und einer Geraden zu bestimmen. Hab schon eineige Formeln gesehen aber leider kann ich nichts mie ihenen anfangen würde mich sehr freuen wenn da jemand was parat hat...

Danke im Vorraus.

mfg Loonatic
 

Marco13

Top Contributor
Schau mal unter Geometric Tools: Intersection "Intersection of lines, rays, or line segments with circles or arcs (2D).". Da gibt's ein PDF, kannst mal schauen was drinsteht, und im Zweifelsfall gibt's auch gleich den Code, den man i.a. mit relativ wenig Aufwand nach Java portieren kann.
 

Loonatic

Mitglied
Hey geil auf den ersten Bilck sieht es richtig gut aus muss allerdings noch die Sachen genauer durchsehen aber ich denk mal damit kann ich sicher was anfangen

Danke nochmal

mfg Loonati
 

Loonatic

Mitglied
Hallo zusammen hoffe das untereuch jemand ist der mir vielleicht helfen kann.

Ich hab ein 2d Grid mit 10 mal 10 zellen. In diese Zellen werden nun Kreisflächen mit random eingefügt. jetzt brauch ich einen Algorithmus der mir anhand der Kreisfläche sagen kann welche Zellen der Kreis berührt also auch die Zellen die von der Ausenkande geschnitten werden und die Zellen die komplett im Kreis liegen.

Ich komm da sowas wie von nicht weiter und hoffe jemand kann mir dabei helfen.

Wäre zu tiefst dankbar.

mfg Loonatic???:L
 

Marco13

Top Contributor
Schau mal unter Geometric Tools: Intersection "Intersection of lines, rays, or line segments with circles or arcs (2D).". Da gibt's ein PDF, kannst mal schauen was drinsteht, und im Zweifelsfall gibt's auch gleich den Code, den man i.a. mit relativ wenig Aufwand nach Java portieren kann.
 

Marco13

Top Contributor
Ja, sollte nur ein Wink sein. Bei einem regelmäßigen Gitter braucht man ja gar nicht so aufwändig rumzurechnen. Da reicht es schon, wenn man schaut, ob die Entfernung des Mittelpunktes des Kreises zu irgendeiner Linie größer oder kleiner ist als der Radius....
 

Loonatic

Mitglied
Ja klar das dachte ich mir auch schon aber was wenn der Radius über 3 Zellen geht. und was machste mit den Zellen die schräg über oder unter der Zelle sind in der sich der Punkt befindet. Bin auf etwas gestoßen das vielleicht helfen könnte. wollte mal eure meinung hören und vorallem einige vorschlage zur syntax da ich java nicht behersche es aber in java machen muss.

also der Punkt A liegt in einer Zelle Punkt B Zellkoordinate wie komm ich am besten auf B??

Dann wollte ich den Vektor BA bestimmen in demfall u dann den Vektor AC also v

v ist aber mein radius der ist bei mir fest definiert mit 5

aus Vektor u und v kann ich w bestimmen und dann soll der Vektor v als Zeiger um den Punkt A rotieren und mir alle Wetre ausgeben.
 

Marco13

Top Contributor
Wenn das eine Aufgabe ist, gibt es doch bestimmt eine Aufgabenbeschreibung, die so präzise ist, dass auch ein normaler Informatiker was damit anfangen kann?
 

Loonatic

Mitglied
es ist eine teilaufgabe von einer großen. Ich muss datenstrukturen vergleichen
und zu den strukturen die ich vergleichen muss gehört eine ArrayListe dann ein 1D Grid also mehrere Zellen in X richtung und dann noch das 2D grid also in X und X richtung das sind schon mal 3 strukturen. bei allen wird eben diese Punktwolke eingeführt und dann muss eine Nachbarschaftssuche statt finden.

So, um zeit zu sparen und nicht Zelle für Zelle auf Punkte indefall Kreise weil ich ja noch einen Radius habe, zu überprüfen wird ein Kreis in einer Zelle genommen und durch den Radius geschaut welche umliegenden Zellen Berührt werden und welche Zellen im Kreis liegen. Dann such ich genau in diesen Zellen nach dem nächsten Kreisnachbar. So wird garantiert das die Suche nicht wirder über alle Zellen geht sondern nur über die die von einem Kreis berührt sind.

Ich hoffe es ist jetzt bisschen klarer geworden. Naja ich muss da einfach mal warten bis mein Betreuer wieder da is der kann mir sicher weiter helfen, dachte ich würde es auch ohne ihn hinbekommen. :autsch:
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Punkt von MouseListener hat falsche Koordinate AWT, Swing, JavaFX & SWT 2
P Abwächselnd ein Punkt und ein x anzeigen AWT, Swing, JavaFX & SWT 2
L 2D-Grafik Frage zu Ellipse2D.Double, Abfrage, ob Punkt enthalten ist funktioniert nicht AWT, Swing, JavaFX & SWT 3
J Rectangle g.fillRec() X/Y Punkt AWT, Swing, JavaFX & SWT 5
S Punkt finden der in einem Shape liegt..? AWT, Swing, JavaFX & SWT 11
K 2D-Grafik Punkt in Eclipse AWT, Swing, JavaFX & SWT 4
S Bild von Punkt zu Punkt zeichnen AWT, Swing, JavaFX & SWT 8
B 3D-Grafik Punkt in JAVA3D darstellen AWT, Swing, JavaFX & SWT 2
L Swing struktur und nahester Punkt AWT, Swing, JavaFX & SWT 4
J Punkt-genaue Positionierung von SWT-Komponenten AWT, Swing, JavaFX & SWT 10
T JComboBox Komma in Punkt umwandeln AWT, Swing, JavaFX & SWT 2
S JTable Float Column fuegt automatisch Punkt hinzu wenn man Zahlen eingibt. AWT, Swing, JavaFX & SWT 21
G Blinkenden Punkt zeichen AWT, Swing, JavaFX & SWT 2
S Will einen Punkt zeichnen aber krieg das net hin. AWT, Swing, JavaFX & SWT 2
J JScrollPane soll automatisch zu einem punkt scrollen AWT, Swing, JavaFX & SWT 4
G Punkt um ein Rotationszentrum rotieren lassen AWT, Swing, JavaFX & SWT 15
S FAQ und JTable Tutorial.Teil.4 Punkt 5 wichtige Bemerkung AWT, Swing, JavaFX & SWT 2
T drehung um einen anderen punkt AWT, Swing, JavaFX & SWT 2
R Hässlicher Punkt bei JPopupMenu AWT, Swing, JavaFX & SWT 12
E x wert von einem vorhandenen punkt abziehen? AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben