C# :: Aufgabe #390
4 Lösungen

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ß!
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:
NET 5.x; C# 9.x; VS-2019
Hier eine Lösung mittels Geradengleichung:
C#-Code
Hier eine Lösung mittels Geradengleichung:

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})"; }

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); }
Hallo hier meine Lösung
C#-Code
C#-Code
C#-Code

namespace Schnittpunkte_2_Geraden_aus_Punkten_Aufgabe_390 { internal class Punkt { public float X { get; set; } public float Y { get; set; } } }

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; } }

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 !!"; } } } }

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(); } } }