Just another Perl shrine PerlMonks

### Delaunay triangulation

by tmoertel (Chaplain)
 on Aug 03, 2005 at 15:14 UTC ( #480510=note: print w/replies, xml ) Need Help??

How does the set of "unintersected edges" computed by your algorithm differ from a Delaunay triangulation? If the difference is insignificant for your application (or can be quickly computed), you might be better off starting with a fast Delaunay triangulation (e.g., using Qhull) and adapting its output to your needs.

Update: Take a look at Aurenhammer and Xu's "Optimal Triangulations". It points out that the greedy triangulation – what you are computing – is not necessarily the minimum-weight triangulation (MWT). The paper also notes, however, that for uniformly distributed point sets both the greedy and Delaunay triangulations yield satisfactory approximations to the MWT.

Second update: The following code uses Qhull and computes an (approximate) DT-derived solution almost instantly:

```#!/usr/bin/perl

# solve.pl

use warnings;
use strict;

use YAML;
use File::Temp 'tempfile';
use List::Util 'sum';

my \$points        = YAML::Load( do { local \$/; <> } );

my \$triangles     = compute_delaunay_triangulation( \$points );
my \$segs          = unique_segments( \$triangles );
my @seg_endpoints = map [ @{\$points}[@\$_] ], @\$segs;
my @seg_lengths   = map seg_length(\$_), @seg_endpoints;

my \$count = @\$segs;
my \$mean  = sum(@seg_lengths) / \$count;

print "edge count          = \$count\n";
print "average edge length = \$mean\n\n";
print "edge endpoints follow in YAML format\n\n";

print YAML::Dump( @seg_endpoints );

sub compute_delaunay_triangulation {

# use Qhull's qdelaunay for this

my (\$points) = @_;

my \$fh = tempfile();
die "cannot open tempfile: \$!" unless \$fh;

my \$pid = open my \$write_to_child, "|-";
die "cannot fork: \$!" unless defined \$pid;

if (\$pid) {  # parent
print \$write_to_child "2\n", scalar @\$points, "\n",
map "@\$_\n", @\$points;
close \$write_to_child || warn "kid exited \$?";
} else {     # child
open STDOUT, '>&', \$fh  or die "could not redirect stdout: \$!"
+;
close \$fh               or die "error on close of tempfile: \$!
+";
exec qw(qdelaunay Qt i) or die "could not exec qdelaunay: \$!";
}

wait;

seek \$fh, 0, 0 or die "could not seek to start of tempfile: \$!";
my \$results = do { local \$/; <\$fh> };
close \$fh;

(undef, my @triangles) = split /\n/, \$results;

return [ map [split], @triangles ];
}

sub unique_segments {
my (\$triangles) = @_;
my %segs;
for my \$tri (@\$triangles) {
for ([0,1],[1,2],[2,0]) {
my @points = sort @{\$tri}[@\$_];
\$segs{"@points"} = \@points;
}
}
[ values %segs ];
}

sub seg_length {
my (\$seg) = @_;
my (\$x,\$y,\$x1,\$y1) = ( \$seg->[0][0], \$seg->[0][1]
, \$seg->[1][0], \$seg->[1][1] );
sqrt( (\$x - \$x1) ** 2 + (\$y - \$y1) ** 2);
}

Example: solve dump_301.yml. Output:

```edge count          = 889
average edge length = 123.835184709118

edge endpoints follow in YAML format

---
-
- 2590
- 3183
-
- 2707
- 3257
---
-
- 2560
- 2850
-
- 2586
- 2869

... other edges omitted ...

Cheers,
Tom

Tom Moertel : Blog / Talks / CPAN / LectroTest / PXSL / Coffee / Movie Rating Decoder

Replies are listed 'Best First'.
Re: Delaunay triangulation
How does the set of "unintersected edges" computed by your algorithm differ from a Delaunay triangulation?
That's a good question. I'd never heard of Delaunay triangulation until your post, so I'm going to need to do some reading. If the answer is that it doesn't or maybe if it's even a better way to show what I'm really after (the idea of remoteness of a set of coordinates... vague enough? ;-) I may just go this route.

I admit to being somewhat of a perl biggot, however; speed in this case is really more important than my love affair with perl. This code will be triggered by a web app submittal of a file with the coords in it. Infact, speed is probally more important than finite accuracy of the stats I'm trying to produce. The end result will be used to relativally diffrenciate sets of coordinates. Or I should say it is my hope that the people who will use these number see them that way. :)

Thanks for the links and the example. I've grabbed qhull and installed it so I can play around in the next few days. I'll update when I learn some more so the next guy that does a search.

If you end up implementing Delaunay Triangulation, you may as well throw in Voronoi diagrams :-)
Re: Delaunay triangulation
by anonymized user 468275 (Curate) on Aug 03, 2005 at 16:16 UTC
I for one would agree you are right on both counts, but to paraphrase Shakespeare, 'Does a problem by any other name solve more sweetly?'

Update: To clarify what I mean: the OP knows the problem and its solution but is looking for the fastest way to achieve it with perl.

One world, one people

To clarify what I mean: the OP knows the problem and its solution but is looking for the fastest way to achieve it with perl.

How do you know what the OP knows and is looking for? Do you have some knowledge beyond what is in the original post? The OP says he is "willing to entertain ideas of differing algorithms." What makes you think otherwise?

Cheers,
Tom

I tend to side with tmoertel. I once in ages past implemented my own naive algorithm for this very thing ( O(n^3) or O(n^4), probably the same way that the OP is doing, but in AutoLISP using AutoCAD), and although I knew there must be a better way, I didn't know at the time that just knowing the name Delaunay Triangulation would've helped in finding better algorithms (and it was long before Google and probably before Al Gore invented the internet). I've since been unable to find the time to implement this in perl :-(

There was a start made on this in perl utilizing a C library, but all I see is a readme file.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://480510]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2022-12-03 09:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?