C# :: Aufgabe #390

4 Lösungen Lösungen öffentlich

Schnittpunkt zweier Geraden endlicher Länge

Fortgeschrittener - C# von hollst - 20.04.2021 um 10:25 Uhr
In der unendlich ausgedehnten euklidischen 2D-Eben wähle man zufällig vier unterschiedliche Punkte P1, P2, P3 und P4. Gedanklich verbinde man P1 und P2 mit einer geraden Linie L12 sowie P3 und P4 mit einer geraden Linie L34.

Man schreibe eine Funktion, die als Rückgabewert ausgibt, ob sich L12 und L34 schneiden in Abhändigkeit von den Anfangs-/Endpunkten P1 ... P4.

Viel Spaß!

Lösungen:

3 Kommentare
1x
vote_ok
von JKooP (18090 Punkte) - 21.04.2021 um 19:36 Uhr
NET 5.x; C# 9.x; VS-2019
Hier eine Lösung mittels Geradengleichung:
Quellcode ausblenden C#-Code
using System;

// Geraden schneiden sich:
Point P1 = new(-4.5, 5.8);
Point P2 = new(3.1, -2);
Point P3 = new(4.5, 6.2);
Point P4 = new(-2.7, -7.8);

// Parallele Geraden => kein Schnittpunkt:
// Point P1 = new(-5, 5);
// Point P2 = new(-5, -5);
// Point P3 = new(5, 5);
// Point P4 = new(5, -5);

Line L12 = new(P1, P2);
Line L34 = new(P3, P4);

IntersectLine isl = new(L12, L34);

Console.WriteLine(isl);


record Point(double X, double Y);

record Line(Point P1, Point P2);

record IntersectLine (Line L1, Line L2)
{
    // Geradengleichung 1: L12 = (yP2 - yP1) / (xP2 - xP1) * (x - xP1) + yP1;
    // Geradengleichung 2: L34 = (yP4 - yP3) / (xP4 - xP3) * (x - xP3) + yP3;

    // beide Geradengleichungen gleich setzen:
    private double S1 => Math.Round((-L1.P2.X * L2.P1.X * L1.P1.Y + L1.P2.X * L2.P2.X * L1.P1.Y + L1.P1.X * L2.P1.X * L1.P2.Y
        - L1.P1.X * L2.P2.X * L1.P2.Y + L1.P1.X * L2.P2.X * L2.P1.Y - L1.P2.X * L2.P2.X * L2.P1.Y
        - L1.P1.X * L2.P1.X * L2.P2.Y + L1.P2.X * L2.P1.X * L2.P2.Y) /
        (-L2.P1.X * L1.P1.Y + L2.P2.X * L1.P1.Y + L2.P1.X * L1.P2.Y
        - L2.P2.X * L1.P2.Y + L1.P1.X * L2.P1.Y - L1.P2.X * L2.P1.Y
        - L1.P1.X * L2.P2.Y + L1.P2.X * L2.P2.Y), 3);

    // S1 in die 2. Gleichung einsetzen
    private double S2 => Math.Round((L2.P2.Y - L2.P1.Y) / (L2.P2.X - L2.P1.X) * (S1 - L2.P1.X) + L2.P1.Y, 3);

    public override string ToString() => double.IsNaN(S1) || double.IsNaN(S2) ? "Kein Schnittpunkt" : $"Schnittpunkt: ({S1}, {S2})";
}
3 Kommentare
vote_ok
von hollst (13980 Punkte) - 22.04.2021 um 21:16 Uhr
Quellcode ausblenden C#-Code
using System;
using static System.Console;
using System.Text;

Double[][] XY_Test = new Double[][]  {
    new double[] {  0,   0 }, // P1 (x1, y1)
    new double[] {  1,   1 }, // P2 (x2, y2)
    new double[] {  1,   1 }, // P3 (x3, y3)
    new double[] {-10,   0 }  // P4 (x4, y4)
};

WriteLine(Environment.NewLine + Intersection(XY_Test));
ReadKey();

static string ToMyString(Double[][] xy)  {
    StringBuilder sb = new();
    for (var i = 0; i < xy.Length; i++)  {
        for (var j = 0; j < xy[i].Length; j++)
            sb.Append($"{xy[i][j].ToString("F2"),6}");
        sb.AppendLine();
    }
    return sb.ToString();
}

static bool Intersection(Double[][] xy)  {

    WriteLine(ToMyString(xy));

    Double dx0 = xy[1][0] - xy[0][0]; WriteLine($"dx0  delta x L12  {dx0}"); //delta x L12
    Double dy0 = xy[1][1] - xy[0][1]; WriteLine($"dy0  delta y L12  {dy0}"); //delta y L12

    Double dx1 = xy[3][0] - xy[2][0]; WriteLine($"dx1  delta x L34  {dx1}"); //delta x L34   
    Double dy1 = xy[3][1] - xy[2][1]; WriteLine($"dy1  delta y L34  {dy1}"); //delta y L34

    Double DX = xy[2][0] - xy[0][0]; 
    Double DY = xy[2][1] - xy[0][1]; 

    Double det = dy0 * dx1 - dy1 * dx0;  

    if (det == 0)
        return false;

    Double det1 = DY * dx1 - dy1 * DX;
    Double det2 = dy0 * DY - DX * dx0;

    WriteLine($"det {det}    det1 {det1}    det2 {det2}");

    Double t1 = det1 / det;
    Double t2 = det2 / det;

    WriteLine($"t1 {t1.ToString("F2"),6} t2 {t2.ToString("F2"),6}");

    return (t1 <= 1) && (t2 <= 1) && (t1 >= 0) && (t2 >= 0);
}
vote_ok
von Waldgeist (2310 Punkte) - 03.05.2021 um 13:51 Uhr
Hallo hier meine Lösung

Quellcode ausblenden C#-Code
namespace Schnittpunkte_2_Geraden_aus_Punkten_Aufgabe_390
{
    internal class Punkt
    {
        public float X { get; set; }
        public float Y { get; set; }
    }
}


Quellcode ausblenden C#-Code
namespace Schnittpunkte_2_Geraden_aus_Punkten_Aufgabe_390
{
    internal class Strecke
    {
        public Punkt Startpunkt = new Punkt();
        public Punkt Endpunkt = new Punkt();

        public float Steigung;
        public float b;
    }
}


Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Schnittpunkte_2_Geraden_aus_Punkten_Aufgabe_390
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Strecke S1 = new Strecke();
            Strecke S2 = new Strecke();

            Punkt Schnittpunkt = new Punkt();

            S1.Startpunkt.X = float.Parse(tbpunkt1_x.Text);
            S1.Startpunkt.Y = float.Parse(tbpunkt1_y.Text);

            S1.Endpunkt.X = float.Parse(tbpunkt2_x.Text);
            S1.Endpunkt.Y = float.Parse(tbpunkt2_y.Text);

            S1.Steigung = (S1.Endpunkt.Y - S1.Startpunkt.Y) / (S1.Endpunkt.X - S1.Startpunkt.X);
            S1.b = S1.Endpunkt.Y - S1.Steigung * S1.Endpunkt.X;

            tb_s1_steigung.Text = S1.Steigung.ToString();
            tb_s1_b.Text = S1.b.ToString();
            string gleichung;
            gleichung = "f(x) = " + S1.Steigung.ToString() +"x + "+ S1.b.ToString();
            tb_s1_gleichung.Text = gleichung;



            S2.Startpunkt.X = float.Parse(tbpunkt3_x.Text);
            S2.Startpunkt.Y = float.Parse(tbpunkt3_y.Text);

            S2.Endpunkt.X = float.Parse(tbpunkt4_x.Text);
            S2.Endpunkt.Y = float.Parse(tbpunkt4_y.Text);

            S2.Steigung = (S2.Endpunkt.Y - S2.Startpunkt.Y) / (S2.Endpunkt.X - S2.Startpunkt.X);
            S2.b = S2.Endpunkt.Y - S2.Steigung * S2.Endpunkt.X;

            tb_s2_steigung.Text = S2.Steigung.ToString();
            tb_s2_b.Text = S2.b.ToString();
            string gleichung2;
            gleichung2 = "f(x) = " + S2.Steigung.ToString() + "x + " + S2.b.ToString();
            tb_s2_gleichung.Text = gleichung2;



            if (S1.Steigung == S2.Steigung)
            {
                MessageBox.Show("Ihre Strecken / Geraden verlaufen paralell.\nEs gibt keinen Schnittpunkt.");
            }

            else
            {


                

                Schnittpunkt.X = (S2.b - S1.b) / (S1.Steigung - S2.Steigung);
                Schnittpunkt.Y = S1.Steigung * Schnittpunkt.X + S1.b;

                tb_schnittpunkt_x.Text = Schnittpunkt.X.ToString();
                tb_schnittpunkt_y.Text = Schnittpunkt.Y.ToString();
            }

            if (  ((S1.Startpunkt.X <= Schnittpunkt.X)&&(Schnittpunkt.X<=S1.Endpunkt.X)) && ((S2.Startpunkt.X <= Schnittpunkt.X)&& (Schnittpunkt.X <= S2.Endpunkt.X)))
            {
                tb_ergebnis.Text = "Die beideen Strecken schneiden sich!";
            }
            else
            {
                tb_ergebnis.Text = "Die beiden Strecken scheiden sich nicht !!";
            }

        }
    }
}

vote_ok
von JchrisP (60 Punkte) - 15.07.2021 um 15:40 Uhr
Quellcode ausblenden C#-Code
namespace Schnittpunkt
{
    class Point 
    {
        public double X;
        public double Y;
        public Point(double x, double y)
        {
            X = x;
            Y = y;
        }
    }
    class Trace
    {
        public Point A;
        public Point B;
        public string Name;
        public Trace(string name, Point a, Point b)
        {
            A = a;
            B = b;
            Name = name;
        }        
    }
    
    class Program
    {
        public static void IntersectControl(Trace a, Trace b) //Die eigentliche Funktion(Methode) "IntersectControl"
        {
            double m1 = (a.B.Y - a.A.Y) / (a.B.X - a.A.X);   //Steigungsrgad von Trace a 
            double m2 = (b.B.Y - b.A.Y) / (b.B.X - b.A.X);   //Steigungsrgad von Trace b    
            if (m1 == m2) Console.WriteLine($"Die beiden Strecken {a.Name} und {b.Name} haben den gleichen Steigungsgrad und daher haben sie keinen gemeinsamen Schnittpunkt"); 
            if (m1 != m2)
            {
                double b1 = a.A.Y - (a.A.X * m1);                      //b (Y_Schnittpunkt) der Geraden, auf Trace a liegt            
                double b2 = b.A.Y - (b.A.X * m2);                      //b (Y_Schnittpunkt) der Geraden, auf Trace b liegt             
                double IntersectX = (b2 - b1) / (m1 - m2);             //Koordinate X des Schnittpunktes berechnen
                double IntersectY = m1 * IntersectX + b1;              //Koordinate Y des Schnittpunktes berechnen

                if ((IntersectX > a.A.X) && (IntersectX < b.A.X) && (IntersectX > b.B.X) && (IntersectX < a.B.X) &&
                    (IntersectY < a.A.Y) && (IntersectY > b.B.Y) && (IntersectY < b.A.Y) && (IntersectY > a.B.Y))       //Prüfen ob der Schnittpunkt der Geraden innerhalb der beiden Strecken liegt   
                {
                    Console.WriteLine($"Die beiden Strecken {a.Name} und {b.Name} haben einen gemeinsamen Schnittpunkt");
                }
                else
                {
                    Console.WriteLine($"Die beiden Strecken {a.Name} und {b.Name} haben keinen gemeinsamen Schnittpunkt");
                }
            }
        }
        static void Main(string[] args)
        {
            //Point L12_P1 = new Point(4.5, 6.2);
            //Point L12_P2 = new Point(-2.7, -7.8);     //Die Werte von L34 als L12 zum testen

            //Point L12_P1 = new Point(-10.77, 12.24); //eine Strecke ohne gemeinsamen Schnittpunkt 
            //Point L12_P2 = new Point(-5.21, 6.53);     

           Point L12_P1 = new Point(-4.5, 5.8);
           Point L12_P2 = new Point(3.1, -2);
           Point L34_P1 = new Point(4.5, 6.2);
           Point L34_P2 = new Point(-2.7, -7.8);
            
           Trace L12 = new Trace("L12",L12_P1, L12_P2);
           Trace L34 = new Trace("L34",L34_P1, L34_P2);


           IntersectControl(L12, L34);   //Aufrufen der Funktion IntersectControl  
            
           Console.ReadKey();
        }
    }
}
1801110

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.