Moin,
zusammen mit @Gonger96 habe ich gestern in SharpMath noch einen kleinen Bug gefunden, der bei mir beim Testen nicht vorkam.
Dazu haben wir eine Testanwendung erstellt und einfach eine Form hinzugefügt:
Simpel, aber erledigt seine Arbeit. Es wird einfach ein entsprechendes Polygon gezeichnet und wenn sich die Maus innerhalb des Polygons befindet, dann soll dieses weiß gefüllt werden (normal ist es rot).
Die Methode dazu habe ich geschrieben und dazu den Punkt-in-Polygon-Test nach Jordan implementiert. Das Ganze sieht so aus:
Das mit dem
Dennoch klappt das nicht und ich glaube, es ist am Einfachsten, das Problem visuell zu zeigen:
Man sieht, es klappt auch mit der Erkennung, wenn ich im Polygon bin, allerdings macht er das tw. auch, wenn ich weiter unten bin. Ich tippe darauf, dass das mit einer entsprechenden Linie durch den einen Punkt
Könnt Ihr mir da helfen?
Grüße
zusammen mit @Gonger96 habe ich gestern in SharpMath noch einen kleinen Bug gefunden, der bei mir beim Testen nicht vorkam.
Dazu haben wir eine Testanwendung erstellt und einfach eine Form hinzugefügt:
C#-Quellcode
- using System.Drawing;
- using System.Windows.Forms;
- using SharpMath.Geometry;
- namespace PolygonTest
- {
- public partial class Form1 : Form
- {
- private readonly Polygon _p;
- private readonly PointF[] _pts =
- {
- new PointF(0, 0), new PointF(200, 80), new PointF(400, 200),
- new PointF(100, 60)
- };
- private bool _b;
- public Form1()
- {
- InitializeComponent();
- _p =
- new Polygon(new Point2D(0, 0), new Point2D(200, 80), new Point2D(400, 200), new Point2D(100, 60));
- }
- private void Form1_Paint(object sender, PaintEventArgs e)
- {
- e.Graphics.FillRectangle(Brushes.Black, ClientRectangle);
- e.Graphics.FillPolygon(_b ? Brushes.AliceBlue : Brushes.Red, _pts);
- }
- private void Form1_MouseMove(object sender, MouseEventArgs e)
- {
- bool bOld = _b;
- _b = _p.ContainsPoint(new Point2D(e.X, e.Y));
- if (_b != bOld)
- Invalidate();
- Text = e.Location.ToString();
- }
- }
- }
Simpel, aber erledigt seine Arbeit. Es wird einfach ein entsprechendes Polygon gezeichnet und wenn sich die Maus innerhalb des Polygons befindet, dann soll dieses weiß gefüllt werden (normal ist es rot).
Die Methode dazu habe ich geschrieben und dazu den Punkt-in-Polygon-Test nach Jordan implementiert. Das Ganze sieht so aus:
C#-Quellcode
- /// <summary>
- /// Determines whether this <see cref="Polygon" /> contains the specified <see cref="Point" />.
- /// </summary>
- /// <param name="point">The <see cref="Point" /> to check.</param>
- /// <returns>
- /// <c>true</c> if this <see cref="Polygon" /> contains the specified <see cref="Point" />; otherwise <c>false</c>
- /// .
- /// </returns>
- public bool ContainsPoint(Point2D point)
- {
- double t = -1;
- var points = Points;
- //points[0] = points[points.Count - 1];
- int j = 1;
- for (int i = 0; i < points.Count; ++i)
- {
- t = t*ContainsPointInternal(point, points[i], points[j]);
- j++;
- if (j == points.Count)
- j = 0;
- }
- return t >= 0;
- }
- private int ContainsPointInternal(Point2D q, Point2D p1, Point2D p2)
- {
- Debug.Print($"From: {p1} to {p2}");
- if (FloatingNumber.AreApproximatelyEqual(q.Y, p1.Y) && FloatingNumber.AreApproximatelyEqual(p1.Y, p2.Y))
- {
- if ((p1.X <= q.X && q.X <= p2.X) || (p2.X <= q.X && q.X <= p1.X))
- return 0;
- return 1;
- }
- if (p1.Y > p2.Y)
- {
- var currentP1 = p1;
- p1 = p2;
- p2 = currentP1;
- }
- else if (FloatingNumber.AreApproximatelyEqual(q.Y, p1.Y) && FloatingNumber.AreApproximatelyEqual(q.X, p1.X))
- return 0;
- else if (q.Y <= p1.Y || q.Y > p2.Y)
- return 1;
- var delta = (p1.X - q.X)*(p2.Y - q.Y) - (p1.Y - q.Y)*(p2.X - q.X);
- if (delta > 0)
- return -1;
- return delta < 0 ? 1 : 0;
- }
Das mit dem
j
ist im Pseudocode von Wikipedia nicht so gemacht, allerdings habe ich das so implementiert und so oder so funktioniert es nicht. Die auskommentierte Zeile verursachte außerdem, dass die Verbindung des letzten Punkts von 100, 60
aus nicht mit 0, 0
, sondern eben 200, 80
stattfand, sodass über dieser Strecke sowieso keine Punkte entdeckt wurden.Dennoch klappt das nicht und ich glaube, es ist am Einfachsten, das Problem visuell zu zeigen:
Man sieht, es klappt auch mit der Erkennung, wenn ich im Polygon bin, allerdings macht er das tw. auch, wenn ich weiter unten bin. Ich tippe darauf, dass das mit einer entsprechenden Linie durch den einen Punkt
100, 60
dort zusammenhängt, denn das wird ja auch geprüft, aber ich komme einfach nicht drauf, warum das so ist.Könnt Ihr mir da helfen?
Grüße
#define for for(int z=0;z<2;++z)for // Have fun!
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!
Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!
Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da