Newsgroups: comp.lang.c,comp.graphics.algorithms,sci.image.processing
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news.mathworks.com!uunet!in1.uu.net!usc!news.isi.edu!gremlin!charming!mcohen
From: mcohen@charming.nrtc.northrop.com (Martin Cohen)
Subject: Re: Sorting points to follow an edge?
Message-ID: <D4BD7K.L6n@gremlin.nrtc.northrop.com>
Sender: news@gremlin.nrtc.northrop.com (Usenet News Manager)
Organization: Northrop Grumman Automation Sciences Laboratory, Pico Rivera, CA
References: <3hk421$epj@mozo.cc.purdue.edu>
Date: Mon, 20 Feb 1995 19:38:08 GMT
Lines: 74
Xref: glinda.oz.cs.cmu.edu comp.lang.c:128273 comp.graphics.algorithms:13521 sci.image.processing:12786

In article <3hk421$epj@mozo.cc.purdue.edu> jonesbr@cartoon.ecn.purdue.edu (Brian R. Jones) writes:
>I am trying to find an efficient algorithim to sort a set of points so
>that they are ordered from top to bottom to follow the edge that they
>represent.  I basically have two vectors of floating point numbers, one
>x and one y, whose index corresponds to a given point location on the
>edge of an object.  Originally, they are sorted first by increasing x
>value and then by increasing y value for a given x.  I assume that from
>a practical standpoint, they might as well be considered unordered.  My
>edges don't form any particular shape so it is rather difficult.  Has
>anyone done something like this or have any C or Fortran code snippets
>lying around that tackle this problem?  Thanks!
>
>-Brian
>

Sounds like you want to find the "minimal spanning tree"
of the set of points. This is the tree of shortest length
that connects all the points.

Fortunately, this problem is solvable in time n^2, where
n is the number of points.

One implementation is in Combinatorial Algorithms, 2nd ed, by
Nijenhuis and Wilf, pages 283-287. It's surprisingly short (and in
Fortran).  It uses an array that contains the distance between each
pair of points, but this can easily be changed to have arrays of (x,
y) locations with a distance function.

Here is my transcription (hope there are no errors!).
Sorry for all the gotos and labels, but that's the way they did it.

	subroutine minspt(n, ndim, dist, tree)
	real dist(ndim, ndim)
	integer tree(n)
c
c	n - number of vertices
c	ndim - size of dist(*, *) array - at least n
c	dist(*, *) - dist(i, j) = distince between points i and j
c	tree(*) - (i, tree(i)) is the i-th edge in the output
c		minimal tree (i=1, n-1)
c
	nm1 = n-1
	do 21 i=1, nm1
21	tree(i) = -n
	tree(n) = 0
c
	do 51 l = 1, nm1
	dmin = 1.e50
40	do 41 i = 1, nm1
	it = tree(i)
	if ( it .gt. 0 ) goto 41
	d = dist(-it, i)
	if ( d .ge. dmin ) goto 41
	dmin = d
	imin = i
41	continue
	tree(imin) = -tree(imin)
50	do 51 i = 1, nm1
	it = tree(i)
	if ( it .gt. 0 ) goto 51
	if ( dist(i, imin) .lt. dist(i, -it) ) tree(i) = -imin
51	continue
	return
	end

Once you get the minimal spanning tree, look for blocks of
connected points such that their distance is small compared
to the distances to the next closest.

Have fun!
-- 
Marty Cohen (mcohen@nrtc.northrop.com) - Not the guy in Philly
  This is my opinion and is probably not Northrop Grumman's!
          Use this material of your own free will
