Commit 411054ad016e08590140d8b54436383662064c95
1 parent
63df1103
Exists in
master
and in
7 other branches
Adicionada a biblioteca R deldir em pacotes/rlib/win
Showing
64 changed files
with
4563 additions
and
0 deletions
Show diff stats
@@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
1 | +Entry: deldir-internal | ||
2 | +Aliases: dumpts ind.dup mid.in mnnd get.cnrind acw | ||
3 | +Keywords: internal | ||
4 | +Description: Internal deldir functions | ||
5 | +URL: ../../../library/deldir/html/deldir-internal.html | ||
6 | + | ||
7 | +Entry: deldir | ||
8 | +Aliases: deldir | ||
9 | +Keywords: spatial | ||
10 | +Description: Construct the Delaunay triangulation and the Dirichlet (Voronoi) tessellation of a planar point set. | ||
11 | +URL: ../../../library/deldir/html/deldir.html | ||
12 | + | ||
13 | +Entry: plot.deldir | ||
14 | +Aliases: plot.deldir | ||
15 | +Keywords: | ||
16 | +Description: Produce a plot of the Delaunay triangulation and Dirichlet (Voronoi) tesselation of a planar point set, as constructed by the function deldir. | ||
17 | +URL: ../../../library/deldir/html/plot.deldir.html | ||
18 | + | ||
19 | +Entry: plot.tile.list | ||
20 | +Aliases: plot.tile.list | ||
21 | +Keywords: hplot | ||
22 | +Description: Plot Dirchlet/Voronoi tiles | ||
23 | +URL: ../../../library/deldir/html/plot.tile.list.html | ||
24 | + | ||
25 | +Entry: tile.list | ||
26 | +Aliases: tile.list | ||
27 | +Keywords: spatial | ||
28 | +Description: Create a list of tiles in a tessellation. | ||
29 | +URL: ../../../library/deldir/html/tile.list.html |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +Package: deldir | ||
2 | +Version: 0.0-7 | ||
3 | +Date: 2007-11-03 | ||
4 | +Title: Delaunay Triangulation and Dirichlet (Voronoi) Tessellation. | ||
5 | +Author: Rolf Turner <r.turner@auckland.ac.nz> | ||
6 | +Maintainer: Rolf Turner <r.turner@auckland.ac.nz> | ||
7 | +Depends: R (>= 0.99) | ||
8 | +Description: Calculates the Delaunay triangulation and the Dirichlet or | ||
9 | + Voronoi tessellation (with respect to the entire plane) of a | ||
10 | + planar point set. | ||
11 | +License: GPL version 2 or newer | ||
12 | +URL: http://www.math.unb.ca/~rolf/ | ||
13 | +Packaged: Sat Nov 3 14:49:01 2007; rolf | ||
14 | +Built: R 2.6.0; i386-pc-mingw32; 2007-11-04 12:29:56; windows |
@@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
1 | +deldir Construct the Delaunay triangulation and the | ||
2 | + Dirichlet (Voronoi) tessellation of a planar | ||
3 | + point set. | ||
4 | +plot.deldir Produce a plot of the Delaunay triangulation | ||
5 | + and Dirichlet (Voronoi) tesselation of a planar | ||
6 | + point set, as constructed by the function | ||
7 | + deldir. | ||
8 | +plot.tile.list Plot Dirchlet/Voronoi tiles | ||
9 | +tile.list Create a list of tiles in a tessellation. |
@@ -0,0 +1,63 @@ | @@ -0,0 +1,63 @@ | ||
1 | +34ef60d93db4e4513ae6b13668340663 *CONTENTS | ||
2 | +ee8fe6e62e3e9bbcb23bc33ec089d31a *DESCRIPTION | ||
3 | +d8d74f53836393d466d4c787015f0bec *INDEX | ||
4 | +e5a045166078a4a7bd4663db86d87395 *Meta/Rd.rds | ||
5 | +cd368d55dede62658f2248198fa90551 *Meta/hsearch.rds | ||
6 | +366a9e3d80f846401b4bbea6cadc152a *Meta/package.rds | ||
7 | +f1e590f87144c3fc1bac5ad7ba9b43c6 *R-ex/deldir.R | ||
8 | +593a215bba63e9347baa5d20f399d843 *R-ex/plot.deldir.R | ||
9 | +21797d2ef6002f35b9539333ad936fe9 *R-ex/plot.tile.list.R | ||
10 | +93422ef22c461433627a006c688284c9 *R-ex/tile.list.R | ||
11 | +3b9c9b8cbab6a88b781daa62777d5f5c *R/deldir | ||
12 | +4e82e5306993afb8f50752201a1801bf *READ_ME | ||
13 | +af071a8a57af7c84d1333c8c402da6a0 *chtml/deldir.chm | ||
14 | +6b9d8dec2bc172cb280aa76cf285b67b *err.list | ||
15 | +b1e64b5aed9484584095ac4e02baea84 *ex.out | ||
16 | +16bd2bedcf7796770e90c3e56d22526e *help/AnIndex | ||
17 | +4d8ead26ee3fc639d613b330b6b4478e *help/deldir | ||
18 | +a84f7d114620c92c0ac0e2ea57265afa *help/deldir-internal | ||
19 | +7881f61ae9a79255ce43f0814a015899 *help/plot.deldir | ||
20 | +4a53379cb1c77bc2cf1c1c425cfbca8c *help/plot.tile.list | ||
21 | +ec37f6d9ceddf4db09dd469dedff211f *help/tile.list | ||
22 | +be17ba586ed30dd13fa15e313a6fd7bf *html/00Index.html | ||
23 | +2ab5a9ca151205217138b518e6d8405d *html/deldir-internal.html | ||
24 | +40f8a12dc94a21820c1ad4ab98886536 *html/deldir.html | ||
25 | +49398bbaf0db6df39fcdcb6f95cf593e *html/plot.deldir.html | ||
26 | +0cc37a506231a768a0bdf3aa3d9c14f5 *html/plot.tile.list.html | ||
27 | +3f9352ec46c00d0fc3f407d3103173a0 *html/tile.list.html | ||
28 | +1f390921c22e235996759df8afeb639a *latex/deldir-internal.tex | ||
29 | +6ad0d68321c5d3be37af79dce2904e68 *latex/deldir.tex | ||
30 | +375f59d2ef90cdfdbc38bb3aec3f45cb *latex/plot.deldir.tex | ||
31 | +e20c7394462a8ef65f11f3f84a2e8819 *latex/plot.tile.list.tex | ||
32 | +6d3ef222fc3e6eff800da2b0adbad24a *latex/tile.list.tex | ||
33 | +797b9359a38e5806fe599e63d173f604 *libs/deldir.dll | ||
34 | +f3c6c1feb137fadf8399c5541034d0c0 *man/deldir.Rd.gz | ||
35 | +32332f6b7cc4f78b3307c77566bb5a89 *ratfor/acchk.r | ||
36 | +5f8b878f079445829c1d9f49e31170bc *ratfor/addpt.r | ||
37 | +93ed44f787438449a98e24be66775d8b *ratfor/adjchk.r | ||
38 | +d53c2495df9c4d1f4d3fcad81e10b801 *ratfor/binsrt.r | ||
39 | +f6e55e5c74ed60b802cb2a827e597603 *ratfor/circen.r | ||
40 | +f54912f73cbfc10232547f97258e6ec6 *ratfor/cross.r | ||
41 | +43bbe616653a6276af389d5af6ff212c *ratfor/delet.r | ||
42 | +1791398b1b1e8db90ef7aca3d901246d *ratfor/delet1.r | ||
43 | +22b1b7d68d94d8d179663d3d7dbee446 *ratfor/delout.r | ||
44 | +6076c5cec0047fe59f8e151eef2041cf *ratfor/delseg.r | ||
45 | +4e775ebb151b3b47656718f9f6aefb8c *ratfor/dirout.r | ||
46 | +ab6664e97b26cd37a8a05ea814eada1d *ratfor/dirseg.r | ||
47 | +77454183e29dd932e494e9f363e7c7a0 *ratfor/dldins.r | ||
48 | +7a0cbe7ba69bc4d3758d7b467378a6a5 *ratfor/inddup.r | ||
49 | +a88b1a39361d1816685cba69561b1733 *ratfor/initad.r | ||
50 | +793f31965fd00d91904dc1145e5a5e95 *ratfor/insrt.r | ||
51 | +8d92aa51712ce4e98089b46daa29614f *ratfor/insrt1.r | ||
52 | +d393dd4b28b863d09b8940bee1e42e97 *ratfor/locn.r | ||
53 | +e6e2b439fea000bc0c4332c1332430d1 *ratfor/master.r | ||
54 | +adaef6c99448a066b58f1a07eb5d883c *ratfor/mnnd.r | ||
55 | +5e7b0ef2ba903423e2b218ca93a9a66a *ratfor/pred.r | ||
56 | +dd315504b6e25408c551b4f2aaf2927f *ratfor/qtest.r | ||
57 | +87629c704f0b27364c80453f5034f86b *ratfor/qtest1.r | ||
58 | +a8636bf7b643eca192877bc38a6f2c87 *ratfor/stoke.r | ||
59 | +6d1ed8f4862aea3c6cd9a28179c51ddf *ratfor/succ.r | ||
60 | +d2d7a614a5ce8ff20006261ac1db36a5 *ratfor/swap.r | ||
61 | +182455cc37ee801235629c44f0277830 *ratfor/testeq.r | ||
62 | +5264af03d65005c360f831afc0b5d160 *ratfor/triar.r | ||
63 | +9afccbeef89e96ce284f18504820e8a0 *ratfor/trifnd.r |
No preview for this file type
No preview for this file type
No preview for this file type
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +### Name: deldir | ||
2 | +### Title: Construct the Delaunay triangulation and the Dirichlet (Voronoi) | ||
3 | +### tessellation of a planar point set. | ||
4 | +### Aliases: deldir | ||
5 | +### Keywords: spatial | ||
6 | + | ||
7 | +### ** Examples | ||
8 | + | ||
9 | +x <- c(2.3,3.0,7.0,1.0,3.0,8.0) | ||
10 | +y <- c(2.3,3.0,2.0,5.0,8.0,9.0) | ||
11 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
12 | +# Puts dummy points at the corners of the rectangular | ||
13 | +# window, i.e. at (0,0), (10,0), (10,10), and (0,10) | ||
14 | +## Not run: | ||
15 | +##D try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr') | ||
16 | +## End(Not run) | ||
17 | +# Plots the triangulation which was created (but not the tesselation). | ||
18 | + | ||
19 | + | ||
20 | + |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +### Name: plot.deldir | ||
2 | +### Title: Produce a plot of the Delaunay triangulation and Dirichlet | ||
3 | +### (Voronoi) tesselation of a planar point set, as constructed by the | ||
4 | +### function deldir. | ||
5 | +### Aliases: plot.deldir | ||
6 | + | ||
7 | + | ||
8 | +### ** Examples | ||
9 | + | ||
10 | +## Not run: | ||
11 | +##D try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
12 | +##D plot(try) | ||
13 | +##D # | ||
14 | +##D deldir(x,y,list(ndx=4,ndy=4),plot=TRUE,add=TRUE,wl='te', | ||
15 | +##D col=c(1,1,2,3,4),num=TRUE) | ||
16 | +##D # Plots the tesselation, but does not save the results. | ||
17 | +##D try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr', | ||
18 | +##D wp='n') | ||
19 | +##D # Plots the triangulation, but not the points, and saves the returned | ||
20 | +##D structure. | ||
21 | +## End(Not run) | ||
22 | + | ||
23 | + | ||
24 | + |
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +### Name: plot.tile.list | ||
2 | +### Title: Plot Dirchlet/Voronoi tiles | ||
3 | +### Aliases: plot.tile.list | ||
4 | +### Keywords: hplot | ||
5 | + | ||
6 | +### ** Examples | ||
7 | + | ||
8 | + x <- runif(20) | ||
9 | + y <- runif(20) | ||
10 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
11 | + w <- tile.list(z) | ||
12 | + plot(w) | ||
13 | + ccc <- heat.colors(20) # Or topo.colors(20), or terrain.colors(20) | ||
14 | + # or cm.colors(20), or rainbox(20). | ||
15 | + plot(w,polycol=ccc,close=TRUE) | ||
16 | + | ||
17 | + | ||
18 | + |
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +### Name: tile.list | ||
2 | +### Title: Create a list of tiles in a tessellation. | ||
3 | +### Aliases: tile.list | ||
4 | +### Keywords: spatial | ||
5 | + | ||
6 | +### ** Examples | ||
7 | + | ||
8 | + x <- runif(20) | ||
9 | + y <- runif(20) | ||
10 | + z <- deldir(x,y) | ||
11 | + w <- tile.list(z) | ||
12 | + | ||
13 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
14 | + w <- tile.list(z) | ||
15 | + | ||
16 | + z <- deldir(x,y,rw=c(0,1,0,1),dpl=list(ndx=2,ndy=2)) | ||
17 | + w <- tile.list(z) | ||
18 | + | ||
19 | + | ||
20 | + | ||
21 | + |
@@ -0,0 +1,520 @@ | @@ -0,0 +1,520 @@ | ||
1 | +.packageName <- "deldir" | ||
2 | +.First.lib <- function(lib,pkg) { | ||
3 | + library.dynam("deldir", pkg, lib) | ||
4 | + ver <- read.dcf(file.path(lib, pkg, "DESCRIPTION"), "Version") | ||
5 | + cat(paste(pkg, ver, "\n")) | ||
6 | +} | ||
7 | +acw <- function(xxx) { | ||
8 | +xbar <- mean(xxx$x) | ||
9 | +ybar <- mean(xxx$y) | ||
10 | +theta <- atan2(xxx$y - ybar,xxx$x-xbar) | ||
11 | +theta <- ifelse(theta > 0, theta, theta + 2 * pi) | ||
12 | +theta.0 <- sort(unique(theta)) | ||
13 | +iii <- match(theta.0, theta) | ||
14 | +xxx$x <- xxx$x[iii] | ||
15 | +xxx$y <- xxx$y[iii] | ||
16 | +xxx$bp <- xxx$bp[iii] | ||
17 | +xxx | ||
18 | +} | ||
19 | +deldir <- function(x,y,dpl=NULL,rw=NULL,eps=1e-9,frac=1e-4, | ||
20 | + sort=TRUE,plotit=FALSE,digits=6,...) { | ||
21 | +# Function deldir | ||
22 | +# | ||
23 | +# Copyright (C) 1996 by T. Rolf Turner | ||
24 | +# | ||
25 | +# Permission to use, copy, modify, and distribute this software and | ||
26 | +# its documentation for any purpose and without fee is hereby | ||
27 | +# granted, provided that the above copyright notice appear in all | ||
28 | +# copies and that both that copyright notice and this permission | ||
29 | +# notice appear in supporting documentation. | ||
30 | +# | ||
31 | +# ORIGINALLY PROGRAMMED BY: Rolf Turner in 1987/88, while with the | ||
32 | +# Division of Mathematics and Statistics, CSIRO, Sydney, Australia. | ||
33 | +# Re-programmed by Rolf Turner to adapt the implementation from a | ||
34 | +# stand-alone Fortran program to an S function, while visiting the | ||
35 | +# University of Western Australia, May 1995. Further revised | ||
36 | +# December 1996. | ||
37 | +# | ||
38 | +# Function to compute the Delaunay Triangulation (and hence the | ||
39 | +# Dirichlet Tesselation) of a planar point set according to the | ||
40 | +# second (iterative) algorithm of Lee and Schacter, International | ||
41 | +# Journal of Computer and Information Sciences, Vol. 9, No. 3, 1980, | ||
42 | +# pages 219 to 242. | ||
43 | + | ||
44 | +# The triangulation is made to be with respect to the whole plane by | ||
45 | +# `suspending' it from `ideal' points | ||
46 | +# (-R,-R), (R,-R) (R,R), and (-R,R), where R --> infinity. | ||
47 | + | ||
48 | +# It is also enclosed in a finite rectangle (whose boundaries truncate any | ||
49 | +# infinite Dirichlet tiles) with corners (xmin,ymin) etc. This rectangle | ||
50 | +# is referred to elsewhere as `the' rectangular window. | ||
51 | + | ||
52 | +# If the first argument is a list, extract components x and y: | ||
53 | +if(is.list(x)) { | ||
54 | + if(all(!is.na(match(c('x','y'),names(x))))) { | ||
55 | + y <- x$y | ||
56 | + x <- x$x | ||
57 | + } | ||
58 | + else { | ||
59 | + cat('Error: called with list lacking both x and y elements\n') | ||
60 | + return() | ||
61 | + } | ||
62 | +} | ||
63 | + | ||
64 | +# If a data window is specified, get its corner coordinates | ||
65 | +# and truncate the data by this window: | ||
66 | +n <- length(x) | ||
67 | +if(n!=length(y)) stop('data lengths do not match') | ||
68 | +if(!is.null(rw)) { | ||
69 | + xmin <- rw[1] | ||
70 | + xmax <- rw[2] | ||
71 | + ymin <- rw[3] | ||
72 | + ymax <- rw[4] | ||
73 | + drop <- (1:n)[x<xmin|x>xmax|y<ymin|y>ymax] | ||
74 | + if(length(drop)>0) { | ||
75 | + x <- x[-drop] | ||
76 | + y <- y[-drop] | ||
77 | + n <- length(x) | ||
78 | + } | ||
79 | +} | ||
80 | + | ||
81 | +# If corners of the window are not specified, form them from | ||
82 | +# the minimum and maximum of the data +/- 10%: | ||
83 | +else { | ||
84 | + xmin <- min(x) | ||
85 | + xmax <- max(x) | ||
86 | + ymin <- min(y) | ||
87 | + ymax <- max(y) | ||
88 | + xdff <- xmax-xmin | ||
89 | + ydff <- ymax-ymin | ||
90 | + xmin <- xmin-0.1*xdff | ||
91 | + xmax <- xmax+0.1*xdff | ||
92 | + ymin <- ymin-0.1*ydff | ||
93 | + ymax <- ymax+0.1*ydff | ||
94 | + rw <- c(xmin,xmax,ymin,ymax) | ||
95 | +} | ||
96 | + | ||
97 | +# Add the dummy points: | ||
98 | +if(!is.null(dpl)) { | ||
99 | + dpts <- dumpts(x,y,dpl,rw) | ||
100 | + x <- dpts$x | ||
101 | + y <- dpts$y | ||
102 | +} | ||
103 | + | ||
104 | +# Eliminate duplicate points: | ||
105 | +iii <- !ind.dup(x,y,rw,frac) | ||
106 | +ndm <- sum(iii[-(1:n)]) | ||
107 | +n <- sum(iii[1:n]) | ||
108 | +x <- x[iii] | ||
109 | +y <- y[iii] | ||
110 | + | ||
111 | +# Make space for the total number of points (real and dummy) as | ||
112 | +# well as 4 ideal points and 4 extra corner points which get used | ||
113 | +# (only) by subroutines dirseg and dirout in the ``output'' process | ||
114 | +# (returning a description of the triangulation after it has been | ||
115 | +# calculated): | ||
116 | +npd <- n + ndm | ||
117 | +ntot <- npd + 4 # ntot includes the 4 ideal points but | ||
118 | + # but NOT the 4 extra corners | ||
119 | +x <- c(rep(0,4),x,rep(0,4)) | ||
120 | +y <- c(rep(0,4),y,rep(0,4)) | ||
121 | + | ||
122 | +# Set up fixed dimensioning constants: | ||
123 | +ntdel <- 4*npd | ||
124 | +ntdir <- 3*npd | ||
125 | + | ||
126 | +# Set up dimensioning constants which might need to be increased: | ||
127 | +madj <- max(20,ceiling(3*sqrt(ntot))) | ||
128 | +tadj <- (madj+1)*(ntot+4) | ||
129 | +ndel <- madj*(madj+1)/2 | ||
130 | +tdel <- 6*ndel | ||
131 | +ndir <- ndel | ||
132 | +tdir <- 8*ndir | ||
133 | + | ||
134 | +# Call the master subroutine to do the work: | ||
135 | +repeat { | ||
136 | + tmp <- .Fortran( | ||
137 | + 'master', | ||
138 | + x=as.double(x), | ||
139 | + y=as.double(y), | ||
140 | + sort=as.logical(sort), | ||
141 | + rw=as.double(rw), | ||
142 | + npd=as.integer(npd), | ||
143 | + ntot=as.integer(ntot), | ||
144 | + nadj=integer(tadj), | ||
145 | + madj=as.integer(madj), | ||
146 | + ind=integer(npd), | ||
147 | + tx=double(npd), | ||
148 | + ty=double(npd), | ||
149 | + ilist=integer(npd), | ||
150 | + eps=as.double(eps), | ||
151 | + delsgs=double(tdel), | ||
152 | + ndel=as.integer(ndel), | ||
153 | + delsum=double(ntdel), | ||
154 | + dirsgs=double(tdir), | ||
155 | + ndir=as.integer(ndir), | ||
156 | + dirsum=double(ntdir), | ||
157 | + nerror=integer(1), | ||
158 | + PACKAGE='deldir' | ||
159 | + ) | ||
160 | + | ||
161 | +# Check for errors: | ||
162 | + nerror <- tmp$nerror | ||
163 | + if(nerror < 0) break | ||
164 | + | ||
165 | + else { | ||
166 | + if(nerror==4) { | ||
167 | + cat('nerror =',nerror,'\n') | ||
168 | + cat('Increasing madj and trying again.\n') | ||
169 | + madj <- ceiling(1.2*madj) | ||
170 | + tadj <- (madj+1)*(ntot+4) | ||
171 | + ndel <- max(ndel,madj*(madj+1)/2) | ||
172 | + tdel <- 6*ndel | ||
173 | + ndir <- ndel | ||
174 | + tdir <- 8*ndir | ||
175 | + } | ||
176 | + else if(nerror==14|nerror==15) { | ||
177 | + cat('nerror =',nerror,'\n') | ||
178 | + cat('Increasing ndel and ndir and trying again.\n') | ||
179 | + ndel <- ceiling(1.2*ndel) | ||
180 | + tdel <- 6*ndel | ||
181 | + ndir <- ndel | ||
182 | + tdir <- 8*ndir | ||
183 | + } | ||
184 | + else { | ||
185 | + cat('nerror =',nerror,'\n') | ||
186 | + return(invisible()) | ||
187 | + } | ||
188 | + } | ||
189 | +} | ||
190 | + | ||
191 | +# Collect up the results for return: | ||
192 | +ndel <- tmp$ndel | ||
193 | +delsgs <- round(t(as.matrix(matrix(tmp$delsgs,nrow=6)[,1:ndel])),digits) | ||
194 | +delsum <- matrix(tmp$delsum,ncol=4) | ||
195 | +del.area <- sum(delsum[,4]) | ||
196 | +delsum <- round(cbind(delsum,delsum[,4]/del.area),digits) | ||
197 | +del.area <- round(del.area,digits) | ||
198 | +ndir <- tmp$ndir | ||
199 | +dirsgs <- round(t(as.matrix(matrix(tmp$dirsgs,nrow=8)[,1:ndir])),digits) | ||
200 | +dirsgs <- as.data.frame(dirsgs) | ||
201 | +dirsum <- matrix(tmp$dirsum,ncol=3) | ||
202 | +dir.area <- sum(dirsum[,3]) | ||
203 | +dirsum <- round(cbind(dirsum,dirsum[,3]/dir.area),digits) | ||
204 | +dir.area <- round(dir.area,digits) | ||
205 | +allsum <- cbind(delsum,dirsum) | ||
206 | +rw <- round(rw,digits) | ||
207 | + | ||
208 | +# Name the columns of the results: | ||
209 | +dimnames(delsgs) <- list(NULL,c('x1','y1','x2','y2','ind1','ind2')) | ||
210 | +names(dirsgs) <- c('x1','y1','x2','y2','ind1','ind2','bp1','bp2') | ||
211 | +mode(dirsgs$bp1) <- 'logical' | ||
212 | +mode(dirsgs$bp2) <- 'logical' | ||
213 | +dimnames(allsum) <- list(NULL,c('x','y','n.tri','del.area','del.wts', | ||
214 | + 'n.tside','nbpt','dir.area','dir.wts')) | ||
215 | + | ||
216 | +# Aw' done!!! | ||
217 | +rslt <- list(delsgs=delsgs,dirsgs=dirsgs,summary=allsum,n.data=n, | ||
218 | + n.dum=ndm,del.area=del.area,dir.area=dir.area,rw=rw) | ||
219 | +class(rslt) <- 'deldir' | ||
220 | +if(plotit) plot(rslt,...) | ||
221 | +if(plotit) invisible(rslt) else rslt | ||
222 | +} | ||
223 | +dumpts <- function(x,y,dpl,rw) { | ||
224 | +# | ||
225 | +# Function dumpts to append a sequence of dummy points to the | ||
226 | +# data points. | ||
227 | +# | ||
228 | + | ||
229 | +ndm <- 0 | ||
230 | +xd <- NULL | ||
231 | +yd <- NULL | ||
232 | +xmin <- rw[1] | ||
233 | +xmax <- rw[2] | ||
234 | +ymin <- rw[3] | ||
235 | +ymax <- rw[4] | ||
236 | + | ||
237 | +# Points on radii of circles emanating from data points: | ||
238 | +if(!is.null(dpl$nrad)) { | ||
239 | + nrad <- dpl$nrad # Number of radii from each data point. | ||
240 | + nper <- dpl$nper # Number of dummy points per radius. | ||
241 | + fctr <- dpl$fctr # Length of each radius = fctr * mean | ||
242 | + # interpoint distance. | ||
243 | + lrad <- fctr*mnnd(x,y)/nper | ||
244 | + theta <- 2*pi*(1:nrad)/nrad | ||
245 | + cs <- cos(theta) | ||
246 | + sn <- sin(theta) | ||
247 | + xt <- c(lrad*(1:nper)%o%cs) | ||
248 | + yt <- c(lrad*(1:nper)%o%sn) | ||
249 | + xd <- c(outer(x,xt,'+')) | ||
250 | + yd <- c(outer(y,yt,'+')) | ||
251 | +} | ||
252 | + | ||
253 | +# Ad hoc points passed over as part of dpl: | ||
254 | +if(!is.null(dpl$x)) { | ||
255 | + xd <- c(xd,dpl$x) | ||
256 | + yd <- c(yd,dpl$y) | ||
257 | +} | ||
258 | + | ||
259 | +# Delete dummy points outside the rectangular window. | ||
260 | +ndm <- length(xd) | ||
261 | +if(ndm >0) { | ||
262 | + drop <- (1:ndm)[xd<xmin|xd>xmax|yd<ymin|yd>ymax] | ||
263 | + if(length(drop)>0) { | ||
264 | + xd <- xd[-drop] | ||
265 | + yd <- yd[-drop] | ||
266 | + } | ||
267 | +} | ||
268 | + | ||
269 | +# Rectangular grid: | ||
270 | +ndx <- dpl$ndx | ||
271 | +okx <- !is.null(ndx) && ndx > 0 | ||
272 | +ndy <- dpl$ndy | ||
273 | +oky <- !is.null(ndy) && ndy > 0 | ||
274 | +if(okx & oky) { | ||
275 | + xt <- if(ndx>1) seq(xmin,xmax,length=ndx) else 0.5*(xmin+xmax) | ||
276 | + yt <- if(ndy>1) seq(ymin,ymax,length=ndy) else 0.5*(ymin+ymax) | ||
277 | + xy <- expand.grid(x=xt,y=yt) | ||
278 | + xd <- c(xd,xy$x) | ||
279 | + yd <- c(yd,xy$y) | ||
280 | +} | ||
281 | + | ||
282 | +ndm <- length(xd) | ||
283 | +list(x=c(x,xd),y=c(y,yd),ndm=ndm) | ||
284 | +} | ||
285 | +get.cnrind <- function(x,y,rw) { | ||
286 | +x.crnrs <- rw[c(1,2,2,1)] | ||
287 | +y.crnrs <- rw[c(3,3,4,4)] | ||
288 | +M1 <- outer(x,x.crnrs,function(a,b){(a-b)^2}) | ||
289 | +M2 <- outer(y,y.crnrs,function(a,b){(a-b)^2}) | ||
290 | +MM <- M1 + M2 | ||
291 | +apply(MM,2,which.min) | ||
292 | +} | ||
293 | +ind.dup <- function(x,y,rw=NULL,frac=0.0001) { | ||
294 | +# | ||
295 | +# Function ind.dup to calculate the indices of data pairs | ||
296 | +# which duplicate earlier ones. (Returns a logical vector; | ||
297 | +# true for such indices, false for the rest.) | ||
298 | +# | ||
299 | + | ||
300 | +if(is.null(rw)) rw <- c(0,1,0,1) | ||
301 | +n <- length(x) | ||
302 | +rslt <- .Fortran( | ||
303 | + 'inddup', | ||
304 | + x=as.double(x), | ||
305 | + y=as.double(y), | ||
306 | + n=as.integer(n), | ||
307 | + rw=as.double(rw), | ||
308 | + frac=as.double(frac), | ||
309 | + dup=logical(n), | ||
310 | + PACKAGE='deldir' | ||
311 | + ) | ||
312 | + | ||
313 | +rslt$dup | ||
314 | +} | ||
315 | +mid.in <- function(x,y,rx,ry) { | ||
316 | +xm <- 0.5*(x[1]+x[2]) | ||
317 | +ym <- 0.5*(y[1]+y[2]) | ||
318 | +(rx[1] < xm & xm < rx[2] & ry[1] < ym & ym < ry[2]) | ||
319 | +} | ||
320 | +mnnd <- function(x,y) { | ||
321 | +# | ||
322 | +# Function mnnd to calculate the mean nearest neighbour distance | ||
323 | +# between the points whose coordinates are stored in x and y. | ||
324 | +# | ||
325 | + | ||
326 | +n <- length(x) | ||
327 | +if(n!=length(y)) stop('data lengths do not match') | ||
328 | +dmb <- (max(x)-min(x))**2 + (max(y)-min(y))**2 | ||
329 | + | ||
330 | +.Fortran( | ||
331 | + "mnnd", | ||
332 | + x=as.double(x), | ||
333 | + y=as.double(y), | ||
334 | + n=as.integer(n), | ||
335 | + dmb=as.double(dmb), | ||
336 | + d=double(1), | ||
337 | + PACKAGE='deldir' | ||
338 | + )$d | ||
339 | +} | ||
340 | +plot.deldir <- function(x,add=FALSE,wlines=c('both','triang','tess'), | ||
341 | + wpoints=c('both','real','dummy','none'), | ||
342 | + number=FALSE,cex=1,nex=1,col=NULL,lty=NULL, | ||
343 | + pch=NULL,xlim=NULL,ylim=NULL,xlab='x',ylab='y',...) | ||
344 | +{ | ||
345 | +# | ||
346 | +# Function plot.deldir to produce a plot of the Delaunay triangulation | ||
347 | +# and Dirichlet tesselation of a point set, as produced by the | ||
348 | +# function deldir(). | ||
349 | +# | ||
350 | + | ||
351 | +wlines <- match.arg(wlines) | ||
352 | +wpoints <- match.arg(wpoints) | ||
353 | + | ||
354 | +if(is.null(class(x)) || class(x)!='deldir') { | ||
355 | + cat('Argument is not of class deldir.\n') | ||
356 | + return(invisible()) | ||
357 | +} | ||
358 | + | ||
359 | +col <- if(is.null(col)) c(1,1,1,1,1) else rep(col,length.out=5) | ||
360 | +lty <- if(is.null(lty)) 1:2 else rep(lty,length.out=2) | ||
361 | +pch <- if(is.null(pch)) 1:2 else rep(pch,length.out=2) | ||
362 | + | ||
363 | +plot.del <- switch(wlines,both=TRUE,triang=TRUE,tess=FALSE) | ||
364 | +plot.dir <- switch(wlines,both=TRUE,triang=FALSE,tess=TRUE) | ||
365 | +plot.rl <- switch(wpoints,both=TRUE,real=TRUE,dummy=FALSE,none=FALSE) | ||
366 | +plot.dum <- switch(wpoints,both=TRUE,real=FALSE,dummy=TRUE,none=FALSE) | ||
367 | + | ||
368 | +delsgs <- x$delsgs | ||
369 | +dirsgs <- x$dirsgs | ||
370 | +n <- x$n.data | ||
371 | +rw <- x$rw | ||
372 | + | ||
373 | +if(plot.del) { | ||
374 | + x1<-delsgs[,1] | ||
375 | + y1<-delsgs[,2] | ||
376 | + x2<-delsgs[,3] | ||
377 | + y2<-delsgs[,4] | ||
378 | +} | ||
379 | + | ||
380 | +if(plot.dir) { | ||
381 | + u1<-dirsgs[,1] | ||
382 | + v1<-dirsgs[,2] | ||
383 | + u2<-dirsgs[,3] | ||
384 | + v2<-dirsgs[,4] | ||
385 | +} | ||
386 | + | ||
387 | +X<-x$summary[,1] | ||
388 | +Y<-x$summary[,2] | ||
389 | + | ||
390 | +if(!add) { | ||
391 | + pty.save <- par()$pty | ||
392 | + on.exit(par(pty=pty.save)) | ||
393 | + par(pty='s') | ||
394 | + if(is.null(xlim)) xlim <- rw[1:2] | ||
395 | + if(is.null(ylim)) ylim <- rw[3:4] | ||
396 | + plot(0,0,type='n',xlim=xlim,ylim=ylim, | ||
397 | + xlab=xlab,ylab=ylab,axes=FALSE,...) | ||
398 | + axis(side=1) | ||
399 | + axis(side=2) | ||
400 | +} | ||
401 | + | ||
402 | +if(plot.del) segments(x1,y1,x2,y2,col=col[1],lty=lty[1],...) | ||
403 | +if(plot.dir) segments(u1,v1,u2,v2,col=col[2],lty=lty[2],...) | ||
404 | +if(plot.rl) { | ||
405 | + x.real <- X[1:n] | ||
406 | + y.real <- Y[1:n] | ||
407 | + points(x.real,y.real,pch=pch[1],col=col[3],cex=cex,...) | ||
408 | +} | ||
409 | +if(plot.dum) { | ||
410 | + x.dumm <- X[-(1:n)] | ||
411 | + y.dumm <- Y[-(1:n)] | ||
412 | + points(x.dumm,y.dumm,pch=pch[2],col=col[4],cex=cex,...) | ||
413 | +} | ||
414 | +if(number) { | ||
415 | + xoff <-0.02*diff(range(X)) | ||
416 | + yoff <-0.02*diff(range(Y)) | ||
417 | + text(X+xoff,Y+yoff,1:length(X),cex=nex,col=col[5],...) | ||
418 | +} | ||
419 | +invisible() | ||
420 | +} | ||
421 | +`plot.tile.list` <- | ||
422 | +function (x, verbose = FALSE, close = FALSE, pch = 1, polycol = NA, | ||
423 | + showpoints = TRUE, asp = 1, ...) | ||
424 | +{ | ||
425 | + object <- x | ||
426 | + if (!inherits(object, "tile.list")) | ||
427 | + stop("Argument \"object\" is not of class tile.list.\n") | ||
428 | + n <- length(object) | ||
429 | + x.all <- unlist(lapply(object, function(w) { | ||
430 | + c(w$pt[1], w$x) | ||
431 | + })) | ||
432 | + y.all <- unlist(lapply(object, function(w) { | ||
433 | + c(w$pt[2], w$y) | ||
434 | + })) | ||
435 | + x.pts <- unlist(lapply(object, function(w) { | ||
436 | + w$pt[1] | ||
437 | + })) | ||
438 | + y.pts <- unlist(lapply(object, function(w) { | ||
439 | + w$pt[2] | ||
440 | + })) | ||
441 | + rx <- range(x.all) | ||
442 | + ry <- range(y.all) | ||
443 | + plot(x.all, y.all, type = "n", asp = asp, xlab = "x", ylab = "y") | ||
444 | + polycol <- apply(col2rgb(polycol,TRUE),2, | ||
445 | + function(x){do.call(rgb,as.list(x/255))}) | ||
446 | + polycol <- rep(polycol, length = length(object)) | ||
447 | + hexbla <- do.call(rgb,as.list(col2rgb("black",TRUE)/255)) | ||
448 | + hexwhi <- do.call(rgb,as.list(col2rgb("white",TRUE)/255)) | ||
449 | + ptcol <- ifelse(polycol == hexbla,hexwhi,hexbla) | ||
450 | + lnwid <- ifelse(polycol == hexbla, 2, 1) | ||
451 | + for (i in 1:n) { | ||
452 | + inner <- !any(object[[i]]$bp) | ||
453 | + if (close | inner) | ||
454 | + polygon(object[[i]], col = polycol[i], border = ptcol[i], | ||
455 | + lwd = lnwid[i]) | ||
456 | + else { | ||
457 | + x <- object[[i]]$x | ||
458 | + y <- object[[i]]$y | ||
459 | + bp <- object[[i]]$bp | ||
460 | + ni <- length(x) | ||
461 | + for (j in 1:ni) { | ||
462 | + jnext <- if (j < ni) | ||
463 | + j + 1 | ||
464 | + else 1 | ||
465 | + do.it <- mid.in(x[c(j, jnext)], y[c(j, jnext)], | ||
466 | + rx, ry) | ||
467 | + if (do.it) | ||
468 | + segments(x[j], y[j], x[jnext], y[jnext], col = ptcol[i], | ||
469 | + lwd = lnwid[i]) | ||
470 | + } | ||
471 | + } | ||
472 | + if (verbose & showpoints) | ||
473 | + points(object[[i]]$pt[1], object[[i]]$pt[2], pch = pch, | ||
474 | + col = ptcol[i]) | ||
475 | + if (verbose & i < n) | ||
476 | + readline("Go? ") | ||
477 | + } | ||
478 | + if (showpoints) | ||
479 | + points(x.pts, y.pts, pch = pch, col = ptcol) | ||
480 | + invisible() | ||
481 | +} | ||
482 | +tile.list <- function (object) | ||
483 | +{ | ||
484 | + if (!inherits(object, "deldir")) | ||
485 | + stop("Argument \"object\" is not of class deldir.\n") | ||
486 | + rw <- object$rw | ||
487 | + x.crnrs <- rw[c(1,2,2,1)] | ||
488 | + y.crnrs <- rw[c(3,3,4,4)] | ||
489 | + ddd <- object$dirsgs | ||
490 | + sss <- object$summary | ||
491 | + npts <- nrow(sss) | ||
492 | + x <- sss[,"x"] | ||
493 | + y <- sss[,"y"] | ||
494 | + i.crnr <- get.cnrind(x,y,rw) | ||
495 | + rslt <- list() | ||
496 | + for (i in 1:npts) { | ||
497 | + m <- as.matrix(rbind(ddd[ddd$ind1 == i, 1:4], ddd[ddd$ind2 == i, 1:4])) | ||
498 | + bp1 <- c(ddd[ddd$ind1 == i, 7], ddd[ddd$ind2 == i, 7]) | ||
499 | + bp2 <- c(ddd[ddd$ind1 == i, 8], ddd[ddd$ind2 == i, 8]) | ||
500 | + m1 <- cbind(m[, 1:2, drop = FALSE], 0 + bp1) | ||
501 | + m2 <- cbind(m[, 3:4, drop = FALSE], 0 + bp2) | ||
502 | + m <- rbind(m1, m2) | ||
503 | + pt <- sss[i, 1:2] | ||
504 | + theta <- atan2(m[, 2] - pt[2], m[, 1] - pt[1]) | ||
505 | + theta <- ifelse(theta > 0, theta, theta + 2 * pi) | ||
506 | + theta.0 <- sort(unique(theta)) | ||
507 | + mm <- m[match(theta.0, theta), ] | ||
508 | + xx <- mm[, 1] | ||
509 | + yy <- mm[, 2] | ||
510 | + bp <- as.logical(mm[, 3]) | ||
511 | +# Add corner points if necessary: | ||
512 | + ii <- i.crnr%in%i | ||
513 | + xx <- c(xx,x.crnrs[ii]) | ||
514 | + yy <- c(yy,y.crnrs[ii]) | ||
515 | + bp <- c(bp,rep(TRUE,sum(ii))) | ||
516 | + rslt[[i]] <- acw(list(pt=pt, x = xx, y = yy, bp = bp)) | ||
517 | + } | ||
518 | + class(rslt) <- "tile.list" | ||
519 | + rslt | ||
520 | +} |
@@ -0,0 +1,186 @@ | @@ -0,0 +1,186 @@ | ||
1 | + | ||
2 | + Version date: 21 February 2002. | ||
3 | + This version is simply an adaptation of the Splus version | ||
4 | + of the package to R. | ||
5 | + | ||
6 | + ***************************** | ||
7 | + | ||
8 | + Version date: 14 February 2002. | ||
9 | + This version supercedes the version dated 24 April 1999. | ||
10 | + | ||
11 | + ***************************** | ||
12 | + | ||
13 | + The changes from the version dated 24 April 1999 to the | ||
14 | + version dated 14 February 2002 were: | ||
15 | + | ||
16 | + A bug in the procedure for eliminating duplicated points was | ||
17 | + fixed. Thanks go to Dr. Berwin Turlach of the Department of | ||
18 | + Maths and Stats at the University of Western Australia, for | ||
19 | + spotting this bug. | ||
20 | + | ||
21 | + ***************************** | ||
22 | + | ||
23 | + The changes from the version dated 26 October 1998 to the | ||
24 | + version dated 24 April 1999 were: | ||
25 | + | ||
26 | + (1) The function mipd(), stored in mipd.sf, and the | ||
27 | + corresponding Fortran subroutine mipd, stored in mipd.r, have | ||
28 | + been replaced by mnnd() in mnnd.sf and mnnd in mnnd.r. The | ||
29 | + function mipd calculated the mean interpoint distance, to be | ||
30 | + used in constructing dummy point structures of a certain | ||
31 | + type. After some reflection it became apparent that the mean | ||
32 | + interpoint distance was much too large for the intended | ||
33 | + purpose, and that a more appropriate value was the ``mean | ||
34 | + nearest neighbour distance'' which is calculated by the new | ||
35 | + function. This new value is now used in constructing dummy | ||
36 | + point structures. | ||
37 | + | ||
38 | + Note that the operative result is that the resulting dummy | ||
39 | + point structures contain many more points than before. The | ||
40 | + old value caused large numbers of the dummy points to fall | ||
41 | + outside the data window and therefore to be clipped. | ||
42 | + | ||
43 | + ***************************** | ||
44 | + | ||
45 | + The changes from the version dated 6 December 1996 to the | ||
46 | + version dated 26 October 1998 were: | ||
47 | + | ||
48 | + (1) A ratfor/Fortran routine named ``inside'' has been | ||
49 | + renamed ``dldins'' to avoid conflict with a name built in to | ||
50 | + some versions of Splus. | ||
51 | + | ||
52 | + (2) Some minor corrections have been made to dangerous | ||
53 | + infelicities in a piece of the ratfor/Fortran code. | ||
54 | + | ||
55 | + (3) The dynamic loading procedure has been changed to use | ||
56 | + dyn.load.shared so that the package is easily usable on | ||
57 | + IRIX systems as well as under SunOS/Solaris. | ||
58 | + | ||
59 | + (4) The package has been adjusted slightly so that it | ||
60 | + can easily be installed as a section of a library. In | ||
61 | + particular, the dynamic loading is now done by the | ||
62 | + .First.lib() function rather than from within deldir() | ||
63 | + itself; reference to an environment variable DYN_LOAD_LIB | ||
64 | + is no longer needed. | ||
65 | + | ||
66 | + ***************************** | ||
67 | + | ||
68 | + This package computes and plots the Dirichlet (Voronoi) tesselation | ||
69 | + and the Delaunay triangulation of a set of of data points and | ||
70 | + possibly a superimposed ``grid'' of dummy points. | ||
71 | + | ||
72 | + The tesselation is constructed with respect to the whole plane | ||
73 | + by suspending it from ideal points at infinity. | ||
74 | + | ||
75 | + ORIGINALLY PROGRAMMED BY: Rolf Turner in 1987/88, while with the | ||
76 | + Division of Mathematics and Statistics, CSIRO, Sydney, Australia. | ||
77 | + Re-programmed by Rolf Turner to adapt the implementation from a | ||
78 | + stand-alone Fortran program to an S function, while visiting the | ||
79 | + University of Western Australia, May 1995. Further revised | ||
80 | + December 1996, October 1998, April 1999, and February 2002. | ||
81 | + Adapted to an R package 21 February 2002. | ||
82 | + | ||
83 | + Current address of the author: | ||
84 | + Department of Mathematics and Statistics, | ||
85 | + University of New Brunswick, | ||
86 | + P.O. Box 4400, Fredericton, New Brunswick, | ||
87 | + Canada E3B 5A3 | ||
88 | + Email: | ||
89 | + rolf@math.unb.ca | ||
90 | + | ||
91 | + The author gratefully acknowledges the contributions, assistance, | ||
92 | + and guidance of Mark Berman, of D.M.S., CSIRO, in collaboration with | ||
93 | + whom this project was originally undertaken. The author also | ||
94 | + acknowledges much useful advice from Adrian Baddeley, formerly of | ||
95 | + D.M.S. CSIRO (now Professor of Statistics at the University of | ||
96 | + Western Australia). Daryl Tingley of the Department of Mathematics | ||
97 | + and Statistics, University of New Brunswick provided some helpful | ||
98 | + insight. Special thanks are extended to Alan Johnson, of the Alaska | ||
99 | + Fisheries Science Centre, who supplied two data sets which were | ||
100 | + extremely valuable in tracking down some errors in the code. | ||
101 | + | ||
102 | + Don MacQueen, of Lawrence Livermore National Lab, wrote an Splus | ||
103 | + driver function for the old stand-alone version of this software. | ||
104 | + That driver, which was available on Statlib, is now deprecated in | ||
105 | + favour of this current package. Don also collaborated in the | ||
106 | + preparation of this current package. | ||
107 | + | ||
108 | + Bill Dunlap of MathSoft Inc. tracked down a bug which was making | ||
109 | + the deldir() function crash on some systems, and pointed out some | ||
110 | + other improvements to be made. | ||
111 | + | ||
112 | + Berwin Turlach of the Department of Maths and Stats at the | ||
113 | + University of Western Australia pointed out a bug in the procedure | ||
114 | + for eliminating duplicated points. | ||
115 | + | ||
116 | + ***************************** | ||
117 | + | ||
118 | + The man directory, contains, in addition to the R documentation | ||
119 | + files deldir.Rd and plot.deldir.Rd: | ||
120 | + | ||
121 | + (a) This READ_ME file. | ||
122 | + (b) A file err.list, containing a list of meanings of possible | ||
123 | + error numbers which could be returned. NONE of these | ||
124 | + errors should ever actually happen except for errors 4, 14, | ||
125 | + and 15. These relate to insufficient dimensioning, and | ||
126 | + if they occur, the driver increases the dimensions and | ||
127 | + tries again (informing you of this fact). | ||
128 | + (c) A file ex.out containing a printout of the object returned | ||
129 | + by running the example given in the help file for deldir. | ||
130 | + | ||
131 | + The src directory contains many, many *.f (Fortran) files, which | ||
132 | + get compiled and dynamically loaded. | ||
133 | + | ||
134 | + The Fortran code is ponderous --- it was automatically generated | ||
135 | + from Ratfor code, which was pretty ponderous to start with. It is | ||
136 | + quite possibly very kludgy aw well --- i.e. a good programmer could | ||
137 | + make it ***much*** more efficient I'm sure. It contains all sorts | ||
138 | + of checking for anomalous situations which probably can/will never | ||
139 | + occur. These checks basically reflect my pessimism and fervent | ||
140 | + belief in Murphy's Law. | ||
141 | + | ||
142 | + The program was also designed with a particular application in mind, | ||
143 | + in which we wished to superimpose a grid of dummy points onto the | ||
144 | + actual data points which we were triangulating. This fact adds | ||
145 | + slightly to the complication of the code. | ||
146 | + | ||
147 | + ***************************** | ||
148 | + | ||
149 | + Here follows a brief description of the package: | ||
150 | + | ||
151 | + (1) The function deldir computes the Delaunay Triangulation (and | ||
152 | + hence the Dirichlet Tesselation) of a planar point set according to | ||
153 | + the second (iterative) algorithm of Lee and Schacter, International | ||
154 | + Journal of Computer and Information Sciences, Vol. 9, No. 3, 1980, | ||
155 | + pages 219 to 242. | ||
156 | + | ||
157 | + The tesselation/triangulation is made to be | ||
158 | + | ||
159 | + **** with respect to the whole plane **** | ||
160 | + | ||
161 | + by `suspending' it from `ideal' points (-Inf,-Inf), (Inf,-Inf) | ||
162 | + (Inf,Inf), and (-Inf,Inf). | ||
163 | + | ||
164 | + (2) The tesselation/triangulation is also enclosed in a finite | ||
165 | + rectangle with corners | ||
166 | + | ||
167 | + (xmin,ymax) * ------------------------ * (xmax,ymax) | ||
168 | + | | | ||
169 | + | | | ||
170 | + | | | ||
171 | + | | | ||
172 | + | | | ||
173 | + (xmin,ymin) * ------------------------ * (xmax,ymin) | ||
174 | + | ||
175 | + The boundaries of this rectangle truncate some Dirichlet tiles, in | ||
176 | + particular any infinite ones. This rectangle is referred to | ||
177 | + elsewhere as `the' rectangular window. | ||
178 | + === | ||
179 | + | ||
180 | + (2) The function plot.deldir is a method for plot. I.e. it may be | ||
181 | + invoked simply by typing ``plot(x)'' provided that ``x'' is an | ||
182 | + object of class ``deldir'' (as produced by the function deldir). | ||
183 | + The plot (by default) consists of the edges of the Delaunay | ||
184 | + triangles (solid lines) and the edges of the Dirichlet tiles (dotted | ||
185 | + lines). By default the real data points are indicated by circles, | ||
186 | + and the dummy points are indicated by triangles. |
No preview for this file type
@@ -0,0 +1,49 @@ | @@ -0,0 +1,49 @@ | ||
1 | + | ||
2 | +Error list: | ||
3 | +=========== | ||
4 | + | ||
5 | +nerror = 1: Contradictory adjacency lists. Error in adjchk. | ||
6 | + | ||
7 | +nerror = 2: Number of points jumbled. Error in binsrt. | ||
8 | + | ||
9 | +nerror = 3: Vertices of 'triangle' are collinear | ||
10 | + and vertex 2 is not between 1 and 3. Error in circen. | ||
11 | + | ||
12 | +nerror = 4: Number of adjacencies too large. Error in insrt. | ||
13 | + (Automatically adjusted for in deldir().) | ||
14 | + | ||
15 | +nerror = 5: Adjacency list of i is empty, and so cannot contain j. | ||
16 | + Error in pred. | ||
17 | + | ||
18 | +nerror = 6: Adjacency list of i does not contain j. Error in pred. | ||
19 | + | ||
20 | +nerror = 7: Indicator ijk is out of range. (This CAN'T happen!) | ||
21 | + Error in qtest. | ||
22 | + | ||
23 | +nerror = 8: Fell through all six cases. | ||
24 | + Something must be totally stuffed up. Error in stoke. | ||
25 | + | ||
26 | +nerror = 9: Adjacency list of i is empty, and so cannot contain j. | ||
27 | + Error in succ. | ||
28 | + | ||
29 | +nerror = 10: Adjacency list of i does not contain j. Error in succ. | ||
30 | + | ||
31 | +nerror = 11: No triangles to find. Error in trifnd. | ||
32 | + | ||
33 | +nerror = 12: Vertices of triangle are collinear. Error in dirseg. | ||
34 | + | ||
35 | +nerror = 13: Vertices of triangle are collinear. Error in dirout. | ||
36 | + | ||
37 | +nerror = 14: Number of Delaunay segments exceeds alloted space. | ||
38 | + Error in delseg. | ||
39 | + (Automatically adjusted for in deldir().) | ||
40 | + | ||
41 | +nerror = 15: Number of Dirichlet segments exceeds alloted space. | ||
42 | + Error in dirseg. | ||
43 | + (Automatically adjusted for in deldir().) | ||
44 | + | ||
45 | +nerror = 16: Line from midpoint to circumcenter does not intersect | ||
46 | + rectangle boundary; but it HAS to!!! Error in dirseg. | ||
47 | + | ||
48 | +nerror = 17: Line from midpoint to circumcenter does not intersect | ||
49 | + rectangle boundary; but it HAS to!!! Error in dirout. |
@@ -0,0 +1,74 @@ | @@ -0,0 +1,74 @@ | ||
1 | +$delsgs | ||
2 | + x1 y1 x2 y2 ind1 ind2 | ||
3 | + [1,] 3 3 2.3 2.3 2 1 | ||
4 | + [2,] 7 2 2.3 2.3 3 1 | ||
5 | + [3,] 7 2 3.0 3.0 3 2 | ||
6 | + [4,] 1 5 2.3 2.3 4 1 | ||
7 | + [5,] 1 5 3.0 3.0 4 2 | ||
8 | + [6,] 3 8 3.0 3.0 5 2 | ||
9 | + [7,] 3 8 7.0 2.0 5 3 | ||
10 | + [8,] 3 8 1.0 5.0 5 4 | ||
11 | + [9,] 8 9 7.0 2.0 6 3 | ||
12 | +[10,] 8 9 3.0 8.0 6 5 | ||
13 | +[11,] 0 0 2.3 2.3 7 1 | ||
14 | +[12,] 0 0 7.0 2.0 7 3 | ||
15 | +[13,] 0 0 1.0 5.0 7 4 | ||
16 | +[14,] 10 0 7.0 2.0 8 3 | ||
17 | +[15,] 10 0 8.0 9.0 8 6 | ||
18 | +[16,] 10 0 0.0 0.0 8 7 | ||
19 | +[17,] 0 10 1.0 5.0 9 4 | ||
20 | +[18,] 0 10 3.0 8.0 9 5 | ||
21 | +[19,] 0 10 8.0 9.0 9 6 | ||
22 | +[20,] 0 10 0.0 0.0 9 7 | ||
23 | +[21,] 10 10 8.0 9.0 10 6 | ||
24 | +[22,] 10 10 10.0 0.0 10 8 | ||
25 | +[23,] 10 10 0.0 10.0 10 9 | ||
26 | + | ||
27 | +$dirsgs | ||
28 | + x1 y1 x2 y2 ind1 ind2 bp1 bp2 | ||
29 | +1 1.650000 3.650000 4.560000 0.740000 2 1 FALSE FALSE | ||
30 | +2 4.560000 0.740000 4.512766 0.000000 3 1 FALSE TRUE | ||
31 | +3 5.750000 5.500000 4.560000 0.740000 3 2 FALSE FALSE | ||
32 | +4 0.000000 2.855556 1.650000 3.650000 4 1 TRUE FALSE | ||
33 | +5 1.650000 3.650000 3.500000 5.500000 4 2 FALSE FALSE | ||
34 | +6 3.500000 5.500000 5.750000 5.500000 5 2 FALSE FALSE | ||
35 | +7 5.750000 5.500000 6.058824 5.705882 5 3 FALSE FALSE | ||
36 | +8 0.500000 7.500000 3.500000 5.500000 5 4 FALSE FALSE | ||
37 | +9 6.058824 5.705882 10.000000 5.142857 6 3 FALSE TRUE | ||
38 | +10 5.200000 10.000000 6.058824 5.705882 6 5 TRUE FALSE | ||
39 | +11 2.300000 0.000000 0.000000 2.300000 7 1 TRUE TRUE | ||
40 | +12 10.000000 3.250000 7.833333 0.000000 8 3 TRUE TRUE | ||
41 | +13 0.000000 7.400000 0.500000 7.500000 9 4 TRUE FALSE | ||
42 | +14 0.500000 7.500000 2.166667 10.000000 9 5 FALSE TRUE | ||
43 | +15 8.750000 10.000000 10.000000 7.500000 10 6 TRUE TRUE | ||
44 | + | ||
45 | +$summary | ||
46 | + x y n.tri del.area del.wts n.tside nbpt dir.area dir.wts | ||
47 | + [1,] 2.3 2.3 4 4.500000 0.045000 4 4 9.092057 0.090921 | ||
48 | + [2,] 3.0 3.0 4 6.050000 0.060500 4 0 10.738500 0.107385 | ||
49 | + [3,] 7.0 2.0 6 18.666667 0.186667 5 4 23.318162 0.233182 | ||
50 | + [4,] 1.0 5.0 5 7.500000 0.075000 4 2 9.394167 0.093942 | ||
51 | + [5,] 3.0 8.0 5 15.000000 0.150000 5 2 18.055637 0.180556 | ||
52 | + [6,] 8.0 9.0 5 16.666667 0.166667 3 4 18.314811 0.183148 | ||
53 | + [7,] 0.0 0.0 4 8.450000 0.084500 1 2 2.645000 0.026450 | ||
54 | + [8,] 10.0 0.0 3 10.500000 0.105000 1 2 3.520833 0.035208 | ||
55 | + [9,] 0.0 10.0 4 7.666667 0.076667 2 2 3.358333 0.033583 | ||
56 | +[10,] 10.0 10.0 2 5.000000 0.050000 1 2 1.562500 0.015625 | ||
57 | + | ||
58 | +$n.data | ||
59 | +[1] 6 | ||
60 | + | ||
61 | +$n.dum | ||
62 | +[1] 4 | ||
63 | + | ||
64 | +$del.area | ||
65 | +[1] 100 | ||
66 | + | ||
67 | +$dir.area | ||
68 | +[1] 100 | ||
69 | + | ||
70 | +$rw | ||
71 | +[1] 0 10 0 10 | ||
72 | + | ||
73 | +attr(,"class") | ||
74 | +[1] "deldir" |
@@ -0,0 +1,224 @@ | @@ -0,0 +1,224 @@ | ||
1 | +deldir package:deldir R Documentation | ||
2 | + | ||
3 | +_C_o_n_s_t_r_u_c_t _t_h_e _D_e_l_a_u_n_a_y _t_r_i_a_n_g_u_l_a_t_i_o_n _a_n_d _t_h_e _D_i_r_i_c_h_l_e_t | ||
4 | +(_V_o_r_o_n_o_i) _t_e_s_s_e_l_l_a_t_i_o_n _o_f _a _p_l_a_n_a_r _p_o_i_n_t _s_e_t. | ||
5 | + | ||
6 | +_D_e_s_c_r_i_p_t_i_o_n: | ||
7 | + | ||
8 | + This function computes the Delaunay triangulation (and hence the | ||
9 | + Dirichlet tesselation) of a planar point set according to the | ||
10 | + second (iterative) algorithm of Lee and Schacter - see REFERENCES. | ||
11 | + The triangulation is made to be with respect to the whole plane | ||
12 | + by 'suspending' it from so-called ideal points (-Inf,-Inf), | ||
13 | + (Inf,-Inf) (Inf,Inf), and (-Inf,Inf). The triangulation is also | ||
14 | + enclosed in a finite rectangular window. A set of dummy points | ||
15 | + may be added, in various ways, to the set of data points being | ||
16 | + triangulated. | ||
17 | + | ||
18 | +_U_s_a_g_e: | ||
19 | + | ||
20 | + deldir(x, y, dpl=NULL, rw=NULL, eps=1e-09, frac=0.0001, | ||
21 | + sort=TRUE, plotit=FALSE, digits=6, ...) | ||
22 | + | ||
23 | +_A_r_g_u_m_e_n_t_s: | ||
24 | + | ||
25 | + x,y: The coordinates of the point set being triangulated. These | ||
26 | + can be given by two arguments x and y which are vectors or by | ||
27 | + a single argument x which is a list with components "x" and | ||
28 | + "y". | ||
29 | + | ||
30 | + dpl: A list describing the structure of the dummy points to be | ||
31 | + added to the data being triangulated. The addition of these | ||
32 | + dummy points is effected by the auxilliary function dumpts(). | ||
33 | + The list may have components: | ||
34 | + | ||
35 | + ndx: The x-dimension of a rectangular grid; if either ndx or | ||
36 | + ndy is null, no grid is constructed. | ||
37 | + | ||
38 | + ndy: The y-dimension of the aforementioned rectangular grid. | ||
39 | + | ||
40 | + nrad: The number of radii or "spokes", emanating from each | ||
41 | + data point, along which dummy points are to be added. | ||
42 | + | ||
43 | + nper: The number of dummy points per spoke. | ||
44 | + | ||
45 | + fctr: A factor determining the length of each spoke; each | ||
46 | + spoke is of length equal to fctr times the mean nearest | ||
47 | + neighbour distance of the data. (This distance is calculated | ||
48 | + by the auxilliary function mnnd().) | ||
49 | + | ||
50 | + x: A vector of x-coordinates of "ad hoc" dummy points | ||
51 | + | ||
52 | + y: A vector of the corresponding y-coordinates of "ad hoc" | ||
53 | + dummy points | ||
54 | + | ||
55 | + rw: The coordinates of the corners of the rectangular window | ||
56 | + enclosing the triangulation, in the order (xmin, xmax, ymin, | ||
57 | + ymax). Any data points (including dummy points) outside this | ||
58 | + window are discarded. If this argument is omitted, it | ||
59 | + defaults to values given by the range of the data, plus and | ||
60 | + minus 10 percent. | ||
61 | + | ||
62 | + eps: A value of epsilon used in testing whether a quantity is | ||
63 | + zero, mainly in the context of whether points are collinear. | ||
64 | + If anomalous errors arise, it is possible that these may | ||
65 | + averted by adjusting the value of eps upward or downward. | ||
66 | + | ||
67 | + frac: A value specifying the tolerance used in eliminating | ||
68 | + duplicate points; defaults to 0.0001. Points are considered | ||
69 | + duplicates if abs(x1-x2) < frac*(xmax-xmin) AND abs(y1-y2) < | ||
70 | + frac*(ymax-ymin). | ||
71 | + | ||
72 | + sort: Logical argument; if 'TRUE' (the default) the data (including | ||
73 | + dummy points) are sorted into a sequence of "bins" prior to | ||
74 | + triangulation; this makes the algorithm slightly more | ||
75 | + efficient. Normally one would set sort equal to 'FALSE' only | ||
76 | + if one wished to observe some of the fine detail of the way | ||
77 | + in which adding a point to a data set affected the | ||
78 | + triangulation, and therefore wished to make sure that the | ||
79 | + point in question was added last. Essentially this argument | ||
80 | + would get used only in a de-bugging process. | ||
81 | + | ||
82 | + plotit: Logical argument; if 'TRUE' a plot of the triangulation and | ||
83 | + tessellation is produced; the default is 'FALSE'. | ||
84 | + | ||
85 | + digits: The number of decimal places to which all numeric values in | ||
86 | + the returned list should be rounded. Defaults to 6. | ||
87 | + | ||
88 | + ...: Auxilliary arguments add, wlines, wpoints, number, nex, col, | ||
89 | + lty, pch, xlim, and ylim (and possibly other plotting | ||
90 | + parameters) may be passed to plot.deldir through "..." if | ||
91 | + plotit='TRUE'. | ||
92 | + | ||
93 | +_D_e_t_a_i_l_s: | ||
94 | + | ||
95 | + This package is a (straightforward) adaptation of the Splus | ||
96 | + library section ``delaunay'' to R. That library section is an | ||
97 | + implementation of the Lee-Schacter algorithm, which was originally | ||
98 | + written as a stand-alone Fortran program in 1987/88 by Rolf | ||
99 | + Turner, while with the Division of Mathematics and Statistics, | ||
100 | + CSIRO, Sydney, Australia. It was re-written as an Splus function | ||
101 | + (using dynamically loaded Fortran code), by Rolf Turner while | ||
102 | + visiting the University of Western Australia, May, 1995. | ||
103 | + | ||
104 | + Further revisions made December 1996. The author gratefully | ||
105 | + acknowledges the contributions, assistance, and guidance of Mark | ||
106 | + Berman, of D.M.S., CSIRO, in collaboration with whom this project | ||
107 | + was originally undertaken. The author also acknowledges much | ||
108 | + useful advice from Adrian Baddeley, formerly of D.M.S., CSIRO (now | ||
109 | + Professor of Statistics at the University of Western Australia). | ||
110 | + Daryl Tingley of the Department of Mathematics and Statistics, | ||
111 | + University of New Brunswick provided some helpful insight. | ||
112 | + Special thanks are extended to Alan Johnson, of the Alaska | ||
113 | + Fisheries Science Centre, who supplied two data sets which were | ||
114 | + extremely valuable in tracking down some errors in the code. | ||
115 | + | ||
116 | + Don MacQueen, of Lawrence Livermore National Lab, wrote an Splus | ||
117 | + driver function for the old stand-alone version of this software. | ||
118 | + That driver, which was available on Statlib, is now deprecated in | ||
119 | + favour of the current package ``delaunay'' package. Don also | ||
120 | + collaborated in the preparation of that package. | ||
121 | + | ||
122 | + Further revisions and bug-fixes were made in 1998, 1999, and 2002. | ||
123 | + | ||
124 | +_V_a_l_u_e: | ||
125 | + | ||
126 | + A list (of class 'deldir'), invisible if plotit='TRUE', with | ||
127 | + components: | ||
128 | + | ||
129 | + delsgs: a matrix with 6 columns. The first 4 entries of each row are | ||
130 | + the coordinates of the points joined by an edge of a Delaunay | ||
131 | + triangle, in the order (x1,y1,x2,y2). The last two entries | ||
132 | + are the indices of the two points which are joined. | ||
133 | + | ||
134 | + dirsgs: a data frame with 8 columns. The first 4 entries of each row | ||
135 | + are the coordinates of the endpoints of one the edges of a | ||
136 | + Dirichlet tile, in the order (x1,y1,x2,y2). The fifth and | ||
137 | + sixth entries are the indices of the two points, in the set | ||
138 | + being triangulated, which are separated by that edge. The | ||
139 | + seventh and eighth entries are logical values. The seventh | ||
140 | + indicates whether the first endpoint of the corresponding | ||
141 | + edge of a Dirichlet tile is a boundary point (a point on the | ||
142 | + boundary of the rectangular window). Likewise for the eighth | ||
143 | + entry and the second endpoint of the edge. | ||
144 | + | ||
145 | + summary: a matrix with 9 columns, and (n.data + n.dum) rows (see | ||
146 | + below). These rows correspond to the points in the set being | ||
147 | + triangulated. The columns are named "x" (the x-coordinate of | ||
148 | + the point), "y" (the y-coordinate), "n.tri" (the number of | ||
149 | + Delaunay triangles emanating from the point), "del.area" (1/3 | ||
150 | + of the total area of all the Delaunay triangles emanating | ||
151 | + from the point), "del.wts" (the corresponding entry of the | ||
152 | + "del.area" column divided by the sum of this column), | ||
153 | + "n.tside" (the number of sides - within the rectangular | ||
154 | + window - of the Dirichlet tile surrounding the point), "nbpt" | ||
155 | + (the number of points in which the Dirichlet tile intersects | ||
156 | + the boundary of the rectangular window), "dir.area" (the area | ||
157 | + of the Dirichlet tile surrounding the point), and "dir.wts" | ||
158 | + (the corresponding entry of the "dir.area" column divided by | ||
159 | + the sum of this column). Note that the factor of 1/3 | ||
160 | + associated with the del.area column arises because each | ||
161 | + triangle occurs three times - once for each corner. | ||
162 | + | ||
163 | + n.data: the number of real (as opposed to dummy) points in the set | ||
164 | + which was triangulated, with any duplicate points eliminated. | ||
165 | + The first n.data rows of "summary" correspond to real | ||
166 | + points. | ||
167 | + | ||
168 | + n.dum: the number of dummy points which were added to the set being | ||
169 | + triangulated, with any duplicate points (including any which | ||
170 | + duplicate real points) eliminated. The last n.dum rows of | ||
171 | + "summary" correspond to dummy points. | ||
172 | + | ||
173 | +del.area: the area of the convex hull of the set of points being | ||
174 | + triangulated, as formed by summing the "del.area" column of | ||
175 | + "summary". | ||
176 | + | ||
177 | +dir.area: the area of the rectangular window enclosing the points being | ||
178 | + triangulated, as formed by summing the "dir.area" column of | ||
179 | + "summary". | ||
180 | + | ||
181 | + rw: the specification of the corners of the rectangular window | ||
182 | + enclosing the data, in the order (xmin, xmax, ymin, ymax). | ||
183 | + | ||
184 | +_S_i_d_e _E_f_f_e_c_t_s: | ||
185 | + | ||
186 | + If plotit=='TRUE' a plot of the triangulation and/or tessellation | ||
187 | + is produced or added to an existing plot. | ||
188 | + | ||
189 | +_N_o_t_e: | ||
190 | + | ||
191 | + If ndx >= 2 and ndy >= 2, then the rectangular window IS the | ||
192 | + convex hull, and so the values of del.area and dir.area are | ||
193 | + identical. | ||
194 | + | ||
195 | +_A_u_t_h_o_r(_s): | ||
196 | + | ||
197 | + Rolf Turner r.turner@auckland.ac.nz <URL: | ||
198 | + http://www.math.unb.ca/~rolf> | ||
199 | + | ||
200 | +_R_e_f_e_r_e_n_c_e_s: | ||
201 | + | ||
202 | + Lee, D. T., and Schacter, B. J. "Two algorithms for constructing | ||
203 | + a Delaunay triangulation", Int. J. Computer and Information | ||
204 | + Sciences, Vol. 9, No. 3, 1980, pp. 219 - 242. | ||
205 | + | ||
206 | + Ahuja, N. and Schacter, B. J. (1983). Pattern Models. New York: | ||
207 | + Wiley. | ||
208 | + | ||
209 | +_S_e_e _A_l_s_o: | ||
210 | + | ||
211 | + plot.deldir | ||
212 | + | ||
213 | +_E_x_a_m_p_l_e_s: | ||
214 | + | ||
215 | + x <- c(2.3,3.0,7.0,1.0,3.0,8.0) | ||
216 | + y <- c(2.3,3.0,2.0,5.0,8.0,9.0) | ||
217 | + try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
218 | + # Puts dummy points at the corners of the rectangular | ||
219 | + # window, i.e. at (0,0), (10,0), (10,10), and (0,10) | ||
220 | + ## Not run: | ||
221 | + try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr') | ||
222 | + ## End(Not run) | ||
223 | + # Plots the triangulation which was created (but not the tesselation). | ||
224 | + |
@@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
1 | +deldir-internal package:deldir R Documentation | ||
2 | + | ||
3 | +_I_n_t_e_r_n_a_l _d_e_l_d_i_r _f_u_n_c_t_i_o_n_s | ||
4 | + | ||
5 | +_D_e_s_c_r_i_p_t_i_o_n: | ||
6 | + | ||
7 | + Internal deldir functions. | ||
8 | + | ||
9 | +_U_s_a_g_e: | ||
10 | + | ||
11 | + dumpts(x,y,dpl,rw) | ||
12 | + ind.dup(x,y,rw=NULL,frac=0.0001) | ||
13 | + mid.in(x,y,rx,ry) | ||
14 | + mnnd(x,y) | ||
15 | + get.cnrind(x,y,rw) | ||
16 | + acw(xxx) | ||
17 | + | ||
18 | +_D_e_t_a_i_l_s: | ||
19 | + | ||
20 | + These functions are auxilliary and are not intended to be called | ||
21 | + by the user. | ||
22 | + |
@@ -0,0 +1,118 @@ | @@ -0,0 +1,118 @@ | ||
1 | +plot.deldir package:deldir R Documentation | ||
2 | + | ||
3 | +_P_r_o_d_u_c_e _a _p_l_o_t _o_f _t_h_e _D_e_l_a_u_n_a_y _t_r_i_a_n_g_u_l_a_t_i_o_n _a_n_d _D_i_r_i_c_h_l_e_t (_V_o_r_o_n_o_i) | ||
4 | +_t_e_s_s_e_l_a_t_i_o_n _o_f _a _p_l_a_n_a_r _p_o_i_n_t _s_e_t, _a_s _c_o_n_s_t_r_u_c_t_e_d _b_y _t_h_e _f_u_n_c_t_i_o_n _d_e_l_d_i_r. | ||
5 | + | ||
6 | +_D_e_s_c_r_i_p_t_i_o_n: | ||
7 | + | ||
8 | + This is a method for plot. | ||
9 | + | ||
10 | +_U_s_a_g_e: | ||
11 | + | ||
12 | + ## S3 method for class 'deldir': | ||
13 | + plot(x,add=FALSE,wlines=c('both','triang','tess'), | ||
14 | + wpoints=c('both','real','dummy','none'), | ||
15 | + number=FALSE,cex=1,nex=1,col=NULL,lty=NULL, | ||
16 | + pch=NULL,xlim=NULL,ylim=NULL,xlab='x',ylab='y',...) | ||
17 | + | ||
18 | +_A_r_g_u_m_e_n_t_s: | ||
19 | + | ||
20 | + x: An object of class "deldir" as constructed by the function | ||
21 | + deldir. | ||
22 | + | ||
23 | + add: logical argument; should the plot be added to an existing | ||
24 | + plot? | ||
25 | + | ||
26 | + wlines: "which lines?". I.e. should the Delaunay triangulation be | ||
27 | + plotted (wlines='triang'), should the Dirichlet tessellation | ||
28 | + be plotted (wlines='tess'), or should both be plotted | ||
29 | + (wlines='both', the default) ? | ||
30 | + | ||
31 | + wpoints: "which points?". I.e. should the real points be plotted | ||
32 | + (wpoints='real'), should the dummy points be plotted | ||
33 | + (wpoints='dummy'), should both be plotted (wpoints='both', | ||
34 | + the default) or should no points be plotted (wpoints='none')? | ||
35 | + | ||
36 | + number: Logical argument, defaulting to 'FALSE'; if 'TRUE' then the | ||
37 | + points plotted will be labelled with their index numbers | ||
38 | + (corresponding to the row numbers of the matrix "summary" in | ||
39 | + the output of deldir). | ||
40 | + | ||
41 | + cex: The value of the character expansion argument cex to be used | ||
42 | + with the plotting symbols for plotting the points. | ||
43 | + | ||
44 | + nex: The value of the character expansion argument cex to be used | ||
45 | + by the text function when numbering the points with their | ||
46 | + indices. Used only if number='TRUE'. | ||
47 | + | ||
48 | + col: the colour numbers for plotting the triangulation, the | ||
49 | + tesselation, the data points, the dummy points, and the point | ||
50 | + numbers, in that order; defaults to c(1,1,1,1,1). If fewer | ||
51 | + than five numbers are given, they are recycled. (If more | ||
52 | + than five numbers are given, the redundant ones are ignored.) | ||
53 | + | ||
54 | + lty: the line type numbers for plotting the triangulation and the | ||
55 | + tesselation, in that order; defaults to 1:2. If only one | ||
56 | + value is given it is repeated. (If more than two numbers are | ||
57 | + given, the redundant ones are ignored.) | ||
58 | + | ||
59 | + pch: the plotting symbols for plotting the data points and the | ||
60 | + dummy points, in that order; may be either integer or | ||
61 | + character; defaults to 1:2. If only one value is given it is | ||
62 | + repeated. (If more than two values are given, the redundant | ||
63 | + ones are ignored.) | ||
64 | + | ||
65 | + xlim: the limits on the x-axis. Defaults to rw[1:2] where rw is | ||
66 | + the rectangular window specification returned by deldir(). | ||
67 | + | ||
68 | + ylim: the limits on the y-axis. Defaults to rw[3:4] where rw is | ||
69 | + the rectangular window specification returned by deldir(). | ||
70 | + | ||
71 | + xlab: label for the x-axis. Defaults to 'x'. Ignored if | ||
72 | + 'add=TRUE'. | ||
73 | + | ||
74 | + ylab: label for the y-axis. Defaults to 'y'. Ignored if | ||
75 | + 'add=TRUE'. | ||
76 | + | ||
77 | + ...: Further plotting parameters to be passed to 'plot()' | ||
78 | + 'segments()' or 'points()'. Unlikely to be used. | ||
79 | + | ||
80 | +_D_e_t_a_i_l_s: | ||
81 | + | ||
82 | + The points in the set being triangulated are plotted with | ||
83 | + distinguishing symbols. By default the real points are plotted as | ||
84 | + circles (pch=1) and the dummy points are plotted as triangles | ||
85 | + (pch=2). | ||
86 | + | ||
87 | +_S_i_d_e _E_f_f_e_c_t_s: | ||
88 | + | ||
89 | + A plot of the points being triangulated is produced or added to an | ||
90 | + existing plot. As well, the edges of the Delaunay triangles | ||
91 | + and/or of the Dirichlet tiles are plotted. By default the | ||
92 | + triangles are plotted with solid lines (lty=1) and the tiles with | ||
93 | + dotted lines (lty=2). | ||
94 | + | ||
95 | +_A_u_t_h_o_r(_s): | ||
96 | + | ||
97 | + Rolf Turner r.turner@auckland.ac.nz <URL: | ||
98 | + http://www.math.unb.ca/~rolf> | ||
99 | + | ||
100 | +_S_e_e _A_l_s_o: | ||
101 | + | ||
102 | + 'deldir()' | ||
103 | + | ||
104 | +_E_x_a_m_p_l_e_s: | ||
105 | + | ||
106 | + ## Not run: | ||
107 | + try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
108 | + plot(try) | ||
109 | + # | ||
110 | + deldir(x,y,list(ndx=4,ndy=4),plot=TRUE,add=TRUE,wl='te', | ||
111 | + col=c(1,1,2,3,4),num=TRUE) | ||
112 | + # Plots the tesselation, but does not save the results. | ||
113 | + try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr', | ||
114 | + wp='n') | ||
115 | + # Plots the triangulation, but not the points, and saves the returned | ||
116 | + structure. | ||
117 | + ## End(Not run) | ||
118 | + |
@@ -0,0 +1,88 @@ | @@ -0,0 +1,88 @@ | ||
1 | +plot.tile.list package:deldir R Documentation | ||
2 | + | ||
3 | +_P_l_o_t _D_i_r_c_h_l_e_t/_V_o_r_o_n_o_i _t_i_l_e_s | ||
4 | + | ||
5 | +_D_e_s_c_r_i_p_t_i_o_n: | ||
6 | + | ||
7 | + A method for 'plot'. Plots (sequentially) the tiles associated | ||
8 | + with each point in the set being tessellated. | ||
9 | + | ||
10 | +_U_s_a_g_e: | ||
11 | + | ||
12 | + plot.tile.list(x, verbose = FALSE, close=FALSE, pch=1, polycol=NA, | ||
13 | + showpoints=TRUE, asp=1, ...) | ||
14 | + ## S3 method for class 'tile.list': | ||
15 | + plot(x, verbose = FALSE, close=FALSE, pch=1, | ||
16 | + polycol=NA, showpoints=TRUE, asp=1, ...) | ||
17 | + | ||
18 | +_A_r_g_u_m_e_n_t_s: | ||
19 | + | ||
20 | + x: A list of the tiles in a tessellation, as produced the | ||
21 | + function 'tile.list()'. | ||
22 | + | ||
23 | + verbose: Logical scalar; if 'TRUE' the tiles are plotted one at a time | ||
24 | + (with a ``Go?'' prompt after each) so that the process can be | ||
25 | + watched. | ||
26 | + | ||
27 | + close: Logical scalar; if 'TRUE' the outer edges of of the tiles | ||
28 | + (i.e. the edges of the enclosing rectangle) are drawn. | ||
29 | + Otherwise tiles on the periphery of the tessellation are left | ||
30 | + ``open''. | ||
31 | + | ||
32 | + pch: The plotting character for plotting the points of the pattern | ||
33 | + which was tessellated. Ignored if 'showpoints' is 'FALSE'. | ||
34 | + | ||
35 | + polycol: Optional vector of integers (or 'NA's); the i-th entry | ||
36 | + indicates with which colour to fill the i-th tile. Note that | ||
37 | + an 'NA' indicates the use of no colour at all. | ||
38 | + | ||
39 | +showpoints: Logical scalar; if 'TRUE' the points of the pattern which | ||
40 | + was tesselated are plotted. | ||
41 | + | ||
42 | + asp: The aspect ratio of the plot; integer scalar or 'NA'. Set | ||
43 | + this argument equal to 'NA' to allow the data to determine | ||
44 | + the aspect ratio and hence to make the plot occupy the | ||
45 | + complete plotting region in both 'x' and 'y' directions. This | ||
46 | + is inadvisable; see the *Warnings*. | ||
47 | + | ||
48 | + ...: Optional arguments; not used. There for consistency with the | ||
49 | + generic 'plot' function. | ||
50 | + | ||
51 | +_V_a_l_u_e: | ||
52 | + | ||
53 | + NULL; side effect is a plot. | ||
54 | + | ||
55 | +_W_a_r_n_i_n_g_s: | ||
56 | + | ||
57 | + The default value for 'verbose' was formerly 'TRUE'; it is now | ||
58 | + 'FALSE'. | ||
59 | + | ||
60 | + The user is _strongly advised_ not to set the value of 'asp' but | ||
61 | + rather to leave 'asp' equal to its default value of '1'. Any | ||
62 | + other value distorts the tesselation and destroys the | ||
63 | + perpendicular appearance of lines which are indeed perpendicular. | ||
64 | + (And conversely can cause lines which are not perpendicular to | ||
65 | + appear as if they are.) | ||
66 | + | ||
67 | + The argument 'asp' is present ``just because it can be''. | ||
68 | + | ||
69 | +_A_u_t_h_o_r(_s): | ||
70 | + | ||
71 | + Rolf Turner r.turner@auckland.ac.nz <URL: | ||
72 | + http://www.math.unb.ca/~rolf> | ||
73 | + | ||
74 | +_S_e_e _A_l_s_o: | ||
75 | + | ||
76 | + 'tile.list()' | ||
77 | + | ||
78 | +_E_x_a_m_p_l_e_s: | ||
79 | + | ||
80 | + x <- runif(20) | ||
81 | + y <- runif(20) | ||
82 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
83 | + w <- tile.list(z) | ||
84 | + plot(w) | ||
85 | + ccc <- heat.colors(20) # Or topo.colors(20), or terrain.colors(20) | ||
86 | + # or cm.colors(20), or rainbox(20). | ||
87 | + plot(w,polycol=ccc,close=TRUE) | ||
88 | + |
@@ -0,0 +1,81 @@ | @@ -0,0 +1,81 @@ | ||
1 | +tile.list package:deldir R Documentation | ||
2 | + | ||
3 | +_C_r_e_a_t_e _a _l_i_s_t _o_f _t_i_l_e_s _i_n _a _t_e_s_s_e_l_l_a_t_i_o_n. | ||
4 | + | ||
5 | +_D_e_s_c_r_i_p_t_i_o_n: | ||
6 | + | ||
7 | + For each point in the set being tessellated produces a list entry | ||
8 | + describing the Dirichlet/Voronoi tile containing that point. | ||
9 | + | ||
10 | +_U_s_a_g_e: | ||
11 | + | ||
12 | + tile.list(object) | ||
13 | + | ||
14 | +_A_r_g_u_m_e_n_t_s: | ||
15 | + | ||
16 | + object: An object of class 'deldir' as produced by the function | ||
17 | + 'deldir()'. | ||
18 | + | ||
19 | +_V_a_l_u_e: | ||
20 | + | ||
21 | + A list with one entry for each of the points in the set being | ||
22 | + tesselated. Each entry is in turn a list with components | ||
23 | + | ||
24 | + pt: The coordinates of the point whose tile is being described. | ||
25 | + | ||
26 | + x: The 'x' coordinates of the vertices of the tile, in | ||
27 | + anticlockwise order. | ||
28 | + | ||
29 | + y: The 'y' coordinates of the vertices of the tile, in | ||
30 | + anticlockwise order. | ||
31 | + | ||
32 | + bp: Vector of logicals indicating whether the tile vertex is a | ||
33 | + ``real'' vertex, or a _boundary point_, i.e. a point where | ||
34 | + the tile edge intersects the boundary of the enclosing | ||
35 | + rectangle | ||
36 | + | ||
37 | +_A_c_k_n_o_w_l_e_d_g_e_m_e_n_t: | ||
38 | + | ||
39 | + The author expresses sincere thanks to Majid Yazdani who found and | ||
40 | + pointed out a serious bug in 'tile.list' in the previous version | ||
41 | + (0.0-5) of the 'deldir' package. | ||
42 | + | ||
43 | +_W_a_r_n_i_n_g: | ||
44 | + | ||
45 | + The set of vertices of each tile may be ``incomplete''. Only | ||
46 | + vertices which lie within the enclosing rectangle, and ``boundary | ||
47 | + points'' are listed. | ||
48 | + | ||
49 | + Note that the enclosing rectangle may be specified by the user in | ||
50 | + the call to 'deldir()'. | ||
51 | + | ||
52 | + In contrast to the previous version of 'deldir', the corners of | ||
53 | + the enclosing rectangle are now include as vertices of tiles. | ||
54 | + I.e. a tile which in fact extends beyond the rectangular window | ||
55 | + and contains a corner of that window will have that corner added | ||
56 | + to its list of vertices. Thus when the corresponding polygon is | ||
57 | + plotted, the result is the intersection of the tile with the | ||
58 | + enclosing rectangular window. | ||
59 | + | ||
60 | +_A_u_t_h_o_r(_s): | ||
61 | + | ||
62 | + Rolf Turner r.turner@auckland.ac.nz <URL: | ||
63 | + http://www.math.unb.ca/~rolf> | ||
64 | + | ||
65 | +_S_e_e _A_l_s_o: | ||
66 | + | ||
67 | + 'deldir()', 'plot.tile.list()' | ||
68 | + | ||
69 | +_E_x_a_m_p_l_e_s: | ||
70 | + | ||
71 | + x <- runif(20) | ||
72 | + y <- runif(20) | ||
73 | + z <- deldir(x,y) | ||
74 | + w <- tile.list(z) | ||
75 | + | ||
76 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
77 | + w <- tile.list(z) | ||
78 | + | ||
79 | + z <- deldir(x,y,rw=c(0,1,0,1),dpl=list(ndx=2,ndy=2)) | ||
80 | + w <- tile.list(z) | ||
81 | + |
@@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | +<html><head><title>R: Delaunay Triangulation and Dirichlet (Voronoi) Tessellation.</title> | ||
3 | +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
4 | +<link rel="stylesheet" type="text/css" href="../../R.css"> | ||
5 | +</head><body> | ||
6 | +<h1>Delaunay Triangulation and Dirichlet (Voronoi) Tessellation. <img class="toplogo" src="../../../doc/html/logo.jpg" alt="[R logo]"></h1> | ||
7 | + | ||
8 | +<hr> | ||
9 | + | ||
10 | +<div align="center"> | ||
11 | +<a href="../../../doc/html/packages.html"><img src="../../../doc/html/left.jpg" | ||
12 | +alt="[Package List]" width="30" height="30" border="0"></a> | ||
13 | +<a href="../../../doc/html/index.html"><img src="../../../doc/html/up.jpg" | ||
14 | +alt="[Top]" width="30" height="30" border="0"></a> | ||
15 | +</div> | ||
16 | + | ||
17 | +<h2>Documentation for package ‘deldir’</h2> | ||
18 | + | ||
19 | +<h2>Help Pages</h2> | ||
20 | + | ||
21 | + | ||
22 | +<table width="100%"> | ||
23 | +<tr><td width="25%"><a href="deldir.html">deldir</a></td> | ||
24 | +<td>Construct the Delaunay triangulation and the Dirichlet (Voronoi) tessellation of a planar point set. </td></tr> | ||
25 | +<tr><td width="25%"><a href="plot.deldir.html">plot.deldir</a></td> | ||
26 | +<td>Produce a plot of the Delaunay triangulation and Dirichlet (Voronoi) tesselation of a planar point set, as constructed by the function deldir. </td></tr> | ||
27 | +<tr><td width="25%"><a href="plot.tile.list.html">plot.tile.list</a></td> | ||
28 | +<td>Plot Dirchlet/Voronoi tiles </td></tr> | ||
29 | +<tr><td width="25%"><a href="tile.list.html">tile.list</a></td> | ||
30 | +<td>Create a list of tiles in a tessellation. </td></tr> | ||
31 | +</table> | ||
32 | +</body></html> |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | +<html><head><title>R: Internal deldir functions</title> | ||
3 | +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
4 | +<link rel="stylesheet" type="text/css" href="../../R.css"> | ||
5 | +</head><body> | ||
6 | + | ||
7 | +<table width="100%" summary="page for deldir-internal {deldir}"><tr><td>deldir-internal {deldir}</td><td align="right">R Documentation</td></tr></table> | ||
8 | +<h2>Internal deldir functions</h2> | ||
9 | + | ||
10 | + | ||
11 | +<h3>Description</h3> | ||
12 | + | ||
13 | +<p> | ||
14 | +Internal deldir functions. | ||
15 | +</p> | ||
16 | + | ||
17 | + | ||
18 | +<h3>Usage</h3> | ||
19 | + | ||
20 | +<pre> | ||
21 | +dumpts(x,y,dpl,rw) | ||
22 | +ind.dup(x,y,rw=NULL,frac=0.0001) | ||
23 | +mid.in(x,y,rx,ry) | ||
24 | +mnnd(x,y) | ||
25 | +get.cnrind(x,y,rw) | ||
26 | +acw(xxx) | ||
27 | +</pre> | ||
28 | + | ||
29 | + | ||
30 | +<h3>Details</h3> | ||
31 | + | ||
32 | +<p> | ||
33 | +These functions are auxilliary and are not intended to be called by | ||
34 | +the user. | ||
35 | +</p> | ||
36 | + | ||
37 | + | ||
38 | + | ||
39 | +<hr><div align="center">[Package <em>deldir</em> version 0.0-7 <a href="00Index.html">Index]</a></div> | ||
40 | + | ||
41 | +</body></html> |
@@ -0,0 +1,293 @@ | @@ -0,0 +1,293 @@ | ||
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | +<html><head><title>R: Construct the Delaunay triangulation and the Dirichlet | ||
3 | +(Voronoi) tessellation of a planar point set.</title> | ||
4 | +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
5 | +<link rel="stylesheet" type="text/css" href="../../R.css"> | ||
6 | +</head><body> | ||
7 | + | ||
8 | +<table width="100%" summary="page for deldir {deldir}"><tr><td>deldir {deldir}</td><td align="right">R Documentation</td></tr></table> | ||
9 | +<h2>Construct the Delaunay triangulation and the Dirichlet | ||
10 | +(Voronoi) tessellation of a planar point set.</h2> | ||
11 | + | ||
12 | + | ||
13 | +<h3>Description</h3> | ||
14 | + | ||
15 | +<p> | ||
16 | +This function computes the Delaunay triangulation (and hence the | ||
17 | +Dirichlet tesselation) of a planar point set according to the second | ||
18 | +(iterative) algorithm of Lee and Schacter — see REFERENCES. The | ||
19 | +triangulation is made to be with respect to the whole plane by | ||
20 | +<code>suspending</code> it from so-called ideal points (-Inf,-Inf), (Inf,-Inf) | ||
21 | +(Inf,Inf), and (-Inf,Inf). The triangulation is also enclosed in a | ||
22 | +finite rectangular window. A set of dummy points may | ||
23 | +be added, in various ways, to the set of data points being triangulated. | ||
24 | +</p> | ||
25 | + | ||
26 | + | ||
27 | +<h3>Usage</h3> | ||
28 | + | ||
29 | +<pre> | ||
30 | +deldir(x, y, dpl=NULL, rw=NULL, eps=1e-09, frac=0.0001, | ||
31 | + sort=TRUE, plotit=FALSE, digits=6, ...) | ||
32 | +</pre> | ||
33 | + | ||
34 | + | ||
35 | +<h3>Arguments</h3> | ||
36 | + | ||
37 | +<table summary="R argblock"> | ||
38 | +<tr valign="top"><td><code>x,y</code></td> | ||
39 | +<td> | ||
40 | +The coordinates of the point set being triangulated. These can be | ||
41 | +given by two arguments x and y which are vectors or by a single | ||
42 | +argument x which is a list with components "x" and "y". | ||
43 | +</td></tr> | ||
44 | +<tr valign="top"><td><code>dpl</code></td> | ||
45 | +<td> | ||
46 | +A list describing the structure of the dummy points to be added | ||
47 | +to the data being triangulated. The addition of these dummy points | ||
48 | +is effected by the auxilliary function dumpts(). The list may have | ||
49 | +components: | ||
50 | +<br> | ||
51 | +ndx: The x-dimension of a rectangular grid; if either ndx or ndy is null, | ||
52 | +no grid is constructed. | ||
53 | +<br> | ||
54 | +ndy: The y-dimension of the aforementioned rectangular grid. | ||
55 | +<br> | ||
56 | +nrad: The number of radii or "spokes", emanating from each data point, | ||
57 | +along which dummy points are to be added. | ||
58 | +<br> | ||
59 | +nper: The number of dummy points per spoke. | ||
60 | +<br> | ||
61 | +fctr: A factor determining the length of each spoke; each spoke is of | ||
62 | +length equal to fctr times the mean nearest neighbour distance of the data. | ||
63 | +(This distance is calculated by the auxilliary function mnnd().) | ||
64 | +<br> | ||
65 | +x: A vector of x-coordinates of "ad hoc" dummy points | ||
66 | +<br> | ||
67 | +y: A vector of the corresponding y-coordinates of "ad hoc" dummy points | ||
68 | +<br> | ||
69 | +</td></tr> | ||
70 | +<tr valign="top"><td><code>rw</code></td> | ||
71 | +<td> | ||
72 | +The coordinates of the corners of the rectangular window enclosing | ||
73 | +the triangulation, in the order (xmin, xmax, ymin, ymax). Any data | ||
74 | +points (including dummy points) outside this window are discarded. | ||
75 | +If this argument is omitted, it defaults to values given by the range | ||
76 | +of the data, plus and minus 10 percent. | ||
77 | +</td></tr> | ||
78 | +<tr valign="top"><td><code>eps</code></td> | ||
79 | +<td> | ||
80 | +A value of epsilon used in testing whether a quantity is zero, mainly | ||
81 | +in the context of whether points are collinear. If anomalous errors | ||
82 | +arise, it is possible that these may averted by adjusting the value | ||
83 | +of eps upward or downward. | ||
84 | +</td></tr> | ||
85 | +<tr valign="top"><td><code>frac</code></td> | ||
86 | +<td> | ||
87 | +A value specifying the tolerance used in eliminating duplicate | ||
88 | +points; defaults to 0.0001. Points are considered duplicates if | ||
89 | +abs(x1-x2) < frac*(xmax-xmin) AND abs(y1-y2) < frac*(ymax-ymin). | ||
90 | +</td></tr> | ||
91 | +<tr valign="top"><td><code>sort</code></td> | ||
92 | +<td> | ||
93 | +Logical argument; if <code>TRUE</code> (the default) the data (including dummy | ||
94 | +points) are sorted into a sequence of "bins" prior to triangulation; | ||
95 | +this makes the algorithm slightly more efficient. Normally one would | ||
96 | +set sort equal to <code>FALSE</code> only if one wished to observe some of the | ||
97 | +fine detail of the way in which adding a point to a data set affected | ||
98 | +the triangulation, and therefore wished to make sure that the point | ||
99 | +in question was added last. Essentially this argument would get used | ||
100 | +only in a de-bugging process. | ||
101 | +</td></tr> | ||
102 | +<tr valign="top"><td><code>plotit</code></td> | ||
103 | +<td> | ||
104 | +Logical argument; if <code>TRUE</code> a plot of the triangulation and tessellation | ||
105 | +is produced; the default is <code>FALSE</code>. | ||
106 | +</td></tr> | ||
107 | +<tr valign="top"><td><code>digits</code></td> | ||
108 | +<td> | ||
109 | +The number of decimal places to which all numeric values in the | ||
110 | +returned list should be rounded. Defaults to 6. | ||
111 | +</td></tr> | ||
112 | +<tr valign="top"><td><code>...</code></td> | ||
113 | +<td> | ||
114 | +Auxilliary arguments add, wlines, wpoints, number, nex, col, lty, | ||
115 | +pch, xlim, and ylim (and possibly other plotting parameters) may be | ||
116 | +passed to plot.deldir through "..." if plotit=<code>TRUE</code>. | ||
117 | +</td></tr> | ||
118 | +</table> | ||
119 | + | ||
120 | +<h3>Details</h3> | ||
121 | + | ||
122 | +<p> | ||
123 | +This package is a (straightforward) adaptation of the Splus library | ||
124 | +section ``delaunay'' to R. That library section is an implementation | ||
125 | +of the Lee-Schacter algorithm, which was originally written as a | ||
126 | +stand-alone Fortran program in 1987/88 by Rolf Turner, while with the | ||
127 | +Division of Mathematics and Statistics, CSIRO, Sydney, Australia. It | ||
128 | +was re-written as an Splus function (using dynamically loaded Fortran | ||
129 | +code), by Rolf Turner while visiting the University of Western | ||
130 | +Australia, May, 1995. | ||
131 | +</p> | ||
132 | +<p> | ||
133 | +Further revisions made December 1996. The author gratefully | ||
134 | +acknowledges the contributions, assistance, and guidance of Mark | ||
135 | +Berman, of D.M.S., CSIRO, in collaboration with whom this project was | ||
136 | +originally undertaken. The author also acknowledges much useful | ||
137 | +advice from Adrian Baddeley, formerly of D.M.S., CSIRO (now Professor | ||
138 | +of Statistics at the University of Western Australia). Daryl Tingley | ||
139 | +of the Department of Mathematics and Statistics, University of New | ||
140 | +Brunswick provided some helpful insight. Special thanks are extended | ||
141 | +to Alan Johnson, of the Alaska Fisheries Science Centre, who supplied | ||
142 | +two data sets which were extremely valuable in tracking down some | ||
143 | +errors in the code. | ||
144 | +</p> | ||
145 | +<p> | ||
146 | +Don MacQueen, of Lawrence Livermore National Lab, wrote an Splus | ||
147 | +driver function for the old stand-alone version of this software. | ||
148 | +That driver, which was available on Statlib, is now deprecated in | ||
149 | +favour of the current package ``delaunay'' package. Don also | ||
150 | +collaborated in the preparation of that package. | ||
151 | +</p> | ||
152 | +<p> | ||
153 | +Further revisions and bug-fixes were made in 1998, 1999, and 2002. | ||
154 | +</p> | ||
155 | + | ||
156 | + | ||
157 | +<h3>Value</h3> | ||
158 | + | ||
159 | +<p> | ||
160 | +A list (of class <code>deldir</code>), invisible if plotit=<code>TRUE</code>, with components: | ||
161 | +</p> | ||
162 | +<table summary="R argblock"> | ||
163 | +<tr valign="top"><td><code>delsgs</code></td> | ||
164 | +<td> | ||
165 | +a matrix with 6 columns. The first 4 entries of each row are the | ||
166 | +coordinates of the points joined by an edge of a Delaunay | ||
167 | +triangle, in the order (x1,y1,x2,y2). The last two entries are the | ||
168 | +indices of the two points which are joined. | ||
169 | +</td></tr> | ||
170 | +<tr valign="top"><td><code>dirsgs</code></td> | ||
171 | +<td> | ||
172 | +a data frame with 8 columns. The first 4 entries of each row are the | ||
173 | +coordinates of the endpoints of one the edges of a Dirichlet tile, in | ||
174 | +the order (x1,y1,x2,y2). The fifth and sixth entries are the indices | ||
175 | +of the two points, in the set being triangulated, which are separated | ||
176 | +by that edge. The seventh and eighth entries are logical values. The | ||
177 | +seventh indicates whether the first endpoint of the corresponding | ||
178 | +edge of a Dirichlet tile is a boundary point (a point on the boundary | ||
179 | +of the rectangular window). Likewise for the eighth entry and the | ||
180 | +second endpoint of the edge. | ||
181 | +</td></tr> | ||
182 | +<tr valign="top"><td><code>summary</code></td> | ||
183 | +<td> | ||
184 | +a matrix with 9 columns, and (n.data + n.dum) rows (see below). | ||
185 | +These rows correspond to the points in the set being triangulated. | ||
186 | +The columns are named "x" (the x-coordinate of the point), "y" (the | ||
187 | +y-coordinate), "n.tri" (the number of Delaunay triangles emanating | ||
188 | +from the point), "del.area" (1/3 of the total area of all the | ||
189 | +Delaunay triangles emanating from the point), "del.wts" (the | ||
190 | +corresponding entry of the "del.area" column divided by the sum of | ||
191 | +this column), "n.tside" (the number of sides — within the | ||
192 | +rectangular window — of the Dirichlet tile surrounding the point), | ||
193 | +"nbpt" (the number of points in which the Dirichlet tile intersects | ||
194 | +the boundary of the rectangular window), "dir.area" (the area of the | ||
195 | +Dirichlet tile surrounding the point), and "dir.wts" (the | ||
196 | +corresponding entry of the "dir.area" column divided by the sum of | ||
197 | +this column). Note that the factor of 1/3 associated with the | ||
198 | +del.area column arises because each triangle occurs three times — | ||
199 | +once for each corner. | ||
200 | +</td></tr> | ||
201 | +<tr valign="top"><td><code>n.data</code></td> | ||
202 | +<td> | ||
203 | +the number of real (as opposed to dummy) points in the set which was | ||
204 | +triangulated, with any duplicate points eliminated. The first n.data | ||
205 | +rows of "summary" correspond to real points. | ||
206 | +</td></tr> | ||
207 | +<tr valign="top"><td><code>n.dum</code></td> | ||
208 | +<td> | ||
209 | +the number of dummy points which were added to the set being triangulated, | ||
210 | +with any duplicate points (including any which duplicate real points) | ||
211 | +eliminated. The last n.dum rows of "summary" correspond to dummy | ||
212 | +points. | ||
213 | +</td></tr> | ||
214 | +<tr valign="top"><td><code>del.area</code></td> | ||
215 | +<td> | ||
216 | +the area of the convex hull of the set of points being triangulated, | ||
217 | +as formed by summing the "del.area" column of "summary". | ||
218 | +</td></tr> | ||
219 | +<tr valign="top"><td><code>dir.area</code></td> | ||
220 | +<td> | ||
221 | +the area of the rectangular window enclosing the points being triangulated, | ||
222 | +as formed by summing the "dir.area" column of "summary". | ||
223 | +</td></tr> | ||
224 | +<tr valign="top"><td><code>rw</code></td> | ||
225 | +<td> | ||
226 | +the specification of the corners of the rectangular window enclosing | ||
227 | +the data, in the order (xmin, xmax, ymin, ymax). | ||
228 | +</td></tr> | ||
229 | +</table> | ||
230 | + | ||
231 | +<h3>Side Effects</h3> | ||
232 | + | ||
233 | +<p> | ||
234 | +If plotit==<code>TRUE</code> a plot of the triangulation and/or tessellation is produced | ||
235 | +or added to an existing plot. | ||
236 | +</p> | ||
237 | + | ||
238 | + | ||
239 | +<h3>Note</h3> | ||
240 | + | ||
241 | +<p> | ||
242 | +If ndx >= 2 and ndy >= 2, then the rectangular window IS the convex | ||
243 | +hull, and so the values of del.area and dir.area are identical. | ||
244 | +</p> | ||
245 | + | ||
246 | + | ||
247 | +<h3>Author(s)</h3> | ||
248 | + | ||
249 | +<p> | ||
250 | +Rolf Turner | ||
251 | +<a href="mailto:r.turner@auckland.ac.nz">r.turner@auckland.ac.nz</a> | ||
252 | +<a href="http://www.math.unb.ca/~rolf">http://www.math.unb.ca/~rolf</a> | ||
253 | +</p> | ||
254 | + | ||
255 | + | ||
256 | +<h3>References</h3> | ||
257 | + | ||
258 | +<p> | ||
259 | +Lee, D. T., and Schacter, B. J. "Two algorithms for constructing a | ||
260 | +Delaunay triangulation", Int. J. Computer and Information | ||
261 | +Sciences, Vol. 9, No. 3, 1980, pp. 219 – 242. | ||
262 | +</p> | ||
263 | +<p> | ||
264 | +Ahuja, N. and Schacter, B. J. (1983). Pattern Models. New York: Wiley. | ||
265 | +</p> | ||
266 | + | ||
267 | + | ||
268 | +<h3>See Also</h3> | ||
269 | + | ||
270 | +<p> | ||
271 | +plot.deldir | ||
272 | +</p> | ||
273 | + | ||
274 | + | ||
275 | +<h3>Examples</h3> | ||
276 | + | ||
277 | +<pre> | ||
278 | +x <- c(2.3,3.0,7.0,1.0,3.0,8.0) | ||
279 | +y <- c(2.3,3.0,2.0,5.0,8.0,9.0) | ||
280 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
281 | +# Puts dummy points at the corners of the rectangular | ||
282 | +# window, i.e. at (0,0), (10,0), (10,10), and (0,10) | ||
283 | +## Not run: | ||
284 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr') | ||
285 | +## End(Not run) | ||
286 | +# Plots the triangulation which was created (but not the tesselation). | ||
287 | +</pre> | ||
288 | + | ||
289 | + | ||
290 | + | ||
291 | +<hr><div align="center">[Package <em>deldir</em> version 0.0-7 <a href="00Index.html">Index]</a></div> | ||
292 | + | ||
293 | +</body></html> |
@@ -0,0 +1,181 @@ | @@ -0,0 +1,181 @@ | ||
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | +<html><head><title>R: Produce a plot of the Delaunay triangulation and Dirichlet (Voronoi) | ||
3 | +tesselation of a planar point set, as constructed by the function deldir.</title> | ||
4 | +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
5 | +<link rel="stylesheet" type="text/css" href="../../R.css"> | ||
6 | +</head><body> | ||
7 | + | ||
8 | +<table width="100%" summary="page for plot.deldir {deldir}"><tr><td>plot.deldir {deldir}</td><td align="right">R Documentation</td></tr></table> | ||
9 | +<h2>Produce a plot of the Delaunay triangulation and Dirichlet (Voronoi) | ||
10 | +tesselation of a planar point set, as constructed by the function deldir.</h2> | ||
11 | + | ||
12 | + | ||
13 | +<h3>Description</h3> | ||
14 | + | ||
15 | +<p> | ||
16 | +This is a method for plot. | ||
17 | +</p> | ||
18 | + | ||
19 | + | ||
20 | +<h3>Usage</h3> | ||
21 | + | ||
22 | +<pre> | ||
23 | +## S3 method for class 'deldir': | ||
24 | +plot(x,add=FALSE,wlines=c('both','triang','tess'), | ||
25 | + wpoints=c('both','real','dummy','none'), | ||
26 | + number=FALSE,cex=1,nex=1,col=NULL,lty=NULL, | ||
27 | + pch=NULL,xlim=NULL,ylim=NULL,xlab='x',ylab='y',...) | ||
28 | + | ||
29 | +</pre> | ||
30 | + | ||
31 | + | ||
32 | +<h3>Arguments</h3> | ||
33 | + | ||
34 | +<table summary="R argblock"> | ||
35 | +<tr valign="top"><td><code>x</code></td> | ||
36 | +<td> | ||
37 | +An object of class "deldir" as constructed by the function deldir. | ||
38 | +</td></tr> | ||
39 | +<tr valign="top"><td><code>add</code></td> | ||
40 | +<td> | ||
41 | +logical argument; should the plot be added to an existing plot? | ||
42 | +</td></tr> | ||
43 | +<tr valign="top"><td><code>wlines</code></td> | ||
44 | +<td> | ||
45 | +"which lines?". I.e. should the Delaunay triangulation be plotted | ||
46 | +(wlines='triang'), should the Dirichlet tessellation be plotted | ||
47 | +(wlines='tess'), or should both be plotted (wlines='both', the | ||
48 | +default) ? | ||
49 | +</td></tr> | ||
50 | +<tr valign="top"><td><code>wpoints</code></td> | ||
51 | +<td> | ||
52 | +"which points?". I.e. should the real points be plotted | ||
53 | +(wpoints='real'), should the dummy points be plotted | ||
54 | +(wpoints='dummy'), should both be plotted (wpoints='both', the | ||
55 | +default) or should no points be plotted (wpoints='none')? | ||
56 | +</td></tr> | ||
57 | +<tr valign="top"><td><code>number</code></td> | ||
58 | +<td> | ||
59 | +Logical argument, defaulting to <code>FALSE</code>; if <code>TRUE</code> then the | ||
60 | +points plotted will be labelled with their index numbers | ||
61 | +(corresponding to the row numbers of the matrix "summary" in the | ||
62 | +output of deldir). | ||
63 | +</td></tr> | ||
64 | +<tr valign="top"><td><code>cex</code></td> | ||
65 | +<td> | ||
66 | +The value of the character expansion argument cex to be used | ||
67 | +with the plotting symbols for plotting the points. | ||
68 | +</td></tr> | ||
69 | +<tr valign="top"><td><code>nex</code></td> | ||
70 | +<td> | ||
71 | +The value of the character expansion argument cex to be used by the | ||
72 | +text function when numbering the points with their indices. Used only | ||
73 | +if number=<code>TRUE</code>. | ||
74 | +</td></tr> | ||
75 | +<tr valign="top"><td><code>col</code></td> | ||
76 | +<td> | ||
77 | +the colour numbers for plotting the triangulation, the tesselation, | ||
78 | +the data points, the dummy points, and the point numbers, in that | ||
79 | +order; defaults to c(1,1,1,1,1). If fewer than five numbers are | ||
80 | +given, they are recycled. (If more than five numbers are given, the | ||
81 | +redundant ones are ignored.) | ||
82 | +</td></tr> | ||
83 | +<tr valign="top"><td><code>lty</code></td> | ||
84 | +<td> | ||
85 | +the line type numbers for plotting the triangulation and the | ||
86 | +tesselation, in that order; defaults to 1:2. If only one value is | ||
87 | +given it is repeated. (If more than two numbers are given, the | ||
88 | +redundant ones are ignored.) | ||
89 | +</td></tr> | ||
90 | +<tr valign="top"><td><code>pch</code></td> | ||
91 | +<td> | ||
92 | +the plotting symbols for plotting the data points and the dummy | ||
93 | +points, in that order; may be either integer or character; defaults | ||
94 | +to 1:2. If only one value is given it is repeated. (If more than | ||
95 | +two values are given, the redundant ones are ignored.) | ||
96 | +</td></tr> | ||
97 | +<tr valign="top"><td><code>xlim</code></td> | ||
98 | +<td> | ||
99 | +the limits on the x-axis. Defaults to rw[1:2] where rw is the | ||
100 | +rectangular window specification returned by deldir(). | ||
101 | +</td></tr> | ||
102 | +<tr valign="top"><td><code>ylim</code></td> | ||
103 | +<td> | ||
104 | +the limits on the y-axis. Defaults to rw[3:4] where rw is the | ||
105 | +rectangular window specification returned by deldir(). | ||
106 | +</td></tr> | ||
107 | +<tr valign="top"><td><code>xlab</code></td> | ||
108 | +<td> | ||
109 | +label for the x-axis. Defaults to <code>x</code>. Ignored if | ||
110 | +<code>add=TRUE</code>. | ||
111 | +</td></tr> | ||
112 | +<tr valign="top"><td><code>ylab</code></td> | ||
113 | +<td> | ||
114 | +label for the y-axis. Defaults to <code>y</code>. Ignored if | ||
115 | +<code>add=TRUE</code>. | ||
116 | +</td></tr> | ||
117 | +<tr valign="top"><td><code>...</code></td> | ||
118 | +<td> | ||
119 | +Further plotting parameters to be passed to <code>plot()</code> | ||
120 | +<code>segments()</code> or <code>points()</code>. Unlikely to be used. | ||
121 | +</td></tr> | ||
122 | +</table> | ||
123 | + | ||
124 | +<h3>Details</h3> | ||
125 | + | ||
126 | +<p> | ||
127 | +The points in the set being triangulated are plotted with distinguishing | ||
128 | +symbols. By default the real points are plotted as circles (pch=1) and the | ||
129 | +dummy points are plotted as triangles (pch=2). | ||
130 | +</p> | ||
131 | + | ||
132 | + | ||
133 | +<h3>Side Effects</h3> | ||
134 | + | ||
135 | +<p> | ||
136 | +A plot of the points being triangulated is produced or added to | ||
137 | +an existing plot. As well, the edges of the Delaunay | ||
138 | +triangles and/or of the Dirichlet tiles are plotted. By default | ||
139 | +the triangles are plotted with solid lines (lty=1) and the tiles | ||
140 | +with dotted lines (lty=2). | ||
141 | +</p> | ||
142 | + | ||
143 | + | ||
144 | +<h3>Author(s)</h3> | ||
145 | + | ||
146 | +<p> | ||
147 | +Rolf Turner | ||
148 | +<a href="mailto:r.turner@auckland.ac.nz">r.turner@auckland.ac.nz</a> | ||
149 | +<a href="http://www.math.unb.ca/~rolf">http://www.math.unb.ca/~rolf</a> | ||
150 | +</p> | ||
151 | + | ||
152 | + | ||
153 | +<h3>See Also</h3> | ||
154 | + | ||
155 | +<p> | ||
156 | +<code><a href="deldir.html">deldir</a>()</code> | ||
157 | +</p> | ||
158 | + | ||
159 | + | ||
160 | +<h3>Examples</h3> | ||
161 | + | ||
162 | +<pre> | ||
163 | +## Not run: | ||
164 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
165 | +plot(try) | ||
166 | +# | ||
167 | +deldir(x,y,list(ndx=4,ndy=4),plot=TRUE,add=TRUE,wl='te', | ||
168 | + col=c(1,1,2,3,4),num=TRUE) | ||
169 | +# Plots the tesselation, but does not save the results. | ||
170 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr', | ||
171 | + wp='n') | ||
172 | +# Plots the triangulation, but not the points, and saves the returned | ||
173 | +structure. | ||
174 | +## End(Not run) | ||
175 | +</pre> | ||
176 | + | ||
177 | + | ||
178 | + | ||
179 | +<hr><div align="center">[Package <em>deldir</em> version 0.0-7 <a href="00Index.html">Index]</a></div> | ||
180 | + | ||
181 | +</body></html> |
@@ -0,0 +1,133 @@ | @@ -0,0 +1,133 @@ | ||
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | +<html><head><title>R: Plot Dirchlet/Voronoi tiles</title> | ||
3 | +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
4 | +<link rel="stylesheet" type="text/css" href="../../R.css"> | ||
5 | +</head><body> | ||
6 | + | ||
7 | +<table width="100%" summary="page for plot.tile.list {deldir}"><tr><td>plot.tile.list {deldir}</td><td align="right">R Documentation</td></tr></table> | ||
8 | +<h2>Plot Dirchlet/Voronoi tiles</h2> | ||
9 | + | ||
10 | + | ||
11 | +<h3>Description</h3> | ||
12 | + | ||
13 | +<p> | ||
14 | +A method for <code>plot</code>. Plots (sequentially) | ||
15 | +the tiles associated with each point in the set being tessellated. | ||
16 | +</p> | ||
17 | + | ||
18 | + | ||
19 | +<h3>Usage</h3> | ||
20 | + | ||
21 | +<pre> | ||
22 | +plot.tile.list(x, verbose = FALSE, close=FALSE, pch=1, polycol=NA, | ||
23 | + showpoints=TRUE, asp=1, ...) | ||
24 | +## S3 method for class 'tile.list': | ||
25 | +plot(x, verbose = FALSE, close=FALSE, pch=1, | ||
26 | + polycol=NA, showpoints=TRUE, asp=1, ...) | ||
27 | +</pre> | ||
28 | + | ||
29 | + | ||
30 | +<h3>Arguments</h3> | ||
31 | + | ||
32 | +<table summary="R argblock"> | ||
33 | +<tr valign="top"><td><code>x</code></td> | ||
34 | +<td> | ||
35 | +A list of the tiles in a tessellation, as produced | ||
36 | +the function <code><a href="tile.list.html">tile.list</a>()</code>.</td></tr> | ||
37 | +<tr valign="top"><td><code>verbose</code></td> | ||
38 | +<td> | ||
39 | +Logical scalar; if <code>TRUE</code> the tiles are | ||
40 | +plotted one at a time (with a ``Go?'' prompt after each) | ||
41 | +so that the process can be watched.</td></tr> | ||
42 | +<tr valign="top"><td><code>close</code></td> | ||
43 | +<td> | ||
44 | +Logical scalar; if <code>TRUE</code> the outer edges of | ||
45 | +of the tiles (i.e. the edges of the enclosing rectangle) | ||
46 | +are drawn. Otherwise tiles on the periphery of the | ||
47 | +tessellation are left ``open''.</td></tr> | ||
48 | +<tr valign="top"><td><code>pch</code></td> | ||
49 | +<td> | ||
50 | +The plotting character for plotting the points of the | ||
51 | +pattern which was tessellated. Ignored if <code>showpoints</code> | ||
52 | +is <code>FALSE</code>.</td></tr> | ||
53 | +<tr valign="top"><td><code>polycol</code></td> | ||
54 | +<td> | ||
55 | +Optional vector of integers (or <code>NA</code>s); | ||
56 | +the <i>i</i>-th entry indicates with which colour to fill | ||
57 | +the <i>i</i>-th tile. Note that an <code>NA</code> indicates | ||
58 | +the use of no colour at all.</td></tr> | ||
59 | +<tr valign="top"><td><code>showpoints</code></td> | ||
60 | +<td> | ||
61 | +Logical scalar; if <code>TRUE</code> the points of | ||
62 | +the pattern which was tesselated are plotted.</td></tr> | ||
63 | +<tr valign="top"><td><code>asp</code></td> | ||
64 | +<td> | ||
65 | +The aspect ratio of the plot; integer scalar or | ||
66 | +<code>NA</code>. Set this argument equal to <code>NA</code> to allow the data | ||
67 | +to determine the aspect ratio and hence to make the plot occupy the | ||
68 | +complete plotting region in both <code>x</code> and <code>y</code> directions. | ||
69 | +This is inadvisable; see the <B>Warnings</B>.</td></tr> | ||
70 | +<tr valign="top"><td><code>...</code></td> | ||
71 | +<td> | ||
72 | +Optional arguments; not used. There for consistency | ||
73 | +with the generic <code>plot</code> function.</td></tr> | ||
74 | +</table> | ||
75 | + | ||
76 | +<h3>Value</h3> | ||
77 | + | ||
78 | +<p> | ||
79 | +NULL; side effect is a plot.</p> | ||
80 | + | ||
81 | +<h3>Warnings</h3> | ||
82 | + | ||
83 | +<p> | ||
84 | +The default value for <code>verbose</code> was formerly <code>TRUE</code>; | ||
85 | +it is now <code>FALSE</code>. | ||
86 | +</p> | ||
87 | +<p> | ||
88 | +The user is <EM>strongly advised</EM> not to set the value of | ||
89 | +<code>asp</code> but rather to leave <code>asp</code> equal to its default | ||
90 | +value of <code>1</code>. Any other value distorts the tesselation | ||
91 | +and destroys the perpendicular appearance of lines which are | ||
92 | +indeed perpendicular. (And conversely can cause lines which | ||
93 | +are not perpendicular to appear as if they are.) | ||
94 | +</p> | ||
95 | +<p> | ||
96 | +The argument <code>asp</code> is present ``just because it can be''. | ||
97 | +</p> | ||
98 | + | ||
99 | + | ||
100 | +<h3>Author(s)</h3> | ||
101 | + | ||
102 | +<p> | ||
103 | +Rolf Turner | ||
104 | +<a href="mailto:r.turner@auckland.ac.nz">r.turner@auckland.ac.nz</a> | ||
105 | +<a href="http://www.math.unb.ca/~rolf">http://www.math.unb.ca/~rolf</a> | ||
106 | +</p> | ||
107 | + | ||
108 | + | ||
109 | +<h3>See Also</h3> | ||
110 | + | ||
111 | +<p> | ||
112 | +<code><a href="tile.list.html">tile.list</a>()</code> | ||
113 | +</p> | ||
114 | + | ||
115 | + | ||
116 | +<h3>Examples</h3> | ||
117 | + | ||
118 | +<pre> | ||
119 | + x <- runif(20) | ||
120 | + y <- runif(20) | ||
121 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
122 | + w <- tile.list(z) | ||
123 | + plot(w) | ||
124 | + ccc <- heat.colors(20) # Or topo.colors(20), or terrain.colors(20) | ||
125 | + # or cm.colors(20), or rainbox(20). | ||
126 | + plot(w,polycol=ccc,close=TRUE) | ||
127 | +</pre> | ||
128 | + | ||
129 | + | ||
130 | + | ||
131 | +<hr><div align="center">[Package <em>deldir</em> version 0.0-7 <a href="00Index.html">Index]</a></div> | ||
132 | + | ||
133 | +</body></html> |
@@ -0,0 +1,127 @@ | @@ -0,0 +1,127 @@ | ||
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||
2 | +<html><head><title>R: Create a list of tiles in a tessellation.</title> | ||
3 | +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
4 | +<link rel="stylesheet" type="text/css" href="../../R.css"> | ||
5 | +</head><body> | ||
6 | + | ||
7 | +<table width="100%" summary="page for tile.list {deldir}"><tr><td>tile.list {deldir}</td><td align="right">R Documentation</td></tr></table> | ||
8 | +<h2>Create a list of tiles in a tessellation.</h2> | ||
9 | + | ||
10 | + | ||
11 | +<h3>Description</h3> | ||
12 | + | ||
13 | +<p> | ||
14 | +For each point in the set being tessellated produces a list | ||
15 | +entry describing the Dirichlet/Voronoi tile containing that | ||
16 | +point. | ||
17 | +</p> | ||
18 | + | ||
19 | + | ||
20 | +<h3>Usage</h3> | ||
21 | + | ||
22 | +<pre> tile.list(object) </pre> | ||
23 | + | ||
24 | + | ||
25 | +<h3>Arguments</h3> | ||
26 | + | ||
27 | +<table summary="R argblock"> | ||
28 | +<tr valign="top"><td><code>object</code></td> | ||
29 | +<td> | ||
30 | +An object of class <code>deldir</code> as produced | ||
31 | +by the function <code><a href="deldir.html">deldir</a>()</code>.</td></tr> | ||
32 | +</table> | ||
33 | + | ||
34 | +<h3>Value</h3> | ||
35 | + | ||
36 | +<p> | ||
37 | +A list with one entry for each of the points in the set | ||
38 | +being tesselated. Each entry is in turn a list with | ||
39 | +components | ||
40 | +</p> | ||
41 | +<table summary="R argblock"> | ||
42 | +<tr valign="top"><td><code>pt</code></td> | ||
43 | +<td> | ||
44 | +The coordinates of the point whose tile is being described.</td></tr> | ||
45 | +<tr valign="top"><td><code>x</code></td> | ||
46 | +<td> | ||
47 | +The <code>x</code> coordinates of the vertices of the tile, in | ||
48 | +anticlockwise order.</td></tr> | ||
49 | +<tr valign="top"><td><code>y</code></td> | ||
50 | +<td> | ||
51 | +The <code>y</code> coordinates of the vertices of the tile, in | ||
52 | +anticlockwise order.</td></tr> | ||
53 | +<tr valign="top"><td><code>bp</code></td> | ||
54 | +<td> | ||
55 | +Vector of logicals indicating whether the tile vertex is a | ||
56 | +``real'' vertex, or a <EM>boundary point</EM>, i.e. a point where the | ||
57 | +tile edge intersects the boundary of the enclosing rectangle</td></tr> | ||
58 | +</table> | ||
59 | + | ||
60 | +<h3>Acknowledgement</h3> | ||
61 | + | ||
62 | +<p> | ||
63 | +The author expresses sincere thanks to Majid Yazdani who found and | ||
64 | +pointed out a serious bug in <code>tile.list</code> in the previous | ||
65 | +version (0.0-5) of the <code>deldir</code> package. | ||
66 | +</p> | ||
67 | + | ||
68 | + | ||
69 | +<h3>Warning</h3> | ||
70 | + | ||
71 | +<p> | ||
72 | +The set of vertices of each tile may be ``incomplete''. Only | ||
73 | +vertices which lie within the enclosing rectangle, and ``boundary | ||
74 | +points'' are listed. | ||
75 | +</p> | ||
76 | +<p> | ||
77 | +Note that the enclosing rectangle may be specified by the user | ||
78 | +in the call to <code><a href="deldir.html">deldir</a>()</code>. | ||
79 | +</p> | ||
80 | +<p> | ||
81 | +In contrast to the previous version of <code>deldir</code>, the | ||
82 | +corners of the enclosing rectangle are now include as vertices | ||
83 | +of tiles. I.e. a tile which in fact extends beyond the rectangular | ||
84 | +window and contains a corner of that window will have that | ||
85 | +corner added to its list of vertices. Thus when the corresponding | ||
86 | +polygon is plotted, the result is the intersection of the tile | ||
87 | +with the enclosing rectangular window. | ||
88 | +</p> | ||
89 | + | ||
90 | + | ||
91 | +<h3>Author(s)</h3> | ||
92 | + | ||
93 | +<p> | ||
94 | +Rolf Turner | ||
95 | +<a href="mailto:r.turner@auckland.ac.nz">r.turner@auckland.ac.nz</a> | ||
96 | +<a href="http://www.math.unb.ca/~rolf">http://www.math.unb.ca/~rolf</a> | ||
97 | +</p> | ||
98 | + | ||
99 | + | ||
100 | +<h3>See Also</h3> | ||
101 | + | ||
102 | +<p> | ||
103 | +<code><a href="deldir.html">deldir</a>()</code>, <code><a href="plot.tile.list.html">plot.tile.list</a>()</code> | ||
104 | +</p> | ||
105 | + | ||
106 | + | ||
107 | +<h3>Examples</h3> | ||
108 | + | ||
109 | +<pre> | ||
110 | + x <- runif(20) | ||
111 | + y <- runif(20) | ||
112 | + z <- deldir(x,y) | ||
113 | + w <- tile.list(z) | ||
114 | + | ||
115 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
116 | + w <- tile.list(z) | ||
117 | + | ||
118 | + z <- deldir(x,y,rw=c(0,1,0,1),dpl=list(ndx=2,ndy=2)) | ||
119 | + w <- tile.list(z) | ||
120 | + | ||
121 | +</pre> | ||
122 | + | ||
123 | + | ||
124 | + | ||
125 | +<hr><div align="center">[Package <em>deldir</em> version 0.0-7 <a href="00Index.html">Index]</a></div> | ||
126 | + | ||
127 | +</body></html> |
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +\HeaderA{deldir-internal}{Internal deldir functions}{deldir.Rdash.internal} | ||
2 | +\aliasA{acw}{deldir-internal}{acw} | ||
3 | +\aliasA{dumpts}{deldir-internal}{dumpts} | ||
4 | +\aliasA{get.cnrind}{deldir-internal}{get.cnrind} | ||
5 | +\aliasA{ind.dup}{deldir-internal}{ind.dup} | ||
6 | +\aliasA{mid.in}{deldir-internal}{mid.in} | ||
7 | +\aliasA{mnnd}{deldir-internal}{mnnd} | ||
8 | +\keyword{internal}{deldir-internal} | ||
9 | +\begin{Description}\relax | ||
10 | +Internal deldir functions. | ||
11 | +\end{Description} | ||
12 | +\begin{Usage} | ||
13 | +\begin{verbatim} | ||
14 | +dumpts(x,y,dpl,rw) | ||
15 | +ind.dup(x,y,rw=NULL,frac=0.0001) | ||
16 | +mid.in(x,y,rx,ry) | ||
17 | +mnnd(x,y) | ||
18 | +get.cnrind(x,y,rw) | ||
19 | +acw(xxx) | ||
20 | +\end{verbatim} | ||
21 | +\end{Usage} | ||
22 | +\begin{Details}\relax | ||
23 | +These functions are auxilliary and are not intended to be called by | ||
24 | +the user. | ||
25 | +\end{Details} | ||
26 | + |
@@ -0,0 +1,216 @@ | @@ -0,0 +1,216 @@ | ||
1 | +\HeaderA{deldir}{Construct the Delaunay triangulation and the Dirichlet | ||
2 | +(Voronoi) tessellation of a planar point set.}{deldir} | ||
3 | +\keyword{spatial}{deldir} | ||
4 | +\begin{Description}\relax | ||
5 | +This function computes the Delaunay triangulation (and hence the | ||
6 | +Dirichlet tesselation) of a planar point set according to the second | ||
7 | +(iterative) algorithm of Lee and Schacter --- see REFERENCES. The | ||
8 | +triangulation is made to be with respect to the whole plane by | ||
9 | +\code{suspending} it from so-called ideal points (-Inf,-Inf), (Inf,-Inf) | ||
10 | +(Inf,Inf), and (-Inf,Inf). The triangulation is also enclosed in a | ||
11 | +finite rectangular window. A set of dummy points may | ||
12 | +be added, in various ways, to the set of data points being triangulated. | ||
13 | +\end{Description} | ||
14 | +\begin{Usage} | ||
15 | +\begin{verbatim} | ||
16 | +deldir(x, y, dpl=NULL, rw=NULL, eps=1e-09, frac=0.0001, | ||
17 | + sort=TRUE, plotit=FALSE, digits=6, ...) | ||
18 | +\end{verbatim} | ||
19 | +\end{Usage} | ||
20 | +\begin{Arguments} | ||
21 | +\begin{ldescription} | ||
22 | +\item[\code{x,y}] The coordinates of the point set being triangulated. These can be | ||
23 | +given by two arguments x and y which are vectors or by a single | ||
24 | +argument x which is a list with components "x" and "y". | ||
25 | + | ||
26 | +\item[\code{dpl}] A list describing the structure of the dummy points to be added | ||
27 | +to the data being triangulated. The addition of these dummy points | ||
28 | +is effected by the auxilliary function dumpts(). The list may have | ||
29 | +components: | ||
30 | + | ||
31 | + | ||
32 | +ndx: The x-dimension of a rectangular grid; if either ndx or ndy is null, | ||
33 | +no grid is constructed. | ||
34 | + | ||
35 | + | ||
36 | +ndy: The y-dimension of the aforementioned rectangular grid. | ||
37 | + | ||
38 | + | ||
39 | +nrad: The number of radii or "spokes", emanating from each data point, | ||
40 | +along which dummy points are to be added. | ||
41 | + | ||
42 | + | ||
43 | +nper: The number of dummy points per spoke. | ||
44 | + | ||
45 | + | ||
46 | +fctr: A factor determining the length of each spoke; each spoke is of | ||
47 | +length equal to fctr times the mean nearest neighbour distance of the data. | ||
48 | +(This distance is calculated by the auxilliary function mnnd().) | ||
49 | + | ||
50 | + | ||
51 | +x: A vector of x-coordinates of "ad hoc" dummy points | ||
52 | + | ||
53 | + | ||
54 | +y: A vector of the corresponding y-coordinates of "ad hoc" dummy points | ||
55 | + | ||
56 | + | ||
57 | + | ||
58 | +\item[\code{rw}] The coordinates of the corners of the rectangular window enclosing | ||
59 | +the triangulation, in the order (xmin, xmax, ymin, ymax). Any data | ||
60 | +points (including dummy points) outside this window are discarded. | ||
61 | +If this argument is omitted, it defaults to values given by the range | ||
62 | +of the data, plus and minus 10 percent. | ||
63 | + | ||
64 | +\item[\code{eps}] A value of epsilon used in testing whether a quantity is zero, mainly | ||
65 | +in the context of whether points are collinear. If anomalous errors | ||
66 | +arise, it is possible that these may averted by adjusting the value | ||
67 | +of eps upward or downward. | ||
68 | + | ||
69 | +\item[\code{frac}] A value specifying the tolerance used in eliminating duplicate | ||
70 | +points; defaults to 0.0001. Points are considered duplicates if | ||
71 | +abs(x1-x2) < frac*(xmax-xmin) AND abs(y1-y2) < frac*(ymax-ymin). | ||
72 | + | ||
73 | +\item[\code{sort}] Logical argument; if \code{TRUE} (the default) the data (including dummy | ||
74 | +points) are sorted into a sequence of "bins" prior to triangulation; | ||
75 | +this makes the algorithm slightly more efficient. Normally one would | ||
76 | +set sort equal to \code{FALSE} only if one wished to observe some of the | ||
77 | +fine detail of the way in which adding a point to a data set affected | ||
78 | +the triangulation, and therefore wished to make sure that the point | ||
79 | +in question was added last. Essentially this argument would get used | ||
80 | +only in a de-bugging process. | ||
81 | + | ||
82 | +\item[\code{plotit}] Logical argument; if \code{TRUE} a plot of the triangulation and tessellation | ||
83 | +is produced; the default is \code{FALSE}. | ||
84 | + | ||
85 | +\item[\code{digits}] The number of decimal places to which all numeric values in the | ||
86 | +returned list should be rounded. Defaults to 6. | ||
87 | + | ||
88 | +\item[\code{...}] Auxilliary arguments add, wlines, wpoints, number, nex, col, lty, | ||
89 | +pch, xlim, and ylim (and possibly other plotting parameters) may be | ||
90 | +passed to plot.deldir through "\dots" if plotit=\code{TRUE}. | ||
91 | + | ||
92 | +\end{ldescription} | ||
93 | +\end{Arguments} | ||
94 | +\begin{Details}\relax | ||
95 | +This package is a (straightforward) adaptation of the Splus library | ||
96 | +section ``delaunay'' to R. That library section is an implementation | ||
97 | +of the Lee-Schacter algorithm, which was originally written as a | ||
98 | +stand-alone Fortran program in 1987/88 by Rolf Turner, while with the | ||
99 | +Division of Mathematics and Statistics, CSIRO, Sydney, Australia. It | ||
100 | +was re-written as an Splus function (using dynamically loaded Fortran | ||
101 | +code), by Rolf Turner while visiting the University of Western | ||
102 | +Australia, May, 1995. | ||
103 | + | ||
104 | +Further revisions made December 1996. The author gratefully | ||
105 | +acknowledges the contributions, assistance, and guidance of Mark | ||
106 | +Berman, of D.M.S., CSIRO, in collaboration with whom this project was | ||
107 | +originally undertaken. The author also acknowledges much useful | ||
108 | +advice from Adrian Baddeley, formerly of D.M.S., CSIRO (now Professor | ||
109 | +of Statistics at the University of Western Australia). Daryl Tingley | ||
110 | +of the Department of Mathematics and Statistics, University of New | ||
111 | +Brunswick provided some helpful insight. Special thanks are extended | ||
112 | +to Alan Johnson, of the Alaska Fisheries Science Centre, who supplied | ||
113 | +two data sets which were extremely valuable in tracking down some | ||
114 | +errors in the code. | ||
115 | + | ||
116 | +Don MacQueen, of Lawrence Livermore National Lab, wrote an Splus | ||
117 | +driver function for the old stand-alone version of this software. | ||
118 | +That driver, which was available on Statlib, is now deprecated in | ||
119 | +favour of the current package ``delaunay'' package. Don also | ||
120 | +collaborated in the preparation of that package. | ||
121 | + | ||
122 | +Further revisions and bug-fixes were made in 1998, 1999, and 2002. | ||
123 | +\end{Details} | ||
124 | +\begin{Value} | ||
125 | +A list (of class \code{deldir}), invisible if plotit=\code{TRUE}, with components: | ||
126 | + | ||
127 | +\begin{ldescription} | ||
128 | +\item[\code{delsgs}] a matrix with 6 columns. The first 4 entries of each row are the | ||
129 | +coordinates of the points joined by an edge of a Delaunay | ||
130 | +triangle, in the order (x1,y1,x2,y2). The last two entries are the | ||
131 | +indices of the two points which are joined. | ||
132 | + | ||
133 | +\item[\code{dirsgs}] a data frame with 8 columns. The first 4 entries of each row are the | ||
134 | +coordinates of the endpoints of one the edges of a Dirichlet tile, in | ||
135 | +the order (x1,y1,x2,y2). The fifth and sixth entries are the indices | ||
136 | +of the two points, in the set being triangulated, which are separated | ||
137 | +by that edge. The seventh and eighth entries are logical values. The | ||
138 | +seventh indicates whether the first endpoint of the corresponding | ||
139 | +edge of a Dirichlet tile is a boundary point (a point on the boundary | ||
140 | +of the rectangular window). Likewise for the eighth entry and the | ||
141 | +second endpoint of the edge. | ||
142 | + | ||
143 | +\item[\code{summary}] a matrix with 9 columns, and (n.data + n.dum) rows (see below). | ||
144 | +These rows correspond to the points in the set being triangulated. | ||
145 | +The columns are named "x" (the x-coordinate of the point), "y" (the | ||
146 | +y-coordinate), "n.tri" (the number of Delaunay triangles emanating | ||
147 | +from the point), "del.area" (1/3 of the total area of all the | ||
148 | +Delaunay triangles emanating from the point), "del.wts" (the | ||
149 | +corresponding entry of the "del.area" column divided by the sum of | ||
150 | +this column), "n.tside" (the number of sides --- within the | ||
151 | +rectangular window --- of the Dirichlet tile surrounding the point), | ||
152 | +"nbpt" (the number of points in which the Dirichlet tile intersects | ||
153 | +the boundary of the rectangular window), "dir.area" (the area of the | ||
154 | +Dirichlet tile surrounding the point), and "dir.wts" (the | ||
155 | +corresponding entry of the "dir.area" column divided by the sum of | ||
156 | +this column). Note that the factor of 1/3 associated with the | ||
157 | +del.area column arises because each triangle occurs three times --- | ||
158 | +once for each corner. | ||
159 | + | ||
160 | +\item[\code{n.data}] the number of real (as opposed to dummy) points in the set which was | ||
161 | +triangulated, with any duplicate points eliminated. The first n.data | ||
162 | +rows of "summary" correspond to real points. | ||
163 | + | ||
164 | +\item[\code{n.dum}] the number of dummy points which were added to the set being triangulated, | ||
165 | +with any duplicate points (including any which duplicate real points) | ||
166 | +eliminated. The last n.dum rows of "summary" correspond to dummy | ||
167 | +points. | ||
168 | + | ||
169 | +\item[\code{del.area}] the area of the convex hull of the set of points being triangulated, | ||
170 | +as formed by summing the "del.area" column of "summary". | ||
171 | + | ||
172 | +\item[\code{dir.area}] the area of the rectangular window enclosing the points being triangulated, | ||
173 | +as formed by summing the "dir.area" column of "summary". | ||
174 | + | ||
175 | +\item[\code{rw}] the specification of the corners of the rectangular window enclosing | ||
176 | +the data, in the order (xmin, xmax, ymin, ymax). | ||
177 | + | ||
178 | +\end{ldescription} | ||
179 | +\end{Value} | ||
180 | +\begin{Section}{Side Effects} | ||
181 | +If plotit==\code{TRUE} a plot of the triangulation and/or tessellation is produced | ||
182 | +or added to an existing plot. | ||
183 | +\end{Section} | ||
184 | +\begin{Note}\relax | ||
185 | +If ndx >= 2 and ndy >= 2, then the rectangular window IS the convex | ||
186 | +hull, and so the values of del.area and dir.area are identical. | ||
187 | +\end{Note} | ||
188 | +\begin{Author}\relax | ||
189 | +Rolf Turner | ||
190 | +\email{r.turner@auckland.ac.nz} | ||
191 | +\url{http://www.math.unb.ca/~rolf} | ||
192 | +\end{Author} | ||
193 | +\begin{References}\relax | ||
194 | +Lee, D. T., and Schacter, B. J. "Two algorithms for constructing a | ||
195 | +Delaunay triangulation", Int. J. Computer and Information | ||
196 | +Sciences, Vol. 9, No. 3, 1980, pp. 219 -- 242. | ||
197 | + | ||
198 | +Ahuja, N. and Schacter, B. J. (1983). Pattern Models. New York: Wiley. | ||
199 | +\end{References} | ||
200 | +\begin{SeeAlso}\relax | ||
201 | +plot.deldir | ||
202 | +\end{SeeAlso} | ||
203 | +\begin{Examples} | ||
204 | +\begin{ExampleCode} | ||
205 | +x <- c(2.3,3.0,7.0,1.0,3.0,8.0) | ||
206 | +y <- c(2.3,3.0,2.0,5.0,8.0,9.0) | ||
207 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
208 | +# Puts dummy points at the corners of the rectangular | ||
209 | +# window, i.e. at (0,0), (10,0), (10,10), and (0,10) | ||
210 | +## Not run: | ||
211 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr') | ||
212 | +## End(Not run) | ||
213 | +# Plots the triangulation which was created (but not the tesselation). | ||
214 | +\end{ExampleCode} | ||
215 | +\end{Examples} | ||
216 | + |
@@ -0,0 +1,113 @@ | @@ -0,0 +1,113 @@ | ||
1 | +\HeaderA{plot.deldir}{Produce a plot of the Delaunay triangulation and Dirichlet (Voronoi) | ||
2 | +tesselation of a planar point set, as constructed by the function deldir.}{plot.deldir} | ||
3 | +\begin{Description}\relax | ||
4 | +This is a method for plot. | ||
5 | +\end{Description} | ||
6 | +\begin{Usage} | ||
7 | +\begin{verbatim} | ||
8 | +## S3 method for class 'deldir': | ||
9 | +plot(x,add=FALSE,wlines=c('both','triang','tess'), | ||
10 | + wpoints=c('both','real','dummy','none'), | ||
11 | + number=FALSE,cex=1,nex=1,col=NULL,lty=NULL, | ||
12 | + pch=NULL,xlim=NULL,ylim=NULL,xlab='x',ylab='y',...) | ||
13 | + | ||
14 | +\end{verbatim} | ||
15 | +\end{Usage} | ||
16 | +\begin{Arguments} | ||
17 | +\begin{ldescription} | ||
18 | +\item[\code{x}] An object of class "deldir" as constructed by the function deldir. | ||
19 | + | ||
20 | +\item[\code{add}] logical argument; should the plot be added to an existing plot? | ||
21 | + | ||
22 | +\item[\code{wlines}] "which lines?". I.e. should the Delaunay triangulation be plotted | ||
23 | +(wlines='triang'), should the Dirichlet tessellation be plotted | ||
24 | +(wlines='tess'), or should both be plotted (wlines='both', the | ||
25 | +default) ? | ||
26 | + | ||
27 | +\item[\code{wpoints}] "which points?". I.e. should the real points be plotted | ||
28 | +(wpoints='real'), should the dummy points be plotted | ||
29 | +(wpoints='dummy'), should both be plotted (wpoints='both', the | ||
30 | +default) or should no points be plotted (wpoints='none')? | ||
31 | + | ||
32 | +\item[\code{number}] Logical argument, defaulting to \code{FALSE}; if \code{TRUE} then the | ||
33 | +points plotted will be labelled with their index numbers | ||
34 | +(corresponding to the row numbers of the matrix "summary" in the | ||
35 | +output of deldir). | ||
36 | + | ||
37 | +\item[\code{cex}] The value of the character expansion argument cex to be used | ||
38 | +with the plotting symbols for plotting the points. | ||
39 | + | ||
40 | +\item[\code{nex}] The value of the character expansion argument cex to be used by the | ||
41 | +text function when numbering the points with their indices. Used only | ||
42 | +if number=\code{TRUE}. | ||
43 | + | ||
44 | +\item[\code{col}] the colour numbers for plotting the triangulation, the tesselation, | ||
45 | +the data points, the dummy points, and the point numbers, in that | ||
46 | +order; defaults to c(1,1,1,1,1). If fewer than five numbers are | ||
47 | +given, they are recycled. (If more than five numbers are given, the | ||
48 | +redundant ones are ignored.) | ||
49 | + | ||
50 | +\item[\code{lty}] the line type numbers for plotting the triangulation and the | ||
51 | +tesselation, in that order; defaults to 1:2. If only one value is | ||
52 | +given it is repeated. (If more than two numbers are given, the | ||
53 | +redundant ones are ignored.) | ||
54 | + | ||
55 | +\item[\code{pch}] the plotting symbols for plotting the data points and the dummy | ||
56 | +points, in that order; may be either integer or character; defaults | ||
57 | +to 1:2. If only one value is given it is repeated. (If more than | ||
58 | +two values are given, the redundant ones are ignored.) | ||
59 | + | ||
60 | +\item[\code{xlim}] the limits on the x-axis. Defaults to rw[1:2] where rw is the | ||
61 | +rectangular window specification returned by deldir(). | ||
62 | + | ||
63 | +\item[\code{ylim}] the limits on the y-axis. Defaults to rw[3:4] where rw is the | ||
64 | +rectangular window specification returned by deldir(). | ||
65 | + | ||
66 | +\item[\code{xlab}] label for the x-axis. Defaults to \code{x}. Ignored if | ||
67 | +\code{add=TRUE}. | ||
68 | + | ||
69 | +\item[\code{ylab}] label for the y-axis. Defaults to \code{y}. Ignored if | ||
70 | +\code{add=TRUE}. | ||
71 | + | ||
72 | +\item[\code{...}] Further plotting parameters to be passed to \code{plot()} | ||
73 | +\code{segments()} or \code{points()}. Unlikely to be used. | ||
74 | + | ||
75 | +\end{ldescription} | ||
76 | +\end{Arguments} | ||
77 | +\begin{Details}\relax | ||
78 | +The points in the set being triangulated are plotted with distinguishing | ||
79 | +symbols. By default the real points are plotted as circles (pch=1) and the | ||
80 | +dummy points are plotted as triangles (pch=2). | ||
81 | +\end{Details} | ||
82 | +\begin{Section}{Side Effects} | ||
83 | +A plot of the points being triangulated is produced or added to | ||
84 | +an existing plot. As well, the edges of the Delaunay | ||
85 | +triangles and/or of the Dirichlet tiles are plotted. By default | ||
86 | +the triangles are plotted with solid lines (lty=1) and the tiles | ||
87 | +with dotted lines (lty=2). | ||
88 | +\end{Section} | ||
89 | +\begin{Author}\relax | ||
90 | +Rolf Turner | ||
91 | +\email{r.turner@auckland.ac.nz} | ||
92 | +\url{http://www.math.unb.ca/~rolf} | ||
93 | +\end{Author} | ||
94 | +\begin{SeeAlso}\relax | ||
95 | +\code{\LinkA{deldir}{deldir}()} | ||
96 | +\end{SeeAlso} | ||
97 | +\begin{Examples} | ||
98 | +\begin{ExampleCode} | ||
99 | +## Not run: | ||
100 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10)) | ||
101 | +plot(try) | ||
102 | +# | ||
103 | +deldir(x,y,list(ndx=4,ndy=4),plot=TRUE,add=TRUE,wl='te', | ||
104 | + col=c(1,1,2,3,4),num=TRUE) | ||
105 | +# Plots the tesselation, but does not save the results. | ||
106 | +try <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10),plot=TRUE,wl='tr', | ||
107 | + wp='n') | ||
108 | +# Plots the triangulation, but not the points, and saves the returned | ||
109 | +structure. | ||
110 | +## End(Not run) | ||
111 | +\end{ExampleCode} | ||
112 | +\end{Examples} | ||
113 | + |
@@ -0,0 +1,81 @@ | @@ -0,0 +1,81 @@ | ||
1 | +\HeaderA{plot.tile.list}{Plot Dirchlet/Voronoi tiles}{plot.tile.list} | ||
2 | +\keyword{hplot}{plot.tile.list} | ||
3 | +\begin{Description}\relax | ||
4 | +A method for \code{plot}. Plots (sequentially) | ||
5 | +the tiles associated with each point in the set being tessellated. | ||
6 | +\end{Description} | ||
7 | +\begin{Usage} | ||
8 | +\begin{verbatim} | ||
9 | +plot.tile.list(x, verbose = FALSE, close=FALSE, pch=1, polycol=NA, | ||
10 | + showpoints=TRUE, asp=1, ...) | ||
11 | +## S3 method for class 'tile.list': | ||
12 | +plot(x, verbose = FALSE, close=FALSE, pch=1, | ||
13 | + polycol=NA, showpoints=TRUE, asp=1, ...) | ||
14 | +\end{verbatim} | ||
15 | +\end{Usage} | ||
16 | +\begin{Arguments} | ||
17 | +\begin{ldescription} | ||
18 | +\item[\code{x}] A list of the tiles in a tessellation, as produced | ||
19 | +the function \code{\LinkA{tile.list}{tile.list}()}. | ||
20 | +\item[\code{verbose}] Logical scalar; if \code{TRUE} the tiles are | ||
21 | +plotted one at a time (with a ``Go?'' prompt after each) | ||
22 | +so that the process can be watched. | ||
23 | +\item[\code{close}] Logical scalar; if \code{TRUE} the outer edges of | ||
24 | +of the tiles (i.e. the edges of the enclosing rectangle) | ||
25 | +are drawn. Otherwise tiles on the periphery of the | ||
26 | +tessellation are left ``open''. | ||
27 | +\item[\code{pch}] The plotting character for plotting the points of the | ||
28 | +pattern which was tessellated. Ignored if \code{showpoints} | ||
29 | +is \code{FALSE}. | ||
30 | +\item[\code{polycol}] Optional vector of integers (or \code{NA}s); | ||
31 | +the \eqn{i}{}-th entry indicates with which colour to fill | ||
32 | +the \eqn{i}{}-th tile. Note that an \code{NA} indicates | ||
33 | +the use of no colour at all. | ||
34 | +\item[\code{showpoints}] Logical scalar; if \code{TRUE} the points of | ||
35 | +the pattern which was tesselated are plotted. | ||
36 | +\item[\code{asp}] The aspect ratio of the plot; integer scalar or | ||
37 | +\code{NA}. Set this argument equal to \code{NA} to allow the data | ||
38 | +to determine the aspect ratio and hence to make the plot occupy the | ||
39 | +complete plotting region in both \code{x} and \code{y} directions. | ||
40 | +This is inadvisable; see the \bold{Warnings}. | ||
41 | +\item[\code{...}] Optional arguments; not used. There for consistency | ||
42 | +with the generic \code{plot} function. | ||
43 | +\end{ldescription} | ||
44 | +\end{Arguments} | ||
45 | +\begin{Value} | ||
46 | +NULL; side effect is a plot. | ||
47 | +\end{Value} | ||
48 | +\begin{Section}{Warnings} | ||
49 | +The default value for \code{verbose} was formerly \code{TRUE}; | ||
50 | +it is now \code{FALSE}. | ||
51 | + | ||
52 | +The user is \emph{strongly advised} not to set the value of | ||
53 | +\code{asp} but rather to leave \code{asp} equal to its default | ||
54 | +value of \code{1}. Any other value distorts the tesselation | ||
55 | +and destroys the perpendicular appearance of lines which are | ||
56 | +indeed perpendicular. (And conversely can cause lines which | ||
57 | +are not perpendicular to appear as if they are.) | ||
58 | + | ||
59 | +The argument \code{asp} is present ``just because it can be''. | ||
60 | +\end{Section} | ||
61 | +\begin{Author}\relax | ||
62 | +Rolf Turner | ||
63 | +\email{r.turner@auckland.ac.nz} | ||
64 | +\url{http://www.math.unb.ca/~rolf} | ||
65 | +\end{Author} | ||
66 | +\begin{SeeAlso}\relax | ||
67 | +\code{\LinkA{tile.list}{tile.list}()} | ||
68 | +\end{SeeAlso} | ||
69 | +\begin{Examples} | ||
70 | +\begin{ExampleCode} | ||
71 | + x <- runif(20) | ||
72 | + y <- runif(20) | ||
73 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
74 | + w <- tile.list(z) | ||
75 | + plot(w) | ||
76 | + ccc <- heat.colors(20) # Or topo.colors(20), or terrain.colors(20) | ||
77 | + # or cm.colors(20), or rainbox(20). | ||
78 | + plot(w,polycol=ccc,close=TRUE) | ||
79 | +\end{ExampleCode} | ||
80 | +\end{Examples} | ||
81 | + |
@@ -0,0 +1,77 @@ | @@ -0,0 +1,77 @@ | ||
1 | +\HeaderA{tile.list}{Create a list of tiles in a tessellation.}{tile.list} | ||
2 | +\keyword{spatial}{tile.list} | ||
3 | +\begin{Description}\relax | ||
4 | +For each point in the set being tessellated produces a list | ||
5 | +entry describing the Dirichlet/Voronoi tile containing that | ||
6 | +point. | ||
7 | +\end{Description} | ||
8 | +\begin{Usage} | ||
9 | +\begin{verbatim} tile.list(object) \end{verbatim} | ||
10 | +\end{Usage} | ||
11 | +\begin{Arguments} | ||
12 | +\begin{ldescription} | ||
13 | +\item[\code{object}] An object of class \code{deldir} as produced | ||
14 | +by the function \code{\LinkA{deldir}{deldir}()}. | ||
15 | +\end{ldescription} | ||
16 | +\end{Arguments} | ||
17 | +\begin{Value} | ||
18 | +A list with one entry for each of the points in the set | ||
19 | +being tesselated. Each entry is in turn a list with | ||
20 | +components | ||
21 | + | ||
22 | +\begin{ldescription} | ||
23 | +\item[\code{pt}] The coordinates of the point whose tile is being described. | ||
24 | +\item[\code{x}] The \code{x} coordinates of the vertices of the tile, in | ||
25 | +anticlockwise order. | ||
26 | +\item[\code{y}] The \code{y} coordinates of the vertices of the tile, in | ||
27 | +anticlockwise order. | ||
28 | +\item[\code{bp}] Vector of logicals indicating whether the tile vertex is a | ||
29 | +``real'' vertex, or a \emph{boundary point}, i.e. a point where the | ||
30 | +tile edge intersects the boundary of the enclosing rectangle | ||
31 | +\end{ldescription} | ||
32 | +\end{Value} | ||
33 | +\begin{Section}{Acknowledgement} | ||
34 | +The author expresses sincere thanks to Majid Yazdani who found and | ||
35 | +pointed out a serious bug in \code{tile.list} in the previous | ||
36 | +version (0.0-5) of the \code{deldir} package. | ||
37 | +\end{Section} | ||
38 | +\begin{Section}{Warning} | ||
39 | +The set of vertices of each tile may be ``incomplete''. Only | ||
40 | +vertices which lie within the enclosing rectangle, and ``boundary | ||
41 | +points'' are listed. | ||
42 | + | ||
43 | +Note that the enclosing rectangle may be specified by the user | ||
44 | +in the call to \code{\LinkA{deldir}{deldir}()}. | ||
45 | + | ||
46 | +In contrast to the previous version of \code{deldir}, the | ||
47 | +corners of the enclosing rectangle are now include as vertices | ||
48 | +of tiles. I.e. a tile which in fact extends beyond the rectangular | ||
49 | +window and contains a corner of that window will have that | ||
50 | +corner added to its list of vertices. Thus when the corresponding | ||
51 | +polygon is plotted, the result is the intersection of the tile | ||
52 | +with the enclosing rectangular window. | ||
53 | +\end{Section} | ||
54 | +\begin{Author}\relax | ||
55 | +Rolf Turner | ||
56 | +\email{r.turner@auckland.ac.nz} | ||
57 | +\url{http://www.math.unb.ca/~rolf} | ||
58 | +\end{Author} | ||
59 | +\begin{SeeAlso}\relax | ||
60 | +\code{\LinkA{deldir}{deldir}()}, \code{\LinkA{plot.tile.list}{plot.tile.list}()} | ||
61 | +\end{SeeAlso} | ||
62 | +\begin{Examples} | ||
63 | +\begin{ExampleCode} | ||
64 | + x <- runif(20) | ||
65 | + y <- runif(20) | ||
66 | + z <- deldir(x,y) | ||
67 | + w <- tile.list(z) | ||
68 | + | ||
69 | + z <- deldir(x,y,rw=c(0,1,0,1)) | ||
70 | + w <- tile.list(z) | ||
71 | + | ||
72 | + z <- deldir(x,y,rw=c(0,1,0,1),dpl=list(ndx=2,ndy=2)) | ||
73 | + w <- tile.list(z) | ||
74 | + | ||
75 | +\end{ExampleCode} | ||
76 | +\end{Examples} | ||
77 | + |
No preview for this file type
No preview for this file type
@@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
1 | +subroutine acchk(i,j,k,anticl,x,y,ntot,eps) | ||
2 | +# Check whether vertices i, j, k, are in anti-clockwise order. | ||
3 | +# Called by locn, qtest, qtest1. | ||
4 | + | ||
5 | +implicit double precision(a-h,o-z) | ||
6 | +dimension x(-3:ntot), y(-3:ntot), xt(3), yt(3) | ||
7 | +logical anticl | ||
8 | + | ||
9 | +# Create indicator telling which of i, j, and k are ideal points. | ||
10 | +if(i<=0) i1 = 1 | ||
11 | +else i1 = 0 | ||
12 | +if(j<=0) j1 = 1 | ||
13 | +else j1 = 0 | ||
14 | +if(k<=0) k1 = 1 | ||
15 | +else k1 = 0 | ||
16 | +ijk = i1*4+j1*2+k1 | ||
17 | + | ||
18 | +# Get the coordinates of vertices i, j, and k. (Pseudo-coordinates for | ||
19 | +# any ideal points.) | ||
20 | +xt(1) = x(i) | ||
21 | +yt(1) = y(i) | ||
22 | +xt(2) = x(j) | ||
23 | +yt(2) = y(j) | ||
24 | +xt(3) = x(k) | ||
25 | +yt(3) = y(k) | ||
26 | + | ||
27 | +# Get the ``normalized'' cross product. | ||
28 | +call cross(xt,yt,ijk,cprd) | ||
29 | + | ||
30 | +# If cprd is positive then (ij-cross-ik) is directed ***upwards*** | ||
31 | +# and so i, j, k, are in anti-clockwise order; else not. | ||
32 | +if(cprd > eps) anticl = .true. | ||
33 | +else anticl = .false. | ||
34 | +return | ||
35 | +end |
@@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
1 | +subroutine addpt(j,nadj,madj,x,y,ntot,eps,nerror) | ||
2 | +# Add point j to the triangulation. | ||
3 | +# Called by master, dirseg. | ||
4 | + | ||
5 | +implicit double precision(a-h,o-z) | ||
6 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
7 | +logical didswp | ||
8 | + | ||
9 | +# Put the new point in, joined to the vertices of its | ||
10 | +# enclosing triangle. | ||
11 | +call initad(j,nadj,madj,x,y,ntot,eps,nerror) | ||
12 | +if(nerror > 0) return | ||
13 | + | ||
14 | +# Look at each `gap', i.e. pair of adjacent segments | ||
15 | +# emanating from the new point; they form two sides of a | ||
16 | +# quadrilateral; see whether the extant diagonal of this | ||
17 | +# quadrilateral should be swapped with its alternate | ||
18 | +# (according to the LOP: local optimality principle). | ||
19 | +now = nadj(j,1) | ||
20 | +nxt = nadj(j,2) | ||
21 | +ngap = 0 | ||
22 | +repeat { | ||
23 | + call swap(j,now,nxt,didswp,nadj,madj,x,y,ntot,eps,nerror) | ||
24 | + if(nerror > 0) return | ||
25 | + n = nadj(j,0) | ||
26 | + if(!didswp) { # If no swap of diagonals | ||
27 | + now = nxt # move to the next gap. | ||
28 | + ngap = ngap+1 | ||
29 | + } | ||
30 | + call succ(nxt,j,now,nadj,madj,ntot,nerror) | ||
31 | + if(nerror > 0) return | ||
32 | +} | ||
33 | +until(ngap==n) | ||
34 | + | ||
35 | +return | ||
36 | +end |
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +subroutine adjchk(i,j,adj,nadj,madj,ntot,nerror) | ||
2 | +# Check if vertices i and j are adjacent. | ||
3 | +# Called by insrt, delet, trifnd, swap, delseg, dirseg. | ||
4 | + | ||
5 | +dimension nadj(-3:ntot,0:madj) | ||
6 | +logical adj | ||
7 | + | ||
8 | +nerror = -1 | ||
9 | +# Check if j is in the adjacency list of i. | ||
10 | +adj = .false. | ||
11 | +ni = nadj(i,0) | ||
12 | +if(ni>0) { | ||
13 | + do k = 1,ni { | ||
14 | + if(j==nadj(i,k)) { | ||
15 | + adj = .true. | ||
16 | + break | ||
17 | + } | ||
18 | + } | ||
19 | +} | ||
20 | + | ||
21 | +# Check if i is in the adjacency list of j. | ||
22 | +nj = nadj(j,0) | ||
23 | +if(nj>0) { | ||
24 | + do k = 1,nj { | ||
25 | + if(i==nadj(j,k)) { | ||
26 | + if(adj) return # Have j in i's list and i in j's. | ||
27 | + else { | ||
28 | + nerror = 1 | ||
29 | + return | ||
30 | + } | ||
31 | + } | ||
32 | + } | ||
33 | +} | ||
34 | + | ||
35 | +# If we get to here i is not in j's list. | ||
36 | +if(adj) { # If adj is true, then j IS in i's list. | ||
37 | + nerror = 1 | ||
38 | + return | ||
39 | +} | ||
40 | + | ||
41 | +return | ||
42 | +end |
@@ -0,0 +1,81 @@ | @@ -0,0 +1,81 @@ | ||
1 | +subroutine binsrt(x,y,ntot,rw,npd,ind,tx,ty,ilst,nerror) | ||
2 | +# Sort the data points into bins. | ||
3 | +# Called by master. | ||
4 | + | ||
5 | +implicit double precision(a-h,o-z) | ||
6 | +dimension x(-3:ntot), y(-3:ntot), tx(npd), ty(npd) | ||
7 | +dimension ind(npd), ilst(npd) | ||
8 | +dimension rw(4) | ||
9 | + | ||
10 | +nerror = -1 | ||
11 | +kdiv = 1+dble(npd)**0.25 # Round high. | ||
12 | +xkdiv = dble(kdiv) | ||
13 | + | ||
14 | +# Dig out the corners of the rectangular window. | ||
15 | +xmin = rw(1) | ||
16 | +xmax = rw(2) | ||
17 | +ymin = rw(3) | ||
18 | +ymax = rw(4) | ||
19 | + | ||
20 | +w = xmax-xmin | ||
21 | +h = ymax-ymin | ||
22 | + | ||
23 | +# Number of bins is to be approx. sqrt(npd); thus number of subdivisions | ||
24 | +# on each side of rectangle is approx. npd**(1/4). | ||
25 | +dw = w/xkdiv | ||
26 | +dh = h/xkdiv | ||
27 | + | ||
28 | +# The width of each bin is dw; the height is dh. We shall move across | ||
29 | +# the rectangle from left to right, then up, then back from right to | ||
30 | +# left, then up, .... Note that kx counts the divisions from the left, | ||
31 | +# ky counts the divisions from the bottom; kx is incremented by ink, which | ||
32 | +# is +/- 1 and switches sign when ky is incremented; ky is always | ||
33 | +# incremented by 1. | ||
34 | +kx = 1 | ||
35 | +ky = 1 | ||
36 | +ink = 1 | ||
37 | +k = 0 | ||
38 | +do i = 1,npd { ilst(i) = 0 } # Keeps a list of those points already added | ||
39 | +while(ky<=kdiv) { # to the new list. | ||
40 | + do i = 1,npd { | ||
41 | + if(ilst(i)==1) next # The i-th point has already been added | ||
42 | + # to the new list. | ||
43 | + # If the i-th point is in the current bin, add it to the list. | ||
44 | + xt = x(i) | ||
45 | + yt = y(i) | ||
46 | + ix = 1+(xt-xmin)/dw | ||
47 | + if(ix>kdiv) ix = kdiv | ||
48 | + jy = 1+(yt-ymin)/dh | ||
49 | + if(jy>kdiv) jy = kdiv | ||
50 | + if(ix==kx&jy==ky) { | ||
51 | + k = k+1 | ||
52 | + ind(i) = k # Index i is the pos'n. of (x,y) in the | ||
53 | + tx(k) = xt # old list; k is its pos'n. in the new one. | ||
54 | + ty(k) = yt | ||
55 | + ilst(i) = 1 # Cross the i-th point off the old list. | ||
56 | + } | ||
57 | + } | ||
58 | + # Move to the next bin. | ||
59 | + kc = kx+ink | ||
60 | + if((1<=kc)&(kc<=kdiv)) kx = kc | ||
61 | + else { | ||
62 | + ky = ky+1 | ||
63 | + ink = -ink | ||
64 | + } | ||
65 | +} | ||
66 | + | ||
67 | +# Check that all points from old list have been added to the new, | ||
68 | +# with no spurious additions. | ||
69 | +if(k!=npd) { | ||
70 | + nerror = 2 | ||
71 | + return | ||
72 | +} | ||
73 | + | ||
74 | +# Copy the new sorted vector back on top of the old ones. | ||
75 | +do i = 1,npd { | ||
76 | + x(i) = tx(i) | ||
77 | + y(i) = ty(i) | ||
78 | +} | ||
79 | + | ||
80 | +return | ||
81 | +end |
@@ -0,0 +1,62 @@ | @@ -0,0 +1,62 @@ | ||
1 | +subroutine circen(i,j,k,x0,y0,x,y,ntot,eps,collin,nerror) | ||
2 | +# Find the circumcentre (x0,y0) of the triangle with | ||
3 | +# vertices (x(i),y(i)), (x(j),y(j)), (x(k),y(k)). | ||
4 | +# Called by qtest1, dirseg, dirout. | ||
5 | + | ||
6 | +implicit double precision(a-h,o-z) | ||
7 | +dimension x(-3:ntot), y(-3:ntot), xt(3), yt(3) | ||
8 | +logical collin | ||
9 | + | ||
10 | +nerror = -1 | ||
11 | + | ||
12 | +# Get the coordinates. | ||
13 | +xt(1) = x(i) | ||
14 | +yt(1) = y(i) | ||
15 | +xt(2) = x(j) | ||
16 | +yt(2) = y(j) | ||
17 | +xt(3) = x(k) | ||
18 | +yt(3) = y(k) | ||
19 | + | ||
20 | +# Check for collinearity | ||
21 | +ijk = 0 | ||
22 | +call cross(xt,yt,ijk,cprd) | ||
23 | +if(abs(cprd) < eps) collin = .true. | ||
24 | +else collin = .false. | ||
25 | + | ||
26 | +# Form the vector u from i to j, and the vector v from i to k, | ||
27 | +# and normalize them. | ||
28 | +a = x(j) - x(i) | ||
29 | +b = y(j) - y(i) | ||
30 | +c = x(k) - x(i) | ||
31 | +d = y(k) - y(i) | ||
32 | +c1 = sqrt(a*a+b*b) | ||
33 | +c2 = sqrt(c*c+d*d) | ||
34 | +a = a/c1 | ||
35 | +b = b/c1 | ||
36 | +c = c/c2 | ||
37 | +d = d/c2 | ||
38 | + | ||
39 | +# If the points are collinear, make sure that they're in the right | ||
40 | +# order --- i between j and k. | ||
41 | +if(collin) { | ||
42 | + alpha = a*c+b*d | ||
43 | + # If they're not in the right order, bring things to | ||
44 | + # a shuddering halt. | ||
45 | + if(alpha>0) { | ||
46 | + nerror = 3 | ||
47 | + return | ||
48 | + } | ||
49 | + # Collinear, but in the right order; think of this as meaning | ||
50 | + # that the circumcircle in question has infinite radius. | ||
51 | + return | ||
52 | +} | ||
53 | + | ||
54 | +# Not collinear; go ahead, make my circumcentre. (First, form | ||
55 | +# the cross product of the ***unit*** vectors, instead of the | ||
56 | +# ``normalized'' cross product produced by ``cross''.) | ||
57 | +crss = a*d - b*c | ||
58 | +x0 = x(i) + 0.5*(c1*d - c2*b)/crss | ||
59 | +y0 = y(i) + 0.5*(c2*a - c1*c)/crss | ||
60 | + | ||
61 | +return | ||
62 | +end |
@@ -0,0 +1,81 @@ | @@ -0,0 +1,81 @@ | ||
1 | +subroutine cross(x,y,ijk,cprd) | ||
2 | +implicit double precision(a-h,o-z) | ||
3 | +dimension x(3), y(3) | ||
4 | +# Calculates a ``normalized'' cross product of the vectors joining | ||
5 | +# [x(1),y(1)] to [x(2),y(2)] and [x(3),y(3)] respectively. | ||
6 | +# The normalization consists in dividing by the square of the | ||
7 | +# shortest of the three sides of the triangle. This normalization is | ||
8 | +# for the purposes of testing for collinearity; if the result is less | ||
9 | +# than epsilon, the smallest of the sines of the angles is less than | ||
10 | +# epsilon. | ||
11 | + | ||
12 | +# Set constants | ||
13 | +zero = 0.d0 | ||
14 | +one = 1.d0 | ||
15 | +two = 2.d0 | ||
16 | +four = 4.d0 | ||
17 | + | ||
18 | +# Adjust the coordinates depending upon which points are ideal, | ||
19 | +# and calculate the squared length of the shortest side. | ||
20 | +switch(ijk) { | ||
21 | + case 0: # No ideal points; no adjustment necessary. | ||
22 | + smin = -one | ||
23 | + do i = 1,3 { | ||
24 | + ip = i+1 | ||
25 | + if(ip==4) ip = 1 | ||
26 | + a = x(ip) - x(i) | ||
27 | + b = y(ip) - y(i) | ||
28 | + s = a*a+b*b | ||
29 | + if(smin < zero | s < smin) smin = s | ||
30 | + } | ||
31 | + case 1: # Only k ideal. | ||
32 | + x(2) = x(2) - x(1) | ||
33 | + y(2) = y(2) - y(1) | ||
34 | + x(1) = zero | ||
35 | + y(1) = zero | ||
36 | + cn = sqrt(x(2)**2+y(2)**2) | ||
37 | + x(2) = x(2)/cn | ||
38 | + y(2) = y(2)/cn | ||
39 | + smin = one | ||
40 | + case 2: # Only j ideal. | ||
41 | + x(3) = x(3) - x(1) | ||
42 | + y(3) = y(3) - y(1) | ||
43 | + x(1) = zero | ||
44 | + y(1) = zero | ||
45 | + cn = sqrt(x(3)**2+y(3)**2) | ||
46 | + x(3) = x(3)/cn | ||
47 | + y(3) = y(3)/cn | ||
48 | + smin = one | ||
49 | + case 3: # Both j and k ideal (i not). | ||
50 | + x(1) = zero | ||
51 | + y(1) = zero | ||
52 | + smin = 2 | ||
53 | + case 4: # Only i ideal. | ||
54 | + x(3) = x(3) - x(2) | ||
55 | + y(3) = y(3) - y(2) | ||
56 | + x(2) = zero | ||
57 | + y(2) = zero | ||
58 | + cn = sqrt(x(3)**2+y(3)**2) | ||
59 | + x(3) = x(3)/cn | ||
60 | + y(3) = y(3)/cn | ||
61 | + smin = one | ||
62 | + case 5: # Both i and k ideal (j not). | ||
63 | + x(2) = zero | ||
64 | + y(2) = zero | ||
65 | + smin = two | ||
66 | + case 6: # Both i and j ideal (k not). | ||
67 | + x(3) = zero | ||
68 | + y(3) = zero | ||
69 | + smin = two | ||
70 | + case 7: # All three points ideal; no adjustment necessary. | ||
71 | + smin = four | ||
72 | +} | ||
73 | + | ||
74 | +a = x(2)-x(1) | ||
75 | +b = y(2)-y(1) | ||
76 | +c = x(3)-x(1) | ||
77 | +d = y(3)-y(1) | ||
78 | + | ||
79 | +cprd = (a*d - b*c)/smin | ||
80 | +return | ||
81 | +end |
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +subroutine delet(i,j,nadj,madj,ntot,nerror) | ||
2 | +# Delete i and j from each other's adjacency lists. | ||
3 | +# Called by initad, swap. | ||
4 | + | ||
5 | +implicit double precision(a-h,o-z) | ||
6 | +dimension nadj(-3:ntot,0:madj) | ||
7 | +logical adj | ||
8 | + | ||
9 | +# First check that they're IN each other's lists. | ||
10 | +call adjchk(i,j,adj,nadj,madj,ntot,nerror) | ||
11 | +if(nerror > 0) return | ||
12 | + | ||
13 | +# Then do the actual deletion if they are. | ||
14 | +if(adj) { | ||
15 | + call delet1(i,j,nadj,madj,ntot) | ||
16 | + call delet1(j,i,nadj,madj,ntot) | ||
17 | +} | ||
18 | + | ||
19 | +return | ||
20 | +end |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +subroutine delet1(i,j,nadj,madj,ntot) | ||
2 | +# Delete j from the adjacency list of i. | ||
3 | +# Called by delet. | ||
4 | + | ||
5 | +implicit double precision(a-h,o-z) | ||
6 | +dimension nadj(-3:ntot,0:madj) | ||
7 | + | ||
8 | +n = nadj(i,0) | ||
9 | +do k = 1,n { | ||
10 | + if(nadj(i,k)==j) { # Find j in the list; | ||
11 | + # then move everything back one notch. | ||
12 | + do kk = k,n-1 { nadj(i,kk) = nadj(i,kk+1) } | ||
13 | + nadj(i,n) = 0 | ||
14 | + nadj(i,0) = n-1 | ||
15 | + return | ||
16 | + } | ||
17 | +} | ||
18 | + | ||
19 | +end |
@@ -0,0 +1,55 @@ | @@ -0,0 +1,55 @@ | ||
1 | +subroutine delout(delsum,nadj,madj,x,y,ntot,npd,ind,nerror) | ||
2 | + | ||
3 | +# Put a summary of the Delaunay triangles with a vertex at point i, | ||
4 | +# for i = 1, ..., npd, into the array delsum. Do this in the original | ||
5 | +# order of the points, not the order into which they have been | ||
6 | +# bin-sorted. | ||
7 | +# Called by master. | ||
8 | + | ||
9 | +implicit double precision(a-h,o-z) | ||
10 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
11 | +dimension delsum(npd,4), ind(npd) | ||
12 | + | ||
13 | +do i1 = 1,npd { | ||
14 | + area = 0. # Initialize area of polygon consisting of triangles | ||
15 | + # with a vertex at point i. | ||
16 | + | ||
17 | + # Get the point number, its coordinates and the number of | ||
18 | + # (real) triangles emanating from it. | ||
19 | + i = ind(i1) | ||
20 | + np = nadj(i,0) | ||
21 | + xi = x(i) | ||
22 | + yi = y(i) | ||
23 | + npt = np | ||
24 | + do k = 1,np { | ||
25 | + kp = k+1 | ||
26 | + if(kp>np) kp = 1 | ||
27 | + if(nadj(i,k)<=0|nadj(i,kp)<=0) npt = npt-1 | ||
28 | + } | ||
29 | + | ||
30 | + # For each point in the adjacency list of point i, find its | ||
31 | + # successor, and the area of the triangle determined by these | ||
32 | + # three points. | ||
33 | + do j1 = 1,np { | ||
34 | + j = nadj(i,j1) | ||
35 | + if(j<=0) next | ||
36 | + xj = x(j) | ||
37 | + yj = y(j) | ||
38 | + call succ(k,i,j,nadj,madj,ntot,nerror) | ||
39 | + if(nerror > 0) return | ||
40 | + if(k<=0) next | ||
41 | + xk = x(k) | ||
42 | + yk = y(k) | ||
43 | + call triar(xi,yi,xj,yj,xk,yk,tmp) | ||
44 | + # Downweight the area by 1/3, since each | ||
45 | + # triangle eventually appears 3 times over. | ||
46 | + area = area+tmp/3. | ||
47 | + } | ||
48 | + delsum(i1,1) = xi | ||
49 | + delsum(i1,2) = yi | ||
50 | + delsum(i1,3) = npt | ||
51 | + delsum(i1,4) = area | ||
52 | +} | ||
53 | + | ||
54 | +return | ||
55 | +end |
@@ -0,0 +1,40 @@ | @@ -0,0 +1,40 @@ | ||
1 | +subroutine delseg(delsgs,ndel,nadj,madj,x,y,ntot,ind,nerror) | ||
2 | + | ||
3 | +# Output the endpoints of the line segments joining the | ||
4 | +# vertices of the Delaunay triangles. | ||
5 | +# Called by master. | ||
6 | + | ||
7 | +implicit double precision(a-h,o-z) | ||
8 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
9 | +dimension delsgs(6,1), ind(1) | ||
10 | +logical value | ||
11 | + | ||
12 | +# For each distinct pair of points i and j, if they are adjacent | ||
13 | +# then put their endpoints into the output array. | ||
14 | +npd = ntot-4 | ||
15 | +kseg = 0 | ||
16 | +do i1 = 2,npd { | ||
17 | + i = ind(i1) | ||
18 | + do j1 = 1,i1-1 { | ||
19 | + j = ind(j1) | ||
20 | + call adjchk(i,j,value,nadj,madj,ntot,nerror) | ||
21 | + if(nerror>0) return | ||
22 | + if(value) { | ||
23 | + kseg = kseg+1 | ||
24 | + if(kseg > ndel) { | ||
25 | + nerror = 14 | ||
26 | + return | ||
27 | + } | ||
28 | + delsgs(1,kseg) = x(i) | ||
29 | + delsgs(2,kseg) = y(i) | ||
30 | + delsgs(3,kseg) = x(j) | ||
31 | + delsgs(4,kseg) = y(j) | ||
32 | + delsgs(5,kseg) = i1 | ||
33 | + delsgs(6,kseg) = j1 | ||
34 | + } | ||
35 | + } | ||
36 | +} | ||
37 | +ndel = kseg | ||
38 | + | ||
39 | +return | ||
40 | +end |
@@ -0,0 +1,110 @@ | @@ -0,0 +1,110 @@ | ||
1 | +subroutine dirout(dirsum,nadj,madj,x,y,ntot,npd,rw,ind,eps,nerror) | ||
2 | + | ||
3 | +# Output the description of the Dirichlet tile centred at point | ||
4 | +# i for i = 1, ..., npd. Do this in the original order of the | ||
5 | +# points, not in the order into which they have been bin-sorted. | ||
6 | +# Called by master. | ||
7 | + | ||
8 | +implicit double precision(a-h,o-z) | ||
9 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
10 | +dimension dirsum(npd,3), ind(npd), rw(4) | ||
11 | +logical collin, intfnd, bptab, bptcd | ||
12 | + | ||
13 | +# Note that at this point some Delaunay neighbors may be | ||
14 | +# `spurious'; they are the corners of a `large' rectangle in which | ||
15 | +# the rectangular window of interest has been suspended. This | ||
16 | +# large window was brought in simply to facilitate output concerning | ||
17 | +# the Dirichlet tesselation. They were added to the triangulation | ||
18 | +# in the routine `dirseg' which ***must*** therefore be called before | ||
19 | +# this routine (`dirout') is called. (Likewise `dirseg' must be called | ||
20 | +# ***after*** `delseg' and `delout' have been called.) | ||
21 | + | ||
22 | +# Dig out the corners of the rectangular window. | ||
23 | +xmin = rw(1) | ||
24 | +xmax = rw(2) | ||
25 | +ymin = rw(3) | ||
26 | +ymax = rw(4) | ||
27 | + | ||
28 | +do i1 = 1,npd { | ||
29 | + area = 0. # Initialize the area of the ith tile to zero. | ||
30 | + nbpt = 0 # Initialize the number of boundary points of | ||
31 | + # the ith tile to zero. | ||
32 | + npt = 0 # Initialize the number of tile boundaries to zero. | ||
33 | + | ||
34 | + i = ind(i1) | ||
35 | + np = nadj(i,0) | ||
36 | + xi = x(i) | ||
37 | + yi = y(i) | ||
38 | + | ||
39 | + # Output the point number, its coordinates, and the number of | ||
40 | + # its Delaunay neighbors == the number of boundary segments in | ||
41 | + # its Dirichlet tile. | ||
42 | + | ||
43 | + # For each Delaunay neighbor, find the circumcentres of the | ||
44 | + # triangles on each side of the segment joining point i to that | ||
45 | + # neighbor. | ||
46 | + do j1 = 1,np { | ||
47 | + j = nadj(i,j1) | ||
48 | + xj = x(j) | ||
49 | + yj = y(j) | ||
50 | + xij = 0.5*(xi+xj) | ||
51 | + yij = 0.5*(yi+yj) | ||
52 | + call pred(k,i,j,nadj,madj,ntot,nerror) | ||
53 | + if(nerror > 0) return | ||
54 | + call succ(l,i,j,nadj,madj,ntot,nerror) | ||
55 | + if(nerror > 0) return | ||
56 | + call circen(i,k,j,a,b,x,y,ntot,eps,collin,nerror) | ||
57 | + if(nerror>0) return | ||
58 | + if(collin) { | ||
59 | + nerror = 13 | ||
60 | + return | ||
61 | + } | ||
62 | + call circen(i,j,l,c,d,x,y,ntot,eps,collin,nerror) | ||
63 | + if(nerror>0) return | ||
64 | + if(collin) { | ||
65 | + nerror = 13 | ||
66 | + return | ||
67 | + } | ||
68 | + | ||
69 | + # Increment the area of the current Dirichlet | ||
70 | + # tile (intersected with the rectangular window) by applying | ||
71 | + # Stokes' Theorem to the segment of tile boundary joining | ||
72 | + # (a,b) to (c,d). (Note that the direction is anti-clockwise.) | ||
73 | + call stoke(a,b,c,d,rw,tmp,sn,eps,nerror) | ||
74 | + if(nerror > 0) return | ||
75 | + area = area+sn*tmp | ||
76 | + | ||
77 | + # If a circumcentre is outside the rectangular window, replace | ||
78 | + # it with the intersection of the rectangle boundary with the | ||
79 | + # line joining the circumcentre to the midpoint of | ||
80 | + # (xi,yi)->(xj,yj). Then output the number of the current | ||
81 | + # Delaunay neighbor and the two circumcentres (or the points | ||
82 | + # with which they have been replaced). | ||
83 | + call dldins(a,b,xij,yij,ai,bi,rw,intfnd,bptab) | ||
84 | + if(intfnd) { | ||
85 | + call dldins(c,d,xij,yij,ci,di,rw,intfnd,bptcd) | ||
86 | + if(!intfnd) { | ||
87 | + nerror = 17 | ||
88 | + return | ||
89 | + } | ||
90 | + if(bptab & bptcd) { | ||
91 | + xm = 0.5*(ai+ci) | ||
92 | + ym = 0.5*(bi+di) | ||
93 | + if(xmin<xm&xm<xmax&ymin<ym&ym<ymax) { | ||
94 | + nbpt = nbpt+2 | ||
95 | + npt = npt+1 | ||
96 | + } | ||
97 | + } | ||
98 | + else { | ||
99 | + npt = npt + 1 | ||
100 | + if(bptab | bptcd) nbpt = nbpt+1 | ||
101 | + } | ||
102 | + } | ||
103 | + dirsum(i1,1) = npt | ||
104 | + dirsum(i1,2) = nbpt | ||
105 | + dirsum(i1,3) = area | ||
106 | + } | ||
107 | +} | ||
108 | + | ||
109 | +return | ||
110 | +end |
@@ -0,0 +1,139 @@ | @@ -0,0 +1,139 @@ | ||
1 | +subroutine dirseg(dirsgs,ndir,nadj,madj,x,y,ntot,rw,eps,ind,nerror) | ||
2 | + | ||
3 | +# Output the endpoints of the segments of boundary of Dirichlet | ||
4 | +# tiles. (Do it economically; each such segment once and only once.) | ||
5 | +# Called by master. | ||
6 | + | ||
7 | +implicit double precision(a-h,o-z) | ||
8 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
9 | +dimension dirsgs(8,ndir), rw(4), ind(1) | ||
10 | +logical collin, adjace, intfnd, bptab, bptcd, goferit | ||
11 | + | ||
12 | +nerror = -1 | ||
13 | + | ||
14 | +# Add in some dummy corner points, outside the actual window. | ||
15 | +# Far enough out so that no resulting tile boundaries intersect the | ||
16 | +# window. | ||
17 | + | ||
18 | +# Note that these dummy corners are needed by the routine `dirout' | ||
19 | +# but will screw things up for `delseg' and `delout'. Therefore | ||
20 | +# this routine (`dirseg') must be called ***before*** dirout, and | ||
21 | +# ***after*** delseg and delout. | ||
22 | + | ||
23 | +# Dig out the corners of the rectangular window. | ||
24 | +xmin = rw(1) | ||
25 | +xmax = rw(2) | ||
26 | +ymin = rw(3) | ||
27 | +ymax = rw(4) | ||
28 | + | ||
29 | +a = xmax-xmin | ||
30 | +b = ymax-ymin | ||
31 | +c = sqrt(a*a+b*b) | ||
32 | + | ||
33 | +npd = ntot-4 | ||
34 | +nstt = npd+1 | ||
35 | +i = nstt | ||
36 | +x(i) = xmin-c | ||
37 | +y(i) = ymin-c | ||
38 | +i = i+1 | ||
39 | +x(i) = xmax+c | ||
40 | +y(i) = ymin-c | ||
41 | +i = i+1 | ||
42 | +x(i) = xmax+c | ||
43 | +y(i) = ymax+c | ||
44 | +i = i+1 | ||
45 | +x(i) = xmin-c | ||
46 | +y(i) = ymax+c | ||
47 | + | ||
48 | +do j = nstt,ntot { | ||
49 | + call addpt(j,nadj,madj,x,y,ntot,eps,nerror) | ||
50 | + if(nerror > 0) return | ||
51 | +} | ||
52 | + | ||
53 | +# Put the segments into the array dirsgs. | ||
54 | + | ||
55 | +# For each distinct pair of (genuine) data points, find out if they are | ||
56 | +# adjacent. If so, find the circumcentres of the triangles lying on each | ||
57 | +# side of the segment joining them. | ||
58 | +kseg = 0 | ||
59 | +do i1 = 2,npd { | ||
60 | + i = ind(i1) | ||
61 | + do j1 = 1,i1-1 { | ||
62 | + j = ind(j1) | ||
63 | + call adjchk(i,j,adjace,nadj,madj,ntot,nerror) | ||
64 | + if(nerror > 0) return | ||
65 | + if(adjace) { | ||
66 | + xi = x(i) | ||
67 | + yi = y(i) | ||
68 | + xj = x(j) | ||
69 | + yj = y(j) | ||
70 | + # Let (xij,yij) be the midpoint of the segment joining | ||
71 | + # (xi,yi) to (xj,yj). | ||
72 | + xij = 0.5*(xi+xj) | ||
73 | + yij = 0.5*(yi+yj) | ||
74 | + call pred(k,i,j,nadj,madj,ntot,nerror) | ||
75 | + if(nerror > 0) return | ||
76 | + call circen(i,k,j,a,b,x,y,ntot,eps,collin,nerror) | ||
77 | + if(nerror > 0) return | ||
78 | + if(collin) { | ||
79 | + nerror = 12 | ||
80 | + return | ||
81 | + } | ||
82 | + | ||
83 | + # If a circumcentre is outside the rectangular window | ||
84 | + # of interest, draw a line joining it to the mid-point | ||
85 | + # of (xi,yi)->(xj,yj). Find the intersection of this | ||
86 | + # line with the boundary of the window; for (a,b), | ||
87 | + # call the point of intersection (ai,bi). For (c,d), | ||
88 | + # call it (ci,di). | ||
89 | + call dldins(a,b,xij,yij,ai,bi,rw,intfnd,bptab) | ||
90 | + if(!intfnd) { | ||
91 | + nerror = 16 | ||
92 | + return | ||
93 | + } | ||
94 | + call succ(l,i,j,nadj,madj,ntot,nerror) | ||
95 | + if(nerror > 0) return | ||
96 | + call circen(i,j,l,c,d,x,y,ntot,eps,collin,nerror) | ||
97 | + if(nerror > 0) return | ||
98 | + if(collin) { | ||
99 | + nerror = 12 | ||
100 | + return | ||
101 | + } | ||
102 | + call dldins(c,d,xij,yij,ci,di,rw,intfnd,bptcd) | ||
103 | + if(!intfnd) { | ||
104 | + nerror = 16 | ||
105 | + return | ||
106 | + } | ||
107 | + goferit = .false. | ||
108 | + if(bptab & bptcd) { | ||
109 | + xm = 0.5*(ai+ci) | ||
110 | + ym = 0.5*(bi+di) | ||
111 | + if(xmin<xm&xm<xmax&ymin<ym&ym<ymax) { | ||
112 | + goferit = .true. | ||
113 | + } | ||
114 | + } | ||
115 | + if((!bptab)|(!bptcd)) goferit = .true. | ||
116 | + if(goferit) { | ||
117 | + kseg = kseg + 1 | ||
118 | + if(kseg > ndir) { | ||
119 | + nerror = 15 | ||
120 | + return | ||
121 | + } | ||
122 | + dirsgs(1,kseg) = ai | ||
123 | + dirsgs(2,kseg) = bi | ||
124 | + dirsgs(3,kseg) = ci | ||
125 | + dirsgs(4,kseg) = di | ||
126 | + dirsgs(5,kseg) = i1 | ||
127 | + dirsgs(6,kseg) = j1 | ||
128 | + if(bptab) dirsgs(7,kseg) = 1.d0 | ||
129 | + else dirsgs(7,kseg) = 0.d0 | ||
130 | + if(bptcd) dirsgs(8,kseg) = 1.d0 | ||
131 | + else dirsgs(8,kseg) = 0.d0 | ||
132 | + } | ||
133 | + } | ||
134 | + } | ||
135 | +} | ||
136 | +ndir = kseg | ||
137 | + | ||
138 | +return | ||
139 | +end |
@@ -0,0 +1,87 @@ | @@ -0,0 +1,87 @@ | ||
1 | +subroutine dldins(a,b,c,d,ai,bi,rw,intfnd,bpt) | ||
2 | + | ||
3 | +# Get a point ***inside*** the rectangular window on the ray from | ||
4 | +# one circumcentre to the next one. I.e. if the `next one' is | ||
5 | +# inside, then that's it; else find the intersection of this ray with | ||
6 | +# the boundary of the rectangle. | ||
7 | +# Called by dirseg, dirout. | ||
8 | + | ||
9 | +implicit double precision(a-h,o-z) | ||
10 | +dimension rw(4) | ||
11 | +logical intfnd, bpt | ||
12 | + | ||
13 | +# Note that (a,b) is the circumcenter of a Delaunay triangle, | ||
14 | +# and that (c,d) is the midpoint of one of its sides. | ||
15 | +# When `dldins' is called by `dirout' it is possible for (c,d) to | ||
16 | +# lie ***outside*** the rectangular window, and for the ray not to | ||
17 | +# intersect the window at all. (The point (c,d) might be the midpoint | ||
18 | +# of a Delaunay edge connected to a `fake outer corner', added to facilitate | ||
19 | +# constructing a tiling that completely covers the actual window.) | ||
20 | +# The variable `intfnd' acts as an indicator as to whether such an | ||
21 | +# intersection has been found. | ||
22 | + | ||
23 | +# The variable `bpt' acts as an indicator as to whether the returned | ||
24 | +# point (ai,bi) is a true circumcentre, inside the window (bpt == .false.), | ||
25 | +# or is the intersection of a ray with the boundary of the window | ||
26 | +# (bpt = .true.). | ||
27 | + | ||
28 | + | ||
29 | +intfnd = .true. | ||
30 | +bpt = .true. | ||
31 | + | ||
32 | +# Dig out the corners of the rectangular window. | ||
33 | +xmin = rw(1) | ||
34 | +xmax = rw(2) | ||
35 | +ymin = rw(3) | ||
36 | +ymax = rw(4) | ||
37 | + | ||
38 | +# Check if (a,b) is inside the rectangle. | ||
39 | +if(xmin<=a&a<=xmax&ymin<=b&b<=ymax) { | ||
40 | + ai = a | ||
41 | + bi = b | ||
42 | + bpt = .false. | ||
43 | + return | ||
44 | +} | ||
45 | + | ||
46 | +# Look for appropriate intersections with the four lines forming | ||
47 | +# the sides of the rectangular window. | ||
48 | + | ||
49 | +# Line 1: x = xmin. | ||
50 | +if(a<xmin) { | ||
51 | + ai = xmin | ||
52 | + s = (d-b)/(c-a) | ||
53 | + t = b-s*a | ||
54 | + bi = s*ai+t | ||
55 | + if(ymin<=bi&bi<=ymax) return | ||
56 | +} | ||
57 | + | ||
58 | +# Line 2: y = ymin. | ||
59 | +if(b<ymin) { | ||
60 | + bi = ymin | ||
61 | + s = (c-a)/(d-b) | ||
62 | + t = a-s*b | ||
63 | + ai = s*bi+t | ||
64 | + if(xmin<=ai&ai<=xmax) return | ||
65 | +} | ||
66 | + | ||
67 | +# Line 3: x = xmax. | ||
68 | +if(a>xmax) { | ||
69 | + ai = xmax | ||
70 | + s = (d-b)/(c-a) | ||
71 | + t = b-s*a | ||
72 | + bi = s*ai+t | ||
73 | + if(ymin<=bi&bi<=ymax) return | ||
74 | +} | ||
75 | + | ||
76 | +# Line 4: y = ymax. | ||
77 | +if(b>ymax) { | ||
78 | + bi = ymax | ||
79 | + s = (c-a)/(d-b) | ||
80 | + t = a-s*b | ||
81 | + ai = s*bi+t | ||
82 | + if(xmin<=ai&ai<=xmax) return | ||
83 | +} | ||
84 | + | ||
85 | +intfnd = .false. | ||
86 | +return | ||
87 | +end |
@@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
1 | +subroutine inddup(x,y,n,rw,frac,dup) | ||
2 | +implicit double precision(a-h,o-z) | ||
3 | +logical dup(n) | ||
4 | +dimension x(n), y(n), rw(4) | ||
5 | + | ||
6 | +xtol = frac*(rw(2)-rw(1)) | ||
7 | +ytol = frac*(rw(4)-rw(3)) | ||
8 | + | ||
9 | +dup(1) = .false. | ||
10 | +do i = 2,n { | ||
11 | + dup(i) = .false. | ||
12 | + do j = 1,i-1 { | ||
13 | + dx = abs(x(i)-x(j)) | ||
14 | + dy = abs(y(i)-y(j)) | ||
15 | + if(dx < xtol & dy < ytol) { | ||
16 | + dup(i) = .true. | ||
17 | + break | ||
18 | + } | ||
19 | + } | ||
20 | +} | ||
21 | + | ||
22 | +return | ||
23 | +end |
@@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
1 | +subroutine initad(j,nadj,madj,x,y,ntot,eps,nerror) | ||
2 | + | ||
3 | +# Intial adding-in of a new point j. | ||
4 | +# Called by addpt. | ||
5 | + | ||
6 | +implicit double precision(a-h,o-z) | ||
7 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
8 | +integer tau(3) | ||
9 | + | ||
10 | +# Find the triangle containing vertex j. | ||
11 | +call trifnd(j,tau,nedge,nadj,madj,x,y,ntot,eps,nerror) | ||
12 | +if(nerror > 0) return | ||
13 | + | ||
14 | +# If the new point is on the edge of a triangle, detach the two | ||
15 | +# vertices of that edge from each other. Also join j to the vertex | ||
16 | +# of the triangle on the reverse side of that edge from the `found' | ||
17 | +# triangle (defined by tau) -- given that there ***is*** such a triangle. | ||
18 | +if(nedge!=0) { | ||
19 | + ip = nedge | ||
20 | + i = ip-1 | ||
21 | + if(i==0) i = 3 # Arithmetic modulo 3. | ||
22 | + call pred(k,tau(i),tau(ip),nadj,madj,ntot,nerror) | ||
23 | + if(nerror > 0) return | ||
24 | + call succ(kk,tau(ip),tau(i),nadj,madj,ntot,nerror) | ||
25 | + if(nerror > 0) return | ||
26 | + call delet(tau(i),tau(ip),nadj,madj,ntot,nerror) | ||
27 | + if(nerror > 0) return | ||
28 | + if(k==kk) call insrt(j,k,nadj,madj,x,y,ntot,nerror,eps) | ||
29 | + if(nerror > 0) return | ||
30 | +} | ||
31 | + | ||
32 | +# Join the new point to each of the three vertices. | ||
33 | +do i = 1,3 { | ||
34 | + call insrt(j,tau(i),nadj,madj,x,y,ntot,nerror,eps) | ||
35 | + if(nerror > 0) return | ||
36 | +} | ||
37 | + | ||
38 | +return | ||
39 | +end |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +subroutine insrt(i,j,nadj,madj,x,y,ntot,nerror,eps) | ||
2 | +# Insert i and j into each other's adjacency list. | ||
3 | +# Called by master, initad, swap. | ||
4 | + | ||
5 | +implicit double precision(a-h,o-z) | ||
6 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
7 | +logical adj | ||
8 | + | ||
9 | +# Check whether i and j are in each other's adjacency lists. | ||
10 | +call adjchk(i,j,adj,nadj,madj,ntot,nerror) | ||
11 | +if(nerror > 0) return | ||
12 | +if(adj) return | ||
13 | + | ||
14 | +# If not, find where in each list they should respectively be. | ||
15 | +call locn(i,j,kj,nadj,madj,x,y,ntot,eps) | ||
16 | +call locn(j,i,ki,nadj,madj,x,y,ntot,eps) | ||
17 | + | ||
18 | +# Put them in each other's lists in the appropriate position. | ||
19 | +call insrt1(i,j,kj,nadj,madj,ntot,nerror) | ||
20 | +if(nerror >0) return | ||
21 | +call insrt1(j,i,ki,nadj,madj,ntot,nerror) | ||
22 | +if(nerror >0) return | ||
23 | + | ||
24 | +return | ||
25 | +end |
@@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
1 | +subroutine insrt1(i,j,kj,nadj,madj,ntot,nerror) | ||
2 | + | ||
3 | +# Insert j into the adjacency list of i. | ||
4 | +# Called by insrt. | ||
5 | + | ||
6 | +implicit double precision(a-h,o-z) | ||
7 | +dimension nadj(-3:ntot,0:madj) | ||
8 | + | ||
9 | +nerror = -1 | ||
10 | + | ||
11 | +# Variable kj is the index which j ***will*** | ||
12 | +# have when it is inserted into the adjacency list of i in | ||
13 | +# the appropriate position. | ||
14 | + | ||
15 | +# If the adjacency list of i had no points just stick j into the list. | ||
16 | +n = nadj(i,0) | ||
17 | +if(n==0) { | ||
18 | + nadj(i,0) = 1 | ||
19 | + nadj(i,1) = j | ||
20 | + return | ||
21 | +} | ||
22 | + | ||
23 | +# If the adjacency list had some points, move everything ahead of the | ||
24 | +# kj-th place one place forward, and put j in position kj. | ||
25 | +kk = n+1 | ||
26 | + | ||
27 | +if(kk>madj) { # Watch out for over-writing!!! | ||
28 | + nerror = 4 | ||
29 | + return | ||
30 | +} | ||
31 | +while(kk>kj) { | ||
32 | + nadj(i,kk) = nadj(i,kk-1) | ||
33 | + kk = kk-1 | ||
34 | +} | ||
35 | +nadj(i,kj) = j | ||
36 | +nadj(i,0) = n+1 | ||
37 | + | ||
38 | +return | ||
39 | +end |
@@ -0,0 +1,50 @@ | @@ -0,0 +1,50 @@ | ||
1 | +subroutine locn(i,j,kj,nadj,madj,x,y,ntot,eps) | ||
2 | + | ||
3 | +# Find the appropriate location for j in the adjacency list | ||
4 | +# of i. This is the index which j ***will*** have when | ||
5 | +# it is inserted into the adjacency list of i in the | ||
6 | +# appropriate place. | ||
7 | +# Called by insrt. | ||
8 | + | ||
9 | +implicit double precision(a-h,o-z) | ||
10 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
11 | +logical before | ||
12 | + | ||
13 | +n = nadj(i,0) | ||
14 | + | ||
15 | +# If there is nothing already adjacent to i, then j will have place 1. | ||
16 | +if(n==0) { | ||
17 | + kj = 1 | ||
18 | + return | ||
19 | +} | ||
20 | + | ||
21 | +# Run through i's list, checking if j should come before each element | ||
22 | +# of that list. (I.e. if i, j, and k are in anti-clockwise order.) | ||
23 | +# If j comes before the kj-th item, but not before the (kj-1)-st, then | ||
24 | +# j should have place kj. | ||
25 | +do ks = 1,n { | ||
26 | + kj = ks | ||
27 | + k = nadj(i,kj) | ||
28 | + call acchk(i,j,k,before,x,y,ntot,eps) | ||
29 | + if(before) { | ||
30 | + km = kj-1 | ||
31 | + if(km==0) km = n | ||
32 | + k = nadj(i,km) | ||
33 | + call acchk(i,j,k,before,x,y,ntot,eps) | ||
34 | + if(before) next | ||
35 | + # If j is before 1 and after n, then it should | ||
36 | + # have place n+1. | ||
37 | + if(kj==1) kj = n+1 | ||
38 | + return | ||
39 | + } | ||
40 | +} | ||
41 | + | ||
42 | +# We've gone right through the list and haven't been before | ||
43 | +# the kj-th item ***and*** after the (kj-1)-st on any occasion. | ||
44 | +# Therefore j is before everything (==> place 1) or after | ||
45 | +# everything (==> place n+1). | ||
46 | +if(before) kj = 1 | ||
47 | +else kj = n+1 | ||
48 | + | ||
49 | +return | ||
50 | +end |
@@ -0,0 +1,84 @@ | @@ -0,0 +1,84 @@ | ||
1 | +subroutine master(x,y,sort,rw,npd,ntot,nadj,madj,ind,tx,ty,ilst,eps, | ||
2 | + delsgs,ndel,delsum,dirsgs,ndir,dirsum,nerror) | ||
3 | + | ||
4 | +# Master subroutine, to organize all the others. | ||
5 | + | ||
6 | +implicit double precision(a-h,o-z) | ||
7 | +logical sort | ||
8 | +dimension x(-3:ntot), y(-3:ntot) | ||
9 | +dimension nadj(-3:ntot,0:madj) | ||
10 | +dimension ind(npd), tx(npd), ty(npd), ilst(npd), rw(4) | ||
11 | +dimension delsgs(6,ndel), dirsgs(8,ndir) | ||
12 | +dimension delsum(npd,4), dirsum(npd,3) | ||
13 | + | ||
14 | +# Define one. | ||
15 | +one = 1.d0 | ||
16 | + | ||
17 | +# Sort the points into bins, the number of such being approx. sqrt(n). | ||
18 | +if(sort) { | ||
19 | + call binsrt(x,y,ntot,rw,npd,ind,tx,ty,ilst,nerror) | ||
20 | + if(nerror > 0) return | ||
21 | +} | ||
22 | +else { | ||
23 | + do i = 1,npd { | ||
24 | + ind(i) = i | ||
25 | + } | ||
26 | +} | ||
27 | + | ||
28 | +# Initialize the adjacency list to 0. | ||
29 | +do i = -3,ntot { | ||
30 | + do j = 0,madj { | ||
31 | + nadj(i,j) = 0 | ||
32 | + } | ||
33 | +} | ||
34 | + | ||
35 | +# Put the four ideal points into x and y and the adjacency list. | ||
36 | +# The ideal points are given pseudo-coordinates | ||
37 | +# (-1,-1), (1,-1), (1,1), and (-1,1). They are numbered as | ||
38 | +# 0 -1 -2 -3 | ||
39 | +# i.e. the numbers decrease anticlockwise from the | ||
40 | +# `bottom left corner'. | ||
41 | +x(-3) = -one | ||
42 | +y(-3) = one | ||
43 | +x(-2) = one | ||
44 | +y(-2) = one | ||
45 | +x(-1) = one | ||
46 | +y(-1) = -one | ||
47 | +x(0) = -one | ||
48 | +y(0) = -one | ||
49 | + | ||
50 | +do i = 1,4 { | ||
51 | + j = i-4 | ||
52 | + k = j+1 | ||
53 | + if(k>0) k = -3 | ||
54 | + call insrt(j,k,nadj,madj,x,y,ntot,nerror,eps) | ||
55 | + if(nerror>0) return | ||
56 | +} | ||
57 | + | ||
58 | +# Put in the first of the point set into the adjacency list. | ||
59 | +do i = 1,4 { | ||
60 | + j = i-4 | ||
61 | + call insrt(1,j,nadj,madj,x,y,ntot,nerror,eps) | ||
62 | + if(nerror>0) return | ||
63 | +} | ||
64 | + | ||
65 | +# Now add the rest of the point set | ||
66 | +do j = 2,npd { | ||
67 | + call addpt(j,nadj,madj,x,y,ntot,eps,nerror) | ||
68 | + if(nerror>0) return | ||
69 | +} | ||
70 | + | ||
71 | +# Obtain the description of the triangulation. | ||
72 | +call delseg(delsgs,ndel,nadj,madj,x,y,ntot,ind,nerror) | ||
73 | +if(nerror>0) return | ||
74 | + | ||
75 | +call delout(delsum,nadj,madj,x,y,ntot,npd,ind,nerror) | ||
76 | +if(nerror>0) return | ||
77 | + | ||
78 | +call dirseg(dirsgs,ndir,nadj,madj,x,y,ntot,rw,eps,ind,nerror) | ||
79 | +if(nerror>0) return | ||
80 | + | ||
81 | +call dirout(dirsum,nadj,madj,x,y,ntot,npd,rw,ind,eps,nerror) | ||
82 | + | ||
83 | +return | ||
84 | +end |
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +subroutine mnnd(x,y,n,dminbig,dminav) | ||
2 | +implicit double precision(a-h,o-z) | ||
3 | +dimension x(n), y(n) | ||
4 | + | ||
5 | +dminav = 0.d0 | ||
6 | +do i = 1,n { | ||
7 | + dmin = dminbig | ||
8 | + do j = 1,n { | ||
9 | + if(i!=j) { | ||
10 | + d = (x(i)-x(j))**2 + (y(i)-y(j))**2 | ||
11 | + if(d < dmin) dmin = d | ||
12 | + } | ||
13 | + } | ||
14 | + dminav = dminav + sqrt(dmin) | ||
15 | +} | ||
16 | + | ||
17 | +dminav = dminav/n | ||
18 | + | ||
19 | +return | ||
20 | +end |
@@ -0,0 +1,34 @@ | @@ -0,0 +1,34 @@ | ||
1 | +subroutine pred(kpr,i,j,nadj,madj,ntot,nerror) | ||
2 | + | ||
3 | +# Find the predecessor of j in the adjacency list of i. | ||
4 | +# Called by initad, trifnd, swap, dirseg, dirout. | ||
5 | + | ||
6 | +implicit double precision(a-h,o-z) | ||
7 | +dimension nadj(-3:ntot,0:madj) | ||
8 | + | ||
9 | +nerror = -1 | ||
10 | + | ||
11 | +n = nadj(i,0) | ||
12 | + | ||
13 | +# If the adjacency list of i is empty, then clearly j has no predecessor | ||
14 | +# in this adjacency list. Something's wrong; stop. | ||
15 | +if(n==0) { | ||
16 | + nerror = 5 | ||
17 | + return | ||
18 | +} | ||
19 | + | ||
20 | +# The adjacency list of i is non-empty; search through it until j is found; | ||
21 | +# subtract 1 from the location of j, and find the contents of this new location | ||
22 | +do k = 1,n { | ||
23 | + if(j==nadj(i,k)) { | ||
24 | + km = k-1 | ||
25 | + if(km<1) km = n # Take km modulo n. (The adjacency list | ||
26 | + kpr = nadj(i,km) # is circular.) | ||
27 | + return | ||
28 | + } | ||
29 | +} | ||
30 | + | ||
31 | +# The adjacency list doesn't contain j. Something's wrong; stop. | ||
32 | +nerror = 6 | ||
33 | +return | ||
34 | +end |
@@ -0,0 +1,106 @@ | @@ -0,0 +1,106 @@ | ||
1 | +subroutine qtest(h,i,j,k,shdswp,x,y,ntot,eps,nerror) | ||
2 | + | ||
3 | +# Test whether the LOP is satisified; i.e. whether vertex j is | ||
4 | +# outside the circumcircle of vertices h, i, and k of the | ||
5 | +# quadrilateral. Vertex h is the vertex being added; i and k are the | ||
6 | +# vertices of the quadrilateral which are currently joined; j is the | ||
7 | +# vertex which is ``opposite'' the vertex being added. If the LOP is | ||
8 | +# not satisfied, the shdswp ("should-swap") is true, i.e. h and j | ||
9 | +# should be joined, rather than i and k. | ||
10 | +# Called by swap. | ||
11 | + | ||
12 | +implicit double precision(a-h,o-z) | ||
13 | +dimension x(-3:ntot), y(-3:ntot) | ||
14 | +integer h | ||
15 | +logical shdswp | ||
16 | + | ||
17 | +nerror = -1 | ||
18 | + | ||
19 | +# Look for ideal points. | ||
20 | +if(i<=0) ii = 1 | ||
21 | +else ii = 0 | ||
22 | +if(j<=0) jj = 1 | ||
23 | +else jj = 0 | ||
24 | +if(k<=0) kk = 1 | ||
25 | +else kk = 0 | ||
26 | +ijk = ii*4+jj*2+kk | ||
27 | +switch(ijk) { | ||
28 | + | ||
29 | +# All three corners other than h (the point currently being | ||
30 | +# added) are ideal --- so h, i, and k are co-linear; so | ||
31 | +# i and k shouldn't be joined, and h should be joined to j. | ||
32 | +# So swap. (But this can't happen, anyway!!!) | ||
33 | + case 7: | ||
34 | + shdswp = .true. | ||
35 | + return | ||
36 | + | ||
37 | +# If i and j are ideal, find out which of h and k is closer to the | ||
38 | +# intersection point of the two diagonals, and choose the diagonal | ||
39 | +# emanating from that vertex. (I.e. if h is closer, swap.) | ||
40 | +# Unless swapping yields a non-convex quadrilateral!!! | ||
41 | + case 6: | ||
42 | + ss = 1 - 2*mod(-j,2) | ||
43 | + xh = x(h) | ||
44 | + yh = y(h) | ||
45 | + xk = x(k) | ||
46 | + yk = y(k) | ||
47 | + test =(xh*yk+xk*yh-xh*yh-xk*yk)*ss | ||
48 | + if(test>0) shdswp = .true. | ||
49 | + else shdswp = .false. | ||
50 | +# Check for convexity: | ||
51 | + if(shdswp) call acchk(j,k,h,shdswp,x,y,ntot,eps) | ||
52 | + return | ||
53 | + | ||
54 | +# Vertices i and k are ideal --- can't happen, but if it did, we'd | ||
55 | +# increase the minimum angle ``from 0 to more than 2*0'' by swapping, | ||
56 | +# and the quadrilateral would definitely be convex, so let's say swap. | ||
57 | + case 5: | ||
58 | + shdswp = .true. | ||
59 | + return | ||
60 | + | ||
61 | +# If i is ideal we'd increase the minimum angle ``from 0 to more than | ||
62 | +# 2*0'' by swapping, so just check for convexity: | ||
63 | + case 4: | ||
64 | + call acchk(j,k,h,shdswp,x,y,ntot,eps) | ||
65 | + return | ||
66 | + | ||
67 | +# If j and k are ideal, this is like unto case 6. | ||
68 | + case 3: | ||
69 | + ss = 1 - 2*mod(-j,2) | ||
70 | + xi = x(i) | ||
71 | + yi = y(i) | ||
72 | + xh = x(h) | ||
73 | + yh = y(h) | ||
74 | + test = (xh*yi+xi*yh-xh*yh-xi*yi)*ss | ||
75 | + if(test>0.) shdswp = .true. | ||
76 | + else shdswp = .false. | ||
77 | +# Check for convexity: | ||
78 | + if(shdswp) call acchk(h,i,j,shdswp,x,y,ntot,eps) | ||
79 | + return | ||
80 | + | ||
81 | +# If j is ideal we'd decrease the minimum angle ``from more than 2*0 | ||
82 | +# to 0'', by swapping; so don't swap. | ||
83 | + case 2: | ||
84 | + shdswp = .false. | ||
85 | + return | ||
86 | + | ||
87 | +# If k is ideal, this is like unto case 4. | ||
88 | + case 1: | ||
89 | + call acchk(h,i,j,shdswp,x,y,ntot,eps) # This checks | ||
90 | + # for convexity. | ||
91 | + # (Was i,j,h,...) | ||
92 | + return | ||
93 | + | ||
94 | +# If none of the `other' three corners are ideal, do the Lee-Schacter | ||
95 | +# test for the LOP. | ||
96 | + case 0: | ||
97 | + call qtest1(h,i,j,k,x,y,ntot,eps,shdswp,nerror) | ||
98 | + return | ||
99 | + | ||
100 | + default: # This CAN'T happen. | ||
101 | + nerror = 7 | ||
102 | + return | ||
103 | + | ||
104 | +} | ||
105 | + | ||
106 | +end |
@@ -0,0 +1,49 @@ | @@ -0,0 +1,49 @@ | ||
1 | +subroutine qtest1(h,i,j,k,x,y,ntot,eps,shdswp,nerror) | ||
2 | + | ||
3 | +# The Lee-Schacter test for the LOP (all points are | ||
4 | +# real, i.e. non-ideal). If the LOP is ***not*** | ||
5 | +# satisfied then the diagonals should be swapped, | ||
6 | +# i.e. shdswp ("should-swap") is true. | ||
7 | +# Called by qtest. | ||
8 | + | ||
9 | +implicit double precision(a-h,o-z) | ||
10 | +dimension x(-3:ntot), y(-3:ntot) | ||
11 | +integer h | ||
12 | +logical shdswp | ||
13 | + | ||
14 | +# The vertices of the quadrilateral are labelled | ||
15 | +# h, i, j, k in the anticlockwise direction, h | ||
16 | +# being the point of central interest. | ||
17 | + | ||
18 | +# Make sure the quadrilateral is convex, so that | ||
19 | +# it makes sense to swap the diagonal. | ||
20 | +call acchk(i,j,k,shdswp,x,y,ntot,eps) | ||
21 | +if(!shdswp) return | ||
22 | + | ||
23 | +# Get the coordinates of vertices h and j. | ||
24 | +xh = x(h) | ||
25 | +yh = y(h) | ||
26 | +xj = x(j) | ||
27 | +yj = y(j) | ||
28 | + | ||
29 | +# Find the centre of the circumcircle of vertices h, i, k. | ||
30 | +call circen(h,i,k,x0,y0,x,y,ntot,eps,shdswp,nerror) | ||
31 | +if(nerror>0) return | ||
32 | +if(shdswp) return # The points h, i, and k are colinear, so | ||
33 | + # the circumcircle has `infinite radius', so | ||
34 | + # (xj,yj) is definitely inside. | ||
35 | + | ||
36 | +# Check whether (xj,yj) is inside the circle of centre | ||
37 | +# (x0,y0) and radius r = dist[(x0,y0),(xh,yh)] | ||
38 | + | ||
39 | +a = x0-xh | ||
40 | +b = y0-yh | ||
41 | +r2 = a*a+b*b | ||
42 | +a = x0-xj | ||
43 | +b = y0-yj | ||
44 | +ch = a*a+b*b | ||
45 | +if(ch<r2) shdswp = .true. | ||
46 | +else shdswp = .false. | ||
47 | + | ||
48 | +return | ||
49 | +end |
@@ -0,0 +1,165 @@ | @@ -0,0 +1,165 @@ | ||
1 | +subroutine stoke(x1,y1,x2,y2,rw,area,s1,eps,nerror) | ||
2 | + | ||
3 | +# Apply Stokes' theorem to find the area of a polygon; | ||
4 | +# we are looking at the boundary segment from (x1,y1) | ||
5 | +# to (x2,y2), travelling anti-clockwise. We find the | ||
6 | +# area between this segment and the horizontal base-line | ||
7 | +# y = ymin, and attach a sign s1. (Positive if the | ||
8 | +# segment is right-to-left, negative if left to right.) | ||
9 | +# The area of the polygon is found by summing the result | ||
10 | +# over all boundary segments. | ||
11 | + | ||
12 | +# Just in case you thought this wasn't complicated enough, | ||
13 | +# what we really want is the area of the intersection of | ||
14 | +# the polygon with the rectangular window that we're using. | ||
15 | + | ||
16 | +# Called by dirout. | ||
17 | + | ||
18 | +implicit double precision(a-h,o-z) | ||
19 | +dimension rw(4) | ||
20 | +logical value | ||
21 | + | ||
22 | +zero = 0.d0 | ||
23 | +nerror = -1 | ||
24 | + | ||
25 | +# If the segment is vertical, the area is zero. | ||
26 | +call testeq(x1,x2,eps,value) | ||
27 | +if(value) { | ||
28 | + area = 0. | ||
29 | + s1 = 0. | ||
30 | + return | ||
31 | +} | ||
32 | + | ||
33 | +# Find which is the right-hand end, and which is the left. | ||
34 | +if(x1<x2) { | ||
35 | + xl = x1 | ||
36 | + yl = y1 | ||
37 | + xr = x2 | ||
38 | + yr = y2 | ||
39 | + s1 = -1. | ||
40 | +} | ||
41 | +else { | ||
42 | + xl = x2 | ||
43 | + yl = y2 | ||
44 | + xr = x1 | ||
45 | + yr = y1 | ||
46 | + s1 = 1. | ||
47 | +} | ||
48 | + | ||
49 | +# Dig out the corners of the rectangular window. | ||
50 | +xmin = rw(1) | ||
51 | +xmax = rw(2) | ||
52 | +ymin = rw(3) | ||
53 | +ymax = rw(4) | ||
54 | + | ||
55 | +# Now start intersecting with the rectangular window. | ||
56 | +# Truncate the segment in the horizontal direction at | ||
57 | +# the edges of the rectangle. | ||
58 | +slope = (yl-yr)/(xl-xr) | ||
59 | +x = max(xl,xmin) | ||
60 | +y = yl+slope*(x-xl) | ||
61 | +xl = x | ||
62 | +yl = y | ||
63 | + | ||
64 | +x = min(xr,xmax) | ||
65 | +y = yr+slope*(x-xr) | ||
66 | +xr = x | ||
67 | +yr = y | ||
68 | + | ||
69 | +if(xr<=xmin|xl>=xmax) { | ||
70 | + area = 0. | ||
71 | + return | ||
72 | +} | ||
73 | + | ||
74 | +# We're now looking at a trapezoidal region which may or may | ||
75 | +# not protrude above or below the horizontal strip bounded by | ||
76 | +# y = ymax and y = ymin. | ||
77 | +ybot = min(yl,yr) | ||
78 | +ytop = max(yl,yr) | ||
79 | + | ||
80 | +# Case 1; ymax <= ybot: | ||
81 | +# The `roof' of the trapezoid is entirely above the | ||
82 | +# horizontal strip. | ||
83 | +if(ymax<=ybot) { | ||
84 | + area = (xr-xl)*(ymax-ymin) | ||
85 | + return | ||
86 | +} | ||
87 | + | ||
88 | +# Case 2; ymin <= ybot <= ymax <= ytop: | ||
89 | +# The `roof' of the trapezoid intersects the top of the | ||
90 | +# horizontal strip (y = ymax) but not the bottom (y = ymin). | ||
91 | +if(ymin<=ybot&ymax<=ytop) { | ||
92 | + call testeq(slope,zero,eps,value) | ||
93 | + if(value) { | ||
94 | + w1 = 0. | ||
95 | + w2 = xr-xl | ||
96 | + } | ||
97 | + else { | ||
98 | + xit = xl+(ymax-yl)/slope | ||
99 | + w1 = xit-xl | ||
100 | + w2 = xr-xit | ||
101 | + if(slope<0.) { | ||
102 | + tmp = w1 | ||
103 | + w1 = w2 | ||
104 | + w2 = tmp | ||
105 | + } | ||
106 | + } | ||
107 | + area = 0.5*w1*((ybot-ymin)+(ymax-ymin))+w2*(ymax-ymin) | ||
108 | + return | ||
109 | +} | ||
110 | + | ||
111 | +# Case 3; ybot <= ymin <= ymax <= ytop: | ||
112 | +# The `roof' intersects both the top (y = ymax) and | ||
113 | +# the bottom (y = ymin) of the horizontal strip. | ||
114 | +if(ybot<=ymin&ymax<=ytop) { | ||
115 | + xit = xl+(ymax-yl)/slope | ||
116 | + xib = xl+(ymin-yl)/slope | ||
117 | + if(slope>0.) { | ||
118 | + w1 = xit-xib | ||
119 | + w2 = xr-xit | ||
120 | + } | ||
121 | + else { | ||
122 | + w1 = xib-xit | ||
123 | + w2 = xit-xl | ||
124 | + } | ||
125 | + area = 0.5*w1*(ymax-ymin)+w2*(ymax-ymin) | ||
126 | + return | ||
127 | +} | ||
128 | + | ||
129 | +# Case 4; ymin <= ybot <= ytop <= ymax: | ||
130 | +# The `roof' is ***between*** the bottom (y = ymin) and | ||
131 | +# the top (y = ymax) of the horizontal strip. | ||
132 | +if(ymin<=ybot&ytop<=ymax) { | ||
133 | + area = 0.5*(xr-xl)*((ytop-ymin)+(ybot-ymin)) | ||
134 | + return | ||
135 | +} | ||
136 | + | ||
137 | +# Case 5; ybot <= ymin <= ytop <= ymax: | ||
138 | +# The `roof' intersects the bottom (y = ymin) but not | ||
139 | +# the top (y = ymax) of the horizontal strip. | ||
140 | +if(ybot<=ymin&ymin<=ytop) { | ||
141 | + call testeq(slope,zero,eps,value) | ||
142 | + if(value) { | ||
143 | + area = 0. | ||
144 | + return | ||
145 | + } | ||
146 | + xib = xl+(ymin-yl)/slope | ||
147 | + if(slope>0.) w = xr-xib | ||
148 | + else w = xib-xl | ||
149 | + area = 0.5*w*(ytop-ymin) | ||
150 | + return | ||
151 | +} | ||
152 | + | ||
153 | +# Case 6; ytop <= ymin: | ||
154 | +# The `roof' is entirely below the bottom (y = ymin), so | ||
155 | +# there is no area contribution at all. | ||
156 | +if(ytop<=ymin) { | ||
157 | + area = 0. | ||
158 | + return | ||
159 | +} | ||
160 | + | ||
161 | +# Default; all stuffed up: | ||
162 | +nerror = 8 | ||
163 | +return | ||
164 | + | ||
165 | +end |
@@ -0,0 +1,34 @@ | @@ -0,0 +1,34 @@ | ||
1 | +subroutine succ(ksc,i,j,nadj,madj,ntot,nerror) | ||
2 | + | ||
3 | +# Find the successor of j in the adjacency list of i. | ||
4 | +# Called by addpt, initad, trifnd, swap, delout, dirseg, dirout. | ||
5 | + | ||
6 | +implicit double precision(a-h,o-z) | ||
7 | +dimension nadj(-3:ntot,0:madj) | ||
8 | + | ||
9 | +nerror = -1 | ||
10 | + | ||
11 | +n = nadj(i,0) | ||
12 | + | ||
13 | +# If the adjacency list of i is empty, then clearly j has no successor | ||
14 | +# in this adjacency list. Something's wrong; stop. | ||
15 | +if(n==0) { | ||
16 | + nerror = 9 | ||
17 | + return | ||
18 | +} | ||
19 | + | ||
20 | +# The adjacency list of i is non-empty; search through it until j is found; | ||
21 | +# add 1 to the location of j, and find the contents of this new location. | ||
22 | +do k = 1,n { | ||
23 | + if(j==nadj(i,k)) { | ||
24 | + kp = k+1 | ||
25 | + if(kp>n) kp = 1 # Take kp modulo n. (The adjacency list | ||
26 | + ksc = nadj(i,kp) # is circular.) | ||
27 | + return | ||
28 | + } | ||
29 | +} | ||
30 | + | ||
31 | +# The adjacency list doesn't contain j. Something's wrong. | ||
32 | +nerror = 10 | ||
33 | +return | ||
34 | +end |
@@ -0,0 +1,43 @@ | @@ -0,0 +1,43 @@ | ||
1 | +subroutine swap(j,k1,k2,shdswp,nadj,madj,x,y,ntot,eps,nerror) | ||
2 | + | ||
3 | +# The segment k1->k2 is a diagonal of a quadrilateral | ||
4 | +# with a vertex at j (the point being added to the | ||
5 | +# triangulation). If the LOP is not satisfied, swap | ||
6 | +# it for the other diagonal. | ||
7 | +# Called by addpt. | ||
8 | + | ||
9 | +implicit double precision(a-h,o-z) | ||
10 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot) | ||
11 | +logical shdswp | ||
12 | + | ||
13 | + | ||
14 | +# If vertices k1 and k2 are not connected there is no diagonal to swap. | ||
15 | +# This could happen if vertices j, k1, and k2 were colinear, but shouldn't. | ||
16 | +call adjchk(k1,k2,shdswp,nadj,madj,ntot,nerror) | ||
17 | +if(nerror > 0) return | ||
18 | +if(!shdswp) return | ||
19 | + | ||
20 | +# Get the other vertex of the quadrilateral. | ||
21 | +call pred(k,k1,k2,nadj,madj,ntot,nerror) # If these aren't the same, then | ||
22 | +if(nerror > 0) return | ||
23 | +call succ(kk,k2,k1,nadj,madj,ntot,nerror) # there is no other vertex. | ||
24 | +if(nerror > 0) return | ||
25 | +if(kk!=k) { | ||
26 | + shdswp = .false. | ||
27 | + return | ||
28 | +} | ||
29 | + | ||
30 | +# Check whether the LOP is satisified; i.e. whether | ||
31 | +# vertex k is outside the circumcircle of vertices j, k1, and k2 | ||
32 | +call qtest(j,k1,k,k2,shdswp,x,y,ntot,eps,nerror) | ||
33 | +if(nerror > 0) return | ||
34 | + | ||
35 | +# Do the actual swapping. | ||
36 | +if(shdswp) { | ||
37 | + call delet(k1,k2,nadj,madj,ntot,nerror) | ||
38 | + if(nerror > 0) return | ||
39 | + call insrt(j,k,nadj,madj,x,y,ntot,nerror,eps) | ||
40 | + if(nerror > 0) return | ||
41 | +} | ||
42 | +return | ||
43 | +end |
@@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
1 | +subroutine testeq(a,b,eps,value) | ||
2 | + | ||
3 | +# Test for the equality of a and b in a fairly | ||
4 | +# robust way. | ||
5 | +# Called by trifnd, circen, stoke. | ||
6 | + | ||
7 | +implicit double precision(a-h,o-z) | ||
8 | +logical value | ||
9 | + | ||
10 | +# If b is essentially 0, check whether a is essentially zero also. | ||
11 | +# The following is very sloppy! Must fix it! | ||
12 | +if(abs(b)<=eps) { | ||
13 | + if(abs(a)<=eps) value = .true. | ||
14 | + else value = .false. | ||
15 | + return | ||
16 | +} | ||
17 | + | ||
18 | +# Test if a is a `lot different' from b. (If it is | ||
19 | +# they're obviously not equal.) This avoids under/overflow | ||
20 | +# problems in dividing a by b. | ||
21 | +if(abs(a)>10.*abs(b)|abs(a)<0.1*abs(b)) { | ||
22 | + value = .false. | ||
23 | + return | ||
24 | +} | ||
25 | + | ||
26 | +# They're non-zero and fairly close; compare their ratio with 1. | ||
27 | +c = a/b | ||
28 | +if(abs(c-1.)<=eps) value = .true. | ||
29 | +else value = .false. | ||
30 | + | ||
31 | +return | ||
32 | +end |
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +subroutine triar(x0,y0,x1,y1,x2,y2,area) | ||
2 | + | ||
3 | +# Calculate the area of a triangle with given | ||
4 | +# vertices, in anti clockwise direction. | ||
5 | +# Called by delout. | ||
6 | + | ||
7 | +implicit double precision(a-h,o-z) | ||
8 | + | ||
9 | +area = 0.5*((x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)) | ||
10 | +return | ||
11 | +end |
@@ -0,0 +1,112 @@ | @@ -0,0 +1,112 @@ | ||
1 | +subroutine trifnd(j,tau,nedge,nadj,madj,x,y,ntot,eps,nerror) | ||
2 | + | ||
3 | +# Find the triangle of the extant triangulation in which | ||
4 | +# lies the point currently being added. | ||
5 | +# Called by initad. | ||
6 | + | ||
7 | +implicit double precision(a-h,o-z) | ||
8 | +dimension nadj(-3:ntot,0:madj), x(-3:ntot), y(-3:ntot), xt(3), yt(3) | ||
9 | +integer tau(3) | ||
10 | +logical adjace | ||
11 | + | ||
12 | +nerror = -1 | ||
13 | + | ||
14 | +# The first point must be added to the triangulation before | ||
15 | +# calling trifnd. | ||
16 | +if(j==1) { | ||
17 | + nerror = 11 | ||
18 | + return | ||
19 | +} | ||
20 | + | ||
21 | +# Get the previous triangle: | ||
22 | +j1 = j-1 | ||
23 | +tau(1) = j1 | ||
24 | +tau(3) = nadj(j1,1) | ||
25 | +call pred(tau(2),j1,tau(3),nadj,madj,ntot,nerror) | ||
26 | +if(nerror > 0) return | ||
27 | +call adjchk(tau(2),tau(3),adjace,nadj,madj,ntot,nerror) | ||
28 | +if(nerror>0) return | ||
29 | +if(!adjace) { | ||
30 | + tau(3) = tau(2) | ||
31 | + call pred(tau(2),j1,tau(3),nadj,madj,ntot,nerror) | ||
32 | + if(nerror > 0) return | ||
33 | +} | ||
34 | + | ||
35 | +# Move to the adjacent triangle in the direction of the new | ||
36 | +# point, until the new point lies in this triangle. | ||
37 | +1 continue | ||
38 | +ntau = 0 # This number will identify the triangle to be moved to. | ||
39 | +nedge = 0 # If the point lies on an edge, this number will identify that edge. | ||
40 | +do i = 1,3 { | ||
41 | + ip = i+1 | ||
42 | + if(ip==4) ip = 1 # Take addition modulo 3. | ||
43 | + | ||
44 | +# Get the coordinates of the vertices of the current side, | ||
45 | +# and of the point j which is being added: | ||
46 | + xt(1) = x(tau(i)) | ||
47 | + yt(1) = y(tau(i)) | ||
48 | + xt(2) = x(tau(ip)) | ||
49 | + yt(2) = y(tau(ip)) | ||
50 | + xt(3) = x(j) | ||
51 | + yt(3) = y(j) | ||
52 | + | ||
53 | +# Create indicator telling which of tau(i), tau(ip), and j | ||
54 | +# are ideal points. (The point being added, j, is ***never*** ideal.) | ||
55 | + if(tau(i)<=0) i1 = 1 | ||
56 | + else i1 = 0 | ||
57 | + if(tau(ip)<=0) j1 = 1 | ||
58 | + else j1 = 0 | ||
59 | + k1 = 0 | ||
60 | + ijk = i1*4+j1*2+k1 | ||
61 | + | ||
62 | +# Calculate the ``normalized'' cross product; if this is positive | ||
63 | +# then the point being added is to the left (as we move along the | ||
64 | +# edge in an anti-clockwise direction). If the test value is positive | ||
65 | +# for all three edges, then the point is inside the triangle. Note | ||
66 | +# that if the test value is very close to zero, we might get negative | ||
67 | +# values for it on both sides of an edge, and hence go into an | ||
68 | +# infinite loop. | ||
69 | + call cross(xt,yt,ijk,cprd) | ||
70 | + if(cprd >= eps) continue | ||
71 | + else if(cprd > -eps) nedge = ip | ||
72 | + else { | ||
73 | + ntau = ip | ||
74 | + break | ||
75 | + } | ||
76 | +} | ||
77 | + | ||
78 | +# We've played ring-around-the-triangle; now figure out the | ||
79 | +# next move: | ||
80 | +switch(ntau) { | ||
81 | + case 0: # All tests >= 0.; the point is inside; return. | ||
82 | + return | ||
83 | + | ||
84 | +# The point is not inside; work out the vertices of the triangle to which | ||
85 | +# to move. Notation: Number the vertices of the current triangle from 1 to 3, | ||
86 | +# anti-clockwise. Then "triangle i+1" is adjacent to the side from vertex i to | ||
87 | +# vertex i+1, where i+1 is taken modulo 3 (i.e. "3+1 = 1"). | ||
88 | + case 1: | ||
89 | + # move to "triangle 1" | ||
90 | + #tau(1) = tau(1) | ||
91 | + tau(2) = tau(3) | ||
92 | + call succ(tau(3),tau(1),tau(2),nadj,madj,ntot,nerror) | ||
93 | + if(nerror > 0) return | ||
94 | + case 2: | ||
95 | + # move to "triangle 2" | ||
96 | + #tau(1) = tau(1) | ||
97 | + tau(3) = tau(2) | ||
98 | + call pred(tau(2),tau(1),tau(3),nadj,madj,ntot,nerror) | ||
99 | + if(nerror > 0) return | ||
100 | + case 3: | ||
101 | + # move to "triangle 3" | ||
102 | + tau(1) = tau(3) | ||
103 | + #tau(2) = tau(2) | ||
104 | + call succ(tau(3),tau(1),tau(2),nadj,madj,ntot,nerror) | ||
105 | + if(nerror > 0) return | ||
106 | +} | ||
107 | + | ||
108 | +# We've moved to a new triangle; check if the point being added lies | ||
109 | +# inside this one. | ||
110 | +go to 1 | ||
111 | + | ||
112 | +end |