Feedback

C# - Vom Polygonzug zum Rohr

Veröffentlicht von am 09.12.2013
(0 Bewertungen)
Aus einer Liste, deren Punkte ein Polygonzug definieren, wird eine neue Liste von Punkten erstellt, die einfach der Methode Graphics.DrawLines(...) übergeben werden muss. Und schwupp wird ein Rohr gezeichnet :)

Aufgerufen werden muss nur die Methode "GetTubePath".
internal static List<PointF> GetTubePath(List<PointF> Points, int move)
        {
            List<PointF> output = new List<PointF>();
            PointF p11, p12, p21, p22 = PointF.Empty, intercept;
            double ang1, ang2;
            Direction dir1, dir2;

            if (Points.Count == 2)
            {
                ang1 = AngelCalc(Points[0], Points[1]);
                dir1 = Forward(Points[0], Points[1]);
                p11 = MovePoint(Points[0], ang1 + (int)dir1, move);
                p22 = MovePoint(Points[1], ang1 + (int)dir1, move);

                output.Add(p11); 
            }
            else
            {
                for (int i = 0; i < Points.Count - 2; i++)
                {
                    ang1 = AngelCalc(Points[i], Points[i + 1]);
                    dir1 = Forward(Points[i], Points[i + 1]);
                    p11 = MovePoint(Points[i], ang1 + (int)dir1, move);
                    p12 = MovePoint(Points[i + 1], ang1 + (int)dir1, move);

                    ang2 = AngelCalc(Points[i + 1], Points[i + 2]);
                    dir2 = Forward(Points[i + 1], Points[i + 2]);
                    p21 = MovePoint(Points[i + 1], ang2 + (int)dir2, move);
                    p22 = MovePoint(Points[i + 2], ang2 + (int)dir2, move);

                    if (i == 0)
                        output.Add(p11);
                    else
                    {
                        intercept = GetIntersectPoint(p11, p12, p21, p22);
                        output.Add(intercept);
                    }
                }
            }
            output.Add(p22);
            output.AddRange(Points.Reverse<PointF>());
            output.Add(output[0]);
            return output;
        }

 internal static PointF MovePoint(PointF p, double α, int move)
        {
            PointF point = new PointF();
            point.X = p.X + (float)(Math.Cos(α * Math.PI / 180) * move);
            point.Y = p.Y + (float)(Math.Sin(α * Math.PI / 180) * move);
            return point;
        }
        

        internal enum Direction { Forward = 90, Backward = 270 }

        internal static Direction Forward(PointF p1, PointF p2)
        {
            if (p2.X > p1.X) return Direction.Forward;
            else return Direction.Backward;
        }

 internal static PointF GetIntersectPoint(PointF P1, PointF P2, PointF B1, PointF B2)
        {
            PointF intersect = new PointF();
            float numerator = -P1.Y + B1.Y - ((B1.X - P1.X) * (P2.Y - P1.Y) / (P2.X - P1.X)),

                  denominator = ((B2.X - B1.X) / (P2.X - P1.X)) * (P2.Y - P1.Y) - (B2.Y - B1.Y);

            float fraction = numerator / denominator ;
            intersect.X = B1.X + fraction * (B2.X - B1.X);
            intersect.Y = B1.Y + fraction * (B2.Y - B1.Y);
            return intersect;
        }

 internal static double AngelCalc(PointF P1, PointF P2)
        {
            if (P1.X > P2.X) return AngelCalc(P2, P1);

            float dy = P2.Y - P1.Y;
            float dx = P2.X - P1.X;

            if (dx == 0 && dy != 0)
            {
                if (P1.Y < P2.Y)
                    return 90f;
                else
                    return 270f;
            }
            if (dy == 0 && dx != 0)
            {
                if (P1.X < P2.X)
                    return 0f;
                else
                    return 180f;
            }
            double ang2 = Math.Atan((dy) / (dx)) * (180 / Math.PI);

            return ang2 ;
        }
Abgelegt unter Polygon, zeichnen, Winkel, Linie, Schnittpunkt, Rohr.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!