C# :: Aufgabe #190

3 Lösungen Lösungen öffentlich

Zählen von Flächensegmenten

Fortgeschrittener - C# von hollst - 09.10.2017 um 09:21 Uhr
1) Gegeben sei ein Quadrat mit der Seitenlänge L (z. B. L = 1).

2) Man wähle zufällig N Punktepaare auf den Seitenlinien des Quadrates, wobei nicht beide Punkte auf der gleichen Seitenlinie liegen dürfen.

3) Die Punkte eines Punktepaares werden nun jeweils durch eine Linie miteinander verbunden. Auf diese Weise wird die Fläche des Quadrates
in eine Vielzahl von Flächensegmenten unterteilt - siehe exemplarisch die zwei Abb. 1 und 2 mit N = 5 bzw. N = 6.

4) Man schreibe ein Programm, das die Anzahl der auf die Weise erzeugten Flächensegmente zurückgibt.

Lösungen:

1 Kommentar
vote_ok
von Tricky (60 Punkte) - 13.10.2017 um 09:59 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace count_area_train_your_programmer
{
    public partial class Form1 : Form
    {
        int counter = 0;

        static Random rnd = new Random((int)DateTime.Now.Ticks);
        int lines = 1;
        int area_count = 0;
        int width = 0;
        int height = 0;
        Color pencolor = Color.Red;

        //-------------------------------------

        public Form1()
        {
            InitializeComponent();
            pictureBox_canvas.Image = new Bitmap(pictureBox_canvas.Width, pictureBox_canvas.Height);
            width = pictureBox_canvas.Width;
            height = pictureBox_canvas.Height;
        }

        //-------------------------------------

        private void button_draw_Click(object sender, EventArgs e)
        {
            area_count = 0;
            Color color = new Color();
            Point pos1 = new Point(0, 0);
            Point pos2 = new Point(0, 0);

            label_areacount.Text = "";
            pictureBox_canvas.Image.Dispose();
            pictureBox_canvas.Image = new Bitmap(pictureBox_canvas.Width, pictureBox_canvas.Height);
            pictureBox_canvas.Refresh();

            Pen pen = new Pen(pencolor, 2);
            Image image = pictureBox_canvas.Image;

            for (int i = 0; i < lines; i++)
            {
                Get_random_Points(ref pos1);
                Get_random_Points(ref pos2);

                while (pos1.X == pos2.X || pos1.Y == pos2.Y)
                {
                    Get_random_Points(ref pos2);
                }



                using (Graphics grahpics = Graphics.FromImage(image))
                {
                    grahpics.DrawLine(pen, pos1, pos2);
                }
                pictureBox_canvas.Image = image;
            }

            for (int i = 0; i < width-1; i++)
            {
                for (int f = 0; f < height-1; f++)
                {
                    color = GetColorAt(i, f);

                    if (color.A == 0)
                    {
                        Check_pixels(i, f);
                    }
                }
            }
            label_areacount.Text = area_count.ToString();
        }

        //-------------------------------------

        public void Get_random_Points(ref Point pos)
        {
            counter = rnd.Next(0, 4);
            switch (counter)
            {
                case 0:
                    pos.X = rnd.Next(0, width+1);
                    pos.Y = -1;
                    break;

                case 1:
                    pos.X = rnd.Next(0, width+1);
                    pos.Y = height+1;
                    break;

                case 2:
                    pos.Y = rnd.Next(0, height+1);
                    pos.X = -1;
                    break;

                case 3:
                    pos.Y = rnd.Next(0, height+1);
                    pos.X = width+1;
                    break;
            }
        }

        //-------------------------------------

        public Color GetColorAt(int x, int y)
        {
            return ((Bitmap)pictureBox_canvas.Image).GetPixel(x, y);
        }

        //-------------------------------------

        public void Check_pixels(int x, int y)
        {
            Color color = new Color();
            Image image = pictureBox_canvas.Image;
            List<Point> points = new List<Point>();
            points.Add(new Point(x, y));
            area_count++;

            while (points.Count != 0)
            {
                foreach(Point pnt in points)
                {
                    color = GetColorAt(pnt.X, pnt.Y);
                    if (color.A == 0)
                    {
                        using (Graphics graph = Graphics.FromImage(image))
                        {
                            Brush aBrush = (Brush)Brushes.Black;
                            graph.FillRectangle(aBrush, pnt.X, pnt.Y, 1, 1);
                        }
                    }
                }

                Direction_Check(points, color, -1, 0);
                Direction_Check(points, color, 1, 0);
                Direction_Check(points, color, 0, 1);
                Direction_Check(points, color, 0, -1);
                points.RemoveAt(0);               
            }
            pictureBox_canvas.Image = image;           
        }

        //-------------------------------------

        public void Direction_Check(List<Point>points, Color color, int to_x, int to_y)
        {
            if (points[0].X + to_x >= 0 && points[0].Y + to_y >= 0 &&
                points[0].X + to_x <= width-1 && points[0].Y + to_y <= height-1)
            {
                color = GetColorAt(points[0].X + to_x, points[0].Y + to_y);

                if (color.A == 0 && color.R == 0 && color.G == 0 && color.B == 0)
                {
                    points.Add(new Point(points[0].X + to_x, points[0].Y + to_y));
                }
            }
        }

        //-------------------------------------

        private void textBox_linecount_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(textBox_linecount.Text, out lines);
            label_linecount.Text = lines.ToString();
        }
    }
}
vote_ok
von hollst (13980 Punkte) - 15.10.2017 um 18:21 Uhr
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

/*
        Install NuGet  
        Open your Visual Studio.  
        Open your solution/project.  
        Open Tools menu, select Library Package Manager and select Package Manager Console
        Run the following command "Install-Package Extended.Wpf.Toolkit" 
 */

namespace aufgabe_190
{
    public partial class MainWindow : Window
    {
        public String NL = Environment.NewLine, LZ = " ";

        public Boolean bo_init_ready = false, bo_is_loaded = false;
        public MainWindow()
        {
            InitializeComponent();
            column1.Width = new GridLength(0, GridUnitType.Star);
            update_gui();
            bo_init_ready = true;
            System.Windows.Forms.Application.DoEvents();
            this.bt_solve.IsEnabled = false;
            this.bt_refresh.IsEnabled = false;
        }

        Int32 N             = 10;
        Double factor       = 500;
        Int32 rect_Margin   = 150;
        Double lmin         = 1E-3;

        Double[][] abstandsmatrix;
        MyLine Quadrat;
        MyLine[] lines;
        List<Point> ListSchnittpunkte, ListUparteteSchnittpunkte, ListBorderpoints;

        private void b1_Click(object sender, RoutedEventArgs e)
        {
            do
            {
                System.Windows.Forms.Application.DoEvents();
                Thread.Sleep(1000);

                this.bt_solve.IsEnabled = true;
                this.bt_refresh.IsEnabled = true;
                this.b2_Click(null, null);
                this.tb2.Clear();
                update_gui();
                int loop_counter = 0;
                do
                {
                    loop_counter++;
                    Quadrat = new MyLine();
                    lines = Quadrat.RandomLines(N);
                    ListSchnittpunkte = Quadrat.ListSchnittpunkte(lines);
                    abstandsmatrix = Quadrat.Abstandsmatrix(ListSchnittpunkte, this.lmin);
                    ListUparteteSchnittpunkte = new List<Point>(Quadrat.upnormal_schnittpunkte);
                    ListBorderpoints = new List<Point>(Quadrat.borderpoints);
                    this.tb2.Text = loop_counter.ToString("n0");
                    System.Windows.Forms.Application.DoEvents();
                    if (loop_counter == 10000) break;
                }
                while ((abstandsmatrix.CountsLessThan(lmin) == 0) && (Boolean)this.cb1.IsChecked);

                this.tb1.Text =
                    "Linien: " + lines.Length.ToString() + NL + NL + lines.LineToString() + NL +
                    "Schnittpunkte: " + ListSchnittpunkte.Count.ToString() + NL + NL + ListSchnittpunkte.PointListToString() + NL +
                    "Abstandsmatrix: Anzahl Schnittpunktabstände kleiner als " + lmin.ToString() + ": " +
                        abstandsmatrix.CountsLessThan(lmin).ToString() +
                        NL + Quadrat.upnormal_schnittpunkte.PointListToString() +
                        NL + abstandsmatrix.DoubleMatrixToString();
                this.tb2.Text += LZ + (ListSchnittpunkte.Count + N + 1).ToString("X4") + LZ + ListUparteteSchnittpunkte.Count.ToString("X4");

                bt_refresh_Click(null, null);
            } while (false);
        }

        private void DrawRect()
        {
            Rectangle rect = new Rectangle            {
                Stroke = Brushes.Red,
                StrokeThickness = 1
            };

            rect.Margin = new Thickness(rect_Margin);
            rect.Width = factor;
            rect.Height = factor;
            SolidColorBrush mySolidColorBrush = new SolidColorBrush();
            mySolidColorBrush.Color = Brushes.Beige.Color;// Azure.Color;
            rect.Fill = mySolidColorBrush;
            this.canvas1.Children.Add(rect);
        }

        private void DrawText(Double[][] abstandsmatrix, MyLine[] lines, List<Point> ListSchnittpunkte)
        {
            TextBlock textBlock = new TextBlock();
            if (abstandsmatrix.CountsLessThan(lmin) == 0)
                textBlock.Text = (lines.Length + 1 + ListSchnittpunkte.Count).ToString("n0") + " area segments";
            else
                textBlock.Text = "degeneracy";

            textBlock.Foreground = new SolidColorBrush(Brushes.Blue.Color);
            textBlock.FontSize = 20;
            textBlock.FontWeight = FontWeights.UltraBold;
            textBlock.Margin = new Thickness(this.rect_Margin, this.factor + this.rect_Margin + textBlock.FontSize, 0, 0);

            this.canvas1.Children.Add(textBlock);
        }

        private void DrawLines(MyLine[] L, Double factor, int farbindex, Double linienstaerke, Int32 abstand00)
        {
            for (var i = 0; i < L.Length; i++)
            {
                Line myLine = new Line();
                myLine.Stroke = System.Windows.Media.Brushes.Black;
                if (farbindex == 1)
                    myLine.Stroke = System.Windows.Media.Brushes.Blue;
                if (farbindex == 2)
                    myLine.Stroke = System.Windows.Media.Brushes.Red;

                myLine.X1 = factor * L[i].p0.X + abstand00;
                myLine.X2 = factor * L[i].p1.X + abstand00;
                myLine.Y1 = factor * L[i].p0.Y + abstand00;
                myLine.Y2 = factor * L[i].p1.Y + abstand00;
                myLine.StrokeThickness = linienstaerke;
                this.canvas1.Children.Add(myLine);
            }
        }

        private void DrawCircles(List<Point> L, Brush farbindex, Double durchmesser, Double linienstaerke, Boolean bo_fill = false)
        {
            for (var i = 0; i < L.Count; i++)
            {
                Ellipse myEllipse = new Ellipse();
                //myEllipse.Stroke = System.Windows.Media.Brushes.Black;
                myEllipse.Stroke = farbindex;
                //if (farbindex == 1)
                //    myEllipse.Stroke = System.Windows.Media.Brushes.Blue;
                //if (farbindex == 2)
                //    myEllipse.Stroke = System.Windows.Media.Brushes.Red;
                myEllipse.StrokeThickness = linienstaerke;
                myEllipse.Width = durchmesser;
                myEllipse.Height = myEllipse.Width;
                if(bo_fill) myEllipse.Fill = farbindex;
                myEllipse.Margin = new Thickness(factor * L[i].X + rect_Margin - myEllipse.Width / 2, factor * L[i].Y + rect_Margin - myEllipse.Width / 2, 0, 0);
                this.canvas1.Children.Add(myEllipse);
            }
        }

        private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            System.Windows.Point pos = e.GetPosition(this.canvas1);
            this.tb2.Text = ((pos.X - rect_Margin) / factor).ToString("0.0000").Digits(8) + " " + ((pos.Y - rect_Margin) / factor).ToString("0.0000").Digits(8);
            this.tb1.Text += NL + this.tb2.Text;
        }

        private void b2_Click(object sender, RoutedEventArgs e)
        {
            this.tb1.Clear(); this.tb2.Clear(); this.canvas1.Children.Clear();
            column1.Width = new GridLength(0, GridUnitType.Star);
        }

        private void myUpDownControl_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            this.N = (Int32)myUpDownControl.Value;
        }

        private void myUpDownControl1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            this.factor = (Double)myUpDownControl1.Value;
        }

        private void myUpDownControl2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            this.rect_Margin = (Int32)myUpDownControl2.Value;
        }

        private void bt_refresh_Click(object sender, RoutedEventArgs e)
        {
            if (!bt_refresh.IsEnabled)
                return;
            ListSchnittpunkte = Quadrat.ListSchnittpunkte(lines);
            abstandsmatrix = Quadrat.Abstandsmatrix(ListSchnittpunkte, this.lmin);
            ListUparteteSchnittpunkte = new List<Point>(Quadrat.upnormal_schnittpunkte);
            ListBorderpoints = new List<Point>(Quadrat.borderpoints);
            
            this.canvas1.Children.Clear();
            DrawRect();
            DrawLines(lines, this.factor, 2, 1, this.rect_Margin);
            if ((Boolean)this.cb3.IsChecked) DrawCircles(ListSchnittpunkte, System.Windows.Media.Brushes.Red, 10, 1);
            DrawCircles(ListUparteteSchnittpunkte, System.Windows.Media.Brushes.Red, 50, 5);
            if ((Boolean)this.cb4.IsChecked) DrawCircles(ListBorderpoints, System.Windows.Media.Brushes.Black, 10, 1, bo_fill: true);
            column1.Width = new GridLength(0, GridUnitType.Star);
        }

        private void cb_intersection_exact_Click(object sender, RoutedEventArgs e)
        {
            update_gui();
        }

        private void myUpDownControl3_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (bo_init_ready)
                update_gui(); 
        }

        private void b3_Click(object sender, RoutedEventArgs e)
        {
            DrawText(abstandsmatrix, lines, ListSchnittpunkte);
        }        

        private void update_gui()
        {
            if ((Boolean)cb_intersection_exact.IsChecked)
            {                
                this.myUpDownControl3.Visibility = Visibility.Hidden;
                this.label_myUpDownControl3.Visibility = Visibility.Hidden;
                this.lmin = 0;
            }
            else
            {
                this.myUpDownControl3.Visibility = Visibility.Visible;
                this.label_myUpDownControl3.Visibility = Visibility.Visible;
                this.lmin = 1.0E-6 * (Int32)myUpDownControl3.Value;
            }
            System.Windows.Forms.Application.DoEvents();
        }
    }

    public class Point
    {
        public Double X;
        public Double Y;

        public Point(Double x, Double y)
        {
            this.X = x;
            this.Y = y;
        }

        public Point() { }
    }

    public class MyLine
    {
        private Random rand = new Random();

        public Double a, b;
        public Point p0 = new Point(), p1 = new Point();
        public List<Point> schnittpunkte = new List<Point>();
        public List<Point> borderpoints = new List<Point>();
        public List<Point> upnormal_schnittpunkte = new List<Point>();
        public Double upnormal_abstand = 0.0;

        public MyLine() { }

        public MyLine(Point p0, Point p1)
        {
            double dx = p1.X - p0.X;
            double dy = p1.Y - p0.Y;
            if (dx == 0.0)
            {
                this.b = Double.PositiveInfinity;
                this.a = p1.X;
            }
            else
            {
                this.b = dy / dx;
                this.a = (p0.Y * p1.X - p1.Y * p0.X) / dx;
            }
        }

        public MyLine[] RandomLines(int N, Double h = 1.0)
        {
            borderpoints = new List<Point>();
            MyLine[] result = new MyLine[N];
            for (var i = 0; i < N; i++)
            {
                int kante1 = rand.Next(4);
                int kante2 = kante1;
                while (kante2 == kante1)
                    kante2 = rand.Next(4);
                double x1 = rand.NextDouble();
                double x2 = rand.NextDouble();
                Point p0 = new Point(), p1 = new Point();
                switch (kante1)
                {
                    case 0: p0 = new Point(x1, 0.0); break;
                    case 1: p0 = new Point(1.0, x1); break;
                    case 2: p0 = new Point(1.0 - x1, 1.0); break;
                    case 3: p0 = new Point(0.0, 1.0 - x1); break;
                }
                switch (kante2)
                {
                    case 0: p1 = new Point(x2, 0.0); break;
                    case 1: p1 = new Point(1.0, x2); break;
                    case 2: p1 = new Point(1.0 - x2, 1.0); break;
                    case 3: p1 = new Point(0.0, 1.0 - x2); break;
                }

                result[i] = new MyLine(p0, p1);
                borderpoints.Add(p0); borderpoints.Add(p1);
                result[i].p0 = p0;
                result[i].p1 = p1;
            }
            Point plo = new Point(0.0, 0.0);
            Point pro = new Point(0.0, 1.0);
            Point plu = new Point(1.0, 0.0);
            Point pru = new Point(1.0, 1.0);
            borderpoints.Add(plo); borderpoints.Add(pro); borderpoints.Add(plu); borderpoints.Add(pru);
            return result;
        }

        public Point Schnittpunkt(MyLine L1, MyLine L2)
        {
            Point result = new Point(Double.PositiveInfinity, Double.PositiveInfinity);

            if (L1.b == L2.b)
                return result;

            if ((L1.b == Double.PositiveInfinity) || (L2.b == Double.PositiveInfinity))
            {
                if (L1.b == Double.PositiveInfinity)
                {
                    result.X = L1.a;
                    result.Y = L2.a + L2.b * result.X;
                }
                else
                {
                    result.X = L2.a;
                    result.Y = L1.a + L1.b * result.X;
                }
                return result;
            }

            Double da = L2.a - L1.a, db = L2.b - L1.b;
            if (db == 0)
                return result;
            else
            {
                result.X = -da / db;
                result.Y = L1.a + L1.b * result.X;
            }
            return result;
        }

        public List<Point> ListSchnittpunkte(MyLine[] L, Double h = 1.0)
        {
            List<Point> result = new List<Point>();
            for(var i = 0; i < L.Length - 1; i++)
                for(var j = i + 1; j < L.Length; j++)
                {
                    Point s = Schnittpunkt(L[i], L[j]);
                    if ((s.X > 0.0) && (s.X < h) && (s.Y > 0.0) && (s.Y < h))
                        result.Add(s);
                }
            return result;
        }

        public Double[][] Abstandsmatrix(List<Point> L, Double upnormal_abstand)
        {
            this.upnormal_abstand = upnormal_abstand;
            upnormal_schnittpunkte = new List<Point>();

            Double[][] result = new Double[L.Count][];
            for(var i = 0; i < L.Count; i++)            {
                result[i] = new Double[L.Count];                
                for (var j = 0; j < result[i].Length; j++)
                {
                    Double dx = L[i].X - L[j].X, dy = L[i].Y - L[j].Y;
                    result[i][j] = Math.Sqrt(dx * dx + dy * dy);
                    if((i < j) && (result[i][j] < upnormal_abstand))
                        upnormal_schnittpunkte.Add(L[j]);
                }
            }
            return result;
        }
    }

    public static class MySpecialTools
    {
        public static string LZ = " ";

        public static string LineToString(this MyLine L)
        {
            StringBuilder sb = new StringBuilder();
            int nk = 8, digits = 11;
            string f = "0.";
            for (var i = 0; i < nk; i++)
                f += "0";
            sb.AppendLine(L.p0.X.ToString(f).Digits(digits) + LZ + L.p0.Y.ToString(f).Digits(digits) + LZ + L.p1.X.ToString(f).Digits(digits) + LZ + L.p1.Y.ToString(f).Digits(digits) +
                "    a: " + L.a.ToString(f).Digits(digits) + "  b: " + L.b.ToString(f).Digits(digits));
            return sb.ToString();
        }

        public static string LineToString(this MyLine[] L)
        {
            StringBuilder sb = new StringBuilder();
            for (var i = 0; i < L.Length; i++)
                sb.Append(L[i].LineToString());
            return sb.ToString();
        }

        public static string PointListToString(this List<Point> L)
        {
            StringBuilder sb = new StringBuilder();
            for (var i = 0; i < L.Count; i++)
                sb.AppendLine(L[i].X.ToString("0.0000").Digits(8) + LZ + L[i].Y.ToString("0.0000").Digits(8));
            return sb.ToString();
        }

        public static string Digits(this string s, int digits)
        {
            string result = s;
            while (result.Length < digits)
                result = " " + result;
            return result;
        }

        public static string DoubleMatrixToString(this Double[][] M, 
            String LK = "[", String RK = "]", String Trenner = " ", Int32 nachkomma = 2, Int32 digits = 8)
        {
            StringBuilder sb = new StringBuilder();
            String f = "0."; for (var i = 0; i < nachkomma; i++) f += "0";
            for(var i = 0; i < M.Length; i++)            {
                sb.Append(LK);
                for (var j = 0; j < M[i].Length; j++)
                    sb.Append(M[i][j].ToString(f).Digits(digits));
                sb.AppendLine(RK);
            }
            return sb.ToString();
        }

        public static int CountsLessThan(this Double[][] M, Double grenze)
        {
            int result = 0;
            for (var i = 0; i < M.Length; i++)
                for (var j = i + 1; j < M[i].Length; j++)
                    if (M[i][j] < grenze) result++;
            return result;
        }
    }
}

<Window x:Class="aufgabe_190.MainWindow"                        
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:landkartenproblem_wpf"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        mc:Ignorable="d"
        Title=" AUFGABE 190" Height="802.87" Width="1129.766" FontFamily="Courier New" WindowState="Maximized">
    <Grid>
        <TabControl x:Name="tabControl" Margin="0" TabStripPlacement="Bottom">
            <TabItem Header=" main ">
                <Grid Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="200"/>
                        <ColumnDefinition Width="100*" Name="column1"/>
                        <ColumnDefinition Width="100*"/>
                    </Grid.ColumnDefinitions>
                    <GridSplitter x:Name="gridSplitter" Grid.Column="2" Margin="0" Grid.RowSpan="2" Width="5" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" ResizeDirection="Columns" HorizontalAlignment="Left"/>
                    <Canvas x:Name="canvas1" Grid.Column="2" Margin="20,15,15,15" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" MouseLeftButtonDown="canvas1_MouseLeftButtonDown" Width="900" Height="900" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    <StackPanel>
                        <GroupBox Header="commands" Margin="5" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}">
                            <StackPanel>
                                <Button x:Name="b2" Content="  clear  " Margin="5,15,5,15" Click="b2_Click" HorizontalAlignment="Center" FontWeight="Normal" FontSize="12"/>

                                <Button x:Name="b1" Content="  draw   " Margin="5" Click="b1_Click" HorizontalAlignment="Center" FontWeight="Normal" FontSize="12"/>

                                <Button x:Name="bt_solve" Content="  solve  " Margin="5" HorizontalAlignment="Center" Click="b3_Click" FontWeight="Normal" FontSize="12" />

                                <Button x:Name="bt_refresh"    Content=" refresh " Margin="5,15,5,15" HorizontalAlignment="Center" Click="bt_refresh_Click" FontWeight="Normal" FontSize="12"/>
                            </StackPanel>
                        </GroupBox>
                        <GroupBox Margin="5" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" Header="settings" >
                            <StackPanel>
                                <Label Margin="5,5,5,0" Content="count lines (max 100)" FontSize="11" HorizontalAlignment="Left"/>
                                <xctk:IntegerUpDown Name="myUpDownControl" Maximum="100" Minimum="0" Value="10" Margin="50,0,50,5" ValueChanged="myUpDownControl_ValueChanged"/>

                                <Label Margin="5,5,5,0" Content="square border (pixel) " FontSize="11" HorizontalAlignment="Left"/>
                                <xctk:IntegerUpDown Name="myUpDownControl1" Minimum="50" Value="900" Margin="50,0,50,5" ValueChanged="myUpDownControl1_ValueChanged"/>

                                <Label Margin="5,5,5,0" Content="margin (pixel)" FontSize="11" HorizontalAlignment="Left"/>
                                <xctk:IntegerUpDown Name="myUpDownControl2" Minimum="0" Value="0" Margin="50,0,50,5" ValueChanged="myUpDownControl2_ValueChanged"/>

                                <Label Margin="5,5,5,0" Content="max inters. gap (1/10^6)" FontSize="11" HorizontalAlignment="Left" Name="label_myUpDownControl3"/>
                                <xctk:IntegerUpDown Name="myUpDownControl3" Minimum="0" Value="1000" Margin="50,0,50,15" ValueChanged="myUpDownControl3_ValueChanged" />

                            </StackPanel>
                        </GroupBox>

                        <GroupBox Header="options" Margin="5" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}">
                            <StackPanel>
                                <StackPanel Grid.Column="0" Grid.ColumnSpan="1" Orientation="Horizontal" Width="190">
                                    <Label Margin="5,5,5,0" Content="intersections exact" FontSize="11" VerticalAlignment="Center"/>
                                    <CheckBox x:Name="cb_intersection_exact"  HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0" Click="cb_intersection_exact_Click" />
                                </StackPanel>
                                <StackPanel Grid.Column="0" Grid.ColumnSpan="1" Orientation="Horizontal" Width="190">
                                    <Label Margin="5,5,5,0" Content="generate degeneracy" FontSize="11" VerticalAlignment="Center"/>
                                    <CheckBox x:Name="cb1"  HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0"/>
                                </StackPanel>
                                <StackPanel Grid.Column="0" Grid.ColumnSpan="1" Orientation="Horizontal" Width="190">
                                    <Label Margin="5,5,5,0" Content="show intersections " FontSize="11" VerticalAlignment="Center"/>
                                    <CheckBox x:Name="cb3"  HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0" Click="bt_refresh_Click"/>
                                </StackPanel>
                                <StackPanel Grid.Column="0" Grid.ColumnSpan="1" Orientation="Horizontal" Width="190">
                                    <Label Margin="5,5,5,0" Content="show border points " FontSize="11" VerticalAlignment="Center"/>
                                    <CheckBox x:Name="cb4"  HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0" Click="bt_refresh_Click"/>
                                </StackPanel>

                            </StackPanel>
                        </GroupBox>
                        <Label Margin="5,5,5,0"     Content=" intern infos " FontSize="11" />
                        <TextBox x:Name="tb2" Margin="10,5,18,5" TextWrapping="Wrap" AcceptsReturn="True" AcceptsTab="True" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/>
                    </StackPanel>
                    <TextBox x:Name="tb1" Grid.Column="1" Margin="5" Text="TextBox" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" AcceptsTab="True"/>
                </Grid>
            </TabItem>
            <TabItem Header=" reserve ">
                <Grid Background="#FFE5E5E5"/>

            </TabItem>
        </TabControl>

    </Grid>
</Window>
1x
vote_ok
von daniel59 (4260 Punkte) - 23.10.2017 um 08:26 Uhr
MainWindow.xaml.cs
Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfFlaechensegmenteZaehlen
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        static readonly Random rnd = new Random();

        static readonly MathLine[] testLines1 =
        {
            new MathLine(new Point(0,0), new Point(size,size)),
            new MathLine(new Point(0,size/2), new Point(size,size/2)),
            new MathLine(new Point(0,size), new Point(size,0)),
            new MathLine(new Point(size/2, 0), new Point(size/2,size))
        };

        const int size = 500;

        private List<MathLine> lines;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Draw(int lines)
        {
            canvas.Children.Clear();
            this.lines = new List<MathLine>();
            for (int i = 0; i < lines; i++)
            {
                Point start = new Point(), end = new Point();

                int startside = rnd.Next(0, 4);
                switch (startside)
                {
                    case 0://links
                        start = new Point(0, rnd.Next(0, size + 1));
                        break;

                    case 1://oben
                        start = new Point(rnd.Next(0, size + 1), 0);
                        break;

                    case 2://rechts
                        start = new Point(size, rnd.Next(0, size + 1));
                        break;

                    case 3://unten
                        start = new Point(rnd.Next(0, size + 1), size);
                        break;
                }

                int endside = startside;
                while (endside == startside)
                {
                    endside = rnd.Next(0, 4);
                }
                switch (endside)
                {
                    case 0://links
                        end = new Point(0, rnd.Next(0, size + 1));
                        break;

                    case 1://oben
                        end = new Point(rnd.Next(0, size + 1), 0);
                        break;

                    case 2://rechts
                        end = new Point(size, rnd.Next(0, size + 1));
                        break;

                    case 3://unten
                        end = new Point(rnd.Next(0, size + 1), size);
                        break;
                }

                MathLine ml = new MathLine(start, end);//testLines1[i];
                Line l = new Line()
                {
                    X1 = ml.Start.X,
                    Y1 = ml.Start.Y,
                    X2 = ml.End.X,
                    Y2 = ml.End.Y,

                    Stroke = Brushes.DarkOrange,
                    StrokeThickness = 2
                };
                this.lines.Add(ml);
                canvas.Children.Add(l);
            }
        }

        private void CountSegments()
        {
            var intersections = GetIntersections();
            int segments = lines.Count + 1 + intersections.Count();

            MessageBox.Show($"{segments} Segmente gefunden");
        }

        private IEnumerable<Point> GetIntersections()
        {
            List<MathLine> used = new List<MathLine>();
            List<Intersection> result = new List<Intersection>();
            foreach (var line in lines)
            {
                used.Add(line);
                var intersections = from l in lines.Except(used)
                                    let i = MathLine.GetIntersection(line, l)
                                    where i != null
                                    let p = i.Point
                                    where p.X >= 0 && p.Y >= 0 && p.X <= size && p.Y <= size
                                    select i;
                foreach (var i in intersections)
                {
                    if (!result.Contains(i))
                    {
                        result.Add(i);
                        yield return i; 
                    }
                }
            }
        }

        private void buttonDraw_Click(object sender, RoutedEventArgs e)
        {
            int l;
            if (int.TryParse(textBoxLines.Text, out l) && l > 0)
            {
                Draw(l);
            }
        }

        private void buttoCount_Click(object sender, RoutedEventArgs e)
        {
            CountSegments();
        }
    }

    public class MathLine
    {
        public Point Start { get; set; }
        public Point End { get; set; }

        public double m => (End - Start).Y / (End - Start).X;
        public double b => Start.Y - m * Start.X;

        public MathLine(Point start, Point end)
        {
            Start = start;
            End = end;
        }

        public static Intersection GetIntersection(MathLine g, MathLine h)
        {
            double mg = g.m;
            double bg = g.b;

            double mh = h.m;
            double bh = h.b;

            if (mh == mg)
            {
                return null;//new Point(-1, -1);
            }
            if (double.IsInfinity(g.m))
            {
                return new Intersection(new Point(g.Start.X, g.Start.X * h.m + h.b), g, h);
            }
            else if (double.IsInfinity(h.m))
            {
                return new Intersection(new Point(h.Start.X, h.Start.X * g.m + g.b), g, h);
            }

            double x = (bh - bg) / (mg - mh);
            double y = mg * x + bg;

            return new Intersection(new Point(x, y), g, h);
        }
    }

    public class Intersection
    {
        public Point Point { get; set; }
        public MathLine FirstLine { get; set; }
        public MathLine SecondLine { get; set; }

        public Intersection(Point p, MathLine l1, MathLine l2)
        {
            Point = p;
            FirstLine = l1;
            SecondLine = l2;
        }

        public override bool Equals(object obj)
        {
            Intersection i = (Intersection)obj;

            return Point == i.Point && (FirstLine == i.FirstLine || FirstLine == i.SecondLine);
        }

        public override int GetHashCode()
        {
            int hash = 13;
            hash = (hash * 7) + Point.GetHashCode();
            hash = (hash * 7) + FirstLine.GetHashCode() + SecondLine.GetHashCode();
            return hash;
        }

        public static implicit operator Point(Intersection v)
        {
            return v.Point;
        }
    }
}


MainWindow.xaml.cs
Quellcode ausblenden XML-Code
<Window x:Class="WpfFlaechensegmenteZaehlen.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfFlaechensegmenteZaehlen"
        mc:Ignorable="d"
        Title="MainWindow" Height="587" Width="533" ResizeMode="CanMinimize">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Grid.Row="0">
            <TextBlock Text="Linien" Margin="10,13,0,0"/>
            <TextBox x:Name="textBoxLines" Width="50" Text="2" Margin="10,10,0,0" TextAlignment="Center"/>
            <Button x:Name="buttonDraw" Content="Zeichnen" Width="80" Margin="10,10,0,0" Click="buttonDraw_Click"/>
            <Button x:Name="buttoCount" Content="Zählen" Width="80" Margin="10,10,0,0" Click="buttoCount_Click"/>
        </StackPanel>
        <Canvas x:Name="canvas" Height="500" Width="500" Background="AliceBlue" Margin="10" Grid.Row="1"/>
    </Grid>
</Window>