Delaunay triangulation with Bowyer-Watson: circumcircle

In my last installment, I started revisiting some old code of mine around Delaunay triangulation, the dual of a Voronoi diagram. My goal is to implement the Bowyer–Watson algorithm, and perhaps use it for procedural map generation at some point.

I will follow the pseudo-code outlined on the Wikipedia page, and work my way through it. Last time I took care of the initialization step, computing an initial super-triangle large enough to completely contain all the points:

function BowyerWatson (pointList)
    triangulation := empty triangle mesh data structure
    add super-triangle to triangulation

Today I will tackle the next step:

for each point in pointList do
    badTriangles := empty set
    for each triangle in triangulation do
        if point is inside circumcircle of triangle
            add triangle to badTriangles
More...

Delaunay triangulation with Bowyer-Watson: initial super triangle

A while ago, I got interested in Delaunay triangulation, because it seemed to be a good building block for procedural map generation, city maps in particular. I started implementing the Bowyer–Watson algorithm, but ended up putting this side-project on ice, because, well, life got busy. I had something messy somewhat working back then, and figured it would be fun to revisit that code and try to get it into shape.

In this post, I’ll revisit one minor piece of the algorithm that seemed easy, but gave me some trouble: the calculation of the so-called “super triangle”.

The algorithm is quite interesting. The first step is to compute a triangle that contains all the points we want to triangulate, adding points one by one and updating the triangulation, until there is nothing left to add. At that point, the initial triangle and anything connected to it is removed, and the triangulation is done.

Super Triangle

What I am after here is fairly simple: given a collection of points on the plane, find 3 points (the super triangle) that enclose every point in the list.

Let’s illustrate with an example. Suppose we have 5 points, like in the example below. The triangle ABC in yellow is a valid super triangle:

A B C More...

Async Commands with Avalonia FuncUi

Another Avalonia FuncUI post this week! One problem I struggled with initially with Avalonia FuncUI is how to handle async calls. I had some familiarity with the Elmish Cmd.OfAsync module, and wanted to use that if possible (Maxime Mangel has a great post on Cmd and how to use them, if you are curious).

Anyways, using Cmd.OfAsync and its cousin Cmd.OfTask in Avalonia FuncUI is what we will cover in today’s installment!

Without further due, let’s dive in, starting with a very basic example, without anything async to begin with. Our example app will have just a TextBox, where the text of a “Request” can be entered, and a Button, which will send the “Request”, and return a “Response”, a string, which we will display back to our user.

simple app with one input and one button

We’ll start synchronous, and work our way up to asynchronous commands.

More...

Maintainable Avalonia FuncUI screen layouts with DockPanels and Borders

I have been using Avalonia FuncUI quite a bit lately, to develop Windows desktop clients for 2 applications. The UI for these applications is not particularly fancy: select items using listboxes, edit the selected item, and save it, that kind of thing.

As these applications grew, the screens grew in complexity, and I realized that I was struggling a bit when I wanted to re-arrange their layout. The problem was not caused by FuncUI, but rather by how I was using controls, creating layouts that ended up being hard to refactor or re-arrange.

In this post, I will go over what I ended up doing. It’s not particularly earth shattering, but who knows - it might help someone out there avoid some of the pain I went through :)

More...

Micro optimizing F# code with a dash of imperative code

In addition to re-designing my Nelder-Mead solver to improve usability, I have also recently dedicated some time looking into performance improvements. This is usually not my primary concern: I tend to focus first on readability and correctness first, and address performance issues later.

However, in the case of a solver, performance matters. In my specific case, the solver works as a loop, iteratively updating a candidate solution until it is good enough. Anything that can speed up that loop will directly speed up the overall solver, so it is worth making sure the code is as efficient as can be.

One particular code area I worked on is the solver termination rule. The changes I made resulted in a significant speedup (roughly 10x), at the expense of style: the final version does not look like idiomatic F# at all. In this post, I will go over these changes.

More...