NNNNNNӹp NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNmO`  @`! #@%`'0)+-/1 O5`79;=?A C@E`GIKMOQ S@U`WY[]_a c@e`gikmoq s@u}@` @ ` @ ` / @ ` @ o ǀ ɠ @ ` ׀ ٠  @` @`Aa  !Aa!O%a')+-/1!3A5a79;=?A!CAEaGIKMOQ!SAUaYO`  @`! #@%`'0)+-/1 O5`79;=?A C@E`GIKMOQ S@U`WY[]_a c@e`gikmoq s@u}@` @ ` @ ` / @ ` @ o ǀ ɠ @ ` ׀ ٠  @` @`Aa  !Aa!O%a')+-/1!3A5a79;=?A!CAEaGIKMOQ!SAUaYDOC  t OBJECTS  t SOURCE  t zDRIEDIM PRG t  DRIEDIM RSC t WLEES_MIJA08t [^CN_CAT1 t ].  t..  tDRIEDIM DOC t L0660103030566 1 2- # - 9[....................................................] Inhoud: 1)Introductie. 2)Start. 3)BewegenindeDrieDimwereld. 4)Hiddenlineremoval. 5)Picturemode. 6)Diversen. 7)DeDrieDimsource. 8)Opmerkingen. AppendixA:Voorbeeld. 1)Introductie. HetprogrammaDriedimiseenuitvloeiselvaneenverzoekvan eenbevriendbouwkundestudentomeenprogrammawaarmee redelijksnelperspectiefschetsenvanbveengebouw,vanuit willekeurigegezichtspuntengezien,kondenwordengemaakt.Een eersteversiewerdgeschreveninPASCALopeennietgrafisch georienteerdcomputersysteem(VAXonderVMS),waarmeehet mogelijkwasomvaneenbeschrijvingvanhettetekenen voorwerpineeneenvoudigebescrijvingstaal,eengezichtspunt eneenkijkrichting,eentekeningaantemaken.Almetaleen nietalteeenvoudigeprocedure,daareengebruikerzich altijdbewustmoestzijnvaneencordinatenstelselwaarin hij/zijzichbewoog. Eentweede(grofwegdehuidige)versiewerdgeschrevenin MODULA-2nadatikmijnSThadaangeschaft.Degrafische mogelijkhedenvandezemachinewerdenbenutomhetuser interfacewatnatuurlijkertemaken:inplaatsvanhet herhaaldelijkinvoerenvandecordinatenvangezichtspunten kijkrichting,kandegebruikerzichnubeschouwenalseen wandelaardiezichdoorenomhettebekijkenobjectheenkan bewegenmetcommando'sals'daarheen','eentikjevooruit', etc.Hetisnogslechtsincidenteelnodigomintermenvanhet onderliggendcordinatenstelseltedenken. Deobjectbeschrijvingmoetnogsteedsmetdehandaangemaakt wordenalseentekstineenbeschrijvingstaal.Driedimbiedt hiervoor(nog)geenfaciliteiten.  EenkortekenschetsvanDriedimisdanook: Driedimiseenprogrammawaarmeevanuiteenvantevoren aangemaaktebeschrijvingvaneenobjectopredelijkeenvoudige wijzetekeningenvanditobjectgegenereerdkunnenworden.  Inditverhaalzaleen(watoperationele)beschrijvinggegeven wordenvandefaciliteitenvanDriedim(secties2-6),alsmede eenbeschrijvingvandeinvoertaal(sectie7).Eenvoorbeeld vaneenobjectbeschrijvingisinAppendixAtevinden. DaarervanwordtuitgegaandatelkeSTgebruikeronderhandwel vertrouwdismetdeGEMterminologie(namenvanwindow attributenendergelijke),wordendezewaarnodigzonder uitleggebruikt.OokopstandaardGEMprocedures,zoals fileselectorafhandelingenmenukeuze,wordtnietingegaan. 2)Start. Objectbescrijvingenmoetenzichineenfilebevindenomte kunnenwordengelezendoorDriedim(aanbevolenextensievan ditsoortfilesis".PLT"). DirectnahetopstartenvanDriedimwordtomeenfilegevraagd waarindegewensteobjectbeschrijvingkanwordengevonden.De heleverderesessiehandeltverdermetdenuingevoerde beschrijving:dezewordtingelezen,gecontroleerdopfouten, enindienfoutvrijkanbegonnenwordenmethetgenererenvan tekeningen(zieverder).Omeennieuwobjecttebekijkenmoet desessiebeindigd-eneennieuweopgestartworden.  Notes: -Aangezienelkekeerbijinlezenvolledigopfoutenwordt gecontroleerdenhetparsenvantekstenzowiezoeendure operatieis,kandeinleesfasewatlangduren.Hoewel uiteraardergonomischonverantwoord,wordtnoggeenenkele informatieoverdevorderingenvandeparsergetoond. -Meldingenvandoordeparsergevondenfoutenverschijnen vooralsnogophetscherm. IneeneventuelevolgendeversievanDriedimzullendezezaken zijnopgelost. 3)BewegeninDrieDimwereld.  Omhetvolgendebetertekunnenbeschrijvenwordtdegebruiker vannuafaanbeschouwdalseenobservatorinhetcoordinaten stelselvanhetingelezenobject,diezichopelkogenblikop eenbepaaldepositiebevindtenineenbepaalderichting kijkt.Hetgenererenvannieuweaangezichtenkandanworden beschouwdalshetbewegenvandezeobservatordoorhet coordinatenstelsel. Zodradebeschrijvingsuccesvolisingelezen,wordteenGEM windowgeopendmeteeneerstegezichtophetingelezenobject. Ditwindowtoontopelkmomenthetbeelddatdeobservatorvan hetobjectheeft,metdeonderdelenvanhetobjectdiezichin dekijkrichtingbevindeninhetmidden. Veranderingenvanpositieofkijkrichtingkunnenworden bewerktstelligdmetbehulpvandewindowattributen,demuis cursorenhetinvulformulierdatdoor"Setviewparameters ..."ondermenutitel"Viewparms"tevoorschijngetoverdkan worden: Muiscursor: Zodrademuiscursorinhettekengebiedvanhetgeopende windowgeplaatstwordt,verandertdecursorvormvanpijlin eenaanwijskruis.Eenklikopdelinkermuisknopverplaatst dekijkrichtingnaarhetaangewezendeelvanhetgetekende object.Depositievandeobservatorveranderthierdoorniet. Sliders: Debeideslidersstaaninhetmiddenvanhunscrollbars.Met deslidersishetmogelijkd.m.v.elevatieenrotatieinhet grondvlakdekijkrichtingteveranderen: -Elevatievankijkrichtingkanhierwordenbeschouwdalshet op-ofneerkijkenvandeobservator.Eenuitwijkingvande verticalesliderbewerktstelligteenelevatievande kijkrichtingvan0tot90gradenomhoog,corresponderendmet eenuitwijkingomhoogvandeslider,ofvan0tot90graden omlaag,corresponderendmeteenuitwijkingomlaagvande slider. -Rotatievankijkrichtingkanwordenbeschouwdalshet draaienvandeobservatoromeenasloodrechtophet grondvlak.Eenuitwijkingvandehorizontaleslider bewerktstelligteenrotatievandekijkrichtingvan0tot 180gradennaarrechts,corresponderendmeteenuitwijking naarrechtsvandeslider,ofvan0tot180gradennaar links,corresponderendmeteenuitwijkingnaarlinksvande slider.Eenmaximaleuitwijkingineenvanderichtingen zorgtvooreenrotatievan180graden:deobservatorkeert zichom. Arrowsenscrollbars: Eenpositieveranderingvandeobservatorismogelijkdooreen bewegingvandeobservatorineenvandezesrichtingen:  -Naarlinksofnaarrechts,loodrechtopdekijkrichting, -Naarbovenofnaarbeneden,loodrechtopdekijkrichting, -Indekijkrichting,ofomgekeerd. Deeersteviersoortenbewegingenkunnenwordengemaaktdoor middelvanklikkenopdepijlenvanhetwindow,delaatste tweedoormiddelvanklikkenopdevertikalescrollbar(boven deslider:beweeginkijkrichting,onderdeslider:beweeg terug).Klikkenopdehorizontalescrollbarheeftgeeneffect opdeobservator,maargenereertwleenniewetekening.Dit kansomshandigzijnalsvaneenbestaandetekeningeenHLR versiegemaaktmoetworden(zieverder). Deafstandwaaroverdeobservatorelkekeerbewogenwordt,kan wordeningesteldmet"Setviewparameters..."(zieverder). Viewparameters. Inhetinvulformulieronder"Setviewparameters..."kunnende positievandeobservatoreneenpuntindekijkrichting directingegevenworden.Hiermeeishetmogelijkominn keereendrastischeveranderingvanpositieenkijkrichtingte bewerkstelligen. Metditformulierkunnenookwordengewijzigd: -dezoomfactor:eenvergrotingsfactorvanhetgetoondebeeld, -destapgroottewaarmeemetdepijlenendescrollbars bewogenkanworden(zievorigealinea). Aangezienhetgenererenvaneennieuwetekeningsomsenige tijdkanduren(zekermethiddenlineremoval),ishet volgendenuttigomteweten:  IndienmetOKhetformulierwordtverlaten,wordtgeennieuwe tekeninggegenereerdindiendepositiesvandeobservatorof hetbekekenpuntnietechtzijnveranderd.  4)Hiddenlineremoval. Hetismogelijkom,zodraeennieuwetekeningwordt gegenereerd,dedoorvlakkenverborgendelenvanhetobject uitdetekeningtelatenverwijderen(hiddenlineremoval). Ditkangebeurendoorinmenumettitel"HLR"hetmenuitem "Hiddenlineremovalon"vaneenvink(checkmark)te voorzien.Aangezienhiddenlineremovaloverhetalgemeeneen tijdrovendkarweiis,wordthiddenlineremovalautomatisch uitgezetnadeeerstvolgendegeneratievaneentekening.Om dittevoorkomenmoetmen"AutomaticHLRreset"uitzetten (onderzelfdemenutitel);hiddenlineremovalblijftdanaan totdathetexplicietwordtuitgezet.  Hiddenlineremovalwordtbewerkstelligddooreennieuwe projectie(tekening)tegenererenmetextrainformatieoverde aanwezigevlakken(ditwordtnormaaluittijdsbesparings oogpuntachterwegegelaten).Daarnawordtelkindetekening aanweziglijnstukafzonderlijkwordtafgedektdoordeze vlakken.Hetafdekkingsproceswordtzichtbaargemaaktdooreen lijntellertelatenlopenbovenaanhetscherm.Pasnaafloop wordtdenieuwetekeningookwerkelijkuitgetekend. Note: Degebruiktemethodeisoverhetalgemeentragerdanhetook welgebruikte"paintersalgorithme",datdeinhetobject aanwezigevlakkenvan"voornaarachter"uittekentopeen devicewaaropmenkan"verven"(bvdemonitor).Afgedekte delenwordenzo"overgeverfd"doorhetvlakdatzeafdekt.Dit algorithmeishierechternietgebruikt,omdatdriedimookeen plottermoetkunnenaansturen.Enplotterskunnenniet verven.. 5)Picturemode: Somsishetnodigeengegenereerdetekeningnogwataante passenalvorenshemuitteprinten,zonderspeciaaleennieuwe tekeningaantemaken.Bijvoorbeeldomeenstukjevande tekeningvergroottebekijken.Ditismogelijkindezgn. "Picturemode",ondermenutitel"Viewparms".Indepicture modeishetideevaneenobservatorindeDriedimwereld tijdelijkverlaten,enschuiftdegegenereerdetekeningachter hetwindowheenenweer.Defunctievandevolgendewindow attributenisveranderd: -Arrows:Schuivenhetwindow1/10evanzijngrootteinde aangegevenrichting. -Scrollbars:Schuivenhetwindow1/1evanzijngrootteinde aangegevenrichting.Menkanzobv.tweenaastliggende stukkenuitprintenm.b.v."Printscreen",enaanelkaar plakken. -Sliders:Hiermeekanhetwindoweenvariabelstukverschoven worden(eenpixelafstand,gelijkaandeuitwijkingvande slider). -Mousecursor:Hiermeekaneenaangewezenpuntvande tekeninggecentreerdworden. 6)Diversen: Devolgendeitemskanmennogonderdeverschillendemenu titelstegenkomen: -Printscreen:Stuurteenscreendumpnaardeprinter;muis cursorwordtuitgeschakeld.  -Outputplotfile:Vraagteenfilenaamvooreeneenaante makenplotfile(weigertnaamvanbestaandefile)(aanbevolen extensie:".LNS").Genereertdaneentextfile,bestaandeuit coordinatenvanbegin-eneindpuntvanelklijnstukinde huidigetekening,inhetvolgendeformat: {XbYbXeYe} Xb,Yb,Xe,Ye:INTEGER; Metelklijnstukindetekeningcorrespondeerteenregelin deplotfilebestaandeuitx-enycoordinatenvanbegin-en eindpuntvanhetlijnstuk,ineencoordinatenstelselmet hetmiddelpuntvanhetkijkwindowalsoorsprongeneenheid 1/10pixel.Dusalshetkijkwindowinhetmiddenvanhet schermstaat,heeftdelinkerbovenhoekvanhetscherm coordinaten(-3200,2000)inditstelsel(inhigh resolution). -Deleteplotfile:Hiermeekunnenfilesvanschijfverwijderd worden.  -Full/NormalView:InFullviewmodewordtdetekening opgeblazentotmaximalegrootte;allewindowattributen wordenverwijderd.Normalviewhersteltdeoudesituatie. -Crosshair:Toonteenpaarkruisdraden,diedekijkrichting aanwijzen. 7)DeDrieDimsource. DeobjectbeschrijvingenvoorDriedimzijnprogramma'sineen eenvoudigebeschrijvingstaal,dieindezesectiegedefinieerd zalworden.DesyntaxwordtgegeveninEBNF(ExtendedBackus NaurForm,ziebv.[1]).Desemantiekwordterinformeelbij verteld: -EenobjectbeschrijvingiseenDDDProgramindevolgende zin: DDDProgram=[SizeDirective";"]Object. -EenSizeDirectivedientomeenwerkgeheugenvaneenbepaalde groottevoordevolgendesessieteclaimen.Deeenheidis kilobyte,endefaultis100:  SizeDirective="HEAPSIZE"HeapSize. HeapSize=Integer. -EenObjectiseenstructuur,diebestaatuiteenaantal onderdelen(de"Parts",zieverder).Hetistoegestaan lokaalhulpobjectentedefinieren,dieverderin DeclarationsenPartsgebruiktmogenworden(maarniet buitendeobjectdefinitiewaarinzegedefinieerdworden). Zgn."forwardreferences"zijnniettoegestaan(vgl.de scopevanproceduresinPASCALprogramma's):  Object="OBJECT"Identifier"=" [Declarations] Parts "OBEND". Declarations={Object";"}. Parts=Part{";"Part}. -Objectsmogenbestaanuit: a)Andereobjecten, b)Lijnen, c)Vlakken:  Part=ObjectPart |LinePart |PlanePart. -Eenanderobject,datgebruiktwordtalsdeelvaneenobject mageerstnogwatgetransformeerdworden.Toegestaanzijn: a)Translatieovereenbepaaldevectortr,door"ATtr", b)Vermenigvuldiginginx-y-en/ofzrichtingmetfactoren respfx,fyenfz,door"TIMESfxfyfz", c)Rotatieomdez-asovereenhoekang(ingraden)tegende wijzersvandeklok,vandepositievez-richtinggezien, door"TURNang":  ObjectPart=Identifier ["AT"Point] ["TIMES"Point] ["TURN"Angle]. -EenLinePartiseenpolylijn,eenaantalverbonden lijnsegmenten(minimaal1).Dezewordtgespecificeerddoor deknikpunten(waaronderbegrependebegin-eneindpunten) involgordeoptesommen: LinePart="LINE" Point","Point {","Point} "ENDLINE". -Eenpolygonwordtgespecificeerddoordecontour(als polylijn).Voorlokalehiddenlineremovalkneenvlakvan eenonzichtbarekantwordenvoorziendooreenwillekeurig puntaandezeonzichtbarekantalsInternPointoptegeven: hetvlakisdanonzichtbaarvoorobservatorsdieaan dezelfdekantvanhetvlakstaan.Opdezewordtopeen redelijkgoedkopemaniereendeelvanhetwerkvande tijdrovendechtehiddenlineremovalverricht.Zieookhet voorbeeldinAppendixA. PlanePart="PLANE" ["INTERN"InternPoint","] Point","Point","Point {","Point} "ENDPLANE". InternPoint=Point. Point=XValYValZVal. Angle:Real. XVal,YVal,ZVal:Real. Note:Commentaarmoetwordengemarkeerdmetaccolades,enis nietrecursief.  8)Opmerkingen. -DriedimisgeheelgeschreveninMODULA-2.Hoewelverwacht wordtdatsommigeroutinesinassemblysnellerzullenwerken (speciaalalswordtgewerktmetintegerrepresentatievan reals),isditnietgedaan.Teneerstehoudtdithet programmanogenigzinsnaspeurbaarententweedeworden zekergeenordessnelheidswinstverwacht. -Erwordtnietgecontroleerdopheapoverflow.Zorgdusvoor voldoendewerkruimte(met"HEAPSIZE"). -WaarschijnlijkdoorafrondingsfoutenwerktHLRniethelemaal alsverwacht.Hierdoorkanincidenteeleenlijnsegment wegvallen. -Driedimispublicdomainsoftwareenmagvrijworden verspreid,opvoorwaardedatdezenietwordtveranderd zondercontactoptenemenmetondergetekende.  -Graagzouikhorenvan(positieveofnegatieve)ervaringen: JuulvanderSpek, deKreyenbeek257, 5553BGValkenswaard, (Mei1986). References: [1]ProgramminginMODULA-2, NiklausWirth, SpringerVerlag. AppendixA:Eenvoorbeeld. Hetvolgendetoontalsvoorbeeldeenbeschrijvingvaneen blokkenwereld: OBJECTblokkenwereld= OBJECTblok={eenheidskubusmetmidden} {vangrondvlakinO}  OBJECTwand={eenheidsvierkantopx=1} PLANE{fungeertalszijvlak} INTERN000,{nietzichtbaar} 10.50,{vanuitoorsprong} 10.51, 1-0.51, 1-0.50, 10.50 ENDPLANE OBEND{wand};  wand; wandTURN90; wandTURN180; wandTURN270;  PLANE{bovenvlak} INTERN000, -0.5-0.51, -0.50.51, 0.50.51, 0.5-0.51, -0.5-0.51 ENDPLANE OBEND{blok;eindescopevanwand};  blokTIMES12100;{eenhlehoge} blokAT101010{eengeroteerde} TURN45; blokAT100010000{eneenverre} OBEND{blokkenwereld}  .  t..  tBADCEL PLT t OMPLEX1PLT t 8OBJECT PLT t (FLAT PLT t *9#KAART PLT t 3 KUBUS PLT t vLPL1 PLT t wtLPL2 PLT t xtPLANES PLT t yobject badcel= object blok = object zijvlak= plane intern 0 0 0, .5 .5 0, .5 .5 1, .5 -.5 1, .5 -.5 0, .5 .5 0 endplane obend; plane intern 0 0 0, .5 .5 1, .5 -.5 1, -.5 -.5 1, -.5 .5 1, .5 .5 1 endplane; zijvlak; zijvlak turn 90; zijvlak turn 180; zijvlak turn 270 obend; blok times 25 2 24 at .5 11 0; blok times 2 22 19.5 at 12 -0.5 0; blok times 2 8 19.5 at -3 6 0; blok times 8 2 19.5 at 7 -1 0 obend ` N[3][Modula-2 Run Time Error : | | #][OK]Modula-2/ST (c) Copyright TDI Software Ltd. 1985. The team : Chris 'how tacky' Hall, Paul 'where's the cursor' Curtis, and Phil 'boot you @#$%' Camp !!. _b ШNYN"pNGNuNV*x ڄ=E*P-E@-M-VNh-H:. Eg :. Ef-n*.P-ENH:. Ef Nh-hN2:. Ef BBN:. E e Nh-PN-n I8B,)n9n)n )n)n)n|.n 9/@>,VNhYN`NsN^NuNVBn ncN:.EIBtP ndRn`I* -EI* -EI* -EI* -EI* -Ez-E=| Bn=|BnBn <I* "NB=|4=|=|=|Bn=|(mI* -E <I* "NB=|Bn=|BnBn <I* "NBpL?NAN^NuNV/-+NIGz+WBn:.IJ4PgRn`=y:. E d:.I0PN(z0x8.  HDE:.IPRnz0x8. HDE:.IPRnI2GzWBn:.I8.nGP@Rn:.IJ4Pg`N+_N^Nu OAbrpNGNurpNGNV-|*.f *. drpNG-n nBBB!.B"H$!.!.@ .PPB! 4"n "N^NuNFNuF'/NNn-/=-/H"Q ,IL?/^>/^Nf,oNsNENuF'/NNn-/=-/H"Q G*- =/^Nf,oNs/NNn-/=/-/H _"h$",HL?/^>/^Nf,oNsF'SSfWWNsSf>NsSfF NsSfNqNsSf NNsNhBBB!<B*H$C! ` <L?NAN`WNs*x b "T@NGNuNNuNVH|".$. &(*HDHEHABBمCمHABBBCHBHCԃԄ-A -BL>N^NuNVHx". $.bBCh8BAHA62HC6BAHA`B6HCBAHA8<㑲eRCQ-C -ALN^NuNVH".$. &(*,BHDHEHABهCهHABBBCHBHCԃԄHEJjJj-A -BLN^Nu |Jj DaD NuJ jD ND DNuNNVH(. ,. dF<gBEVBBGVB0G|b.f ؆dRE`kgb|HDkSEjؼdREBJfBEJEnB`|mpN-D LN^Nu |oNNVH(. ,..HD:|glM||HF>|gXO||G|~mF H@HFB@H@2Ё"HAHFЁHD؀kSEؼdREJEk|m pNB` -D LN^NuNVH(. ,..BGg^<BEgV<✚G|HF⌈0BDHD8 H@∀HDkSEؼdREJEk|m pNB` -D LN^NuNVH . $j ļfB".$j ļfBLN^NuNVH .$ļfBJLN^NuNVH .g*2<bH@|bQAU-@LN^NuNVH .j g` BA<☒|lB`|DAlpN⨰b-@LN^NuNVpNN^NuNVpNN^NuNVpNN^NuNVpNN^NuNVpNN^NuNVpNN^NuNVpNN^NuNVpNN^NuF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsNVN^NuNV/??<NMN^NuNqNqNq O h*# ( ШШ//??<JNA *< z rN *< rN *< rN *< rN *< rN *<$ r'N *<n r&N *< r%N #pNG?<1Hy8N \?<BHykN \?<"HyN \N 2NVIl89n9n 9n 9n <I6* "NB3=yN^NuNV3 v3xN^NuNV3 v3 x3zN^NuNV3v3 x3 z3|N^NuNV3v3x3z3|3~3 3 3N^NuNV(n 8(n8N^NuNV(n8(n8(n 8(n8N^NuN NVINB BBBBI6Gl* (GN* )EGv* )EG* )E G* )EG* )EN^N4NVBg?< Bg?<BgBgN O =_N^NuNV?.?. N 8X#Bg?< ?<?<?<BgN O 3N^NuNV?.?. N 8X#Bg?< ?<?<?<BgN O 3N^NuNV(n* #Bg?< Bg?<?<BgN O =_N^NuNV?. ?.N 8X# Bg?<?<?<?<BgN O 3N^NuNV3v# Bg?<?<?<?<BgN O 3N^NuNVBg?<Bg?<BgBgN O 3N^NuN ,NVN^NnNV0.?NA*-E N^NuNV0.?0. ?NA*-E N^NuNV ./ . /0.?0.?NA*-EN^NuNV ./ . / ./0.?0.?NA*-EN^NuNV ./0. ?NA*-EN^NuNV0.? . /0.?NA*-EN^NuNV0.?0. ? . /0.?NA*-EN^NuNVBBgN@T-_N^NuNVB?<N@T*(nN^NuNVB?<N@T-_*.(n *.x(nN^NuNVB?<z.?NVX-_N^NuNVB?<N@T*(nN^NuNVB?<z.?NVX-_N^NuNVB?<z.?NVX-_N^NuNVJ.fB?<?<NVX*(n N(n B?<BgNVX*EN^NuNVB?<N@T*(nN^NuNVB?<N@T-_*.(n *.x(nN^NuNVB?<N@T*(nN^NuNVB?< (n* /N\-_N^NuNVB?< (n* /N\-_N^NuNVB?< N@TJf B.N^NuN |N^NuNVB?<?. NVX(n(N^NuNVB?<N@TJf B.N^NuN |N^NuNVB?<N@TJf B.N^NuN |N^NuNVB?<N@TJf B.N^NuN |N^NuNVB?<N@TJf B.N^NuN |N^NuNVB?<N@T*(n8N^NuNVB?</.N\-_N^NuNVB?<*N@T*(n8N^NuNVB?<+?.NVX-_N^NuNVB?<,N@T*(n8N^NuNVB?<-?.NVX-_N^NuNVB?</N@T(n(N^NuNVB?<0N@T*(n8N^NuNVB?<1/. ?.NP-_N^NuNVB?<6(n * /?.NP-_N^NuNVB?<9(n* /N\Jf|N^NuN B.N^NuNVB?<:(n* /N\Jf|N^NuN B.N^NuNVB?<;(n* /N\Jf|N^NuN B.N^NuNVB?<<(n* /?. NP*(n8N^NuNVB?<=(n* /?. NP*(n8N^NuNVB?<>?.NVXJf| N^NuN B. N^NuNVB?<??.(n //.NrO (n (N^NuNVB?<@?.(n //.NrO (n (N^NuNVB?<A(n* /N\Jf|N^NuN B.N^NuNVB?<B/.?.z. ?NO (n(N^NuNVJ. f*B?<C(n* /?<(n?NO -_N*B?<C(n* /Bg(n?NO *(n8N^NuNVB?<G(n * /?.NP-_N^NuNVB?<H/. N\(n(N^NuNVB?<I/.N\Jf| N^NuN B. N^NuNVB?<JBg/. /.NrO Jf|N^NuN B.N^NuNVB?<Kz.?(n* /(n* /(n * /NO*(n8N^NuNVB?<LN@TJf| N^NuN B. N^NuNVB?<N(n* /?. NP*(n8N^NuNVB?<ON@T*(n8N^NuNVB?<VBg(n* /(n* /NrO -_N^NuNVJ.f&B?<WI * /?.BgNO -_N&B?<WI * /?.?<NO -_N^NuN.NVN^NNVps"9NBN^NuNV333 3 3N^NuNhNVI* #I* #I* #I* #I* #####I* #N^N"vNV?<BgBg?<?.NO Nz(n 8(n8N^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?< ?.NO NzN^NuNV?<BgBg?< ?.NO NzN^NuNV?<Bg?<?< ?. NO 3 3NzN^NuNV3 By:9yn:9(nJ4PfN,:9(nx4P:9EI9PRy`JyfN^Nu?<Bg?9?< ?.NO NzN^NuNV?<BgBg?< ?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO Nz(n 8(n8N^NuNV?<BgBg?<?.NO Nz=y N^NuNV?<BgBg?<?.NO NzN^NuNV?<?<Bg?<?. NO 3 3NzN^NuNV?<BgBg?<?.NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV nCpQBy yoN4:9EI89DG7P@ ylRy`?<?<Bg?<?. NO NzN^NuNV?<BgBg?<?.NO NzN^NuNV333By:9yn:9(nJ4PfN.:9(nx4PzyEI9PRy`JyfN^Nu:9TEEIBtP?<?. zy??<?.NO NzN^NuNV3?<Bg?<?<z3<|3:~38363432303.3,3*3(3"3 #$Bg?<?<?<?<BgN O =_(nHT(nHT(nHT(nHTN O(n 8(n8=nDN^NuNV?. ?.N 8XBg?<?<?<BgBgN O =_ N^NuN)NVN^N8pNNV/.N 0Xf B N^NuN,/.N 0Xl-| N^NuN-|? N^NupNpNNVJnf Bn N^NuN Jnl=| N^NuN =| N^NupNpNNV/.N 0Xf Bn N^NuN(/.N 0Xl=| N^NuN =| N^NupNpNNVJnf B N^NuN$Jnl-| N^NuN-|? N^NupNpNNV/./.NX-_BBBn:. ?0.WcN\-n:.K E(n/./.NX/.NX/4PNX-_-n-n0.WdRn`T/./.NX-_N^NupNpNNV/./N-O /.NX-_/.//./[NX-_ N^NupNpNNV/. N 0Xf BN^NuN/.N 0Xf -|?N^NuB/. N4X-_/.N *=E/.*/NPm/./NPl././<@NX-_/./<@NPX-_`/./NX-_N&/NX-_/./.NPX/.NX/<@NPX-_/./.NPX/.NX/<@NPX-_/./.NX-_ N^NupNN,jpNNV#e#5  #8#;c# #?]#0#3ef"#5e@`2*#:.#<2#>~6#?~:#2>#0B#F#39J#3N#66uR#[V#8Z#5 7^#;sb#Xdf#?aj#n#1 r#v#3z#~#6pob#ې#91#]#<C##?n#N^N@pNNV-n-|@-|@@-n/./.NX-_/./.NX-_/./.NPX*/./NX-_/./LLEXMOD DEF t 7LPARSER DEF t =MKLINES DEF t OBJECTS DEF t /SINCOS DEF t UVECTORS DEF t DEFINITION MODULE DDHelp; (*****************************************************) (* *) (* DDHELP version 2.1 *) (* ------------------ *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines a few procedures, used in *) (* main program DRIEDIM (which handles the user *) (* interface) *) (* This main program became too big for *) (* the compiler, that's why it was divided into *) (* four parts: GLOBALS, DDHELP, DRAWPROJ and DRIEDIM *) (* *) (*****************************************************) FROM Objects IMPORT PartList; FROM Vectors IMPORT Point; FROM Globals IMPORT ObArray; TYPE FillFormResult= (* result type for procedure fillform *) (NewCoords, NewZoom, Canceled, NewStep, Nothing); PROCEDURE scale(slided, max: INTEGER): INTEGER; PROCEDURE member(el, set: INTEGER): BOOLEAN; PROCEDURE CheckItem(item: INTEGER; VAR b: BOOLEAN); PROCEDURE SetMenuText(item: INTEGER; VAR str: ARRAY OF CHAR); PROCEDURE SwitchFullView(VAR fullview: BOOLEAN); PROCEDURE FillForm( (* data to be filled in *) VAR Observer, ObPoint: Point; VAR Zoom, TransStep : REAL): FillFormResult; PROCEDURE ReadForm(VAR Observer, ObPoint: Point; VAR Zoom, TransStep : REAL ); PROCEDURE PutForm(Observer, ObPoint: Point; Zoom, TransStep : REAL ); PROCEDURE DoDial(form: ObArray; ftext: INTEGER): INTEGER; PROCEDURE DrawCross(x,y,w,h: INTEGER); END DDHelp. DEFINITION MODULE DrawProj; (*****************************************************) (* *) (* DRAWPROJ version 2.1 *) (* -------------------- *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines a few procedures, used in *) (* main program DRIEDIM (which handles the user *) (* interface). *) (* This main program became too big for *) (* the compiler, that's why it was divided into *) (* four parts: GLOBALS, DDHELP, DRAWPROJ and DRIEDIM *) (* *) (*****************************************************) FROM Objects IMPORT LineList; FROM Vectors IMPORT Point; PROCEDURE DrawWindow(Proj : LineList; (* description of projection *) dirtyX,dirtyY, dirtyW,dirtyH : INTEGER; (* XYWH of area to redraw *) Zoom : REAL; (* Multiplication factor *) Window : INTEGER; (* Window ID *) dx, dy : INTEGER; (* translation of picture *) Cross : BOOLEAN); (* Crosshair on? *) (********************************) (* Draws window with 3D picture *) (********************************) PROCEDURE NewView(Observer, ObPoint: Point; VAR Proj: LineList; VAR HLR : BOOLEAN; ResetFlg: BOOLEAN); (*********************************************) (* Deallocate old projection and compute new *) (* remove hidden lines when HLR is TRUE and *) (* reset HLR when ResetFlg is TRUE *) (*********************************************) END DrawProj. DEFINITION MODULE Globals; (*****************************************************) (* *) (* GLOBALS version 2.1 *) (* ------------------- *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines all *) (* global constants, types and variables of *) (* main program DRIEDIM (which handles the user *) (* interface), along with some procedures. *) (* This main program became too big for *) (* the compiler, that's why it was divided into *) (* four parts: GLOBALS, DDHELP, DRAWPROJ and DRIEDIM *) (* *) (*****************************************************) FROM Objects IMPORT PartList; CONST (* constants, naming elements of nodes in various resources *) (* in DRIEDIM.RSC, which was constructed using the resource *) (* construction set. The next is the included file DRIEDIM.I *) MENU = 0; (* TREE *) FORM = 1; (* TREE *) ABOUT = 2; (* TREE *) ZEROVIEW = 0; (* STRING *) ZEROZOOM = 1; (* STRING *) UNKNFILE = 2; (* STRING *) SYNTXERR = 3; (* STRING *) NOMEMORY = 4; (* STRING *) DISKFULL = 5; (* STRING *) FILEXIST = 6; (* STRING *) CANTOPEN = 7; (* STRING *) READONLY = 8; (* STRING *) OBSX = 6; (* OBJECT in TREE #1 *) OBSY = 7; (* OBJECT in TREE #1 *) OBSZ = 8; (* OBJECT in TREE #1 *) LOOKX = 9; (* OBJECT in TREE #1 *) LOOKY = 10; (* OBJECT in TREE #1 *) LOOKZ = 11; (* OBJECT in TREE #1 *) ZOOM = 14; (* OBJECT in TREE #1 *) DTRANS = 15; (* OBJECT in TREE #1 *) FORMOK = 5; (* OBJECT in TREE #1 *) FORMCAN = 16; (* OBJECT in TREE #1 *) ABOUTDD = 10; (* OBJECT in TREE #0 *) VIEWPIC = 24; (* OBJECT in TREE #0 *) SETPARMS = 25; (* OBJECT in TREE #0 *) RESETFLG = 29; (* OBJECT in TREE #0 *) HLRFLG = 28; (* OBJECT in TREE #0 *) FULLVIEW = 26; (* OBJECT in TREE #0 *) CROSSFLG = 32; (* OBJECT in TREE #0 *) PRINTSCR = 31; (* OBJECT in TREE #0 *) QUITDD = 20; (* OBJECT in TREE #0 *) PLOTFILE = 19; (* OBJECT in TREE #0 *) DELPLOTF = 22; (* OBJECT in TREE #0 *) TYPE Strng = ARRAY [0 .. 80] OF CHAR; TedInfo= RECORD (* See AES Programmers Guide pag 6.5 *) text : POINTER TO Strng; tmpl : POINTER TO Strng; valid: POINTER TO Strng; font : CARDINAL; rsrv1: CARDINAL; just : CARDINAL; color: CARDINAL; rsrv2: CARDINAL; thick: CARDINAL; len : CARDINAL; tmlen: CARDINAL; END; Object= RECORD (* See AES Programmers Guide pag 6.4 *) next : CARDINAL; head : CARDINAL; tail : CARDINAL; type : CARDINAL; flags: CARDINAL; state: CARDINAL; spec : POINTER TO TedInfo; obx : CARDINAL; oby : CARDINAL; width: CARDINAL; depth: CARDINAL; END; ObArray= (* Pointer to Tree Array; *) (* Number of object in tree x= *) (* index in x's array *) POINTER TO ARRAY [ 0 .. 200 ] OF Object; VAR (* Handles for Application, workstation and Windows used: *) ApId, Window1, Window2, handle: INTEGER; (* Identifiers for trees for the menubar, aboutbox *) (* and the viewparms form: *) MenuTree, FormTree, AboutTree: ObArray; (* Size of work area on desktop: *) WDesk, HDesk: INTEGER; (* Height of menubar: *) HMenuBar : INTEGER; (* Parts of observed object *) Parts : PartList; PROCEDURE AllocateStuff(VAR WindTitle: ARRAY OF CHAR): BOOLEAN; PROCEDURE DeAllocateStuff; PROCEDURE InitDrieDim(): BOOLEAN; PROCEDURE ChooseFile(VAR fil: ARRAY OF CHAR): BOOLEAN; PROCEDURE ShowAlert(Str: INTEGER): INTEGER; END Globals. DEFINITION MODULE LLexMod; (*****************************************************) (* *) (* DRIEDIM SCANNER V2.1 *) (* -------------------- *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines a lexical analyser for *) (* program DrieDim; a token type is defined, and *) (* routines to read and print elements of this type. *) (* *) (*****************************************************) FROM String IMPORT Strings; TYPE LTokenId= (* token types *) (* general tokens: *) (LStringTok, (* string *) LIntegerTok, (* integer *) LRealTok, (* real *) LIdenTok, (* identifier *) LEofTok, (* endmarker *) LErrTok, (* error *) (* special tokens: *) LDotTok, (* . *) LCommaTok, (* , *) LSemicolTok, (* ; *) LEqualTok, (* = *) (* reserved words: *) LHeapSizeTok, (* HEAPSIZE *) LObjectTok, (* OBJECT *) LObendTok, (* OBEND *) LLineTok, (* LINE *) LLineEndTok, (* ENDLINE *) LPlaneTok, (* PLANE *) LPlaneEndTok, (* ENDPLANE *) LAtTok, (* AT *) LTurnTok, (* TURN *) LTimesTok, (* TIMES *) LInternTok (* INTERN *) ); LIdenNr = CARDINAL; Str = RECORD Base, Len: CARDINAL END; LToken = RECORD (* attributed lexical token *) CASE Sel: LTokenId OF LStringTok : StringVal : Str | LIntegerTok : IntegerVal: INTEGER | LRealTok : RealVal : REAL | LIdenTok : IdenVal : LIdenNr | LErrTok : ErrVal : CHAR ELSE END END; VAR LineNr : CARDINAL; (* Current input line number *) LexError : BOOLEAN; (* Boolean to flag errors during reading of * strings and numbers *) PROCEDURE LMakeReal(VAR t: LToken); (********************************) (* Converts integer token to a *) (* real token with same value. *) (* PRE: t.Sel=LIntegerTok *) (********************************) PROCEDURE LLex(VAR Tok: LToken); (********************************) (* Reads one new token which is *) (* placed into Tok. *) (********************************) PROCEDURE LInitWarmLex(s: Strings): BOOLEAN; (******************************************) (* This procedure is used to initialise *) (* the lexical analyser with inputfile- *) (* name in s; Returns FALSE iff the file *) (* cannot be found. *) (******************************************) PROCEDURE LPrintToken(t: LToken); (**************************************) (* print representation of t *) (**************************************) END LLexMod. DEFINITION MODULE LParser; (*****************************************************) (* *) (* DRIEDIM PARSER V2.1 *) (* -------------------- *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines the parser for the Driedim *) (* Object definition language. *) (* *) (*****************************************************) FROM String IMPORT Strings; FROM Objects IMPORT PartList; PROCEDURE LInitWarmParser(s: Strings): BOOLEAN; (******************************************) (* Warm start of parser, with inputfile s *) (* returns FALSE iff s cannot be found *) (******************************************) PROCEDURE LParseError(): BOOLEAN; (*******************************) (* tests if error has occurred *) (*******************************) PROCEDURE ReadObject(): PartList; (*******************************************) (* Read an object, and return its partlist *) (*******************************************) PROCEDURE ReadHeapSize(): LONGCARD; (**********************************************) (* Parses '[ "HEAPSIZE" number ]' and returns *) (* the number, or 0 if none specified. *) (**********************************************) END LParser. DEFINITION MODULE MkLines; (*****************************************************) (* *) (* MKLINES V2.1 *) (* ------------ *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines procedures to generate a *) (* projection of a set of lines and planes; with *) (* or without hidden line removal. *) (* *) (*****************************************************) FROM Vectors IMPORT Point; FROM Objects IMPORT PartList, LineList; PROCEDURE MkProjection(obj : PartList; Observer, ObPoint: Point; HLR : BOOLEAN; VAR proj: LineList); (*********************************) (* Deallocates old projection *) (* and project all visible lines *) (* into returned projection. *) (* Hidden lines are removed when *) (* HLR is true. *) (*********************************) END MkLines. DEFINITION MODULE Objects; (*****************************************************) (* *) (* DRIEDIM OBJECTS V2.1 *) (* -------------------- *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines all kind of objects in which *) (* sets of lines and planes can be stored, along with*) (* routines to deal with them. *) (* *) (*****************************************************) FROM Vectors IMPORT Matrix, Point, PointList; FROM LLexMod IMPORT LIdenNr; TYPE PlotFileResult= (* result type of procedure PlotFile *) (DiskFull, FileExists, CantOpen, Prima); PartKind= (Line, Plane); (* Different kinds of parts *) (* objects are always expanded *) PartList= POINTER TO partlist; Part = RECORD CASE Sel: PartKind OF Line : line : PointList (* Points of line *) | Plane : plane: PointList; (* Points on plane *) int : Point (* Internal point *) END; END; partlist= RECORD Head: Part; Tail: PartList END; (* The following functions serve to set up an environment *) (* i.e. a function from identifiers to partlists *) Alist= POINTER TO alist; (* environment type *) EnvPair= RECORD Name : LIdenNr; Contents: PartList END; alist= RECORD Head: EnvPair; Tail: Alist END; (* (Lists of) line segments: *) LineList= POINTER TO linelist; LineSeg= RECORD p1,p2: Point END; linelist= RECORD Head: LineSeg; Tail: LineList END; (* (Lists of) plane contours: *) PlaneList= POINTER TO planelist; plane = RECORD XMin,YMin, (* Defines rectangle, containing *) XMax,YMax: REAL; (* the planes' projection. *) Contour : LineList END; planelist= RECORD Head : plane; Tail : PlaneList END; PROCEDURE AddPart(VAR l: PartList; p: Part); (*********************************) (* Add next part to a Partlist *) (*********************************) PROCEDURE NextPart(VAR l: PartList; VAR p: Part): BOOLEAN; (*********************************) (* When l is not empty: *) (* set p to the head, and l to *) (* of the original list and *) (* return TRUE, *) (* else return false. *) (* Typical use: *) (* WHILE NextPart(l,p) DO *) (* S(p) END *) (*********************************) PROCEDURE TrPartList(l : PartList; Add : Point; Prod : Matrix ): PartList; (*************************************************) (* Transforms each part in l, and returns these *) (* points in a REVERSED list (according to l *) (*************************************************) PROCEDURE DeAllPartList(VAR l: PartList); (**********************) (* Deallocates list l *) (**********************) PROCEDURE AddEnv(VAR l: Alist; i: LIdenNr; p: PartList); (*********************************) (* Add a new pair to environment *) (*********************************) PROCEDURE Assoc(Env: Alist; i: LIdenNr): PartList; (***********************************) (* Get value of i from environment *) (***********************************) PROCEDURE DeAllPair(VAR l: Alist); (*******************************) (* Deallocates first pair of l *) (* and pops l *) (*******************************) PROCEDURE AddLine(VAR l: LineList; p1,p2: Point); (*********************************) (* Add new line segment (p1,p2) *) (* to linelist l *) (*********************************) PROCEDURE AppendLineList(VAR l1: LineList; l2: LineList); (*******************) (* Chains l2 to l1 *) (*******************) PROCEDURE CopyLineList(l: LineList): LineList; (********************) (* make a copy of l *) (********************) PROCEDURE DeAllLineList(VAR l: LineList); (***********************) (* deallocate linelist *) (***********************) PROCEDURE PlotFile(VAR FileName: ARRAY OF CHAR; dx, dy: INTEGER; Zoom : REAL; Proj : LineList): PlotFileResult; (******************************************************) (* Generate a textfile of name 'FileName', containing *) (* the coordinates of endpoints of all linesegments *) (* in proj. Procedure returns appropriate message *) (******************************************************) PROCEDURE PlotProjection(handle, midX, midY: INTEGER; scale: REAL; p: LineList); (****************************************) (* Plot lines in l to workstation *) (* "handle", with (midX,midY) as origin *) (* projection is multiplied by scale *) (****************************************) PROCEDURE AddPlane(VAR l: PlaneList; p: LineList); (*****************************) (* Add new plane (contour) *) (* to planelist l *) (*****************************) PROCEDURE DeAllPlaneList(VAR l: PlaneList); (************************) (* deallocate planelist *) (************************) END Objects. DEFINITION MODULE sincos; (*****************************************************) (* *) (* SINCOS *) (* ------ *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (*****************************************************) (* *) (* This module provides a correct sine and cosine *) (* implementation. *) (* *) (*****************************************************) PROCEDURE sin(x: REAL): REAL; PROCEDURE cos(x: REAL): REAL; END sincos. DEFINITION MODULE Vectors; (*****************************************************) (* *) (* VECTORS V2.1 *) (* ------------ *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module defines *) (* 1) 3D vectors, along with several vector *) (* functions (inproduct, rotation, outproduct) *) (* 2) Lists of vectors, along with routines to *) (* handle them. *) (* 3) Some Driedim specific vector functions. *) (* *) (*****************************************************) TYPE (* Driedimensional points, and lists of them: *) Point = RECORD x1,x2,x3: REAL END; Matrix = RECORD x11,x21,x12,x22,x33: REAL END; PointList = POINTER TO point; point= RECORD Head: Point; Tail: PointList END; (*************************************************) PROCEDURE NextPoint(VAR l: PointList; VAR p: Point) : BOOLEAN; (********************************) (* Tests if l is not empty list *) (* If so, then p is set to its *) (* head, and l to its tail *) (* Typical use: *) (* WHILE NextPoint(l,p) DO *) (* S(p) END; *) (********************************) PROCEDURE AddPoint (VAR l: PointList; p: Point); (********************) (* Adds p to list l *) (********************) PROCEDURE TrPointList(l : PointList; Add : Point; Prod : Matrix ): PointList; (*************************************************) (* Transforms each point in l, and returns these *) (* points in a REVERSED list (according to l *) (*************************************************) PROCEDURE DeAllPointList(VAR l: PointList); (**********************) (* Deallocates list l *) (**********************) (****************************************************) PROCEDURE ViewDirection(viewdir: Point); (***************************) (* Sets the view direction *) (***************************) PROCEDURE Transform(x : Point; Add : Point; Mult : Matrix; VAR y: Point); (**********************) (* y:= Add + Mult.x *) (**********************) PROCEDURE Visible(x: Point): BOOLEAN; (****************************************************) (* Is x visible for Observer when looking at Point? *) (* See ViewParms. *) (****************************************************) PROCEDURE Project(x: Point; VAR y: Point); (**********************************************) (* Project x onto a plane before the observer *) (* Result: x1 and x2: Coordinates in plane *) (* x3 : Distance x to Observer *) (**********************************************) PROCEDURE Add(x,y: Point; VAR z: Point); (********************************************) (* componentwise addition of x and y into z *) (********************************************) PROCEDURE Subtract(x,y: Point; VAR z: Point); (***********************************************) (* componentwise subtraction of x and y into z *) (***********************************************) PROCEDURE EqPoint(x,y: Point): BOOLEAN; (********) (* x=y? *) (********) PROCEDURE UitProd(x,y: Point; VAR z: Point); (***********************************) (* Outer product of x and y into z *) (***********************************) PROCEDURE InProd(x,y: Point): REAL; (********************************) (* Returns inproduct of x and y *) (********************************) PROCEDURE MatMult(M1,M2: Matrix; VAR M: Matrix); (********************************) (* M:= M1.M2 *) (********************************) PROCEDURE MatProd(M: Matrix; x: Point; VAR y: Point); (********************************) (* y:= M.x *) (********************************) PROCEDURE MoveHoriz(VAR Observer, ObPoint: Point; Step: REAL); (*************************************************) (* Move Step to the right (according to ViewDir) *) (*************************************************) PROCEDURE MoveUp(VAR Observer, ObPoint: Point; Step: REAL); (******************************************) (* Move Step up (according to ViewDir) *) (******************************************) PROCEDURE MoveFurther(VAR Observer, ObPoint: Point; Step: REAL); (**************************) (* Move Step into ViewDir *) (**************************) PROCEDURE Elevate(VAR Observer, ObPoint: Point; Angle: REAL); (*************************) (* Look Angle degrees up *) (*************************) PROCEDURE Rotate(VAR Observer, ObPoint: Point; Angle: REAL); (***********************************) (* Look Angle degrees to the right *) (***********************************) PROCEDURE LookAt(dx, dy: INTEGER; Zoom : REAL; VAR Observer, ObPoint: Point); (********************************************************) (* Set new view direction, such that points with old *) (* projection coordinates (dx, dy) are observed now.. *) (********************************************************) END Vectors. .   t..   tzDDHELP MOD t e)DRAWPROJMOD t sDRIEDIM MOD t LGLOBALS MOD% t W(LLEXMOD MOD( t Z5LPARSER MOD, t ;MKLINES MOD0 t POBJECTS MOD5 t (SINCOS MOD9 t  VECTORS MOD< t - IMPLEMENTATION MODULE DDHelp; (*****************************************************) (* *) (* DDHELP version 2.1 *) (* ------------------ *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module implements a few procedures, used in *) (* main program DRIEDIM (which handles the user *) (* interface). *) (* This main program became too big for *) (* the compiler, that's why it was divided into *) (* four parts: GLOBALS, DDHELP, DRAWPROJ and DRIEDIM *) (* *) (*****************************************************) FROM AESMenus IMPORT MenuText, MenuItemCheck; FROM AESForms IMPORT FormDo, FormCenter, FormDialogue; FROM AESObjects IMPORT ObjectDraw; FROM SYSTEM IMPORT ADR; FROM VDIOutputs IMPORT PolyLine; FROM GEMVDIbase IMPORT PxyArrayType; FROM GEMAESbase IMPORT MouseOn, MouseOff, Arrow, FormStart, FormGrow, FormShrink, FormFinish, CurrXYWH, FullXYWH, Selected; FROM AESGraphics IMPORT GrafMouse, GrafGrowBox, GrafShrinkBox; FROM AESWindows IMPORT WindowOpen, WindowGet, WindowSet, WindowClose, WindowUpdate; FROM M2Conversions IMPORT ConvertToReal, ConvertReal; FROM Vectors IMPORT Point, EqPoint; FROM Globals IMPORT MenuTree, FormTree, Window1, Window2, HMenuBar, WDesk, HDesk, handle, ObArray, Strng, ShowAlert, MENU, FORM, ZEROVIEW, ZEROZOOM, ABOUTDD, QUITDD, VIEWPIC, OBSX, OBSY, OBSZ, LOOKX, LOOKY, LOOKZ, ZOOM, DTRANS, FORMOK, FORMCAN, UNKNFILE, SYNTXERR, NOMEMORY, ABOUT, SETPARMS, RESETFLG, HLRFLG, FULLVIEW, CROSSFLG, PRINTSCR; PROCEDURE scale(slided, max: INTEGER): INTEGER; (* Desperately looking for MODULA-3, with *) (* automatic type transfer between *) (* different numeric types *) VAR cheat: RECORD CASE BOOLEAN OF TRUE : i1,i2,i3,i4: INTEGER| FALSE: l1,l2 : LONGCARD (* compiler bombs on *) END (* LONGINT multiplication *) END; BEGIN WITH cheat DO i1:= 0; i2:= slided; i3:= 0; i4:= max; l1:= (l1*l2) DIV 1000; RETURN i2 - (max DIV 2) END; END scale; PROCEDURE member(el, set: INTEGER): BOOLEAN; (*****************************************************) (* Why don't those GEM interfaces use proper sets??? *) (*****************************************************) BEGIN RETURN (set MOD (2*el)) > (el-1) END member; PROCEDURE SetMenuText(item: INTEGER; VAR str: ARRAY OF CHAR); (* Put text for menu item *) BEGIN MenuText(MenuTree, item, ADR(str) ); END SetMenuText; PROCEDURE CheckItem(item: INTEGER; VAR b: BOOLEAN); CONST Check = 1; NoCheck= 0; BEGIN b:= NOT b; IF b THEN MenuItemCheck(MenuTree,item,Check) ELSE MenuItemCheck(MenuTree,item,NoCheck) END; END CheckItem; PROCEDURE SwitchFullView(VAR fullview: BOOLEAN); (*******************************************) (* Procedure that switches windows 1 and 2 *) (* Note how menu text is changed. *) (*******************************************) CONST (* Menu texts for 'full view': *) FVText1= " Full view "; FVText2= " Normal view"; VAR (* Sizes for window1 and window2: *) x1,y1,w1,h1, x2,y2,w2,h2: INTEGER; BEGIN WindowGet(Window1, CurrXYWH, x1,y1,w1,h1); WindowGet(Window2, FullXYWH, x2,y2,w2,h2); IF fullview THEN (* Shrink box from w2 to w1, and close w2 *) SetMenuText( FULLVIEW, FVText1 ); GrafShrinkBox( x1,y1,w1,h1, x2,y2,w2,h2); WindowClose ( Window2 ); ELSE (* Grow box from w1 to w2's size, and open w2 *) SetMenuText( FULLVIEW, FVText2 ); GrafMouse(MouseOff, NIL); GrafGrowBox( x1,y1,w1,h1, x2,y2,w2,h2); WindowOpen(Window2, 0, HMenuBar, WDesk, HDesk); GrafMouse(MouseOn, NIL); END; fullview:= NOT fullview; END SwitchFullView; PROCEDURE FillForm( (* data to be filled in *) VAR Observer, ObPoint: Point; VAR Zoom, TransStep : REAL): FillFormResult; (******************************************************) (* Let user input data into FORM until correct data *) (* See also more general (and clearer) procedure *) (* DoDial (furtheron) *) (******************************************************) VAR begtext, (* Index of editable text to be *) (* started with at FormDo *) r,x,y,w,h : INTEGER; ok : BOOLEAN; (* Exit condition *) str : POINTER TO Strng; HObP,HObs : Point; (* To remember old values of *) HZoom,HTrS: REAL; (* view parameters. *) BEGIN (* Put view parameters into Tree FORM *) (* and store old values: *) PutForm (Observer, ObPoint, Zoom, TransStep); ReadForm(HObs, HObP, HZoom, HTrS); (* Compute x,y,w and h such that FORM *) (* will be placed into middle of screen *) (* Note: x,y,w,h are VAR parameters here *) FormCenter(FormTree, x,y,w,h); (* Reserve screen area for FORM *) FormDialogue( FormStart, 0,0,0,0, x,y,w,h ); (* Grow box for FORM *) FormDialogue( FormGrow, 0,0,0,0, x,y,w,h ); (* Set mouse back to an arrow: *) GrafMouse(Arrow, NIL); begtext:= DTRANS; REPEAT ok:= TRUE; (* Draw object FORM *) ObjectDraw ( FormTree, 0, 10, x,y,w,h ); (* Monitor user interactions in FORM *) r:= FormDo ( FormTree, begtext); (* Deselect exit button used (Ok or Cancel) *) WITH FormTree^[r] DO state:= state-Selected END; (* Read values into variables if Ok was selected *) IF r=FORMOK THEN ReadForm(Observer, ObPoint, Zoom, TransStep) END; (* Ask for new values on erroneous input *) IF Zoom=0.0 THEN (* Multiplication factor of zero is meaningless *) r:= ShowAlert(ZEROZOOM); begtext:= ZOOM; ok:= FALSE ELSIF EqPoint(Observer, ObPoint) THEN (* Undefined view direction *) r:= ShowAlert(ZEROVIEW); begtext:= OBSX; ok:= FALSE END; UNTIL ok; (* Until correct data *) (* Shrink form box *) FormDialogue( FormShrink, 0,0,0,0, x,y,w,h ); (* and free screen area used *) FormDialogue( FormFinish, 0,0,0,0, x,y,w,h ); IF r=FORMCAN THEN RETURN Canceled END; IF ( (NOT EqPoint(HObs,Observer)) OR (NOT EqPoint(HObP,ObPoint))) THEN RETURN NewCoords END; IF HZoom#Zoom THEN RETURN NewZoom END; IF HTrS#TransStep THEN RETURN NewStep END; RETURN Nothing END FillForm; PROCEDURE ReadForm(VAR Observer, ObPoint: Point; VAR Zoom, TransStep : REAL ); (*********************************************) (* Read all view parameters from object FORM *) (*********************************************) PROCEDURE GetValue(field: INTEGER): REAL; (* Read REAL from edited string 'field' in object FORM *) VAR b: BOOLEAN; r: REAL; BEGIN ConvertToReal(FormTree^[field].spec^.text^, b, r); RETURN r END GetValue; BEGIN WITH Observer DO x1:= GetValue(OBSX); x2:= GetValue(OBSY); x3:= GetValue(OBSZ); END; WITH ObPoint DO x1:= GetValue(LOOKX); x2:= GetValue(LOOKY); x3:= GetValue(LOOKZ); END; Zoom:= GetValue(ZOOM); TransStep:= GetValue(DTRANS); END ReadForm; PROCEDURE PutForm(Observer, ObPoint: Point; Zoom, TransStep : REAL ); (********************************************) (* Put all view parameters into object FORM *) (********************************************) PROCEDURE PutValue(field: INTEGER; val: REAL); (* Put string representation of val into field *) BEGIN ConvertReal(val, 6, 2, FormTree^[field].spec^.text^); END PutValue; BEGIN WITH Observer DO PutValue(OBSX, x1); PutValue(OBSY, x2); PutValue(OBSZ, x3); END; WITH ObPoint DO PutValue(LOOKX, x1); PutValue(LOOKY, x2); PutValue(LOOKZ, x3); END; PutValue(ZOOM, Zoom); PutValue(DTRANS, TransStep); END PutForm; PROCEDURE DoDial(form: ObArray; ftext: INTEGER): INTEGER; (******************************************************) (* Let user edit a dialogue box; see for explaination *) (* comments in FillForm *) (******************************************************) VAR r,x,y,w,h: INTEGER; BEGIN GrafMouse(Arrow, NIL); FormCenter(form, x,y,w,h); FormDialogue( FormStart, 0,0,0,0, x,y,w,h ); FormDialogue( FormGrow, 0,0,0,0, x,y,w,h ); ObjectDraw ( form, 0, 10, x,y,w,h ); r:= FormDo ( form, ftext); FormDialogue( FormShrink, 0,0,0,0, x,y,w,h ); FormDialogue( FormFinish, 0,0,0,0, x,y,w,h ); WITH form^[r] DO state:= state-Selected END; RETURN r END DoDial; PROCEDURE DrawCross(x,y,w,h: INTEGER); (* Plots cross in middle of rectangle *) TYPE Double= RECORD CASE BOOLEAN OF (* for omitting index computations *) TRUE : x1,x2,y1,y2: INTEGER | FALSE: array : PxyArrayType END END; VAR Buff : Double; mx, my: INTEGER; BEGIN mx:= x+ (w DIV 2); my:= y+ (h DIV 2); WITH Buff DO x1:= x; x2:= my; y1:= x+w; y2:= my; PolyLine(handle,2,array); x1:= mx; x2:= y; y1:= mx; y2:= y+h; PolyLine(handle,2,array); END; END DrawCross; END DDHelp. IMPLEMENTATION MODULE DrawProj; (*****************************************************) (* *) (* DRAWPROJ version 2.1 *) (* -------------------- *) (* *) (* Author: Juul v/d Spek, Valkenswaard. *) (* *) (* please do not alter this text without *) (* author's permission. *) (* *) (*****************************************************) (* *) (* This module implements a few procedures, used in *) (* main program DRIEDIM (which handles the user *) (* interface). *) (* This main program became too big for *) (* the compiler, that's why it was divided into *) (* four parts: GLOBALS, DDHELP, DRAWPROJ and DRIEDIM *) (* *) (*****************************************************) FROM GEMVDIbase IMPORT PxyArrayType; FROM VDIControls IMPORT SetClipping; FROM VDIOutputs IMPORT FillRectangle; FROM AESMenus IMPORT MenuBar, MenuTitleNormal; FROM GEMAESbase IMPORT MouseOn, MouseOff, HourGlass, Arrow, FirstXYWH, NextXYWH, FullXYWH, CurrXYWH, WorkXYWH, EndUpdate, BeginUpdate; FROM AESGraphics IMPORT GrafMouse; FROM AESWindows IMPORT WindowGet; FROM Objects IMPORT LineList, PlotProjection; FROM MkLines IMPORT MkProjection; FROM Vectors IMPORT Point; FROM DDHelp IMPORT DrawCross, CheckItem; FROM Globals IMPORT handle, MenuTree, Parts, HLRFLG; PROCEDURE DrawWindow(Proj : LineList; (* description of projection *) dirtyX,dirtyY, dirtyW,dirtyH : INTEGER; (* XYWH of area to redraw *) Zoom : REAL; (* Multiplication factor *) Window : INTEGER; (* Window ID *) dx, dy : INTEGER; (* translation of picture *) Cross : BOOLEAN); (* Crosshair on? *) (********************************) (* Draws window with 3D picture *) (********************************) CONST ClippingOff= 0; ClippingOn = 1; VAR midx, midy, X,Y,W,H, x,y,w,h: INTEGER; line: PxyArrayType; PROCEDURE Intersect(VAR x1,y1,w1,h1: INTEGER; x2,y2,w2,h2: INTEGER); (***********************************************) (* Intersects rectangle 1 against reactangle 2 *) (***********************************************) VAR xh1,xh2,yh1,yh2: INTEGER; BEGIN xh1:= x1+w1; xh2:= x2+w2; yh1:= y1+h1; yh2:= y2+h2; IF x2>x1 THEN x1 := x2 END; IF y2>y1 THEN y1 := y2 END; IF xh2