
Naj bosta na ravnini samo dve točki p1 in p2. Naj bo premica B(p1, p2) = B12, ki pravokotno razdeli segment p1p2 na dva enaka dela. Potem je vsaka točka x na premici B12 enako oddaljena od točke p1, kakor tudi od točke p2. Velja: |p1x| = |p2x| (Slika 1).



pri čemer je potrebno upoštevati presek preko vseh i in j, za katere
velja
. Iz enačbe sledi lastnost Voronoi diagrama: območja Voronoi
diagrama so konveksna, ker nastanejo kot presečišča večih polravnin.
Kadar so ta območja omejena, so to konveksni poligoni. Robovi se
imenujejo Voronoi robovi in temena Voronoi temena. Katerakoli točka na
Voronoi robu ima dve najbližji točki niza točk na ravnini, Voronoi teme
pa ima najmanj tri najbližje take točke.
V primeru štirih točk na ravnini, ki oblikujejo vogale kvadrata, je to
Voronoi diagram kot je prikazano na Sliki 3a. Voronoi teme je v tem
primeru četrte stopnje. Če se eno točko nekoliko premakne (Slika 3b),
postane diagram normalen. Prvi primer je izrojen zaradi centričnega
položaja štirih točk na ravnini.




Za Delaunayevo triangulacijo veljajo lastnosti:
D1. D(P) je ravnočrtna dvojnost V(P), po definiciji.
D2. D(P) je triangulacija, če ne obstajajo štiri centrične
točke na ravnini: vsaka površina je trikotnik. Ploskve D(P) so
Delaunayevi trikotniki.
D3. Vsak trikotnik grafa D(P) ustreza temenu grafa V(P).
D4. Vsak rob grafa D(P) ustreza robu grafa V(P).
D5. Vsak vozel grafa D(P) ustreza območju grafa V(P).
D6. Meja D(P) je konveksna lupina
D7. Notranjost trikotnikov D(P) ne vsebuje nobenih točk niza P.
Za Voronoi diagram veljajo lastnosti:
V1. Vsako Voronoi območje V(pi) je konveksno.
V2. V(pi) je neomejen, če je pi na
konveksni lupini niza točk P.
V3. Če je Voronoi teme na stičišču V(p1),
V(p2) in V(p3), potem je v središču
kroga C(v), ki ga določajo točke p1,
p2 in p3.
V4. C(v) je očrtan krog pri Delaunayevi triangulaciji, ki ustreza v.
V5. V notranjosti C(v) ni nobene točke niza P.
V6. Če je pj najbližji pi,
potem je (pj,pi) rob triagulacije D(P).
V7. Če obstaja krog skozi točki pj in pi, ki ne vsebuje nobenih
drugih točk niza P, potem je (pj,pi) rob triangulacije D(P).
Začetek pregledovanja je tako rob, ki ga določata najnižja, najbolj desna točka in točka, ki je prva najbližja po naraščujočem kotu glede na os x (Slika 7).


Prvi program, z imenom Princip tretje točke bere podatke iz datoteke Pod.txt in nato po teoriji tretje točke določi robove optimalne trikotniške mreže. Optimalna trikotnižka mreža je konveksna. Sestavljena je optimalnih trikotnikov, kjer naj bi veljalo pravilo maksimiziranja najmanjšega kota v trikotniku. To pravilo ni uporabljeno direktno, temveč po metodi principu tretje točke, kjer določimo središče očrtanega kroga in središče aktivnega roba (ta postopek ja že opisan v poglavju princip tretje točke).
V tem programu imamo dva podprograma. Podprogram tretja točka določuje
tretjo točko aktivnega roba ter izpisuje te točke v datoteko
Phigs.txt.
Drugi podprogram, z imenom Krog, določuje središče očrtanega kroga
trikotniku.
Drugi program Phigs.for prebere točke robov trikotnikov iz datoteke Phigs.txt ter jih s pomočjo grafične knjižnice PHIGS izriše v optimalno trikotniško mrežo.
program Princip tretje tocke
real x(1000),y(1000),p(1000,1000),alfa(1000)
real pxd,pyd,pxz,pyz
open(3,file='pod.txt')
open(4,file='phigs.txt')
open(5,file='brez.txt')
do i=1,1000
read(3,*,end=10)x(i),y(i)
p(i,1)=x(i)
p(i,2)=y(i)
sttock=i
write(*,*)p(i,1),p(i,2)
enddo
10 close(3)
**************************************************************************
c Dolocitev zacetne tocke (pxz,pyz).
pyz=y(1)
pxz=x(1)
do i=1,sttock-1
if (p(i+1,2).le.pyz)then
pxz=p(i+1,1)
pyz=p(i+1,2)
if(p(i+1,2).eq.pyz)then
if(p(i+1,1).lt.pxz)then
pxz=p(i+1,1)
pyz=p(i+1,2)
else
pxz=pxz
pyz=pyz
endif
endif
endif
enddo
write(*,*)'zacetna tocka je',pxz,pyz
***********************************************************
c Dolocitev druge tocke prvega trikotnika (pxd,pyd).
alf=180
do i=1,sttock
if(x(i).eq.pxz.and.y(i).eq.pyz)then
go to 20
endif
if(x(i).ge.pxz)then
alfa(i)=atan((y(i)-pyz)/(x(i)-pxz+0.000001))
else
alfa(i)=180+atan((y(i)-pyz)/(x(i)-pxz+0.000001))
endif
if(alfa(i).lt.alf)then
alf=alfa(i)
pxd=x(i)
pyd=y(i)
else
alf=alf
pxd=pxd
pyd=pyd
20 endif
enddo
write(*,*)'druga tocka je',pxd,pyd
**********************************************************
c pxz,pyz=zacetna tocka
c pyd,pyd=druga tocka
write(4,*)pxz,pyz
write(4,*)pxd,pyd
call tretja_t(pyz,pyd,pyt,pxz,pxd,pxt,sttock,x,y,pycrz)
do j=1,2*sttock
xz=pxz
yz=pyz
xt=pxt
yt=pyt
xd=pxd
yd=pyd
pxz=pxz1
pyz=pyz1
pxt=pxt1
pyt=pyt1
pxd=pxd1
pyd=pyd1
***********************************************************
pxz1=xz
pyz1=yz
pxd1=xt
pyd1=yt
call tretja_t(pyz1,pyd1,pyt1,pxz1,pxd1,pxt1,sttock,x,y,
1 pycrz)
if (pycrz.eq.1001)then
write(*,*)'ni leve zunaj 1'
goto 70
endif
write(5,*)'nekaj 1 t d z',xt,yt,xd,yd,xz,yz
write(5,*)'nekaj 1 pt pd pz',pxt1,pyt1,pxd1,pyd1,pxz1,
1 pyz1,pycrz
***********************************************************
70 pxz=xt
pyz=yt
pxd=xd
pyd=yd
call tretja_t(pyz,pyd,pyt,pxz,pxd,pxt,sttock,x,y,pycrz)
if (pycrz.eq.1001)then
write(*,*)'ni leve zunaj'
pxz=pxz1
pyz=pyz1
pxt=pxt1
pyt=pyt1
pxd=pxd1
pyd=pyd1
endif
write(5,*)'nekaj 2 t d z',xt,yt,xd,yd,xz,yz
write(5,*)'nekaj 2 pt pd pz',pxt,pyt,pxd,pyd,pxz,pyz,
1 pycrz
enddo
stop
100 write(*,*)'nekaj je narobe 100'
close(4)
end
**********************************************************
SUBROUTINE tretja_t(pyz,pyd,pyt,pxz,pxd,pxt,sttock,x,y,pycrz)
* subrotina nam izracuna:
* - kot rot. koord. sistema
* - doloci lego premice - orientiranost
* - rotira koord. sistem in vse tocke glede na nov koord. sistem
* - glede na levost tock, ocrta krog, sredisce, IZBERE 3. TOCKO
real d,e,fi,kpremice,x(1000),y(1000),pycrz
parameter(pi=3.14159265359)
c Izracun kota premice zacetnega aktivnega roba (fi)
kpremice=(pyz-pyd+0.000001)/(pxz-pxd+0.000001)
fi=atan(kpremice)*180/pi
c Dolocitev lege premice
if(pxz.ge.pxd.and.pyz.le.pyd)then
fi=180+fi
elseif(pxz.le.pxd.and.pyz.ge.pyd)then
fi=360+fi
elseif(pxz.gt.pxd.and.pyz.gt.pyd)then
fi=180+fi
elseif(pxz.lt.pxd.and.pyz.lt.pyd)then
fi=fi
endif
write(*,*)'***************************'
***********************************************************
c Rotacija koordinatnega sistema
d=cos(fi*pi/180)
e=sin(fi*pi/180)
pxdr=(pxd-pxz)*d+(pyd-pyz)*e
pydr=-((pxd-pxz)*e)+(pyd-pyz)*d
pxzr=(pxz-pxz)*d+(pyz-pyz)*e
pyzr=-((pxz-pxz)*e)+(pyz-pyz)*d
c Postavitev tock v nov koordinatni sistem.
pycrz=1001
do i=1,sttock
pxt=x(i) ! pxt,pyt=tretja tocka
pyt=y(i)
pxtr=(pxt-pxz)*d+(pyt-pyz)*e
pytr=-(pxt-pxz)*e+(pyt-pyz)*d
if(pytr.gt.0.001)then
call krog(pxzr,pyzr,pxdr,pydr,pxtr,pytr,pxcr,pycr)
if(pycr.lt.pycrz.and.pycr.ne.0.000)then
pycrz=pycr !min rot.y = pycrz
stevec=i
endif
endif
enddo
if (pycrz.eq.1001)then
write(*,*)'ni leve od znotraj'
goto 50
endif
write(*,*)'min rot. y',pycrz,x(stevec),y(stevec),stevec
pxt=x(stevec)
pyt=y(stevec)
***********************************************************
* zapis za PHIGS
write(4,*)pxz,pyz
write(4,*)pxt,pyt
write(4,*)pxt,pyt
write(4,*)pxd,pyd
50 return
end
***********************************************************
SUBROUTINE krog(x1,y1,x2,y2,x3,y3,xc,yc)
pr(xs,ys,x1,y1,x2,y2)=(ys-y1)*(x2-x1)-(xs-x1)*(y2-y1)
fp(v1,v2,w1,w2)=((v2*v2-v1*v1)+(w2*w2-w1+w1))
f(v1,v2,w1,w2)=fp(v1,v2,w1,w2)/(2.0*(v2-v1+0.000001))
g(v1,v2,w1,w2)=(w2-w1)/(v2-v1+0.000001)
ay(x1,x2,x3,y1,y2,y3)=(f(x1,x3,y1,y3)-f(x1,x2,y1,y2))/
1 (g(x1,x3,y1,y3)-g(x1,x2,y1,y2)+0.000001)
ax(x1,x2,x3,y1,y2,y3)=((x3*x3-x1*x1)+(y3-y1)*
2 ((y3+y1)-2*ay(x1,x2,x3,y1,y2,y3)))/(2.0*(x3-x1+0.000001))
if(pr(x1,y1,x2,y2,x3,y3).eq.0.0) then
else
if(x1.ne.x3) then
xc = ax(x1,x2,x3,y1,y2,y3)
yc = ay(x1,x2,x3,y1,y2,y3)
else
xc=ax(x2,x1,x3,y2,y1,y3)
yc=ay(x2,x1,x3,y2,y1,y3)
endif
rk=sqrt((x3-xc)**2+(y3-yc)**2)
endif
return
end
***********************************************************
program phigs
include 'phigsdef.f'
real WindowLimits(4)/0.0,15.0,0.0,15.0/
real ViewportLimits(4)/0.2,0.8,0.2,0.8/
real ClipLimits(4) /0.0,1.0,0.0,1.0/
real ViewMappingMatrix(3,3)
integer wkid, ErrorReturn, i,j,k,l
real qx(1000),qy(1000)
open(10,file='phigs.txt')
do i=1,1000
read(10,*,end=20)qx(i),qy(i)
k=i
enddo
20 write(*,*)'stevilo ogljisc =',k
close(10)
call popph(2,0)
wkid=2
call popwk(wkid," ",WK151280)
call pevmm(WindowLimits, ViewportLimits, ErrorReturn,
* ViewMappingMatrix)
do 50 i=1,3
do 60 j=1,3
write (*,*)ViewMappingMatrix(i,j)
60 continue
50 continue
call psplci(2)
call pslwsc(5)
call psln(plsoli)
call pswkw(wkid,0.0,1.0,0.0,1.0)
call pschh(0.005)
call pswkv(wkid,0.0,0.15,0.0,0.12)
******* Izris daljic kot polyline **********************************
call ppl(k,qx,qy)
pause
call pclwk(wkid)
c Zapre PHIGS (zakljuci z graficnim nacinom dela)
c ( PhigsCLosePHigs )
call pclph()
stop
end
[2] L. Kos, J. Duhovnik, Fakulteta za strojništvo, Ljubljana 1997.
[3] K. Mulmuley,Computational Geomtry: an Introduction Trough Rendomized Algorithms, Prentice -Hall, Inc.,1994
[4] Joseph O'Rourke,Computational Geomtry in C, Cambridge Universty Press, 1993
Vaše mnenje lahko pošljete na:
Andrej Marlin
Telephone: +386 61 1771-436