	subroutine primin(error,show)
#
# initialisiert den "Primitive Extractor". Die Routine
# - bestimmt den Zentralpunkt fuer die Analyse
# - und initialisiert alle Datenstrukturen fuer Subroutine PRIMEX
# - bzw. zeigt durch error=true an, dass kein passender Zentralpunkt
#   gefunden wurde (sonst ist error=false).
#
# Die folgenden Programm-Parameter, die mit Programm INIT in Bank 1 
# hinterlegt worden sind, werden hier in Common-Bloecke geschrieben.
#
# Im Common-Block 'tolrnc' stehen die Toleranzwerte
# - fuer die Suche nach terminalen Strecken:
#   imin  = Mindestlaenge einer potentiellen terminalen Strecke
#   dimax = max.erlaubter Abstand zwischen zwei Flanken (Luecke)
#   dgmax = max.erlaubte Grauwertdifferenz innerhalb der Strecke
# - fuer die Suche nach Schnittpunkten:
#   imax  = Hoechstbreite einer Flanke
#   dimin = Mindestbreite des Peaks
#   dgmin = Mindest-Grauwertdifferenz fuer Flanke
#   schfak= Faktor (<1) fuer Schulterhoehe der Flanke
#
# Im Common-Block 'para' stehen die Parameter
# - fuer die Bestimmung des Winkelinkrements zwischen zwei Strahlen:
#   bog    = absolute Bogenlaenge in Pixels
#   minbog = Bogenlaenge fuer min. Winkelinkrement
# - fuer die Erkennung von Defekten:
#   maxgap = max. Laenge einer Luecke im Rand
# - fuer die Feinaufloesung:
#   minabs = Mindestabstand der Endpunkte zur Winkelhalbierenden
#
#
#				ACHTUNG!!!
# Das Pixel (1,1) des Grauwertbildes liegt per definitionem in der linken 
# oberen (!) Ecke. Um aber bei der Analyse mit Winkeln und Steigungen im 
# gewohnten (Umlauf-)Sinn operieren zu koennen, wird die y-Koordinate in 
# der Zugriffsroutine 'getpix' (in File SUBS) gespiegelt. Somit ist der x,y-
# Ursprung in der linken unteren Ecke anzunehmen.
#
# Verwendete externe Routinen, die nicht in FORLIB sind:
# Name		File,Bibliothek
# loadb		BANKLIB		holt 1 Byte aus Bank 1
# loadw		BANKLIB		holt 2 Bytes aus Bank 1
# loadr		BANKLIB		holt 4 Bytes aus Bank 1
# storeb	BANKLIB		schreibt ein Byte in Bank 1
# varptr	BANKLIB		liefert eine Variablenadresse
# zpunkt	PRIMIN		bestimmt den Zentralpunkt fuer Analyse
# putp		PLOTLIB		setzt einen Plottpunkt
# inkey		PARSER		wartet auf Keyboard-Zeichen
#
# Idee und Programmierung  A.Herrmann
#
# Version 2.0	30.03.85
#
include defsymbl.rat
include defstack.rat
#
define	BADR x'1000'	# Basisadresse in Bank 1
define	REPMAX 5	# max.Anzahl der Startversuche
define	START 1		# Startadresse
define	TRY 2		# Label
#
logical	error		# Error Flag
logical	show		# mit/ohne Bildschirm-Ausgabe
#
byte	g		# Grauwert
byte	gwmax		# max. Grauwert
byte	char,yes,bigyes	# Eingabezeichen, Yes
byte	inkey		# function; liefert Keyboard-Zeichen
#
integer	xanz,yanz	# tatsaechl.Bildgrenzen
integer	zx,zy		# Zentralpunkt
integer	repcnt		# Zaehler fuer Startversuche 
integer	stack(TOPMAX,8)	# Stack mit Symbol und Attributen
integer	top		# Top of Stack
integer	zustnd,		# Zustand des Kelleruebersetzers (Kurventyp)
	wsymbl,		# letzter Winkeltyp
	w1,w2,dw	# letzte Winkel und Differenzwinkel
#
integer	dgmin,dgmax	# s.oben
integer imin,imax,
	dimin,dimax
integer	bog,minbog
integer	maxgap,minabs
#
integer	i,j,k		# Laufindizes
#
integer pon,pof		# Plott-Pen on/off
integer	xx1,yy1,xx2,yy2,# Plott-Koord.
	xxi,yyi
#
#	Banking Adressen 
#
integer	axanz,ayanz,	# Adressen der Bildkenndaten in Bank 1
	agwmax
integer	adrb		# Adresse des Bildes in Bank 1
integer	adrr		# Adresse der Zufallszahl in Bank 1
integer	arts		# Adresse des RTS-Flags in Bank 1
integer	radr		# Adresse der Variable r im Programm
integer	ranadr		# Startadresse der ran-Function im Programm
integer	varptr		# function; liefert eine Variablenadresse im Programm
#
#
real	cgx,cgy		# muessen bleiben wegen Common-Block bild
real	area,perim,form
real	schfak		# Faktor fuer Schulterhoehe
real	r		# Real-Zahl
#
external ran		# Random number generator Adresse
#
common	/bank/adrb
common	/bild/xanz,yanz,gwmax,zx,zy,cgx,cgy,area,perim,formf
common	/systck/top,stack
common	/status/zustnd,wsymbl,w1,w2,dw
common	/tolrnc/imin,dimax,dgmax,imax,dimin,dgmin,schfak
common	/para/bog,minbog,maxgap,minabs
#
data	bigyes,yes/'Y','y'/
data	pon,pof/1,0/
#
if (show) write (1,10)
10 format(/' *** PRIMIN ***')
#
#	Chaining-Praeliminarien
#
adrr=BADR				# Variablenadressen in Bank 1
arts=adrr+7
axanz=arts+1 ; ayanz=axanz+2 ; agwmax=ayanz+2
adrb=BADR+x'100'
#
ranadr=varptr(ran)-7			# Adresse des Zuf'zahlenspeichers
radr=varptr(r)
do i=0,6				# vorige Zuf'zahl holen
[	k=adrr+i ; call loadb(g,k) 
	k=ranadr+i ; call poke(k,g)
	if (i<<4) [ k=radr+i ; call poke(k,g) ]
]
if (show) write(1,12) r
12 format(' random = ',f8.7)
call loadw(xanz,axanz)			# Bilddaten aus Bank 1 holen
call loadw(yanz,ayanz)
call loadw(gwmax,agwmax)
#
if (show) write(1,20) xanz,yanz,gwmax
20 format(' Bildgroesse',2i4,'  max.Grauwert',i4)
#
# Plotte Bild rechts unten 
#
xx1=158-xanz ; yy1=0 ; xx2=xx1+xanz+1 ; yy2=yy1+yanz+1
call window(xx1,yy1,xx2,yy2) ; call frame
do yyi=1,yanz
[	i=yanz-yyi+1
	do xxi=1,xanz
	[	k=adrb+(xxi-1)*yanz+yyi-1
		call loadb(g,k)
		if (g==0) call putp(xxi,i,pon)
]	]
#
i=BADR+16 ; call loadw(bog,i)
i=i+2 ; call loadw(minbog,i)
i=i+2 ; call loadw(maxgap,i)
i=i+2 ; call loadw(minabs,i)
i=i+2 ; call loadw(imin,i)
i=i+2 ; call loadw(dimax,i)
i=i+2 ; call loadw(dgmax,i)
i=i+2 ; call loadw(imax,i)
i=i+2 ; call loadw(dimin,i)
i=i+2 ; call loadw(dgmin,i)
i=i+2 ; call loadr(schfak,i)
#
if (show) 
[	write(1,30)
	30 format(' Toleranzen fuer')
	write(1,32) bog,minbog,maxgap,minabs
	32 format(' - winkr und whalb: bog,minbog,maxgap,minabs = ',4i3)
	write(1,34) imin,dimax,dgmax
	34 format(' - terminal: imin,dimax,dgmax = ',3i3)
	write(1,36) imax,dimin,dgmin,schfak
	36 format(' - durchp: imax,dimin,dgmin,schfak = ',3i3,f6.3)
]
#	Initialisierung des "Primitive Extractors"
#	(ggf. mit mehreren Zentralpunkten versuchen)
#
error=.false.
START	repcnt=0				# zaehlt die Versuche
repeat
[	repcnt=repcnt+1
	call zpunkt(zx,zy,error,show)		# Zentralpunkt bestimmen
TRY	if (.not.error)				# Falls gefunden:
	[	top=1 ; stack(top,SYM)=XS	# Kelleruebersetzer init.
		zustnd=ZI
	]
] until(.not.error !! repcnt>=REPMAX)
#
if (error)
[	write(1,40) repcnt
	40 format(' *** PRIMIN - ',i3,' Versuche')
	write(1,42)
	42 format(' Weiter versuchen ? (Y/N) ')
	char=inkey(.true.)
	if (char==yes !! char==bigyes) goto START
	zx=0 ; zy=0
]
cgx=float(zx) ; cgy=float(zy) 		# Dummy-Schwerpunkt
call putp(zx,zy,pon)			# Zentralpunkt plotten
#
do i=0,6				# letzte Zuf'zahl abspeichern
[	k=ranadr+i ; g=peek(k) 
	k=adrr+i ; call storeb(g,k)
]
if (show) write(1,90)
90 format(' *** PRIMIN - Ende ***')
end


	subroutine zpunkt(zx,zy,error,show)
#
# liefert den Zentralpunkt fuer die Analyse.
# Vorlaeufige Arbeitsweise:
# Es wird - ggf. mehrmals - versucht, einen Punkt zu finden, dessen 3x3-
# Nachbarschaft keinen schwarzen Punkt enthaelt. 
# Falls bei Einsprung error=false ist, findet der erste Versuch in der 
# Bildmitte statt, sonst zufaellig.
# Falls kein passender Punkt gefunden wird, ist error=true und zx=zy=0.
#
# Verwendete externe Routinen, die nicht in FORLIB sind:
# Name		File,Bibliothek
# getpix	SUBS		holt Pixel aus Bank 1
# irand		RANFCT		liefert Integer-Zufallszahl
# inkey		PARSER		liefert Keyboard-Zeichen
#
# Version 1.3	16.08.84
#
define	MAXREP 10	# max.Anzahl der Versuche
define	EXIT 999	# Label
#
logical	error
logical	show		# mit/ohne Bildschirm-Ausgabe
logical	okay		# Testflag
#
byte	g		# Grauwert
byte	char,yes,bigyes
byte	inkey		# function, liefert Keyboard-Zeichen
byte	getpix		# function, liefert Pixelgrauwert aus Bank 1
#
integer	zx,zy		# Zentralpunkt-Pixelkoord.
integer	xanz,yanz	# tatsaechl.Bildgrenzen
integer	repcnt		# Wiederholungsszaehler
integer ix,iy		# Punktkoord.
integer	irand		# function; liefert Integer-Zufallszahl
#
common	/bild/xanz,yanz
#
data	bigyes,yes/'Y','y'/
#
write(1,10) 
10 format(' ZPUNKT - Eingabe (Y/N) ')
char=inkey(.true.)
repcnt=0
if (char==yes !! char==bigyes) 
[	write(1,12)
	12 format(' x,y-Koord. ')
	read(1,14) zx,zy
	14 format(2i4)
	error=.false. ; goto EXIT
]
repeat
[	repcnt=repcnt+1
	if (.not.error && repcnt==1)
	[	zx=int(float(xanz)/2) ; zy=int(float(yanz)/2) ]	# Bildmitte
	else
	[	zx=irand(2,xanz-1) ; zy=irand(2,yanz-1)	]	# zuf.Punkt
	okay=.true.
	for (iy=zy-1; iy<=zy+1; iy=iy+1)
	[	for (ix=zx-1; ix<=zx+1; ix=ix+1)
		[	g=getpix(ix,iy)		# Pixel aus Bank 1 holen
			if (g==0) okay=.false.
	]	]
] until (okay !! repcnt>=MAXREP)
if (.not.okay) [ error=.true. ; zx=0 ; zy=0 ]
else error=.false.
#
EXIT if (show) write(1,90) zx,zy,repcnt
90 format(' Zentralpunkt',2i4,/' im',i3,'. Versuch')
return
end
