简体   繁体   中英

How to fill a WPF window with triangles that don't cover each other?

Please see my code below.

I'm using a DispatcherTimer in order to fill a grid with triangles. My problem is that some of the triangles created by my code cover eavch other. How to modify the code to make sure this will not happen? I want them to be located next to each other and with time to cover the entire window, but without cover one another.

    Random rnd = new Random();

    DispatcherTimer Timer = new DispatcherTimer();

    List<Point> Points = new List<Point>();
    public MainWindow()
    {
        InitializeComponent();
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        ((Button)(sender)).Visibility = Visibility.Hidden;
        Timer.Interval = new TimeSpan(0,0,1);
        Timer.Tick += Timer_Tick;
        Timer.Start();

    }

    void Timer_Tick(object sender, EventArgs e)
    {
        if (Points.Count == 0)
        {
            Point P1 = new Point( rnd.Next(1000), rnd.Next(800));
            Point P2 = new Point(rnd.Next(1000), rnd.Next(800));
            Points.Add(P1);
            Points.Add(P2);
        }
        int First = rnd.Next(Points.Count);
        int Second = rnd.Next(Points.Count);
        while (Second==First)
        {
            Second = rnd.Next(Points.Count);
        }
        Point NewPoint = new Point(rnd.Next(1000), rnd.Next(800));
        Points.Add(NewPoint);

        Polygon Poly = new Polygon();
        Poly.Points.Add(Points[First]);
        Poly.Points.Add(Points[Second]);
        Poly.Points.Add(NewPoint);
        Poly.StrokeThickness = 1.5;
        Poly.Stroke = Brushes.Black;
        int FillColor = rnd.Next(3);
        switch (FillColor)
        {
            case 0:
                Poly.Fill = Brushes.Red;
                break;
            case 1:
                Poly.Fill = Brushes.Yellow;
                break;
            default:
                Poly.Fill = Brushes.Lime;
                break;
        }
        G1.Children.Add(Poly);

    }

You're just creating triangles at random points and hoping they don't overlay? To make sure they don't overlay you either need to:

  1. -

    create them in a regular way (equilateral triangles can be placed next to each other in a regular programmatic way that can cover a rectangular area completely)

  2. -

    if the triangles are going to be completely different sizes/types then good luck! You'll need to do some maths for volume collision detection, or maybe something more ALife like and try to solve a placement problem.

I dont think you realize the complexity of your problem. You want to triangulate randomly the window in addition to get only one triangle at a time and to be neighbour. I think it is hardly possible with this apporoach. I would rather try this:

  • generate random number of points (add corners as points as well)
  • triangulate those points with an algoritmth and store neighbour triangles info
  • choose random starting triangle and draw it
  • choose random triangle from your TIN which is neighbour to any already drawn triangle and draw it
  • continue untill all your triangles were drawn

At the moment you are generating random triangles as you go along. You seem to picking two previous points randomly from the list of points so far then and generating a new point randomly to make the triangle. Your problem obivously is that the new random point needs to consider if it is going to overlay an existing triangle or not, and as time goes on that decision gets harder and harder.

You need a different algorithm.

Firstly while developing this, don't worry about the timer tick part. You want to generate your entire set of triangles up front and then just use timer tick to draw them, but while you are developing this, just calculate them, then draw the lot at once.

Now we need a reasonable algorithm to create triangles. Random will simply get more complicated as you go along. Here are a couple of ideas based on the fact that a rectangle can be split into 2 triangles.

  1. Take a rectangle. Split it diagonally into two triangles. Keep splitting the triangles into half into you think you have enough.

  2. For an irregular result. Imagine a grid that is at least one cell bigger than your window all the way round, but wobble the points of the grid so that they move by up to half the cell size in all directions. Randomly divide each cell into two triangles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM