# XNA/C# Mathe: Berechnung von Punkten auf einer Geraden



## tobee (19. Januar 2008)

Ich möchte die Punkte die auf einer Geraden sind berechnen und als Koordinate  ausgeben.
Die angehängte Grafik ist selbsterklärend.

Schonmal Danke für eure Hilfe.


----------



## Mark (19. Januar 2008)

Hi!

...das werden aber ein Menge Punkte ... bzw. ja fast mehr als unendlich 

Folgendes aus'm löchrigen Hirn, also ohne Gewähr:

P1 (x1 / y1)
P2 (x2 / y2)

g(x) = a * x + b //Geradengleichung
a = Steigung = delta y / delta x
a = (y2-y1) / (x2-x1)

b = g(x) - a * x //muß für einen gegebenen Punkt gelten, also:
b = y1 - a * x1

=> g(x) = (y2-y1) / (x2-x1) * x + (y1 - ((y2-y1) / (x2-x1)) * x1 )

*g* wenn das stimmt, fress ich einen Besen 

Liebe Grüße,
Mark.

//edit: die Deltas noch in Klammern gesetzt...


----------



## deepthroat (19. Januar 2008)

Hi.

Die allgemeine Formel einer Geraden lautet: f(x) = a * x + b

Damit lassen sich alle Punkte auf der Geraden berechnen. Die Parameter a und b lassen sich mittels zwei gegebener Punkte die auf der Gerade liegen bestimmen.

Allerdings wirst du nicht alle Punkte berechnen können, da in einem Intervall auf einer Gerade unendlich viele Punkte liegen.

Gruß


----------



## tobee (19. Januar 2008)

Danke an euch, aber ich hab den Schritt noch nicht geschafft und steh immer noch auf dem Schlauch.
Als Ausgangswerte hab ich x und y von Punkt 1, x und y von Punkt 2.
Wie würde dann meine Funktion aussehen und wie wende ich diese genau an?


----------



## Mark (19. Januar 2008)

Hi!

Also, wenn g(x) = (y2-y1) / (x2-x1) * x + (y1 - ((y2-y1) / (x2-x1)) * x1) richtig ist - vielleicht mag das ja wer bestätigen, ich habe es probiert und es funktionierte -, ersetzt Du einfach alle x1, y1, x2, y2 mit den dementsprechenden Punkten P1(x1/y1) und P2(x2/y2).
Nun kannst Du für x beliebige Werte eintragen und die Formel liefert Dir y = g(x)...

Liebe Grüße,
Mark.


----------



## tobee (19. Januar 2008)

Also ich hab die Berechnung mal probiert und das Ergebniss ist 26,6.
Laut meinem Koordiaten-System müsste der Wert bei ca. 13,5 liegen.


----------



## Matthias Reitinger (19. Januar 2008)

tobee hat gesagt.:


> Also ich hab die Berechnung mal probiert und das Ergebniss ist 26,6.
> Laut meinem Koordiaten-System müsste der Wert bei ca. 13,5 liegen.


Ohne Ausgangswerte und Rechenweg wird dir hier keiner sagen können, was da schief gelaufen ist…


----------



## Mark (19. Januar 2008)

Hi!

Hm, komisch, ich habe die Kreiszahl Pi raus! 
Deine Werte helfen leider gar nicht, wenn die Punkte nicht bekannt sind 
Vor allem wolltest Du doch "alle Punkte" ... und das soll das Ergebnis sein? 

-> für welchen x-Wert erhälst Du das gepostete Ergebnis?
-> wie lauten Deine Punkte?

Grüße,
Mark.


----------



## tobee (19. Januar 2008)

Ich hab das Koordinatensystem mit Zahlen versehen.
Meine Aussage hatte doch nicht gestimmt. 14 müsste rauskommen nicht 13,5.

Ich habe für x 5 eingesetzt und 26,6 ist rausgekommen


----------



## Matthias Reitinger (19. Januar 2008)

tobee hat gesagt.:


> Ich habe für x 5 eingesetzt und 26,6 ist rausgekommen


Dann hast du dich wohl verrechnet. Mit den Werten _x1 = 5, x2 = 17, y1 = 14, y2 = 9_ komme ich auf _g(5) = 14_.


----------



## Mark (19. Januar 2008)

Hi!

Jupp, ich komme auch auf das richtige Ergebnis:

Gegeben P1 (5/14) und P2 (17/9):
Laut Formel oben: g(x) = ((9-14) / (17-5)) * x + 14 - ((9-14) / (17-5)) * 5
=> g(x) = -5 / 12 * x + 193 / 12

Kontrolle P1 g(5) = -5 / 12 * 5 + 193 / 12 = -25 / 12 + 193 / 12 = 168 / 12 = 14
Kontrolle P2 g(17) = -5 / 12 * 17 + 193 / 12 = -85 / 12 + 193 / 12 = 108 / 12 = 9


Grüße,
Mark.


----------



## tobee (19. Januar 2008)

Vielen Dank für eure Antworten.
Wenn es geht bitte in das XNA/C# Forum tun, die Frage geht jetzt nämlich in den Bereich XNA/C#

```
// Maus mit der Position und Taste abfragen
if (Mouse.GetState().RightButton == ButtonState.Pressed)
{
    MouseX = Mouse.GetState().X;
    MouseY = Mouse.GetState().Y;

    /*
    x1  MouseX = Mouse.GetState().X;
    y1  MouseY = Mouse.GetState().Y;
    x2  TankPosition.X;
    y2  TankPosition.Y;
    */
    if (MouseX > TankPosition.X){
        for (float x = MouseX; x < TankPosition.X; x++)
        {
            TankPosition.Y = (TankPosition.Y - MouseY) / (TankPosition.X - MouseX) * x + (MouseY - (TankPosition.Y - MouseY) / (TankPosition.X - MouseX) * MouseX);
            TankPosition.X = x;
        }
    }
    MouseX = Mouse.GetState().X;
    MouseY = Mouse.GetState().Y;
}
```
Ich will mein Objekt (Panzer) dorthin fahren lassen wo ich mit der rechten Maustaste gedrückt hab.
Ist der Ansatz so richtig? 
Funktionieren tut es leider nicht.


----------



## deepthroat (19. Januar 2008)

tobee hat gesagt.:


> Wenn es geht bitte in das XNA/C# Forum tun, die Frage geht jetzt nämlich in den Bereich XNA/C#


Warum "tust" du die Frage denn nicht selber dorthin? Sprich: Warum erstellst du nicht gleich ein neues Thema im entsprechenden Forum? 

Gruß


----------



## Mark (19. Januar 2008)

Hi!

Verschoben ... hoffe, es passt so 

Wenn der Panzer auch noch schießen können soll, wird aber nicht in's Waffen-Forum verschoben 

Liebe Grüße,
Mark.


----------



## tobee (19. Januar 2008)

Damit die User den Zusammenhang meiner Funktion sehen.
Nicht das die Frage auftaucht: Was willst du damit berechnen?
Ich kann aber auch eine neue Frage erstellen


----------



## deepthroat (19. Januar 2008)

tobee hat gesagt.:


> Damit die User den Zusammenhang meiner Funktion sehen.
> Nicht das die Frage auftaucht: Was willst du damit berechnen?
> Ich kann aber auch eine neue Frage erstellen


Im Grunde ist egal was du damit berechnen willst. Du machst die Berechnung falsch, da das sicherlich alles Integer Werte sind und damit Integer-Arithmetik verwendet wird.

Versuch's mal so:
	
	
	



```
TankPosition.Y = (TankPosition.Y - MouseY) * x / (TankPosition.X - MouseX) + (MouseY - (TankPosition.Y - MouseY) * MouseX / (TankPosition.X - MouseX) )
```
Gruß


----------



## tobee (19. Januar 2008)

Ich hab irgendwas anderes falsch gemacht:

```
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion

namespace Wehrmacht
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {

        GraphicsDeviceManager graphics;
        ContentManager content;

        SpriteBatch Sprite;
        SpriteFont Arial;

        Texture2D Tank;
        public float TankAngle;
        public Rectangle TankPosition;

        Texture2D Ammo;
        public Vector2 AmmoPosition;

        public bool Shooted;

        public int MouseX;
        public int MouseY;

        public Game1()
        {

            graphics = new GraphicsDeviceManager(this);
            content = new ContentManager(Services);

            this.IsMouseVisible = true;

            TankAngle = 0;

            AmmoPosition = new Vector2(100, 100);


            Shooted = false;
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {

                Arial = content.Load<SpriteFont>("Arial");

                Tank = content.Load<Texture2D>("Tank");
                TankAngle = 0.0f;
                TankPosition = new Rectangle(100, 100, Tank.Width, Tank.Height);

                Ammo = content.Load<Texture2D>("Ammo");

                Sprite = new SpriteBatch(graphics.GraphicsDevice);

            }
        }

        protected override void UnloadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent)
            {
                content.Unload();
            }
        }

        protected override void Update(GameTime gameTime)
        {

            // Maus mit der Position und Taste abfragen
            if (Mouse.GetState().RightButton == ButtonState.Pressed)
            {
                MouseX = Mouse.GetState().X;
                MouseY = Mouse.GetState().Y;

                /*
                x1  MouseX = Mouse.GetState().X;
                y1  MouseY = Mouse.GetState().Y;
                x2  TankPosition.X;
                y2  TankPosition.Y;
                */
                if (MouseX > TankPosition.X){
                    for (float x = MouseX; x < TankPosition.X; x++)
                    {
                        TankPosition.Y = TankPosition.Y = (TankPosition.Y - MouseY) * x / (TankPosition.X - MouseX) + (MouseY - (TankPosition.Y - MouseY) * MouseX / (TankPosition.X - MouseX));
                        TankPosition.X = x;
                    }
                }
                MouseX = Mouse.GetState().X;
                MouseY = Mouse.GetState().Y;
            }

            // Munition schießen
            if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                Shooted = true;
            }
            if (Shooted == true && AmmoPosition.X < 800)
            {
                AmmoPosition.X += 5;
            }

            // Spiel verlassen
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                this.Exit();
            }

            // Panzer vorwärts fahren lassen
            if (Keyboard.GetState().IsKeyDown(Keys.Up))
            {
                TankPosition.X += 1;
                if (Shooted == false)
                {
                    AmmoPosition.X += 1;
                }
            }

            // Panzer rückwärts fahren lassen
            if (Keyboard.GetState().IsKeyDown(Keys.Down))
            {
                TankPosition.X -= 1;
                if (Shooted == false)
                {
                    AmmoPosition.X -= 1;
                }
            }

            // Panzer nach links drehen
            if (Keyboard.GetState().IsKeyDown(Keys.Left))
            {
                TankAngle -= 0.02f;
            }

            // Panzer nach rechts drehen
            if (Keyboard.GetState().IsKeyDown(Keys.Right))
            {
                TankAngle += 0.02f;
            }


            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            Sprite.Begin();
            Sprite.Draw(Tank, TankPosition, Color.White);

            /*Sprite.Draw(
                    Tank,
                    TankPosition, 
                    new Rectangle(0, 0, Tank.Width, Tank.Height),
                    Color.White,
                    TankAngle,
                    new Vector2(Tank.Width / 2, Tank.Height / 2),
                    SpriteEffects.None,
                    0.0f
                    );*/

            Sprite.Draw(Ammo, AmmoPosition, Color.White);
            Sprite.End();
            base.Draw(gameTime);
        }


    }

}
```


----------



## deepthroat (19. Januar 2008)

Hi.

Obwohl du solange angemeldet bist und eine größere Zahl von Beiträgen geschrieben hast, weißt du leider immer noch nicht wie man Fragen stellt. Was sind die Fehlermeldungen? In welcher Zeile sind diese aufgetreten? *Was* funktioniert nicht?

Es ist nicht möglich den Inkrementoperator auf eine float Variable anzwenden.

Die Berechnung in der Schleife ist unnötig komplex. Berechne einfach vor der Schleife die Parameter der Funktionsgleichung f(x) = a * x + b. 

```
double a = ((double)TankPosition.Y - MouseY) / (TankPosition.X - MouseX);
double b = MouseY - a * MouseX;

for (int offset = (TankPosition.X < MouseX ? 1 : -1);
     TankPosition.X != MouseX; TankPosition.X += offset) {
  TankPosition.Y = a * x + b;
}
```
Gruß

PS: Du solltest dir evtl. mal den Bresenham Algorithmus zum Zeichnen einer Linie anschauen.


----------

