Positionsermittlung

Nico_G

Mitglied
Hi,

nachdem mir hier das letzte mal so gut geholfen wurde hab ich mal wieder eine kleine Frage und hoffe auf Antwort =)

Ich möchte eine eine minütliche Positionsermittlung durchführen. Ich habe ein Objekt, die aktuelle Position und ein Ziel. Das Objekt verfügt zudem über eine Geschwindigkeit. Jede Minute wird die Position des Objektes neu ermittelt.

Wenn die aktuelle Position dem Ziel nahe liegt ist es angekommen. Folgenden Code habe ich geschrieben der auch eigentlich ganz gut funktioniert.

Java:
/**
 * Diese Klasse stellt die Position der Clients dar und berechnet unter Angabe
 * der Geschwindigkeit die nächste Position.
 * 
 * @author Nico
 * 
 */
public class Position {

	private double x;
	private double y;
	private Position normalizedDirectionVector;

	public Position(double a, double b) {
		x = a;
		y = b;
	}

	public void setX(double x) {
		this.x = x;
	}

	public void setY(double y) {
		this.y = y;
	}

	public double getX() {
		return x;
	}

	public double getY() {
		return y;
	}

	/**
	 * Liefert unter Angabe des Ziels und der Geschwindigkeit die nächste
	 * Position
	 * 
	 * @param speed
	 * @param target
	 * @return nextPosition
	 */
	public Position nextPosition(double speed, Position target) {
		Position nextPosition = new Position(0, 0);
		createNormalizedDirectionVector(this, target);
		if(target.getX()>this.x&&target.getY()>this.y){
		nextPosition.x = this.x + (speed * normalizedDirectionVector.x);
		nextPosition.y = this.y + (speed * normalizedDirectionVector.y);
		
		}
		if(target.getX()<this.x&&target.getY()<this.y){
			nextPosition.x = this.x - (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y - (speed * normalizedDirectionVector.y);
		}
		if(target.getX()>this.x&&target.getY()==this.y){
			nextPosition.x = this.x + (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y - (speed * normalizedDirectionVector.y);
		}
		if(target.getX()>this.x&&target.getY()==this.y){
			nextPosition.x = this.x + (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y - (speed * normalizedDirectionVector.y);
		}
		if(target.getX()<this.x&&target.getY()==this.y){
			nextPosition.x = this.x - (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y - (speed * normalizedDirectionVector.y);
		}
		if(target.getX()==this.x&&target.getY()>this.y){
			nextPosition.x = this.x - (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y + (speed * normalizedDirectionVector.y);
		}
		if(target.getX()==this.x&&target.getY()<this.y){
			nextPosition.x = this.x - (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y + (speed * normalizedDirectionVector.y);
		}
		if(target.getX()<this.x&&target.getY()>this.y){
			nextPosition.x = this.x - (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y + (speed * normalizedDirectionVector.y);
		}
		if(target.getX()>this.x&&target.getY()<this.y){
			nextPosition.x = this.x + (speed * normalizedDirectionVector.x);
			nextPosition.y = this.y - (speed * normalizedDirectionVector.y);
			if(this.x>nextPosition.x){
				nextPosition.x=target.x;
			}
		}
		
		this.x = nextPosition.x;
		this.y = nextPosition.y;

		return nextPosition;
	}

	/**
	 * Gibt den normierten Richtungsvektor zweier Vektoren zurück
	 * 
	 * @param aufpunkt
	 * @param ziel
	 * @return
	 */
	private void createNormalizedDirectionVector(Position aufpunkt,
			Position ziel) {

		normalizedDirectionVector = minus(aufpunkt, ziel);
		double leng = length(normalizedDirectionVector);

		double k = normalizedDirectionVector.x;
		double o = normalizedDirectionVector.y;
		double l = leng;

		normalizedDirectionVector.x = Math.abs(k / l);
		normalizedDirectionVector.y = Math.abs(o / l);
	}

	/**
	 * Subtrahiert zwei Vektoren
	 * 
	 * @param startPoint
	 * @param target
	 * @return
	 */
	private Position minus(Position startPoint, Position target) {
		Position local = new Position(0, 0);
		local.x = target.x - startPoint.x;
		local.y = target.y - startPoint.y;

		return local;
	}

	/**
	 * Berechnet die Länge eines Vektors
	 * 
	 * @param a
	 * @return
	 */
	private double length(Position a) {
		double local = 0;
		local = Math.sqrt(Math.pow(a.x, 2) + Math.pow(a.y, 2));

		return local;

	}

}

Jedoch habe ich das Problem, dass wenn ich ein zu schnelles Objekt habe z.B. 135 km/h, legt dieses in der Minute 2,25 Kilometer zurück und ist somit im nächsten Zeitschritt nicht mehr in der Nähe des Ziels sondern schon drüber hinweg. Dann springt es zwischen zwei Positionen hin und her, erreicht aber niemals das Ziel.

Irgendeine Abfrage müsste ich einbauen die dies verhindert.

Vielleicht habt Ihr ja eine gute Idee dazu oder eine andere viel elegantere Lösungsidee um das Problem zu lösen. :)

Nico
 
S

SlaterB

Gast
wozu die ganzen if-Unterscheidungen? zeigt der normalizedDirectionVector nicht genau in die richtige Richtung?
dann einfach den so addieren wie er ist oder welche Schwierigkeit gibt es dabei?

------

von nextPosition kannst du in diesem Durchgang nochmal den normalizedDirectionVector bestimmen,
wenn er derselbe geblieben ist, dann liegt das Ziel weiter in der bisherigen Richtung,
wenn genau entgegengesetzter Vector, dann darüber hinaus und irgendwie reagieren, direkt zum Ziel gehen
oder nur halbe speed, was immer du vorhast,

------

length() kann auch helfen, bestimme den Abstand vom Ausgangspunkt zum Ziel,
also length(normalizedDirectionVector) bevor er normalisiert ist ;)

dazu mit length(speed *normalizedDirectionVector) die aktuell zurückgelegte Strecke,
wenn diese größer als der Abstand zum Ziel ist, dann ist dass auch die benötigte Info

edit: das letzte ist wohl genau speed, also speed mit Abstand zum Ziel vergleichen
 
Zuletzt bearbeitet von einem Moderator:

Nico_G

Mitglied
Oh man bin ich ein Idiot.....

bei deinem Kommentar bezüglich der Richtung des Richtungsvektors bin ich stutzig geworden.

Ich bilde in der Funktion createNormalizedDirectionVector den Betrag von dem Vektor mit Math.abs:autsch:

Damit wären zumndest schon mal die ganzen if-Abfrage weg. Jetzt betrachte ich mal das eigentliche Problem.

Heut ist nicht mein tag ^^
 

Nico_G

Mitglied
So, vielen Dank noch mal für Deinen Tip. Mit dem Überprüfen des Vorzeichenwechsels des Richtungsvektors hats geklappt =)

Java:
public Position nextPosition(double speed, Position target) {
		Position nextPosition = new Position(0, 0);
		double x = target.getX();
		double y = target.getY();
		normalizedDirectionVector = createNormalizedDirectionVector(this, target);

		nextPosition.x = this.x + (speed * normalizedDirectionVector.x);
		nextPosition.y = this.y + (speed * normalizedDirectionVector.y);
		
		
		this.x = nextPosition.x;
		this.y = nextPosition.y;
		
		normalizedDirectionVectorNew = createNormalizedDirectionVector(nextPosition, target);
		
		if(normalizedDirectionVector.x >0 && normalizedDirectionVectorNew.x >0 ||normalizedDirectionVector.x <0 && normalizedDirectionVectorNew.x <0 && normalizedDirectionVector.y >0 && normalizedDirectionVectorNew.y>0||normalizedDirectionVector.y <0 && normalizedDirectionVectorNew.y<0){
			return nextPosition;
		}
			
			
		else{return target;}
	}

Greez

Nico
 
S

SlaterB

Gast
was würde Zeile 16 zusammenschrumpfen, wenn du die langen Namen wie normalizedDirectionVector lieber n + m nennen würdest..

&& und || wild durcheinander ohne Klammern könnte ich persönlich gar nicht interpretieren,
aber wenn es bei dir geht, dann bitte

sinnvoll ist vielleicht noch der Vergleich
(n.x > 0 == m.x > 0)


bzw.
(Math.signum(n.x) == Math.signum(m.x))
 

Neue Themen


Oben