diff -rc2P 3DLDF-2.0.2/README 3DLDF-2.0.3/README *** 3DLDF-2.0.2/README Thu Nov 7 13:51:40 2013 --- 3DLDF-2.0.3/README Fri Dec 13 16:36:51 2013 *************** *** 50,54 **** * Downloading ! GNU 3DLDF 2.0 is available for downloading from the following servers using the protocols indicated (i.e., `ftp', `http', and `rsync'): --- 50,54 ---- * Downloading ! GNU 3DLDF 2.0.3 is available for downloading from the following servers using the protocols indicated (i.e., `ftp', `http', and `rsync'): *************** *** 60,64 **** * Mailing lists ! The following mailing lists are now available: help-3dldf@gnu.org --- For users to ask one another for help. --- 60,64 ---- * Mailing lists ! The following mailing lists are available: help-3dldf@gnu.org --- For users to ask one another for help. *************** *** 79,83 **** * Documentation ! See the directories 3DLDF-2.0/doc/ and 3DLDF-2.0/doc/old_doc. --- 79,83 ---- * Documentation ! See the directories 3DLDF-2.0.3/doc/ and 3DLDF-2.0.3/doc/old_doc. *************** *** 89,93 **** e.g.: ! cd /3DLDF-2.0 export LIBS="-lgsl -lgslcblas -lm" configure --prefix=`pwd` --- 89,93 ---- e.g.: ! cd /3DLDF-2.0.3 export LIBS="-lgsl -lgslcblas -lm" configure --prefix=`pwd` *************** *** 95,99 **** or ! cd /3DLDF-2.0 configure --prefix=`pwd` LIBS="-lgsl -lgslcblas -lm" --- 95,99 ---- or ! cd /3DLDF-2.0.3 configure --prefix=`pwd` LIBS="-lgsl -lgslcblas -lm" *************** *** 101,105 **** i.e., the top-level distribution directory. It is safe to do this. ! Alternatively, the shellscript `3DLDF-2.0/reconfig.sh' may be used to call `configure'. If `reconfig.sh' is invoked without any arguments, or if its first argument is 0, shared libraries will be built. Otherwise, they won't. --- 101,105 ---- i.e., the top-level distribution directory. It is safe to do this. ! Alternatively, the shellscript `3DLDF-2.0.3/reconfig.sh' may be used to call `configure'. If `reconfig.sh' is invoked without any arguments, or if its first argument is 0, shared libraries will be built. Otherwise, they won't. *************** *** 122,126 **** however, it must be specified. ! See the subdirectories `3DLDF-2.0/src/' and `3DLDF-2.0/examples/' for examples. %% Local Variables: --- 122,126 ---- however, it must be specified. ! See the subdirectories `3DLDF-2.0.3/src/' and `3DLDF-2.0.3/examples/' for examples. %% Local Variables: diff -rc2P 3DLDF-2.0.2/configure 3DLDF-2.0.3/configure *** 3DLDF-2.0.2/configure Sun Nov 10 18:30:12 2013 --- 3DLDF-2.0.3/configure Wed Dec 11 19:09:09 2013 *************** *** 1,5 **** #! /bin/sh # Guess values for system-dependent variables and create Makefiles. ! # Generated by GNU Autoconf 2.68 for GNU 3DLDF 2.0.2. # # Report bugs to . --- 1,5 ---- #! /bin/sh # Guess values for system-dependent variables and create Makefiles. ! # Generated by GNU Autoconf 2.68 for GNU 3DLDF 2.0.3. # # Report bugs to . *************** *** 571,576 **** PACKAGE_NAME='GNU 3DLDF' PACKAGE_TARNAME='3DLDF' ! PACKAGE_VERSION='2.0.2' ! PACKAGE_STRING='GNU 3DLDF 2.0.2' PACKAGE_BUGREPORT='Laurence.Finston@gmx.de' PACKAGE_URL='http://www.gnu.org/software/3DLDF/' --- 571,576 ---- PACKAGE_NAME='GNU 3DLDF' PACKAGE_TARNAME='3DLDF' ! PACKAGE_VERSION='2.0.3' ! PACKAGE_STRING='GNU 3DLDF 2.0.3' PACKAGE_BUGREPORT='Laurence.Finston@gmx.de' PACKAGE_URL='http://www.gnu.org/software/3DLDF/' *************** *** 1319,1323 **** # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF ! \`configure' configures GNU 3DLDF 2.0.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... --- 1319,1323 ---- # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF ! \`configure' configures GNU 3DLDF 2.0.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... *************** *** 1389,1393 **** if test -n "$ac_init_help"; then case $ac_init_help in ! short | recursive ) echo "Configuration of GNU 3DLDF 2.0.2:";; esac cat <<\_ACEOF --- 1389,1393 ---- if test -n "$ac_init_help"; then case $ac_init_help in ! short | recursive ) echo "Configuration of GNU 3DLDF 2.0.3:";; esac cat <<\_ACEOF *************** *** 1508,1512 **** if $ac_init_version; then cat <<\_ACEOF ! GNU 3DLDF configure 2.0.2 generated by GNU Autoconf 2.68 --- 1508,1512 ---- if $ac_init_version; then cat <<\_ACEOF ! GNU 3DLDF configure 2.0.3 generated by GNU Autoconf 2.68 *************** *** 2052,2056 **** running configure, to aid debugging if configure makes a mistake. ! It was created by GNU 3DLDF $as_me 2.0.2, which was generated by GNU Autoconf 2.68. Invocation command line was --- 2052,2056 ---- running configure, to aid debugging if configure makes a mistake. ! It was created by GNU 3DLDF $as_me 2.0.3, which was generated by GNU Autoconf 2.68. Invocation command line was *************** *** 2916,2920 **** # Define the identity of the package. PACKAGE='3DLDF' ! VERSION='2.0.2' --- 2916,2920 ---- # Define the identity of the package. PACKAGE='3DLDF' ! VERSION='2.0.3' *************** *** 17442,17446 **** # values after options handling. ac_log=" ! This file was extended by GNU 3DLDF $as_me 2.0.2, which was generated by GNU Autoconf 2.68. Invocation command line was --- 17442,17446 ---- # values after options handling. ac_log=" ! This file was extended by GNU 3DLDF $as_me 2.0.3, which was generated by GNU Autoconf 2.68. Invocation command line was *************** *** 17510,17514 **** ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ ! GNU 3DLDF config.status 2.0.2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" --- 17510,17514 ---- ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ ! GNU 3DLDF config.status 2.0.3 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -rc2P 3DLDF-2.0.2/configure.ac 3DLDF-2.0.3/configure.ac *** 3DLDF-2.0.2/configure.ac Sun Nov 10 18:30:05 2013 --- 3DLDF-2.0.3/configure.ac Wed Nov 13 13:43:43 2013 *************** *** 50,54 **** .# Process this file with autoconf to produce a configure script. ! AC_INIT([GNU 3DLDF], [2.0.2], [Laurence.Finston@gmx.de], [3DLDF]) AC_CONFIG_SRCDIR([src/main.web]) AM_INIT_AUTOMAKE --- 50,54 ---- .# Process this file with autoconf to produce a configure script. ! AC_INIT([GNU 3DLDF], [2.0.3], [Laurence.Finston@gmx.de], [3DLDF]) AC_CONFIG_SRCDIR([src/main.web]) AM_INIT_AUTOMAKE Binary files 3DLDF-2.0.2/doc/3dldf.dvi and 3DLDF-2.0.3/doc/3dldf.dvi differ diff -rc2P 3DLDF-2.0.2/doc/3dldf.html 3DLDF-2.0.3/doc/3dldf.html *** 3DLDF-2.0.2/doc/3dldf.html Wed Nov 6 17:51:37 2013 --- 3DLDF-2.0.3/doc/3dldf.html Fri Dec 13 16:56:52 2013 *************** *** 203,212 ****

This manual documents 3DLDF 2.0. The most important difference between release 2.0 and previous releases is that 3DLDF 2.0 is an interactive program, whereas in previous ! releases, 3DLDF was more like a library of C++ ! functions that users could use in their own programs to make drawings. !

Now, 3DLDF implements a language similar to the METAFONT ! language, and in particular the MetaPost language derived from it. --- 203,210 ----

This manual documents 3DLDF 2.0. The most important difference between release 2.0 and previous releases is that 3DLDF 2.0 is an interactive program, whereas in previous ! releases, 3DLDF was more like a library of C++ functions that users could use in their own programs to make drawings. !

Now, 3DLDF implements a language similar to the METAFONT language, and in particular the MetaPost language derived from it. *************** *** 416,420 ****

focus
Focus for the perspective projection. !
pen
dash_pattern
color --- 414,418 ----
focus
Focus for the perspective projection. !
pen
dash_pattern
color diff -rc2P 3DLDF-2.0.2/doc/3dldf.info 3DLDF-2.0.3/doc/3dldf.info *** 3DLDF-2.0.2/doc/3dldf.info Wed Nov 6 17:51:37 2013 --- 3DLDF-2.0.3/doc/3dldf.info Fri Dec 13 16:56:52 2013 *************** *** 96,104 **** release 2.0 and previous releases is that 3DLDF 2.0 is an "interactive" program, whereas in previous releases, 3DLDF was more like a "library" ! of C++ functions that users could use in their own programs to make drawings. ! Now, 3DLDF implements a "language" similar to the METAFONT ! language, and in particular the MetaPost language derived from it. For several years, interactive versions of 3DLDF have been available --- 96,104 ---- release 2.0 and previous releases is that 3DLDF 2.0 is an "interactive" program, whereas in previous releases, 3DLDF was more like a "library" ! of C++ functions that users could use in their own programs to make drawings. ! Now, 3DLDF implements a "language" similar to the METAFONT language, ! and in particular the MetaPost language derived from it. For several years, interactive versions of 3DLDF have been available *************** *** 1566,1579 **** Node: Top779 Node: Introduction1930 ! Node: Installation4116 ! Node: Invoking4236 ! Node: Getting Started5135 ! Node: Data Types5262 ! Node: FDL7144 ! Node: GPL32256 ! Node: Variable Index69789 ! Node: Data Type Index69929 ! Node: Function Index70082 ! Node: Concept Index70232  End Tag Table --- 1566,1579 ---- Node: Top779 Node: Introduction1930 ! Node: Installation4115 ! Node: Invoking4235 ! Node: Getting Started5134 ! Node: Data Types5261 ! Node: FDL7143 ! Node: GPL32255 ! Node: Variable Index69788 ! Node: Data Type Index69928 ! Node: Function Index70081 ! Node: Concept Index70231  End Tag Table Binary files 3DLDF-2.0.2/doc/3dldf.pdf and 3DLDF-2.0.3/doc/3dldf.pdf differ diff -rc2P 3DLDF-2.0.2/doc/3dldf.ps 3DLDF-2.0.3/doc/3dldf.ps *** 3DLDF-2.0.2/doc/3dldf.ps Wed Nov 6 17:51:37 2013 --- 3DLDF-2.0.3/doc/3dldf.ps Fri Dec 13 16:56:52 2013 *************** *** 2,6 **** %%Creator: dvips(k) 5.991 Copyright 2011 Radical Eye Software %%Title: 3dldf.dvi ! %%CreationDate: Wed Nov 6 18:51:36 2013 %%Pages: 34 %%PageOrder: Ascend --- 2,6 ---- %%Creator: dvips(k) 5.991 Copyright 2011 Radical Eye Software %%Title: 3dldf.dvi ! %%CreationDate: Fri Dec 13 17:56:52 2013 %%Pages: 34 %%PageOrder: Ascend *************** *** 13,17 **** %DVIPSCommandLine: dvips -o 3dldf.ps 3dldf.dvi %DVIPSParameters: dpi=600 ! %DVIPSSource: TeX output 2013.11.06:1851 %%BeginProcSet: tex.pro 0 0 %! --- 13,17 ---- %DVIPSCommandLine: dvips -o 3dldf.ps 3dldf.dvi %DVIPSParameters: dpi=600 ! %DVIPSSource: TeX output 2013.12.13:1756 %%BeginProcSet: tex.pro 0 0 %! *************** *** 1639,1668 **** {restore}if %%EndFont ! %%BeginFont: CMCSC10 ! %!PS-AdobeFont-1.0: CMCSC10 003.002 ! %%Title: CMCSC10 %Version: 003.002 %%CreationDate: Mon Jul 13 16:17:00 2009 %%Creator: David M. Jones %Copyright: Copyright (c) 1997, 2009 American Mathematical Society ! %Copyright: (), with Reserved Font Name CMCSC10. % This Font Software is licensed under the SIL Open Font License, Version 1.1. % This license is in the accompanying file OFL.txt, and is also % available with a FAQ at: http://scripts.sil.org/OFL. %%EndComments ! FontDirectory/CMCSC10 known{/CMCSC10 findfont dup/UniqueID known{dup ! /UniqueID get 5087402 eq exch/FontType get 1 eq and}{pop false}ifelse {save true}{false}ifelse}{false}ifelse 11 dict begin /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def ! /FontName /CMCSC10 def ! /FontBBox {14 -250 1077 750 }readonly def ! /UniqueID 5087402 def /PaintType 0 def ! /FontInfo 10 dict dup begin /version (003.002) readonly def ! /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMCSC10.) readonly def ! /FullName (CMCSC10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def --- 1639,1668 ---- {restore}if %%EndFont ! %%BeginFont: CMR10 ! %!PS-AdobeFont-1.0: CMR10 003.002 ! %%Title: CMR10 %Version: 003.002 %%CreationDate: Mon Jul 13 16:17:00 2009 %%Creator: David M. Jones %Copyright: Copyright (c) 1997, 2009 American Mathematical Society ! %Copyright: (), with Reserved Font Name CMR10. % This Font Software is licensed under the SIL Open Font License, Version 1.1. % This license is in the accompanying file OFL.txt, and is also % available with a FAQ at: http://scripts.sil.org/OFL. %%EndComments ! FontDirectory/CMR10 known{/CMR10 findfont dup/UniqueID known{dup ! /UniqueID get 5000793 eq exch/FontType get 1 eq and}{pop false}ifelse {save true}{false}ifelse}{false}ifelse 11 dict begin /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def ! /FontName /CMR10 def ! /FontBBox {-40 -250 1009 750 }readonly def ! /UniqueID 5000793 def /PaintType 0 def ! /FontInfo 9 dict dup begin /version (003.002) readonly def ! /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMR10.) readonly def ! /FullName (CMR10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def *************** *** 1671,2838 **** /UnderlinePosition -100 def /UnderlineThickness 50 def - /ascent 750 def end readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 97 /a put dup 99 /c put dup 105 /i put dup 115 /s put ! readonly def ! currentdict end ! currentfile eexec ! D9D66F633B846AB284BCF8B0411B772DE5CE3C05EF98F858322DCEA45E0874C5 ! 45D25FE192539D9CDA4BAA46D9C431465E6ABF4E4271F89EDED7F37BE4B31FB4 ! 7934F62D1F46E8671F6290D6FFF601D4937BF71C22D60FB800A15796421E3AA7 ! 72C500501D8B10C0093F6467C553250F7C27B2C3D893772614A846374A85BC4E ! BEC0B0A89C4C161C3956ECE25274B962C854E535F418279FE26D8F83E38C5C89 ! 974E9A224B3CBEF90A9277AF10E0C7CAC8DC11C41DC18B814A7682E5F0248674 ! 11453BC81C443407AF41AF8A831A85A700CFC65E2181BB89566A9BDEC70EB4F2 ! 048A6EB631F05C014D372103E37FC3FA317EBC9973565A638403DA02E48B7D31 ! CFF6C241DC5CDB470561002FF46437C06EF93BC99352DF04393C661FFFBF4BA2 ! 0723ABD9B3E9CA9E63BA57EFDBAE684655CBBDBA15ADAE43E1A2C98A3CF060A3 ! D16AF8FE3A49B50A24C20EEED716E49AF6013D4D38CD9CC41A91C17E4D04D79D ! 567E1EF49110AA9C34464E95D81A730ECEB2C9AF38FBA6B45E253288438B4CB3 ! DC75B3A906D4357293BA41E59C35223A6C9CBD6FF5FC90C2D07CBB376C7320FF ! 435A6251822BFCBB612CE630EDF826C37E95F541C21B93FCE127591D5E38165E ! 2B58A34AAE37712BC58B63FFD70AB80F4F24612CFD2F1466BAAF3CA2BCB45148 ! D0DEA0E9B8FBA4C4FF5B8B3CB02E461355051842BD1C94F41066B9B909DB83B1 ! DCDCBEF7CD00A43E4C0B8191A29600CA197F0BA227FB8309BB539D2A620BAC70 ! 8A1AB2DFA51ADC9873B8E5582DCD3ED154E5D727D1665F99BD89883D69E6CC2F ! DB3A57AEB612171A88E22F038461DE03FC357F771675E34E90D4D19B4B36891C ! 9D2333960400E97494F4FC4DBCE6A73C34A0409E433BBDC0AAAEBA7D3555066E ! 1CFBB4515C8B573C9B9DD12ED5B6ECEBE35AD0DDEA9DB004FC6CB540B5117B49 ! 59CABE5FD74C6F5B6482B42C20B5FF0467D1DBD7CED2CC651CA57852B6FBB402 ! A6764DB342889132C911CAA713A7F2FDD8A5E849345D6C81025E02F5B8B682BA ! 90CC9B467FBC37362436EA6BF8EB62D784B01D5430147945BC09D1F49EE89F2E ! 3E2B8E6D439248A56F82F2E03EA5C7A922F2813BE6538A3A423BEBC55B345AFB ! 3B3C125306749E137C647D78028AE1FBF3E1A82C260132832A9668F454D39C41 ! 736717DED0A99F6B11F005F0E1D07FE84713AAB4C042FDC166AA146D7B5E9198 ! E4F485BE5B135EA281FF1C1E616B5AAF02771F58C5840CB5A427FF9794F93E94 ! 17FD799C78AED1DC4810BCEF4C6C51D3C1504EA2C6F2B29805B7ECF97B5F637D ! FE92E168CB9029E90404CB54FB312FC7AA8A9F2F524C03E61F03B1E31D4F061E ! 1677B39D5D30C9FD4673E1723F4AE3CCF38593AD6D7F61E9DF3C010E51F25085 ! 35D51105E1464BA146A78D7297D4D310AD91342A0BB942034A3EC0696B467367 ! 3E39D202D637E6B14D0EBCA6AD3CF22B07D4CA69C0FCBB6C93782B2F0DFC5AC1 ! 5D8A16CB5EDB671A0C1BA9D10F63CEAFCD0E06E42C730C8EF769CCFD57937245 ! 658F486036D37E8BDDE5670A212FB488A8753322A5B170C9662750AA958C0BBD ! 8E97D8239D2A08B30416504DEEC4E506013E037C91785C674F8A6A44E23FEE6F ! CCC00CC5E4D355B0871FDB8ECD64F70EE32449BB5D6F84F8C8AA2D5B1A489BA9 ! D7FF2DBAA8D0B84054E93D64D3E77850A3724824914A0F821EEC3D605DD851A7 ! 606936B8B9E24D6E932E16C448140FE94DD96C75AECB73850035ED9C04A1D93C ! 64B21E7D4657E030483EC5C3554AEF8BE4D0FE5B9743B875340B09E01273DAE8 ! F256C50A1A8F2E0417440A8BB0173F59E11523E1CEF2593A4AC5AF2167627B00 ! C5EA97D125EB8A4BD4C372877ABF10F5B7B149D73787E0834BFB3084E9508DF7 ! 072DD71637019599252059738D4D6BC57A9358E4B14F6AF9C4B31DB8E25C29B3 ! 7A15F9953BD73ACDE5F0445A5DC406BB4635FAE51C1D8202AE31730E6F355317 ! 1DC197DB0B6177307C60E5D38F4487363EE051B2E609A52BC4D45B14B6558B6B ! 5E1618748794B8340752CDBE7756C068975B559615D4CD5A97CE30BAA7B2B1A3 ! 2FEF2E055232B24FD8A21BECDE1B6A479A28EC80AE2CD16DB50B30B4A6CFCF06 ! 491C7CD5AC29FB964D4846415233947522676DEABDA0D9535F8507D33693930C ! B4E4240A02B0CE7EA288516B8A6EF908D7F8BAF9012D052C6AC96D9F8F6ADB07 ! 8984F3559C5E7E3022A957982155FC9CD599C74E18328D3AB46F9DD15D1C4C3F ! 9B93ADB4489BA02CFCF57DE6270F3AD2F8597BE71786510EF08142F430EE5568 ! 4F9DDB792B7C46B6135E341DBBF062FBC50FABA80CD4A384157BAE57CBEA9781 ! AA4416323265168AC097DE7E30A0D4750143A4FCE70A863A31876A8FA5327C3E ! 36E89589E363AA2B1A6E8B09F5AEB8FFFD0396067173465B6503383DE517A6EA ! 88C0FC08578398C2A721E5AEB29F4AC9BC990A50CD87BD35A11F9E81F68E7B85 ! 5E5B95A4F9A5D30379EF90D78E1E466DEF867BAEFC4F5ED2C762BFF099C1C2B3 ! 5E0DA1C2FB33BE1379413CDDB1EE6BB3A495331F72F2FAEB8152E8AD5FD334A8 ! AAB0082A71D5574B618EA8D487B8FAF1B445F3395B1E21224F5492A0E06F5152 ! 7726835C900E2E52BE3B7B654183AEDEC68053DD0AF19EF6DBC10B6FC08EC7D0 ! CC0E2C8FAF8C9A4C21FB7C34E074BBA4EE64226BEC8C928A784C1BEE35B72EC8 ! E9295240B29DDC2539CD118BAC38DB3917D14CD33AB45FE47E827F2A2B193AFF ! 53C5396C52CEA4F43F06AC2D08C74CC85D608CBA267175EC31311EE25AB48DD9 ! FE811B411AE426C9FC0B6044D1EBF130231623F1566CEA4D1C06D8032FD9808A ! 94479C842BC41B675CF6B90113BD681F8D43F51D5016D80EDC11D7640FB950D4 ! E709A46184406ED90D0892A4CD9062938A8205697A200DBE1F38EB166EFEA0EC ! 4FCB45CDAF82EA103DD6FDD03D146F3E42EDA6496064DB3F4FC1C5280C9E604B ! D5EBCA08BF2AAC90156C11EF68137DC76502EBF216F3AF3EE30DD2676D218428 ! F41C655093F8B530FCA378B5769F262A6FDB4B66B83F18F050E77227E28D71F4 ! 5F4425CB8D51B3DAE872CD86D7804F870BC564A6DA1CA13EDB00D131CE4F6460 ! 7021661B99612629DCC20C85CF155EDC5111E015A77B0B82A8FC1EBB374B7EF2 ! 361419BA93B857D5C9944BB5B4AEDD86ABCC261542077FE09701C96370168579 ! 5F89D5AAA08D700E2643E88C2FB8D1D56D37AAA9744872E7C050B4CE046B47A7 ! 83F224FA9FD311C955EFBF173042C8FC66524135F579B1397828870D5C9DC71F ! 8615FADE2A1CFAEA90F732B6C266E2F3048FC43EDA7A6B6D98E9DB793CF457B3 ! F5877E7A055C92B0246FEA8C72B3B3456F93BF36E2651D32CD614C3AECC0B4BC ! F824C8363E593A6458D37408FC5B09883B280005DD24123E2D4B1B85F4113327 ! EEDD9186A4AF2CD6439B46C5C168C125CA80F9EE9E68906620EE126CFBF26E15 ! B269838A54224EDCFE2A373EB750D4829BFA410DE5F1541E428BB1E024AF496D ! F5F1C151F5A645C8622F2EF9088D57A2811868A8A8BFCDBFCE3ACB8463AC35B4 ! 8B6F44E1C1232805842F56FA468F81FF37D5D55B81CA56058558544C142EB3BE ! 07CFB1F75DECB1E48C14D6AFDD455989AA6FFE8B8DC54F462B3C20E31D270BCE ! 8E68E2B43A6625AC7E9792704FAAD6CE8BBE0B341DA7189EBB3E9D5375B27FD4 ! 12506D5BCA50AEDC6955E6C3C7BAA84BACAF7ABDF3A270C7734EC3C6EC22793B ! E67B0E288F99699D38DA8B79F2D21DD97945FBDDD132A8F0BF947950D3C0B4AA ! EB7B2C435AFE54489E1930610311D718AC610C21A644F34CB2D1959B3066F39B ! EADEAB5CFC6AF4D191D86B02402B00D1C5262707861C5308730579795EB53207 ! A291A27A8B5C4DAE0A87A0C6A260026CA3CB620E1002E066A515D7990F3DEA29 ! 0FAC962E0B82B7A6C86B1EDC54007822BAECED673FAAEF88C8109777EB79A53F ! AF3C58546974F2F56E70E9B5CB59ACB5C27CB01895557B2D82134D7F02029B24 ! 3331621F38E68717F5CB68A8892D0B9C0A8ED4F8BB56E80505170D44C6856128 ! 2DED0254ADA4875CF56B4D97372AAE730D4C77A2940DC8C178274DF88A9EE037 ! 215C6FE7B9D481EE4DE809B124C0270782411ACCCF89906A8B143D0BA8B2CEDE ! E9B90465C3E57A4FD9AD2702323450256ABD09A1F8C26F08480317C08B75B720 ! 70A161C99715A35A94DD5C9647ED0F8A5337B774C8E54F9653AC859485A1FED5 ! 37B725A7E4BA58711CBCDA6054E34CBD8E9F9460179DA7DBD243D81A1531FDDE ! BF2BD425BD9DBE75EAA333B1F5793669A215549A774597E6ADA16D323FE5601A ! EDA41092730009A99BF5B5AAE281844A6BF3292D4D4EDE36B4FD8BCAEB6EB72F ! AC5D3CD53D0D621CA9EA8D254FDCB2B5161EE9E80B266563F669805A3A15271A ! 0753983004A1ECC7FBADF62AFEA4DAB49A178C231759857DB910668BDB07CB3F ! 7E8EC24901863088B3231EE3FA563924032C91CA9D68DB398F9BD9AC0C651EC8 ! 9051C9F709CD784F3FF5951DECD7E869ACC34B83AECDB011E6594347855EE7F5 ! 28811F744A4BD70D4E9077EA7EC19FFCF612689F12B34332857AE41F13E6D16A ! 962DB9B6AAAC167B9FBDF0068EA13412F318384134B29F3F0C399F1973A3564E ! F9C3C39B5BDD4C98D81A6CB476E565860B50704BD65ABD630A5F1372F2D826F3 ! 3AD47C08B8AD3176A170C369EF3CEEB190134006D6135C5B8CCDBE1C11FFF1EC ! 3F6D8C46E15C4F5EB9ED9F31A129594D542D40DC3815CD075A0DBB648D868AF5 ! 15A05C4BDB28BF23653A3AD96CF6AFC065DCCCB23D5D9A945F8CBB539DD3BFA8 ! DB8F1FBF9B6F25B41EB4309995CA3D5D6ABD70CBB4A2F0C6364E5439AD1045FF ! 72F6B45A30BD3A548CFAADDCC6C15D46F6D783D3E520215751DC98335A4ED512 ! D7D19235CDF911CC69F3CF4365B678EBF3E87C456A4E77339C74930083445588 ! 462529C22A96A28C5CE87AFA0C981F26CAED5A1C8DBCDDA612624DBE0373F026 ! 465185A4D8C73CCD8D71EE97116F8F7D341B87FD78F9CCB9FBDA2A7799711607 ! 6BBA855AE9D5C505870DC85FDFAAA130A351D56AADBFBD6A7D52055E3200F8B7 ! 8AE9A00092B55DEA8BDE224B4BA7FD4A191CB1FFC4CB995FEE1AC2883AB69E1A ! AFFC09AB5B9AE311A030A5BA05E2213F9BBF016C8FA80689C069314D91274B20 ! 53FCC65C7D7B3A7504887525BFFA060304931672A078BCD7F269595686310E34 ! E1ECA868899BC402D17EC36CE40D5041D7CEDA77F7764C9D98793F5334F574DF ! E93CB10A5E8ADAE95CE63D2339557091B4B4911A4987CF21B7F1DBADBC2DD605 ! 8EB72473C1F2EABCC44E0D0339EECB55DA74085606C3F89D57ACFBF5755A5395 ! CA8D4BD47E4EE8D8B882D3AB31A1F0C62E74654C7E041E4FF2693A38A9796064 ! 46526B0A37E6B5BF8E48E80EDEF81E34DA8F6CC9025936A4D0E6D709D61B7B5C ! AB550397117F3F9D2F5A542A64DEA8E1178F7337124D6B56BA92F659AAD694D7 ! 391028731E01284BFEA635314A8DA8DF7A34EA3B6B2F8803BE6DCB423A9E8015 ! 55EBD90EBAE8A00298B3B6B1C02BA516AF528122C1F2B07EF69F5466C2C36643 ! 0D665D6561705509B7582D8301AF3C32E2F3B9433E3E04D62117C7E8A368BDE1 ! 0D4DAA1C415B2A6573116D2A169AFEF700A83F55D88813585E89C94C07802BA8 ! 3AE8F9BC3CDBFD9C2E35D062B1FD6E79E1EF104FC70B0AB09D12CA027F33F85A ! 22F0ECBB4AD55FE8C616B82C46CE69A600E4F767BD7A9C5F9B37A3196B038384 ! 5DEF76A8884425FE598A63AEB19FA698C2AF7CAA4983CEC789268E22BA051EE0 ! 20A40633D22D8F707626ED30E8273EAAD1C065F0B2E1718B5AC853ABE09330C3 ! B0082A71D557169BC1559B6D285A3499D41C4CCF1F74884EC3917EB9C574371E ! AFE8578DDCA459B8D22C0188A8D150437B05FB92022C95EB6FBCC954216B5FED ! CBC7C90B9A1F061376A9840FB64390A6BA99CFC8279A86A730C6DBFD14C53C4B ! 7277D676BD42203677E9ABEEC8C97E13DAA626474513B06F8734DD784F2FBBB9 ! B3B448B8E8221E380AB4A86D3A683B86A54129519D50DD4FE63B30954D805CED ! A9A5D9A39C58B65B08E1C19555E927C6DBF7FD07252B2B57F62B905D6B488201 ! 213D106A41033B26FFBAC2E616DA6ADA6D560BADF10E68872806CFD6F6E19D7B ! 57CF1F7A030A7BAD374F16A977E0ECB8742D034ADAF9C247DA19C8AEA74EF6CE ! DAFD6B1DC562FD3B77E4D008BDE4D8C7FCA9895DA1AC9EAA01C32A0DA712B082 ! 9438E77230D38FC4153E1711417B918BA6CC03203A5FF082AF880F48518D8271 ! C1121E4F1386B30A7F1BC6F10EA98443F8A65C867A109336B808BC9A8E2A75AC ! F950835AA84B56F59DA4C8A18859C3B68F6B6DE09A6675F639EA9107BDB67B0F ! 54EBC564BC2D781B61C14363A54956BA78A2BB89C9F966C94EEFC29EE9F4E23E ! C0BF750144DC289F0DEE1F8A25BB52E54F656FAFEE4BD2DA57E1306BBE648051 ! 1D0CFD6A23A3DF082E3CF13197BF1B7FB22B2CD427BB78F455C9634DF989DC90 ! 7BB2AE247B1C99AB2062855B2948341B0F857ACD750B59E370A6698C6A1F5287 ! 72A4A9628A592E313956C242DF8277EDD2F1FDFB07CDC104275FFBF796D7518A ! DF49FF3CDEC3BDFF1D290C382F244DF18005ECDABF0C5C2C64EEC4383E2E07DC ! 5C82587C071E59B46B7BEF31D268F39D9B12D534344FBA515E9DE8F166FAD1E2 ! 7D1558967AAAD3829D3F7EC6938D20E5379F414532976ABA844D97A5E9078901 ! EAE4D0ED1F4C7EE7A2D80D891A5013D6409A38ACFA497F5A169EB7F9F4890DC4 ! 62FA6A89EA48267331F086992B9CA9305E16611E6AEE67DCDD588A25D37F45B1 ! 0DE75C802EE021E574B64B3969DE2E5061ED9364B646C38D4BBA86802CA6338A ! 94E135D2256920EBFB1AA22D9E90C7D16853F0DF9F2D942748EE540E4FCE63C6 ! 5380D7AB4ADD6CB00FE8F7867E4862D8DB432F28331428CC350CDF7F447A65ED ! D7683ECA35A22ADD06E9FE6BAF060913AEEE7B2B8EE4798E437698CC9EB2428E ! 74CE73F84D0D2292DE709D71FFF8901C3505370E6F1D4E28E6B7372492C65A88 ! 159371B1D60D77CEC93B272B6C5394EE1D2EF9969DB2838B8E128553879A1BA5 ! 2884B0A596E8FC3D1E648B7E26A4AC57DF09B9CE09B2F91D8CA618CA52AB3DBD ! D005A56A420366069B73146A6F58E88BA49671A1AB7C2070C3D42AA770285143 ! 40AE7D7868C0E1993506B07C086AD7D4F28CE2D15853FC5FBCBF9425D8012B9E ! DB6E1E5002517659C8DA69DCEACA94F368537668843D281FC11782F1C5F71977 ! CA215349EE6F20565DE3D8D8212A40E1227A4B22965FA64A0B02C62BFDE97E6F ! C3C54FED4057EF9D258C42D7440C78C5E0CC58A40DD74ECED4152F70A93CE71A ! 1B3A57C46F74A6D27BF98C97CCD31A8EA487260F224A3E40F52C65490AB4098A ! 7B9EEB54A5A415C8C88568F7D9EFE74BBB785FA18AA27D9201F28BBC477A20A5 ! D1307AA78EB8C7CAD409AB64B29E4115E45F5FADDCC80CA74B296C4265A40614 ! 37F2ACD8386AC0202D6FDB6711E8CB06442F209D781E940ADDD6D881D4F8E874 ! 357C533115923B90138FFE31D3577C6AAE60D768970FAAB682CD0DCA3E9A9A68 ! 6393E4B772691C1013ADFFC90C508D51B02D2518ADCC7E79F7DE5DF9D18B8435 ! 6129064DD1A3995E5A6F45D78287CC10A0EAFBF47223494C5EA934B1BC2F7C53 ! 686C5880303F9E3ADC8B100D441D944686E1FD811C646C6DD0224F6CF55FA87F ! D132EF50450879A25242A18683BD6D0266F8F333F3768D1952B0F32AA75106D8 ! EC0AB703F287E847CB91FFB88CD9DA174B49171822BDE34621CF41EA772230A6 ! 3088F8D19CF2364A329162D39E166AC728B267758341630B00398D64538FCC4D ! E3E6CF103794C29AEF7F7E56970F6B1ABA87DC8D23E280EDC77556593D02DFF3 ! 154883CFE4EF04E07E7539A4750FA1CF1A994E99B656E728D140C83AE1F196AD ! 9F049188A4184C84556C0476BE46DDA8ED86888DDA3065C5091D99EEEAC43092 ! 40B97AE327215024ACC0134CBE91FD761C26A48EDFF9028DA28222985FAED7B6 ! A1CC891D07185666E34BEFBBF77C6C32B88FF3F1046E4EB2CD942E70746DDCDE ! 002E74BA03A2B15E0529E61DCAC207A71F61C89D81B3C53C5B458EAC70ADFC54 ! 810310CB04E1A21FFBC5DE2429EC0989A3F2B6AE4290A005FBE736750956765D ! 637B7CABF7F9A593D9FF6C322895835C0007A78771D1404671122F9CF898AB24 ! 1A5648EF8C40B27FD537612C4CBC6E584FBD058DBD4F0A00C63A79077826D3F1 ! 859589B221F7F82DBE392601B0A89142648EB40BCD943E382FC7758A10F978FF ! 6DD9C3C1D284C5642C812DBF29A75A50BF63F788CBEA5883DC1544ABB49289EE ! 2C99CB03C1BA72C7320904C7EC94736825A793D5629EABFCEFAB8D28B6F23858 ! 89A6967942A943FAB5E5B26B8567CC9606DE60329C6D890843F700FC1F60656A ! 38164ED7976AD47A8E54940B9E340D61353AAD260C9273D45772AEC8E9F4F045 ! 9CC576D152757AF3B74DFB9B6962001EA9FF7F62C2E36F71D9B76BB99DA7631F ! 774795B8CD1E08480153496DE5E08A1F4BEA681D0C1D6336A49A222B0537ABD9 ! 75A3A9D27D0B71B8913E9355F8E56C5FB3E14B9D5ACC4F87339FF9D9039ADEEC ! 660B5CEF75E7C1772D4A3A4D0C8976A165766D9DBD0CA8132D17E5149AE716A9 ! 2E255277FB5294A96194C462C74AAB251A36941768EDB3EC6DC2C481393ABA6C ! 8BC2F3AB0BF5A6E5619BE16DF43BB09D0E9D5FA4577426BE8A2F847C25E55D7F ! F67F71F3F7BEB60A2DE7183A562D7A8C97E96A43C9E06549B174431F4499FB8B ! 949498C1DCBD58F8C028B52BD41EC7950B2F3F570CC86B44382CB9F2D5EA8CC6 ! BD9601797B108FEC00511C0D50484F503C1CA95A766012B9BAD38F014867A27E ! D4564B02850D3892796717EDA0E3AF8F81B1B4404DA8FF7D0FF25B1464E75B6B ! 2A55554A12D0C032029C19B72CE17052E96D235A0825065ABB286814A465351B ! 6AA15EBFC67E9FBCA14D7B8F1B9AD6DEA70CDAE988751E1703C41504A15F25A4 ! AD04721DFDDF69C267DAABAAFD31ADF59861FC3A7D9B3EC7E65E424DDF65E253 ! 7E22E3190B20B2221849EC1FF3DB635393446B435A51DFDF427C2EE6C45CC9EB ! CF142528D4F8869E6E44FFD471CFBEFD327B5D204C879BC8F9611D5B67383211 ! 5224ED2DDE9A993549039A6FE27BA358AA91C292216E9AD0FBFB5C3A34F5ABCE ! DED5848E2F0E438737A9C1DB313A943BDEAEA9B30B1B224D81FA6C74E5BCC03F ! 032C3951F93F7291E5DD988B44DCB8E8900746AF88AB0D464DAF82129D29AA30 ! C8E6102ADA9C9D5F0086E13F8C33F09B9332242B98F6C635B4940592135C75FD ! AF697976371F61D88DE453D7BC926C68F4DC15189B85BA08700A5CC26A1590C5 ! EDFCAF063D28095048939FB2A21B6EF7D08E6189907A5D0D5CC24CC577104438 ! 79D693CE13C22BC55612038F56A07C3BFAE2513905B0AB3F5CDC4808BF581D14 ! E1F3B0E771C0E7DF3CDC1A80002989F77EEF09DA90EC20CF2B1153598E7EF452 ! 4FE4BD2CE3EB3E8E41041C42 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! cleartomark ! {restore}if ! %%EndFont ! %%BeginFont: CMTT10 ! %!PS-AdobeFont-1.0: CMTT10 003.002 ! %%Title: CMTT10 ! %Version: 003.002 ! %%CreationDate: Mon Jul 13 16:17:00 2009 ! %%Creator: David M. Jones ! %Copyright: Copyright (c) 1997, 2009 American Mathematical Society ! %Copyright: (), with Reserved Font Name CMTT10. ! % This Font Software is licensed under the SIL Open Font License, Version 1.1. ! % This license is in the accompanying file OFL.txt, and is also ! % available with a FAQ at: http://scripts.sil.org/OFL. ! %%EndComments ! FontDirectory/CMTT10 known{/CMTT10 findfont dup/UniqueID known{dup ! /UniqueID get 5000832 eq exch/FontType get 1 eq and}{pop false}ifelse ! {save true}{false}ifelse}{false}ifelse ! 11 dict begin ! /FontType 1 def ! /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def ! /FontName /CMTT10 def ! /FontBBox {-4 -233 537 696 }readonly def ! /UniqueID 5000832 def ! /PaintType 0 def ! /FontInfo 9 dict dup begin ! /version (003.002) readonly def ! /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMTT10.) readonly def ! /FullName (CMTT10) readonly def ! /FamilyName (Computer Modern) readonly def ! /Weight (Medium) readonly def ! /ItalicAngle 0 def ! /isFixedPitch true def ! /UnderlinePosition -100 def ! /UnderlineThickness 50 def ! end readonly def ! /Encoding 256 array ! 0 1 255 {1 index exch /.notdef put} for ! dup 45 /hyphen put ! dup 46 /period put ! dup 47 /slash put ! dup 48 /zero put ! dup 49 /one put ! dup 50 /two put ! dup 51 /three put ! dup 58 /colon put ! dup 68 /D put ! dup 70 /F put ! dup 76 /L put ! dup 95 /underscore put ! dup 97 /a put ! dup 98 /b put ! dup 99 /c put ! dup 100 /d put ! dup 101 /e put ! dup 102 /f put ! dup 103 /g put ! dup 104 /h put ! dup 105 /i put ! dup 106 /j put ! dup 108 /l put ! dup 109 /m put ! dup 110 /n put ! dup 111 /o put ! dup 112 /p put ! dup 113 /q put ! dup 114 /r put ! dup 115 /s put ! dup 116 /t put ! dup 117 /u put ! dup 118 /v put ! dup 119 /w put ! dup 120 /x put ! dup 121 /y put ! readonly def ! currentdict end ! currentfile eexec ! D9D66F633B846AB284BCF8B0411B772DE5CE3DD325E55798292D7BD972BD75FA ! 0E079529AF9C82DF72F64195C9C210DCE34528F540DA1FFD7BEBB9B40787BA93 ! 51BBFB7CFC5F9152D1E5BB0AD8D016C6CFA4EB41B3C51D091C2D5440E67CFD71 ! 7C56816B03B901BF4A25A07175380E50A213F877C44778B3C5AADBCC86D6E551 ! E6AF364B0BFCAAD22D8D558C5C81A7D425A1629DD5182206742D1D082A12F078 ! 0FD4F5F6D3129FCFFF1F4A912B0A7DEC8D33A57B5AE0328EF9D57ADDAC543273 ! C01924195A181D03F5054A93B71E5065F8D92FE23794DDF2E5ECEBA191DB82B3 ! 7A69521B0C4D40495B5D9CE7A3AF33D17EE69979B82B715BAD8A5904C5DE0260 ! 6C15950CCF6E188A0CDF841EB68E5A2F88253E382140F87C87E55C9EA93B8C89 ! 14A36CDF630D6BE7CD36DBDCE22B21778E8648B97B7EC6742EB5114BDF0454B0 ! 0EA7B1FE236C84C0E5308C871F67B973892890557AA12E00B2C20C71F516C397 ! 3F3BBD14A1D0149CA064391056E45E9470FC7F6F556ABC82653B3C8049AB5CF4 ! BA83C8F2158C236B2FFD4208846013BAF4165E8BB8D334C8FF2E8D74AF5DAB2F ! D44788869B08399421AAA900ECC6A2D594641C121660D4B5F512938994C18DD0 ! FCD9B008F68F0351D21ED735B2740CB1E0C1CCD25EB548C35B844601D98828DB ! 556F71D07E081A593FF12DAF83676492A0FFE16E95717A07082B43A966C1EE8F ! 8A59E1255E1705C43A23CF29A5E4A6547C93F1680A870EE7BAD8CF74D838CD5E ! F806911D8FE4262ED8E7F5BC58B92C9C6D74F8AD45FBB021EC7E97393018B9DB ! B1B84E7B243ADB05ADD3F1DB3692ADC5D47FEC7DF93080669E63281F1576B673 ! 125EDF08016664BE73364F65389F7C3B66623AD1754ECBEF9E5CE6948D933787 ! A5674279ACB2EBECD3B4E6361419AB32028A27670C9F3E18B746A10B00AF6D77 ! 4EC00E3BE521C02A99AE5BAA98F793EB1228952BE67934B91472E01AF7B816BC ! 56D7F19F631A1927846D800C107B1E9CBFF9D2DD513B4A8CE2E0DFD77B1ED178 ! E43FA7052765E9FAF89989D490D8FEF6C536EC0D4AE27A74F474B98DA9E6B92F ! 15E063DB260571979A5DE2423920CE1F59F56EB11E00E3BB9D466A8263E1E385 ! 2014BEFDA8D1EA3EDA04BE32AEE6CD15C5C010A1DF7F705A2C0C18E87C8DCCE9 ! 05D9163181CBA56C0FAC8C06A2990554C8E759D076B01BBEADE3B5FB8B551390 ! 6C8E4A2A1C6E7D9C708614626F3770C0AB7DD2027469C77975C27576065862AD ! 04E5E50CEBE907E3E991FA0C627302C0E207B4D5992BEBAB5853AD1C0D271728 ! C76F40A79392ACCA7358F948AC65DC823CFDA59E1FF69CEBB6B7EC3CF21669E4 ! 70D999508F9C49E2D9F8818CA53C977D93E15FBBBAF75B1E84F0BA62BCC4BAFA ! 4EEC82D804C8A8C0210F3E5E258BB1F6921AF02BA9861BAD5C3D5FC8CEFABA8A ! A607E547B802096F7AEB09FBA99C83C9A494B94408DD607CA6561A6E6660C473 ! 62CF8D35F31D052F6C6C8138A8E1430CBA7EA6973D6D510C1A06B3FBD79D9364 ! 240C1A00272DA44B89A9FE8D5BF36DC1B5EBB4A78ADBE9C5EDB485F093D9517D ! 69E1AC9A8E6C9D7C324E3797CFEAD9A18E82E03F69B2CED7D5DDCD1A218BF2E2 ! ED2293AE999FE2A4B5213A10083EE0407BCF8007670B8C737EAB30311C868D84 ! 121149ACB4A27F3ED6C0C181C98AAAF51B105F264B5672D7F745131ABAB5BEA4 ! 0C9B43C0DD9116D6DC61F90BE72018F290D26D5E9D341055CAF09C9F45333CDB ! D45B7954271767F638EEC499F7B53C2CC5774EA7A7F024C4CABFB93D9CB1856A ! 0C671A4ECA7C62EA5242648A84E7F3AFB9547A0AFC29593CFCE6D8B873A78157 ! D337CABD291431C0A2CE1F37E0CD7340567AC206FF98E4B5A6410F70F750451C ! 550EFB54AA259A1B236CA9CB730D2CEF125EC65D959441F7CC9768F777B44844 ! CC9842A307C72B740680ACBBF6AA35FA7A94825069BF7696ED81A371A9E5475A ! 9D997F2DFAD339AADF797F7E03E654234455AC3D17702A420EE0A597BA31BDE4 ! FEB8DBA7C61D311CC90441A620164DC22DC2D373973EF84CC553453AB1B3337F ! 7B39983B8DFFB3A9425F119B45C1CD37A76F905777B3154CA6200792F1759D06 ! E017890F4041A385F2238E3C48B6C8EE6F5258463FDBFF7AC762F6C4363926D6 ! 50F004D473B7B7F73CA686B559C2885F1AA761653C727A77D73431E9D110E76A ! 2E55C68CD50F43997C9B2FC4710F8C8540909829E215678E63BB8363C4B8AF05 ! 9986102BB36580D9CA95CD216B7C321822CB41B2E0422CD077F3B55E0246FDB2 ! 44D5976F67296B5B0BE4B06F6E43535C21164E6C5089C3E9BA2D6B30888C57DE ! 49DC8D9D46C0D5EDC47ACF2C03B72DE3B69512508539019B759280BABEA12BC9 ! 385308A0395C4CD33182A10A5A229743379C2075D82D8BFCE4A66E1AA087A091 ! 8F5372684FA5037D1B92D50CD9CB4F50AD4F8EE7D51F1C9E63C721CB5B9BD011 ! 6F0A8DD4FDCD2B008F223A1036D90F0F3B252487DE7898F9AFBB3A9D9CD49E0C ! EF4ADAD5155A98D2125ED5A3D3907F67301649519419F33CD942E8DDEAC1BDA0 ! E90C431B198F646766A8FA9F8D1561B57E126EF604838C0C1966655CF31FB7EB ! C8CCC434FC1C96046D38203E1791EC824A3D7AED85C029288D4608CA7668A2BE ! 484C99639F121845B22EEFCE0A3B808261921AA042AE19E641769E91277BEC29 ! 4594082CCB3058F90FAC4A700A8A827ACA00FCF574ABC8EB7DBCECD97F2B22C0 ! 0AA19E8739B81AF8C6F621D69B8E6F29BAE233FBA655A0AF5BDFD7F5C6B9167C ! 6BC7AB693D45EF2AD999F5DA3CEFA39BA48A17EE6D9F2C4DAB91AE3F0044DC3F ! 5D5506CE4675AA928B0092D6F173644F91295216D8BBB14CDDE0AD524A4D545C ! 1B5E284A3BF0396664081CFB4F186A84A0D24D61E82F4767C1E55A0642720CF3 ! 909FA1AB8EAB78030B59BEA067DEDBD2F1D0340E790AB2777DB18248521934A8 ! BB38A58B7F633DEA4291B0D5D13E9A882C974697CC6D3B49E030C94EA29B5506 ! CC29C44D01B4751B453A46A9F6BF3BF135AE87A4CE232AF57B66578310DE41E0 ! 2A6AC422117F1963C4D7CC306BD25A6E724E51921779F22F029733122E23E2F0 ! CB340008813ABB104380C80A492B3FC6D0BB07CB8D8409E9576891EF6E5C9D08 ! EB8320DFA31BAFFBD336D0C2BBC3D3B2D30368B9860768FC080D30569C7F7811 ! 0EBEDA2962476113625EEB555490B8CE4C5F99D74ED10F738C61854CFF8B41C6 ! 9402E56BE8856144A1A05D0B05F4CB7EF728B2F4F5A439F18C3B68CEFA41E59A ! D8308ADC92EC1289DC84CF48D2CDEFF509A145BF945E1E00D552D329EBD2A7C4 ! 21D58082CC8FA790E981F4AC8EAB99950678FD3A7DA3DF13778681B208DD71A0 ! 7C3CBD0664B37C9EDC6B601D79A2C51FB54DAEE849F93209793849104E722D3F ! 52DFAF7047EEEDDFE744787A5801E4AC2C3D58EC5DDC15FCEE03990C53B0C57A ! FC54F125A04C8E4A0ADAA725808C587E7DAFB9F784FA2875689979D316DC22BD ! AA36B306A1ABCF907B63C6476737B746099973CAEA8C1E2C5C41F27E0F7DE8D7 ! F0D942E34E92F43FE902653D4D2EBB6F3B9F7928B1550A82AF234D45D028F429 ! 067652BD3D391BF423AE72B9CB1E8D91E898161BE3A7849D456A861A2046711E ! E934DC59442AE7D81661CE8EF727D8D7DDC0270E937E40F896AEAE6171661431 ! C1025C53172F9D366834BA0054FBFD84503FBAE328B6FDEA180F8EA35B1DA937 ! 5CC3B8F00C206908C2FFFFA6A7AC6915D15EA44BDCF29E2BFCFD4A849535F19B ! 0D307C696BE8205C7D84B9C77F02EF27D911056EDBB4080E4D3ED72788666CAD ! CD91B0ECE27A177DB23320A7FA9C31408B4D02D2A4B1CC6DDE1A6CAC3D8EC1EC ! 2226EC98E51046D1EC26FA20EE62D24747D83CF4941DCE5CCEEC0DBE387149CD ! E05B19FFCAFC0D117F9A3E60DCD4C815228D98EF95EB559AD0ACC0D50FFDF714 ! 56C3C812EA5ADBB013BBD956A7C4CC0ED7D3E25D5C9AF5E626F18297F75D4957 ! F5B0B33379114B903FE98BCF35C3FF76FEE1D9AEB711F2962276531F7380EE3F ! E368720E0292A170A15C5539B1FC7BB954EE2624B504CB8C805B8D31AC38307F ! 0513606F09211AE64DAC447693B2A0AD15E9A64C34F5A911ECD0ABCA90E9791D ! 67C6BD202B0858EF96E7722305B8AC02B01AB1706CC6AE875A8DDD15EE349046 ! EAA65005E7866B506EDFB7A5A2AFD5C9E9DCC821A79EE9C1EA2C7BBA32A40BC7 ! CEC26DB1AC473C8C3960ACEC581B37D6569E8C8C42950BAB7930B65E1570E3F8 ! 9A7FA719F1DCFDA45A3BF2AAB32C9A93BA3552608A61C623DE59BCB346E87EF5 ! 9CF025A87803161221C5C1C6F6B3403712C76E9D755C7BD68D7F2DC03C14CDF0 ! C1BBED1D648B905B4B17037B7263C1EA7A7F06FAAC4E09E08483A8D714C19861 ! 327CD9C32DDF850302DD6DDE24912D00C22ECDF3CDFB18FA831A41A7488EC203 ! F564CFE30D506F0829A96D35A7E09C3DCD107D589B627A15B55C5D6649126BEC ! 60B88C55ECCBB4E680265D9EAB4CE22965D3B1AF759B01ACB0D0E6C92B6B4EFD ! A81E6A648708979487FC591CF09631310D46891423F4EC159A73E30D8DD147A4 ! B0EACF6D45D18CD16CEB8176F03ABCB41F2234747B9733C8FAF34AE5D43D3BA5 ! 0CE0FACFC9B087F84FB6C68678BC6E76022B1526D6E5B3A48EC1A110BD75F45F ! 1C4DC6D39F254976453F57DF873B7D635C80C42026DE020E5BAFE0DA0D54D1E1 ! DC634D2621BA184347E5252F645A6A1DB7657C48124186F0E4C644077457C24D ! 55753C651A9A7B6349867641464B515B821349C795A645420508673B93750D0C ! 7A3B33EB1F09782033742AE8F3A23FC02284E6C03818FADD1731361542E3FA3E ! 75B8D52B668C3E18A4AE967D0FC3157083D952AFB8144D549E69EAAC51C279C5 ! E5D88A0D9D53013DFFB4352A1598FF84DCDE6FA32FC377306B9B92C0F96EE149 ! 8CD55E7B2445B86CCA7A547FA732D52D59025129FD8C6333AC0DF4F0CFF6287E ! F2036D5DBBB3B91B92F12FEBE0B61A313A4DB5A9CF0BB3DDB781A56FEBFFACCB ! 8CB9D1D3DBDBC4CB6AAE6769E470582403CB920630221B68BCB625CD4605FA8F ! D3D5B7A1A28D15E44B38E92E906C138E72C15B86F64C38E23BF0440052A8C914 ! 54397F49DBED99D0AF7CEA3B0A05FF37C2D7EAE1412567E6776333237C31E3C0 ! 49949EC8BFD6E0F6446CE2D4DCD2C1524A288818CC5D159BF8463A847AE4A2B9 ! CC8C58F822804B81B13BF4F2DEB6229C4F51F093075581791D02C36A13B855A0 ! 34900AA7CD4F1A797652656FE3A8425A38F421C4CC0ACA1CDD44FA6B31219276 ! 1CDE1CD63D6A58CE705CB56CCA1260F9B86E989019071563A9B4C274A87558CA ! 6EF1660D574EDA276801F0057740E2C3B80D253D697736484D892CE1AB128B8A ! DECD69712F5E70E895FBAA927E8194D792A04AB6CE205E04E38A433BBB793FB4 ! E8BBC4279D58A223C6673D909D6AFECD246E66A52F4CB35E5931D24C828489BD ! 4ECAF621A220D8ECF702BEB01C4FC7510197D3F6D15321EC87175ADBA6434ECD ! 2B5A306E91375CAD22CD94301763E4A8B981472890422C5488FCD523C9CB17DC ! ED22FBF12D5F7525D0D6BCFE8CE85B0DFB1D6F989C267FFBA0A996D309E4A934 ! 3DB54A9D29C88B9D55D7300DA3D46419256C5A07A2A529A8DE8BD1727281F5FE ! 97033D861E0531B14E811378EC1AF1CC7EE9BA2B07D935843D3053F673979F8C ! FAFD59D555B56CE338F606747238B22BD62C42BB7238FEA335678D474A643570 ! A9E7B4970E8C541CE9DBC7BF70ED7BA33639D6744A18379455029E934C95E2EF ! 639C4848CE9A0879B51649FAB023A71782444B451F92A34CB8A124270CCF86D4 ! D18EEF5C1D2B2A29012613851C49F50702D63BACF95EE2AB4D72B375E0A62615 ! E0991E130A67ECBA9E05329B740708F1CB148724C3A6E5E3AEC1F88EBCA398D2 ! 1CA8827C977D72734310233176D1AE26C55CF2CEACA62223315C28FCF6305C7E ! A22414D4739A059F552F1F9372CCCA5FED4F9AC987942848EB498900269511F3 ! F408CBEA0659B954F5F1B18AE4FB270213646F9B28AE4439D2BA2D3E0AAAA780 ! 5E530E4EFC8A060EB979E12191044509DA0C14397AFF949E12DC970658D5EAF5 ! 4EA963F5BC1407A32F3837CA6A24B7F3D60EB8E6222B702E25ED903F9D21AE50 ! 664A095009BDEAF4B78DAF94E5A55D48366CABF07791A1684B2F54EA69070844 ! 4F031AF8DF416C2D3679F8BA038B0DC9DD0400CA6B34667BCBBC07E62C1668A8 ! 35A8C57C9048A7227E672E89681B54D662079A189A9E96A3CA96D8DD10189B04 ! 1DA49BA2729F1CA585B1BD5C467295285D52E47CA904235A1A3E48EFAE9EB6F6 ! 01374125CE89D53C276858668CF45D2F092DDCAA52418E0BB94C2B8266B4D88A ! 5D911507BB1DDA3D8F6E7C14A91CA11AE799EC42E993098E18CADA70BD2A1D82 ! 2C39326C6E3F9E84CD9758B9AE43D79BF99E6A0CD713E95B3D9B7DB90D127DE0 ! DAFEBF850CAAACBD860B5DEF2082F1ADA64B44B193C4A1417BE221FDCA36456C ! BE5934C8CE3ED55AE3A11697C2D682B7D0F72D48976451D205783BE25DBD2507 ! 39C14FFB4BB828DFD187104F38A7F11D5F0698C11E8C1D4F107CACE573FDC4B1 ! C56FDAE47024D6FD16A2FEABB434CA320300FC4B6C1B6CA08F76C60B7C08A665 ! 99F404DBA8A2A1EB18EF6750E4EC186E31561A3F080BA6562967546715859481 ! 7BA782940F5C5D06626D6F6A412CA7C13820EC7C1DF23E15E5829F698CF617BE ! D940523E4EE4ADECEC48C24297DBAD528BA1DCE7AC335A1D15D55415B108EFC8 ! 6D45030D27B3EA63B2B4CD771DBE66AE0218ABB1153D4B7482289D1313CEF184 ! 5C960B1E3C3C953912CC6F4521D1E15636C1545EEE457EFB87B88C9E43CC2F38 ! 6BC4BC96969F4FF28ABB06F4454C01CEF1B6DC538F1E832FC1666D977E5A881B ! F72F1B4C7DD4BE167A5535F1163A0706F9A0B26400178DF8A128FB5EBE6A7B81 ! E478AD183EC06622B591337B9F1872AAEA356F4FC67EE767B34CB5A4D90702D9 ! 39FB846947F4096FB3DCF16EC81455164783BA0B5D723060DAFF411B68307E81 ! 7BEA1D9A47A5AA3D648E618C83C60F060029E6EC4D46B045FA7415BAB2AD0AA5 ! ED9C729C24136F6AF61E6409C0B5CA760B16225641E268A68CFB8260BBEAFC77 ! 6626EBD97195E77CAB425CFB0096D805D9EE699E41680D095AE9FA10122A7882 ! 2F00F495C9EB2102DF0D3E61833BC0A2E468C5CF7AB430FDB7C0BE3DF2C0D230 ! 1580BAA25D65F599378D873165482A1FBB224AEA89C6BCCFBDBA42AE1C5DCF41 ! 06969F585CD3B737D1388D6359F5468D88FCD2279BDB270F6A858FB7D2ABDEFE ! 5EE8FB79FA437F8F50237B92C307B73B0DCB808D07A9C3255CB9B3B17039CE5A ! 288103D05D132863FB522A02CEE3839EF9AF7F07D99732F0B8B384745369FB3E ! 7901166478F4A16076A1504C5E98D17408494E270BBF4470ED12B4332422679F ! 759F1D93984D7E506D16950DB6C2682FE1379EFFA6F6C95DD71F6E55BE3EF6AF ! E0CB25388EEB436E6527806FC75484133F6E561DEB979D5C1FFEFDAF2A6D964E ! 03BAE0BD593C2992AD84569C81050F7A793C5263E50C2F50B98C4CC703EAE17A ! 6AEDAACE312DAFAF5278D125B6EFC5587484F61DAFF46B87B7C9B1EEDECA4859 ! 314A9A9E2248467DE1E54D90DD671660B9040B3E0DD982260822177EFD757266 ! 74A16C83A7FB168016A320D3DF3BD7726F1F4EC90EE5DFE810C96B099FD4368D ! 906AE4699049EFD37E8EF058D4B97BF71106445AADD4FC6E90615A0066823A36 ! 673B8DE32322BBE861AE251226B4385AB28702831270DBD25D666FBB0AD7B96E ! A44E891EA1EAF0F87013AFC982E33D67A28E96E0C9CB99B9E4192536830D9901 ! 931A8CAFA41289633B20BA3BD7AA3414B6DA8D57CCF2FBE39920CC06361F075B ! CC40335DB9A0071CFF77F6B7BB47F3100DBDC9C4A58C2B81EC99E8E966AF3390 ! E3FBCC28BA1D79961C8A1584266454DF772FBA99664D74D4A89FC82FFEDFCFE1 ! 4C9E4A04291E803D142E37E7ACA66AB279378F2F192FFB2B5BBAD18B95F03136 ! 2CB594A3D6D3F8576B90A6C4DAD6D6C8EE07AF682F925F01D0B26CBA347C03BE ! F3B0585CF4539FDC66915E22117078CC94D621F31DCB3E021998A5D6EE94CA4B ! E214D07517283D56973D8E4367392BF6C1150DEBF459D141AE0941C1C8C5CFBE ! E735D796E365A1B0F60BB4CF2801EAFE4889EE5F338D3C4885368281B3C95CCE ! 251C28A90D318A8A0384439B38D63B94757252062EA44E88509FDD2E75FAAB71 ! 7329622828B2785C1A8B26351BC7448C1719C88FE99BCB73F7DEA427FBFCDF4F ! 00EE079B0C712F7D2C8DF98D4830A9D8C8B70A8C5D54BC1DF3171135278BED55 ! DA1CF0E696B12935EB59B606AA3C0CC50C7A259AF32F4C81D9B39470D9993CBC ! 8644403D2833B34AF40511654F96BCE0064860F39849DC62E4A0693F75308FF5 ! FF450EC05F142D5E300D3850C66D432BA581D5D8DFA97D901589C53181CB5057 ! 7FA8B2C95DF751A861DD1A614B2F32ABD284607F40B3462FB05C79DCBB586B43 ! B853D7F77AF5ED7AF2A913FB2CE66241C5102CAEC3992BEEF19A4F760E98EAF5 ! 063E373A084CD6829DC18D063618B4AE443B35B63BFA956368397A69D41DD715 ! 6C5ED849CFCB2825CCB577C1669626E2C87DE60D69559B3CB98FAA07F1893EE9 ! DAAAE01D549A252D77E79AD37BF64540DAF7FDF2FDF4017F94D9D89F1B6F249B ! CAAC5BF817A1979163F3A316640E382B501A6BE18C334DED469CA5643FD07D8F ! 6E37275108F7168F45BFB5024D4FFBDB140741D2C8AA4AF19F22592587A05FF0 ! A324A0DD415F312D653513ADE6EDE9E560BA16573295F6B3A0427A15A585A40D ! 5265A4CB711011332AAE28B05BE6E4B11B1B3C178225B2108D94089E6544907F ! DDC2496C2624F6F7E45CD885C5E032FFEA7C337BE414E421FF8AD3D0959B08F6 ! 6B8931D93180F66A13E86ABB8C7F755D67838B8E8B5A35E6BF9BF3098535D75A ! 3A8880D5E2B1D9C87CDF16AE86047B3D6CB83D9A7A3702A2428BBA8209D50F64 ! 7728F58AFB5CE3F8E8387EE3F2ABFBA17B3F0E6D549E7C6D13BFC785759F32C5 ! B1C8A525B1CED15790CF637B59BAD929E3E3E52223066404D53CEC7C42236ED0 ! E509521FAD3CCADF68D695660BC6A6F743E66DDE0A4A395F7F17F5D533E82963 ! B831C3F3A7BDC6A6F5F62F5F7F9A3C75C12C7E401DCAB10411FB36B96894B6B7 ! 765205D82B57A53D0148BCB96CE67468ED168A7EE08120D79E30FEDB84C86D4D ! 1A103694E049DB8929F2E389124FBA0DBA9E4CC099AE441600E63F70978D0C2E ! 0B21352A2113D96B50649491592406CF1EE84B5AD03265040AB41503D2FBE78C ! 1B0726B6027551614D756C17F939CBC1FD3EE28B99BC31FF9BB31C292002F1BF ! 67BA8B632D158A299E13335EF69FEDFBD28BBF5773AD17D0ED5623F1E578AEA4 ! FF9F8E856950CC7A10CA01238A7371B619AE8C08F51628F39E7173F60745F218 ! 8401AE34EBF1BD24B442988AE5DCE4EC0DA8F922D3DBFB6E2C47B27FBF000735 ! 2C6EFBACD68367409253A4DDBB04501562CC2543F368881E5062A25F890C7711 ! 1A6C3C5AD462F825F1D340D8AED4AF056CC26E592C0337EA2F1DCFDD91F00F82 ! 11642DE4E37B381ADD4976C0C850E31B6EF51DD65E1DECC56BAF0D22F7A4EB91 ! 276AB6567430CD58BB1F3F685149BC5AD0083EBD3AD39976C921024B55FC6DDD ! 3478009D95A97CB0F2A1FF263C72291E18515F5CC3BB29A622139213BC77E3A4 ! F5DBD8BE65E922D39D0C9A4A1355160F9A6B1EF22EF6C2099ACBE1FCDB7E7C02 ! D312BC14113E4C2D09772658701AB0520A6974F24809EC4D35B0E4C29B004835 ! 087AD14CFD0DE38561B1C61AA4157F7CC11191593BB6EFBBE85003091F9D5262 ! 3D89A4527BCCDC19CBE16973BC44D7799F1A19CE476848430A7A8423C64DE9F6 ! 8745BBD0A12852D2AC83B18E2A2479BC1900FA6A840CFCAE9342B4D0A858F8A3 ! B7E375FC626C6784AB0F7B8FE4CC012C90068953CD0554E046F4C249576B9551 ! 7D685A8FBE21E9B7BDA528E311E5DC3B1128C3299CE786D1E24A8B87C66DAB1C ! 0E1CC71C6BAD6E8C7ADD190B894AECDA108EB4BD56A257C2E28E5F570774C972 ! 00F0601ACB1D1B2C6737D6F1401CC1CF6ED9BAE208EE69B800EBDB886B542E94 ! E57F17A05053D888D6C101B6C8FE8C841C25A8BA85A9363FC512D6D893351AC0 ! DBBEDF009D69522D40693B0B1E461C5432AD5A20EDCE9F5858F7D48E2C2A2829 ! C0E0EBB4826BB2E584A5E61AF553E4B2DA0E2145BC70265B6ACD1C493E9AB21F ! 5E97F5F3CD6C9AB94020F5738655897685B69203BFB3D601BC9A46AF09462728 ! 6CE76585722024C445271DBA3DFA5BB7F6251E100F29B27639D712BFFAE19894 ! 1B7DEF345BBA213B3DF67CC19F06AE714057F90F1B5CCD48601E8AFCEC2BF71E ! 56683B42D74AF04FB95130181253E980E14ABB8F849546A7AFB4BAF575595AF8 ! F6B730EFCEA25C4AC01E4A64DF3F74F36E773AE887DDE805528C27294D0F30F7 ! E8F77C2A44865D97EEB9EFD4AB7C41035E362A2B90BFCD7FD07158CECAB3DB9B ! C8F91CEEEC80A9BA0C60186C9A50C00718E0FC8E6097A664A4C4B321D6146C7D ! 0392CB6C88A4648ABB22FD71F82D85ECE54688B082A506687AFF494EAE0A152C ! 23E511482F98E98F1030E5B2F8C5F40A58E52D113B3FE833D0223D0FE85D9600 ! 9E065BF3653113D486F53D1459BB3BD8E8BD8C7E18F41D7EBB4A70D4340541E0 ! EA448903D94CEA9D521ED856B0FE28A72FAA4F9D8151A44B44461A58A006CB50 ! 3FC86BFA479185E04FC0B047104AAA015299930820C8BBD90E0AF87EA5404397 ! 84320814C4FA99AC16033F41BF6EDC2A3403E798B8941D9DD88FCC4E4428D21D ! 4E60FB89D5A9EEAC9EF2741ED1F8180623F6D3AD936D5600B2DC6DE55A6235FA ! A9A16931B9DCC55499B640F363F65CC81B91DDCE0CA3E50E72BDC4D5F448C457 ! AF1DC3C7F38939A6B325C4AB1A8C283F3B25EEBE6A144D303C3C8F935A6A2176 ! 817DE79350B574752E140F608B04EA1CD5FD3CD8874FACE37342768FFB574D07 ! 4514D304601DE4531980F5477763D47AC058910265D01A48AD9160CFFD358B10 ! 24639AA7554AFE3D8920BE46C37463E71B6CE2B8F6798A01A905A9EED23599D8 ! A818D847D901D405F4843840CC0A296F59309CD16F085B3C76EA4C19ABBE3AA1 ! D97BEA533FCA29C31C9781128DFE5A1F8CC5BB81D5E506C3401F54620BB1C462 ! 8448BE8089FBB908B4D90DF5E382A0246073E46AC45E1DFE62C820BDD392FD3C ! 76514F4C47BC1BABEAFB32D697CE621A8E1CEFDF1A910FC2C89CE4DA17E06E84 ! A2EB9462C9C83FE7BEC4ECFEB38C54542D8B088438B765B055BE4C31E8C1BC2D ! 32CBAF963464922E21A316F6E2E6D53D794F36D579D2D08215CC724D7CDEBF9C ! AF7B3D88FA3EADFB3FC7B750A44E46DC0CF4D9343ED935853933110E560C0AF8 ! FCC9DF07C9BFF1A83CC4651E0AEA83F5A67D88F7D0B219E79EDC96595160F591 ! 5E8C3885EFCB121BD203AF4572F966C09A59DE83D86389F07F3567A001FEB241 ! 7A96DE158C54346C1EC97DD31E6560F46BAA988671A46829BAF7A441CF077E31 ! CA1896C44E8CCD90150D48AB2B62CCD3FB6BFAD3307BB7EF55FA0E2F5ADB3DC7 ! 1C50EB7423DEE791C64EA44DE301D6D6B324947E2F679C12634AC3A0E21A11A5 ! 8F6D0E1095336E01D754170006B62442C12AAEAE64A66E2ABA8E9AC613F628F7 ! 6BA9395FA195E676F1318B114D9566447914076A6ABC5B712695E87460D14104 ! FC77A586010FAC5D1D172D00313656CA863D3F7E473CE8FCEBEBDCDA467DBB5A ! 6D620F7FC87F4C9508CFD30DC1E22E976D5FA4BC86E84D859005B46DE89A49E9 ! 3ED0C35A11E9FE5641973D60147211BE2ADB7B0ADB1CA055EF2021CB3DF9C8C7 ! D5D94C4B3ECB43047224A46E23DD319074C7C959D5411E1B6C206A79EE4E51DB ! 8970A0163084DCBE14F6CBA8100EFE1976F083F1D0A9AB03EEB82651214AA965 ! 7BFF69ECB58D15165B494704725402C756D7660D881C5E2501291BFFE8C8C2BC ! 63C14EBD23D5083FB1D0ED21AAE569A16C9CBCDCC61AE4EDA8BE5638F2997DF2 ! 1FC21CBED006BBE636F1AE21B54C15B9149A173E0A940DAA518B49D6C267D6EE ! 9BA64FEEFDCAD3DA06BD8E558FF04963966E9B6F104FDDFFF7A2A085B68CA534 ! CDFF1553C3DCC435B430A073A880DE68959684BB793E02807435B691F545CFFA ! 299D6EA31270B13F6235107F09E09D3F2B2C9395474ADB3965BB48E38D959E72 ! B653E1799E2BFB6DDCAD5E1C8FB21C65F9DCA556754F17A20D1CD9876ABB5782 ! 1708E5FB350EEE8077AB140F77A325E2029457DEA0172C22DF99823470BF5943 ! 4587A3074D891DCB4C581FEDEBACE045BBAA742E61297C179899D3D869468D26 ! 4D8BAAFA945CBD92924B59EF633739CA32BB4707265611B248195B90B51BE889 ! 6C0C823266A655444D925D89FD7E49376A5F1410A722270F8E6E0699AB7B0FCA ! 2CEA7F8EF31C96066E85F59BC92D500D41ACD51E0688CB33A871F20ABC9D79A6 ! 3569993AD4F45B4585126E69D4B47D9EBE7A47859F982B5EFC37E801AE043A5F ! 95A384A9F7CE4B69A44C7F5479F705589E5A11C60F85EF592C7C0F3757A8EC18 ! C5D34E39E6D954EF39D0D2CA84301B945962214DCC7511346851AF9C19607EF0 ! D9FB3EE4784307458C536F92A95C52C13894C915AB9D8C62BE4D7978B730A72F ! E539EED5DAD13459C6EC90896173E2DBCB93AFEBDCF500013CF23DB3F8BB1F3A ! FC54E4C6732D2D6D7F376B663960C8DF4B562C47AA4989EC41FA4C193B10F680 ! 16E800F7D7D77AAB041386D22F88A92D8936C7964E518E75B044F3282F6140BD ! 495B29EDFBFAD9F74A56A2686959CB34E40FF2F772C24664EFE4E6EE486B5805 ! 0557F095C4D421223E64F7133D8D510561259A182049D34A3A4017640B052832 ! 323B65884AC2DB65D843E8A3E9CBAE3775A5C2A3AB701369C95A06157976EF62 ! B1691DB4B9F10BC985EE8CB266B8C4B64272A1647086F144D0D7F71938F34DC0 ! 5D8DF3152714E6A9D97EE1F70ED43F598AF97F5FB29462858DA60CB4D250A20D ! E0690CD34B24BF30FDA1A97DD29E40C0C7DF12F039A920FBC1DDB0E271D18B7F ! C560B2BD8B1E8077D2BEA3307273132EB33AE0F8CB8DBCF2B712D4A0354A0C35 ! E57738E1C7FC995E96C4F60A126AAD1E1D1DDA8B51F51C56F7B526087BDE12EB ! 6143B3BCB7EBDEE1EF6F0A1A3CF1F779125A202BEF50F0E2B5F556CC20064B0F ! AC7ABA30677391F1E73D5CB18B417A7208B05188FDC9CC5497861E7A5F8852A5 ! B5AA742230610C8D83F4C951CBA659BF90092F0CB2172F162D39AC41378152DD ! 2FC84FF83A0E7BF5FDDDA7ACA0BE10BDF9809F9D064A0BAC6162C92DE06326AC ! 12442D20E550FE667A177A21D584912DE5331B0BAB0587BD7DD38A8D16E181C5 ! 6BCEA6DD9A1B42B8C7251D8AB33C41A1033DC086B264F8B6BBF5B0BA97C99C34 ! D8B20723380891CAAFFF370EEFBCD54039E96A532165B57E27A5E3B038BFC365 ! C1A0E00618E070696088E63B5735F7FCD961A40EA8EE189E96C70B6DA53388F1 ! 7F8909EAADF1D741EEE40032D7F93457CA4449C46ADFCA3163831DDA56FE2CB2 ! 190D05AC0C60BEE6C572059F312AB3094B1A5F94D2129A4725D367DD625278D8 ! 554E9FBEFC3708B3E83D87F31D80B242E648344FCC18128DCBB1D56F6CD8C1C3 ! 6BE080D87D632037EDE74FC9F1B2433D62E2CDA0FA3B30C449B9C54043797C9B ! 9DCE84AD556731E3D5AEE38F3C6B005EEFC98C19FBE5F786AEC0BCCC5815EC06 ! AF41C6677A59550DB98AF1CACA702928193E331FAA988DBA1BC95A5372A75664 ! 726B0AE3BCB87974A7AAD2395B3CE3874702EE51D1F8046B1C963AD4E82A74AD ! 3EB134E6796A80C7233081519B350DDC8F3B8C4CB2FE71837DE89A6F0375C79E ! 6F5E7B8509CF9AA15444A3C9398BA39B8570080EF488321CE5364DD89767E138 ! 39FBC00517E27CC866554F1F740429AE6DBD30CD73C4B612145F4D862B551218 ! 6A188D5FA719A16C640CB3FF8B88D898836586FEA2A4137429B08265051F1990 ! 7925613DF0B2715856C1BEB0D5AD58362D9EA8FF2D97D2BDD9D637A20B34E08C ! 645C4DDBBF7A4CA2E09B307D37EA061800C02C91D2E4AB90D9B250DF739D50D3 ! CB62A2C2FB9A6B418EFCF20F0B1903418265EAE5E99852DE2B6515160D0D39AD ! 6ABE1A0B4318D78C44730E50F868F68032363101DE435B4DD2B4C595D79B4826 ! FAA76BDC6B4B899573319A05926B4075CBA22569FE0A088D27729E433DCBAE60 ! 096F54CCDA15CB83D5FCBD8200FC1590941AD503C9096E3D67A8B98CDE3F245D ! 32E468DD7B8976FFE627DA3AF4DF9C79E54099EB00EE4FDDD9E1D9169AA03991 ! 7C810A09E793EAB014B1EFA30D24FA6A8F3746CC7AE5F28146CC2483C4A0ABD8 ! 1889AB40382FFB44EE3F819E184A8B70AD235C1C927DC9CD0710D4C6B8B819E9 ! B52F29C4A4A9B8B67361300AD672D0834C14D8DE91AA1E3E380E81840BC36F5E ! 11DEE396CFF9A809952F25B26C659935B6BC6433C3FF6660EB84F590556982A4 ! 3EDE38FAF0D0E068D1BFC1192B3AD49DB03714D0237685034374D4EEB5AD28C1 ! C43EE02C2F77E06E8C5145A7385E8DDE436FA86CB3BD9039D1BD8EC4E629799E ! 775BEE5E4BABA9C7632E6A62B100AC7FFD28AE8D186C157A54D42984F87B73B5 ! 3DBA67175EBE62605D59DB6CDBD4D13BD117A24724B05FDA20440B61FE7E3C49 ! 29161822AACF180E0026A82FE53362C2941584868B2F2473BAC29D7D9841A28E ! 462D6C8FB9C9DDFFD640F43F9B28D533A48B2B9BCB0C001B1552E3915FAB931C ! 6D37A92CC7779D83D2D1A3AFC207A02882EDB602ACD31C62E12E69F19AB20109 ! 44F444235CB11312C20DB878A10E5EF0F516E75190F6F2EFE9AE13B058618FBB ! BE8FBCA23F602F8F781D79BFFBFB0D1C1D3F47DA98AEAA68DD52D3A5E6565DAB ! 50C5C2920B33610CE9A764F6966E7912EE232C0D37F753971174867BE9F68068 ! 5CC128443A608F2CF90589806B865650A951F79F2751634031F59ED1F7EDF042 ! F20E96EE2C5AD862D2E70D29B262A1691E1E481C34877647E84B8BD54BEAE277 ! C31F0AA542C7CAF62B8375245B7C5CFEB79E547AEEE4E83CF265C90955DDBF99 ! 72EABBD9746B5C834F4DF36938EC2E19109A1CD22D0D3856333EBED92C48FA5E ! 39659525C1512E0C50592957D27750336FB0DE4E401E238C4967E5B24AC2E80B ! CA6FDDC930AB83276D034E195491F7C9662779BF9273B7F4D48C448EEFF194DB ! F9DA81ADD27085D86B6780CB0843B6CEC3F714ACB8C18037A73F47B15E1CB007 ! 4A2FF55F8B58FDFD7C83BC9DB506692DC3734FBB0C8A41B4D7E30144AE1C8092 ! C854F4FCEE95E64FC69FCA85A40B77DA2FD88D95987AD38E0DCBDBC763D19EF5 ! 914E021F41BA70F853F3F8523D76D6E82FDC48E1D689383FB22B1B2CC2A0BF53 ! 30AE3EFEEAB5B7CF1E8843B314C05BC0CE2B6208DC479DC56A441BC156E53717 ! 317B6726FCEE74E51A933E50C8E5D8E07D08ECF03A72B6C12D733B5E28F8F9DE ! C09BCDAB9F3A85ADA3C1A206F77E957F349E560F969FE827ABCF5A75C23C86AC ! 7D4F994C9E8B1A4846CDD582BDFBD1F0345B3EB6EB5308390DE8CCB077D3CC27 ! 836016047A8B74D9C1A3A44291FC9FA3401B0A25F1195C102577CAD6F67B4601 ! 7464DBE1A25FF8CE0875583C26824FCDA0896303C9AE3728D68CD9A5C6E8A330 ! EBD5F2DDDFAEB7A262DAB8CCDF61F065B0A154F59D6C283465F4B3D2AD9380BD ! 90A6D3634961C87FAA8F471BD7ECDD2F3639DFDE556E7C56C81F984E972E628C ! 185C70EFF2359367FC50B6E4F40AF6986122D3A0D17078B0C4A3C45FF65BD50B ! 9D7097935AC46770E0D2062677B44BED75FEB1DB6795635CC7F12ED9046BF004 ! 13257833C45499B53203C68BD8917021B4039804D50684BC2392905B3D72400B ! F4A486573FC896C57DF54C032897377B301E1BF2D75F10A8FAA738E9EA68D0B3 ! DBF1FD8E1DB00787490941DFFE9602201EA98B43310FA2087074871452278E01 ! 2DFA344D83468803C49E129B6CBD118B22EE160FE0008C01D2AB2E528E4EA85E ! 0630F5B9E219C7409EB977D73A16DB0CB4C51D19787E27C92807BF50FF9A6ECF ! C1D3ED2F8B0E094296F4E9443FDA35DE5CF7AB46C37E2075C3952FAD218DCFBC ! C4C687CE5AF906B307C2D324421DF5D89E34826B859EE1669497898157C81ACE ! 30AB792C31BF29A4A32378F3AECCEB7E2D87092F7E2B4B28DFCE0A3E0C4ACF24 ! 25A0C58B44A19E44F27BBE83B8D6EEAA54CE0ADDEA3A392C05D748B625FB27B7 ! 97C8526618F56D4439037D8C85D7ACC755407E758DF2FA3F1225A1DBD034F399 ! DEEBDFBB42E17E8E65D77626C231B0003670E72A25069A2674CFFAA9C0B87041 ! 43EAF4B8B9A3B86440CB22CEB29C19EF056025525D8228F5E9FDAA28132E4CA0 ! F41350110FF9EE73B2985B2EA98FF6D09516BABCE0B3CBC199F6F7B4C5B202B3 ! BF3AF93B3F7133AFC8EEB068F32006C7ED6FE47C26CB0A5B4DD964AA235017A9 ! B9D67449878A3FA64A5D56AB8F7E066958487396C1F20195F55685251479EF5C ! 988B60F750BF64EC9BC75371A910D410C9C046B23C29D300B1FAE80ACC15A87C ! 9194651157D731F35165D0398F0E812C75A1DC353F8BF12526F9AD7CC4553377 ! FDEEA054B7D5DE1CBA1AD6D02E0689326A0E3A6AA6402FFFF8382FCD370EBB75 ! 750BFD3F868CB9EBB2CA8A1FE0B522623648326E31F7355B0CF91148CBA74355 ! 149F32D782CF0ACB6DF5CA60DE55E8FB6123C284468C885BD924939D0A5769A8 ! 01BEE9323839A316E7DD8319F168300BB0CDB009DE4CCB3793DAA486BED1C394 ! 20BFA3EDA02C5D0ED20722E93FC2FB84908538FBACEAEE134B73DBFEE2153CFC ! 8E0F64EF92ED448C8E8D82EB176553BF3081C0EB1542E9AACD24B3BD94055DCA ! 8A574F7691A345B4BA7636E47701D86902C567031B272F865D4C1B9B03E1448B ! 0FD35AC238BA74CABD13D7CBDE80885D9443A373DFB0D612AA9633C277F79513 ! 0B822D8652E695CE5B0C75A941BECE1A13AEE24AE81D690F8A565577DCE9BC18 ! BFCB12229DB81787A42C2E1D24DE8F8AB5ABE0556821275F3666CBC24115E8CF ! 91225879AD3A2335DCE19C81F312980C14D47434D484E1B7D4648CF4D24184F6 ! 4942251018DA1E3E3B67704AB0AC2B837406124F58B3AADF359820EBE42D5B88 ! E8FD0E44C1CE50D51630BBB01116FF49548D4E4A684AE911BED4FC49F91F6DE7 ! 273E629615E4811C340164A7311CB99AF74199D602A4DD4D458CCF67E8D66F84 ! 7E0C0BD9CDF68EF509388ACF1F9824F20EBF866D63777AE58E21B8C9A8DCF510 ! 7BC767D18A088633A9C8D53B268B5B8596B8CCEB0689269544769376C772994E ! 86322EECF2703E49A109A635B9244EFF123F90E2AA108A003D0FECDCD61F07FE ! FC0AEC3BEE8004 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! cleartomark ! {restore}if ! %%EndFont ! %%BeginFont: manfnt ! %!PS-AdobeFont-1.0: manfnt 1.0 ! %%CreationDate: Thu Jul 30 15:00:55 1998 ! %%VMusage: 120000 150000 ! 11 dict begin ! /FontInfo 14 dict dup begin ! /version (1.0) readonly def ! /Notice (Copyright 1998 Taco Hoekwater) readonly def ! /FullName (manfnt) readonly def ! /FamilyName (manfnt) readonly def ! /ItalicAngle 0 def ! /isFixedPitch false def ! /UnderlinePosition -100 def ! /UnderlineThickness 50 def ! /Weight (Medium) readonly def ! end readonly def ! /FontName /manfnt def ! /Encoding 256 array ! 0 1 255 {1 index exch /.notdef put} for ! dup 65 /char41 put ! dup 69 /char45 put ! dup 70 /char46 put ! dup 77 /char4d put ! dup 78 /char4e put ! dup 79 /char4f put ! dup 84 /char54 put ! readonly def ! /PaintType 0 def ! /FontType 1 def ! /FontMatrix [0.001 0 0 0.001 0 0] readonly def ! /FontBBox {-500 -1100 2728 2822} readonly def ! currentdict end ! currentfile eexec ! D9D66F633B846A989B9974B0179FC6CC445BCF7C3C3333173232E3FDBFF43949 ! 1DB866C39088C203DC22FDC758584860EC7BB67FDA28CC6208249060E18FAB32 ! 204779B5C03C0493BBBBC95CF02692CC4DEAA8D2EA90B5C2E64374E92BCB8501 ! 429B8FAE4A76C0C6B76D6FF7CF9A7D5EDFBCA0E959541C59BD05B7DE43D25D53 ! FC3DDA6EF0C2743978A6D03E19CCED4A11F2EA4BCC3110BE8B8D9E2772361969 ! C19258EFAFDC276CB1ADE9208A941A36D18F9FB1C33DEF76AA3140A8A4C99ADB ! B3214E61CB091BB87421CEF35FF5745EF8DDC51293183D75AE11F26462B918E3 ! F15A016BF051C59D797E59AC042DB329D8738C9DF453DD062F0BA8A59E23E500 ! D03758832A6150BF51F1096E643C98DA553929EDAC78FE0F28B0D59B9D5725E1 ! 6E190624F3B19DC32D111A8C852FEB8D154F78BEA76C2B07D944F53EABB7DFDE ! CF0B80EE145C7E2C0FCF6231002BAD917541FF7B3B4A8A5DE6F9E8E423ADD14D ! 40849076959CA9471D0B4ADA2A4ED0080FA3B5B1E9C8EC18C1C606069381DF62 ! 8676CF29193A8562CFA0B0978EB39EF291633F7C978166E6F328EC4DBDEE9749 ! 46D88B0E05F75ACF9FB6F479C29591C1D3DA100643C72BD9F0CC8D3F6E95BD78 ! BFB884C7D0A29FC1AF8728C48DAD913EC539CD1A455345BB841D7F7C77DB9CA8 ! B886659353982A5E6E90BE63239465D91C75ED1D149BA60502DE3D37BDD49D7D ! C00B6D60C5A482C8BD5ABD5E85230FC000420E41808BDBDE14F8F2A80816C44D ! 6BEBA24F6CD5F3C438986C41E503FD4D34DEBC04FC9C3F676CD9EB07B13D15CB ! 4DF818FFDF41740B4ECF707FCD9749F543461C53539A315B02812F210590351E ! F004AA448DF4CFACC540A62ECCAFB5CB817B56C52F4ACC384012EF4438B20D76 ! 61ED669A2E735D76FDC12401A034C5627BC3064CFC2C22A6045DA11977863CE1 ! C39C5226DF4B039A65CA13619129F1E26AFFE6C22F0C38540F8CBEE0AC711CE1 ! E16B4167884211F6DE4412EB3B3D93B76E3306DAE64B091449E2D0E3B22CCB33 ! AA0DA46FCF5A8067C15164F153977501F5E8D84097245BE68983327CB2EFE3EB ! 3F3C2568AABFA42B037CC295BA56554160303CF3A527114CF51E0D1E4B1F05B4 ! B3F6105B29B65043035C87695F6EC20B734CEA18D38A940B773F20E7043E2156 ! 3212B299C29640996055791B98EBBFFC02F81FFB57B3DF725DA363357714256A ! EADF217F5EC05555464AE3F13BE05939C2A6FAB0B85ABB32D64FFBE347DAA7DA ! 7233A207B2B331CD0C7DA49CAD9CCA95EAB9A501E4F61D1E3FD0027343ECDC06 ! 733227E0443FAA99BA72293492313CE91189AE699720EB42C77BFAD3CAEED786 ! A815F570A36F29862D61723A8109626C101972BC869F117899967C94D5F462C2 ! 58F17AED73977B49149929360F17F612A6FE9DE276F26A887842F0A1D162780E ! 47C3AA3031EC4A7C6FBEB6852130A73557A1339BEF9DAF8BFF567BF35694A130 ! 5B5DFD43E9B786ACDE6898E01116C3843A210A307CE9FDD9D6601E98BDDD8B47 ! 3ADD0973BFF38B764B379487ABB6B79056C126C6A4375A12AA968802D9931250 ! C30F4F61A29A02700F822CD63B8A3431233E6AC2EC3824270FA26729DCCD7E8F ! CF38067456BEEE0F49C4F5DAA77E7DFC0F81DD433757B10DEDC15C127DD6B025 ! 441BBF77AC5850819FE9985B205847633E8AC159018198211FFA1139271EC19F ! 73C5EB7674B2931CBC0388450920C78F732C1AFDCDBBF6F14ACA416AC5B2F0C4 ! FFDCFC450E1E9B3F8C21C7503B7BB6A37006BB78A9F28A79B77157D41C6E02BC ! FC843FC70D36F6C864ADDF513DADD4F7466A05BAAC2B17B1792D9BB3B3BC31B1 ! 78C3D0C94F267356C25CD7E09DF1451F15360E4FE4E4E11D47BF53E1429E0530 ! D7C99BC782FFA452136FD0E1D2ED1549B2163A25C5A7D11765025B4BD463EF1A ! 6786DD31755FA68BA830D8B753C66A17953D5452B79F4E36D6BF916CFEC03366 ! 0DC1BA6F6369CB5ED0494F916965CDD7E3DEE48E9FE00EC44870BCCA76173DFB ! C2E271B92FA19382AE8B61CE4FDF88605C7B9F01E9D635ACFFB875E1250A586E ! 4161981BE48DAAFC16A55D0C2B622BFA364B2103F8CEDC5560702E9954FF0F25 ! A13DAD43F19918850215A19C7AEE42621C568330ADB8DF5F555E70A5169C152E ! 5C84F48430E4F37BEFB5520F62FF6E5D1C22622E19BD8ABE6A897A894C70A05D ! B92A1CEE36A2A4CFF6760B511A4A2197DFB2F8BC9CC15E6DA49052B0AF009B9F ! E10BC9BF7A3DA750285D9DF00A89AF60E00D6C1271377FE2513702EFAE04EC52 ! C52383F12AE6668A55BD572C82BFF837203C4EB3A3AE0E3F1CEC59E41A149A12 ! 98318150346B8A93CC05389475B55B7F662D7E1CF490B975193A492369FC588F ! C5A7C40BD6F57F5E13BD0BBAFD6ED503F6D27495AC81C5C6EE923F6F5EB1A2FA ! 43D51F6F209919460FC0FA49931671F76F754044D58F4BD856EB96BD13C590E1 ! 5ABDE36261EE35EBB7A3C111D87AB52EF712F0C12F3C1AA10BCF86B80923A9ED ! 513B8050BEA4E0055F8A5BD831F8CF731C76C7A59B07C199F94E3D888F523DCA ! 2C82BB44A4E9CF593DDA5AE69ABA0271F05E010553247F782689C2AB65FD38DA ! A74273272220E564B3A1EADF071E87040F2B442A21D647C79984FDEC0DAB2E62 ! 9D6F2D951C35F8E4AE7411195FD1A4B269D118F9CD8279DE8C56D76B3DA2C20C ! 694FC78959A558E894DD87C1A48C878B54738C080BBE1A54E61FC577149F325D ! 82549D2DF22CE9A081774343BBEC6D2D33097D8CD752445A574B51 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! cleartomark ! %%EndFont ! %%BeginFont: CMR7 ! %!PS-AdobeFont-1.0: CMR7 003.002 ! %%Title: CMR7 ! %Version: 003.002 ! %%CreationDate: Mon Jul 13 16:17:00 2009 ! %%Creator: David M. Jones ! %Copyright: Copyright (c) 1997, 2009 American Mathematical Society ! %Copyright: (), with Reserved Font Name CMR7. ! % This Font Software is licensed under the SIL Open Font License, Version 1.1. ! % This license is in the accompanying file OFL.txt, and is also ! % available with a FAQ at: http://scripts.sil.org/OFL. ! %%EndComments ! FontDirectory/CMR7 known{/CMR7 findfont dup/UniqueID known{dup ! /UniqueID get 5000790 eq exch/FontType get 1 eq and}{pop false}ifelse ! {save true}{false}ifelse}{false}ifelse ! 11 dict begin ! /FontType 1 def ! /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def ! /FontName /CMR7 def ! /FontBBox {-27 -250 1122 750 }readonly def ! /UniqueID 5000790 def ! /PaintType 0 def ! /FontInfo 9 dict dup begin ! /version (003.002) readonly def ! /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMR7.) readonly def ! /FullName (CMR7) readonly def ! /FamilyName (Computer Modern) readonly def ! /Weight (Medium) readonly def ! /ItalicAngle 0 def ! /isFixedPitch false def ! /UnderlinePosition -100 def ! /UnderlineThickness 50 def ! end readonly def ! /Encoding 256 array ! 0 1 255 {1 index exch /.notdef put} for ! dup 43 /plus put ! readonly def ! currentdict end ! currentfile eexec ! D9D66F633B846AB284BCF8B0411B772DE5CE3DD325E55798292D7BD972BD75FA ! 0E079529AF9C82DF72F64195C9C210DCE34528F540DA1FFD7BEBB9B40787BA93 ! 51BBFB7CFC5F9152D1E5BB0AD8D016C6CFA4EB41B3C51D091C2D5440E67CFD71 ! 7C56816B03B901BF4A25A07175380E50A213F877C44778B3C5AADBCC86D6E551 ! E6AF364B0BFCAAD22D8D558C5C81A7D425A1629DD5182206742D1D082A12F078 ! 0FD4F5F6D3129FCFFF1F4A912B0A7DEC8D33A57B5AE0328EF9D57ADDAC543273 ! C01924195A181D03F5054A93B71E5065F8D92FE23794D2DB981ABA2ACC9A23A5 ! 3E152596AF52983541F86D859FC064A0E3D5FC6647C3CAB83AD4F31DDA35019C ! CDB9E3DD3FEBD4C2B36BA3CF6E6C7DA85E25D8A31A9BAD39BDF31FD0D1790707 ! 9DE6A078E8A409D8295F642DF492AC4F86AC84383B0F4C6BAA7C22AD5A898A71 ! D6CB34D2CD12266C486B75E75A69C14819DD9BB8159088E04D4717E576B8482D ! BDA52110AC8B8A80E4E9D58F470EEBD3CF44A1E1EE8DA318FFF3611B02534FC9 ! F4018C7C57E80570D2F634D98BE5D5EC6D95051157F0EA94A3D12BE0B4B79939 ! F82F8D73136D3337C44E314B0B16CB030D9A12E01FB667105F334C3EE965E5A3 ! D410D2F1531547A4497C355AEEB295CD3C5334BEE5232992960B757594B89F3E ! 52095042DBE6B4DA3C3AD50CA95EA9EBADA10630B500CF1FCCA7D60306743681 ! 7E428D33B7F7C40B425CD58E4CD8AB474BCE6A307BC6C6EBC15A8A96E0E2977E ! A33389154536F5C5D8CF036D07F24094E779E5ACBE5502C92892F10F4C6DB627 ! C7EC4C7BF20B39418A8A85D7FD9B0EAAFD871DDD41F93BDE5FE619AFB8711824 ! DE890E62C1969A6FE28DD3578AF43D58A728FAFF0B9FAA640962C8F35A26F76C ! 67F3548D6DB54A25CEB368B47F97EA2B0C4D7C0E7894A4F0C823C6C1922CF9DC ! 10E05600556F1C7C9AFB33A2DB6F8730F70D6BF94B1FB0887451F2FFEEF3584F ! DFADCFA9A2D4846B8F0E51620E1327D994CDF973B837D10C90FF76DE22B47CD5 ! EE3183898D156861AB4DFAD34A1E3FA260B8164E6680BF58413A553E88F6100B ! C4F4E8E972C81A5F88A7DBCDC308B4C3581BCDE13877B976B1F84330839FE5CF ! C78551620EB803DF94A5C921F8EE24F7EF8FC4C3E1653514212631F54F90E3DC ! E9EAF96E998F340C4F729ECF7AB430FDB7C0BE3DF2C0D23015820E28B743CAD7 ! 7F0AE95413C3EEABBC69E852F53EE1DC260D7F1E712BECEF2F18437DB23D8E74 ! 2902AAFBC733AC5BAA452DD6F3671859AD836C8564E99CDC4183D8495AFD99D6 ! 1F0D65B6588CE7546717911E25BDCA6C2649E3A7466A3E2DA7C7994A30AB4449 ! 672EFD00632EFA8629C1AFB7D53D801028F77C864869FE636213A69173003EA6 ! BE1ABA95EB07B13D1594BEFCC95ECB0A9CFA9892EE0677D6B6C250855762B7A7 ! 8E4E022640F93169DFA0303A0D5E73BF3E0F4D4AAD10FD7E4EB20532BA30371F ! E9F480F9513432946F9828AFB5D4AEAFA5829B2CB544E5EB634C4537EF7DF08A ! A1CFD94A52DCF0E7CE4C5EFFB01E6D50558B75DB4C8D5512B06080F27BE62E01 ! 2EEA6A0357441401458C842D3DD4C35B8F561D816B336216CE0C14BF77648AF5 ! E33912CF95872A1E1AB9A18980A0B29A881D13397C15E1CBA5D3E0B27943EBE2 ! F3003D15EB446BCFC1C231832475D5B7AA19E4CFDE119D6CD62D053C6D29C333 ! 5F729791D17B3F7108074EEF4D1BD101CB33E01004532CB0D716D2E54D169C6E ! 80163E70C0E9081F31A1ECBAE079D2A518B790B0CB2CD03DFD034A0F4788E800 ! B0CD2DC1FAFDD487C2F381EBAB2A2F3F3AF82021B211DC9CD2FBA6A1BB3D4AEA ! 4C7F3D9A5C21DFF284CCB827D205A69638E98D5DD8E36AFC1A4481B5CB2A2E8F ! D6C838DA6F81990F5ED928DC7457501B5C979FF4CD20A830896A460C5DB13D56 ! A3B2B5D9B292374A9BF392894DD99FCD6A1E655AB395E839F074D1596488700C ! 4E2891C8AEEF66568E82A8B826F9A28FF84D4D9BDA21F638EAF96880B4EBE0D8 ! 081982F34831A03BEE81FC177700C2360D2A48915EC40D5FE85B400E175D5AF1 ! 067FA0097904FB647757BB44B4042D30D1557BD0F7922D731142FD682139CEB7 ! 58CA4C8C240A0B86B1888CACC507E24E04020BF1882BD9B4CAECFA97DB24D7F5 ! AD64C69454027F198BA35881B94EE9159A2D73E450C3BDAED66B886D6DEBC84B ! 653E165176228F88993F12A170775A8D7038BDF2FE8DC1F7B98BDC02D1E6686E ! 9B834F6C0AD90780B17DFE25F0A4E470CBA84E73F2D22BEE09A040F14CFA2C14 ! 0FDA5A5149B5FAFFE49F55EEFC43831BC43A8326FEE9C7F469C0FC3B000884FA ! 41DA7318EB57262CB96FC4EC7F16CA07FE1C3BE8C2DBC8A8135953D6DDF20BDF ! 75A2B6D26074FCE752BD32FB9F5CA797775E8DB9BB9786B469A3CD65A0D9DDDA ! C2A166E454A94860EEF5B5C12172DDFC576A03F6E6F8A735FF21A3E9CCB4CAA1 ! 3064893487697986A42CB5888B2B0A79FA3C74E8187BDDF7BEAB884B70B8D4AA ! AC6615745AEB906E08BF831CFDE222F58D02B428D55E9D5A3CDE74E42D8A2CB7 ! E1A3A9439B678AD438793ABBEB72B21C58981DAF3EDCE4BB93D95F4A1E943BBC ! B3A012DE92FED4F232A3A7D60CE60B605151F9C7C18A5C653E5D6D15E5B49A63 ! 73E7A339504D0ACC74B8B116EA88C3EBA2CC631AAB29F761E5F062966AD2FD28 ! 7FFE52FA8A115DBE23E471094FFB3CBAFBDF11B7E9058313F2D069B2CE98A962 ! 64645738F02A31E2F2AC11628724034ADBCEE012721EBF0A567893411F950410 ! B20754A7510D041FFA6144AC9CC46D846B82581F20BBD001D34D9764010824BE ! 61C30D05E5C5D100A24F1917F01799CF5BC4E50FCECFEA732CB50196825F0E08 ! 8A1EC868C6D4357857EE2957E081A0E4372E31A8ABEF23C3F2EA0FEE57DE4D08 ! 61C570175C41AA0C7A3A579ADF593F18B4AE3782D2552E4E0759C32E059EE741 ! 2D8191E381731769F6648B3581CAF11DAE46471896666F18F02918B0860BDA3C ! BD5DE777672447C23C62ACFC2611ED5239D6A266FDA6031EBC5A530C1A2FF7A6 ! B4380B9A4C877267854AD1F1677CB5433F28894ADF93D39EAB94541A8D232E08 ! 22D082D0951A60F62B87DC028714EC74133A4D65F7D0D1296C0E189C4A42AA98 ! 28E8AE7ECBB9FC8DFABCC6EEB1E9FB06227F90808EF31331CCC5D4C9A6182181 ! 047902DC9FD0444FB94B60FC74F3B677758088CE6A159D940C5CF682335E756A ! 8BACF06AD7225D49B0002392C889B0FE2C71311D2596F4903D12FA20BA2FFE25 ! A0804B4BC282929BE31E0F46B34532CB5795A65218CFAE21F390792DA67775C7 ! B91A2BF4C16DE4F6551DAE3A5827F616BE9040EE6B1008DA2F99A01EF66D697A ! 6CD1A44E0A15D1F39EA8025E886A68A1E9C334327C7703EE721E497CA924AC90 ! 7723106D913C5ED4BA4FC743CEA8D0F5172526107DA65775C0B1B77179D336C2 ! 9B09B608D80B1A1E87CA1A84A833A00D980D919BFF56F6390E9D5B45E9935CF5 ! E69D003564462F750F7DCE02DC23CC215A0696B74D8BD3156A392A94F557655E ! 00BFAA035647568ED66157FACC585E411F7F428569C147DC43F6E4FDE693D0F3 ! 9917BEFEDF61FB980B85515FF6424824E2D995B05CA1E5D3E8BD8D3281DB7CE4 ! E54923E84058FFC0A8A2C491327D0F87CE4C352B724167CEE224DABA3B95757E ! 4A419594BE4F92E78BA6D35D4C93D31ECC3134B24A45DC32445725BB044F09A3 ! AA8C31EFC0A2944ACE2F2CE054CF24DB350FB3C71115518C24BDC0F7E54250AF ! 9D3378D38480E1CB9029F31570C619A28F065CA4FED5665EDB96712ABEB33B9B ! 4232C00C1B0215F08D53F7E430887035AC25BEAF06942FD1B6C442253C887AB7 ! D694C1A6115C8990B4CAF1E81DD1FDDD6B03C00055BE956BE7FD8A4E1049AE69 ! EDA8593CBA8C4A41E046C689FBBF9F1B64E5856A7FB1C61EC815A56DE2A8ED33 ! 41F370B8203D4E5B19C63AE9E6E0D26F4F3814B5AF48AD30EC9B8402C941FDD9 ! 722FCAFC638FBB835F83DC77F93D367266FA7DFFFCB567EF82B1695AB4D94D09 ! B18AC041811027229DF431F5CB2BBF6ACCE9D500C8F075A74590641C1A607C56 ! D2B8624797BCD9C91C3177818691FBB4744EDB6056464A0B95B8D63F7C22309B ! 82D6126E2057BCC9FE5566D96B7A9B201A09B0D3252A5494C8CA2C8BA8A13C29 ! 37EF2A882D61DA708C279F663D88A8E2999A0F3B6F98C49901A7631BF7708B67 ! 54D0B4C52BF4BE0DA0439E6763A7C9D639AD4092E77B13D3510DAE1475C978AC ! 796F9B2AAD3BFF35C5A3E19B5E2BF704B3BBDF68CE48BA4FA2496D60E58888EA ! 28AE12D00E9F0816FAC190590A865BB58569A91BF0345D01230ABA361442006D ! BA2C90EC2036BBAB79EBAFC3F217DBD5854C519235F9627A1C3C71D21ED38AEF ! 0BB40F3B86BB9F09A3F309473D8757AB7E638DC1C59A7F9BCD49DE4107A2E54F ! 422767FB94048987847205584309397F554744690ACFFDF5902FE5DB355930B8 ! 71863217830DD7A563B0B3A4025ACE75B0E777B4414B62A13B50C54E0E6D47E9 ! D43BF769B9411B74E1069BF71BA873B4B8973EC9BA492A5DEA58D267872BB246 ! 10AA67B143D0E2223FFB4991E583E629413CC894C3FA4869B72D19CE1A0CEC8C ! 0FF5E5A3EC1FCB7D3C4289813F0D249A11B55104BD60B2A89BEF44CC77CCDA9A ! 065B8B83B4F4253AA1D535290DCFAA4773452D110D2B3370F9E2FE5432B54A9E ! 644EB3BA9BFF62347F376839024CD5EF3C5DFD30F412DD5474B7933E6A1AB63B ! 4B12F2417C72D0543C26A263AEA53E5BAEBD67E23553A72E949DEC556BEB5D09 ! C4D7A89B14FE4EC68D0E3E9D65A64B285E53590F418EDA8175113CA375A29930 ! DDCF4C71ABB26CEB800C2C2B253AC1F53651C88A56ABE5A74F3B54CB4FFDDB92 ! 60AD7272BA25EC2F6FB759AA6E1E7964FB55AD09F4EB25DE45FD01833947BD05 ! 6266AA8ABB7DD792941C7A070FCF3A4636FBF8921C70298D42FE92F079DBA2AD ! 6149D9CF9EF7264DE6DFCD4429949B15EA90B596340713BD61926DDB2BB23BE8 ! F9DE38A31620A817420A245946E551463960A8C5C7295E3B3D6A59BCDF5E472A ! 40B7A2CDDAA43CD8AAFC411D037142579D11054A903E102DF0D0C7B5BB854DBA ! F3F086AF991F7F5D5C730F8F9AF213F25786F3EC0E54530FF912F4876FDE16B6 ! A07D0DC4FC46EC6363BCB68B83ACC448B801EC43FDD2F8BE0E93D809FF81E38E ! 176AE17C67C85FEA58EC95435434C49A950AA955D8B20989C550AB1F1C31B7FF ! 99422E1F48FB7D6F327C6DBC4695A03903DB275B94CB39386E46579271870A25 ! 21823E75C377E9D5B46655E8CD8F986372CF8BA846423E26582315A9D19E0BF5 ! 305C32B2A0EAC3ECB275B1D8BE11A37ADF524944219D94EA2C5DBDA768828B6D ! 775DA8CDB09E0570E4ADDF462EFD8D3FA3F86B1DEECDFFB699AF6507257C1879 ! 16FC615868C2D51F03CD57BA38D42995D9164B257441210084DC409B6EE4C119 ! 0B2E17B0A8D5326DD0010E4A325D5F77BF935693BC90A00A28C7B5F74817DA39 ! F47A41E32F4F92AA04D30D810F7B1484EB53AD8CFC8CE8928B570314E0F713F8 ! AF127227190F9C16BB73D2A217FF801C391A29095DA5E4974D137A0CAA7DE702 ! E20DD4755B1D78739756A5E7EC3542B96AD6844199FFA2F5F2E9C64E2DA4FB2A ! ED79869F745C59D235438251BC2E6D26112AAED20E06021D1AB896EE1F1DD2EB ! 437FBD4A25E42245C5A647493FCC9922E6DD7AF57D5D482921D1CBD6F0F02949 ! C27777144751C1E72F4EE2BC343D4AE7A8A8758123B54FB1A026144C643651EF ! 0907A376945E19A8FC7F98A034832A5820A481B0823F980F59623E0511593FEA ! BDE6EFBCC0383242CBD4954027B075B21F10472059A480D6E5ED01C3B07461CE ! 9810251A5C5643EC7403130C2246E8616CEA25EAC7A0076731FEA8CC43BCE3BE ! 933FCE61067F5FD402E67E2B9DAD954AA77C5BC86BC5E4BCE2ED676D8D8EC7D0 ! ABC5C86D82180B9D5D7451C71B5149B6B67883578DE9909317928C0A92E3205E ! F23015400A1763A6FBF67FDE3318AD2696685A1832FC31CF38589EBC7CA1C818 ! 60D2B2211E04EFCCEA88D9A9082E82951EEB123924A267CB03C48889032F2892 ! 4227E217FA28F87E01CBF27BF1EA60641A4238258CB7AA355908FE36D90F5CAD ! FE992D03A33E47CA9AEBEFDA57793F39DC6A9E85D5B289F6B862B35DBCF82E43 ! 5CD6A862F6FFAC36478C384C3BDB0148CB1FEDF55969C776E77917635B5A65EB ! F2AD351D21CD3822D43289FE8EB0FED58182997097C7E9F4373553AE1CA92083 ! EDE3BBE6C3BC7009D15AB5FEC6A59E9FD1BCC7B2099CA15FEF083B9CBF7B890E ! CDDDE6BA0AFF306C76500C945DC91BD533FF9A585CEEDEF79238C54E6168001E ! 26FEB29E523EE501BFA4F60B782B1499B07084C35A2434B4D29D3D8E2C8F945F ! A9922443B68D07DF7EAA1F4CDEFFC438B597D8943E231B5216808A85F30EDC81 ! 9DF5DD22F54A45335B4C2203887475F39D247F0E7347BACFEAF220ED82F9263A ! 6488E73C1910023E505FDEB143006C1A351D441AC57F9D52D2C6D63D78C75605 ! 999885676BBBAD56074298E0BFDACBA1830BA58E87F436CC670EE8EB1870154D ! 72DDBBF3794F8CAAA3F1E11DE29752DD99EAC695838A19BB67A1FA3829B6E0BC ! 5301610A0351AAA749F456AE31ADD87D6ABADCDD1FB3CE81C3713F48780DF407 ! 530CB284B2AC709F52EE7AD647DEF9FA4D2A867CCEF728F3D40CF34C28D21527 ! 10160B3DAFB5FE16AFC9D36C6EC4021FC189005862082BEA60AC72B63AD27D72 ! FAF3C2D89DA2648FC4C65104A069212D87144E8533CD86A6D73DC7CD9DBA25CE ! 7DA53B000266F3871B24663C77723703315C5E4A89DFCDBAB384AE7EB2F455AE ! AB191FED406F7F6EC9E5B8276EF5C4CBA041AC7E8BCEC7CAE840154BDCA3232F ! 15711ABD1E867A434E9787CA0A6D1F197597DA27ED2402CB2D84ED082E8D3A39 ! 81E6EB270DCA4E7A90E2BEBD3CBB3A2BE3CAB926192D7292CC16845B6399A543 ! BCFD224BB52F21352732DB5154FA3442733066CDC3E186D8AA97CD801DFBE43A ! 116C86889BE198DA88CA978B8C40ACB67E8F7BA499DE68A6FF0DC72C3D00BA1A ! B378B39610F15CA026F95ED8155CE3FFFFA2E2FEB352DBE14CEE1669F2387B70 ! 55B91185FBBED764266215D518716EDA3DFC9E5DB6B148A553E75AE5E38E1CFC ! 6EF47B314D54CF24BC13856F4F7C976BB91D143DE32FF49BFFC87E17885A1893 ! BA1B8E441B08EFC04F7D103C1FFBB665194B3D0920473740C55FB1C50EBCF717 ! A2359B687FCEAD65616EE89A68F8D91AFACAA0B238EE4AF0279AF5BE5294C3DE ! A7E1F5E6248C0210E7D40683F04B12A933C746ECB517CF94BBCC6E4CF49AC715 ! D8005AFECBDFB7A6B417DB8A28F8E9EAF39CEC1CA64DF37A5E66A76C26F721F8 ! A63B003A040A62F87DCF61B298F960D510BEFA453F118E59E7DE8CA3DD002EF0 ! 127EAF733D5C61B5132348D280F84D159809CC71A3C6F7373BBFD8D6EF715D34 ! 0016DEFF14AA5F960BF1BB9AC304A1823722843547BB4CA5EA4C41C6C2701C8F ! 7BDC810443F9DF34BA469A3260009B799871BAF8523C8763544DCD0B382D44C5 ! F75046AFF85F0B5A3188C2EE786CEEE5496A5AF4BCB0B429CAFC403FB983EFE3 ! 61FD9F52ADFC38E07A0FD7BACBA530D2E4DAB2592AA9564843E7E2305047F060 ! C5FE4243FA8FDF1B5D4F61ACA7850A604FBC6D6970959752695C90F78961B4E2 ! C8CFA41082B1A37405AABCEE5BA3DC2B9EA76F486117B84728EC6D8AE6379CCB ! 402C2AA89078EC992C00D53151E9D82C65643F549A572A20F05107A41BE5AC57 ! 8EDE92AE20B05E2D0C98151CC92D5389A675DFE39DF546A33A84A4C534337ADE ! B17C34E09145B37CE1EB1D10D42CC8D6E6B127A3809F7202381FDB88D42084CD ! 0AEAEB8A8288CB56870EA2BE9D0B9DC8291021CA561E2BA388DA3494E433E0EE ! 5E69DA51D0AC505C9F71562D3E9750F23CF14D2C8ECF0692FBBCB4A92B48B4B0 ! AA2163A447D5FBE86D961AE4D4251149F11C4BC269E10B48E8C42DC2484EDE87 ! 6540CB8A5EA2494148D09CC9D5014EB723739F7ABAD029CD0ACEEA511B20D40F ! 02BD96495D28149638962B6424883D4D5D8C38C94551B5AA8DF167D91517EE14 ! 06F909B6AA503049621C788228477703593C0546A84FC1487844423DB4C42499 ! 9D5905520FCAFD47F7149117650FC174FDBBB8554B8588489AB27158DF249802 ! AD977E71A7CE1C0CF6BBA1BB839A1A9E7BF8B170A75CB81C8EDBD1FB4E3A1221 ! 2C39F4A0C240CE33BD533614A14108AEA1F4E1D7043D110F4AF7B8CA8C43DE29 ! 8B603588CB1ACAF13DB4DC068F3C855EB04886D3 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! 0000000000000000000000000000000000000000000000000000000000000000 ! cleartomark ! {restore}if ! %%EndFont ! %%BeginFont: CMR10 ! %!PS-AdobeFont-1.0: CMR10 003.002 ! %%Title: CMR10 ! %Version: 003.002 ! %%CreationDate: Mon Jul 13 16:17:00 2009 ! %%Creator: David M. Jones ! %Copyright: Copyright (c) 1997, 2009 American Mathematical Society ! %Copyright: (), with Reserved Font Name CMR10. ! % This Font Software is licensed under the SIL Open Font License, Version 1.1. ! % This license is in the accompanying file OFL.txt, and is also ! % available with a FAQ at: http://scripts.sil.org/OFL. ! %%EndComments ! FontDirectory/CMR10 known{/CMR10 findfont dup/UniqueID known{dup ! /UniqueID get 5000793 eq exch/FontType get 1 eq and}{pop false}ifelse ! {save true}{false}ifelse}{false}ifelse ! 11 dict begin ! /FontType 1 def ! /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def ! /FontName /CMR10 def ! /FontBBox {-40 -250 1009 750 }readonly def ! /UniqueID 5000793 def ! /PaintType 0 def ! /FontInfo 9 dict dup begin ! /version (003.002) readonly def ! /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMR10.) readonly def ! /FullName (CMR10) readonly def ! /FamilyName (Computer Modern) readonly def ! /Weight (Medium) readonly def ! /ItalicAngle 0 def ! /isFixedPitch false def ! /UnderlinePosition -100 def ! /UnderlineThickness 50 def ! end readonly def ! /Encoding 256 array ! 0 1 255 {1 index exch /.notdef put} for ! dup 11 /ff put ! dup 12 /fi put ! dup 13 /fl put ! dup 14 /ffi put ! dup 34 /quotedblright put ! dup 39 /quoteright put ! dup 40 /parenleft put ! dup 41 /parenright put ! dup 44 /comma put ! dup 45 /hyphen put ! dup 46 /period put ! dup 47 /slash put ! dup 48 /zero put ! dup 49 /one put ! dup 50 /two put ! dup 51 /three put ! dup 52 /four put ! dup 53 /five put ! dup 54 /six put ! dup 55 /seven put ! dup 56 /eight put ! dup 57 /nine put ! dup 58 /colon put ! dup 59 /semicolon put ! dup 65 /A put ! dup 66 /B put ! dup 67 /C put ! dup 68 /D put ! dup 69 /E put ! dup 70 /F put ! dup 71 /G put ! dup 72 /H put ! dup 73 /I put ! dup 74 /J put ! dup 75 /K put ! dup 76 /L put ! dup 77 /M put ! dup 78 /N put ! dup 79 /O put ! dup 80 /P put ! dup 81 /Q put ! dup 82 /R put ! dup 83 /S put ! dup 84 /T put ! dup 85 /U put ! dup 86 /V put ! dup 87 /W put ! dup 88 /X put ! dup 89 /Y put ! dup 90 /Z put ! dup 92 /quotedblleft put ! dup 96 /quoteleft put ! dup 97 /a put ! dup 98 /b put ! dup 99 /c put ! dup 100 /d put ! dup 101 /e put ! dup 102 /f put ! dup 103 /g put ! dup 104 /h put ! dup 105 /i put ! dup 106 /j put ! dup 107 /k put ! dup 108 /l put ! dup 109 /m put ! dup 110 /n put ! dup 111 /o put ! dup 112 /p put ! dup 113 /q put ! dup 114 /r put ! dup 115 /s put ! dup 116 /t put ! dup 117 /u put ! dup 118 /v put ! dup 119 /w put ! dup 120 /x put ! dup 121 /y put ! dup 122 /z put ! dup 124 /emdash put readonly def currentdict end --- 1671,1756 ---- /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for + dup 11 /ff put + dup 12 /fi put + dup 13 /fl put + dup 14 /ffi put + dup 34 /quotedblright put + dup 39 /quoteright put + dup 40 /parenleft put + dup 41 /parenright put + dup 44 /comma put + dup 45 /hyphen put + dup 46 /period put + dup 47 /slash put + dup 48 /zero put + dup 49 /one put + dup 50 /two put + dup 51 /three put + dup 52 /four put + dup 53 /five put + dup 54 /six put + dup 55 /seven put + dup 56 /eight put + dup 57 /nine put + dup 58 /colon put + dup 59 /semicolon put + dup 65 /A put + dup 66 /B put + dup 67 /C put + dup 68 /D put + dup 69 /E put + dup 70 /F put + dup 71 /G put + dup 72 /H put + dup 73 /I put + dup 74 /J put + dup 75 /K put + dup 76 /L put + dup 77 /M put + dup 78 /N put + dup 79 /O put + dup 80 /P put + dup 81 /Q put + dup 82 /R put + dup 83 /S put + dup 84 /T put + dup 85 /U put + dup 86 /V put + dup 87 /W put + dup 88 /X put + dup 89 /Y put + dup 90 /Z put + dup 92 /quotedblleft put + dup 96 /quoteleft put dup 97 /a put + dup 98 /b put dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 102 /f put + dup 103 /g put + dup 104 /h put dup 105 /i put + dup 106 /j put + dup 107 /k put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 111 /o put + dup 112 /p put + dup 113 /q put + dup 114 /r put dup 115 /s put ! dup 116 /t put ! dup 117 /u put ! dup 118 /v put ! dup 119 /w put ! dup 120 /x put ! dup 121 /y put ! dup 122 /z put ! dup 124 /emdash put readonly def currentdict end *************** *** 3572,3575 **** --- 2490,3575 ---- {restore}if %%EndFont + %%BeginFont: CMCSC10 + %!PS-AdobeFont-1.0: CMCSC10 003.002 + %%Title: CMCSC10 + %Version: 003.002 + %%CreationDate: Mon Jul 13 16:17:00 2009 + %%Creator: David M. Jones + %Copyright: Copyright (c) 1997, 2009 American Mathematical Society + %Copyright: (), with Reserved Font Name CMCSC10. + % This Font Software is licensed under the SIL Open Font License, Version 1.1. + % This license is in the accompanying file OFL.txt, and is also + % available with a FAQ at: http://scripts.sil.org/OFL. + %%EndComments + FontDirectory/CMCSC10 known{/CMCSC10 findfont dup/UniqueID known{dup + /UniqueID get 5087402 eq exch/FontType get 1 eq and}{pop false}ifelse + {save true}{false}ifelse}{false}ifelse + 11 dict begin + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def + /FontName /CMCSC10 def + /FontBBox {14 -250 1077 750 }readonly def + /UniqueID 5087402 def + /PaintType 0 def + /FontInfo 10 dict dup begin + /version (003.002) readonly def + /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMCSC10.) readonly def + /FullName (CMCSC10) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + /UnderlinePosition -100 def + /UnderlineThickness 50 def + /ascent 750 def + end readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 97 /a put + dup 99 /c put + dup 105 /i put + dup 115 /s put + readonly def + currentdict end + currentfile eexec + D9D66F633B846AB284BCF8B0411B772DE5CE3C05EF98F858322DCEA45E0874C5 + 45D25FE192539D9CDA4BAA46D9C431465E6ABF4E4271F89EDED7F37BE4B31FB4 + 7934F62D1F46E8671F6290D6FFF601D4937BF71C22D60FB800A15796421E3AA7 + 72C500501D8B10C0093F6467C553250F7C27B2C3D893772614A846374A85BC4E + BEC0B0A89C4C161C3956ECE25274B962C854E535F418279FE26D8F83E38C5C89 + 974E9A224B3CBEF90A9277AF10E0C7CAC8DC11C41DC18B814A7682E5F0248674 + 11453BC81C443407AF41AF8A831A85A700CFC65E2181BB89566A9BDEC70EB4F2 + 048A6EB631F05C014D372103E37FC3FA317EBC9973565A638403DA02E48B7D31 + CFF6C241DC5CDB470561002FF46437C06EF93BC99352DF04393C661FFFBF4BA2 + 0723ABD9B3E9CA9E63BA57EFDBAE684655CBBDBA15ADAE43E1A2C98A3CF060A3 + D16AF8FE3A49B50A24C20EEED716E49AF6013D4D38CD9CC41A91C17E4D04D79D + 567E1EF49110AA9C34464E95D81A730ECEB2C9AF38FBA6B45E253288438B4CB3 + DC75B3A906D4357293BA41E59C35223A6C9CBD6FF5FC90C2D07CBB376C7320FF + 435A6251822BFCBB612CE630EDF826C37E95F541C21B93FCE127591D5E38165E + 2B58A34AAE37712BC58B63FFD70AB80F4F24612CFD2F1466BAAF3CA2BCB45148 + D0DEA0E9B8FBA4C4FF5B8B3CB02E461355051842BD1C94F41066B9B909DB83B1 + DCDCBEF7CD00A43E4C0B8191A29600CA197F0BA227FB8309BB539D2A620BAC70 + 8A1AB2DFA51ADC9873B8E5582DCD3ED154E5D727D1665F99BD89883D69E6CC2F + DB3A57AEB612171A88E22F038461DE03FC357F771675E34E90D4D19B4B36891C + 9D2333960400E97494F4FC4DBCE6A73C34A0409E433BBDC0AAAEBA7D3555066E + 1CFBB4515C8B573C9B9DD12ED5B6ECEBE35AD0DDEA9DB004FC6CB540B5117B49 + 59CABE5FD74C6F5B6482B42C20B5FF0467D1DBD7CED2CC651CA57852B6FBB402 + A6764DB342889132C911CAA713A7F2FDD8A5E849345D6C81025E02F5B8B682BA + 90CC9B467FBC37362436EA6BF8EB62D784B01D5430147945BC09D1F49EE89F2E + 3E2B8E6D439248A56F82F2E03EA5C7A922F2813BE6538A3A423BEBC55B345AFB + 3B3C125306749E137C647D78028AE1FBF3E1A82C260132832A9668F454D39C41 + 736717DED0A99F6B11F005F0E1D07FE84713AAB4C042FDC166AA146D7B5E9198 + E4F485BE5B135EA281FF1C1E616B5AAF02771F58C5840CB5A427FF9794F93E94 + 17FD799C78AED1DC4810BCEF4C6C51D3C1504EA2C6F2B29805B7ECF97B5F637D + FE92E168CB9029E90404CB54FB312FC7AA8A9F2F524C03E61F03B1E31D4F061E + 1677B39D5D30C9FD4673E1723F4AE3CCF38593AD6D7F61E9DF3C010E51F25085 + 35D51105E1464BA146A78D7297D4D310AD91342A0BB942034A3EC0696B467367 + 3E39D202D637E6B14D0EBCA6AD3CF22B07D4CA69C0FCBB6C93782B2F0DFC5AC1 + 5D8A16CB5EDB671A0C1BA9D10F63CEAFCD0E06E42C730C8EF769CCFD57937245 + 658F486036D37E8BDDE5670A212FB488A8753322A5B170C9662750AA958C0BBD + 8E97D8239D2A08B30416504DEEC4E506013E037C91785C674F8A6A44E23FEE6F + CCC00CC5E4D355B0871FDB8ECD64F70EE32449BB5D6F84F8C8AA2D5B1A489BA9 + D7FF2DBAA8D0B84054E93D64D3E77850A3724824914A0F821EEC3D605DD851A7 + 606936B8B9E24D6E932E16C448140FE94DD96C75AECB73850035ED9C04A1D93C + 64B21E7D4657E030483EC5C3554AEF8BE4D0FE5B9743B875340B09E01273DAE8 + F256C50A1A8F2E0417440A8BB0173F59E11523E1CEF2593A4AC5AF2167627B00 + C5EA97D125EB8A4BD4C372877ABF10F5B7B149D73787E0834BFB3084E9508DF7 + 072DD71637019599252059738D4D6BC57A9358E4B14F6AF9C4B31DB8E25C29B3 + 7A15F9953BD73ACDE5F0445A5DC406BB4635FAE51C1D8202AE31730E6F355317 + 1DC197DB0B6177307C60E5D38F4487363EE051B2E609A52BC4D45B14B6558B6B + 5E1618748794B8340752CDBE7756C068975B559615D4CD5A97CE30BAA7B2B1A3 + 2FEF2E055232B24FD8A21BECDE1B6A479A28EC80AE2CD16DB50B30B4A6CFCF06 + 491C7CD5AC29FB964D4846415233947522676DEABDA0D9535F8507D33693930C + B4E4240A02B0CE7EA288516B8A6EF908D7F8BAF9012D052C6AC96D9F8F6ADB07 + 8984F3559C5E7E3022A957982155FC9CD599C74E18328D3AB46F9DD15D1C4C3F + 9B93ADB4489BA02CFCF57DE6270F3AD2F8597BE71786510EF08142F430EE5568 + 4F9DDB792B7C46B6135E341DBBF062FBC50FABA80CD4A384157BAE57CBEA9781 + AA4416323265168AC097DE7E30A0D4750143A4FCE70A863A31876A8FA5327C3E + 36E89589E363AA2B1A6E8B09F5AEB8FFFD0396067173465B6503383DE517A6EA + 88C0FC08578398C2A721E5AEB29F4AC9BC990A50CD87BD35A11F9E81F68E7B85 + 5E5B95A4F9A5D30379EF90D78E1E466DEF867BAEFC4F5ED2C762BFF099C1C2B3 + 5E0DA1C2FB33BE1379413CDDB1EE6BB3A495331F72F2FAEB8152E8AD5FD334A8 + AAB0082A71D5574B618EA8D487B8FAF1B445F3395B1E21224F5492A0E06F5152 + 7726835C900E2E52BE3B7B654183AEDEC68053DD0AF19EF6DBC10B6FC08EC7D0 + CC0E2C8FAF8C9A4C21FB7C34E074BBA4EE64226BEC8C928A784C1BEE35B72EC8 + E9295240B29DDC2539CD118BAC38DB3917D14CD33AB45FE47E827F2A2B193AFF + 53C5396C52CEA4F43F06AC2D08C74CC85D608CBA267175EC31311EE25AB48DD9 + FE811B411AE426C9FC0B6044D1EBF130231623F1566CEA4D1C06D8032FD9808A + 94479C842BC41B675CF6B90113BD681F8D43F51D5016D80EDC11D7640FB950D4 + E709A46184406ED90D0892A4CD9062938A8205697A200DBE1F38EB166EFEA0EC + 4FCB45CDAF82EA103DD6FDD03D146F3E42EDA6496064DB3F4FC1C5280C9E604B + D5EBCA08BF2AAC90156C11EF68137DC76502EBF216F3AF3EE30DD2676D218428 + F41C655093F8B530FCA378B5769F262A6FDB4B66B83F18F050E77227E28D71F4 + 5F4425CB8D51B3DAE872CD86D7804F870BC564A6DA1CA13EDB00D131CE4F6460 + 7021661B99612629DCC20C85CF155EDC5111E015A77B0B82A8FC1EBB374B7EF2 + 361419BA93B857D5C9944BB5B4AEDD86ABCC261542077FE09701C96370168579 + 5F89D5AAA08D700E2643E88C2FB8D1D56D37AAA9744872E7C050B4CE046B47A7 + 83F224FA9FD311C955EFBF173042C8FC66524135F579B1397828870D5C9DC71F + 8615FADE2A1CFAEA90F732B6C266E2F3048FC43EDA7A6B6D98E9DB793CF457B3 + F5877E7A055C92B0246FEA8C72B3B3456F93BF36E2651D32CD614C3AECC0B4BC + F824C8363E593A6458D37408FC5B09883B280005DD24123E2D4B1B85F4113327 + EEDD9186A4AF2CD6439B46C5C168C125CA80F9EE9E68906620EE126CFBF26E15 + B269838A54224EDCFE2A373EB750D4829BFA410DE5F1541E428BB1E024AF496D + F5F1C151F5A645C8622F2EF9088D57A2811868A8A8BFCDBFCE3ACB8463AC35B4 + 8B6F44E1C1232805842F56FA468F81FF37D5D55B81CA56058558544C142EB3BE + 07CFB1F75DECB1E48C14D6AFDD455989AA6FFE8B8DC54F462B3C20E31D270BCE + 8E68E2B43A6625AC7E9792704FAAD6CE8BBE0B341DA7189EBB3E9D5375B27FD4 + 12506D5BCA50AEDC6955E6C3C7BAA84BACAF7ABDF3A270C7734EC3C6EC22793B + E67B0E288F99699D38DA8B79F2D21DD97945FBDDD132A8F0BF947950D3C0B4AA + EB7B2C435AFE54489E1930610311D718AC610C21A644F34CB2D1959B3066F39B + EADEAB5CFC6AF4D191D86B02402B00D1C5262707861C5308730579795EB53207 + A291A27A8B5C4DAE0A87A0C6A260026CA3CB620E1002E066A515D7990F3DEA29 + 0FAC962E0B82B7A6C86B1EDC54007822BAECED673FAAEF88C8109777EB79A53F + AF3C58546974F2F56E70E9B5CB59ACB5C27CB01895557B2D82134D7F02029B24 + 3331621F38E68717F5CB68A8892D0B9C0A8ED4F8BB56E80505170D44C6856128 + 2DED0254ADA4875CF56B4D97372AAE730D4C77A2940DC8C178274DF88A9EE037 + 215C6FE7B9D481EE4DE809B124C0270782411ACCCF89906A8B143D0BA8B2CEDE + E9B90465C3E57A4FD9AD2702323450256ABD09A1F8C26F08480317C08B75B720 + 70A161C99715A35A94DD5C9647ED0F8A5337B774C8E54F9653AC859485A1FED5 + 37B725A7E4BA58711CBCDA6054E34CBD8E9F9460179DA7DBD243D81A1531FDDE + BF2BD425BD9DBE75EAA333B1F5793669A215549A774597E6ADA16D323FE5601A + EDA41092730009A99BF5B5AAE281844A6BF3292D4D4EDE36B4FD8BCAEB6EB72F + AC5D3CD53D0D621CA9EA8D254FDCB2B5161EE9E80B266563F669805A3A15271A + 0753983004A1ECC7FBADF62AFEA4DAB49A178C231759857DB910668BDB07CB3F + 7E8EC24901863088B3231EE3FA563924032C91CA9D68DB398F9BD9AC0C651EC8 + 9051C9F709CD784F3FF5951DECD7E869ACC34B83AECDB011E6594347855EE7F5 + 28811F744A4BD70D4E9077EA7EC19FFCF612689F12B34332857AE41F13E6D16A + 962DB9B6AAAC167B9FBDF0068EA13412F318384134B29F3F0C399F1973A3564E + F9C3C39B5BDD4C98D81A6CB476E565860B50704BD65ABD630A5F1372F2D826F3 + 3AD47C08B8AD3176A170C369EF3CEEB190134006D6135C5B8CCDBE1C11FFF1EC + 3F6D8C46E15C4F5EB9ED9F31A129594D542D40DC3815CD075A0DBB648D868AF5 + 15A05C4BDB28BF23653A3AD96CF6AFC065DCCCB23D5D9A945F8CBB539DD3BFA8 + DB8F1FBF9B6F25B41EB4309995CA3D5D6ABD70CBB4A2F0C6364E5439AD1045FF + 72F6B45A30BD3A548CFAADDCC6C15D46F6D783D3E520215751DC98335A4ED512 + D7D19235CDF911CC69F3CF4365B678EBF3E87C456A4E77339C74930083445588 + 462529C22A96A28C5CE87AFA0C981F26CAED5A1C8DBCDDA612624DBE0373F026 + 465185A4D8C73CCD8D71EE97116F8F7D341B87FD78F9CCB9FBDA2A7799711607 + 6BBA855AE9D5C505870DC85FDFAAA130A351D56AADBFBD6A7D52055E3200F8B7 + 8AE9A00092B55DEA8BDE224B4BA7FD4A191CB1FFC4CB995FEE1AC2883AB69E1A + AFFC09AB5B9AE311A030A5BA05E2213F9BBF016C8FA80689C069314D91274B20 + 53FCC65C7D7B3A7504887525BFFA060304931672A078BCD7F269595686310E34 + E1ECA868899BC402D17EC36CE40D5041D7CEDA77F7764C9D98793F5334F574DF + E93CB10A5E8ADAE95CE63D2339557091B4B4911A4987CF21B7F1DBADBC2DD605 + 8EB72473C1F2EABCC44E0D0339EECB55DA74085606C3F89D57ACFBF5755A5395 + CA8D4BD47E4EE8D8B882D3AB31A1F0C62E74654C7E041E4FF2693A38A9796064 + 46526B0A37E6B5BF8E48E80EDEF81E34DA8F6CC9025936A4D0E6D709D61B7B5C + AB550397117F3F9D2F5A542A64DEA8E1178F7337124D6B56BA92F659AAD694D7 + 391028731E01284BFEA635314A8DA8DF7A34EA3B6B2F8803BE6DCB423A9E8015 + 55EBD90EBAE8A00298B3B6B1C02BA516AF528122C1F2B07EF69F5466C2C36643 + 0D665D6561705509B7582D8301AF3C32E2F3B9433E3E04D62117C7E8A368BDE1 + 0D4DAA1C415B2A6573116D2A169AFEF700A83F55D88813585E89C94C07802BA8 + 3AE8F9BC3CDBFD9C2E35D062B1FD6E79E1EF104FC70B0AB09D12CA027F33F85A + 22F0ECBB4AD55FE8C616B82C46CE69A600E4F767BD7A9C5F9B37A3196B038384 + 5DEF76A8884425FE598A63AEB19FA698C2AF7CAA4983CEC789268E22BA051EE0 + 20A40633D22D8F707626ED30E8273EAAD1C065F0B2E1718B5AC853ABE09330C3 + B0082A71D557169BC1559B6D285A3499D41C4CCF1F74884EC3917EB9C574371E + AFE8578DDCA459B8D22C0188A8D150437B05FB92022C95EB6FBCC954216B5FED + CBC7C90B9A1F061376A9840FB64390A6BA99CFC8279A86A730C6DBFD14C53C4B + 7277D676BD42203677E9ABEEC8C97E13DAA626474513B06F8734DD784F2FBBB9 + B3B448B8E8221E380AB4A86D3A683B86A54129519D50DD4FE63B30954D805CED + A9A5D9A39C58B65B08E1C19555E927C6DBF7FD07252B2B57F62B905D6B488201 + 213D106A41033B26FFBAC2E616DA6ADA6D560BADF10E68872806CFD6F6E19D7B + 57CF1F7A030A7BAD374F16A977E0ECB8742D034ADAF9C247DA19C8AEA74EF6CE + DAFD6B1DC562FD3B77E4D008BDE4D8C7FCA9895DA1AC9EAA01C32A0DA712B082 + 9438E77230D38FC4153E1711417B918BA6CC03203A5FF082AF880F48518D8271 + C1121E4F1386B30A7F1BC6F10EA98443F8A65C867A109336B808BC9A8E2A75AC + F950835AA84B56F59DA4C8A18859C3B68F6B6DE09A6675F639EA9107BDB67B0F + 54EBC564BC2D781B61C14363A54956BA78A2BB89C9F966C94EEFC29EE9F4E23E + C0BF750144DC289F0DEE1F8A25BB52E54F656FAFEE4BD2DA57E1306BBE648051 + 1D0CFD6A23A3DF082E3CF13197BF1B7FB22B2CD427BB78F455C9634DF989DC90 + 7BB2AE247B1C99AB2062855B2948341B0F857ACD750B59E370A6698C6A1F5287 + 72A4A9628A592E313956C242DF8277EDD2F1FDFB07CDC104275FFBF796D7518A + DF49FF3CDEC3BDFF1D290C382F244DF18005ECDABF0C5C2C64EEC4383E2E07DC + 5C82587C071E59B46B7BEF31D268F39D9B12D534344FBA515E9DE8F166FAD1E2 + 7D1558967AAAD3829D3F7EC6938D20E5379F414532976ABA844D97A5E9078901 + EAE4D0ED1F4C7EE7A2D80D891A5013D6409A38ACFA497F5A169EB7F9F4890DC4 + 62FA6A89EA48267331F086992B9CA9305E16611E6AEE67DCDD588A25D37F45B1 + 0DE75C802EE021E574B64B3969DE2E5061ED9364B646C38D4BBA86802CA6338A + 94E135D2256920EBFB1AA22D9E90C7D16853F0DF9F2D942748EE540E4FCE63C6 + 5380D7AB4ADD6CB00FE8F7867E4862D8DB432F28331428CC350CDF7F447A65ED + D7683ECA35A22ADD06E9FE6BAF060913AEEE7B2B8EE4798E437698CC9EB2428E + 74CE73F84D0D2292DE709D71FFF8901C3505370E6F1D4E28E6B7372492C65A88 + 159371B1D60D77CEC93B272B6C5394EE1D2EF9969DB2838B8E128553879A1BA5 + 2884B0A596E8FC3D1E648B7E26A4AC57DF09B9CE09B2F91D8CA618CA52AB3DBD + D005A56A420366069B73146A6F58E88BA49671A1AB7C2070C3D42AA770285143 + 40AE7D7868C0E1993506B07C086AD7D4F28CE2D15853FC5FBCBF9425D8012B9E + DB6E1E5002517659C8DA69DCEACA94F368537668843D281FC11782F1C5F71977 + CA215349EE6F20565DE3D8D8212A40E1227A4B22965FA64A0B02C62BFDE97E6F + C3C54FED4057EF9D258C42D7440C78C5E0CC58A40DD74ECED4152F70A93CE71A + 1B3A57C46F74A6D27BF98C97CCD31A8EA487260F224A3E40F52C65490AB4098A + 7B9EEB54A5A415C8C88568F7D9EFE74BBB785FA18AA27D9201F28BBC477A20A5 + D1307AA78EB8C7CAD409AB64B29E4115E45F5FADDCC80CA74B296C4265A40614 + 37F2ACD8386AC0202D6FDB6711E8CB06442F209D781E940ADDD6D881D4F8E874 + 357C533115923B90138FFE31D3577C6AAE60D768970FAAB682CD0DCA3E9A9A68 + 6393E4B772691C1013ADFFC90C508D51B02D2518ADCC7E79F7DE5DF9D18B8435 + 6129064DD1A3995E5A6F45D78287CC10A0EAFBF47223494C5EA934B1BC2F7C53 + 686C5880303F9E3ADC8B100D441D944686E1FD811C646C6DD0224F6CF55FA87F + D132EF50450879A25242A18683BD6D0266F8F333F3768D1952B0F32AA75106D8 + EC0AB703F287E847CB91FFB88CD9DA174B49171822BDE34621CF41EA772230A6 + 3088F8D19CF2364A329162D39E166AC728B267758341630B00398D64538FCC4D + E3E6CF103794C29AEF7F7E56970F6B1ABA87DC8D23E280EDC77556593D02DFF3 + 154883CFE4EF04E07E7539A4750FA1CF1A994E99B656E728D140C83AE1F196AD + 9F049188A4184C84556C0476BE46DDA8ED86888DDA3065C5091D99EEEAC43092 + 40B97AE327215024ACC0134CBE91FD761C26A48EDFF9028DA28222985FAED7B6 + A1CC891D07185666E34BEFBBF77C6C32B88FF3F1046E4EB2CD942E70746DDCDE + 002E74BA03A2B15E0529E61DCAC207A71F61C89D81B3C53C5B458EAC70ADFC54 + 810310CB04E1A21FFBC5DE2429EC0989A3F2B6AE4290A005FBE736750956765D + 637B7CABF7F9A593D9FF6C322895835C0007A78771D1404671122F9CF898AB24 + 1A5648EF8C40B27FD537612C4CBC6E584FBD058DBD4F0A00C63A79077826D3F1 + 859589B221F7F82DBE392601B0A89142648EB40BCD943E382FC7758A10F978FF + 6DD9C3C1D284C5642C812DBF29A75A50BF63F788CBEA5883DC1544ABB49289EE + 2C99CB03C1BA72C7320904C7EC94736825A793D5629EABFCEFAB8D28B6F23858 + 89A6967942A943FAB5E5B26B8567CC9606DE60329C6D890843F700FC1F60656A + 38164ED7976AD47A8E54940B9E340D61353AAD260C9273D45772AEC8E9F4F045 + 9CC576D152757AF3B74DFB9B6962001EA9FF7F62C2E36F71D9B76BB99DA7631F + 774795B8CD1E08480153496DE5E08A1F4BEA681D0C1D6336A49A222B0537ABD9 + 75A3A9D27D0B71B8913E9355F8E56C5FB3E14B9D5ACC4F87339FF9D9039ADEEC + 660B5CEF75E7C1772D4A3A4D0C8976A165766D9DBD0CA8132D17E5149AE716A9 + 2E255277FB5294A96194C462C74AAB251A36941768EDB3EC6DC2C481393ABA6C + 8BC2F3AB0BF5A6E5619BE16DF43BB09D0E9D5FA4577426BE8A2F847C25E55D7F + F67F71F3F7BEB60A2DE7183A562D7A8C97E96A43C9E06549B174431F4499FB8B + 949498C1DCBD58F8C028B52BD41EC7950B2F3F570CC86B44382CB9F2D5EA8CC6 + BD9601797B108FEC00511C0D50484F503C1CA95A766012B9BAD38F014867A27E + D4564B02850D3892796717EDA0E3AF8F81B1B4404DA8FF7D0FF25B1464E75B6B + 2A55554A12D0C032029C19B72CE17052E96D235A0825065ABB286814A465351B + 6AA15EBFC67E9FBCA14D7B8F1B9AD6DEA70CDAE988751E1703C41504A15F25A4 + AD04721DFDDF69C267DAABAAFD31ADF59861FC3A7D9B3EC7E65E424DDF65E253 + 7E22E3190B20B2221849EC1FF3DB635393446B435A51DFDF427C2EE6C45CC9EB + CF142528D4F8869E6E44FFD471CFBEFD327B5D204C879BC8F9611D5B67383211 + 5224ED2DDE9A993549039A6FE27BA358AA91C292216E9AD0FBFB5C3A34F5ABCE + DED5848E2F0E438737A9C1DB313A943BDEAEA9B30B1B224D81FA6C74E5BCC03F + 032C3951F93F7291E5DD988B44DCB8E8900746AF88AB0D464DAF82129D29AA30 + C8E6102ADA9C9D5F0086E13F8C33F09B9332242B98F6C635B4940592135C75FD + AF697976371F61D88DE453D7BC926C68F4DC15189B85BA08700A5CC26A1590C5 + EDFCAF063D28095048939FB2A21B6EF7D08E6189907A5D0D5CC24CC577104438 + 79D693CE13C22BC55612038F56A07C3BFAE2513905B0AB3F5CDC4808BF581D14 + E1F3B0E771C0E7DF3CDC1A80002989F77EEF09DA90EC20CF2B1153598E7EF452 + 4FE4BD2CE3EB3E8E41041C42 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + {restore}if + %%EndFont + %%BeginFont: CMTT10 + %!PS-AdobeFont-1.0: CMTT10 003.002 + %%Title: CMTT10 + %Version: 003.002 + %%CreationDate: Mon Jul 13 16:17:00 2009 + %%Creator: David M. Jones + %Copyright: Copyright (c) 1997, 2009 American Mathematical Society + %Copyright: (), with Reserved Font Name CMTT10. + % This Font Software is licensed under the SIL Open Font License, Version 1.1. + % This license is in the accompanying file OFL.txt, and is also + % available with a FAQ at: http://scripts.sil.org/OFL. + %%EndComments + FontDirectory/CMTT10 known{/CMTT10 findfont dup/UniqueID known{dup + /UniqueID get 5000832 eq exch/FontType get 1 eq and}{pop false}ifelse + {save true}{false}ifelse}{false}ifelse + 11 dict begin + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def + /FontName /CMTT10 def + /FontBBox {-4 -233 537 696 }readonly def + /UniqueID 5000832 def + /PaintType 0 def + /FontInfo 9 dict dup begin + /version (003.002) readonly def + /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMTT10.) readonly def + /FullName (CMTT10) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch true def + /UnderlinePosition -100 def + /UnderlineThickness 50 def + end readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 45 /hyphen put + dup 46 /period put + dup 47 /slash put + dup 48 /zero put + dup 49 /one put + dup 50 /two put + dup 51 /three put + dup 58 /colon put + dup 68 /D put + dup 70 /F put + dup 76 /L put + dup 95 /underscore put + dup 97 /a put + dup 98 /b put + dup 99 /c put + dup 100 /d put + dup 101 /e put + dup 102 /f put + dup 103 /g put + dup 104 /h put + dup 105 /i put + dup 106 /j put + dup 108 /l put + dup 109 /m put + dup 110 /n put + dup 111 /o put + dup 112 /p put + dup 113 /q put + dup 114 /r put + dup 115 /s put + dup 116 /t put + dup 117 /u put + dup 118 /v put + dup 119 /w put + dup 120 /x put + dup 121 /y put + readonly def + currentdict end + currentfile eexec + D9D66F633B846AB284BCF8B0411B772DE5CE3DD325E55798292D7BD972BD75FA + 0E079529AF9C82DF72F64195C9C210DCE34528F540DA1FFD7BEBB9B40787BA93 + 51BBFB7CFC5F9152D1E5BB0AD8D016C6CFA4EB41B3C51D091C2D5440E67CFD71 + 7C56816B03B901BF4A25A07175380E50A213F877C44778B3C5AADBCC86D6E551 + E6AF364B0BFCAAD22D8D558C5C81A7D425A1629DD5182206742D1D082A12F078 + 0FD4F5F6D3129FCFFF1F4A912B0A7DEC8D33A57B5AE0328EF9D57ADDAC543273 + C01924195A181D03F5054A93B71E5065F8D92FE23794DDF2E5ECEBA191DB82B3 + 7A69521B0C4D40495B5D9CE7A3AF33D17EE69979B82B715BAD8A5904C5DE0260 + 6C15950CCF6E188A0CDF841EB68E5A2F88253E382140F87C87E55C9EA93B8C89 + 14A36CDF630D6BE7CD36DBDCE22B21778E8648B97B7EC6742EB5114BDF0454B0 + 0EA7B1FE236C84C0E5308C871F67B973892890557AA12E00B2C20C71F516C397 + 3F3BBD14A1D0149CA064391056E45E9470FC7F6F556ABC82653B3C8049AB5CF4 + BA83C8F2158C236B2FFD4208846013BAF4165E8BB8D334C8FF2E8D74AF5DAB2F + D44788869B08399421AAA900ECC6A2D594641C121660D4B5F512938994C18DD0 + FCD9B008F68F0351D21ED735B2740CB1E0C1CCD25EB548C35B844601D98828DB + 556F71D07E081A593FF12DAF83676492A0FFE16E95717A07082B43A966C1EE8F + 8A59E1255E1705C43A23CF29A5E4A6547C93F1680A870EE7BAD8CF74D838CD5E + F806911D8FE4262ED8E7F5BC58B92C9C6D74F8AD45FBB021EC7E97393018B9DB + B1B84E7B243ADB05ADD3F1DB3692ADC5D47FEC7DF93080669E63281F1576B673 + 125EDF08016664BE73364F65389F7C3B66623AD1754ECBEF9E5CE6948D933787 + A5674279ACB2EBECD3B4E6361419AB32028A27670C9F3E18B746A10B00AF6D77 + 4EC00E3BE521C02A99AE5BAA98F793EB1228952BE67934B91472E01AF7B816BC + 56D7F19F631A1927846D800C107B1E9CBFF9D2DD513B4A8CE2E0DFD77B1ED178 + E43FA7052765E9FAF89989D490D8FEF6C536EC0D4AE27A74F474B98DA9E6B92F + 15E063DB260571979A5DE2423920CE1F59F56EB11E00E3BB9D466A8263E1E385 + 2014BEFDA8D1EA3EDA04BE32AEE6CD15C5C010A1DF7F705A2C0C18E87C8DCCE9 + 05D9163181CBA56C0FAC8C06A2990554C8E759D076B01BBEADE3B5FB8B551390 + 6C8E4A2A1C6E7D9C708614626F3770C0AB7DD2027469C77975C27576065862AD + 04E5E50CEBE907E3E991FA0C627302C0E207B4D5992BEBAB5853AD1C0D271728 + C76F40A79392ACCA7358F948AC65DC823CFDA59E1FF69CEBB6B7EC3CF21669E4 + 70D999508F9C49E2D9F8818CA53C977D93E15FBBBAF75B1E84F0BA62BCC4BAFA + 4EEC82D804C8A8C0210F3E5E258BB1F6921AF02BA9861BAD5C3D5FC8CEFABA8A + A607E547B802096F7AEB09FBA99C83C9A494B94408DD607CA6561A6E6660C473 + 62CF8D35F31D052F6C6C8138A8E1430CBA7EA6973D6D510C1A06B3FBD79D9364 + 240C1A00272DA44B89A9FE8D5BF36DC1B5EBB4A78ADBE9C5EDB485F093D9517D + 69E1AC9A8E6C9D7C324E3797CFEAD9A18E82E03F69B2CED7D5DDCD1A218BF2E2 + ED2293AE999FE2A4B5213A10083EE0407BCF8007670B8C737EAB30311C868D84 + 121149ACB4A27F3ED6C0C181C98AAAF51B105F264B5672D7F745131ABAB5BEA4 + 0C9B43C0DD9116D6DC61F90BE72018F290D26D5E9D341055CAF09C9F45333CDB + D45B7954271767F638EEC499F7B53C2CC5774EA7A7F024C4CABFB93D9CB1856A + 0C671A4ECA7C62EA5242648A84E7F3AFB9547A0AFC29593CFCE6D8B873A78157 + D337CABD291431C0A2CE1F37E0CD7340567AC206FF98E4B5A6410F70F750451C + 550EFB54AA259A1B236CA9CB730D2CEF125EC65D959441F7CC9768F777B44844 + CC9842A307C72B740680ACBBF6AA35FA7A94825069BF7696ED81A371A9E5475A + 9D997F2DFAD339AADF797F7E03E654234455AC3D17702A420EE0A597BA31BDE4 + FEB8DBA7C61D311CC90441A620164DC22DC2D373973EF84CC553453AB1B3337F + 7B39983B8DFFB3A9425F119B45C1CD37A76F905777B3154CA6200792F1759D06 + E017890F4041A385F2238E3C48B6C8EE6F5258463FDBFF7AC762F6C4363926D6 + 50F004D473B7B7F73CA686B559C2885F1AA761653C727A77D73431E9D110E76A + 2E55C68CD50F43997C9B2FC4710F8C8540909829E215678E63BB8363C4B8AF05 + 9986102BB36580D9CA95CD216B7C321822CB41B2E0422CD077F3B55E0246FDB2 + 44D5976F67296B5B0BE4B06F6E43535C21164E6C5089C3E9BA2D6B30888C57DE + 49DC8D9D46C0D5EDC47ACF2C03B72DE3B69512508539019B759280BABEA12BC9 + 385308A0395C4CD33182A10A5A229743379C2075D82D8BFCE4A66E1AA087A091 + 8F5372684FA5037D1B92D50CD9CB4F50AD4F8EE7D51F1C9E63C721CB5B9BD011 + 6F0A8DD4FDCD2B008F223A1036D90F0F3B252487DE7898F9AFBB3A9D9CD49E0C + EF4ADAD5155A98D2125ED5A3D3907F67301649519419F33CD942E8DDEAC1BDA0 + E90C431B198F646766A8FA9F8D1561B57E126EF604838C0C1966655CF31FB7EB + C8CCC434FC1C96046D38203E1791EC824A3D7AED85C029288D4608CA7668A2BE + 484C99639F121845B22EEFCE0A3B808261921AA042AE19E641769E91277BEC29 + 4594082CCB3058F90FAC4A700A8A827ACA00FCF574ABC8EB7DBCECD97F2B22C0 + 0AA19E8739B81AF8C6F621D69B8E6F29BAE233FBA655A0AF5BDFD7F5C6B9167C + 6BC7AB693D45EF2AD999F5DA3CEFA39BA48A17EE6D9F2C4DAB91AE3F0044DC3F + 5D5506CE4675AA928B0092D6F173644F91295216D8BBB14CDDE0AD524A4D545C + 1B5E284A3BF0396664081CFB4F186A84A0D24D61E82F4767C1E55A0642720CF3 + 909FA1AB8EAB78030B59BEA067DEDBD2F1D0340E790AB2777DB18248521934A8 + BB38A58B7F633DEA4291B0D5D13E9A882C974697CC6D3B49E030C94EA29B5506 + CC29C44D01B4751B453A46A9F6BF3BF135AE87A4CE232AF57B66578310DE41E0 + 2A6AC422117F1963C4D7CC306BD25A6E724E51921779F22F029733122E23E2F0 + CB340008813ABB104380C80A492B3FC6D0BB07CB8D8409E9576891EF6E5C9D08 + EB8320DFA31BAFFBD336D0C2BBC3D3B2D30368B9860768FC080D30569C7F7811 + 0EBEDA2962476113625EEB555490B8CE4C5F99D74ED10F738C61854CFF8B41C6 + 9402E56BE8856144A1A05D0B05F4CB7EF728B2F4F5A439F18C3B68CEFA41E59A + D8308ADC92EC1289DC84CF48D2CDEFF509A145BF945E1E00D552D329EBD2A7C4 + 21D58082CC8FA790E981F4AC8EAB99950678FD3A7DA3DF13778681B208DD71A0 + 7C3CBD0664B37C9EDC6B601D79A2C51FB54DAEE849F93209793849104E722D3F + 52DFAF7047EEEDDFE744787A5801E4AC2C3D58EC5DDC15FCEE03990C53B0C57A + FC54F125A04C8E4A0ADAA725808C587E7DAFB9F784FA2875689979D316DC22BD + AA36B306A1ABCF907B63C6476737B746099973CAEA8C1E2C5C41F27E0F7DE8D7 + F0D942E34E92F43FE902653D4D2EBB6F3B9F7928B1550A82AF234D45D028F429 + 067652BD3D391BF423AE72B9CB1E8D91E898161BE3A7849D456A861A2046711E + E934DC59442AE7D81661CE8EF727D8D7DDC0270E937E40F896AEAE6171661431 + C1025C53172F9D366834BA0054FBFD84503FBAE328B6FDEA180F8EA35B1DA937 + 5CC3B8F00C206908C2FFFFA6A7AC6915D15EA44BDCF29E2BFCFD4A849535F19B + 0D307C696BE8205C7D84B9C77F02EF27D911056EDBB4080E4D3ED72788666CAD + CD91B0ECE27A177DB23320A7FA9C31408B4D02D2A4B1CC6DDE1A6CAC3D8EC1EC + 2226EC98E51046D1EC26FA20EE62D24747D83CF4941DCE5CCEEC0DBE387149CD + E05B19FFCAFC0D117F9A3E60DCD4C815228D98EF95EB559AD0ACC0D50FFDF714 + 56C3C812EA5ADBB013BBD956A7C4CC0ED7D3E25D5C9AF5E626F18297F75D4957 + F5B0B33379114B903FE98BCF35C3FF76FEE1D9AEB711F2962276531F7380EE3F + E368720E0292A170A15C5539B1FC7BB954EE2624B504CB8C805B8D31AC38307F + 0513606F09211AE64DAC447693B2A0AD15E9A64C34F5A911ECD0ABCA90E9791D + 67C6BD202B0858EF96E7722305B8AC02B01AB1706CC6AE875A8DDD15EE349046 + EAA65005E7866B506EDFB7A5A2AFD5C9E9DCC821A79EE9C1EA2C7BBA32A40BC7 + CEC26DB1AC473C8C3960ACEC581B37D6569E8C8C42950BAB7930B65E1570E3F8 + 9A7FA719F1DCFDA45A3BF2AAB32C9A93BA3552608A61C623DE59BCB346E87EF5 + 9CF025A87803161221C5C1C6F6B3403712C76E9D755C7BD68D7F2DC03C14CDF0 + C1BBED1D648B905B4B17037B7263C1EA7A7F06FAAC4E09E08483A8D714C19861 + 327CD9C32DDF850302DD6DDE24912D00C22ECDF3CDFB18FA831A41A7488EC203 + F564CFE30D506F0829A96D35A7E09C3DCD107D589B627A15B55C5D6649126BEC + 60B88C55ECCBB4E680265D9EAB4CE22965D3B1AF759B01ACB0D0E6C92B6B4EFD + A81E6A648708979487FC591CF09631310D46891423F4EC159A73E30D8DD147A4 + B0EACF6D45D18CD16CEB8176F03ABCB41F2234747B9733C8FAF34AE5D43D3BA5 + 0CE0FACFC9B087F84FB6C68678BC6E76022B1526D6E5B3A48EC1A110BD75F45F + 1C4DC6D39F254976453F57DF873B7D635C80C42026DE020E5BAFE0DA0D54D1E1 + DC634D2621BA184347E5252F645A6A1DB7657C48124186F0E4C644077457C24D + 55753C651A9A7B6349867641464B515B821349C795A645420508673B93750D0C + 7A3B33EB1F09782033742AE8F3A23FC02284E6C03818FADD1731361542E3FA3E + 75B8D52B668C3E18A4AE967D0FC3157083D952AFB8144D549E69EAAC51C279C5 + E5D88A0D9D53013DFFB4352A1598FF84DCDE6FA32FC377306B9B92C0F96EE149 + 8CD55E7B2445B86CCA7A547FA732D52D59025129FD8C6333AC0DF4F0CFF6287E + F2036D5DBBB3B91B92F12FEBE0B61A313A4DB5A9CF0BB3DDB781A56FEBFFACCB + 8CB9D1D3DBDBC4CB6AAE6769E470582403CB920630221B68BCB625CD4605FA8F + D3D5B7A1A28D15E44B38E92E906C138E72C15B86F64C38E23BF0440052A8C914 + 54397F49DBED99D0AF7CEA3B0A05FF37C2D7EAE1412567E6776333237C31E3C0 + 49949EC8BFD6E0F6446CE2D4DCD2C1524A288818CC5D159BF8463A847AE4A2B9 + CC8C58F822804B81B13BF4F2DEB6229C4F51F093075581791D02C36A13B855A0 + 34900AA7CD4F1A797652656FE3A8425A38F421C4CC0ACA1CDD44FA6B31219276 + 1CDE1CD63D6A58CE705CB56CCA1260F9B86E989019071563A9B4C274A87558CA + 6EF1660D574EDA276801F0057740E2C3B80D253D697736484D892CE1AB128B8A + DECD69712F5E70E895FBAA927E8194D792A04AB6CE205E04E38A433BBB793FB4 + E8BBC4279D58A223C6673D909D6AFECD246E66A52F4CB35E5931D24C828489BD + 4ECAF621A220D8ECF702BEB01C4FC7510197D3F6D15321EC87175ADBA6434ECD + 2B5A306E91375CAD22CD94301763E4A8B981472890422C5488FCD523C9CB17DC + ED22FBF12D5F7525D0D6BCFE8CE85B0DFB1D6F989C267FFBA0A996D309E4A934 + 3DB54A9D29C88B9D55D7300DA3D46419256C5A07A2A529A8DE8BD1727281F5FE + 97033D861E0531B14E811378EC1AF1CC7EE9BA2B07D935843D3053F673979F8C + FAFD59D555B56CE338F606747238B22BD62C42BB7238FEA335678D474A643570 + A9E7B4970E8C541CE9DBC7BF70ED7BA33639D6744A18379455029E934C95E2EF + 639C4848CE9A0879B51649FAB023A71782444B451F92A34CB8A124270CCF86D4 + D18EEF5C1D2B2A29012613851C49F50702D63BACF95EE2AB4D72B375E0A62615 + E0991E130A67ECBA9E05329B740708F1CB148724C3A6E5E3AEC1F88EBCA398D2 + 1CA8827C977D72734310233176D1AE26C55CF2CEACA62223315C28FCF6305C7E + A22414D4739A059F552F1F9372CCCA5FED4F9AC987942848EB498900269511F3 + F408CBEA0659B954F5F1B18AE4FB270213646F9B28AE4439D2BA2D3E0AAAA780 + 5E530E4EFC8A060EB979E12191044509DA0C14397AFF949E12DC970658D5EAF5 + 4EA963F5BC1407A32F3837CA6A24B7F3D60EB8E6222B702E25ED903F9D21AE50 + 664A095009BDEAF4B78DAF94E5A55D48366CABF07791A1684B2F54EA69070844 + 4F031AF8DF416C2D3679F8BA038B0DC9DD0400CA6B34667BCBBC07E62C1668A8 + 35A8C57C9048A7227E672E89681B54D662079A189A9E96A3CA96D8DD10189B04 + 1DA49BA2729F1CA585B1BD5C467295285D52E47CA904235A1A3E48EFAE9EB6F6 + 01374125CE89D53C276858668CF45D2F092DDCAA52418E0BB94C2B8266B4D88A + 5D911507BB1DDA3D8F6E7C14A91CA11AE799EC42E993098E18CADA70BD2A1D82 + 2C39326C6E3F9E84CD9758B9AE43D79BF99E6A0CD713E95B3D9B7DB90D127DE0 + DAFEBF850CAAACBD860B5DEF2082F1ADA64B44B193C4A1417BE221FDCA36456C + BE5934C8CE3ED55AE3A11697C2D682B7D0F72D48976451D205783BE25DBD2507 + 39C14FFB4BB828DFD187104F38A7F11D5F0698C11E8C1D4F107CACE573FDC4B1 + C56FDAE47024D6FD16A2FEABB434CA320300FC4B6C1B6CA08F76C60B7C08A665 + 99F404DBA8A2A1EB18EF6750E4EC186E31561A3F080BA6562967546715859481 + 7BA782940F5C5D06626D6F6A412CA7C13820EC7C1DF23E15E5829F698CF617BE + D940523E4EE4ADECEC48C24297DBAD528BA1DCE7AC335A1D15D55415B108EFC8 + 6D45030D27B3EA63B2B4CD771DBE66AE0218ABB1153D4B7482289D1313CEF184 + 5C960B1E3C3C953912CC6F4521D1E15636C1545EEE457EFB87B88C9E43CC2F38 + 6BC4BC96969F4FF28ABB06F4454C01CEF1B6DC538F1E832FC1666D977E5A881B + F72F1B4C7DD4BE167A5535F1163A0706F9A0B26400178DF8A128FB5EBE6A7B81 + E478AD183EC06622B591337B9F1872AAEA356F4FC67EE767B34CB5A4D90702D9 + 39FB846947F4096FB3DCF16EC81455164783BA0B5D723060DAFF411B68307E81 + 7BEA1D9A47A5AA3D648E618C83C60F060029E6EC4D46B045FA7415BAB2AD0AA5 + ED9C729C24136F6AF61E6409C0B5CA760B16225641E268A68CFB8260BBEAFC77 + 6626EBD97195E77CAB425CFB0096D805D9EE699E41680D095AE9FA10122A7882 + 2F00F495C9EB2102DF0D3E61833BC0A2E468C5CF7AB430FDB7C0BE3DF2C0D230 + 1580BAA25D65F599378D873165482A1FBB224AEA89C6BCCFBDBA42AE1C5DCF41 + 06969F585CD3B737D1388D6359F5468D88FCD2279BDB270F6A858FB7D2ABDEFE + 5EE8FB79FA437F8F50237B92C307B73B0DCB808D07A9C3255CB9B3B17039CE5A + 288103D05D132863FB522A02CEE3839EF9AF7F07D99732F0B8B384745369FB3E + 7901166478F4A16076A1504C5E98D17408494E270BBF4470ED12B4332422679F + 759F1D93984D7E506D16950DB6C2682FE1379EFFA6F6C95DD71F6E55BE3EF6AF + E0CB25388EEB436E6527806FC75484133F6E561DEB979D5C1FFEFDAF2A6D964E + 03BAE0BD593C2992AD84569C81050F7A793C5263E50C2F50B98C4CC703EAE17A + 6AEDAACE312DAFAF5278D125B6EFC5587484F61DAFF46B87B7C9B1EEDECA4859 + 314A9A9E2248467DE1E54D90DD671660B9040B3E0DD982260822177EFD757266 + 74A16C83A7FB168016A320D3DF3BD7726F1F4EC90EE5DFE810C96B099FD4368D + 906AE4699049EFD37E8EF058D4B97BF71106445AADD4FC6E90615A0066823A36 + 673B8DE32322BBE861AE251226B4385AB28702831270DBD25D666FBB0AD7B96E + A44E891EA1EAF0F87013AFC982E33D67A28E96E0C9CB99B9E4192536830D9901 + 931A8CAFA41289633B20BA3BD7AA3414B6DA8D57CCF2FBE39920CC06361F075B + CC40335DB9A0071CFF77F6B7BB47F3100DBDC9C4A58C2B81EC99E8E966AF3390 + E3FBCC28BA1D79961C8A1584266454DF772FBA99664D74D4A89FC82FFEDFCFE1 + 4C9E4A04291E803D142E37E7ACA66AB279378F2F192FFB2B5BBAD18B95F03136 + 2CB594A3D6D3F8576B90A6C4DAD6D6C8EE07AF682F925F01D0B26CBA347C03BE + F3B0585CF4539FDC66915E22117078CC94D621F31DCB3E021998A5D6EE94CA4B + E214D07517283D56973D8E4367392BF6C1150DEBF459D141AE0941C1C8C5CFBE + E735D796E365A1B0F60BB4CF2801EAFE4889EE5F338D3C4885368281B3C95CCE + 251C28A90D318A8A0384439B38D63B94757252062EA44E88509FDD2E75FAAB71 + 7329622828B2785C1A8B26351BC7448C1719C88FE99BCB73F7DEA427FBFCDF4F + 00EE079B0C712F7D2C8DF98D4830A9D8C8B70A8C5D54BC1DF3171135278BED55 + DA1CF0E696B12935EB59B606AA3C0CC50C7A259AF32F4C81D9B39470D9993CBC + 8644403D2833B34AF40511654F96BCE0064860F39849DC62E4A0693F75308FF5 + FF450EC05F142D5E300D3850C66D432BA581D5D8DFA97D901589C53181CB5057 + 7FA8B2C95DF751A861DD1A614B2F32ABD284607F40B3462FB05C79DCBB586B43 + B853D7F77AF5ED7AF2A913FB2CE66241C5102CAEC3992BEEF19A4F760E98EAF5 + 063E373A084CD6829DC18D063618B4AE443B35B63BFA956368397A69D41DD715 + 6C5ED849CFCB2825CCB577C1669626E2C87DE60D69559B3CB98FAA07F1893EE9 + DAAAE01D549A252D77E79AD37BF64540DAF7FDF2FDF4017F94D9D89F1B6F249B + CAAC5BF817A1979163F3A316640E382B501A6BE18C334DED469CA5643FD07D8F + 6E37275108F7168F45BFB5024D4FFBDB140741D2C8AA4AF19F22592587A05FF0 + A324A0DD415F312D653513ADE6EDE9E560BA16573295F6B3A0427A15A585A40D + 5265A4CB711011332AAE28B05BE6E4B11B1B3C178225B2108D94089E6544907F + DDC2496C2624F6F7E45CD885C5E032FFEA7C337BE414E421FF8AD3D0959B08F6 + 6B8931D93180F66A13E86ABB8C7F755D67838B8E8B5A35E6BF9BF3098535D75A + 3A8880D5E2B1D9C87CDF16AE86047B3D6CB83D9A7A3702A2428BBA8209D50F64 + 7728F58AFB5CE3F8E8387EE3F2ABFBA17B3F0E6D549E7C6D13BFC785759F32C5 + B1C8A525B1CED15790CF637B59BAD929E3E3E52223066404D53CEC7C42236ED0 + E509521FAD3CCADF68D695660BC6A6F743E66DDE0A4A395F7F17F5D533E82963 + B831C3F3A7BDC6A6F5F62F5F7F9A3C75C12C7E401DCAB10411FB36B96894B6B7 + 765205D82B57A53D0148BCB96CE67468ED168A7EE08120D79E30FEDB84C86D4D + 1A103694E049DB8929F2E389124FBA0DBA9E4CC099AE441600E63F70978D0C2E + 0B21352A2113D96B50649491592406CF1EE84B5AD03265040AB41503D2FBE78C + 1B0726B6027551614D756C17F939CBC1FD3EE28B99BC31FF9BB31C292002F1BF + 67BA8B632D158A299E13335EF69FEDFBD28BBF5773AD17D0ED5623F1E578AEA4 + FF9F8E856950CC7A10CA01238A7371B619AE8C08F51628F39E7173F60745F218 + 8401AE34EBF1BD24B442988AE5DCE4EC0DA8F922D3DBFB6E2C47B27FBF000735 + 2C6EFBACD68367409253A4DDBB04501562CC2543F368881E5062A25F890C7711 + 1A6C3C5AD462F825F1D340D8AED4AF056CC26E592C0337EA2F1DCFDD91F00F82 + 11642DE4E37B381ADD4976C0C850E31B6EF51DD65E1DECC56BAF0D22F7A4EB91 + 276AB6567430CD58BB1F3F685149BC5AD0083EBD3AD39976C921024B55FC6DDD + 3478009D95A97CB0F2A1FF263C72291E18515F5CC3BB29A622139213BC77E3A4 + F5DBD8BE65E922D39D0C9A4A1355160F9A6B1EF22EF6C2099ACBE1FCDB7E7C02 + D312BC14113E4C2D09772658701AB0520A6974F24809EC4D35B0E4C29B004835 + 087AD14CFD0DE38561B1C61AA4157F7CC11191593BB6EFBBE85003091F9D5262 + 3D89A4527BCCDC19CBE16973BC44D7799F1A19CE476848430A7A8423C64DE9F6 + 8745BBD0A12852D2AC83B18E2A2479BC1900FA6A840CFCAE9342B4D0A858F8A3 + B7E375FC626C6784AB0F7B8FE4CC012C90068953CD0554E046F4C249576B9551 + 7D685A8FBE21E9B7BDA528E311E5DC3B1128C3299CE786D1E24A8B87C66DAB1C + 0E1CC71C6BAD6E8C7ADD190B894AECDA108EB4BD56A257C2E28E5F570774C972 + 00F0601ACB1D1B2C6737D6F1401CC1CF6ED9BAE208EE69B800EBDB886B542E94 + E57F17A05053D888D6C101B6C8FE8C841C25A8BA85A9363FC512D6D893351AC0 + DBBEDF009D69522D40693B0B1E461C5432AD5A20EDCE9F5858F7D48E2C2A2829 + C0E0EBB4826BB2E584A5E61AF553E4B2DA0E2145BC70265B6ACD1C493E9AB21F + 5E97F5F3CD6C9AB94020F5738655897685B69203BFB3D601BC9A46AF09462728 + 6CE76585722024C445271DBA3DFA5BB7F6251E100F29B27639D712BFFAE19894 + 1B7DEF345BBA213B3DF67CC19F06AE714057F90F1B5CCD48601E8AFCEC2BF71E + 56683B42D74AF04FB95130181253E980E14ABB8F849546A7AFB4BAF575595AF8 + F6B730EFCEA25C4AC01E4A64DF3F74F36E773AE887DDE805528C27294D0F30F7 + E8F77C2A44865D97EEB9EFD4AB7C41035E362A2B90BFCD7FD07158CECAB3DB9B + C8F91CEEEC80A9BA0C60186C9A50C00718E0FC8E6097A664A4C4B321D6146C7D + 0392CB6C88A4648ABB22FD71F82D85ECE54688B082A506687AFF494EAE0A152C + 23E511482F98E98F1030E5B2F8C5F40A58E52D113B3FE833D0223D0FE85D9600 + 9E065BF3653113D486F53D1459BB3BD8E8BD8C7E18F41D7EBB4A70D4340541E0 + EA448903D94CEA9D521ED856B0FE28A72FAA4F9D8151A44B44461A58A006CB50 + 3FC86BFA479185E04FC0B047104AAA015299930820C8BBD90E0AF87EA5404397 + 84320814C4FA99AC16033F41BF6EDC2A3403E798B8941D9DD88FCC4E4428D21D + 4E60FB89D5A9EEAC9EF2741ED1F8180623F6D3AD936D5600B2DC6DE55A6235FA + A9A16931B9DCC55499B640F363F65CC81B91DDCE0CA3E50E72BDC4D5F448C457 + AF1DC3C7F38939A6B325C4AB1A8C283F3B25EEBE6A144D303C3C8F935A6A2176 + 817DE79350B574752E140F608B04EA1CD5FD3CD8874FACE37342768FFB574D07 + 4514D304601DE4531980F5477763D47AC058910265D01A48AD9160CFFD358B10 + 24639AA7554AFE3D8920BE46C37463E71B6CE2B8F6798A01A905A9EED23599D8 + A818D847D901D405F4843840CC0A296F59309CD16F085B3C76EA4C19ABBE3AA1 + D97BEA533FCA29C31C9781128DFE5A1F8CC5BB81D5E506C3401F54620BB1C462 + 8448BE8089FBB908B4D90DF5E382A0246073E46AC45E1DFE62C820BDD392FD3C + 76514F4C47BC1BABEAFB32D697CE621A8E1CEFDF1A910FC2C89CE4DA17E06E84 + A2EB9462C9C83FE7BEC4ECFEB38C54542D8B088438B765B055BE4C31E8C1BC2D + 32CBAF963464922E21A316F6E2E6D53D794F36D579D2D08215CC724D7CDEBF9C + AF7B3D88FA3EADFB3FC7B750A44E46DC0CF4D9343ED935853933110E560C0AF8 + FCC9DF07C9BFF1A83CC4651E0AEA83F5A67D88F7D0B219E79EDC96595160F591 + 5E8C3885EFCB121BD203AF4572F966C09A59DE83D86389F07F3567A001FEB241 + 7A96DE158C54346C1EC97DD31E6560F46BAA988671A46829BAF7A441CF077E31 + CA1896C44E8CCD90150D48AB2B62CCD3FB6BFAD3307BB7EF55FA0E2F5ADB3DC7 + 1C50EB7423DEE791C64EA44DE301D6D6B324947E2F679C12634AC3A0E21A11A5 + 8F6D0E1095336E01D754170006B62442C12AAEAE64A66E2ABA8E9AC613F628F7 + 6BA9395FA195E676F1318B114D9566447914076A6ABC5B712695E87460D14104 + FC77A586010FAC5D1D172D00313656CA863D3F7E473CE8FCEBEBDCDA467DBB5A + 6D620F7FC87F4C9508CFD30DC1E22E976D5FA4BC86E84D859005B46DE89A49E9 + 3ED0C35A11E9FE5641973D60147211BE2ADB7B0ADB1CA055EF2021CB3DF9C8C7 + D5D94C4B3ECB43047224A46E23DD319074C7C959D5411E1B6C206A79EE4E51DB + 8970A0163084DCBE14F6CBA8100EFE1976F083F1D0A9AB03EEB82651214AA965 + 7BFF69ECB58D15165B494704725402C756D7660D881C5E2501291BFFE8C8C2BC + 63C14EBD23D5083FB1D0ED21AAE569A16C9CBCDCC61AE4EDA8BE5638F2997DF2 + 1FC21CBED006BBE636F1AE21B54C15B9149A173E0A940DAA518B49D6C267D6EE + 9BA64FEEFDCAD3DA06BD8E558FF04963966E9B6F104FDDFFF7A2A085B68CA534 + CDFF1553C3DCC435B430A073A880DE68959684BB793E02807435B691F545CFFA + 299D6EA31270B13F6235107F09E09D3F2B2C9395474ADB3965BB48E38D959E72 + B653E1799E2BFB6DDCAD5E1C8FB21C65F9DCA556754F17A20D1CD9876ABB5782 + 1708E5FB350EEE8077AB140F77A325E2029457DEA0172C22DF99823470BF5943 + 4587A3074D891DCB4C581FEDEBACE045BBAA742E61297C179899D3D869468D26 + 4D8BAAFA945CBD92924B59EF633739CA32BB4707265611B248195B90B51BE889 + 6C0C823266A655444D925D89FD7E49376A5F1410A722270F8E6E0699AB7B0FCA + 2CEA7F8EF31C96066E85F59BC92D500D41ACD51E0688CB33A871F20ABC9D79A6 + 3569993AD4F45B4585126E69D4B47D9EBE7A47859F982B5EFC37E801AE043A5F + 95A384A9F7CE4B69A44C7F5479F705589E5A11C60F85EF592C7C0F3757A8EC18 + C5D34E39E6D954EF39D0D2CA84301B945962214DCC7511346851AF9C19607EF0 + D9FB3EE4784307458C536F92A95C52C13894C915AB9D8C62BE4D7978B730A72F + E539EED5DAD13459C6EC90896173E2DBCB93AFEBDCF500013CF23DB3F8BB1F3A + FC54E4C6732D2D6D7F376B663960C8DF4B562C47AA4989EC41FA4C193B10F680 + 16E800F7D7D77AAB041386D22F88A92D8936C7964E518E75B044F3282F6140BD + 495B29EDFBFAD9F74A56A2686959CB34E40FF2F772C24664EFE4E6EE486B5805 + 0557F095C4D421223E64F7133D8D510561259A182049D34A3A4017640B052832 + 323B65884AC2DB65D843E8A3E9CBAE3775A5C2A3AB701369C95A06157976EF62 + B1691DB4B9F10BC985EE8CB266B8C4B64272A1647086F144D0D7F71938F34DC0 + 5D8DF3152714E6A9D97EE1F70ED43F598AF97F5FB29462858DA60CB4D250A20D + E0690CD34B24BF30FDA1A97DD29E40C0C7DF12F039A920FBC1DDB0E271D18B7F + C560B2BD8B1E8077D2BEA3307273132EB33AE0F8CB8DBCF2B712D4A0354A0C35 + E57738E1C7FC995E96C4F60A126AAD1E1D1DDA8B51F51C56F7B526087BDE12EB + 6143B3BCB7EBDEE1EF6F0A1A3CF1F779125A202BEF50F0E2B5F556CC20064B0F + AC7ABA30677391F1E73D5CB18B417A7208B05188FDC9CC5497861E7A5F8852A5 + B5AA742230610C8D83F4C951CBA659BF90092F0CB2172F162D39AC41378152DD + 2FC84FF83A0E7BF5FDDDA7ACA0BE10BDF9809F9D064A0BAC6162C92DE06326AC + 12442D20E550FE667A177A21D584912DE5331B0BAB0587BD7DD38A8D16E181C5 + 6BCEA6DD9A1B42B8C7251D8AB33C41A1033DC086B264F8B6BBF5B0BA97C99C34 + D8B20723380891CAAFFF370EEFBCD54039E96A532165B57E27A5E3B038BFC365 + C1A0E00618E070696088E63B5735F7FCD961A40EA8EE189E96C70B6DA53388F1 + 7F8909EAADF1D741EEE40032D7F93457CA4449C46ADFCA3163831DDA56FE2CB2 + 190D05AC0C60BEE6C572059F312AB3094B1A5F94D2129A4725D367DD625278D8 + 554E9FBEFC3708B3E83D87F31D80B242E648344FCC18128DCBB1D56F6CD8C1C3 + 6BE080D87D632037EDE74FC9F1B2433D62E2CDA0FA3B30C449B9C54043797C9B + 9DCE84AD556731E3D5AEE38F3C6B005EEFC98C19FBE5F786AEC0BCCC5815EC06 + AF41C6677A59550DB98AF1CACA702928193E331FAA988DBA1BC95A5372A75664 + 726B0AE3BCB87974A7AAD2395B3CE3874702EE51D1F8046B1C963AD4E82A74AD + 3EB134E6796A80C7233081519B350DDC8F3B8C4CB2FE71837DE89A6F0375C79E + 6F5E7B8509CF9AA15444A3C9398BA39B8570080EF488321CE5364DD89767E138 + 39FBC00517E27CC866554F1F740429AE6DBD30CD73C4B612145F4D862B551218 + 6A188D5FA719A16C640CB3FF8B88D898836586FEA2A4137429B08265051F1990 + 7925613DF0B2715856C1BEB0D5AD58362D9EA8FF2D97D2BDD9D637A20B34E08C + 645C4DDBBF7A4CA2E09B307D37EA061800C02C91D2E4AB90D9B250DF739D50D3 + CB62A2C2FB9A6B418EFCF20F0B1903418265EAE5E99852DE2B6515160D0D39AD + 6ABE1A0B4318D78C44730E50F868F68032363101DE435B4DD2B4C595D79B4826 + FAA76BDC6B4B899573319A05926B4075CBA22569FE0A088D27729E433DCBAE60 + 096F54CCDA15CB83D5FCBD8200FC1590941AD503C9096E3D67A8B98CDE3F245D + 32E468DD7B8976FFE627DA3AF4DF9C79E54099EB00EE4FDDD9E1D9169AA03991 + 7C810A09E793EAB014B1EFA30D24FA6A8F3746CC7AE5F28146CC2483C4A0ABD8 + 1889AB40382FFB44EE3F819E184A8B70AD235C1C927DC9CD0710D4C6B8B819E9 + B52F29C4A4A9B8B67361300AD672D0834C14D8DE91AA1E3E380E81840BC36F5E + 11DEE396CFF9A809952F25B26C659935B6BC6433C3FF6660EB84F590556982A4 + 3EDE38FAF0D0E068D1BFC1192B3AD49DB03714D0237685034374D4EEB5AD28C1 + C43EE02C2F77E06E8C5145A7385E8DDE436FA86CB3BD9039D1BD8EC4E629799E + 775BEE5E4BABA9C7632E6A62B100AC7FFD28AE8D186C157A54D42984F87B73B5 + 3DBA67175EBE62605D59DB6CDBD4D13BD117A24724B05FDA20440B61FE7E3C49 + 29161822AACF180E0026A82FE53362C2941584868B2F2473BAC29D7D9841A28E + 462D6C8FB9C9DDFFD640F43F9B28D533A48B2B9BCB0C001B1552E3915FAB931C + 6D37A92CC7779D83D2D1A3AFC207A02882EDB602ACD31C62E12E69F19AB20109 + 44F444235CB11312C20DB878A10E5EF0F516E75190F6F2EFE9AE13B058618FBB + BE8FBCA23F602F8F781D79BFFBFB0D1C1D3F47DA98AEAA68DD52D3A5E6565DAB + 50C5C2920B33610CE9A764F6966E7912EE232C0D37F753971174867BE9F68068 + 5CC128443A608F2CF90589806B865650A951F79F2751634031F59ED1F7EDF042 + F20E96EE2C5AD862D2E70D29B262A1691E1E481C34877647E84B8BD54BEAE277 + C31F0AA542C7CAF62B8375245B7C5CFEB79E547AEEE4E83CF265C90955DDBF99 + 72EABBD9746B5C834F4DF36938EC2E19109A1CD22D0D3856333EBED92C48FA5E + 39659525C1512E0C50592957D27750336FB0DE4E401E238C4967E5B24AC2E80B + CA6FDDC930AB83276D034E195491F7C9662779BF9273B7F4D48C448EEFF194DB + F9DA81ADD27085D86B6780CB0843B6CEC3F714ACB8C18037A73F47B15E1CB007 + 4A2FF55F8B58FDFD7C83BC9DB506692DC3734FBB0C8A41B4D7E30144AE1C8092 + C854F4FCEE95E64FC69FCA85A40B77DA2FD88D95987AD38E0DCBDBC763D19EF5 + 914E021F41BA70F853F3F8523D76D6E82FDC48E1D689383FB22B1B2CC2A0BF53 + 30AE3EFEEAB5B7CF1E8843B314C05BC0CE2B6208DC479DC56A441BC156E53717 + 317B6726FCEE74E51A933E50C8E5D8E07D08ECF03A72B6C12D733B5E28F8F9DE + C09BCDAB9F3A85ADA3C1A206F77E957F349E560F969FE827ABCF5A75C23C86AC + 7D4F994C9E8B1A4846CDD582BDFBD1F0345B3EB6EB5308390DE8CCB077D3CC27 + 836016047A8B74D9C1A3A44291FC9FA3401B0A25F1195C102577CAD6F67B4601 + 7464DBE1A25FF8CE0875583C26824FCDA0896303C9AE3728D68CD9A5C6E8A330 + EBD5F2DDDFAEB7A262DAB8CCDF61F065B0A154F59D6C283465F4B3D2AD9380BD + 90A6D3634961C87FAA8F471BD7ECDD2F3639DFDE556E7C56C81F984E972E628C + 185C70EFF2359367FC50B6E4F40AF6986122D3A0D17078B0C4A3C45FF65BD50B + 9D7097935AC46770E0D2062677B44BED75FEB1DB6795635CC7F12ED9046BF004 + 13257833C45499B53203C68BD8917021B4039804D50684BC2392905B3D72400B + F4A486573FC896C57DF54C032897377B301E1BF2D75F10A8FAA738E9EA68D0B3 + DBF1FD8E1DB00787490941DFFE9602201EA98B43310FA2087074871452278E01 + 2DFA344D83468803C49E129B6CBD118B22EE160FE0008C01D2AB2E528E4EA85E + 0630F5B9E219C7409EB977D73A16DB0CB4C51D19787E27C92807BF50FF9A6ECF + C1D3ED2F8B0E094296F4E9443FDA35DE5CF7AB46C37E2075C3952FAD218DCFBC + C4C687CE5AF906B307C2D324421DF5D89E34826B859EE1669497898157C81ACE + 30AB792C31BF29A4A32378F3AECCEB7E2D87092F7E2B4B28DFCE0A3E0C4ACF24 + 25A0C58B44A19E44F27BBE83B8D6EEAA54CE0ADDEA3A392C05D748B625FB27B7 + 97C8526618F56D4439037D8C85D7ACC755407E758DF2FA3F1225A1DBD034F399 + DEEBDFBB42E17E8E65D77626C231B0003670E72A25069A2674CFFAA9C0B87041 + 43EAF4B8B9A3B86440CB22CEB29C19EF056025525D8228F5E9FDAA28132E4CA0 + F41350110FF9EE73B2985B2EA98FF6D09516BABCE0B3CBC199F6F7B4C5B202B3 + BF3AF93B3F7133AFC8EEB068F32006C7ED6FE47C26CB0A5B4DD964AA235017A9 + B9D67449878A3FA64A5D56AB8F7E066958487396C1F20195F55685251479EF5C + 988B60F750BF64EC9BC75371A910D410C9C046B23C29D300B1FAE80ACC15A87C + 9194651157D731F35165D0398F0E812C75A1DC353F8BF12526F9AD7CC4553377 + FDEEA054B7D5DE1CBA1AD6D02E0689326A0E3A6AA6402FFFF8382FCD370EBB75 + 750BFD3F868CB9EBB2CA8A1FE0B522623648326E31F7355B0CF91148CBA74355 + 149F32D782CF0ACB6DF5CA60DE55E8FB6123C284468C885BD924939D0A5769A8 + 01BEE9323839A316E7DD8319F168300BB0CDB009DE4CCB3793DAA486BED1C394 + 20BFA3EDA02C5D0ED20722E93FC2FB84908538FBACEAEE134B73DBFEE2153CFC + 8E0F64EF92ED448C8E8D82EB176553BF3081C0EB1542E9AACD24B3BD94055DCA + 8A574F7691A345B4BA7636E47701D86902C567031B272F865D4C1B9B03E1448B + 0FD35AC238BA74CABD13D7CBDE80885D9443A373DFB0D612AA9633C277F79513 + 0B822D8652E695CE5B0C75A941BECE1A13AEE24AE81D690F8A565577DCE9BC18 + BFCB12229DB81787A42C2E1D24DE8F8AB5ABE0556821275F3666CBC24115E8CF + 91225879AD3A2335DCE19C81F312980C14D47434D484E1B7D4648CF4D24184F6 + 4942251018DA1E3E3B67704AB0AC2B837406124F58B3AADF359820EBE42D5B88 + E8FD0E44C1CE50D51630BBB01116FF49548D4E4A684AE911BED4FC49F91F6DE7 + 273E629615E4811C340164A7311CB99AF74199D602A4DD4D458CCF67E8D66F84 + 7E0C0BD9CDF68EF509388ACF1F9824F20EBF866D63777AE58E21B8C9A8DCF510 + 7BC767D18A088633A9C8D53B268B5B8596B8CCEB0689269544769376C772994E + 86322EECF2703E49A109A635B9244EFF123F90E2AA108A003D0FECDCD61F07FE + FC0AEC3BEE8004 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + {restore}if + %%EndFont + %%BeginFont: manfnt + %!PS-AdobeFont-1.0: manfnt 1.0 + %%CreationDate: Thu Jul 30 15:00:55 1998 + %%VMusage: 120000 150000 + 11 dict begin + /FontInfo 14 dict dup begin + /version (1.0) readonly def + /Notice (Copyright 1998 Taco Hoekwater) readonly def + /FullName (manfnt) readonly def + /FamilyName (manfnt) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + /UnderlinePosition -100 def + /UnderlineThickness 50 def + /Weight (Medium) readonly def + end readonly def + /FontName /manfnt def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 65 /char41 put + dup 69 /char45 put + dup 70 /char46 put + dup 77 /char4d put + dup 78 /char4e put + dup 79 /char4f put + dup 84 /char54 put + readonly def + /PaintType 0 def + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0] readonly def + /FontBBox {-500 -1100 2728 2822} readonly def + currentdict end + currentfile eexec + D9D66F633B846A989B9974B0179FC6CC445BCF7C3C3333173232E3FDBFF43949 + 1DB866C39088C203DC22FDC758584860EC7BB67FDA28CC6208249060E18FAB32 + 204779B5C03C0493BBBBC95CF02692CC4DEAA8D2EA90B5C2E64374E92BCB8501 + 429B8FAE4A76C0C6B76D6FF7CF9A7D5EDFBCA0E959541C59BD05B7DE43D25D53 + FC3DDA6EF0C2743978A6D03E19CCED4A11F2EA4BCC3110BE8B8D9E2772361969 + C19258EFAFDC276CB1ADE9208A941A36D18F9FB1C33DEF76AA3140A8A4C99ADB + B3214E61CB091BB87421CEF35FF5745EF8DDC51293183D75AE11F26462B918E3 + F15A016BF051C59D797E59AC042DB329D8738C9DF453DD062F0BA8A59E23E500 + D03758832A6150BF51F1096E643C98DA553929EDAC78FE0F28B0D59B9D5725E1 + 6E190624F3B19DC32D111A8C852FEB8D154F78BEA76C2B07D944F53EABB7DFDE + CF0B80EE145C7E2C0FCF6231002BAD917541FF7B3B4A8A5DE6F9E8E423ADD14D + 40849076959CA9471D0B4ADA2A4ED0080FA3B5B1E9C8EC18C1C606069381DF62 + 8676CF29193A8562CFA0B0978EB39EF291633F7C978166E6F328EC4DBDEE9749 + 46D88B0E05F75ACF9FB6F479C29591C1D3DA100643C72BD9F0CC8D3F6E95BD78 + BFB884C7D0A29FC1AF8728C48DAD913EC539CD1A455345BB841D7F7C77DB9CA8 + B886659353982A5E6E90BE63239465D91C75ED1D149BA60502DE3D37BDD49D7D + C00B6D60C5A482C8BD5ABD5E85230FC000420E41808BDBDE14F8F2A80816C44D + 6BEBA24F6CD5F3C438986C41E503FD4D34DEBC04FC9C3F676CD9EB07B13D15CB + 4DF818FFDF41740B4ECF707FCD9749F543461C53539A315B02812F210590351E + F004AA448DF4CFACC540A62ECCAFB5CB817B56C52F4ACC384012EF4438B20D76 + 61ED669A2E735D76FDC12401A034C5627BC3064CFC2C22A6045DA11977863CE1 + C39C5226DF4B039A65CA13619129F1E26AFFE6C22F0C38540F8CBEE0AC711CE1 + E16B4167884211F6DE4412EB3B3D93B76E3306DAE64B091449E2D0E3B22CCB33 + AA0DA46FCF5A8067C15164F153977501F5E8D84097245BE68983327CB2EFE3EB + 3F3C2568AABFA42B037CC295BA56554160303CF3A527114CF51E0D1E4B1F05B4 + B3F6105B29B65043035C87695F6EC20B734CEA18D38A940B773F20E7043E2156 + 3212B299C29640996055791B98EBBFFC02F81FFB57B3DF725DA363357714256A + EADF217F5EC05555464AE3F13BE05939C2A6FAB0B85ABB32D64FFBE347DAA7DA + 7233A207B2B331CD0C7DA49CAD9CCA95EAB9A501E4F61D1E3FD0027343ECDC06 + 733227E0443FAA99BA72293492313CE91189AE699720EB42C77BFAD3CAEED786 + A815F570A36F29862D61723A8109626C101972BC869F117899967C94D5F462C2 + 58F17AED73977B49149929360F17F612A6FE9DE276F26A887842F0A1D162780E + 47C3AA3031EC4A7C6FBEB6852130A73557A1339BEF9DAF8BFF567BF35694A130 + 5B5DFD43E9B786ACDE6898E01116C3843A210A307CE9FDD9D6601E98BDDD8B47 + 3ADD0973BFF38B764B379487ABB6B79056C126C6A4375A12AA968802D9931250 + C30F4F61A29A02700F822CD63B8A3431233E6AC2EC3824270FA26729DCCD7E8F + CF38067456BEEE0F49C4F5DAA77E7DFC0F81DD433757B10DEDC15C127DD6B025 + 441BBF77AC5850819FE9985B205847633E8AC159018198211FFA1139271EC19F + 73C5EB7674B2931CBC0388450920C78F732C1AFDCDBBF6F14ACA416AC5B2F0C4 + FFDCFC450E1E9B3F8C21C7503B7BB6A37006BB78A9F28A79B77157D41C6E02BC + FC843FC70D36F6C864ADDF513DADD4F7466A05BAAC2B17B1792D9BB3B3BC31B1 + 78C3D0C94F267356C25CD7E09DF1451F15360E4FE4E4E11D47BF53E1429E0530 + D7C99BC782FFA452136FD0E1D2ED1549B2163A25C5A7D11765025B4BD463EF1A + 6786DD31755FA68BA830D8B753C66A17953D5452B79F4E36D6BF916CFEC03366 + 0DC1BA6F6369CB5ED0494F916965CDD7E3DEE48E9FE00EC44870BCCA76173DFB + C2E271B92FA19382AE8B61CE4FDF88605C7B9F01E9D635ACFFB875E1250A586E + 4161981BE48DAAFC16A55D0C2B622BFA364B2103F8CEDC5560702E9954FF0F25 + A13DAD43F19918850215A19C7AEE42621C568330ADB8DF5F555E70A5169C152E + 5C84F48430E4F37BEFB5520F62FF6E5D1C22622E19BD8ABE6A897A894C70A05D + B92A1CEE36A2A4CFF6760B511A4A2197DFB2F8BC9CC15E6DA49052B0AF009B9F + E10BC9BF7A3DA750285D9DF00A89AF60E00D6C1271377FE2513702EFAE04EC52 + C52383F12AE6668A55BD572C82BFF837203C4EB3A3AE0E3F1CEC59E41A149A12 + 98318150346B8A93CC05389475B55B7F662D7E1CF490B975193A492369FC588F + C5A7C40BD6F57F5E13BD0BBAFD6ED503F6D27495AC81C5C6EE923F6F5EB1A2FA + 43D51F6F209919460FC0FA49931671F76F754044D58F4BD856EB96BD13C590E1 + 5ABDE36261EE35EBB7A3C111D87AB52EF712F0C12F3C1AA10BCF86B80923A9ED + 513B8050BEA4E0055F8A5BD831F8CF731C76C7A59B07C199F94E3D888F523DCA + 2C82BB44A4E9CF593DDA5AE69ABA0271F05E010553247F782689C2AB65FD38DA + A74273272220E564B3A1EADF071E87040F2B442A21D647C79984FDEC0DAB2E62 + 9D6F2D951C35F8E4AE7411195FD1A4B269D118F9CD8279DE8C56D76B3DA2C20C + 694FC78959A558E894DD87C1A48C878B54738C080BBE1A54E61FC577149F325D + 82549D2DF22CE9A081774343BBEC6D2D33097D8CD752445A574B51 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + %%EndFont + %%BeginFont: CMR7 + %!PS-AdobeFont-1.0: CMR7 003.002 + %%Title: CMR7 + %Version: 003.002 + %%CreationDate: Mon Jul 13 16:17:00 2009 + %%Creator: David M. Jones + %Copyright: Copyright (c) 1997, 2009 American Mathematical Society + %Copyright: (), with Reserved Font Name CMR7. + % This Font Software is licensed under the SIL Open Font License, Version 1.1. + % This license is in the accompanying file OFL.txt, and is also + % available with a FAQ at: http://scripts.sil.org/OFL. + %%EndComments + FontDirectory/CMR7 known{/CMR7 findfont dup/UniqueID known{dup + /UniqueID get 5000790 eq exch/FontType get 1 eq and}{pop false}ifelse + {save true}{false}ifelse}{false}ifelse + 11 dict begin + /FontType 1 def + /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def + /FontName /CMR7 def + /FontBBox {-27 -250 1122 750 }readonly def + /UniqueID 5000790 def + /PaintType 0 def + /FontInfo 9 dict dup begin + /version (003.002) readonly def + /Notice (Copyright \050c\051 1997, 2009 American Mathematical Society \050\051, with Reserved Font Name CMR7.) readonly def + /FullName (CMR7) readonly def + /FamilyName (Computer Modern) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + /UnderlinePosition -100 def + /UnderlineThickness 50 def + end readonly def + /Encoding 256 array + 0 1 255 {1 index exch /.notdef put} for + dup 43 /plus put + readonly def + currentdict end + currentfile eexec + D9D66F633B846AB284BCF8B0411B772DE5CE3DD325E55798292D7BD972BD75FA + 0E079529AF9C82DF72F64195C9C210DCE34528F540DA1FFD7BEBB9B40787BA93 + 51BBFB7CFC5F9152D1E5BB0AD8D016C6CFA4EB41B3C51D091C2D5440E67CFD71 + 7C56816B03B901BF4A25A07175380E50A213F877C44778B3C5AADBCC86D6E551 + E6AF364B0BFCAAD22D8D558C5C81A7D425A1629DD5182206742D1D082A12F078 + 0FD4F5F6D3129FCFFF1F4A912B0A7DEC8D33A57B5AE0328EF9D57ADDAC543273 + C01924195A181D03F5054A93B71E5065F8D92FE23794D2DB981ABA2ACC9A23A5 + 3E152596AF52983541F86D859FC064A0E3D5FC6647C3CAB83AD4F31DDA35019C + CDB9E3DD3FEBD4C2B36BA3CF6E6C7DA85E25D8A31A9BAD39BDF31FD0D1790707 + 9DE6A078E8A409D8295F642DF492AC4F86AC84383B0F4C6BAA7C22AD5A898A71 + D6CB34D2CD12266C486B75E75A69C14819DD9BB8159088E04D4717E576B8482D + BDA52110AC8B8A80E4E9D58F470EEBD3CF44A1E1EE8DA318FFF3611B02534FC9 + F4018C7C57E80570D2F634D98BE5D5EC6D95051157F0EA94A3D12BE0B4B79939 + F82F8D73136D3337C44E314B0B16CB030D9A12E01FB667105F334C3EE965E5A3 + D410D2F1531547A4497C355AEEB295CD3C5334BEE5232992960B757594B89F3E + 52095042DBE6B4DA3C3AD50CA95EA9EBADA10630B500CF1FCCA7D60306743681 + 7E428D33B7F7C40B425CD58E4CD8AB474BCE6A307BC6C6EBC15A8A96E0E2977E + A33389154536F5C5D8CF036D07F24094E779E5ACBE5502C92892F10F4C6DB627 + C7EC4C7BF20B39418A8A85D7FD9B0EAAFD871DDD41F93BDE5FE619AFB8711824 + DE890E62C1969A6FE28DD3578AF43D58A728FAFF0B9FAA640962C8F35A26F76C + 67F3548D6DB54A25CEB368B47F97EA2B0C4D7C0E7894A4F0C823C6C1922CF9DC + 10E05600556F1C7C9AFB33A2DB6F8730F70D6BF94B1FB0887451F2FFEEF3584F + DFADCFA9A2D4846B8F0E51620E1327D994CDF973B837D10C90FF76DE22B47CD5 + EE3183898D156861AB4DFAD34A1E3FA260B8164E6680BF58413A553E88F6100B + C4F4E8E972C81A5F88A7DBCDC308B4C3581BCDE13877B976B1F84330839FE5CF + C78551620EB803DF94A5C921F8EE24F7EF8FC4C3E1653514212631F54F90E3DC + E9EAF96E998F340C4F729ECF7AB430FDB7C0BE3DF2C0D23015820E28B743CAD7 + 7F0AE95413C3EEABBC69E852F53EE1DC260D7F1E712BECEF2F18437DB23D8E74 + 2902AAFBC733AC5BAA452DD6F3671859AD836C8564E99CDC4183D8495AFD99D6 + 1F0D65B6588CE7546717911E25BDCA6C2649E3A7466A3E2DA7C7994A30AB4449 + 672EFD00632EFA8629C1AFB7D53D801028F77C864869FE636213A69173003EA6 + BE1ABA95EB07B13D1594BEFCC95ECB0A9CFA9892EE0677D6B6C250855762B7A7 + 8E4E022640F93169DFA0303A0D5E73BF3E0F4D4AAD10FD7E4EB20532BA30371F + E9F480F9513432946F9828AFB5D4AEAFA5829B2CB544E5EB634C4537EF7DF08A + A1CFD94A52DCF0E7CE4C5EFFB01E6D50558B75DB4C8D5512B06080F27BE62E01 + 2EEA6A0357441401458C842D3DD4C35B8F561D816B336216CE0C14BF77648AF5 + E33912CF95872A1E1AB9A18980A0B29A881D13397C15E1CBA5D3E0B27943EBE2 + F3003D15EB446BCFC1C231832475D5B7AA19E4CFDE119D6CD62D053C6D29C333 + 5F729791D17B3F7108074EEF4D1BD101CB33E01004532CB0D716D2E54D169C6E + 80163E70C0E9081F31A1ECBAE079D2A518B790B0CB2CD03DFD034A0F4788E800 + B0CD2DC1FAFDD487C2F381EBAB2A2F3F3AF82021B211DC9CD2FBA6A1BB3D4AEA + 4C7F3D9A5C21DFF284CCB827D205A69638E98D5DD8E36AFC1A4481B5CB2A2E8F + D6C838DA6F81990F5ED928DC7457501B5C979FF4CD20A830896A460C5DB13D56 + A3B2B5D9B292374A9BF392894DD99FCD6A1E655AB395E839F074D1596488700C + 4E2891C8AEEF66568E82A8B826F9A28FF84D4D9BDA21F638EAF96880B4EBE0D8 + 081982F34831A03BEE81FC177700C2360D2A48915EC40D5FE85B400E175D5AF1 + 067FA0097904FB647757BB44B4042D30D1557BD0F7922D731142FD682139CEB7 + 58CA4C8C240A0B86B1888CACC507E24E04020BF1882BD9B4CAECFA97DB24D7F5 + AD64C69454027F198BA35881B94EE9159A2D73E450C3BDAED66B886D6DEBC84B + 653E165176228F88993F12A170775A8D7038BDF2FE8DC1F7B98BDC02D1E6686E + 9B834F6C0AD90780B17DFE25F0A4E470CBA84E73F2D22BEE09A040F14CFA2C14 + 0FDA5A5149B5FAFFE49F55EEFC43831BC43A8326FEE9C7F469C0FC3B000884FA + 41DA7318EB57262CB96FC4EC7F16CA07FE1C3BE8C2DBC8A8135953D6DDF20BDF + 75A2B6D26074FCE752BD32FB9F5CA797775E8DB9BB9786B469A3CD65A0D9DDDA + C2A166E454A94860EEF5B5C12172DDFC576A03F6E6F8A735FF21A3E9CCB4CAA1 + 3064893487697986A42CB5888B2B0A79FA3C74E8187BDDF7BEAB884B70B8D4AA + AC6615745AEB906E08BF831CFDE222F58D02B428D55E9D5A3CDE74E42D8A2CB7 + E1A3A9439B678AD438793ABBEB72B21C58981DAF3EDCE4BB93D95F4A1E943BBC + B3A012DE92FED4F232A3A7D60CE60B605151F9C7C18A5C653E5D6D15E5B49A63 + 73E7A339504D0ACC74B8B116EA88C3EBA2CC631AAB29F761E5F062966AD2FD28 + 7FFE52FA8A115DBE23E471094FFB3CBAFBDF11B7E9058313F2D069B2CE98A962 + 64645738F02A31E2F2AC11628724034ADBCEE012721EBF0A567893411F950410 + B20754A7510D041FFA6144AC9CC46D846B82581F20BBD001D34D9764010824BE + 61C30D05E5C5D100A24F1917F01799CF5BC4E50FCECFEA732CB50196825F0E08 + 8A1EC868C6D4357857EE2957E081A0E4372E31A8ABEF23C3F2EA0FEE57DE4D08 + 61C570175C41AA0C7A3A579ADF593F18B4AE3782D2552E4E0759C32E059EE741 + 2D8191E381731769F6648B3581CAF11DAE46471896666F18F02918B0860BDA3C + BD5DE777672447C23C62ACFC2611ED5239D6A266FDA6031EBC5A530C1A2FF7A6 + B4380B9A4C877267854AD1F1677CB5433F28894ADF93D39EAB94541A8D232E08 + 22D082D0951A60F62B87DC028714EC74133A4D65F7D0D1296C0E189C4A42AA98 + 28E8AE7ECBB9FC8DFABCC6EEB1E9FB06227F90808EF31331CCC5D4C9A6182181 + 047902DC9FD0444FB94B60FC74F3B677758088CE6A159D940C5CF682335E756A + 8BACF06AD7225D49B0002392C889B0FE2C71311D2596F4903D12FA20BA2FFE25 + A0804B4BC282929BE31E0F46B34532CB5795A65218CFAE21F390792DA67775C7 + B91A2BF4C16DE4F6551DAE3A5827F616BE9040EE6B1008DA2F99A01EF66D697A + 6CD1A44E0A15D1F39EA8025E886A68A1E9C334327C7703EE721E497CA924AC90 + 7723106D913C5ED4BA4FC743CEA8D0F5172526107DA65775C0B1B77179D336C2 + 9B09B608D80B1A1E87CA1A84A833A00D980D919BFF56F6390E9D5B45E9935CF5 + E69D003564462F750F7DCE02DC23CC215A0696B74D8BD3156A392A94F557655E + 00BFAA035647568ED66157FACC585E411F7F428569C147DC43F6E4FDE693D0F3 + 9917BEFEDF61FB980B85515FF6424824E2D995B05CA1E5D3E8BD8D3281DB7CE4 + E54923E84058FFC0A8A2C491327D0F87CE4C352B724167CEE224DABA3B95757E + 4A419594BE4F92E78BA6D35D4C93D31ECC3134B24A45DC32445725BB044F09A3 + AA8C31EFC0A2944ACE2F2CE054CF24DB350FB3C71115518C24BDC0F7E54250AF + 9D3378D38480E1CB9029F31570C619A28F065CA4FED5665EDB96712ABEB33B9B + 4232C00C1B0215F08D53F7E430887035AC25BEAF06942FD1B6C442253C887AB7 + D694C1A6115C8990B4CAF1E81DD1FDDD6B03C00055BE956BE7FD8A4E1049AE69 + EDA8593CBA8C4A41E046C689FBBF9F1B64E5856A7FB1C61EC815A56DE2A8ED33 + 41F370B8203D4E5B19C63AE9E6E0D26F4F3814B5AF48AD30EC9B8402C941FDD9 + 722FCAFC638FBB835F83DC77F93D367266FA7DFFFCB567EF82B1695AB4D94D09 + B18AC041811027229DF431F5CB2BBF6ACCE9D500C8F075A74590641C1A607C56 + D2B8624797BCD9C91C3177818691FBB4744EDB6056464A0B95B8D63F7C22309B + 82D6126E2057BCC9FE5566D96B7A9B201A09B0D3252A5494C8CA2C8BA8A13C29 + 37EF2A882D61DA708C279F663D88A8E2999A0F3B6F98C49901A7631BF7708B67 + 54D0B4C52BF4BE0DA0439E6763A7C9D639AD4092E77B13D3510DAE1475C978AC + 796F9B2AAD3BFF35C5A3E19B5E2BF704B3BBDF68CE48BA4FA2496D60E58888EA + 28AE12D00E9F0816FAC190590A865BB58569A91BF0345D01230ABA361442006D + BA2C90EC2036BBAB79EBAFC3F217DBD5854C519235F9627A1C3C71D21ED38AEF + 0BB40F3B86BB9F09A3F309473D8757AB7E638DC1C59A7F9BCD49DE4107A2E54F + 422767FB94048987847205584309397F554744690ACFFDF5902FE5DB355930B8 + 71863217830DD7A563B0B3A4025ACE75B0E777B4414B62A13B50C54E0E6D47E9 + D43BF769B9411B74E1069BF71BA873B4B8973EC9BA492A5DEA58D267872BB246 + 10AA67B143D0E2223FFB4991E583E629413CC894C3FA4869B72D19CE1A0CEC8C + 0FF5E5A3EC1FCB7D3C4289813F0D249A11B55104BD60B2A89BEF44CC77CCDA9A + 065B8B83B4F4253AA1D535290DCFAA4773452D110D2B3370F9E2FE5432B54A9E + 644EB3BA9BFF62347F376839024CD5EF3C5DFD30F412DD5474B7933E6A1AB63B + 4B12F2417C72D0543C26A263AEA53E5BAEBD67E23553A72E949DEC556BEB5D09 + C4D7A89B14FE4EC68D0E3E9D65A64B285E53590F418EDA8175113CA375A29930 + DDCF4C71ABB26CEB800C2C2B253AC1F53651C88A56ABE5A74F3B54CB4FFDDB92 + 60AD7272BA25EC2F6FB759AA6E1E7964FB55AD09F4EB25DE45FD01833947BD05 + 6266AA8ABB7DD792941C7A070FCF3A4636FBF8921C70298D42FE92F079DBA2AD + 6149D9CF9EF7264DE6DFCD4429949B15EA90B596340713BD61926DDB2BB23BE8 + F9DE38A31620A817420A245946E551463960A8C5C7295E3B3D6A59BCDF5E472A + 40B7A2CDDAA43CD8AAFC411D037142579D11054A903E102DF0D0C7B5BB854DBA + F3F086AF991F7F5D5C730F8F9AF213F25786F3EC0E54530FF912F4876FDE16B6 + A07D0DC4FC46EC6363BCB68B83ACC448B801EC43FDD2F8BE0E93D809FF81E38E + 176AE17C67C85FEA58EC95435434C49A950AA955D8B20989C550AB1F1C31B7FF + 99422E1F48FB7D6F327C6DBC4695A03903DB275B94CB39386E46579271870A25 + 21823E75C377E9D5B46655E8CD8F986372CF8BA846423E26582315A9D19E0BF5 + 305C32B2A0EAC3ECB275B1D8BE11A37ADF524944219D94EA2C5DBDA768828B6D + 775DA8CDB09E0570E4ADDF462EFD8D3FA3F86B1DEECDFFB699AF6507257C1879 + 16FC615868C2D51F03CD57BA38D42995D9164B257441210084DC409B6EE4C119 + 0B2E17B0A8D5326DD0010E4A325D5F77BF935693BC90A00A28C7B5F74817DA39 + F47A41E32F4F92AA04D30D810F7B1484EB53AD8CFC8CE8928B570314E0F713F8 + AF127227190F9C16BB73D2A217FF801C391A29095DA5E4974D137A0CAA7DE702 + E20DD4755B1D78739756A5E7EC3542B96AD6844199FFA2F5F2E9C64E2DA4FB2A + ED79869F745C59D235438251BC2E6D26112AAED20E06021D1AB896EE1F1DD2EB + 437FBD4A25E42245C5A647493FCC9922E6DD7AF57D5D482921D1CBD6F0F02949 + C27777144751C1E72F4EE2BC343D4AE7A8A8758123B54FB1A026144C643651EF + 0907A376945E19A8FC7F98A034832A5820A481B0823F980F59623E0511593FEA + BDE6EFBCC0383242CBD4954027B075B21F10472059A480D6E5ED01C3B07461CE + 9810251A5C5643EC7403130C2246E8616CEA25EAC7A0076731FEA8CC43BCE3BE + 933FCE61067F5FD402E67E2B9DAD954AA77C5BC86BC5E4BCE2ED676D8D8EC7D0 + ABC5C86D82180B9D5D7451C71B5149B6B67883578DE9909317928C0A92E3205E + F23015400A1763A6FBF67FDE3318AD2696685A1832FC31CF38589EBC7CA1C818 + 60D2B2211E04EFCCEA88D9A9082E82951EEB123924A267CB03C48889032F2892 + 4227E217FA28F87E01CBF27BF1EA60641A4238258CB7AA355908FE36D90F5CAD + FE992D03A33E47CA9AEBEFDA57793F39DC6A9E85D5B289F6B862B35DBCF82E43 + 5CD6A862F6FFAC36478C384C3BDB0148CB1FEDF55969C776E77917635B5A65EB + F2AD351D21CD3822D43289FE8EB0FED58182997097C7E9F4373553AE1CA92083 + EDE3BBE6C3BC7009D15AB5FEC6A59E9FD1BCC7B2099CA15FEF083B9CBF7B890E + CDDDE6BA0AFF306C76500C945DC91BD533FF9A585CEEDEF79238C54E6168001E + 26FEB29E523EE501BFA4F60B782B1499B07084C35A2434B4D29D3D8E2C8F945F + A9922443B68D07DF7EAA1F4CDEFFC438B597D8943E231B5216808A85F30EDC81 + 9DF5DD22F54A45335B4C2203887475F39D247F0E7347BACFEAF220ED82F9263A + 6488E73C1910023E505FDEB143006C1A351D441AC57F9D52D2C6D63D78C75605 + 999885676BBBAD56074298E0BFDACBA1830BA58E87F436CC670EE8EB1870154D + 72DDBBF3794F8CAAA3F1E11DE29752DD99EAC695838A19BB67A1FA3829B6E0BC + 5301610A0351AAA749F456AE31ADD87D6ABADCDD1FB3CE81C3713F48780DF407 + 530CB284B2AC709F52EE7AD647DEF9FA4D2A867CCEF728F3D40CF34C28D21527 + 10160B3DAFB5FE16AFC9D36C6EC4021FC189005862082BEA60AC72B63AD27D72 + FAF3C2D89DA2648FC4C65104A069212D87144E8533CD86A6D73DC7CD9DBA25CE + 7DA53B000266F3871B24663C77723703315C5E4A89DFCDBAB384AE7EB2F455AE + AB191FED406F7F6EC9E5B8276EF5C4CBA041AC7E8BCEC7CAE840154BDCA3232F + 15711ABD1E867A434E9787CA0A6D1F197597DA27ED2402CB2D84ED082E8D3A39 + 81E6EB270DCA4E7A90E2BEBD3CBB3A2BE3CAB926192D7292CC16845B6399A543 + BCFD224BB52F21352732DB5154FA3442733066CDC3E186D8AA97CD801DFBE43A + 116C86889BE198DA88CA978B8C40ACB67E8F7BA499DE68A6FF0DC72C3D00BA1A + B378B39610F15CA026F95ED8155CE3FFFFA2E2FEB352DBE14CEE1669F2387B70 + 55B91185FBBED764266215D518716EDA3DFC9E5DB6B148A553E75AE5E38E1CFC + 6EF47B314D54CF24BC13856F4F7C976BB91D143DE32FF49BFFC87E17885A1893 + BA1B8E441B08EFC04F7D103C1FFBB665194B3D0920473740C55FB1C50EBCF717 + A2359B687FCEAD65616EE89A68F8D91AFACAA0B238EE4AF0279AF5BE5294C3DE + A7E1F5E6248C0210E7D40683F04B12A933C746ECB517CF94BBCC6E4CF49AC715 + D8005AFECBDFB7A6B417DB8A28F8E9EAF39CEC1CA64DF37A5E66A76C26F721F8 + A63B003A040A62F87DCF61B298F960D510BEFA453F118E59E7DE8CA3DD002EF0 + 127EAF733D5C61B5132348D280F84D159809CC71A3C6F7373BBFD8D6EF715D34 + 0016DEFF14AA5F960BF1BB9AC304A1823722843547BB4CA5EA4C41C6C2701C8F + 7BDC810443F9DF34BA469A3260009B799871BAF8523C8763544DCD0B382D44C5 + F75046AFF85F0B5A3188C2EE786CEEE5496A5AF4BCB0B429CAFC403FB983EFE3 + 61FD9F52ADFC38E07A0FD7BACBA530D2E4DAB2592AA9564843E7E2305047F060 + C5FE4243FA8FDF1B5D4F61ACA7850A604FBC6D6970959752695C90F78961B4E2 + C8CFA41082B1A37405AABCEE5BA3DC2B9EA76F486117B84728EC6D8AE6379CCB + 402C2AA89078EC992C00D53151E9D82C65643F549A572A20F05107A41BE5AC57 + 8EDE92AE20B05E2D0C98151CC92D5389A675DFE39DF546A33A84A4C534337ADE + B17C34E09145B37CE1EB1D10D42CC8D6E6B127A3809F7202381FDB88D42084CD + 0AEAEB8A8288CB56870EA2BE9D0B9DC8291021CA561E2BA388DA3494E433E0EE + 5E69DA51D0AC505C9F71562D3E9750F23CF14D2C8ECF0692FBBCB4A92B48B4B0 + AA2163A447D5FBE86D961AE4D4251149F11C4BC269E10B48E8C42DC2484EDE87 + 6540CB8A5EA2494148D09CC9D5014EB723739F7ABAD029CD0ACEEA511B20D40F + 02BD96495D28149638962B6424883D4D5D8C38C94551B5AA8DF167D91517EE14 + 06F909B6AA503049621C788228477703593C0546A84FC1487844423DB4C42499 + 9D5905520FCAFD47F7149117650FC174FDBBB8554B8588489AB27158DF249802 + AD977E71A7CE1C0CF6BBA1BB839A1A9E7BF8B170A75CB81C8EDBD1FB4E3A1221 + 2C39F4A0C240CE33BD533614A14108AEA1F4E1D7043D110F4AF7B8CA8C43DE29 + 8B603588CB1ACAF13DB4DC068F3C855EB04886D3 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + cleartomark + {restore}if + %%EndFont %%BeginFont: CMSL10 %!PS-AdobeFont-1.0: CMSL10 003.002 *************** *** 5748,5781 **** 39 39 39 39 39 1[39 39 39 39 39 2[39 39 39 39 39 39 39 39 39 5[39 39 6[39 1[39 1[39 39 39 39 2[39 39 39 39[{}56 ! 74.7198 /CMTT9 rf /Fe 140[42 9[27 5[54 1[56 97[{}4 90.9091 ! /CMCSC10 rf /Ff 134[48 48 48 48 48 48 48 48 48 48 48 ! 48 48 48 1[48 48 48 48 48 48 48 48 48 48 1[48 18[48 5[48 ! 1[48 9[48 6[48 48 48 48 48 48 48 45[{}36 90.9091 /CMTT10 ! rf /Fg 171[48 4[55 55 66 6[52 52 3[55 65[{}7 83.022 /manfnt ! rf /Fh 212[51 43[{}1 58.1154 /CMR7 rf /Fi 167[62 3[60 ! 46 2[57 1[62 76 52 1[43 1[62 65 54 1[63 60 67[{}13 83.022 ! /CMR10 rf /Fj 134[48 2[48 51 35 36 36 1[51 45 51 1[25 ! 1[28 25 1[45 28 40 1[40 51 45 97[{}18 90.9091 /CMSL10 ! rf /Fk 197[25 58[{}1 90.9091 /CMMI10 rf /Fl 197[33 58[{}1 ! 119.552 /CMMI12 rf /Fm 134[85 85 1[85 90 63 64 66 1[90 ! 81 90 134 45 85 1[45 90 81 49 74 90 72 90 78 10[122 124 ! 112 90 2[110 1[126 1[97 2[60 1[127 101 1[124 117 13[81 ! 81 81 81 81 49[{}39 143.462 /CMBX12 rf /Fn 134[51 51 ! 1[51 54 38 38 38 1[54 49 54 81 27 51 1[27 1[49 1[43 54 ! 43 54 49 10[73 73 70 54 2[66 1[73 1[61 2[35 1[77 64 1[75 ! 70 9[49 49 49 49 49 49 49 49 49 49 48[{}42 99.6264 /CMR12 ! rf /Fo 242[91 13[{}1 90.9091 /CMSY10 rf /Fp 134[71 71 ! 97 71 75 52 53 55 1[75 67 75 112 37 71 1[37 75 67 41 ! 61 75 60 75 65 7[102 2[102 103 94 75 100 1[92 101 105 ! 128 81 2[50 105 106 85 88 103 97 1[102 6[37 67 67 67 ! 67 67 67 67 67 67 67 1[37 46[{}54 119.552 /CMBX12 rf ! /Fq 131[91 1[40 48 48 66 48 51 35 36 36 48 51 45 51 76 ! 25 48 28 25 51 45 28 40 51 40 51 45 25 3[45 1[56 68 68 ! 93 68 68 66 51 67 71 62 71 68 83 57 71 47 33 68 71 59 ! 62 69 66 64 68 5[25 25 45 45 45 45 45 45 45 45 45 45 ! 45 25 30 25 2[35 35 25 4[45 19[76 51 51 53 11[{}79 90.9091 ! /CMR10 rf /Fr 138[108 1[76 79 3[108 1[54 6[88 3[94 11[149 ! 7[184 116 5[122 1[148 16[97 97 1[97 1[54 46[{}16 172.154 ! /CMBX12 rf end %%EndProlog %%BeginSetup --- 5748,5781 ---- 39 39 39 39 39 1[39 39 39 39 39 2[39 39 39 39 39 39 39 39 39 5[39 39 6[39 1[39 1[39 39 39 39 2[39 39 39 39[{}56 ! 74.7198 /CMTT9 rf /Fe 167[62 3[60 46 2[57 1[62 76 52 ! 1[43 1[62 65 54 1[63 60 67[{}13 83.022 /CMR10 rf /Ff ! 140[42 9[27 5[54 1[56 97[{}4 90.9091 /CMCSC10 rf /Fg ! 134[48 48 48 48 48 48 48 48 48 48 48 48 48 48 1[48 48 ! 48 48 48 48 48 48 48 48 1[48 18[48 5[48 1[48 9[48 6[48 ! 48 48 48 48 48 48 45[{}36 90.9091 /CMTT10 rf /Fh 171[48 ! 4[55 55 66 6[52 52 3[55 65[{}7 83.022 /manfnt rf /Fi ! 212[51 43[{}1 58.1154 /CMR7 rf /Fj 134[48 2[48 51 35 ! 36 36 1[51 45 51 1[25 1[28 25 1[45 28 40 1[40 51 45 97[{}18 ! 90.9091 /CMSL10 rf /Fk 197[25 58[{}1 90.9091 /CMMI10 ! rf /Fl 197[33 58[{}1 119.552 /CMMI12 rf /Fm 134[85 85 ! 1[85 90 63 64 66 1[90 81 90 134 45 85 1[45 90 81 49 74 ! 90 72 90 78 10[122 124 112 90 2[110 1[126 1[97 2[60 1[127 ! 101 1[124 117 13[81 81 81 81 81 49[{}39 143.462 /CMBX12 ! rf /Fn 134[51 51 1[51 54 38 38 38 1[54 49 54 81 27 51 ! 1[27 1[49 1[43 54 43 54 49 10[73 73 70 54 2[66 1[73 1[61 ! 2[35 1[77 64 1[75 70 9[49 49 49 49 49 49 49 49 49 49 ! 48[{}42 99.6264 /CMR12 rf /Fo 242[91 13[{}1 90.9091 /CMSY10 ! rf /Fp 134[71 71 97 71 75 52 53 55 1[75 67 75 112 37 ! 71 1[37 75 67 41 61 75 60 75 65 7[102 2[102 103 94 75 ! 100 1[92 101 105 128 81 2[50 105 106 85 88 103 97 1[102 ! 6[37 67 67 67 67 67 67 67 67 67 67 1[37 46[{}54 119.552 ! /CMBX12 rf /Fq 131[91 1[40 48 48 66 48 51 35 36 36 48 ! 51 45 51 76 25 48 28 25 51 45 28 40 51 40 51 45 25 3[45 ! 1[56 68 68 93 68 68 66 51 67 71 62 71 68 83 57 71 47 ! 33 68 71 59 62 69 66 64 68 5[25 25 45 45 45 45 45 45 ! 45 45 45 45 45 25 30 25 2[35 35 25 4[45 19[76 51 51 53 ! 11[{}79 90.9091 /CMR10 rf /Fr 138[108 1[76 79 3[108 1[54 ! 6[88 3[94 11[149 7[184 116 5[122 1[148 16[97 97 1[97 ! 1[54 46[{}16 172.154 /CMBX12 rf end %%EndProlog %%BeginSetup *************** *** 5919,5928 **** (release)g(2.0)150 643 y(and)g(previous)g(releases)i(is)f(that)h(3DLDF) g(2.0)g(is)f(an)f Fj(in)m(teractiv)m(e)48 b Fq(program,)42 ! b(whereas)e(in)f(previous)150 752 y(releases,)30 b(3DLDF)g(w)m(as)f ! (more)g(lik)m(e)h(a)f Fj(library)35 b Fq(of)29 b Fi(C)1937 ! 744 y Fh(+)-8 b(+)2063 752 y Fq(functions)29 b(that)g(users)e(could)i ! (use)f(in)g(their)h(o)m(wn)150 862 y(programs)h(to)h(mak)m(e)g(dra)m (wings.)275 996 y(No)m(w,)e(3DLDF)g(implemen)m(ts)f(a)g ! Fj(language)35 b Fq(similar)28 b(to)g(the)g Fg(MET)n(AF)l(ONT)57 b Fq(language,)30 b(and)d(in)g(partic-)150 1106 y(ular)j(the)h(MetaP)m (ost)i(language)e(deriv)m(ed)g(from)f(it.)275 1240 y(F)-8 --- 5919,5928 ---- (release)g(2.0)150 643 y(and)g(previous)g(releases)i(is)f(that)h(3DLDF) g(2.0)g(is)f(an)f Fj(in)m(teractiv)m(e)48 b Fq(program,)42 ! b(whereas)e(in)f(previous)150 752 y(releases,)30 b(3DLDF)g(w)m(as)e ! (more)g(lik)m(e)i(a)e Fj(library)36 b Fq(of)28 b(C)1940 ! 744 y Fi(+)-8 b(+)2066 752 y Fq(functions)28 b(that)g(users)g(could)g ! (use)g(in)g(their)g(o)m(wn)150 862 y(programs)i(to)h(mak)m(e)g(dra)m (wings.)275 996 y(No)m(w,)e(3DLDF)g(implemen)m(ts)f(a)g ! Fj(language)35 b Fq(similar)28 b(to)g(the)g Fh(MET)n(AF)l(ONT)57 b Fq(language,)30 b(and)d(in)g(partic-)150 1106 y(ular)j(the)h(MetaP)m (ost)i(language)e(deriv)m(ed)g(from)f(it.)275 1240 y(F)-8 *************** *** 5930,5934 **** (of)g(3DLDF)h(ha)m(v)m(e)g(b)s(een)e(a)m(v)-5 b(ailable)41 b(for)e(do)m(wnloading)150 1350 y(from)26 b(the)g(Sa)m(v)-5 ! b(annah)26 b(w)m(ebsite:)39 b Ff(https://savannah.gnu.org/)o(proj)o (ects)o(/3d)o(ldf/)o Fq(.)34 b(Ho)m(w)m(ev)m(er,)29 b(2.0)150 1460 y(is)h(the)h(\014rst)f(release)h(that)g(includes)f(this)h --- 5930,5934 ---- (of)g(3DLDF)h(ha)m(v)m(e)g(b)s(een)e(a)m(v)-5 b(ailable)41 b(for)e(do)m(wnloading)150 1350 y(from)26 b(the)g(Sa)m(v)-5 ! b(annah)26 b(w)m(ebsite:)39 b Fg(https://savannah.gnu.org/)o(proj)o (ects)o(/3d)o(ldf/)o Fq(.)34 b(Ho)m(w)m(ev)m(er,)29 b(2.0)150 1460 y(is)h(the)h(\014rst)f(release)h(that)g(includes)f(this)h *************** *** 5944,5950 **** b(On)21 b(the)h(other)g(hand,)h(the)f(reference)h(sections)g(are)f (longer)g(needed)g(for)g(just)f(using)h(the)g(program.)150 ! 2142 y(The)k(old)g(man)m(ual)g(is)g(included)f(in)h(the)g(distribution) ! g(in)f(the)i(directory)f(`)p Ff(3DLDF-2.0/doc/old_doc/)p ! Fq('.)275 2276 y(The)41 b(co)s(de)h(for)f Fj(scanning)50 b Fq(and)41 b Fj(parsing)p Fq(,)j(i.e.,)i(that)d(whic)m(h)e(implemen)m (ts)i(the)f Fj(in)m(terpreter)48 b Fq(that)150 2386 y(mak)m(es)31 --- 5944,5950 ---- b(On)21 b(the)h(other)g(hand,)h(the)f(reference)h(sections)g(are)f (longer)g(needed)g(for)g(just)f(using)h(the)g(program.)150 ! 2142 y(The)30 b(old)g(man)m(ual)h(is)g(included)e(in)h(the)h ! (distribution)e(in)i(the)f(directory)h Fg(3DLDF-2.0/doc/old_doc/)p ! Fq(.)275 2276 y(The)41 b(co)s(de)h(for)f Fj(scanning)50 b Fq(and)41 b Fj(parsing)p Fq(,)j(i.e.,)i(that)d(whic)m(h)e(implemen)m (ts)i(the)f Fj(in)m(terpreter)48 b Fq(that)150 2386 y(mak)m(es)31 *************** *** 5961,5973 **** (to)h(mak)m(e)g(a)f(release)i(without)e(rewriting)g(the)150 2959 y(man)m(ual,)31 b(although)g(this)f(is)g(clearly)i(not)f(ideal.) ! 275 3093 y(As)h(a)g(partial)h(substitute,)f(release)i(2.0)f(con)m ! (tains)g(the)f(directory)h(`)p Ff(3DLDF-2.0/examples/)p ! Fq(')27 b(with)150 3203 y(man)m(y)k(examples)g(whic)m(h)f(can)h(used)f ! (to)i(learn)e(ho)m(w)h(to)g(use)g(the)g(3DLDF)h(language.)43 ! b(In)30 b(addition,)h(the)150 3313 y(directory)g(`)p ! Ff(3DLDF-2.0/src/)p Fq(')c(con)m(tains)32 b(the)f(\014les)f(`)p ! Ff(sample.ldf)p Fq(',)f(`)p Ff(sample.ldf)p Fq(',)f(`)p ! Ff(sample0.ldf)p Fq(',)150 3422 y(`)p Ff(sample1.ldf)p ! Fq(')g(and)i(`)p Ff(sample2.ldf)p Fq('.)p eop end %%Page: 2 6 TeXDict begin 2 5 bop 150 -116 a Fq(Chapter)30 b(2:)41 --- 5961,5973 ---- (to)h(mak)m(e)g(a)f(release)i(without)e(rewriting)g(the)150 2959 y(man)m(ual,)31 b(although)g(this)f(is)g(clearly)i(not)f(ideal.) ! 275 3093 y(As)36 b(a)i(partial)g(substitute,)g(release)h(2.0)f(con)m ! (tains)g(the)f(directory)h Fg(3DLDF-2.0/examples/)31 ! b Fq(with)150 3203 y(man)m(y)41 b(examples)g(whic)m(h)f(can)h(used)e ! (to)i(learn)g(ho)m(w)f(to)i(use)e(the)g(3DLDF)i(language.)73 ! b(In)39 b(addition,)150 3313 y(the)d(directory)g Fg(3DLDF-2.0/src/)c ! Fq(con)m(tains)37 b(the)g(\014les)e Fg(sample.ldf)p Fq(,)g ! Fg(sample.ldf)p Fq(,)g Fg(sample0.ldf)p Fq(,)150 3422 ! y Fg(sample1.ldf)27 b Fq(and)j Fg(sample2.ldf)p Fq(.)p ! eop end %%Page: 2 6 TeXDict begin 2 5 bop 150 -116 a Fq(Chapter)30 b(2:)41 *************** *** 5977,5997 **** TeXDict begin 3 6 bop 150 -116 a Fq(Chapter)30 b(3:)41 b(In)m(v)m(oking)2750 b(3)150 299 y Fm(3)80 b(In)l(v)l(oking)150 ! 533 y Fq(Command-line)30 b(options:)150 692 y Ff(--bison-trace)630 802 y Fq(Prin)m(ts)h(information)g(generated)g(b)m(y)g(GNU)g(Bison)g (for)g(tracing)h(whic)m(h)e(parser)g(rules)h(are)630 912 y(reduced)f(and)f(the)i(state)h(of)e(the)h(Bison)g(stac)m(k.)150 ! 1071 y Ff(--multithread-input)630 1181 y Fq(Enables)f(the)h(use)f(of)g ! (m)m(ultiple)h(threads)f(for)h(input.)150 1340 y Ff (--multithread-output)630 1450 y Fq(Enables)f(the)h(use)f(of)g(m)m ! (ultiple)h(threads)f(for)h(output.)150 1609 y Ff(--multithread-include) 630 1719 y Fq(Enables)f(the)f(use)h(of)g(m)m(ultiple)g(threads)g(for)f (input)g(\014les)h(included)f(in)g(other)h(input)f(\014les.)150 ! 1878 y Ff(--silent)96 b Fq(Suppresses)28 b(almost)k(all)f(output)f(to)h (standard)f(output)g(and)f(standard)h(error.)150 2037 ! y Ff(--quiet)144 b Fq(Suppresses)28 b(some)j(output)f(to)h(standard)f ! (output)g(and)f(standard)h(error.)150 2197 y Ff(--verbose)630 2306 y Fq(Causes)g(status)h(information)f(to)i(b)s(e)d(prin)m(ted)h(to) ! h(standard)f(output.)150 2466 y Ff(--help)192 b Fq(Prin)m(ts)30 ! b(a)h(help)f(message)h(and)f(exits.)150 2625 y Ff(--version)630 2735 y Fq(Prin)m(ts)g(v)m(ersion)h(information)g(and)f(exits.)p eop end --- 5977,5997 ---- TeXDict begin 3 6 bop 150 -116 a Fq(Chapter)30 b(3:)41 b(In)m(v)m(oking)2750 b(3)150 299 y Fm(3)80 b(In)l(v)l(oking)150 ! 533 y Fq(Command-line)30 b(options:)150 692 y Fg(--bison-trace)630 802 y Fq(Prin)m(ts)h(information)g(generated)g(b)m(y)g(GNU)g(Bison)g (for)g(tracing)h(whic)m(h)e(parser)g(rules)h(are)630 912 y(reduced)f(and)f(the)i(state)h(of)e(the)h(Bison)g(stac)m(k.)150 ! 1071 y Fg(--multithread-input)630 1181 y Fq(Enables)f(the)h(use)f(of)g ! (m)m(ultiple)h(threads)f(for)h(input.)150 1340 y Fg (--multithread-output)630 1450 y Fq(Enables)f(the)h(use)f(of)g(m)m ! (ultiple)h(threads)f(for)h(output.)150 1609 y Fg(--multithread-include) 630 1719 y Fq(Enables)f(the)f(use)h(of)g(m)m(ultiple)g(threads)g(for)f (input)g(\014les)h(included)f(in)g(other)h(input)f(\014les.)150 ! 1878 y Fg(--silent)96 b Fq(Suppresses)28 b(almost)k(all)f(output)f(to)h (standard)f(output)g(and)f(standard)h(error.)150 2037 ! y Fg(--quiet)144 b Fq(Suppresses)28 b(some)j(output)f(to)h(standard)f ! (output)g(and)f(standard)h(error.)150 2197 y Fg(--verbose)630 2306 y Fq(Causes)g(status)h(information)f(to)i(b)s(e)d(prin)m(ted)h(to) ! h(standard)f(output.)150 2466 y Fg(--help)192 b Fq(Prin)m(ts)30 ! b(a)h(help)f(message)h(and)f(exits.)150 2625 y Fg(--version)630 2735 y Fq(Prin)m(ts)g(v)m(ersion)h(information)g(and)f(exits.)p eop end *************** *** 6003,6024 **** TeXDict begin 5 8 bop 150 -116 a Fq(Chapter)30 b(5:)41 b(Data)32 b(T)m(yp)s(es)2623 b(5)150 299 y Fm(5)80 b(Data)55 ! b(T)l(yp)t(es)150 1434 y Fp(5.1)68 b(Numeric)45 b(t)l(yp)t(es)150 ! 1733 y Ff(numeric)144 b Fq(In)m(tegers)31 b(and)f(\015oating)h(p)s(oin) ! m(t)g(n)m(um)m(b)s(ers.)150 2122 y Ff(boolean)144 b(true)29 ! b Fq(or)i Ff(false)150 2511 y(ulong_long)630 2620 y Fq(Unsigned)j(long) g(long)h(in)m(tegers.)53 b(Corresp)s(onds)32 b(to)j(the)f(C)g(t)m(yp)s ! (e)g Ff(unsigned)28 b(long)h(long)630 2730 y(int)p Fq(.)150 ! 3119 y Ff(complex)144 b Fq(Complex)30 b(n)m(um)m(b)s(er.)150 ! 3507 y Ff(matrix)192 b Fq(Matrix.)150 4084 y Fp(5.2)68 b(T)l(yp)t(es)45 b(for)g(dra)l(wing)g(and)g(lab)t(eling:)150 ! 4383 y Ff(transform)630 4493 y Fq(T)-8 b(ransformation)30 ! b(matrix.)150 4881 y Ff(focus)240 b Fq(F)-8 b(o)s(cus)31 b(for)f(the)h Fj(p)s(ersp)s(ectiv)m(e)f(pro)5 b(jection)p ! Fq(.)150 4991 y Ff(pen)150 5101 y(dash_pattern)150 5210 y(color)150 5320 y(string)p eop end %%Page: 6 10 TeXDict begin 6 9 bop 150 -116 a Fq(Chapter)30 b(5:)41 b(Data)32 b(T)m(yp)s(es)2623 b(6)150 299 y Fp(5.3)68 ! b(Shap)t(e)45 b(t)l(yp)t(es)150 566 y Ff(point)150 676 y(path)150 786 y(circle)150 895 y(circle_slice)150 1005 y(arc)150 1114 y(cone)150 1224 y(conic_section_lattice)150 --- 6003,6024 ---- TeXDict begin 5 8 bop 150 -116 a Fq(Chapter)30 b(5:)41 b(Data)32 b(T)m(yp)s(es)2623 b(5)150 299 y Fm(5)80 b(Data)55 ! b(T)l(yp)t(es)150 1352 y Fp(5.1)68 b(Numeric)45 b(t)l(yp)t(es)150 ! 1640 y Fg(numeric)144 b Fq(In)m(tegers)31 b(and)f(\015oating)h(p)s(oin) ! m(t)g(n)m(um)m(b)s(ers.)150 2005 y Fg(boolean)144 b(true)29 ! b Fq(or)i Fg(false)150 2371 y(ulong_long)630 2481 y Fq(Unsigned)j(long) g(long)h(in)m(tegers.)53 b(Corresp)s(onds)32 b(to)j(the)f(C)g(t)m(yp)s ! (e)g Fg(unsigned)28 b(long)h(long)630 2590 y(int)p Fq(.)150 ! 2956 y Fg(complex)144 b Fq(Complex)30 b(n)m(um)m(b)s(er.)150 ! 3321 y Fg(matrix)192 b Fq(Matrix.)150 3863 y Fp(5.2)68 b(T)l(yp)t(es)45 b(for)g(dra)l(wing)g(and)g(lab)t(eling:)150 ! 4150 y Fg(transform)630 4260 y Fq(T)-8 b(ransformation)30 ! b(matrix.)150 4625 y Fg(focus)240 b Fq(F)-8 b(o)s(cus)31 b(for)f(the)h Fj(p)s(ersp)s(ectiv)m(e)f(pro)5 b(jection)p ! Fq(.)150 4991 y Fg(pen)150 5101 y(dash_pattern)150 5210 y(color)150 5320 y(string)p eop end %%Page: 6 10 TeXDict begin 6 9 bop 150 -116 a Fq(Chapter)30 b(5:)41 b(Data)32 b(T)m(yp)s(es)2623 b(6)150 299 y Fp(5.3)68 ! b(Shap)t(e)45 b(t)l(yp)t(es)150 566 y Fg(point)150 676 y(path)150 786 y(circle)150 895 y(circle_slice)150 1005 y(arc)150 1114 y(cone)150 1224 y(conic_section_lattice)150 *************** *** 6030,6035 **** 2977 y(sphere)150 3087 y(sphere_development)150 3197 y(triangle)150 3679 y Fp(5.4)68 b(Com)l(bined)46 b(t)l(yp)t(es)150 ! 3946 y Ff(bool_point)150 4320 y Fp(5.5)68 b(Other)45 ! b(t)l(yp)t(es)150 4587 y Ff(plane)150 4697 y(nurb)150 4807 y(origami_figure)150 5181 y Fp(5.6)68 b(V)-11 b(ector)45 b(t)l(yp)t(es)150 5340 y Fq(V)-8 b(ector)32 b(t)m(yp)s(es)f(\(alphab)s --- 6030,6035 ---- 2977 y(sphere)150 3087 y(sphere_development)150 3197 y(triangle)150 3679 y Fp(5.4)68 b(Com)l(bined)46 b(t)l(yp)t(es)150 ! 3946 y Fg(bool_point)150 4320 y Fp(5.5)68 b(Other)45 ! b(t)l(yp)t(es)150 4587 y Fg(plane)150 4697 y(nurb)150 4807 y(origami_figure)150 5181 y Fp(5.6)68 b(V)-11 b(ector)45 b(t)l(yp)t(es)150 5340 y Fq(V)-8 b(ector)32 b(t)m(yp)s(es)f(\(alphab)s *************** *** 6037,6041 **** %%Page: 7 11 TeXDict begin 7 10 bop 150 -116 a Fq(Chapter)30 b(5:)41 ! b(Data)32 b(T)m(yp)s(es)2623 b(7)150 299 y Ff(arc_vector)150 408 y(boolean_vector)150 518 y(bool_point_vector)150 628 y(circle_slice_vector)150 737 y(circle_vector)150 --- 6037,6041 ---- %%Page: 7 11 TeXDict begin 7 10 bop 150 -116 a Fq(Chapter)30 b(5:)41 ! b(Data)32 b(T)m(yp)s(es)2623 b(7)150 299 y Fg(arc_vector)150 408 y(boolean_vector)150 518 y(bool_point_vector)150 628 y(circle_slice_vector)150 737 y(circle_vector)150 *************** *** 6066,6070 **** Fq(2000,)j(2001,)f(2002,)g(2007,)h(2008)f(F)-8 b(ree)31 b(Soft)m(w)m(are)h(F)-8 b(oundation,)31 b(Inc.)390 745 ! y Ff(http://fsf.org/)390 964 y Fq(Ev)m(ery)m(one)g(is)g(p)s(ermitted)f (to)h(cop)m(y)g(and)f(distribute)g(v)m(erbatim)h(copies)390 1074 y(of)g(this)f(license)h(do)s(cumen)m(t,)g(but)e(c)m(hanging)j(it)f --- 6066,6070 ---- Fq(2000,)j(2001,)f(2002,)g(2007,)h(2008)f(F)-8 b(ree)31 b(Soft)m(w)m(are)h(F)-8 b(oundation,)31 b(Inc.)390 745 ! y Fg(http://fsf.org/)390 964 y Fq(Ev)m(ery)m(one)g(is)g(p)s(ermitted)f (to)h(cop)m(y)g(and)f(distribute)g(v)m(erbatim)h(copies)390 1074 y(of)g(this)f(license)h(do)s(cumen)m(t,)g(but)e(c)m(hanging)j(it)f *************** *** 6181,6237 **** (is)330 2134 y(not)c(\\T)-8 b(ransparen)m(t")31 b(is)f(called)i (\\Opaque".)330 2285 y(Examples)53 b(of)g(suitable)h(formats)f(for)g(T) ! -8 b(ransparen)m(t)53 b(copies)h(include)f(plain)g Fe(asci)r(i)g Fq(without)330 2395 y(markup,)37 b(T)-8 b(exinfo)36 b(input)f(format,)j (LaT)1759 2414 y(E)1810 2395 y(X)e(input)f(format,)j ! Fi(SGML)f Fq(or)f Fi(XML)g Fq(using)g(a)g(publicly)330 ! 2504 y(a)m(v)-5 b(ailable)42 b Fi(DTD)p Fq(,)g(and)d ! (standard-conforming)h(simple)g Fi(HTML)p Fq(,)g(P)m(ostScript)h(or)f ! Fi(PDF)g Fq(designed)330 2614 y(for)e(h)m(uman)g(mo)s(di\014cation.)65 ! b(Examples)38 b(of)h(transparen)m(t)f(image)i(formats)e(include)g ! Fi(PNG)p Fq(,)h Fi(X)n(CF)330 2724 y Fq(and)h Fi(JPG)p ! Fq(.)g(Opaque)h(formats)g(include)f(proprietary)g(formats)h(that)h(can) ! f(b)s(e)f(read)g(and)h(edited)330 2833 y(only)54 b(b)m(y)f(proprietary) ! h(w)m(ord)f(pro)s(cessors,)59 b Fi(SGML)54 b Fq(or)f ! Fi(XML)h Fq(for)g(whic)m(h)f(the)h Fi(DTD)g Fq(and/or)330 ! 2943 y(pro)s(cessing)61 b(to)s(ols)h(are)f(not)g(generally)i(a)m(v)-5 ! b(ailable,)71 b(and)60 b(the)h(mac)m(hine-generated)j ! Fi(HTML)p Fq(,)330 3052 y(P)m(ostScript)31 b(or)f Fi(PDF)h ! Fq(pro)s(duced)d(b)m(y)j(some)f(w)m(ord)g(pro)s(cessors)g(for)g(output) ! g(purp)s(oses)f(only)-8 b(.)330 3203 y(The)34 b(\\Title)h(P)m(age")i ! (means,)e(for)f(a)h(prin)m(ted)f(b)s(o)s(ok,)h(the)f(title)i(page)f ! (itself,)h(plus)e(suc)m(h)f(follo)m(wing)330 3313 y(pages)28 ! b(as)g(are)g(needed)g(to)g(hold,)g(legibly)-8 b(,)30 ! b(the)e(material)h(this)e(License)i(requires)e(to)h(app)s(ear)f(in)h ! (the)330 3422 y(title)g(page.)40 b(F)-8 b(or)28 b(w)m(orks)e(in)g ! (formats)h(whic)m(h)g(do)f(not)h(ha)m(v)m(e)h(an)m(y)e(title)j(page)e ! (as)g(suc)m(h,)g(\\Title)h(P)m(age")330 3532 y(means)j(the)f(text)i ! (near)e(the)h(most)g(prominen)m(t)g(app)s(earance)f(of)h(the)g(w)m ! (ork's)g(title,)h(preceding)f(the)330 3641 y(b)s(eginning)f(of)g(the)h ! (b)s(o)s(dy)e(of)h(the)h(text.)330 3792 y(The)j(\\publisher")g(means)h ! (an)m(y)f(p)s(erson)g(or)h(en)m(tit)m(y)h(that)f(distributes)f(copies)i ! (of)e(the)h(Do)s(cumen)m(t)330 3902 y(to)c(the)g(public.)330 ! 4052 y(A)f(section)h(\\En)m(titled)g(XYZ")f(means)f(a)h(named)g ! (subunit)e(of)h(the)h(Do)s(cumen)m(t)h(whose)e(title)i(either)330 ! 4162 y(is)d(precisely)g(XYZ)g(or)f(con)m(tains)i(XYZ)f(in)f(paren)m ! (theses)i(follo)m(wing)g(text)g(that)f(translates)h(XYZ)e(in)330 ! 4271 y(another)e(language.)40 b(\(Here)26 b(XYZ)f(stands)f(for)h(a)g ! (sp)s(eci\014c)g(section)h(name)f(men)m(tioned)h(b)s(elo)m(w,)g(suc)m ! (h)330 4381 y(as)i(\\Ac)m(kno)m(wledgemen)m(ts",)33 b(\\Dedications",)e ! (\\Endorsemen)m(ts",)e(or)f(\\History".\))42 b(T)-8 b(o)29 ! b(\\Preserv)m(e)330 4491 y(the)34 b(Title")h(of)e(suc)m(h)h(a)g ! (section)g(when)f(y)m(ou)h(mo)s(dify)e(the)i(Do)s(cumen)m(t)h(means)e ! (that)h(it)g(remains)g(a)330 4600 y(section)e(\\En)m(titled)f(XYZ")g ! (according)g(to)g(this)g(de\014nition.)330 4751 y(The)c(Do)s(cumen)m(t) ! i(ma)m(y)f(include)f(W)-8 b(arran)m(t)m(y)30 b(Disclaimers)f(next)f(to) ! g(the)g(notice)h(whic)m(h)e(states)i(that)330 4861 y(this)34 ! b(License)g(applies)g(to)h(the)f(Do)s(cumen)m(t.)52 b(These)33 ! b(W)-8 b(arran)m(t)m(y)36 b(Disclaimers)f(are)g(considered)e(to)330 ! 4970 y(b)s(e)k(included)g(b)m(y)g(reference)h(in)g(this)f(License,)j ! (but)d(only)h(as)g(regards)f(disclaiming)i(w)m(arran)m(ties:)330 ! 5080 y(an)m(y)e(other)g(implication)i(that)e(these)g(W)-8 ! b(arran)m(t)m(y)39 b(Disclaimers)f(ma)m(y)g(ha)m(v)m(e)g(is)f(v)m(oid)g ! (and)f(has)h(no)330 5189 y(e\013ect)32 b(on)e(the)h(meaning)f(of)h ! (this)f(License.)199 5340 y(2.)61 b(VERBA)-8 b(TIM)31 ! b(COPYING)p eop end %%Page: 10 14 TeXDict begin 10 13 bop 150 -116 a Fq(GNU)31 b(F)-8 b(ree)31 --- 6181,6237 ---- (is)330 2134 y(not)c(\\T)-8 b(ransparen)m(t")31 b(is)f(called)i (\\Opaque".)330 2285 y(Examples)53 b(of)g(suitable)h(formats)f(for)g(T) ! -8 b(ransparen)m(t)53 b(copies)h(include)f(plain)g Ff(asci)r(i)g Fq(without)330 2395 y(markup,)37 b(T)-8 b(exinfo)36 b(input)f(format,)j (LaT)1759 2414 y(E)1810 2395 y(X)e(input)f(format,)j ! Fe(SGML)f Fq(or)f Fe(XML)g Fq(using)g(a)g(publicly)330 ! 2504 y(a)m(v)-5 b(ailable)42 b Fe(DTD)p Fq(,)h(and)c ! (standard-conforming)g(simple)h Fe(HTML)p Fq(,)i(P)m(ostScript)e(or)f ! Fe(PDF)h Fq(designed)330 2614 y(for)e(h)m(uman)f(mo)s(di\014cation.)65 ! b(Examples)38 b(of)h(transparen)m(t)f(image)h(formats)g(include)f ! Fe(PNG)p Fq(,)i Fe(X)n(CF)330 2724 y Fq(and)e Fe(JPG)p ! Fq(.)64 b(Opaque)38 b(formats)h(include)f(proprietary)h(formats)f(that) ! h(can)g(b)s(e)f(read)h(and)f(edited)330 2833 y(only)54 ! b(b)m(y)f(proprietary)h(w)m(ord)f(pro)s(cessors,)59 b ! Fe(SGML)54 b Fq(or)f Fe(XML)h Fq(for)g(whic)m(h)f(the)h ! Fe(DTD)g Fq(and/or)330 2943 y(pro)s(cessing)61 b(to)s(ols)h(are)f(not)g ! (generally)i(a)m(v)-5 b(ailable,)71 b(and)60 b(the)h(mac)m ! (hine-generated)j Fe(HTML)p Fq(,)330 3052 y(P)m(ostScript)31 ! b(or)f Fe(PDF)h Fq(pro)s(duced)d(b)m(y)j(some)f(w)m(ord)g(pro)s ! (cessors)g(for)g(output)g(purp)s(oses)f(only)-8 b(.)330 ! 3203 y(The)34 b(\\Title)h(P)m(age")i(means,)e(for)f(a)h(prin)m(ted)f(b) ! s(o)s(ok,)h(the)f(title)i(page)f(itself,)h(plus)e(suc)m(h)f(follo)m ! (wing)330 3313 y(pages)28 b(as)g(are)g(needed)g(to)g(hold,)g(legibly)-8 ! b(,)30 b(the)e(material)h(this)e(License)i(requires)e(to)h(app)s(ear)f ! (in)h(the)330 3422 y(title)g(page.)40 b(F)-8 b(or)28 ! b(w)m(orks)e(in)g(formats)h(whic)m(h)g(do)f(not)h(ha)m(v)m(e)h(an)m(y)e ! (title)j(page)e(as)g(suc)m(h,)g(\\Title)h(P)m(age")330 ! 3532 y(means)j(the)f(text)i(near)e(the)h(most)g(prominen)m(t)g(app)s ! (earance)f(of)h(the)g(w)m(ork's)g(title,)h(preceding)f(the)330 ! 3641 y(b)s(eginning)f(of)g(the)h(b)s(o)s(dy)e(of)h(the)h(text.)330 ! 3792 y(The)j(\\publisher")g(means)h(an)m(y)f(p)s(erson)g(or)h(en)m(tit) ! m(y)h(that)f(distributes)f(copies)i(of)e(the)h(Do)s(cumen)m(t)330 ! 3902 y(to)c(the)g(public.)330 4052 y(A)f(section)h(\\En)m(titled)g ! (XYZ")f(means)f(a)h(named)g(subunit)e(of)h(the)h(Do)s(cumen)m(t)h ! (whose)e(title)i(either)330 4162 y(is)d(precisely)g(XYZ)g(or)f(con)m ! (tains)i(XYZ)f(in)f(paren)m(theses)i(follo)m(wing)g(text)g(that)f ! (translates)h(XYZ)e(in)330 4271 y(another)e(language.)40 ! b(\(Here)26 b(XYZ)f(stands)f(for)h(a)g(sp)s(eci\014c)g(section)h(name)f ! (men)m(tioned)h(b)s(elo)m(w,)g(suc)m(h)330 4381 y(as)i(\\Ac)m(kno)m ! (wledgemen)m(ts",)33 b(\\Dedications",)e(\\Endorsemen)m(ts",)e(or)f ! (\\History".\))42 b(T)-8 b(o)29 b(\\Preserv)m(e)330 4491 ! y(the)34 b(Title")h(of)e(suc)m(h)h(a)g(section)g(when)f(y)m(ou)h(mo)s ! (dify)e(the)i(Do)s(cumen)m(t)h(means)e(that)h(it)g(remains)g(a)330 ! 4600 y(section)e(\\En)m(titled)f(XYZ")g(according)g(to)g(this)g ! (de\014nition.)330 4751 y(The)c(Do)s(cumen)m(t)i(ma)m(y)f(include)f(W) ! -8 b(arran)m(t)m(y)30 b(Disclaimers)f(next)f(to)g(the)g(notice)h(whic)m ! (h)e(states)i(that)330 4861 y(this)34 b(License)g(applies)g(to)h(the)f ! (Do)s(cumen)m(t.)52 b(These)33 b(W)-8 b(arran)m(t)m(y)36 ! b(Disclaimers)f(are)g(considered)e(to)330 4970 y(b)s(e)k(included)g(b)m ! (y)g(reference)h(in)g(this)f(License,)j(but)d(only)h(as)g(regards)f ! (disclaiming)i(w)m(arran)m(ties:)330 5080 y(an)m(y)e(other)g ! (implication)i(that)e(these)g(W)-8 b(arran)m(t)m(y)39 ! b(Disclaimers)f(ma)m(y)g(ha)m(v)m(e)g(is)f(v)m(oid)g(and)f(has)h(no)330 ! 5189 y(e\013ect)32 b(on)e(the)h(meaning)f(of)h(this)f(License.)199 ! 5340 y(2.)61 b(VERBA)-8 b(TIM)31 b(COPYING)p eop end %%Page: 10 14 TeXDict begin 10 13 bop 150 -116 a Fq(GNU)31 b(F)-8 b(ree)31 *************** *** 6594,6598 **** (in)g(spirit)330 653 y(to)j(the)g(presen)m(t)f(v)m(ersion,)i(but)e(ma)m (y)h(di\013er)f(in)g(detail)h(to)g(address)f(new)g(problems)f(or)i ! (concerns.)330 762 y(See)c Ff(http://www.gnu.org/copy)o(left)o(/)p Fq(.)330 897 y(Eac)m(h)f(v)m(ersion)g(of)g(the)f(License)h(is)g(giv)m (en)g(a)g(distinguishing)f(v)m(ersion)h(n)m(um)m(b)s(er.)39 --- 6594,6598 ---- (in)g(spirit)330 653 y(to)j(the)g(presen)m(t)f(v)m(ersion,)i(but)e(ma)m (y)h(di\013er)f(in)g(detail)h(to)g(address)f(new)g(problems)f(or)i ! (concerns.)330 762 y(See)c Fg(http://www.gnu.org/copy)o(left)o(/)p Fq(.)330 897 y(Eac)m(h)f(v)m(ersion)g(of)g(the)f(License)h(is)g(giv)m (en)g(a)g(distinguishing)f(v)m(ersion)h(n)m(um)m(b)s(er.)39 *************** *** 6693,6697 **** 663 y(Cop)m(yrigh)m(t)842 660 y(c)817 663 y Fo(\015)h Fq(2007)i(F)-8 b(ree)32 b(Soft)m(w)m(are)f(F)-8 b(oundation,)32 ! b(Inc.)e Ff(http://fsf.org/)390 882 y Fq(Ev)m(ery)m(one)h(is)g(p)s (ermitted)f(to)h(cop)m(y)g(and)f(distribute)g(v)m(erbatim)h(copies)g (of)g(this)390 991 y(license)g(do)s(cumen)m(t,)g(but)e(c)m(hanging)j --- 6693,6697 ---- 663 y(Cop)m(yrigh)m(t)842 660 y(c)817 663 y Fo(\015)h Fq(2007)i(F)-8 b(ree)32 b(Soft)m(w)m(are)f(F)-8 b(oundation,)32 ! b(Inc.)e Fg(http://fsf.org/)390 882 y Fq(Ev)m(ery)m(one)h(is)g(p)s (ermitted)f(to)h(cop)m(y)g(and)f(distribute)g(v)m(erbatim)h(copies)g (of)g(this)390 991 y(license)g(do)s(cumen)m(t,)g(but)e(c)m(hanging)j *************** *** 7586,7590 **** (redistribute)j(it)390 3373 y(under)e(certain)h(conditions;)h(type)e (`show)g(c')g(for)g(details.)275 3508 y Fq(The)27 b(h)m(yp)s(othetical) ! i(commands)f(`)p Ff(show)h(w)p Fq(')f(and)f(`)p Ff(show)j(c)p Fq(')d(should)g(sho)m(w)h(the)g(appropriate)g(parts)g(of)150 3617 y(the)i(General)h(Public)f(License.)41 b(Of)30 b(course,)h(y)m --- 7586,7590 ---- (redistribute)j(it)390 3373 y(under)e(certain)h(conditions;)h(type)e (`show)g(c')g(for)g(details.)275 3508 y Fq(The)27 b(h)m(yp)s(othetical) ! i(commands)f(`)p Fg(show)h(w)p Fq(')f(and)f(`)p Fg(show)j(c)p Fq(')d(should)g(sho)m(w)h(the)g(appropriate)g(parts)g(of)150 3617 y(the)i(General)h(Public)f(License.)41 b(Of)30 b(course,)h(y)m *************** *** 7597,7601 **** h(program,)g(if)f(necessary)-8 b(.)48 b(F)-8 b(or)34 b(more)e(information)h(on)g(this,)150 4081 y(and)d(ho)m(w)g(to)h(apply) ! f(and)g(follo)m(w)i(the)e(GNU)h(GPL,)g(see)g Ff (http://www.gnu.org/licen)o(ses)o(/)p Fq(.)275 4215 y(The)44 b(GNU)h(General)g(Public)f(License)i(do)s(es)e(not)h(p)s(ermit)e --- 7597,7601 ---- h(program,)g(if)f(necessary)-8 b(.)48 b(F)-8 b(or)34 b(more)e(information)h(on)g(this,)150 4081 y(and)d(ho)m(w)g(to)h(apply) ! f(and)g(follo)m(w)i(the)e(GNU)h(GPL,)g(see)g Fg (http://www.gnu.org/licen)o(ses)o(/)p Fq(.)275 4215 y(The)44 b(GNU)h(General)g(Public)f(License)i(do)s(es)e(not)h(p)s(ermit)e *************** *** 7608,7612 **** (the)g(GNU)h(Lesser)g(General)g(Public)f(License)h(instead)g(of)f(this) h(License.)40 b(But)30 b(\014rst,)f(please)150 4653 y(read)h ! Ff(http://www.gnu.org/philos)o(ophy)o(/why)o(-no)o(t-lg)o(pl.h)o(tml)o Fq(.)p eop end %%Page: 27 31 --- 7608,7612 ---- (the)g(GNU)h(Lesser)g(General)g(Public)f(License)h(instead)g(of)f(this) h(License.)40 b(But)30 b(\014rst,)f(please)150 4653 y(read)h ! Fg(http://www.gnu.org/philos)o(ophy)o(/why)o(-no)o(t-lg)o(pl.h)o(tml)o Fq(.)p eop end %%Page: 27 31 diff -rc2P 3DLDF-2.0.2/doc/3dldf.texi 3DLDF-2.0.3/doc/3dldf.texi *** 3DLDF-2.0.2/doc/3dldf.texi Wed Nov 6 16:00:14 2013 --- 3DLDF-2.0.3/doc/3dldf.texi Fri Dec 13 16:38:27 2013 *************** *** 7,22 **** %%%% fdl.texi for copying conditions. \input epsf ! \def\epsfsize#1#2{#1} \newbox\PPbox % symbol for ++ ! \setbox\PPbox=\hbox{\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt} ! \def\PP{\copy\PPbox} ! \let\mc=\tenrm ! \def\CPLUSPLUS{{\mc C\PP\spacefactor1000}} - \font\manual=manfnt % font used for the METAFONT logo, etc. - \input texinfo @c -*-texinfo-*- @c %**start of header --- 7,28 ---- %%%% fdl.texi for copying conditions. + \input texinfo @c -*-texinfo-*- + + @iftex + @tex \input epsf ! \global\def\epsfsize#1#2{#1} \newbox\PPbox % symbol for ++ ! \global\setbox\PPbox=\hbox{\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt} ! \global\def\PP{\copy\PPbox} ! \global\let\mc=\tenrm ! \global\def\CPLUSPLUS{{\mc C\PP\spacefactor1000}} ! \global\font\manual=manfnt % font used for the METAFONT logo, etc. ! @end tex ! @end iftex ! @c %**start of header *************** *** 146,172 **** @end menu - - @macro cpp {} @iftex @tex @CPLUSPLUS @end tex @end iftex @ifnottex C++ - @end ifnottex @end macro - - @macro MF {} @iftex @tex {@manual METAFONT} @end tex @end iftex @ifnottex METAFONT - @end ifnottex @end macro @macro MP {} --- 152,182 ---- @end menu @iftex + @macro cpp {} @tex @CPLUSPLUS @end tex + @end macro @end iftex + @ifnottex + @macro cpp {} C++ @end macro + @end ifnottex @iftex + @macro MF {} @tex {@manual METAFONT} @end tex + @end macro @end iftex + @ifnottex + @macro MF {} METAFONT @end macro + @end ifnottex @macro MP {} diff -rc2P 3DLDF-2.0.2/doc/Makefile.am 3DLDF-2.0.3/doc/Makefile.am *** 3DLDF-2.0.2/doc/Makefile.am Thu Nov 7 15:08:25 2013 --- 3DLDF-2.0.3/doc/Makefile.am Wed Nov 13 13:11:23 2013 *************** *** 59,63 **** invoking.texi varidx.texi ! EXTRA_DIST = 3dldf.ps 3dldf.pdf 3dldf.dvi 3dldf.html 3dldf.info $(SOURCES_MANUAL) all: 3dldf.dvi 3dldf.ps 3dldf.pdf 3dldf.info 3dldf.html html-split --- 59,63 ---- invoking.texi varidx.texi ! EXTRA_DIST = 3dldf.ps 3dldf.pdf 3dldf.dvi 3dldf.html 3dldf.info $(SOURCES_MANUAL) texinfo.tex all: 3dldf.dvi 3dldf.ps 3dldf.pdf 3dldf.info 3dldf.html html-split *************** *** 98,105 **** makeinfo --html --no-split 3dldf.texi ! .PHONY: html-split html-split: $(SOURCES_MANUAL) makeinfo --html 3dldf.texi #### ** (2) Tags --- 98,106 ---- makeinfo --html --no-split 3dldf.texi ! #### .PHONY: html-split html-split: $(SOURCES_MANUAL) makeinfo --html 3dldf.texi + touch html-split #### ** (2) Tags diff -rc2P 3DLDF-2.0.2/doc/Makefile.in 3DLDF-2.0.3/doc/Makefile.in *** 3DLDF-2.0.2/doc/Makefile.in Sun Nov 10 18:30:13 2013 --- 3DLDF-2.0.3/doc/Makefile.in Fri Dec 13 12:29:28 2013 *************** *** 132,136 **** host_triplet = @host@ subdir = doc ! DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ --- 132,136 ---- host_triplet = @host@ subdir = doc ! DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am texinfo.tex ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ *************** *** 299,303 **** invoking.texi varidx.texi ! EXTRA_DIST = 3dldf.ps 3dldf.pdf 3dldf.dvi 3dldf.html 3dldf.info $(SOURCES_MANUAL) all: all-am --- 299,303 ---- invoking.texi varidx.texi ! EXTRA_DIST = 3dldf.ps 3dldf.pdf 3dldf.dvi 3dldf.html 3dldf.info $(SOURCES_MANUAL) texinfo.tex all: all-am *************** *** 518,525 **** makeinfo --html --no-split 3dldf.texi ! .PHONY: html-split html-split: $(SOURCES_MANUAL) makeinfo --html 3dldf.texi #### ** (2) Tags --- 518,526 ---- makeinfo --html --no-split 3dldf.texi ! #### .PHONY: html-split html-split: $(SOURCES_MANUAL) makeinfo --html 3dldf.texi + touch html-split #### ** (2) Tags diff -rc2P 3DLDF-2.0.2/doc/dttypes.texi 3DLDF-2.0.3/doc/dttypes.texi *** 3DLDF-2.0.2/doc/dttypes.texi Wed Nov 6 17:26:14 2013 --- 3DLDF-2.0.3/doc/dttypes.texi Wed Nov 13 12:29:06 2013 *************** *** 51,55 **** Focus for the @dfn{perspective projection}. ! @itemx pen @itemx dash_pattern --- 51,55 ---- Focus for the @dfn{perspective projection}. ! @item pen @itemx dash_pattern diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/About-This-Manual.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/About-This-Manual.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/About-This-Manual.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/About-This-Manual.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,132 ---- + + + About This Manual - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Sources of Information, + Up: Introduction +


+
+ +

1.2 About This Manual

+ +

This manual has been created using + Texinfo, a documentation system which is part of the GNU Project, whose + main sponsor is the Free Software Foundation. + Texinfo can be used to generate online and printed documentation from + the same input files. + +

For more information about Texinfo, see: + +

+ 
+ 
+ + Stallmann, Richard M. and Robert J. Chassell. + Texinfo. The GNU Documentation Format. + The Free Software Foundation. Boston 1999. +
+ 
+ 
+ +

For more information about the GNU Project and the Free Software + Foundation, see the following web site: http://www.gnu.org. + +

The edition of this manual is + 1.1.5.1 and it documents version 1.1.5.1 of 3DLDF. + The edition number of the manual and the version number of the program + are the same (as of 16 January 2004), + but may diverge at a later date. + +

Note that “I”, “me”, etc., in this manual refers to + Laurence D. Finston, so far the sole author of + both 3DLDF and this manual. “Currently” and similar formulations + refer to version 1.1.5.1 of 3DLDF as of + 16 January 2004. + +

This manual is intended for both beginning and advanced users of 3DLDF. + So, if there's something you don't understand, it's probably best to + skip it and come back to it later. + Some of the more difficult points, or ones that presuppose familiarity + with features not yet described, are in the footnotes. + + + + + + + + +

I firmly believe that an adequate program with good documentation is + more useful than a great program with poor or no documentation. The + ideal case, of course, is a great program with great documentation. I'm + sorry to say, that this manual is not yet as good as I'd like it to be. + I apologize for the number of typos and other errors. I hope they don't + detract too much from its usefulness. I would have liked to have + proofread and corrected it again before publication, but for reasons + external to 3DLDF, it is necessary for me to publish now. I plan to set + up an errata list on + the official 3DLDF website, + and/or + my own website. + +

Unless I've left anything out by mistake, this manual documents all of + the data types, constants and variables, namespaces, and functions + defined in 3DLDF. However, some of the descriptions are terser than I + would like, and I'd like to have more examples and illustrations. There + is also more to be said on a number of topics touched on in this + manual, and some topics I haven't touched on at all. In general, while + I've tried to give complete information on the “what and how”, the + “why and wherefore” has sometimes gotten short shrift. + I hope to correct these defects in future editions. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Accuracy.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Accuracy.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Accuracy.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Accuracy.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,107 ---- + + + Accuracy - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Caveats, + Up: Caveats +


+
+ +

1.5.1 Accuracy

+ +

When 3DLDF is run, it uses the three-dimensional data contained in the + user code to create a two-dimensional projection. + Currently, this can be a perspective projection, or a parallel + projection onto one of the major planes. MetaPost code representing + this projection is then written to the output file. + 3DLDF does no scan conversion,1 + so all of the curves in the projection are + generated by means of the algorithms MetaPost inherited from Metafont. + These algorithms, however, are designed to find the + “most pleasing curve”2 + given one or more two-dimensional points and connectors; they do not + account for the the fact that the two-dimensional points are projections + of three-dimensional ones. This can lead to unsatisfactory results, + especially where extreme foreshortening occurs. In particular, + ‘curl’, dir, ‘tension’, and control points should be + used cautiously, or avoided altogether, when specifying connectors. + +

3DLDF operates on + the assumption that, given an adequate number of points, + MetaPost will produce an adequate approximation to the desired + curve in perspective, since the greater the number of + points given for a curve, the less “choice” MetaPost has for + the path through them. My experience with 3DLDF bears this + out. Generally, the curves look quite good. Where problems arise, + it usually helps to increase the number of points in a curve. + +

A more serious problem is the imprecision resulting from the operation + of rotation. Rotations use the trigonometric functions, which return + approximate values. This has the result that points that should have + identical coordinate values, sometimes do not. + This has consequences for the functions that compare points. + The more rotations + are applied to points, the greater the divergence between their actual + coordinate values, and the values they should have. So far, I haven't + found a solution for this problem. On the other hand, it hasn't + yet affected the usability of 3DLDF. + +

+
+

Footnotes

[1] Scan conversion is the process of digitizing geometric + data. The ultimate result is a + 2 X 2 + map of pixels, which can be used for printing or representing the projection on a + computer screen. The number of pixels per a given unit of measurement + is the resolution of a given output device, e.g., 300 pixels per inch.

+ +

[2] Knuth, The METAFONTbook, Chapter 14, p. 127.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Adding-a-File.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Adding-a-File.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Adding-a-File.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Adding-a-File.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,168 ---- + + + Adding a File - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Utility Functions, + Up: Top +


+
+ +

39 Adding a File

+ +

Version 1.1.1 was the first version of 3DLDF since it became a GNU + package (the current version is 1.1.5.1). In previous versions, + recompilation was controlled by an + auxilliary program, which I wrote in C++ + using CWEB. However, + in the course of making 3DLDF conformant to the + GNU Coding Standards1, + this has + been changed. Recompilation is now controlled by make, as is + customary. The chapter “Compiling” in previous editions of this + manual, is therefore no longer needed. + +

Nonetheless, using CWEB still has consequences for the way recompilation + must be handled, and it was fairly tricky getting make to work + for 3DLDF. Users who only put code in main.web and/or change + code in existing files won't have to worry about this; + for others, this chapter explains how to add + files to 3DLDF. + +

Let's say you want to add a file widgets.web that defines a + class Widget, and that the latter needs access to + class Rectangle, and is in turn required by class Ellipse. + Code must be added to 3DLDF-1.1.5.1/CWEB/Makefile for + ctangling widgets.web, compiling widgets.cxx, and linking + widgets.o with the other object files to make the executable + 3dldf. + +

The best way to do this is to change + 3DLDF-1.1.5.1/CWEB/Makefile.am and use Automake + to generate a new Makefile.in. Then, configure can be + used to generate a new Makefile. It would be possible to modify + Makefile by hand, but I don't recommend it. The following + assumes that the user has access to Automake. If he or she is using a + GNU/Linux system, this is probably true.2 + +

widgets.web’ must be added between ‘rectangs.web’ and + ‘ellipses.web’ in the following variable declaration in + 3DLDF-1.1.5.1/CWEB/Makefile.am: + +

     3dldf_SOME_CWEBS = pspglb.web io.web colors.web transfor.web \
+                         shapes.web pictures.web points.web \
+                         lines.web planes.web paths.web curves.web \
+                         polygons.web rectangs.web ellipses.web \
+                         circles.web patterns.web solids.web
+                         solfaced.web cuboid.web polyhed.web \
+                         utility.web parser.web examples.web
+ 
+

Now, add ‘widgets.o’ between ‘ellipses.o’ and + ‘rectangs.o’ in the following variable declaration: + +

     3dldf_OBS_REVERSED = main.o examples.o parser.o utility.o \
+                           polyhed.o cuboid.o  solfaced.o solids.o \
+                           patterns.o circles.o ellipses.o rectangs.o \
+                           polygons.o curves.o paths.o \
+                           planes.o lines.o points.o pictures.o shapes.o
+                           transfor.o colors.o io.o pspglb.o
+ 
+

3dldf_OBS_REVERSED is needed, because 3DLDF fails with + a “Segmentation fault”, if + the executable is linked using $(3dldf_OBJECTS). This may cause + problems, if 3dldf isn't built using the GNU C++ + compiler + (GCC). + +

Now add a target for widgets.o between the targets for + rectangs.o and ellipses.o, and add widgets.tim + after rectangs.tim in the list of prerequisites for + ellipses.o: + +

     rectangs.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.cxx
+      
+      ellipses.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.tim ellipses.cxx
+ 
+

This is the result: +

     rectangs.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.cxx
+      
+      widgets.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.tim \
+               widgets.cxx
+      
+      ellipses.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.tim widgets.tim \
+               ellipses.cxx
+ 
+

In addition, widgets.tim + must be added to the list of prerequisites in all of the following + targets up to and including examples.o. + + + + + + +

+
+

Footnotes

[1] The GNU Coding Standards are available at + http://www.gnu.org/prep/standards_toc.html.

+ +

[2] Automake is available for downloading from + http://ftp.gnu.org/gnu/automake/. The Automake website is at + http://www.gnu.org/software/automake/.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Ellipses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Ellipses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Ellipses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Ellipses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,92 ---- + + + Affine Transformations for Ellipses - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Labeling Ellipses, + Up: Ellipse Reference +


+
+ +

31.6 Affine Transformations

+ +
+ — Virtual function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — Virtual function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+ — Virtual function: Transform rotate (const Path& p, [const real angle = 180])
+ — Virtual function: Transform scale (real x, [real y = 1, [real z = 1]])
+ — Virtual function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+ — Virtual function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Virtual function: Transform shift (const Point& p)
+ — Virtual function: void shift_times (real x, [real y = 1, [real z = 1]])
+ — Virtual function: void shift_times (const Point& p)
+

These create a Transform t locally, and call + do_transform(t). + See Ellipse Reference; Performing Transformations. + +

Rotating and shifting an Ellipse neither change the size of an + Ellipse, nor cause it to become + non-elliptical. However, scaling and shearing can have these effects. + For this reason, in scale() and shear(), + do_transform() is called with true as its check + argument, while it is false in rotate(), shift(), + and shift_times(). + +

If scaling or shearing is performed on an Ellipse, and it is + still elliptical after the transformation, focus0, focus1, + axis_h, axis_v, linear_eccentricity, and + numerical_eccentricity are all + recalculated. If the Ellipse is non-elliptical after the + transformation, axis_h, axis_v, + linear_eccentricity, and numerical_eccentricity + are all set to INVALID_REAL. center, focus0, and + focus1 are not set to INVALID_POINT. Although they are no + longer the center and foci of an elliptical Ellipse, they may + still have some use for the user or programmer. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,245 ---- + + + Affine Transformations for Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Modifying Paths, + Up: Path Reference +


+
+ +

26.9 Affine Transformations

+ +
+ — Virtual function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+

Creates a Transform t locally and calls + t.rotate(x, y, z). + t is then applied to all of the Points on points. + The return value is t. +

+ +
+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Creates a Transform t locally and calls + t.scale(x, y, z). + t is then applied to all of the Points on points. + The return value is t. + +

The Points on the Path are scaled according to the + arguments: + +

          Point pt[8];
+           pt[0] = (-1, -1);
+           for (int i = 1; i < 8; ++i)
+             {
+               pt[i] = pt[0];
+               pt[i].rotate(0, 0, i * 45);
+             }
+           Path p("--", true, &pt[0], &pt[1], &pt[2], &pt[3],
+                  &pt[4], &pt[5], &pt[6],
+                  &pt[7], 0);
+           p.draw();
+           p.scale(2, 2);
+           p.draw();
+ 
+

+
+ [Figure 115. Not displayed.] +
+
+ Fig. 115. +
+

+ +
+ +
+ — Function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+

Creates a Transform t locally and calls + t.shear(xy, xz, yx, yz, zx, zy). + t is then applied to all of the Points on points. + The return value is t. + +

          Point p0;
+           Point p1(1);
+           Point p2(1, 1);
+           Point p3(0, 1);
+           Path q("--", true, &p0, &p1, &p2, &p3, 0);
+           q.rotate(0, 45);
+           q.shift(1);
+           q.filldraw(black, light_gray);
+           q.shear(1.5, 2, 2.5, 3, 3.5, 5);
+           q.filldraw(black, light_gray);
+ 
+

+
+ [Figure 116. Not displayed.] +
+
+ Fig. 116. +
+

+ +
+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+

Creates a Transform t locally and calls + t.shift(x, y, z). + t is then applied to all of the Points on points. + The return value is t. + +

Shifts each of the Points on the Path according to the + arguments. + +

          default_focus.set(5, 10, -10, 0, 10, 10, 10);
+           Point pt[6];
+           pt[0].set(-2, -2);
+           pt[1].set(0, -3);
+           pt[2].set(2, -2);
+           pt[3].set(2, 2);
+           pt[4].set(0, 3);
+           pt[5].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2],
+                  &pt[3], &pt[4], &pt[5], 0);
+           p.draw();
+           p.shift(3, 3, 3);
+           p.draw();
+ 
+

+
+ [Figure 117. Not displayed.] +
+
+ Fig. 117. +
+

+ +
+ +
+ — Function: Transform shift (const Point& p)
+

Creates a Transform t locally and calls + t.shift(p). + t is then applied to all of the Points on points. + The return value is t. + +

This version of shift() uses the x, y, and z-coordinates of the + Point p to shift the Path. + +

          default_focus.set(5, 10, -10, 0, 10, 10, 10);
+           Point pt[6];
+           pt[0].set(-2, -2);
+           pt[1].set(0, -3);
+           pt[2].set(2, -2);
+           pt[3].set(2, 2);
+           pt[4].set(0, 3);
+           pt[5].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2],
+                  &pt[3], &pt[4], &pt[5], 0);
+           p.draw();
+           Point s(1, 1, 1);
+           p.shift(s);
+           p.draw();
+ 
+

+
+ [Figure 118. Not displayed.] +
+
+ Fig. 118. +
+

+ +
+ +
+ — Virtual function: void shift_times (real x, [real y = 1, [real z = 1]])
+ — Virtual function: void shift_times (const Point& p)
+

Each of these functions calls the corresponding version of + Point::shift_times() on all of the + Points on points. + See Point Reference; Affine Transformations. + The return value is void, + because there is no guarantee that all of the Points on a + Path will have identical transform members (although it's + likely). + +

Please note that shift_times() will only have an effect on + the Points on a Path if it's called after a call to + shift() and before an operation is applied that causes + Point::apply_transform() to be called. +

+ +
+ — Virtual function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+

Creates a Transform t locally and calls + t.rotate(p0, p1, angle). + t is then applied to all of the Points on points. + The return value is t. +

+ +
+ — Function: Transform rotate (const Path& p, [const real angle = 180])
+

If p.is_linear() returns true, this function + creates a Transform t locally and calls + t.rotate(p, angle). + t is then applied to all of the Points on points. + The return value is t. + Otherwise, it issues an error message and returns + INVALID_TRANSFORM. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Pictures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Pictures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Pictures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Pictures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,98 ---- + + + Affine Transformations for Pictures - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Picture Operators, + Up: Picture Reference +


+
+ +

21.5 Affine Transformations

+ +

The functions in this section all operate on the transform data + member of the Picture and return a Transform representing the + transformation—not transform. + +

+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Performs transform.scale(x, y, z) and returns + the result. This has the effect of scaling + all of the elements of shapes and labels. +

+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+

Performs transform.shift(x, y, z) and returns + the result. This has the effect of shifting + all of the Shapes and Labels on the Picture. +

+ +
+ — Function: Transform shift (const Point& p)
+

Performs transform.shift(p) and returns + the result. This has the effect of shifting + all of the Shapes and Labels on the Picture by the + x, y, and z-coordinates of p. +

+ +
+ — Function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+

Performs transform.rotate(x, y, z) and returns + the result. This has the effect of rotating + all of the elements of shapes and labels. +

+ +
+ — Function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180]);
+

Performs transform.rotate(p0, p1, angle) and returns + the result. This has the effect of rotating + all of the elements of shapes and labels about the line + from p_0 to p_1. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,274 ---- + + + Affine Transformations for Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.12 Affine Transformations

+ +
+ — Function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — Function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+ — Function: Transform rotate (const Path& p, [const real angle = 180])
+

Each of these functions calls the corresponding version of + Transform::rotate(), and returns its + return value, namely, a Transform representing the rotation + only. + +

In the first version, taking three real arguments, the + Point is rotated x degrees around the x-axis, y + degrees around the y-axis, and z degrees around the z-axis in + that order. + +

          Point p0(1, 0, 2);
+           p0.rotate(90);
+           p0.show("p0:")
+           -| p0: (1, 2, 0)
+           Point p1(-1, 1, 1);
+           p1.rotate(-90, 90, 90);
+           p1.show("pt1:");
+           -| p1: (1, -1, -1)
+ 
+

+
+ [Figure 81. Not displayed.] +
+
+ Fig. 81. +
+

+ +

Please note that rotations are not commutative operations. Nor are they + commutative with other transformations. + So, if you want to rotate a Point about the x, y and z-axes in + that order, + you can do so with a single invocation of rotate(), as in + the previous example. + However, if you want to rotate a Point first about the + y-axis and then about the x-axis, you must invoke rotate() twice. + +

          Point pt0(1, 1, 1);
+           pt0.rotate(0, 45);
+           pt0.rotate(45);
+           pt0.show("pt0:");
+           -| pt0: (0, 1.70711, 0.292893)
+ 
+

In the version taking two Point arguments p0 and p1, + and a real argument angle, the Point is rotated + angle degrees around the axis determined + by p0 and p1, 180 degrees + by default. + +

          Point P(2, 0, 0);
+           Point A;
+           Point B(2, 2, 2);
+           P.rotate(A, B, 180);
+ 
+

+
+ [Figure 82. Not displayed.] +
+
+ Fig. 82. +
+

+ +
+ +
+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Calls transform.scale(x, y, z) and returns its + return value, namely, a Transform representing the scaling operation + only. + +

Scaling causes the x-coordinate of the Point to be multiplied by + x, the y-coordinate of the Point to be multiplied by + y, and the z-coordinate of the Point to be multiplied by + z. + +

          Point p0(1, 0, 3);
+           p0.scale(4);
+           p0.show("p0:");
+           -| p0: (4, 0, 3)
+           Point p1(-2, -1, -2);
+           p1.scale(-2, -3, -4);
+           p1.show("p1:");
+           -| p1: (4, 3, 8)
+ 
+

+
+ [Figure 83. Not displayed.] +
+
+ Fig. 83. +
+

+ +
+ +
+ — Function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+

Calls transform.shear() with the same arguments + and returns its + return value, namely, a Transform representing the shearing operation + only. + +

Shearing modifies each coordinate of a Point + proportionately to the values of the other two coordinates. + Let x_0, y_0, and z_0 stand for the coordinates of + a Point P before P.shear(\alpha, \beta, + \gamma, \delta, \epsilon, \zeta + ), + and x_1, y_1, and z_1 + for its coordinates afterwards. + +

          x_1 == x_0 + \alpha y + \beta z
+           y_1 == y_0 + \gamma x + \delta z
+           z_1 == z_0 + \epsilon x + \zeta y
+ 
+

[next figure] + demonstrates the effect of shearing the four + Points of a + 3 * 3 + +

Rectangle (i.e., a square) r in the x-y plane using only an + xy argument, making it non-rectangular. + +

          Point P0;
+           Point P1(3);
+           Point P2(3, 3);
+           Point P3(0, 3);
+           Rectangle r(p0, p1, p2, p3);
+           r.draw();
+           r.shear(1.5);
+           r.draw(black, "evenly");
+ 
+

+
+ [Figure 84. Not displayed.] +
+
+ Fig. 84. +
+

+ +
+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Function: Transform shift (const Point& p)
+

Each of these functions calls the corresponding version of + Transform::shift() on transform, and returns its return + value, namely, a Transform representing the shifting operation + only. + +

The Point is shifted x units in the direction of the + positive x-axis, y units in the direction of the + positive y-axis, and z units in the direction of the + positive z-axis. + +

          p0(1, 2, 3);
+           p0.shift(2, 3, 5);
+           p0.show("p0:");
+           -| p0: (3, 5, 8)
+ 
+
+ +
+ — Function: Transform shift_times (real x, [real y = 1, [real z = 1]])
+ — Function: Transform shift_times (const Point& p)
+

Each of these functions calls the corresponding version of + Transform::shift_times() on transform and + returns its return value, namely the new value of transform. + +

shift_times() makes it possible to increase the magnitude of a + shift applied to a Point, while maintaining its direction. + Please note that shift_times() will only have an effect + if it's called after a call to + shift() and before transform is reset. + This is performed by reset_transform(), which is called in + apply_transform(), and can also be called directly. + See Transform Reference; Resetting, and + Point Reference; Applying Transformations. + +

          Point P;
+           P.drawdot();
+           P.shift(1, 1, 1);
+           P.drawdot();
+           P.shift_times(2, 2, 2);
+           P.drawdot();
+           P.shift_times(2, 2, 2);
+           P.drawdot();
+           P.shift_times(2, 2, 2);
+           P.drawdot();
+ 
+

+
+ [Figure 85. Not displayed.] +
+
+ Fig. 85. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Polygons.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Polygons.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Polygons.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Polygons.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,86 ---- + + + Affine Transformations for Polygons - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Querying Polygons, + Up: Polygon Reference +


+
+ +

27.4 Affine Transformations

+ +
+ — Virtual function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — Virtual function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+ — Virtual function: Transform rotate (const Path& p, [const real angle = 180])
+ — Virtual function: Transform scale (real x, [real y = 1, [real z = 1]])
+ — Virtual function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+ — Virtual function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Virtual function: Transform shift (const Point& p)
+ — Virtual function: void shift_times (real x, [real y = 1, [real z = 1]])
+ — Virtual function: void shift_times (const Point& p)
+

The affine transformation functions for Polygon differ from the + Path versions only in that center is transformed as well. + See Path Reference; Affine Transformations. + +

Please note, that the classes currently derived from Polygon, + namely Reg_Polygon and Rectangle, currently inherit these + functions from Polygon. The problem with this is, that they have + data members, which are not recalculated when a Reg_Polygon or + Rectangle is transformed. I plan to do something about this soon! + It will also be necessary to add the function + Reg_Polygon::is_reg_polygonal(), in order to test whether operations + on a Reg_Polygon have caused it to become + irregular and/or non-polygonal. Similarly, the function + Rectangle::is_rectangular() must be added, to test whether + operations on a Rectangle has caused it to become + non-rectangular. + See Regular Polygon Reference; Data Members, and Rectangle Reference; Data Members. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Affine Transformations for Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

18.5 Affine Transformations

+ +
+ — Pure virtual functions: Transform rotate (const real x, const real y, const real z)
+ — : Transform scale (real x, real y, real z)
+ — : Transform shear (real xy, real xz, real yx, real yz, real zx, real zy)
+ — : Transform shift (real x, real y, real z)
+ — : Transform rotate (const Point& p0, const Point& p1, const real r)
+

See Point Reference; Affine Transformations. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,71 ---- + + + Affine Transformations for Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Showing Solids, + Up: Solid Reference +


+
+ +

34.10 Affine Transformations

+ +
+ — Virtual functions: Transform scale (real x, [real y = 0, [real z = 0]])
+

Solid. + + — : Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+ — : Transform shift (real x, [real y = 0, [real z = 0]])
+ — : Transform shift (const Point& pt)
+ — : Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — : Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+

These functions perform the corresponding transformations on all of the + Shapes belonging to the Solid. + See Transform Reference; Affine Transformations. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Affine-Transformations-for-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,288 ---- + + + Affine Transformations for Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

19.10 Affine Transformations

+ +

The affine transformation functions use their arguments to create a new + Transform t (local to the function) representing the + appropriate transformation. Then, *this is multiplied by t + and t is returned. + Returning t instead of *this makes it possible to put the + affine transformation function at the end of a chain of invocations of + Transform::operator*=(): + +

     Transform t0, t1, t2, t3;
+      ...
+      t0 *= t1 *= t2 *= t3.scale(2, 3.5, 9);
+ 
+

t0, t1, and t2 are all multiplied by the + Transform with +

     matrix =
+      2   0    0  0
+      0   3.5  0  0
+      0   0    9  0
+      0   0    0  1
+ 
+

representing the scaling operation, not t3, which may + represent a combination of transformations. + +

+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Creates a Transform t representing the scaling operation locally, + multiplies *this by t, and returns t. + A Transform representing scaling only, when applied to a + Point p, will cause its x-coordinate to be multiplied by + x, its y-coordinate to be multiplied by y, and its + z-coordinate to be multiplied by z. + +

          Transform t;
+           t.scale(x, y, z);
+ 
+
t.matrix =
+           x 0 0 0
+           0 y 0 0
+           0 0 z 0
+           0 0 0 1
+ 
+
          Transform t;
+           t.scale(12.5, 20, 1.3);
+           t.show("t:");
+           -| t:
+              12.5       0       0       0
+                 0      20       0       0
+                 0       0     1.3       0
+                 0       0       0       1
+ 
+
+ +
+ — Function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+

Creates a Transform t representing the shearing operation locally, + multiplies *this by t, and returns t. + +

When applied to a Point, shearing causes each coordinate to be + modified according to the values of the other coordinates and the + arguments to shear: + +

          Point p(x,y,z);
+           Transform t;
+           t.shear(a, b, c, d, e, f);
+           p *= t;
+ 
+
          ⇒ p = ((x + ay + bz), (y + cx + dz), (z + ex + fy))
+ 
+
          Transform t;
+           t.shear(2, 3, 4, 5, 6, 7);
+           t.show("t:");
+           -| t:
+                 1       4       6       0
+                 2       1       7       0
+                 3       5       1       0
+                 0       0       0       1
+ 
+
+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Function: Transform shift (const Point& p)
+
+

These functions create a Transform t representing the shifting + operation locally, multiplies *this by t, and returns t. + +

The version with the argument const Point& p + passes the updated x, y, and z-coordinates of p (from + world_coordinates) to the + version with three real arguments. + +

When a Transform representing a single shifting operation only + is applied to a Point, the x, + y, and z arguments are added to the corresponding + coordinates of the Point: + +

          Point p(x,y,z);
+           Transform t;
+           t.shift(a, b, c);
+           p *= t;
+ 
+
          ⇒ p = (x + a, y + b, z + c)
+ 
+
+ +
+ — Function: Transform shift_times (real x, [real y = 1, [real z = 1]])
+

Multiplies the corresponding elements of matrix by + the real arguments, i.e., + matrix[3][0] is multiplied by x, + matrix[3][1] is multiplied by y, and + matrix[3][2] is multiplied by z. Returns *this. + +

Ordinary shifting is additive, so a special function is needed to + multiply the elements of matrix responsible for shifting. + The effect of shift_times() is to modify a Transform + representing a shifting operation such that the direction of the shift + is maintained, while changing the distance. + +

If the Transform represents other operations in addition to + shifting, e.g., scaling and/or shearing, the effect of + shift_times() may be unpredictable.1 + +

          Transform t;
+           t.shift(1, 2, 3);
+ 
+
t.matrix =
+           1 0 0 0
+           0 1 0 0
+           0 0 1 0
+           1 2 3 1
+ 
+
          t.shift_times(2, 2, 2);
+ 
+
t.matrix =
+           1 0 0 0
+           0 1 0 0
+           0 0 1 0
+           2 4 6 1
+ 
+
          Rectangle r[4];
+           r[0].set(origin, 1, 1, 90);
+           r[3] = r[2] = r[1] = r[0];
+           Transform t;
+           t.shift(1.5, 1.5);
+           r[0] *= t;
+           r[0].draw();
+           t.shift_times(1.5, 1.5);
+           r[1] *= t;
+           r[1].draw();
+           t.shift_times(1.5, 1.5);
+           r[2] *= t;
+           r[2].draw();
+           t.shift_times(1.5, 1.5);
+           r[3] *= t;
+           r[3].draw();
+ 
+

+
+ [Figure 73. Not displayed.] +
+
+ Fig. 73. +
+

+ +
          Cuboid c(origin, 1, 1, 1);
+           c.draw();
+           Transform t;
+           t.rotate(30, 30, 30);
+           t.shift(1, 0, 1);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+ 
+

+
+ [Figure 74. Not displayed.] +
+
+ Fig. 74. +
+

+ +
+ +
+ — Function: Transform rotate (real x, [real y = 0, [real z = 0]])
+

Rotation around the main axes. + Creates a Transform t representing the rotation, + multiplies *this by t, and returns t. +

+ +
+ — Function: Transform rotate (Point p0, Point p1, [const real angle = 180])
+

Rotation around an arbitrary axis. The Point arguments represent + the end points of the axis, and angle is the angle of rotation. + Since 180 degrees + rotation is needed so often, 180 is the default for + angle. +

+ +
+ — Function: Transform rotate (const Path& p, [const real angle = 180])
+

Rotation around an arbitrary axis. Path argument. + The Path p must be linear, i.e., p.is_linear() must + return true. See Path Reference; Querying. +

+ +
+
+

Footnotes

[1] For a person, not in the sense of the program behaving + unpredictably.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Aligning-Paths-with-an-Axis.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Aligning-Paths-with-an-Axis.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Aligning-Paths-with-an-Axis.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Aligning-Paths-with-an-Axis.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,140 ---- + + + Aligning Paths with an Axis - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

26.10 Aligning with an Axis

+ +
+ — const function: Transform align_with_axis ([const char axis = 'z'])
+ — Function: Transform align_with_axis (bool assign, [const char axis = 'z'])
+ — Function: Transform align_with_axis (const Point& p0, const Point& p1, const char axis)
+

These functions return the Transform which, if applied to the + Path, would align it with the major axis indicated by the + axis argument. + +

The first and second versions can only be called + for Paths where line_switch is true. The first + version is const, so the Path remains unchanged. The second + version should only be called with assign = true, so that the + Transform is applied to the Path, actually aligning it with + the axis indicated. If the second version is called with + assign = false, a warning message is issued to the standard error + output (stderr), since one might as well use the first version in + this case, but it won't do any harm. The third version creates a + Transform t locally that would align the line from p0 to + p1 with the axis indicated, and applies t to the Path. + +

          Point A(2, 3, 2);
+           Point B(-1, 1, 3);
+           Path p(A, B);
+           Transform t = p.align_with_axis(true, 'z');
+           t.show("t:");
+           -| t:
+               -0.316   0.507  -0.802       0
+                    0  -0.845  -0.535       0
+               -0.949  -0.169   0.267       0
+                 2.53    1.86    2.67       1
+           p *= t;
+           p.show("p:");
+           -| p:
+              (2.53, 1.86, 2.67) -- (-1.02, 1.23, 3.67);
+           
+           Point C(1);
+           C *= t.inverse();
+           
+           Path q;
+           q += "..";
+           q += C;
+           
+           for (int i = 0; i < 15; ++i)
+             {
+               C.rotate(A, B, 360.0/16);
+               q += C;
+             }
+           q.set_cycle(true);
+           q.show("q:");
+           -| q:
+              (1.68, 3, 1.05) .. (1.9, 2.68, 1.06) ..
+              (2.13, 2.4, 1.21) .. (2.35, 2.22, 1.48) ..
+              (2.51, 2.15, 1.83) .. (2.59, 2.22, 2.21) ..
+              (2.58, 2.4, 2.55) .. (2.49, 2.68, 2.81) ..
+              (2.32, 3, 2.95) .. (2.1, 3.32, 2.94) ..
+              (1.87, 3.6, 2.79) .. (1.65, 3.78, 2.52) ..
+              (1.49, 3.85, 2.17) .. (1.41, 3.78, 1.79) ..
+              (1.42, 3.6, 1.45) .. (1.51, 3.32, 1.19) .. cycle;
+           q.align_with_axis(A, B, 'z');
+           q.show("q:");
+           -| q:
+              (1, 0, 0) .. (0.924, 0.383, 0) ..
+              (0.707, 0.707, 0) .. (0.383, 0.924, 0) ..
+              (0, 1, 0) .. (-0.383, 0.924, 0) ..
+              (-0.707, 0.707, 0) .. (-0.924, 0.383, 0) ..
+              (-1, 0, 0) .. (-0.924, -0.383, 0) ..
+              (-0.707, -0.707, 0) .. (-0.383, -0.924, 0) ..
+              (0, -1, 0) .. (0.383, -0.924, 0) ..
+              (0.707, -0.707, 0) .. (0.924, -0.383, 0) .. cycle;
+ 
+

+
+ [Figure 119. Not displayed.] +
+
+ Fig. 119. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Alignment-with-an-Axis-for-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Alignment-with-an-Axis-for-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Alignment-with-an-Axis-for-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Alignment-with-an-Axis-for-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,130 ---- + + + Alignment with an Axis for Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

19.11 Alignment with an Axis

+ +
+ — Function: Transform align_with_axis (Point p0, Point p1, [char axis = 'z'])
+

Returns the Transform that would align the line through p0 + and p1 with the major axis denoted by the axis argument. + The default is the z-axis. This function is used in the functions that + find intersections. + +

          Point P0(1, 1, 1);
+           Point P1(2, 3, 4);
+           P0.draw(P1);
+           P0.dotlabel("$P_0$");
+           P1.dotlabel("$P_1$");
+           Transform t;
+           t.align_with_axis(P0, P1, 'z');
+           P0 *= P1 *= t;
+           t.show("t:");
+           -| t:
+                0.949  -0.169   0.267       0
+                    0   0.845   0.535       0
+               -0.316  -0.507   0.802       0
+               -0.632  -0.169    -1.6       1
+           P0.show("P0:");
+           -| P0: (0, 0, 0)
+           P1.show("P1:");
+           -| P1: (0, 0, 3.74)
+ 
+

The following example shows how align_with_axis() can be used for + putting plane figures into a + major plane. + +

          default_focus.set(2, 3, -10, 2, 3, 10, 10);
+           Circle c(origin, 3, 75, 25, 6);
+           c.shift(2, 3);
+           c.draw();
+           Point n = c.get_normal();
+           n.shift(c.get_center());
+           Transform t;
+           t.align_with_axis(c.get_center(), n, 'y');
+           t.show("t:");
+           -| t:
+             0.686   0.379  -0.621       0
+             0.543     0.3   0.784       0
+             0.483  -0.875       0       0
+                -3   -1.66   -1.11       1
+           n *= c *= t;
+           c.draw();
+           c.show("c:");
+           -| c:
+           fill_draw_value == 0
+           (1.31, 0, -0.728) .. (1.49, 0, -0.171) ..
+           (1.44, 0, 0.413) .. (1.17, 0, 0.933) ..
+           (0.728, 0, 1.31) .. (0.171, 0, 1.49) ..
+           (-0.413, 0, 1.44) .. (-0.933, 0, 1.17) ..
+           (-1.31, 0, 0.728) .. (-1.49, 0, 0.171) ..
+           (-1.44, 0, -0.413) .. (-1.17, 0, -0.933) ..
+           (-0.728, 0, -1.31) .. (-0.171, 0, -1.49) ..
+           (0.413, 0, -1.44) .. (0.933, 0, -1.17) .. cycle;
+           n.show("n:");
+           -| n: (0, 1, 0)
+ 
+

+
+ [Figure 75. Not displayed.] +
+
+ Fig. 75. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Appending-to-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Appending-to-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Appending-to-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Appending-to-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,100 ---- + + + Appending to Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Path Operators, + Up: Path Reference +


+
+ +

26.5 Appending

+ +
+ — Function: Path append (const Path& pa, [string connector = "–", [bool assign = true]])
+

Appends pa to *this using connector to join them and + returns the resulting Path. If + assign == true, then the return value is + assigned to *this, otherwise, *this remains unchanged. + +

If necessary, a const version could be added, for + const Paths. + +

          Point A(-2, 2);
+           Point B(-2, -2);
+           Point C(2, -2);
+           Point D(2, 2);
+           Path q("--", false, &A, &B, &C, &D, 0);
+           Point E(1, 2);
+           Point F(0, 4);
+           Point G(-.5, 3);
+           Path r("..", false, &E, &F, &G, 0);
+           q.append(r, "..", true);
+           q += "..";
+           q += "--";
+           q.set_cycle();
+           q.show("q:");
+           -| q:
+              (-2, 2, 0) -- (-2, -2, 0) --
+              (2, -2, 0) -- (2, 2, 0) ..
+              (1, 2, 0) .. (0, 4, 0) ..
+              (-0.5, 3, 0) -- cycle;
+ 
+

+
+ [Figure 114. Not displayed.] +
+
+ Fig. 114. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,64 ---- + + + Applying Transformations to Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

26.11 Applying Transformations

+ +
+ — Virtual function: void apply_transform (void)
+

Calls Point::apply_transform() on all of the Points on + points. + See Point Reference; Applying Transformations. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,63 ---- + + + Applying Transformations to Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.13 Applying Transformations

+ +
+ — Function: void apply_transform (void)
+

Updates world_coordinates by multiplying it by transform, + which is subsequently reset to the identity Transform. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Applying Transformations to Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Affine Transformations for Shapes, + Up: Shape Reference +


+
+ +

18.6 Applying Transformations

+ +
+ — Pure virtual function: void apply_transform (void)
+

Applies the Transform stored in the transform data member + of the Points belonging to the Shape to their + world_coordinates. The transforms are subsequently reset + to the identity Transform. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transformations-to-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,63 ---- + + + Applying Transformations to Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

34.11 Applying Transformations

+ +
+ — Virtual function: void apply_transform (void)
+

Calls apply_transform() on all of the Shapes belonging to + the Solid. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transforms-to-Points-Intro.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transforms-to-Points-Intro.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Applying-Transforms-to-Points-Intro.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Applying-Transforms-to-Points-Intro.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,122 ---- + + + Applying Transforms to Points Intro - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transforms, + Up: Transforms +


+
+ +

4.1 Applying Transforms to Points

+ +

A Transform t is applied to a + Point P using the binary *= operation + (Point::operator*=(const Transform&)) + which performs matrix multiplication of P.transform by t. + See Point Reference; Operators. + +

     Point P(0, 1);
+      Transform t;
+      t.rotate(90);
+      t.show("t:");
+      -| t:
+         1       0       0       0
+         0       0      -1       0
+         0       1       0       0
+         0       0       0       1
+      P *= t;
+      P.show_transform("P:");
+      -| P:
+      Transform:
+         1       0       0       0
+         0       0      -1       0
+         0       1       0       0
+         0       0       0       1
+      P.show("P:");
+      -| P: (0, 0, -1)
+ 
+

In the example above, there is no real need to use a Transform, + since P.rotate(90) could have been called directly. + As constructions become more complex, the power of Transforms + becomes clear: + + + +

     1. Point p0(0, 0, 0);
+      2. Point p1(10, 5, 10);
+      3. Point p2(16, 14, 32);
+      4. Point p3(25, 50, 99);
+      5. Point p4(12, 6, 88);
+      6. Transform a;
+      7. a.shift(2, 3, 4);
+      8. a.scale(1, 3, 1);
+      9. p2 *= p3 *= a;
+      10. a.rotate(p0, p1, 75);
+      11. p4 *= a;
+      12. p2.show("p2:");
+         -| p2: (18, 51, 36)
+      13. p3.show("p3:");
+         -| p3: (27, 159, 103)
+      14. p4.show("p4:");
+         -| p4: (24.4647, -46.2869, 81.5353)
+ 
+ + +

In this example, a is shifted and scaled, and a is applied + to both in line 9. This works, because + the binary operation + operator*=(const Transform& t) returns t, + making it possible to chain invocations of *=. + Following this, a is rotated + 75 degrees + +

about the line through p_0 and p_1. + Finally, all three transformations, which are stored in a, are + applied to p_4. + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Bibliography.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Bibliography.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Bibliography.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Bibliography.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,253 ---- + + + Bibliography - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Changes, + Up: Top +


+
+ +

Bibliography

+ + + + + + + +

Cundy, H. Martyn and A.P. Rollet. + Mathematical Models. + Oxford 1961. + Oxford University Press. + +

     Unfortunately out of print.
+ 
+
+ 
+ 
+ +

Finston, Laurence D. + 3DLDF: The Program. + Göttingen 2003. +

+ 
+ 
+ +

Fischer, Gerd. + Ebene algebraische Kurven. + Vieweg Studium. Aufbaukurs Mathematik. + Friedr. Vieweg & Sohn Verlagsgesellschaft mbH. + Braunschweig/Wiesbaden 1994. +

+ 
+ 
+ +

Gill, Robert W. + Creative Perspective. + London 1975. + Thames and Hudson Ltd. + ISBN 0-500-27056-2. +

+ 
+ 
+ +

Harbison, Samuel P., and Guy L. Steele Jr. + C, A Reference Manual. + Prentice Hall. + Englewood Cliffs, New Jersey 1995. + ISBN 0-13-326232-4 {Case}. + ISBN~0-13-326224-3 {Paperback}. +

+ 
+ 
+ +

Hobby, John D. + Smooth, Easy to Compute Interpolating Splines. + Discrete and Computational Geometery 1(2). + Springer-Verlag. + New York 1986. +

+ 
+ 
+ +

Hobby, John D. + A User's Manual for MetaPost. + AT & T Bell Laboratories. + Murray Hill, NJ. No date. +

+ 
+ 
+ +

Jones, Huw. + Computer Graphics through Key Mathematics. + Springer-Verlag London Limited 2001. + ISBN 1-85233-422-3. +

+ 
+ 
+ +

Knuth, Donald Ervin. + Metafont: The Program. Computers and Typesetting; D. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. + ISBN 0-201-13438-1. +

+ 
+ 
+ +

Knuth, Donald Ervin. + The METAFONTbook. + Computers and Typesetting; C. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. +

+ 
+ 
+ +

Knuth, Donald Ervin. + TeX: The Program. Computers and Typesetting; B. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. + ISBN 0-201-13437-3. +

+ 
+ 
+ +

Knuth, Donald E. The TeXbook. + Computers and Typesetting; A. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. +

+ 
+ 
+ +

Knuth, Donald E. and Silvio Levy. + The CWEB System of Structured Documentation. + Version 3.64—February 2002. +

+ 
+ 
+ +

Rokicki, Tomas. + Dvips: A DVI-to-PostScript Translator + for version 5.66a. + February 1997. + http://dante.ctan.org/CTAN/dviware/dvips/ +

+ 
+ 
+ +

Salomon, David. + Computer Graphics and Geometric Modeling. + Berlin 1999. + Springer-Verlag. + ISBN: 0-387-98682-0. +

+ 
+ 
+ +

Stallman, Richard M. and Roland McGrath. + GNU Make. A Program for Directing Recompilation. + make Version 3.79. + Boston 2000. + Free Software Foundation, Inc. + ISBN: 1-882114-80-9. +

+ 
+ 
+ +

Stallman, Richard M. + Using and Porting the GNU Compiler Collection. + For GCC Version 3.3.2. + Boston 2003. + Free Software Foundation, Inc. +

+ 
+ 
+ +

Stroustrup, Bjarne. + The C++ + Programming Language. + Special Edition. + Reading, Massachusetts 2000. + Addison-Wesley. + ISBN 0-201-70073-5. +

+ 
+ 
+ +

Stroustrup, Bjarne. + The Design and Evolution of C++ + . + Reading, Massachusetts 1994. + Addison-Wesley Publishing Company. + ISBN 0-201-54330-3. +

+ 
+ 
+ +

Vredeman de Vries, Jan. + Perspective. + New York 1968. + Dover Publications, Inc. + Standard Book Number: 486-21086-4. + +

     The beautiful perspective constructions in this volume are taken from
+      the original work, first published by Henricus Hondius in Leiden in 1604
+      and 1605.
+ 
+
+ 
+ 
+ +

White, Gwen. + Perspective. A Guide for Artists, Architects and Designers. + London 1968 and 1982. + B T Batsford Ltd. + ISBN 0-7134-3412-0. + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/CWEB-Documentation.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/CWEB-Documentation.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/CWEB-Documentation.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/CWEB-Documentation.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,115 ---- + + + CWEB Documentation - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: About This Manual, + Up: Introduction +


+
+ +

1.3 CWEB Documentation

+ +

As mentioned above, 3DLDF has been programmed using CWEB, which is a + “literate programming” tool developed by + Donald E. Knuth and Silvio Levy. See Sources of Information, for a + reference to the CWEB manual. + Knuth's TeX—The Program and + Metafont—The Program both include a section + “How to read a WEB” (pp. x–xv, in both volumes). + +

CWEB files combine source code + and documentation. Running ctangle on a CWEB file, + for example, main.web, produces the file main.c containing + C or C++ + code. Running cweave main.web creates a + TeX file with pretty-printed source code and nicely formatted + documentation. I find that using CWEB makes it more natural to + document my code as I write it, and makes the source files easier to + read when editing them. It does have certain consequences + with regard to compilation, but these are taken care of by make. + See Adding a File, and Changes, for more + information. + +

The CWEB files in the directory 3DLDF-1.1.5.1/CWEB/ contain the + source code for 3DLDF. The file 3DLDFprg.web in this directory + is only ever used for cweaving; it is never ctangled and contains no + C++ + code for compilation. It does, however, include all of the other + CWEB files, so that cweave 3DLDFprg.web generates the TeX file + containing the complete documentation of the source code of 3DLDF. + +

The files 3DLDF-1.1.5.1/CWEB/3DLDFprg.tex, + 3DLDF-1.1.5.1/CWEB/3DLDFprg.dvi, and + 3DLDF-1.1.5.1/CWEB/3DLDFprg.ps are + included in the distribution of 3DLDF as a + convenience. However, users may generate them themselves, should there + be some reason for doing so, by entering make ps + from the command line of a shell from the working + directory 3DLDF-1.1.5.1/ or 3DLDF-1.1.5.1/CWEB. + Alternatively, the user may generate them + by hand from the working directory 3DLDF-1.1.5.1/CWEB/ in the + following way: + +

    +
  1. cweave 3DLDFprg.web + generates 3DLDFprg.tex. + +
  2. tex 3DLDFprg or tex 3DLDFprg.tex generates + 3DLDFprg.dvi. + +
  3. dvips -o 3DLDFprg.ps 3DLDFprg (possibly with additional options) + generates 3DLDFprg.ps. + +
  4. lpr -P<print queue> 3DLDFprg.ps + sends 3DLDFprg.ps to a printer, on a UNIX or UNIX-like system. +
+ +

The individual commands may differ, depending on the system you're + using. + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Caveats.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Caveats.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Caveats.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Caveats.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Caveats - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Metafont and MetaPost, + Up: Introduction +


+
+ +

1.5 Caveats

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,75 ---- + + + Changes in 3DLDF 1.1.4 - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ + +

+ Next: , + Previous: Changes in 3DLDF 1.1.4.1, + Up: Changes +


+
+ +

41.5 3DLDF 1.1.4

+ +
    +
  • MAX_REAL is now the second largest float value. However, the + calculation is system dependent, and will only work on 32-bit + little-endian architectures. I will start working on porting this + soon. + +
  • Fixed bug in tsthdweb, that caused files to be compiled more + often than necessary. It will be necessary to keep an eye on this. + +
  • Added Rectangle::is_rectangular(). + +
  • Made mediate() a member function of Point. + +
  • It is now possible to generate this manual in the Info and HTML + formats. +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e1.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e1.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e1.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e1.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Changes in 3DLDF 1.1.4.1 - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ + +

+ Next: , + Previous: Changes in 3DLDF 1.1.4.2, + Up: Changes +


+
+ +

41.4 3DLDF 1.1.4.1

+ +
    +
  • The HTML output now includes illustrations. +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e2.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e2.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e2.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e4_002e2.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,63 ---- + + + Changes in 3DLDF 1.1.4.2 - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ + +

+ Next: , + Previous: Changes in 3DLDF 1.1.5, + Up: Changes +


+
+ +

41.3 3DLDF 1.1.4.2

+ +
    +
  • The illustrations in the HTML output are now scaled to + magstep3. +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,116 ---- + + + Changes in 3DLDF 1.1.5 - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ + +

+ Next: , + Previous: Changes in 3DLDF 1.1.5.1, + Up: Changes +


+
+ +

41.2 3DLDF 1.1.5

+ +

In release 1.1.5, I've tied up some loose ends. I wanted to do this + before starting on the input routine. + +

    +
  • Added const real step argument to the version of + Ellipse::intersection_points() that takes an Ellipse + argument. + See Ellipse Reference; Intersections. + +
  • It is now possible to “typedef” real to either float + or double. This means that real can now be made a synonym + for either float or double by using a typedef + declaration. real is typedeffed to float by default. + +
  • Added const bool ldf_real_float and + extern const bool ldf_real_double + for use in non-conditionally compiled code. + They are set according to the values + of LDF_REAL_FLOAT and LDF_REAL_DOUBLE. + +
  • Transform::epsilon() and Point::epsilon() now return + different values, depending on the values of the preprocessor macros + LDF_REAL_FLOAT and LDF_REAL_DOUBLE. I have not yet tested + whether good values are returned when real is double. + +
  • MAX_REAL and MAX_REAL_SQRT are no longer constants. + Their values are set at the beginning of main(). However, + users should not change their values. MAX_REAL is the + second-largest float or double on a given machine. This + now works for all common architectures. + +
  • Added namespace System containing the following functions: + get_endianness(), is_big_endian(), + is_little_endian(), get_register_width(), + is_32_bit(), is_64_bit(), and the template function + get_second_largest(). + +

    namespace System and its functions are documented in + system.texi, which is new in edition 1.1.5.1. + +

  • Replaced the various create_new_<type>() functions with the + template function create_new(). The latter is documented in + creatnew.texi, which is new in edition 1.1.5.1. + +
  • Added the file 3DLDF-1.1.5.1/CWEB/cnepspng.el to + the distribution. It contains the definitions of the Emacs-Lisp + functions convert-eps and convert-eps-loop. + See Running 3DLDF; Converting EPS Files; Emacs-Lisp Functions. + +
  • Added the files + 3DLDF-1.1.5.1/CWEB/exampman.web and
    + 3DLDF-1.1.5.1/CWEB/examples.mp to the + distribution. They contain the C++ + and MetaPost code, + respectively, for generating the illustrations in this manual. + +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5_002e1.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5_002e1.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5_002e1.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes-in-3DLDF-1_002e1_002e5_002e1.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,70 ---- + + + Changes in 3DLDF 1.1.5.1 - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ + +

+ Next: , + Previous: Changes, + Up: Changes +


+
+ +

41.1 3DLDF 1.1.5.1

+ +
    +
  • Added missing Texinfo files to the 3dldf_TEXINFOS variable in + 3DLDF-1.1.5.1/DOC/TEXINFO/Makefile.am, and reordered the + filenames. + +
  • Changed the names of the PNG (Portable Network Graphics) files + included in the HTML version of this manual. + Changed the names in the commands for including these + files in the Texinfo files. I wasn't able to write some of the + files with the old names to a CD-R (Compact Disk, Recordable). +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Changes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Changes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,67 ---- + + + Changes - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Future Plans, + Up: Top +


+
+ +

41 Changes

+ +

Updated 16 January 2004. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,95 ---- + + + Circle Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Circle Data Members, + Up: Circle Reference +


+
+ +

32.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Circle (void)
+

Creates an empty Circle. +

+ +
+ — Constructor: void Circle (const Point& ccenter, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0, [const unsigned short nnumber_of_points = DEFAULT_NUMBER_OF_POINTS]]]])
+

Creates a Circle with radius == + ddiameter/2 in the x-z plane and centered at the origin + with nnumber_of_points Points. If any of the arguments + angle_x, angle_y, or angle_z is + != 0, + the Circle is rotated around the major axes by the angles + indicated by the arguments. Finally, the + Circle is shifted such that center comes to lie at + ccenter. +

+ +
+ — Setting function: void set (const Point& ccenter, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Circle* create_new<Circle> (const Circle* c)
+ — : Circle* create_new<Circle> (const Circle& c)
+

Pseudo-constructors for dynamic allocation of Circles. + They create a Circle on the free store and allocate memory for it using + new(Circle). They return a pointer to the new Circle. + +

If c is a non-zero pointer or a reference, + the new Circle will be a copy of + c. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Circle>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Circle Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

32.1 Data Members

+ +
+ — Private variable: real radius
+

The radius of the Circle. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,95 ---- + + + Circle Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Querying Circles, + Up: Circle Reference +


+
+ +

32.5 Intersections

+ +
+ — Virtual const function: bool_point_quadruple intersection_points (const Circle& c, [const bool verbose = false])
+

Returns the intersection points of two Circles. + +

If the Circles are coplanar, they can intersect at at most two + points. There is an easy algebraic solution for this, so in this case, + this function is faster than Ellipse::intersection_points(Ellipse, + bool), which uses an iterative procedure to find the points. + +

If the Circles are non-coplanar, the intersection points of each + Circle with the plane of the other Circle are returned, so + a maximum of four Points can be found. + + +

          Circle t(origin, 5, 90);
+           Circle c(origin, 3, 90);
+           c.shift(3);
+           c.rotate(0, 0, 45);
+           bool_point_quadruple bpq = t.intersection_points(c);
+           bpq.first.pt.dotlabel("$f$");
+           bpq.second.pt.dotlabel("$s$");
+ 
+

+
+ [Figure 177. Not displayed.] +
+
+ Fig. 177. +
+

+ +
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,71 ---- + + + Circle Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

32.3 Operators

+ +
+ — Assignment operator: Circle& operator= (const Circle& c)
+

Makes the Circle a copy of c. +

+ +
+ — Assignment operator: Circle& operator= (const Ellipse& e)
+

Makes the Circle a copy of e, if e is circular. + radius is set to e.axis_v / 2 and + *this is returned. + +

If e is not circular, this function issues an error message and returns *this. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circle-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circle-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,76 ---- + + + Circle Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Ellipse Reference, + Up: Top +


+
+ +

32 Circle Reference

+ +

Class Circle is defined in circles.web. + It is derived from Ellipse, using public derivation. + +

Since Circle is just a special kind of Ellipse, there is + often no need to define special functions for Circles. + +

Currently, Circle inherits the transformation functions and + operator*=(const Transform&) from Ellipse. Consequently, + the data member radius, described below, + is not recalculated, when transformations + are performed on a Circle. I plan to change this soon! + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circles-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circles-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circles-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circles-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,110 ---- + + + Circles Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Ellipses Getstart, + Up: Plane Figures +


+
+ +

7.4 Circles

+ +

Circles are constructed just like Ellipses, except that + the vertical and horizontal axes are per definition the same, so + there's only one argument for the diameter, instead of two for the + horizontal and vertical axes: + +

     Point P(0, 2, 1);
+      Circle c(P, 3.5, 90, 90);
+      c.draw();
+ 
+

+
+ [Figure 35. Not displayed.] +
+
+ Fig. 35. +
+

+ +

This constructor, too, has a corresponding setting function: + +

     Circle c;
+      Point p(-1, 0, 5);
+      for (int i = 0; i < 16; ++i)
+        {
+            c.set(p, 5, i * 22.5, 0, 0, 64);
+            c.draw();
+        }
+ 
+

+
+ [Figure 36. Not displayed.] +
+
+ Fig. 36. +
+

+ +

In the preceding example, the last argument to set(), namely “64”, + is for the number of Points used for constructing the perimeter + of the Circle. The default value is 16, however, if it is used, + foreshortening distorts the most nearly horizontal Circle. + Increasing the number of points used improves its appearance. However, + there may be a limit to how much improvement is possible. + See Accuracy. + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circles-for-Regular-Polygons.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circles-for-Regular-Polygons.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Circles-for-Regular-Polygons.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Circles-for-Regular-Polygons.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,152 ---- + + + Circles for Regular Polygons - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

28.5 Circles

+ +
+ — const function: Circle in_circle (void)
+

Returns the enclosed Circle of the Reg_Polygon. + +

          Point P(0, -1, 1);
+           Reg_Polygon h(P, 6, 4, 15, 12, 11.5);
+           h.filldraw(black, gray);
+           Circle c = h.in_circle();
+           c.unfilldraw(black);
+ 
+

+
+ [Figure 147. Not displayed.] +
+
+ Fig. 147. +
+

+ +
+ +
+ — const function: Circle draw_in_circle ([const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = "", [Picture& picture = current_picture]]])
+ — const function: Circle draw_in_circle ([Picture& picture = current_picture, [const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = ""]]])
+

Draws and returns the enclosed Circle of the Reg_Polygon. + +

          Point P(0, 1, 1);
+           Reg_Polygon h(P, 7, 4, 80, 2, 5);
+           h.draw(black, "evenly");
+           h.draw_in_circle();
+ 
+

+
+ [Figure 148. Not displayed.] +
+
+ Fig. 148. +
+

+ +
+ +
+ — const function: Circle out_circle (void)
+

Returns the surrounding Circle of the Reg_Polygon. + +

          Point P(0, -1, 1);
+           Reg_Polygon h(P, 6, 4, 15, 12, 11.5);
+           Circle c = h.out_circle();
+           c.filldraw(black, gray);
+           h.unfilldraw(black);
+ 
+

+
+ [Figure 149. Not displayed.] +
+
+ Fig. 149. +
+

+ +
+ +
+ — const function: Circle draw_out_circle ([const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = "", [Picture& picture = current_picture]]])
+ — const function: Circle draw_out_circle ([Picture& picture = current_picture, [const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = ""]]])
+

Draws and returns the surrounding Circle of the Reg_Polygon. + +

          Point P(0, 1, 1);
+           Reg_Polygon h(P, 7, 4, 80, 2, 5);
+           h.draw(black, "evenly");
+           h.draw_out_circle();
+ 
+

+
+ [Figure 150. Not displayed.] +
+
+ Fig. 150. +
+

+ +
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cleaning-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cleaning-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cleaning-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cleaning-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Cleaning Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Resetting Transforms, + Up: Transform Reference +


+
+ +

19.13 Cleaning

+ +
+ — Function: void clean (void)
+

Sets elements in matrix whose absolute values are + < epsilon() to 0. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Clearing-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Clearing-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Clearing-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Clearing-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,73 ---- + + + Clearing Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Copying Paths, + Up: Path Reference +


+
+ +

26.7 Clearing

+ +
+ — Virtual function: void clear (void)
+

Does the same thing the destructor ~Path() does: + Calls delete() on the pointers to Points on points, + clears points and connectors, deletes draw_color + and fill_color, if they point to Colors that were + allocated on the free store, and sets them to 0. + +

clear() is a pure virtual function in class Shape, + so Path must be have a clear() function. + It is needed, because it is sometimes called through a + pointer to Shape, so that ~Path() cannot be accessed. + At least, so far I haven't found a way to call a destructor through the + virtual function facility. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Clearing-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Clearing-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Clearing-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Clearing-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Clearing Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Applying Transformations to Shapes, + Up: Shape Reference +


+
+ +

18.7 Clearing

+ +
+ — Pure virtual function: void clear (void)
+

The precise definition of this function will depend on the nature of the + derived class. In general, it will call the destructor on dynamically + allocated objects belonging to the Shape, and deallocate the + memory they occupied. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Clearing-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Clearing-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Clearing-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Clearing-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,73 ---- + + + Clearing Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Drawing and Filling Solids, + Up: Solid Reference +


+
+ +

34.14 Clearing

+ +
+ — Virtual function: void clear (void)
+

Calls clear() on all the Shapes belonging to the + Solid. + Used in Picture::clear() for deallocating + and destroying Solids. + +

Currently, <Shape>.clear() always resolves to + Path::clear(), since none of the other types of Shape that a + Solid can contain, e.g., Ellipse, Circle, etc., + overloads Path::clear(). +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,117 ---- + + + Color Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Color Data Members, + Up: Color Reference +


+
+ +

16.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Color (void)
+

Creates a Color and initializes its red_part, + green_part, and blue_part to 0. use_name and + on_free_store are set to false. +

+ +
+ — Copy constructor: void Color (const Color& c, [const string n = "", [const bool u = true]])
+

Creates a Color and makes it a copy of c. If n is + not the empty string and u is true, use_name is set + to true. Otherwise, its set to false. +

+ +
+ — Constructor: void Color (const string n, const unsigned short r, const unsigned short g, const unsigned short b, [const bool u = true])
+

Creates a Color with name n. Its red_part, + green_part, and blue_part are set to + r/255.0, g/255.0, and b/255.0, + respectively. + use_name is set to u. +

+ +
+ — Setting function: void set (const string n, const unsigned short r, const unsigned short g, const unsigned short b, [const bool u = false])
+

Corresponds to the constructor above, except that u is false by default. +

+ +
+ — Constructor: void Color (const real r, const real g, const real b)
+

Creates an unnamed Color using the real values r, + g, and b for its red_part, green_part, and + blue_part, respectively. +

+ +
+ — Setting function: void set (const real r, const real g, const real b)
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Color* create_new<Color> (const Color* c)
+ — : Color* create_new<Color> (const Color& c)
+

Pseudo-constructors for dynamic allocation of Colors. + They create a Color on the free store and allocate memory for it using + new(Color). They return a pointer to the new Color. + +

If c is a non-zero pointer or a reference, + the new Color will be a copy of + c. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Color>() as its argument. + See Dynamic Allocation of Shapes, for more information. + + +

This function is used in the drawing and filling functions for + Path and Solid. Point::drawdot() should be changed + to use it too, but I haven't gotten around to doing this yet. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,89 ---- + + + Color Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

16.1 Data Members

+ +
+ — Variable: string name
+

The name of the Color. +

+ +
+ — Variable: bool use_name
+

If true, name is written to out_stream when the + Color is used for drawing or filling. Otherwise, the + RGB (red-green-blue) values are written to out_stream. +

+ +
+ — Variable: bool on_free_store
+

true, if the Color has been created by + create_new<Color>(), which allocates memory for the + Color on the free store. Otherwise false. + Colors should only ever be dynamically allocated by using + create_new<Color>(). + See Color Reference;;Constructors and Setting Functions. +

+ +
+ — Variable: real red_part
+ — Variable: real green_part
+ — Variable: real blue_part
+

The RGB (red-green-blue) values of the Color. + A real value r is valid for these variables if and + only if + 0 <= r <= 1. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,94 ---- + + + Color Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

16.3 Operators

+ +
+ — Assignment operator: void operator= (const Color& c)
+

Sets name to the empty string, use_name to + false, and red_part, green_part, and + blue_part to c.red_part, c.green_part, and + c.blue_part, respectively. +

+ +
+ — const operator: bool operator== (const Color& c)
+

Equality operator. Returns true, if the red_parts, + green_parts, and blue_parts of *this and c + are equal, otherwise false. The names and + use_names are not compared. +

+ +
+ — const operator: bool operator!= (const Color& c)
+

Inequality operator. Returns false, if the red_parts, + green_parts, and blue_parts of *this and c + are equal, otherwise true. The names and + use_names are not compared. +

+ +
+ — Non-member function: ostream& operator<< (ostream& o, const Color& c)
+

Output operator. Writes the MetaPost code for the Color to + out_stream when a Picture is output. This occurs when + the Color has been used as an argument to + drawing or filling functions. + +

If use_name is true, name is written to + out_stream. Otherwise, + “(red_part, green_part, blue_part)” is written to + out_stream. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Color-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Color-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Color Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: System Information, + Up: Top +


+
+ +

16 Color Reference

+ +

Class Color is defined in colors.web. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Command-Line-Arguments.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Command-Line-Arguments.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Command-Line-Arguments.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Command-Line-Arguments.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,94 ---- + + + Command Line Arguments - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Converting EPS Files, + Up: Running 3DLDF +


+
+ +

11.2.2 Command Line Arguments

+ +

3dldf can be called with the following + command line arguments. + +

+
--help
Prints information about the valid command line options to standard + output and exits with return value 0. + +
--silent
Suppresses some output to standard output + and standard error when 3dldf is run + +
--verbose
Causes status information to be printed to standard output + when 3dldf is run. + +
--version
Prints the version number of 3DLDF + to standard output and exits with return value 0. +
+ +

Currently, 3dldf can only handle long options. ‘-’ + cannot be substituted for ‘--’. However, the names of the options + themselves can be abbreviated, as long as the abbreviation is + unambigous. For example, ‘3dldf --h’ and ‘3dldf --verb’ are + valid, but ‘3dldf --ver’ is not. + + + + + + + + + + + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Concept-Index.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Concept-Index.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Concept-Index.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Concept-Index.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,171 ---- + + + Concept Index - 3DLDF User and Reference Manual + + + + + + + + + + + +

+ +

+ Previous: Function Index, + Up: Top +


+
+ +

Concept Index

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Contributing-to-3DLDF.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Contributing-to-3DLDF.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Contributing-to-3DLDF.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Contributing-to-3DLDF.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,67 ---- + + + Contributing to 3DLDF - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Introduction, + Up: Top +


+
+ +

1.7 Contributing to 3DLDF

+ +

So far, I've been the sole author and user of 3DLDF. + I would be very interested in having other programmers contribute to + it. I would be particularly interested in help in making 3DLDF conform + as closely as possible to the GNU Coding Standards. I would be + grateful if someone would write proper Automake and Autoconf files, + since I haven't yet learned how to do so (I'm working on it). + +

See Introduction, for information on how to contact the author. + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files-ELISP.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files-ELISP.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files-ELISP.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files-ELISP.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,111 ---- + + + Converting EPS Files ELISP - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Previous: Converting EPS Files, + Up: Converting EPS Files +


+
+ +
11.2.1.1 Emacs-Lisp Functions
+ +

The file 3DLDF-1.1.5.1/CWEB/cnepspng.el contains + definitions of two Emacs-Lisp functions that can be used to + convert Encapsulated PostScript (EPS) files to structured PostScript + (PS) and Portable Network Graphics (PNG) files. + +

+ — Emacs-Lisp function: convert-eps filename do-not-delete-files
+

Converts an EPS image file to the PS and PNG formats. + +

If called interactively, convert-eps prompts for the + filename, including the extension, of an + EPS image file. It follows the procedure described above in + Converting EPS Files, to create + filename.ps and filename.png. + +

If do-not-delete-files is nil, + the .tex, .dvi, and .log files will be deleted. + This is the case when convert-eps is called interactively + with no prefix argument. + If convert-eps is called interactively with a prefix + argument, or non-interactively with a non-nil + do-not-delete-files argument, these files will not be deleted. +

+ +
+ — Emacs-Lisp function: convert-eps-loop arg start end
+

Converts a set of EPS image files to the PS and PNG formats. + The files + must all have the same filename, and the extensions must form a range of + positive integers. For example, convert-eps-loop can be + used to convert the files 3DLDFmp.1, 3DLDFmp.2, and + 3DLDFmp.3 to 3DLDFmp.1.ps, 3DLDFmp.2.ps, and + 3DLDFmp.3.ps on the one hand, and + 3DLDFmp.1.png, 3DLDFmp.2.png, + 3DLDFmp.3.png on the other. + +

If convert-eps-loop is called interactively, + it prompts for filename with no extension + and the starting and ending numbers of the range. + +

For all i \in \INT and start \le i \le end, + convert-eps-loop checks whether a file named + filename.i exists. If it does, + it calls convert-eps, passing + filename.i as the latter's filename argument. + +

do-not-delete-files is also passed to convert-eps. If + it's nil, + the .tex, .dvi, and .log files will be deleted. + This is the case when convert-eps-loop is called interactively + with no prefix argument. + If convert-eps-loop is called interactively with a prefix + argument, or non-interactively with a non-nil + do-not-delete-files argument, these files will not be deleted. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Converting-EPS-Files.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,154 ---- + + + Converting EPS Files - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Running 3DLDF, + Up: Running 3DLDF +


+
+ +

11.2.1 Converting EPS Files

+ +

ImageMagick is a + “collection of tools and libraries” for image manipulation. + It provides a `convert' utility which can convert images from one + format to another. It can convert structured PostScript (PS) to + to Portable Network Graphics (PNG), but not + EPS (Encapsulated PostScript) to PNG. Nor can it convert EPS to + structured PostScript. + +

It is possible to have MetaPost generate structured PostScript directly + by including the command ‘prologues:=1;’ at the beginning of the + MetaPost input. + However, this “generally doesn't work when you use TeX + fonts.”1 + This is a significant problem if your labels contain math mode + material, and you haven't already taken steps to ensure that appropriate + fonts will be used in the PS output. + +

In the following, I describe the only way I've found to convert + an EPS image to PNG format while still using TeX fonts. There may be + other and better ways of doing this, but I haven't found them. + +

    +
  1. Assume the EPS image is in the file 3DLDFmp.1 + Include the EPS image in a TeX file + which looks like this: + +
              \advance\voffset by -1in
    +           \advance\hoffset by -1in
    +           \nopagenumbers
    +           \input epsf
    +           \epsfverbosetrue
    +           \def\epsfsize#1#2{#1}
    +           \setbox0=\vbox{\epsffile{3DLDFmp.1}}
    +           \vsize=\ht0
    +           \hsize=\wd0
    +           \special{papersize=\the\wd0,\the\ht0}
    +           \box0
    +           \bye
    + 
    +

    Do not name this file 3DLDFmp.1.tex! + While this worked fine for me on a DECalpha Personal Workstation + running under Tru64 Unix 5.1, with TeX, Version 3.1415 + (C version 6.1), and dvipsk 5.58f, + it failed on a PC Pentium II XEON under Linux 2.4, + with TeX, Version 3.14159 (Web2C 7.4.5), and + dvips(k) 5.92b, kpathsea version 3.4.5, + with the following error message: +

              “No BoundingBox comment found in file examples.1; using defaults”
    + 
    +

    The resulting PS image had the wrong size and the + the graphic was positioned improperly. + +

    Apparently, it confuses the EPSF macros when the name of an + included image is the same as ‘\jobname’. + So, for this example, let's call it 3DLDFmp.1_.tex. + +

    You don't really need to call the macro ‘\epsfverbosetrue’. If you + do, it will print the measurements of the bounding box and other information + to standard output.2 + +

  2. Run ‘tex 3DLDFmp.1_.tex’. + +
  3. Run ‘dvips -o 3DLDF.1.ps 3DLDFmp.1_.dvi’. + +
  4. Run ‘convert 3DLDF.1.ps 3DLDFmp.1.png’. +
+ +

ImageMagick + supplies a `display' utility, which can be used to display the + PNG image: + +

     display 3DLDFmp.1.png
+ 
+

It can be included in an HTML document as follows: + +

     <img src="3DLDFmp.1.png"
+               alt="[Fig. 1]."
+ 
+

Please note! The PNG files for this manual are now called + filename 3DLDF1.png, 3DLDF2.png, ..., + 3DLDF199.png, + because I wasn't able to write files + with names like 3DLDFmp.<number>.png to a CD-R (Compact + Disk, Recordable), when `number' had more than one digit. + +

+ +
+
+

Footnotes

[1] Hobby, A User's Manual for MetaPost, pp. 21–22.

+ +

[2] Rokicki, Dvips: A DVI-to-PostScript Translator, p. 24.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Labels.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Labels.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Labels.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Labels.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,72 ---- + + + Copying Labels - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Label Data Members, + Up: Label Reference +


+
+ +

20.2 Copying

+ +
+ — const Function: Label* get_copy (void)
+

Creates a copy of the Label and returns a pointer to the copy. + Called in Picture::operator=() and Picture::operator+=() + where Pictures are copied. + Users should never need to call this function directly. + See Picture Reference; Operators. + +

This function dynamically allocates a new + Label and a new Point within the Label, and copies + the strings from *this to the new Label. The + standard library functions for strings take care of the + allocation for the string members of Label. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Copying Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Appending to Paths, + Up: Path Reference +


+
+ +

26.6 Copying

+ +
+ — const virtual function: Shape* get_copy (void)
+

Creates a copy of the Path using create_new<Path>(), which + returns a pointer to Path. get_copy() then + casts this pointer to a pointer to Shape and returns it. + +

This function is used when copying Pictures and in + Solid::output(), where objects of types derived from Shape + must be handled in the same way, without their actual types being known. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,67 ---- + + + Copying Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Point Operators, + Up: Point Reference +


+
+ +

22.7 Copying

+ +
+ — const function: Shape* get_copy (void)
+

Creates a copy of the Point, and allocates memory for it on the + free store using create_new<Point>(). + It returns a pointer to Shape that points to the new Point. + This function is used in the drawing commands for putting Points + onto Pictures. + See Point Reference; Drawing. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,67 ---- + + + Copying Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Shape Operators, + Up: Shape Reference +


+
+ +

18.3 Copying

+ +
+ — const pure virtual function: Shape* get_copy (void)
+

Copies an object, allocating memory on the free store for the copy, + and returns a pointer to Shape for accessing the copy. + +

Used in the drawing and filling functions for copying the Shape, + and putting a pointer to the copy onto the vector<Shape*> shapes + of the Picture. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Copying-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Copying-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,67 ---- + + + Copying Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Solid Operators, + Up: Solid Reference +


+
+ +

34.5 Copying

+ +
+ — const virtual function: Shape* get_copy (void)
+

Dynamically allocates a new Solid on the free store, using + create_new<Solid>(), and makes it a copy of *this. Then, a + pointer to Shape is pointed at the copy and returned. Used for + putting Solids onto Picture::shapes in the drawing and + filling functions for Solid. + See Solid Reference; Drawing and Filling. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,116 ---- + + + Cuboid Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Cuboid Data Members, + Up: Cuboid Reference +


+
+ +

36.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Cuboid (void)
+

Creates an empty Cuboid. +

+ +
+ — Copy constructor: void Cuboid (const Cuboid& c)
+

Creates a new Cuboid and makes it a copy of c. +

+ +
+ — Constructor: void Cuboid (const Point& c, const real h, const real w, const real d, [const real x = 0, [const real y = 0, [const real z = 0]]])
+

Creates a Cuboid with center at the origin, with + height == h, width == w, and + depth == d. If x, y, or z is + non-zero, the Cuboid is rotated by the amounts indicated around + the corresponding main axes. Finally, the + Cuboid is shifted such that center comes to lie at + c. + +

          Point P(-3, -2, 12);
+           Cuboid c(P, 3, 5, 2.93, 35, 10, 60);
+ 
+

+
+ [Figure 186. Not displayed.] +
+
+ Fig. 186. +
+

+ +
+ +
+ — Template specializations: Cuboid* create_new<Cuboid> (const Cuboid* c)
+ — : Cuboid* create_new<Cuboid> (const Cuboid& c)
+

Pseudo-constructors for dynamic allocation of Cuboids. + They create a Cuboid on the free store and allocate memory for it using + new(Cuboid). They return a pointer to the new Cuboid. + +

If c is a non-zero pointer or a reference, + the new Cuboid will be a copy of + c. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Cuboid>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ +
+ — Destructor: void ~Cuboid (void)
+

Deallocates the Rectangles pointed to by the pointers on + rectangles (a Solid data member), and calls + rectangles.clear(). Cuboids consist entirely of + Rectangles, so nothing must be done to the other vectors. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Cuboid Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

36.1 Data Members

+ +
+ — Protected variables: real height
+ — : real width
+ — : real depth
+

The height, width, and depth of the Cuboid, respectively. + +

Please note, that “height”, “width”, and + “depth” are conventional terms. There are no restrictions on + the orientation of a Cuboid. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,106 ---- + + + Cuboid Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Solid Figures, + Up: Solid Figures +


+
+ +

8.1 Cuboids

+ +

A cuboid is a solid figure consisting of six rectangular faces + that meet at right angles. A cube is a special form of cuboid, whose + faces are all squares. The constructor for the class Cuboid + follows the pattern familiar from the constructors for the plane + figures: The first argument is the center of the Cuboid, + followed by three real arguments for the height, width, and + depth, and then three more real arguments for the angles of + rotation about the x, y, and z-axes. The Cuboid is first + constructed with its center at the origin. Its width, height, and depth + are measured along the x, y, and z-axes respectively. If rotations are + specified, it is rotated about the x, y, z-axes in that order. Finally, + it is shifted such that its center comes to lie on its Point + argument, if the latter is not the origin. + +

If the width, height, and depth arguments are equal, the Cuboid + is a cube: + +

     Cuboid c0(origin, 3, 3, 3, 0, 30);
+      c0.draw();
+ 
+

+
+ [Figure 37. Not displayed.] +
+
+ Fig. 37. +
+

+ +

In the following example, the Cuboid is “filldrawn”, so that + the lines dilineating the hidden surfaces of the Cuboid are + covered. + +

     Cuboid c1(origin, 3, 4, 5, 0, 30);
+      c1.filldraw();
+ 
+

+
+ [Figure 38. Not displayed.] +
+
+ Fig. 38. +
+

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Cuboid Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +

36.3 Operators

+ +
+ — Assignment operator: void operator= (const Cuboid& c)
+

Makes the Cuboid a copy of c. The old contents of *this + are deallocated (where necessary) and discarded. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Cuboid-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Cuboid-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Cuboid Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Faced Solid Reference, + Up: Top +


+
+ +

36 Cuboid Reference

+ +

Class Cuboid is defined in cuboid.web. + It is derived from Solid_Faced using public derivation. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Curves-and-Surfaces.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Curves-and-Surfaces.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Curves-and-Surfaces.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Curves-and-Surfaces.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,107 ---- + + + Curves and Surfaces - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Geometry, + Up: Future Plans +


+
+ +

40.2 Curves and Surfaces

+ +

3D modelling software usually supports the creation and manipulation of + various kinds of spline curves: Bézier curves, + B-splines, and non-uniform rational B-splines or + NURBS. These curves can be used for generating surfaces.1 + +

paths in Metafont and MetaPost are Bézier curves. + It would be possible to implement three-dimensional Bézier curves in + 3DLDF, but unfortunately they are not projectively invariant: + +

Let c_0 represent a Bézier curve in three dimensions, + P the control points of c_0, and + t a projection transformation. + Further, let Q represent the points generated from applying + t to P, and c_1 the curve generated from Q. + Finally, let R represent the points generated from applying + t to all of the points on c_0, and + c_2 the curve through R: + c_1 \not\equiv c_2. + +

NURBS, on the other hand, are projectively invariant,2 + so I will probably + concentrate on implementing them. On the other hand, it would be nice + to be able to implement Metafont's way of specifying paths + using `curl', `tension', and `dir' in 3DLDF. + This may prove to be difficult or impossible. I do not yet know + whether Metafont's path creation algorithm can be generalized to + three dimensions.3 + +

Curves and surfaces are advanced topics, so it may be a while + before I implement them in 3DLDF. + +

+
+

Footnotes

[1] Huw Jones, + Computer Graphics through Key Mathematics, and + David Salomon, + Computer Graphics and Geometric Modeling, are my main sources of + information about spline curves.

+ +

[2] Jones, Huw. + Computer Graphics through Key Mathematics, p. 282.

+ +

[3] Knuth, Donald Ervin. + The METAFONTbook, p. 130, and + Hobby, John D. + Smooth, Easy to Compute Interpolating Splines. + Discrete and Computational Geometery 1(2).

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Data-Type-and-Variable-Index.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Data-Type-and-Variable-Index.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Data-Type-and-Variable-Index.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Data-Type-and-Variable-Index.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,305 ---- + + + Data Type and Variable Index - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: GNU Free Documentation License, + Up: Top +


+
+ +

Data Type and Variable Index

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,181 ---- + + + Declaring and Initializing Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Paths, + Up: Paths +


+
+ +

6.1 Declaring and Initializing Paths

+ +

There are various ways of declaring and initializing Paths. The + simplest is to use the constructor taking two Point arguments: + +

     Point A;
+      Point B(2, 2);
+      Path p(A, B);
+      p.draw();
+ 
+

+
+ [Figure 9. Not displayed.] +
+
+ Fig. 9. +
+

+ +

Paths created in this way are important, because they are + guaranteed to be linear, as long as no operations are performed on them + that cause them to become non-linear. + Linear Paths can be used to find intersections. + See Path Intersections. + +

Paths can be declared and initialized using a single connector + and an arbitrary number of Points. The first argument is a + string specifying the connector. It is followed by a + bool, indicating whether the + Path is cyclical or not. Then, an arbitrary number of + pointers to Point follow. The last argument must be 0.1 + +

     Point p[3];
+      p[0].shift(1);
+      p[1].set(1, 2, 2);
+      p[2].set(1, 0, 2);
+      Path pa("--", true, &p[0], &p[1], &p[2], 0);
+      pa.draw();
+ 
+

+
+ [Figure 10. Not displayed.] +
+
+ Fig. 10. +
+

+ +

Another constructor must be used for Paths with + more than one connector and an arbitrary number of Points. + The argument list starts with a pointer to Point, followed by + string for the first connector. Then, + pointer to Point arguments alternate with string arguments + for the connectors. + Again, the list of arguments ends in 0. There is no + need for a bool to indicate whether the Path is cyclical + or not; if it is, the last non-zero argument will be a connector, + otherwise, it will be a pointer to Point. + +

     Point p[8];
+      p[0].set(-2);
+      p[1].set(2);
+      p[2].set(0, 0, -2);
+      p[3].set(0, 0, 2);
+      p[4] = p[0].mediate(p[2]);
+      p[5] = p[2].mediate(p[1]);
+      p[6] = p[1].mediate(p[3]);
+      p[7] = p[3].mediate(p[0]);
+      p[4] *= p[5] *= p[6] *= p[7].shift(0, 1);
+      Path pa(&p[0], "..", &p[4], "...", &p[2],
+              "..", &p[5], "...", &p[1], "..", &p[6],
+              "...", &p[3], "..", &p[7], "...", 0);
+      pa.draw();
+ 
+

+
+ [Figure 11. Not displayed.] +
+
+ Fig. 11. +
+

+ +

As mentioned above (see Accuracy), specifying connectors is + problematic for three-dimensional Paths, + because MetaPost ultimately calculates the “most pleasing curve” + based on the two-dimensional points in the MetaPost code written by + 3DLDF.2 + For this reason, it's advisable to avoid specifying ‘curl’, + ‘dir’, ‘tension’ or control points in connectors. + The more Points a (3DLDF) Path or other object contains, + the less freedom MetaPost has to determine the (MetaPost) path + through them. + So a three-dimensional Path or + other object in 3DLDF should have enough Points to ensure + satisfactory results. The Path in [the previous figure] + does not + really have enough Points. It may require some trial and error + to determine + what a sufficient number of Points is in a given case. + +

Paths are very flexible, but not always convenient. 3DLDF + provides a number of classes representing common geometric + Shapes, which will be described in subsequent sections, and I + intend to add more in the course of time. + +

+
+

Footnotes

[1] It's easy to forget to use Point* arguments, rather + than plain Point arguments, and to forget to end the list of + arguments with 0. If plain Point arguments are used, compilation + fails with GCC. With the DEC compiler, compilation succeeds, but a + memory fault error occurs at run-time. If the argument list doesn't end + in 0, neither compiler signals an error, but a memory fault error always + occurs at run-time.

+ +

[2] Knuth, The METAFONTbook, Chapter 14, p. 127.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Declaring-and-Initializing-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,159 ---- + + + Declaring and Initializing Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Points, + Up: Points +


+
+ +

2.1 Declaring and Initializing Points

+ +

The most basic drawable object in 3DLDF is class Point. It is + analogous to pair in Metafont. For example, in Metafont one + can define a pair using the “z” syntax as + follows: + +

     z0 = (1cm, 1cm);
+ 
+

There are other ways of defining pairs in Metafont (and + MetaPost), but this is the usual way. + +

In 3DLDF, a Point is declared and initialized as follows: + +

     Point pt0(1, 2, 3);
+ 
+

This simple example demonstrates several differences between Metafont + and 3DLDF. First of all, there is no analog in 3DLDF to Metafont's + “z” syntax. + If I want to have Points called “pt0”, “pt1”, + “pt2”, etc., then I must declare each of them to be a + Point: + +

     Point pt0(10, 15, 2);
+      Point pt1(13, 41, 5.5);
+      Point pt2(62.9, 7.02, 8);
+ 
+

Alternatively, I could declare an array of Points: + +

     Point pt[3];
+ 
+

Now I can refer to pt[0], pt[1], and pt[2]. + +

In the Metafont example, the x and y-coordinates of the pair z0 + are specified using the unit of measurement, in this case, centimeters. + This is currently not possible in 3DLDF. The current unit of + measurement is stored in the static variable Point::measurement_units, + which is a string. Its default value is "cm" for + “centimeters”. + At present, it is best to stick with one unit of measurement for a + drawing. + After I've defined an input routine, 3DLDF should handle + units of measurement in the same way that Metafont does. + +

Another difference is that the Points pt0, pt1, and + pt2 have three coordinates, x, y, and z, whereas z0 has + only two, x and y. Actually, the difference goes deeper than this. In + Metafont, a pair has two parts, xpart and ypart, + which can be examined by the user. In 3DLDF, a Point contains + the following sets of coordinates: + +

     world_coordinates
+      user_coordinates
+      view_coordinates
+      projective_coordinates
+ 
+

These are sets of 3-dimensional homogeneous coordinates, which + means that they contain four coordinates: x, y, z, and w. Homogeneous + coordinates are used in the affine and perspective transformations + (see Transforms). + +

Currently, only world_coordinates and + projective_coordinates are used in 3DLDF. + The world_coordinates refer to the position of a Point in + 3DLDF's basic, unchanging coordinate system. + The projective_coordinates are the coordinates of the + two-dimensional projection of the Point onto a plane. + This projection is what is ultimately printed out or displayed on the + computer screen. Please note, that when the coordinates of a + Point are referred to in this manual, the + world_coordinates are meant, unless otherwise stated. + +

Points can be declared and their values can be set in different + ways. + +

     Point pt0;
+      Point pt1(1);
+      Point pt2(2.3, 52);
+      Point pt3(4.5, 7, 13.205);
+ 
+

pt0 is declared without any arguments, i.e., using the default + constructor, so the values of its x, y, and + z-coordinates are all 0. + +

pt1 is declared and initialized with one argument for the x-coordinate, + so its y and z-coordinates are initialized with the values of + CURR_Y and CURR_Z respectively. + The latter are static constant data members + of class Point, whose values are 0 by default. They can be reset + by the user, who should + make sure that they have sensible values. + +

pt2 is declared and initialized with two arguments for its x and + y-coordinates, so its z-coordinate is initialized to the value of + CURR_Z. Finally, pt3 has an argument for each of its + coordinates. + +

Please note that pt0 is constructed using a the default + constructor, whereas the other Points are constructed using a + constructor with one required argument (for the x-coordinate), and two + optional arguments (for the y and z-coordinates). The default + constructor always sets all the coordinates to 0, irrespective of the + values of CURR_Y and CURR_Z. + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Defining-and-Initializing-Colors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Defining-and-Initializing-Colors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Defining-and-Initializing-Colors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Defining-and-Initializing-Colors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,71 ---- + + + Defining and Initializing Colors - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Querying Colors, + Up: Color Reference +


+
+ +

16.7 Defining and Initializing Colors

+ +
+ — const function: void define_color_mp ()
+

Writes MetaPost code to out_stream, in order to define objects of + type color within MetaPost, and set their redparts, + greenparts, and blueparts. +

+ +
+ — Static function: void initialize_colors (void)
+

Calls define_color_mp() (described above) for the + Colors that are defined in namespace Colors + (see Namespace Colors). +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,102 ---- + + + Dodecahedron Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Dodecahedron Data Members, + Up: Dodecahedron +


+
+ +
37.2.2.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Dodecahedron (void)
+

Creates an empty Dodecahedron. +

+ +
+ — Constructor: void Dodecahedron (const Point& p, const real pentagon_diameter, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Creates a Dodecahedron with its center at the origin, where the + pentagonal faces have enclosing circles of diameter + pentagon_diameter. If any of angle_x, angle_y, or + angle_z is non-zero, the Dodecahedron is rotated by the + amounts specified around the corresponding axes. Finally, if p is + not the origin, the Dodecahedron is shifted such that + center comes to lie at p. + +

          Point P(-1, -2, 4);
+           Dodecahedron d(P, 3, 12.5, 16, 2);
+           d.draw();
+ 
+

+
+ [Figure 191. Not displayed.] +
+
+ Fig. 191. +
+

+ +
          d.filldraw();
+ 
+

+
+ [Figure 192. Not displayed.] +
+
+ Fig. 192. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,74 ---- + + + Dodecahedron Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +
37.2.2.1 Data Members
+ +
+ — Protected static const variable: real dihedral_angle
+

The angle between the faces of the Dodecahedron, + namely + 116 degrees + 34' + = \pi - \arctan(2). + +

+ +
+ — Protected variable: real pentagon_radius
+

The radius of the circle enclosing a pentagonal face of the + Dodecahedron. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,133 ---- + + + Dodecahedron Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Tetrahedron Getstart, + Up: Polyhedron Getstart +


+
+ +

8.2.2 Dodecahedron

+ +

A dodecahedron has 12 similar regular pentagonal faces. + The following examples show the same Dodecahedron using different + projections: + +

     default_focus.set(2, 5, -10, 2, 5, 10, 10);
+      Dodecahedron d(origin, 3);
+      d.draw();
+ 
+

+
+ [Figure 40. Not displayed.] +
+
+ Fig. 40. +
+

+ + +

+
+ [Figure 41. Not displayed.] +
+
+ Fig. 41. +
+

+ + +

Please note that the Dodecahedron in [next figure] + is drawn, and not + filldrawn! + +

+
+ [Figure 42. Not displayed.] +
+
+ Fig. 42. +
+

+ + +

+
+ [Figure 43. Not displayed.] +
+
+ Fig. 43. +
+

+ + +

In [next figure] + , d is filldrawn. In this case, + the surface hiding algorithm has worked properly. + See Surface Hiding. + +

+
+ [Figure 44. Not displayed.] +
+
+ Fig. 44. +
+

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Net.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Net.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Net.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron-Net.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,115 ---- + + + Dodecahedron Net - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +
37.2.2.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real pentagon_diameter, [bool do_half = false])
+

Returns the net, i.e., the two-dimensional pattern of pentagons + that can be folded into a model of a dodecahedron. The net lies + in the x-z plane. The pentagons have enclosing circles of diameter + pentagon_diameter. The center of the center pentagon of the first + half of the net is at the origin. If the argument + do_half is true, only the first half of the + net is created. This is used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Dodecahedron; Constructors and Setting Functions. + +

          vector<Reg_Polygon*> vrp = Dodecahedron::get_net(1);
+           for(vector<Reg_Polygon*>::iterator iter = vrp.begin();
+               iter != vrp.end(); ++iter)
+                  (**iter).draw();
+ 
+

+
+ [Figure 193. Not displayed.] +
+
+ Fig. 193. +
+

+ +
+ +
+ — Static function: void draw_net (const real pentagon_diameter, [bool portrait = true, [bool make_tabs = true]])
+

Draws the net for a Dodecahedron in the x-z plane. The pentagons + have enclosing circles of diameter pentagon_diameter. The + origin is used as the center of the middle pentagon of the first half of + the net. The centers of the pentagons are numbered. + +

If the argument portrait is true (the default), the net + is arranged for printing in portrait format. If it's false, + it's arranged for printing in landscape format. + +

The argument make_tabs currently has no effect. + When I get around to programming this, it will be used for specifying + whether tabs for gluing and/or sewing a cardboard model should be drawn, + too. + +

          Dodecahedron::draw_net(1, false);
+ 
+

+
+ [Figure 194. Not displayed.] +
+
+ Fig. 194. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dodecahedron.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dodecahedron.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Dodecahedron - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Tetrahedron, + Up: Regular Platonic Polyhedra +


+
+ +

37.2.2 Dodecahedron

+ +

Class Dodecahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

Dodecahedra have 12 regular pentagonal faces. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-Points-Intro.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-Points-Intro.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-Points-Intro.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-Points-Intro.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,208 ---- + + + Drawing Points Intro - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

5.1 Drawing Points

+ +

It's all very well to declare Points, place them at particular + locations, print their locations to standard output, and transform them, + but none of these operations produce any MetaPost output. + In order to do this, the first step is to use drawing and + filling commands. The drawing and filling commands in 3DLDF are + modelled on those in Metafont. + +

The following example demonstrates how to draw a dot specifying a + Color (see Color Reference) and a + pen1. + +

     Point P(0, 1);
+      P.drawdot(Colors::black, "pencircle scaled 3mm");
+ 
+

+
+ [Figure 3. Not displayed.] +
+
+ Fig. 3. +
+

+ +

In drawdot(), a Color argument precedes the + string argument for the pen, so “Colors::black” must be + specified as a placeholder in the call to + drawdot().2 + +

The following example “undraws” a dot at the same location using a + smaller pen. undraw() does not take a Color argument. + +

     p.undrawdot("pencircle scaled 2mm");
+ 
+

+
+ [Figure 4. Not displayed.] +
+
+ Fig. 4. +
+

+ +

For complete descriptions of drawdot() and undrawdot(), + see Point Reference; Drawing. + +

Drawing and undrawing dots is not very exciting. In order to make a + proper drawing it is necessary to connect the Points. The most + basic way of doing this is to use the Point member function + draw() with a Point argument: + +

     Point p0;
+      Point p1(2, 2);
+      p0.draw(p1);
+ 
+

+
+ [Figure 5. Not displayed.] +
+
+ Fig. 5. +
+

+ +

p0.draw(p1) is equivalent in its effect to + p1.draw(p0). + +

The function Point::draw() takes a required Point& + argument (a reference3 + to a Point) an optional Color + argument, and optional string arguments for + the dash pattern and the + pen. The string arguments, if present, are passed unchanged to + the output file. + The empty string following the + argument p1 is a placeholder for the dash pattern argument, which + isn't used here. + +

     p0.draw(p1, Colors::gray, "", "pensquare scaled .5cm rotated 45");
+ 
+

+
+ [Figure 6. Not displayed.] +
+
+ Fig. 6. +
+

+ +

The function Point::undraw() takes a required Point& + argument and + optional string arguments for the dash pattern and the + pen. Unlike Point::draw(), a Color argument would have no + meaning for Point::undraw(). + The string arguments are passed unchanged to the output file. + +

undraw() can be used to “hollow out” the region + drawn in [the previous figure] + . Since a dash pattern is used, portions + of the middle of the region are not undrawn. + +

     p0.undraw(p1, "evenly scaled 6", "pencircle scaled .2cm");
+ 
+

+
+ [Figure 7. Not displayed.] +
+
+ Fig. 7. +
+

+ +

For complete descriptions of draw() and undraw(), + see Point Reference; Drawing. + +

+
+

Footnotes

[1] Pens are a concept from Metafont. In 3DLDF, + there is currently no type “Pen”. Pen arguments to functions + are simply strings, and are written unaltered to out_stream. + For more information about + Metafont's pens, see + Knuth, The Metafontbook, Chapter 4.

+ +

[2] Colors are declared in the + namespace Colors, so if you have + a “using” declaration in the function where you use + drawdot(), you can write “black” instead of + “Colors::black”. For more information about namespaces, see + Stroustrup, The C++ + Programming Language, Chapter 8.

+ +

[3] “A reference is an alternative name for an object. The + main use of references is for specifying arguments and return values for + functions in general and for overloaded operators (Chapter 11) in + particular.” Stroustrup, The C++ + Programming Language, + section + 5.5, p. 97.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths-Intro.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths-Intro.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths-Intro.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths-Intro.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,239 ---- + + + Drawing and Filling Paths Intro - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Declaring and Initializing Paths, + Up: Paths +


+
+ +

6.2 Drawing and Filling Paths

+ +

The easiest way to draw a Path is with no arguments. + +

     Point pt[5];
+      pt[0].set(-1, -2);
+      pt[1].set(0, -3);
+      pt[2].set(1, 0);
+      pt[3].set(2, 1);
+      pt[4].set(-1, 2);
+      Path pa("..", true, &pt[0], &pt[1], &pt[2], &pt[3], &pt[4], 0);
+      pa.draw();
+ 
+

+
+ [Figure 12. Not displayed.] +
+
+ Fig. 12. +
+

+ +

Since pa is closed, it can be filled as well as drawn. The + following example uses fill() with a Color argument, in + order to avoid having a large splotch of black on the page. + Common Colors are declared in the namespace Colors. + See Color Reference. + +

     pa.fill(Colors::gray);
+ 
+

+
+ [Figure 13. Not displayed.] +
+
+ Fig. 13. +
+

+ +

Closed Paths can be filled and drawn, using the function + filldraw(). This function draws the Path using the pen + specified, or MetaPost's currentpen by default. A Color + for drawing the Path can also be specified, otherwise, the + default color (currently Colors::black) is used. + In addition, the Path is filled using a second Color, + which can be specified, or the background_color + (Colors::background_color), by default. + Filling a Path using the background color causes it to hide + objects that lie behind it. + See Surface Hiding, for a description of the surface hiding + algorithm, and examples. Currently, this algorithm is quite primitive + and only works + for simple cases. + +

     Point p0(-3, 0, 1);
+      Point p1(3, 1, 1);
+      p0.draw(p1);
+      pa.filldraw();
+ 
+

+
+ [Figure 14. Not displayed.] +
+
+ Fig. 14. +
+

+ +

The following example uses arguments for the Colors used for + drawing and filling, and the pen. The empty string argument before the + pen argument is a placeholder for the dash pattern argument. + +

     pa.filldraw(black, gray, "",
+         "pensquare xscaled 3mm yscaled 1mm rotated 60");
+ 
+

+
+ [Figure 15. Not displayed.] +
+
+ Fig. 15. +
+

+ +

Paths can also be “undrawn”, “unfilled”, and “unfilldrawn”, + using the corresponding functions: + +

     pa.fill(gray);
+      p0.undraw(p1, "", "pencircle scaled 3mm");
+ 
+

+
+ [Figure 16. Not displayed.] +
+
+ Fig. 16. +
+

+ +
     pa.fill(gray);
+      Path q;
+      q = pa;
+      q.scale(.5, .5);
+      q.unfill();
+ 
+

+
+ [Figure 17. Not displayed.] +
+
+ Fig. 17. +
+

+ +

The function unfilldraw() takes a Color argument for + drawing the Path, which is *Colors::background_color by + default. This makes it possible to unfill the Path while drawing + the outline with a visible Color. On the other hand, it also + makes it necessary to specify *Colors::background_color or + Colors::white, if the user wants to use the dash pattern and/or + pen arguments, without drawing the Path. + +

     pa.fill(gray);
+      q.unfilldraw(white, "", "pensquare xscaled 3mm yscaled 1mm");
+ 
+

+
+ [Figure 18. Not displayed.] +
+
+ Fig. 18. +
+

+ +

The following example demonstrates the use of unfilldraw() with + black as its Color argument. Unfortunately, it also + demonstrates one of the limitations of the surface hiding algorith: The + line from p0 to p1 is hidden by the + filled Path pa. Since the portion of pa covered by + Path q has been unfilled, + the line from p_0 to p_1 + should be visible as it passes through q. However, from the + point of view of 3DLDF, there is no relationship between pa and + q; nor does it “know” whether a Path has been filled or + unfilled. If it's on a Picture, it will hide objects lying + behind it, unless the surface hiding algorithm fails for another + reason. See Surface Hiding, for more information. + +

     p0.draw(p1);
+      pa.fill(gray);
+      q.unfilldraw(black, "", "pensquare xscaled 3mm yscaled 1mm");
+ 
+

+
+ [Figure 19. Not displayed.] +
+
+ Fig. 19. +
+

+ +

See Paths; Drawing and Filling, for more + information, and complete descriptions of the functions. + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,601 ---- + + + Drawing and Filling Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Applying Transformations to Paths, + Up: Path Reference +


+
+ +

26.12 Drawing and Filling

+ +
+ — const virtual function: void draw ([const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]]])
+ — const Virtual function: void draw (Picture& picture, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = ""]]])
+

Allocates a copy of the Path on the free store, puts a pointer to + the copy on picture.shapes, sets + its fill_draw_value to DRAW, and + the values of its + draw_color, dashed, and pen according to the + arguments. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

All of the arguments to draw() are optional, so it can be invoked + as follows: + +

          Point A;
+           Point B(2);
+           Point C(3, 3);
+           Point D(1, 2);
+           Point E(-1, 1);
+           Path p("..", true, &A, &B, &C, &D, &E, 0);
+           p.draw();
+ 
+

+
+ [Figure 120. Not displayed.] +
+
+ Fig. 120. +
+

+ +

The arguments: + +

+
ddraw_color
Used to specify a color for the + Path. ddraw_color is a reference to a Color. + Colors are described in Color Reference. + +

The most basic Colors are predefined in 3DLDF (in the + namespace Colors), and + users may create new Colors and specify their red-green-blue + values. + +

The Path p could be drawn in red by calling + p.draw(Colors::red). This manual isn't intended to be printed in + color, so there's no figure to demonstrate this. However, gray values + can be printed on non-color printers. + +

               using namespace Colors;
+                p.draw(gray, "", "pencircle scaled .25mm");
+ 
+

+
+ [Figure 121. Not displayed.] +
+
+ Fig. 121. +
+

+ +
ddashed
A string representing a “dash pattern”, as defined in + MetaPost1. + Dash patterns have no meaning in 3DLDF, they are simply strings + that are written unchanged to out_stream. + +
               p.draw(black, "evenly");
+ 
+

+
+ [Figure 122. Not displayed.] +
+
+ Fig. 122. +
+

+ +
ppen
A string representing a “pen”, as defined in Metafont and + MetaPost2. + Pens have no meaning in 3DLDF, they are simply strings + that are written unchanged to out_stream. + +
               p.draw(black, "", "pensquare xscaled 3mm
+                       yscaled .25mm scaled .5mm");
+ 
+

+
+ [Figure 123. Not displayed.] +
+
+ Fig. 123. +
+

+ +
picture
Indicates the Picture on which the Path should be + drawn. + +

The two versions of draw() differ in the position of the + picture argument: In the first version, it's the last argument, + while in the second version, it's the first argument. If a + picture argument is used, it's often more convenient to use the second + version. + +

The following example puts Path p onto temp_picture. It + also demonstrates how the labels are put onto temp_picture, and + how temp_picture is output. In + the previous examples, the commands for making the labels and outputting + current_picture were left out in order to reduce clutter. + See Point Reference; Labelling, and + Picture Reference; Outputting; Output Functions. + +

               Picture temp_picture;
+                p.draw(temp_picture);
+                A.dotlabel("A", "bot", temp_picture);
+                B.dotlabel("B", "bot", temp_picture);
+                C.dotlabel("C", "top", temp_picture);
+                D.dotlabel("D", "top", temp_picture);
+                E.dotlabel("E", "lft", temp_picture);
+                temp_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 124. Not displayed.] +
+
+ Fig. 124. +
+

+ +
+

+ +
+ — const function: void draw_help ([const Color& ddraw_color = *help_color, [string ddashed = help_dash_pattern, [string ppen = "", [Picture& picture = current_picture]]]])
+ — const function: void draw_help (Picture& picture, [const Color& ddraw_color = *help_color, [string ddashed = help_dash_pattern, [string ppen = ""]]])
+

This functions are for drawing help lines. + They are like draw(), except that draw_help() returns immediately, + if do_help_lines (a static data member in + Path) is false. + Also, the defaults for ddraw_color and + ddashed differ from those for draw(). +

+ +
+ — const virtual function: void drawarrow ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — const virtual function: void drawarrow (Picture& picture, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = ""]]])
+

Like draw(), except that the MetaPost command drawarrow is + written to out_stream when picture + is output. + The second version is convenient for passing a Picture argument + without having to specify all of the other arguments. + + + +

          Point m;
+           Point n(2, 2);
+           m.dotlabel("$m$", "bot");
+           n.dotlabel("$n$");
+           m.drawarrow(n);
+ 
+

+
+ [Figure 125. Not displayed.] +
+
+ Fig. 125. +
+

+ +
+ +
+ — Non-member function: void draw_axes ([real dist = 2.5, [string pos_x = "bot", [string pos_y = "lft", [string pos_z = "bot", [const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string ppen = "", [const Point& shift_x = origin, [const Point& shift_y = origin, [const Point& shift_z = origin, [Picture& picture = current_picture]]]]]]]]]]])
+ — Non-member function: void draw_axes (const Color& ddraw_color, [real dist = 2.5, [string pos_x = "bot", [string pos_y = "lft", [string pos_z = "bot", [const string ddashed = "", [const string ppen = "", [const Point& shift_x = origin, [const Point& shift_y = origin, [const Point& shift_z = origin, [Picture& picture = current_picture]]]]]]]]]])
+

These functions draw lines centered on the origin, and ending in arrows in the + directions of the positive x, + y, and z-axes, and labels them with the appropriate letters. + draw_axes() is used in + many of the figures in this handbook. It can be helpful in determining + whether a Focus has a good “up” direction. + See Focus Reference; Data Members. + +

In the first version, all of the arguments are optional. In the second + version, ddraw_color is required and has been moved to the front + of the argument list. This version is often convenient, when a + Color other than the default is desired. + +

The arguments: +

+
dist
The length of the lines drawn. The default is 2.5. The value 0 can be + used as a dummy argument, if the default for dist is desired, but + other arguments must be specified. + +
pos_x
pos_y
pos_z
The position arguments for the labelling commands for each of the axes. + The defaults are "bot" for the x and z-axes, and "lft" for + the y-axis. + The usual strings for the + position of labels can be used, + namely: "top", "bot", "lft", + "rt", "ulft", "urt", "llft", + "lrt", and "". If "" is used, that axis is not + drawn. This can be useful for parallel projections onto one of the + major planes3. + In addition, "d" can be used to indicate that the default should + be used for that label. This can be useful if one needs a placeholder, + but doesn't remember what the default is for that label. + +
               draw_axes(0, "bot", "rt", "");
+                current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 126. Not displayed.] +
+
+ Fig. 126. +
+

+ +

In addition, the arguments shift_x, shift_y, + and shift_z can be used to adjust the positions of the labels + further (see below). + +

ddraw_color
ddashed
ppen
Arguments for the drawarrow() command, described above, in this + section. + +
shift_x
shift_y
shift_z
Offsets for the labels. These arguments make it possible to adjust the + positions of the labels. The defaults are origin, so no shifting + takes place, if they are used. In [next figure] + , + draw_axes is called without any arguments, so the defaults + are used. + +
               draw_axes();
+ 
+

+
+ [Figure 127. Not displayed.] +
+
+ Fig. 127. +
+

+ +

In [next figure] + , the Point P is used to shift the labels. + Please note that placeholders must be used for the first arguments. + +

               Point P(.5, .5, .5);
+                draw_axes(0, "d", "d", "d", black, "", "", P, -P, P);
+ 
+

+
+ [Figure 128. Not displayed.] +
+
+ Fig. 128. +
+

+ +

Please note that the Points used for placing the labels are + three-dimensional Points, whether the shift_x, + shift_y, and/or shift_z arguments are used or not. + It is not currently possible to adjust the positions of the + labels on the two-dimensional projection itself. This would + probably be more useful, but would require changing the way + Picture::output() functions. + +

picture
The Picture, onto which the Paths and Labels are put. +
+

+ +
+ — const function: void fill ([const Color& ffill_color = *Colors::default_color, [Picture& picture = current_picture]])
+ — Function: void fill (Picture& picture, [const Color& ffill_color = *Colors::default_color])
+
+

Allocates a copy of the Path on the free store, puts a pointer to + it onto picture.shapes, sets + its fill_draw_value to FILL, and + its fill_color to *ffill_color. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

The arguments are similar to those of draw(), except that the + Color argument is called ffill_color instead of + ddraw_color. + +

          p.fill(gray);
+ 
+

+
+ [Figure 129. Not displayed.] +
+
+ Fig. 129. +
+

+ +
+ +
+ — const function: void filldraw ([const Color& ddraw_color = *Colors::default_color, [const Color& ffill_color = *Colors::background_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]]])
+ — const function: void filldraw (Picture& picture, [const Color& ddraw_color = *Colors::default_color, [const Color& ffill_color = *Colors::background_color, [string ddashed = "", [string ppen = ""]]]])
+

Allocates a copy of the Path on the free store, puts a pointer to + the copy onto picture.shapes, sets + its fill_draw_value to FILLDRAW, + its draw_color and fill_color to + *ddraw_color and *ffill_color, respectively, + its dashed to ddashed, and its pen + to ppen. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

The arguments are similar to those of draw() and fill(), + except that both ddraw_color and ffill_color are used. + +

3DLDF's filldraw() differs from Metafont's and MetaPost's + filldraw commands: In Metafont and MetaPost, filldrawing + is equivalent to filling a path and then drawing its + border using the pen. + Metafont does not have colors. While MetaPost does, its filldraw + command does not foresee the use of different colors for drawing and + filling. + +

          p.filldraw(black, gray, "", "pencircle scaled 2mm");
+ 
+

+
+ [Figure 130. Not displayed.] +
+
+ Fig. 130. +
+

+ +

It can often be useful to draw the outline of a Path, but to have + it hide objects that lie behind it. This is why the default for + ffill_color is *Colors::background_color. + +

          default_focus.set(3, 0, -10, 3, 10, 10, 10);
+           Point p[8];
+           p[0] = p[1] = p[2] = p[3] = p[4]
+                = p[5] = p[6] = p[7].set(-1,-1, 5);
+           p[1] *= p[2] *= p[3] *= p[4] *= p[5]
+                *= p[6] *= p[7].rotate(0, 0, 45);
+           p[2] *= p[3] *= p[4]
+                *= p[5] *= p[6] *= p[7].rotate(0, 0, 45);
+           p[3] *= p[4] *= p[5] *= p[6]
+                *= p[7].rotate(0, 0, 45);
+           p[4] *= p[5] *= p[6] *= p[7].rotate(0, 0, 45);
+           p[5] *= p[6] *= p[7].rotate(0, 0, 45);
+           p[6] *= p[7].rotate(0, 0, 45);
+           p[7].rotate(0, 0, 45);
+           Path r0("..", true, &p[0], &p[1], &p[2],
+                   &p[3], &p[4], &p[5], &p[6], &p[7], 0);
+           r0.filldraw(black, light_gray);
+           r0.scale(2, .5);
+           r0.shift(0, 0, -2.5);
+           r0.filldraw(black, gray);
+           r0.scale(.25, 3);
+           r0.shift(0, 0, -2.5);
+           r0.filldraw();
+ 
+

+
+ [Figure 131. Not displayed.] +
+
+ Fig. 131. +
+

+ +
+ +
+ — Function: void undraw ([string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]])
+ — Function: void undraw (Picture& picture, [string ddashed = "", [string ppen = ""]])
+

Allocates a copy of the Path on the free store, puts a pointer to + it on picture.shapes, sets + its fill_draw_value to UNDRAW, and + the values of its + dashed and pen according to the + arguments. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

This function “undraws” a Path. This is equivalent to drawing + the Path using the background color + (*Colors::background_color). + +

Undrawing is useful for removing a portion of a Path. + + +

          Point P0(1, 1);
+           Point P1(2, 1);
+           Point P2(2, 3);
+           Point P3(-1, 1);
+           Path p("--", false, &origin, &P0, &P1, &P2, &P3, 0);
+           p.draw(black, "", "pencircle scaled 3mm");
+           p.undraw("", "pencircle scaled 1mm");
+ 
+

+
+ [Figure 132. Not displayed.] +
+
+ Fig. 132. +
+

+ +
+ +
+ — Function: void unfill ([Picture& picture = current_picture])
+

Allocates a copy of the Path on the free store, puts a pointer to + it on picture.shapes and sets + its fill_draw_value to UNFILL + +

This function is useful for removing a portion of a filled region. + +

          Point pt[4];
+           pt[0].set(-2, -2);
+           pt[1].set(2, -2);
+           pt[2].set(2, 2);
+           pt[3].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2], &pt[3], 0);
+           p.draw();
+           p.dotlabel();
+           p.filldraw(black, gray);
+           p.scale(.5, .5);
+           p.unfill();
+ 
+

+
+ [Figure 133. Not displayed.] +
+
+ Fig. 133. +
+

+ +
+ +
+ — Function: void unfilldraw ([const Color& ddraw_color = *Colors::background_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — Function: void unfilldraw (Picture& picture, [const Color& ddraw_color = *Colors::background_color, [string ddashed = "", [string ppen = ""]]])
+

Allocates a copy of the Path on the free store, puts a pointer to + it on picture.shapes, sets + its fill_draw_value to UNFILLDRAW, and + the values of its + draw_color, dashed, and pen according to the + arguments. While the default for ddraw_color is + *Colors::background_color, any other Color can be used, + so that unfilldraw() can unfill a Path and draw an outline + around it. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

This function is similar to unfill() + (see Path Reference; Drawing and Filling), + except that the outline of the Path will be “undrawn” using the + pen specified with the ppen argument, or MetaPost's + currentpen, if no ppen argument is specified. In addition, + the Path will be drawn using the Color specified in the + ddraw_color argument. Since the default is + *Colors::background_color, the Path will be “undrawn” + unless a different Color is specified. + +

          Point pt[6];
+           pt[0].set(-2, -2);
+           pt[1].set(0, -3);
+           pt[2].set(2, -2);
+           pt[3].set(2, 2);
+           pt[4].set(0, 3);
+           pt[5].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2],
+                  &pt[3], &pt[4], &pt[5], 0);
+           p.fill(gray);
+           p.scale(.5, .5);
+           p.unfilldraw(black, "", "pensquare xscaled 3mm");
+ 
+

+
+ [Figure 134. Not displayed.] +
+
+ Fig. 134. +
+

+ +
+ +
+
+

Footnotes

[1] Hobby, A User's Manual for MetaPost, p. 32.

+ +

[2] Knuth, The METAFONTbook, Chapter 4, p. 21ff. + Hobby, A User's Manual for MetaPost, p. 32.

+ +

[3] The usual interpretation of "" as a + position argument to a + labelling command would be to put it directly onto *(Label.pt), + which in this case would put it onto the arrowhead. Since this + will probably never be desirable, I've decided to use "" to + suppress drawing axes. Formerly, draw_axes() used three + additional arguments for this purpose.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Filling-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,167 ---- + + + Drawing and Filling Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Outputting Solids, + Up: Solid Reference +


+
+ +

34.13 Drawing and Filling

+ +
+ — const virtual function: void draw ([const vector<const Color*> v = Colors::default_color_vector, [const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Solid. + +

This function allocates a new Solid, makes it a copy of + *this, and puts a pointer to the copy onto + picture.shapes. The data members of the Shapes + belonging to the copy are set appropriately, so that they can be drawn, + when Picture::output() is called. + +

The Colors used + for drawing the various + Paths, Circles, Ellipses, etc., belonging to the + Solid are passed in v. If the Solid contains more + Shapes than v contains pointers to Color, the + Color pointed to by the last pointer on v is used to draw + the remaining Shapes. + +

Currently, a Solid can + only be drawn with a single dash pattern (ddashed), and + pen (ppen). +

+ +
+ — const virtual function: void fill ([const vector<const Color*> v = Colors::default_color_vector, [Picture& picture = current_picture]])
+

Fills the Solid. + +

This function allocates a new Solid makes it a copy of *this, and puts a + pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be filled, + when Picture::output() is called. + +

The Colors used + for filling the various + Paths, Circles, Ellipses, etc., belonging to the + Solid are passed in v. + If the Solid contains more + Shapes than v contains pointers to Color, the + Color pointed to by the last pointer on v is used to fill + the remaining Shapes. +

+ +
+ — const virtual function: void filldraw ([const vector<const Color*> draw_colors = Colors::default_color_vector, [const vector<const Color*> fill_colors = Colors::background_color_vector, [const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]]]])
+

Filldraws the Solid. + +

This function allocates a new Solid, makes it a copy of *this, and puts a + pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be filldrawn, + when Picture::output() is called. + +

The Colors used + for drawing and filling the various + Paths, Circles, Ellipses, etc., belonging to the + Solid are passed in draw_colors and fill_colors. + If the Solid contains more + Shapes than draw_colors contains pointers to Color, the + Color pointed to by the last pointer on draw_colors is used to draw + the remaining Shapes. The same applies to fill_colors. + +

Currently, a Solid can only be filldrawn with a single dash + pattern (ddashed), and pen (ppen). +

+ +
+ — const virtual function: void undraw ([const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]])
+

Undraws the Solid. + +

This function allocates a new Solid, makes it a copy of *this, and puts a + pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be undrawn, + when Picture::output() is called. + +

A Solid can currently only be undrawn using a single dash + pattern (ddashed), and + pen (ppen). +

+ +
+ — const virtual function: void unfill ([Picture& picture = current_picture])
+

Unfills the Solid. + +

This function allocates a new Solid makes it a copy of + *this, and puts a pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be unfilled, + when Picture::output() is called. + +

+ +
+ — const virtual function: void unfilldraw ([const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]])
+ — const virtual function: void undraw ([const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]])
+

Unfilldraws the Solid. + +

This function allocates a new Solid, makes it a copy of + *this, and puts a + pointer to it onto picture.shapes. The data members of the + Shapes + belonging to the copy are set appropriately, so that they can be + unfilldrawn, when Picture::output() is called. + +

A Solid can currently only be unfilldrawn using a single dash + pattern (ddashed), and + pen (ppen). +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Labeling-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Labeling-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Drawing-and-Labeling-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Drawing-and-Labeling-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,61 ---- + + + Drawing and Labeling Points - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transforms, + Up: Top +


+
+ +

5 Drawing and Labeling Points

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dynamic-Allocation-of-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dynamic-Allocation-of-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Dynamic-Allocation-of-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Dynamic-Allocation-of-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,113 ---- + + + Dynamic Allocation of Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Global Constants and Variables, + Up: Top +


+
+ +

14 Dynamic Allocation of Shapes

+ +
+ — Template function: template <class C> C* create_new (const C* arg)
+ — Template function: template <class C> C* create_new (const C& arg)
+

These functions dynamically allocate an object derived from + Shape on the free store, + returning a pointer to the type of the Shape and setting + on_free_store to true. + +

If a non-zero pointer or a reference is passed to create_new(), + the new object will be a copy of arg. + +

It is not possible to instantiate more than one specialization of + create_new() that takes no argument, because calls to these + functions would be ambiguous. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to create_new() + as its argument. + +

create_new is called like this: + +

          Point* p = create_new<Point>(0);
+           p->show("*p:");
+           -| *p: (0, 0, 0)
+           
+           Color c(.3, .5, .25);
+           Color* d = create_new<Color>(c);
+           d->show("*d:");
+           -|
+           *d:
+           name ==
+           use_name == 0
+           red_part == 0.3
+           green_part == 0.5
+           blue_part == 0.25
+           
+           
+           Point a0(3, 2.5, 6);
+           Point a1(10, 11, 14);
+           Path q(a0, a1);
+           Path* r = create_new<Path>(&q);
+           r->show("*r:");
+           -|
+           *r:
+           points.size() == 2
+           connectors.size() == 1
+           (3, 2.5, 6) -- (10, 11, 14);
+ 
+

Specializations of this template function are currently declared for + Color, Point, Path, Reg_Polygon, + Rectangle, Ellipse, Circle, Solid, and + Cuboid. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,124 ---- + + + Ellipse Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

31.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Ellipse (void)
+

Creates an empty Ellipse. +

+ +
+ — Constructor: void Ellipse (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0, [const unsigned short nnumber_of_points = DEFAULT_NUMBER_OF_POINTS]]]])
+

Creates an Ellipse in the x-z plane, centered at the origin, with + its horizontal axis + == aaxis_h and its vertical axis == aaxis_v. If + any of the arguments angle_x, angle_y, or angle_z is + non-zero, the Ellipse is rotated about the x, y, and z-axis in + that order, by the amounts indicated by the corresponding arguments. + Finally, the Ellipse is shifted such that its + center comes to lie at ccenter. + +

          Ellipse e(origin, 6, 4);
+           e.draw();
+ 
+

+
+ [Figure 159. Not displayed.] +
+
+ Fig. 159. +
+

+ +
          Point P(1, 1, 1);
+           Ellipse e(P, 6, 4, 15, 12, 11);
+           e.draw();
+ 
+

+
+ [Figure 160. Not displayed.] +
+
+ Fig. 160. +
+

+ +
+ +
+ — Setting function: void set (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0, [const unsigned short nnumber_of_points = DEFAULT_NUMBER_OF_POINTS]]]])
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Ellipse* create_new<Ellipse> (const Ellipse* e)
+ — : Ellipse* create_new<Ellipse> (const Ellipse& e)
+

Pseudo-constructors for dynamic allocation of Ellipses. + They create a Ellipse on the free store and allocate memory for it using + new(Ellipse). They return a pointer to the new Ellipse. + +

If e is a non-zero pointer or a reference, + the new Ellipse will be a copy of + e. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Ellipse>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,105 ---- + + + Ellipse Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

31.1 Data Members

+ +
+ — Protected variables: Point focus0
+ — : Point focus1
+

The foci of the Ellipse. They are located on the major axis of + the Ellipse at a distance of linear_eccentricity from + center, on opposite sides of the minor axis. +

+ +
+ — Protected variable: real linear_eccentricity
+

The linear eccentricity of the Ellipse e, such that + e = \sqrta^2 - b^2, + where a and b are half the lengths of the major + and minor axes, respectively. Let h stand for axis_h and v + for axis_v. If h>v, then a = h/2 and b = v/2. If v>h, + then a =v/2 and b = h/2. If h = v, then the Ellipse is + circular (but not an object of type Circle!), and a = b = v/2 = h/2. + +

The linear eccentricity is the distance along the major axis of the + Ellipse from center to focus0 and focus1. + +

+ +
+ — Protected variable: real numerical_eccentricity
+

The numerical eccentricity \epsilon of the Ellipse, + such + that \epsilon = e/a < 1, where e is the linear eccentricity of the + Ellipse, and a is half the length of the major axis of the + Ellipse. +

+ +
+ — Protected variables: real axis_h
+ — : real axis_v
+

The horizontal and vertical axes, respectively, of the Ellipse. + +

Actually, they are only or vertical + horizontal by convention, since there are no restrictions on the + orientation of an Ellipse. +

+ +
+ — Protected static variable: unsigned short DEFAULT_NUMBER_OF_POINTS
+

The number of Points on an Ellipse, unless another number + is specified when an Ellipse constructor is invoked. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,256 ---- + + + Ellipse Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

31.9 Intersections

+ +
+ — const virtual function: bool_point_pair intersection_points (const Point& p0, const Point& p1)
+ — const virtual function: bool_point_pair intersection_points (const Path& p)
+

These functions return the intersection points of a line with an + Ellipse. In the first version, the line is specified by the two + Point arguments. + In the second version, p.is_linear() must return true, + otherwise, intersection_points() issues an error message and + returns INVALID_BOOL_POINT_PAIR. + +

If the line and the Ellipse are coplanar, there can be at most two + intersection points. Otherwise, there can be at most one. + +

          Ellipse e(origin, 5, 7, 30, 30, 30);
+           e.shift(3, 0, 3);
+           Point p0 = e.get_center().mediate(e.get_point(3));
+           Point normal = e.get_normal();
+           Point A = normal;
+           A *= 2.5;
+           A.shift(p0);
+           Point B = normal;
+           B *= -2.5;
+           B.shift(p0);
+           bool_point_pair bpp = e.intersection_points(A, B);
+           bpp.first.pt.dotlabel("$i_0$", "rt");
+           Point C = e.get_point(15).mediate(e.get_point(11), 1.25);
+           Point D = e.get_point(11).mediate(e.get_point(15), 1.5);
+           Path q = C.draw(D);
+           bpp = e.intersection_points(q);
+           bpp.first.pt.dotlabel("$i_1$", "llft");
+           bpp.second.pt.dotlabel("$i_2$", "ulft");
+ 
+

+
+ [Figure 167. Not displayed.] +
+
+ Fig. 167. +
+

+ +
+ +
+ — const virtual function: bool_point_quadruple intersection_points (Ellipse e, [const real step = 3, [bool verbose = false]])
+

Returns the intersection points of two Ellipses. Two Ellipses + can intersect at at most four points. + +

Let bpq be the bool_point_quadruple returned by + intersection_points(). If one or more intersection points are + found, the corresponding Points are stored in the + pt elements of the four bool_points belonging to + bpq, otherwise INVALID_POINT. If a Point is found, the + b element of the bool_point will be true, otherwise + false. + +

The step argument is used when the Ellipses are coplanar + and either have different centers or the vertical axis of one Ellipse is + colinear with the horizontal axis of the other (and vice versa). In + these cases, the intersection points must be found by an iterative + routine. A Point p travels around the perimeter of *this, + and its location with respect to e is tested. step is the + angle of rotation used for stepping around the perimeter of + *this. The default value, 3, should be adequate, unless the + Ellipses differ greatly in size. + +

If the verbose argument is true, + intersection_points() will print information about the + intersection points to standard output. + +

In [next figure] + , the Ellipses e and f both lie in the x-z + plane, are centered at the origin, and intersect at four points. + +

          Ellipse e(origin, 5, 2);
+           Ellipse f(origin, 2, 5);
+           bool_point_quadruple bpq = e.intersection_points(f);
+           bpq.first.pt.dotlabel(1, "llft");
+           bpq.second.pt.dotlabel(2, "urt");
+           bpq.third.pt.dotlabel(3, "ulft");
+           bpq.fourth.pt.dotlabel(4, "lrt");
+ 
+

+
+ [Figure 168. Not displayed.] +
+
+ Fig. 168. +
+

+ +

In [next figure] + , e and f are coplanar, but don't lie in a major plane, + have different centers, and only intersect at two points. + +

          Ellipse e(origin, 4, 2);
+           Ellipse f(origin, 2, 5);
+           f.shift(0, 0, 1);
+           f.rotate(0, 15);
+           f.shift(1, 0, 1);
+           e *= f.shift(-.25, 1, -1);
+           e *= f.rotate(10, -12.5, 3);
+           bool_point_quadruple bpq = e.intersection_points(f, true);
+           bpq.first.pt.dotlabel(1, "urt");
+           bpq.second.pt.dotlabel(2, "ulft");
+ 
+

+
+ [Figure 169. Not displayed.] +
+
+ Fig. 169. +
+

+ +

If the planes of the Ellipses are parallel, there are, of course, + no intersection points. If the Ellipses are non-coplanar, and + their planes are not parallel to each other, + intersection_points() first finds the line of intersection of the + planes of the Ellipses. It then returns the Points of + intersection of this line with the Ellipses, if they exist. If + the verbose argument is true, information about the + Points is printed to standard output. + +

In [next figure] + , the two Ellipses lie in skew planes. The plane + of f intersects with e at the Points labelled “1” and “2”, + while the plane of e intersects with f at the Points labelled + “3” and “4”. + +

          Ellipse e(origin, 5, 3);
+           Ellipse f(origin, 2, 5);
+           f.rotate(0, 0, 30);
+           f.rotate(0, 10);
+           f.rotate(45);
+           f.shift(1.5, 1);
+           bool_point_quadruple bpq = e.intersection_points(f, true);
+           bpq.first.pt.dotlabel(1);
+           bpq.second.pt.dotlabel(2);
+           bpq.third.pt.dotlabel(3, "rt");
+           bpq.fourth.pt.dotlabel(4, "urt");
+           -| First point lies on the perimeter of *this.
+              First point lies inside e.
+              Second point lies on the perimeter of *this.
+              Second point lies outside e.
+              Third point lies outside *this.
+              Third point lies on the perimeter of e.
+              Fourth point lies inside *this.
+              Fourth point lies on the perimeter of e.
+ 
+

+
+ [Figure 170. Not displayed.] +
+
+ Fig. 170. +
+

+ +

In [next figure] + , the two Ellipses lie in skew planes. The plane of + f intersects with e at the Points labelled “1” and “2”. + The plane of e does not intersect with f, so bpq.third.pt + and bpq.fourth.pt are INVALID_POINT. + +

          Ellipse e(origin, 5, 3);
+           Ellipse f(origin, 2, 5, 45);
+           f.shift(0, 2.5, 3);
+           bool_point_quadruple bpq = e.intersection_points(f, true);
+           bpq.first.pt.dotlabel(1);
+           bpq.second.pt.dotlabel(2);
+           -| First point lies on the perimeter of *this.
+              First point lies outside e.
+              Second point lies on the perimeter of *this.
+              Second point lies outside e.
+              Third intersection point is INVALID_POINT.
+              Fourth intersection point is INVALID_POINT.
+ 
+

+
+ [Figure 171. Not displayed.] +
+
+ Fig. 171. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Ellipse Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

31.4 Operators

+ +
+ — Assignment operator: Ellipse& operator= (const Ellipse& e)
+

Makes the Ellipse a copy of e. +

+ +
+ — Virtual function: Transform operator*= (const Transform& t)
+

Calls do_transform(t, true), and returns the latter's return + value. + See Ellipse Reference; Performing Transformations. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipse-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipse-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,73 ---- + + + Ellipse Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Regular Closed Plane Curve Reference, + Up: Top +


+
+ +

31 Ellipse Reference

+ +

Class Ellipse is defined in ellipses.web. + It is derived from Reg_Cl_Plane_Curve using public derivation. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipses-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipses-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipses-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipses-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,116 ---- + + + Ellipses Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Rectangles Getstart, + Up: Plane Figures +


+
+ +

7.3 Ellipses

+ +

Ellipse has a constructor similar to those for + Reg_Polygon and Rectangle. The first argument is the + center of the Ellipse, and the following two specify the lengths + of the horizontal and vertical axes respectively. The Ellipse is + first created in the x-z plane, centered about the origin. The + horizontal axis lies along the x-axis and the vertical axis lies along + the z-axis. The three subsequent arguments specify the amounts of + rotation about the x, y, and z-axes respectively and default to 0. + Finally, + Ellipse is shifted such that its center comes to lie at the + Point specified in the first argument. + +

     Point pt(-1, 1, 1);
+      Ellipse e(pt, 3, 6, 90);
+      e.draw();
+ 
+

+
+ [Figure 33. Not displayed.] +
+
+ Fig. 33. +
+

+ +

As you may expect, this constructor has a corresponding setting + function: + + +

     Ellipse e;
+      real h_save = 1.5;
+      real v_save = 2;
+      real h = h_save;
+      real v = v_save;
+      Point p(-1);
+      for (int i = 0; i < 5; ++i)
+        {
+            e.set(p, h, v, 90);
+            e.draw();
+            h_save += .25;
+            v_save += .25;
+            h *= sqrt(h_save);
+            v *= sqrt(v_save);
+            p.shift(0, 0, 2);
+        }
+ 
+

+
+ [Figure 34. Not displayed.] +
+
+ Fig. 34. +
+

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipses-for-Rectangles.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipses-for-Rectangles.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ellipses-for-Rectangles.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ellipses-for-Rectangles.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,122 ---- + + + Ellipses for Rectangles - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Querying Rectangles, + Up: Rectangle Reference +


+
+ +

29.6 Ellipses

+ +
+ — const function: Ellipse out_ellipse (void)
+

Returns the smallest Ellipse that surrounds the Rectangle. + +

          Point P(-1, -1, 3);
+           Rectangle r(P, 3, 4, 60, 30, 15);
+           Ellipse e = r.out_ellipse();
+           e.filldraw(black, gray);
+           r.unfilldraw(black);
+ 
+

+
+ [Figure 152. Not displayed.] +
+
+ Fig. 152. +
+

+ +
+ +
+ — const function: Ellipse in_ellipse (void)
+

Returns the Ellipse enclosed by the Rectangle. + +

          Point P(-1, -1, 3);
+           Rectangle r(P, 3, 4, 60, 30, 15);
+           Ellipse e = r.in_ellipse();
+           r.filldraw(black, gray);
+           e.unfilldraw(black);
+ 
+

+
+ [Figure 153. Not displayed.] +
+
+ Fig. 153. +
+

+ +
+ +
+ — const function: Ellipse draw_out_ellipse ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the smallest Ellipse that surrounds the Rectangle. + The arguments are like those of Path::draw() + (see Path Reference; Drawing and Filling). + The return value is the surrounding Ellipse. +

+ +
+ — const function: Ellipse draw_in_ellipse ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Ellipse enclosed by the Rectangle. + The arguments are like those of Path::draw() + (see Path Reference; Drawing and Filling). + The return value is the enclosed Ellipse. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Endianness.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Endianness.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Endianness.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Endianness.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,132 ---- + + + Endianness - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: System Information, + Up: System Information +


+
+ +

15.1 Endianness

+ +
+ — Function: signed short get_endianness ([const bool verbose = false])
+

Returns the following values: + +

+
0
if the processor is little-endian. + +
1
if the processor is big-endian. + +
-1
if the endianness cannot be determined. + +
+ +

It is called by is_little_endian() and + is_big_endian(). + +

If verbose is true, messages are printed to standard + output. + +

This function has been adapted from + Harbison, Samuel P., and Guy L. Steele Jr. + C, A Reference Manual, pp. 163–164. + This book has the clearest explanation of endianness that I've found so + far. + +

This is the C++ + code: + +

          signed short
+           System::get_endianness(const bool verbose)
+           {
+             union {
+               long Long;
+               char Char[sizeof(long)];
+             } u;
+             u.Long = 1;
+             if (u.Char[0] == 1)
+               {
+                 if (verbose)
+                   cout << "Processor is little-endian."
+                        << endl << endl << flush;
+                 return 0;
+               }
+             else if (u.Char[sizeof(long) - 1] == 1)
+               {
+                 if (verbose)
+                   cout << "Processor is big-endian."
+                        << endl << endl << flush;
+                 return 1;
+               }
+             else
+               {
+                 cerr << "ERROR! In System::get_endianness():\n"
+                      << "Can't determine endianness. Returning -1"
+                      << endl << endl << flush;
+                 return -1;
+               }
+           }
+ 
+
+ +
+ — Function: bool is_big_endian ([const bool verbose = false])
+

Returns true if the processor is big-endian, otherwise false. + If verbose is true, messages are printed to standard + output. +

+ +
+ — Function: bool is_little_endian ([const bool verbose = false])
+

Returns true if the processor is little-endian, otherwise false. + If verbose is true, messages are printed to standard + output. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Epicycloids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Epicycloids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Epicycloids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Epicycloids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,147 ---- + + + Epicycloids - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Roulettes and Involutes, + Up: Roulettes and Involutes +


+
+ +

33.2.1 Epicycloids

+ + + +
+ — Function: unsigned int epicycloid_pattern_1 (real diameter_inner, real diameter_outer_start, real diameter_outer_end, real step, int arc_divisions, unsigned int offsets, [vector<const Color*> colors = Colors::default_color_vector])
+

Draws a pattern consisting of epicycloids. The outer circle rolls + around the circumference of the inner circle and a Point on the + outer circle traces an epicycloid. + +

If offsets is greater than 1, the outer circle is rotated + offset times around the center of the inner circle + by + 360 / offsets + (starting from the outer circle's original + position). From each of these new positions, an epicycloid is drawn. + +

While diameter_outer_start is + greater than or equal to diameter_outer_end, the diameter of the + outer circle is reduced by step, and another set of epicycloids is + traced, as described above. Each time the diameter of + the outer circle is reduced, a new Color is taken from + colors for the drawing commands. If there are more iterations + than Colors, the last Color on colors is used for + the remaining iterations. + + +

The arguments: +

+
real diameter_inner
The diameter of the inner circle. + +
real diameter_outer_start
The diameter of the outer circle for the first iteration. It must be + greater than or equal to diameter_outer_end. + +
real diameter_outer_end
The diameter of the outer circle for the last iteration. + It must be + less than or equal to diameter_outer_start. + +
real step
The amount by which the diameter of the outer circle is reduced + upon each iteration. + +
int arc_divisions
The number of divisions of the circle used for calculating Points + on the epicycloid. For instance, if arc_divisions is 90, then + the Path for each epicycloid will only have 4 Points, + since 360 / 90 = 4. + +
unsigned int offsets
The number of epicycloids drawn upon each iteration. Each one is + rotated by 360 / offsets around the center of the inner circle. + offsets must be greater than or equal to 1. + +
vector<const Color*> colors
Default: Colors::default_color_vector. The Colors pointed + to by the pointers on this vector are used for drawing the epicycloids. + One Color is used for each iteration. + +
+ +

Example: +

          epicycloid_pattern_1(5, 3, 3, 1, 72);
+           current_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 180. Not displayed.] +
+
+ Fig. 180. +
+

+ +

Example: +

          default_focus.set(2, 5, -10, 2, 5, 10, 10);
+           epicycloid_pattern_1(5, 3, 3, 1, 36);
+           current_picture.output();
+ 
+

+
+ [Figure 181. Not displayed.] +
+
+ Fig. 181. +
+

+ +
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Faced-Solid-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Faced-Solid-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Faced-Solid-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Faced-Solid-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Faced Solid Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Solid Reference, + Up: Top +


+
+ +

35 Faced Solid Reference

+ +

Class Solid_Faced is defined in solfaced.web. + It is derived from Solid using public derivation. + +

Solid_Faced currently has no member functions. It is intended + for use as a base class. The classes Cuboid and + Polyhedron are derived from Solid_Faced. + See Cuboid Reference, and Polyhedron Reference. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,90 ---- + + + Focus Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Focus Global Variables, + Up: Focus Reference +


+
+ +

23.3 Constructors and Setting Functions

+ +
+ — Default constructor: void Focus (void)
+

Creates an empty Focus +

+ +
+ — Constructor: void Focus (const real pos_x, const real pos_y, const real pos_z, const real dir_x, const real dir_y, const real dir_z, const real dist, [const real ang = 0, [char ax = 'z']])
+

Constructs a Focus using the first three real arguments as + the x, y, and z-coordinates of position, and the fourth through the + sixth argument as the x, y, and z-coordinates of direction. dist + specifies the distance of the Focus + from the plane of projection, ang the angle of rotation, which affects which + direction is considered to be “up”, and ax the major axis to + which the Focus is aligned. +

+ +
+ — Setting function: void set (const real pos_x, const real pos_y, const real pos_z, const real dir_x, const real dir_y, const real dir_z, const real dist, [const real ang = 0, [char ax = 'z']])
+

Resets an existing Focus. Corresponds to the constructor above. +

+ +
+ — Constructor: void Focus (const Point& pos, const Point& dir, const real dist, [const real ang = 0, [char ax = 'z']])
+

Constructs a Focus using Point arguments for + position and direction. Otherwise, the arguments of this constructor + correspond to those of the one above. +

+ +
+ — Setting function: void set (const Point& pos, const Point& dir, const real dist, [const real ang = 0, [char ax = 'z']])
+

Resets an existing Focus. Corresponds to the constructor above. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,123 ---- + + + Focus Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Focus Reference, + Up: Focus Reference +


+
+ +

23.1 Data Members

+ +
+ — Private variable: Point position
+

The location of the Focus in the world coordinate system. +

+ +
+ — Private variable: Point direction
+

The direction of view from position into the scene. +

+ +
+ — Private variable: Point up
+

The direction that will be at the top of the projected drawing. +

+ +
+ — Private variable: real distance
+

The distance of the Focus from the plane of projection. +

+ +
+ — Private variable: real angle
+

Used for determining the up direction. +

+ +
+ — Private variable: char axis
+

The main axis onto which the Focus is transformed in order to + perform the perspective projection, z by default. + +

It will normally not matter which axis is used, but it might be + advantageous to use a particular axis in some special situations. +

+ +
+ — Private variable: Transform transform
+

The Transform, which will be applied to the Shapes on the + Picture, when the latter is output. The effect of this is + equivalent to transforming the Focus, so that it lies on a major + axis. + +

          Focus f(5, 5, -10, 2, 4, 10, 10, 180);
+           ⇒
+ 
+
          f.transform ==
+            0.989  -0.00733  -0.148  0
+            0       0.999    -0.0494 0
+            0.148   0.0488    0.988  0
+           -3.4    -4.47      0.865  1
+           
+ 
+
+ +
+ — Private variable: Transform persp
+

The Transform representing the perspective transformation for a + particular Focus. + Let d stand for distance, then +

          persp ==
+           1 0 0  0
+           0 1 0  0
+           0 0 0 1/d
+           0 0 0  1
+ 
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Global-Variables.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Global-Variables.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Global-Variables.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Global-Variables.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,77 ---- + + + Focus Global Variables - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

23.2 Global Variables

+ +
+ — Variable: Focus default_focus
+

Effectively, the default Focus in Picture::output(). + See Picture Reference; Outputting; Functions. + It's not really the default, but the version of + output() that doesn't take a + Focus argument calls another version + that does take one, passing default_focus to the + latter as its Focus argument. + +

It's necessary to do this in such a roundabout way, + because Picture::output() must be declared before + class Focus is completely defined and default_focus is declared. + +

The declaration ‘Focus& f = default_focus;’ makes f a + reference to default_focus, i.e., it makes f another name + for default_focus. This may be convenient, if you don't feel + like typing default_focus. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Focus Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

23.4 Operators

+ +
+ — Assignment operator: const Focus& operator= (const Focus& f)
+

Sets the Focus to f. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focus-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focus-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,71 ---- + + + Focus Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Point Reference, + Up: Top +


+
+ +

23 Focus Reference

+ +

Class Focus is defined in points.web. + Focuses are used when creating a perspective projection. + They represent the center of projection and can be thought of like a + camera viewing the scene. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focuses-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focuses-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Focuses-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Focuses-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,258 ---- + + + Focuses Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Projections, + Up: Pictures +


+
+ +

9.2 Focuses

+ +

The perspective transformation requires a focus; as a consequence, + outputting a Picture requires an object of class + Focus. + Picture::output() takes an optional pointer-to-Focus + argument, which is 0 by default. If the default is used, (or 0 is + passed explicitly), the global variable default_focus is used. + See Focus Reference; Global Variables. + +

A Focus can be thought of as the observer of a scene, or a + camera. It contains a Point position for its location with + respect to 3DLDF's coordinate system, and a Point direction, + specifying the direction where the observer is looking, or where the + camera is pointed. The Focus can be rotated freely about the + line + PD, + where P stands for position and + D + for direction, + so a Focus contains a third Point up, to indicate which + direction will be “up” on the projection, when a Picture is + projected. + +

The projection plane q + will always be perpendicular to + the line PD, + or to put it another way, + the line PD, + is normal to q. + +

Unlike the traditional perspective construction, where the distance from + the focus to the center of vision fixes both the location of the focus + in space, and its distance to the + picture plane,1 + these two parameters can be set independently when the perspective + transformation is used. + The distance from a Focus to the picture plane is stored in the + data member distance, of type real. + +

A Focus can be declared using two Point arguments for + position and direction, and a real argument for + distance, in that order. + +

     Point pos(0, 5, -10);
+      Point dir(0, 5, 10);
+      Focus f(pos, dir, 10);
+      
+      Point center(2, 0, 3);
+      Rectangle r(center, 3, 3);
+      r.draw();
+      current_picture.output(f);
+ 
+

+
+ [Figure 60. Not displayed.] +
+
+ Fig. 60. +
+

+ +

The “up” direction is calculated by the Focus constructor + automatically. An optional argument can be used to specify the angle by + which to rotate the Focus about + the line PD. + +

     Point pos(0, 5, -10);
+      Point dir(0, 5, 10);
+      Focus f(pos, dir, 10, 30);
+      Point center(2, 0, 3);
+      Rectangle r(center, 3, 3);
+      r.draw();
+      current_picture.output(f);
+ 
+

+
+ [Figure 61. Not displayed.] +
+
+ Fig. 61. +
+

+ +

Alternatively, a Focus can be declared using three real + arguments each for the x, y, and z-coordinates of position and + direction, respectively, followed by the real arguments + for distance and the angle of rotation: + +

     Focus f(3, 5, -5, 0, 3, 0, 10, 10);
+      Point center(2, 0, 3);
+      Rectangle r(center, 3, 3);
+      r.draw();
+      current_picture.output(f);
+ 
+

+
+ [Figure 62. Not displayed.] +
+
+ Fig. 62. +
+

+ +

Focuses contain two Transforms, transform and persp. + A Focus can be located anywhere in 3DLDF's coordinate system. + However, performing the perspective projection is more convenient, if + position and direction both lie on one of the major axes, + and the plane of projection corresponds to one of the major planes. + transform is the transformation which would have this affect on + the Focus, and is calculated by the Focus constructor. + When a Picture is output using that Focus, + transform is applied to all of the Shapes on the + Picture, maintaining the relationship between the Focus + and the Shapes, while making it easier to calculate the + projection. The Focus need never be + transformed by transform. + The actual perspective transformation is stored + in persp. + +

Focuses can be moved by using one of the setting functions, which + take the same arguments as the constructors. + + Currently, there are no affine transformation functions for moving + Focuses, but I plan to add them soon. If 3DLDF is used for + making + animation, resetting the Focus can be used to simulate camera + movements: + +

     beginfig(1);
+      Point pos(2, 10, 3);
+      Point dir(2, -10, 3);
+      Focus f;
+      Point center(2, 0, 3);
+      for (int i = 0; i < 5; ++i)
+        {
+          f.set(pos, dir, 10, (15 * i));
+          Rectangle r(center, 3, 3);
+          r.draw();
+          current_picture.output(f);
+          current_picture.clear();
+          pos.shift(1, 1, 0);
+          dir.rotate(0, 0, 10);
+        }
+      endfig(1);
+ 
+

+
+ [Figure 63. Not displayed.] +
+
+ Fig. 63. +
+

+ +

In [the previous figure] + , current_picture is output 5 times within a single + MetaPost figure. Since the file passed to MetaPost is called + persp.mp, the file of Encapsulated PostScript (EPS) code + containing [the previous figure] + is called persp.1. + To use this technique for making an animation, it's necessary to output + the Picture into multiple MetaPost figures. + +

     Point pos(2, 10, 3);
+      Point dir(2, -10, 3);
+      Focus f;
+      Point center(2, 0, 3);
+      for (int i = 0; i < 5; ++i)
+        {
+          f.set(pos, dir, 10, (15 * i));
+          Rectangle r(center, 3, 3);
+          r.draw();
+          beginfig(i+1);
+          current_picture.output(f);
+          endfig();
+          current_picture.clear();
+          pos.shift(1, 1, 0);
+          dir.rotate(0, 0, 10);
+        }
+ 
+

Now, running MetaPost on persp.mp generates the EPS files + persp.1, persp.2, persp.3, persp.4, and + persp.5, containing the five separate drawings of r. + + + +

+
+

Footnotes

[1] I believe this + to be true, but I'm not + certain.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Function-Index.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Function-Index.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Function-Index.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Function-Index.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,473 ---- + + + Function Index - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Data Type and Variable Index, + Up: Top +


+
+ +

Function Index

+ + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Future-Plans.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Future-Plans.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Future-Plans.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Future-Plans.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,81 ---- + + + Future Plans - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Adding a File, + Up: Top +


+
+ +

40 Future Plans

+ +

3DLDF is a work-in-progress. In fact, it can never be + finished, because the supply of interesting geometric constructions + is inexhaustible. However, presently 3DLDF still has a number of major + gaps. + +

If you're interesting in contributing to 3DLDF, with respect to one of + the topics below and in the following sections, or if you have ideas + of your own, see Contributing to 3DLDF. + +

    +
  • Input routine. + The lack of one is the most significant + defect in 3DLDF, as mentioned in No Input Routine. + +
  • Port to other platforms. + See Ports. +
+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/GNU-Free-Documentation-License.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/GNU-Free-Documentation-License.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/GNU-Free-Documentation-License.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/GNU-Free-Documentation-License.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,531 ---- + + + GNU Free Documentation License - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Bibliography, + Up: Top +


+
+ +

Appendix A GNU Free Documentation License

+ + +
Version 1.3, 3 November 2008
+ + + +
     Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+      http://fsf.org/
+      
+      Everyone is permitted to copy and distribute verbatim copies
+      of this license document, but changing it is not allowed.
+ 
+
    +
  1. PREAMBLE + +

    The purpose of this License is to make a manual, textbook, or other + functional and useful document free in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or noncommercially. + Secondarily, this License preserves for the author and publisher a way + to get credit for their work, while not being considered responsible + for modifications made by others. + +

    This License is a kind of “copyleft”, which means that derivative + works of the document must themselves be free in the same sense. It + complements the GNU General Public License, which is a copyleft + license designed for free software. + +

    We have designed this License in order to use it for manuals for free + software, because free software needs free documentation: a free + program should come with manuals providing the same freedoms that the + software does. But this License is not limited to software manuals; + it can be used for any textual work, regardless of subject matter or + whether it is published as a printed book. We recommend this License + principally for works whose purpose is instruction or reference. + +

  2. APPLICABILITY AND DEFINITIONS + +

    This License applies to any manual or other work, in any medium, that + contains a notice placed by the copyright holder saying it can be + distributed under the terms of this License. Such a notice grants a + world-wide, royalty-free license, unlimited in duration, to use that + work under the conditions stated herein. The “Document”, below, + refers to any such manual or work. Any member of the public is a + licensee, and is addressed as “you”. You accept the license if you + copy, modify or distribute the work in a way requiring permission + under copyright law. + +

    A “Modified Version” of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + +

    A “Secondary Section” is a named appendix or a front-matter section + of the Document that deals exclusively with the relationship of the + publishers or authors of the Document to the Document's overall + subject (or to related matters) and contains nothing that could fall + directly within that overall subject. (Thus, if the Document is in + part a textbook of mathematics, a Secondary Section may not explain + any mathematics.) The relationship could be a matter of historical + connection with the subject or with related matters, or of legal, + commercial, philosophical, ethical or political position regarding + them. + +

    The “Invariant Sections” are certain Secondary Sections whose titles + are designated, as being those of Invariant Sections, in the notice + that says that the Document is released under this License. If a + section does not fit the above definition of Secondary then it is not + allowed to be designated as Invariant. The Document may contain zero + Invariant Sections. If the Document does not identify any Invariant + Sections then there are none. + +

    The “Cover Texts” are certain short passages of text that are listed, + as Front-Cover Texts or Back-Cover Texts, in the notice that says that + the Document is released under this License. A Front-Cover Text may + be at most 5 words, and a Back-Cover Text may be at most 25 words. + +

    A “Transparent” copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images composed of + pixels) generic paint programs or (for drawings) some widely available + drawing editor, and that is suitable for input to text formatters or + for automatic translation to a variety of formats suitable for input + to text formatters. A copy made in an otherwise Transparent file + format whose markup, or absence of markup, has been arranged to thwart + or discourage subsequent modification by readers is not Transparent. + An image format is not Transparent if used for any substantial amount + of text. A copy that is not “Transparent” is called “Opaque”. + +

    Examples of suitable formats for Transparent copies include plain + ascii without markup, Texinfo input format, LaTeX input + format, SGML or XML using a publicly available + DTD, and standard-conforming simple HTML, + PostScript or PDF designed for human modification. Examples + of transparent image formats include PNG, XCF and + JPG. Opaque formats include proprietary formats that can be + read and edited only by proprietary word processors, SGML or + XML for which the DTD and/or processing tools are + not generally available, and the machine-generated HTML, + PostScript or PDF produced by some word processors for + output purposes only. + +

    The “Title Page” means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the material + this License requires to appear in the title page. For works in + formats which do not have any title page as such, “Title Page” means + the text near the most prominent appearance of the work's title, + preceding the beginning of the body of the text. + +

    The “publisher” means any person or entity that distributes copies + of the Document to the public. + +

    A section “Entitled XYZ” means a named subunit of the Document whose + title either is precisely XYZ or contains XYZ in parentheses following + text that translates XYZ in another language. (Here XYZ stands for a + specific section name mentioned below, such as “Acknowledgements”, + “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” + of such a section when you modify the Document means that it remains a + section “Entitled XYZ” according to this definition. + +

    The Document may include Warranty Disclaimers next to the notice which + states that this License applies to the Document. These Warranty + Disclaimers are considered to be included by reference in this + License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and has + no effect on the meaning of this License. + +

  3. VERBATIM COPYING + +

    You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License applies + to the Document are reproduced in all copies, and that you add no other + conditions whatsoever to those of this License. You may not use + technical measures to obstruct or control the reading or further + copying of the copies you make or distribute. However, you may accept + compensation in exchange for copies. If you distribute a large enough + number of copies you must also follow the conditions in section 3. + +

    You may also lend copies, under the same conditions stated above, and + you may publicly display copies. + +

  4. COPYING IN QUANTITY + +

    If you publish printed copies (or copies in media that commonly have + printed covers) of the Document, numbering more than 100, and the + Document's license notice requires Cover Texts, you must enclose the + copies in covers that carry, clearly and legibly, all these Cover + Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on + the back cover. Both covers must also clearly and legibly identify + you as the publisher of these copies. The front cover must present + the full title with all words of the title equally prominent and + visible. You may add other material on the covers in addition. + Copying with changes limited to the covers, as long as they preserve + the title of the Document and satisfy these conditions, can be treated + as verbatim copying in other respects. + +

    If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto adjacent + pages. + +

    If you publish or distribute Opaque copies of the Document numbering + more than 100, you must either include a machine-readable Transparent + copy along with each Opaque copy, or state in or with each Opaque copy + a computer-network location from which the general network-using + public has access to download using public-standard network protocols + a complete Transparent copy of the Document, free of added material. + If you use the latter option, you must take reasonably prudent steps, + when you begin distribution of Opaque copies in quantity, to ensure + that this Transparent copy will remain thus accessible at the stated + location until at least one year after the last time you distribute an + Opaque copy (directly or through your agents or retailers) of that + edition to the public. + +

    It is requested, but not required, that you contact the authors of the + Document well before redistributing any large number of copies, to give + them a chance to provide you with an updated version of the Document. + +

  5. MODIFICATIONS + +

    You may copy and distribute a Modified Version of the Document under + the conditions of sections 2 and 3 above, provided that you release + the Modified Version under precisely this License, with the Modified + Version filling the role of the Document, thus licensing distribution + and modification of the Modified Version to whoever possesses a copy + of it. In addition, you must do these things in the Modified Version: + +

      +
    1. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. + +
    2. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. + +
    3. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + +
    4. Preserve all the copyright notices of the Document. + +
    5. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + +
    6. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. + +
    7. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. + +
    8. Include an unaltered copy of this License. + +
    9. Preserve the section Entitled “History”, Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled “History” in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. + +
    10. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the “History” section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. + +
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve + the Title of the section, and preserve in the section all the + substance and tone of each of the contributor acknowledgements and/or + dedications given therein. + +
    12. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. + +
    13. Delete any section Entitled “Endorsements”. Such a section + may not be included in the Modified Version. + +
    14. Do not retitle any existing section to be Entitled “Endorsements” or + to conflict in title with any Invariant Section. + +
    15. Preserve any Warranty Disclaimers. +
    + +

    If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no material + copied from the Document, you may at your option designate some or all + of these sections as invariant. To do this, add their titles to the + list of Invariant Sections in the Modified Version's license notice. + These titles must be distinct from any other section titles. + +

    You may add a section Entitled “Endorsements”, provided it contains + nothing but endorsements of your Modified Version by various + parties—for example, statements of peer review or that the text has + been approved by an organization as the authoritative definition of a + standard. + +

    You may add a passage of up to five words as a Front-Cover Text, and a + passage of up to 25 words as a Back-Cover Text, to the end of the list + of Cover Texts in the Modified Version. Only one passage of + Front-Cover Text and one of Back-Cover Text may be added by (or + through arrangements made by) any one entity. If the Document already + includes a cover text for the same cover, previously added by you or + by arrangement made by the same entity you are acting on behalf of, + you may not add another; but you may replace the old one, on explicit + permission from the previous publisher that added the old one. + +

    The author(s) and publisher(s) of the Document do not by this License + give permission to use their names for publicity for or to assert or + imply endorsement of any Modified Version. + +

  6. COMBINING DOCUMENTS + +

    You may combine the Document with other documents released under this + License, under the terms defined in section 4 above for modified + versions, provided that you include in the combination all of the + Invariant Sections of all of the original documents, unmodified, and + list them all as Invariant Sections of your combined work in its + license notice, and that you preserve all their Warranty Disclaimers. + +

    The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name but + different contents, make the title of each such section unique by + adding at the end of it, in parentheses, the name of the original + author or publisher of that section if known, or else a unique number. + Make the same adjustment to the section titles in the list of + Invariant Sections in the license notice of the combined work. + +

    In the combination, you must combine any sections Entitled “History” + in the various original documents, forming one section Entitled + “History”; likewise combine any sections Entitled “Acknowledgements”, + and any sections Entitled “Dedications”. You must delete all + sections Entitled “Endorsements.” + +

  7. COLLECTIONS OF DOCUMENTS + +

    You may make a collection consisting of the Document and other documents + released under this License, and replace the individual copies of this + License in the various documents with a single copy that is included in + the collection, provided that you follow the rules of this License for + verbatim copying of each of the documents in all other respects. + +

    You may extract a single document from such a collection, and distribute + it individually under this License, provided you insert a copy of this + License into the extracted document, and follow this License in all + other respects regarding verbatim copying of that document. + +

  8. AGGREGATION WITH INDEPENDENT WORKS + +

    A compilation of the Document or its derivatives with other separate + and independent documents or works, in or on a volume of a storage or + distribution medium, is called an “aggregate” if the copyright + resulting from the compilation is not used to limit the legal rights + of the compilation's users beyond what the individual works permit. + When the Document is included in an aggregate, this License does not + apply to the other works in the aggregate which are not themselves + derivative works of the Document. + +

    If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half of + the entire aggregate, the Document's Cover Texts may be placed on + covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic form. + Otherwise they must appear on printed covers that bracket the whole + aggregate. + +

  9. TRANSLATION + +

    Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section 4. + Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also include + the original English version of this License and the original versions + of those notices and disclaimers. In case of a disagreement between + the translation and the original version of this License or a notice + or disclaimer, the original version will prevail. + +

    If a section in the Document is Entitled “Acknowledgements”, + “Dedications”, or “History”, the requirement (section 4) to Preserve + its Title (section 1) will typically require changing the actual + title. + +

  10. TERMINATION + +

    You may not copy, modify, sublicense, or distribute the Document + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense, or distribute it is void, and + will automatically terminate your rights under this License. + +

    However, if you cease all violation of this License, then your license + from a particular copyright holder is reinstated (a) provisionally, + unless and until the copyright holder explicitly and finally + terminates your license, and (b) permanently, if the copyright holder + fails to notify you of the violation by some reasonable means prior to + 60 days after the cessation. + +

    Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from that + copyright holder, and you cure the violation prior to 30 days after + your receipt of the notice. + +

    Termination of your rights under this section does not terminate the + licenses of parties who have received copies or rights from you under + this License. If your rights have been terminated and not permanently + reinstated, receipt of a copy of some or all of the same material does + not give you any rights to use it. + +

  11. FUTURE REVISIONS OF THIS LICENSE + +

    The Free Software Foundation may publish new, revised versions + of the GNU Free Documentation License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. See + http://www.gnu.org/copyleft/. + +

    Each version of the License is given a distinguishing version number. + If the Document specifies that a particular numbered version of this + License “or any later version” applies to it, you have the option of + following the terms and conditions either of that specified version or + of any later version that has been published (not as a draft) by the + Free Software Foundation. If the Document does not specify a version + number of this License, you may choose any version ever published (not + as a draft) by the Free Software Foundation. If the Document + specifies that a proxy can decide which future versions of this + License can be used, that proxy's public statement of acceptance of a + version permanently authorizes you to choose that version for the + Document. + +

  12. RELICENSING + +

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any + World Wide Web server that publishes copyrightable works and also + provides prominent facilities for anybody to edit those works. A + public wiki that anybody can edit is an example of such a server. A + “Massive Multiauthor Collaboration” (or “MMC”) contained in the + site means any set of copyrightable works thus published on the MMC + site. + +

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 + license published by Creative Commons Corporation, a not-for-profit + corporation with a principal place of business in San Francisco, + California, as well as future copyleft versions of that license + published by that same organization. + +

    “Incorporate” means to publish or republish a Document, in whole or + in part, as part of another Document. + +

    An MMC is “eligible for relicensing” if it is licensed under this + License, and if all works that were first published under this License + somewhere other than this MMC, and subsequently incorporated in whole + or in part into the MMC, (1) had no cover texts or invariant sections, + and (2) were thus incorporated prior to November 1, 2008. + +

    The operator of an MMC Site may republish an MMC contained in the site + under CC-BY-SA on the same site at any time before August 1, 2009, + provided the MMC is eligible for relicensing. + +

+ +

ADDENDUM: How to use this License for your documents

+ +

To use this License in a document you have written, include a copy of + the License in the document and put the following copyright and + license notices just after the title page: + +

       Copyright (C)  year  your name.
+        Permission is granted to copy, distribute and/or modify this document
+        under the terms of the GNU Free Documentation License, Version 1.3
+        or any later version published by the Free Software Foundation;
+        with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+        Texts.  A copy of the license is included in the section entitled ``GNU
+        Free Documentation License''.
+ 
+

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, + replace the “with...Texts.” line with this: + +

         with the Invariant Sections being list their titles, with
+          the Front-Cover Texts being list, and with the Back-Cover Texts
+          being list.
+ 
+

If you have Invariant Sections without Cover Texts, or some other + combination of the three, merge those two alternatives to suit the + situation. + +

If your document contains nontrivial examples of program code, we + recommend releasing these examples in parallel under your choice of + free software license, such as the GNU General Public License, + to permit their use in free software. + + + + + + + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Geometry.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Geometry.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Geometry.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Geometry.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,117 ---- + + + Geometry - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Future Plans, + Up: Future Plans +


+
+ +

40.1 Geometry

+ +

3DLDF currently provides a set of basic plane and solid geometrical + figures. However, some important ones are still missing. + There are many useful geometrical data types and functions whose + implementation would require no more than elementary geometry. + +

    +
  • Add constructors with a normal vector argument rather than angles of + rotation about the main axes. + +
  • I have started defining class Triangle, which can be used for + calculating triangle solutions. + +
  • Add a class Conic_Section and derive Ellipse + from it. This will be the first case of + multiple inheritance1 + in 3DLDF, since Ellipse is already + derived from Path. See Ellipse Reference. + Add the classes Parabola and Hyperbola. + +
  • Add more functions for finding the intersections of objects of various + types, starting with the plane figures. + In particular, I believe I've found an algebraic solution for + the intersection of an Ellipse and a Circle in a plane, + but I haven't had a chance to try implementing it yet. + +

    If this works, I think it will make it possible to find the intersection + of two coplanar ellipses algebraically, because it will be possible to + transform them both such that one of them becomes circular. + +

  • Class Octahedron will complete the set of regular Platonic + polyhedra. + +
  • Add classes for the Kepler-Poinsot polyhedra, the semi-regular + Archimedean polyhedra, the dual solids, the stellated Archimedean + polyhedra, and the regular compounds.2 + +
  • Add class Ellipsoid and a derived class Sphere. + +
  • Improve the specification of Solid and + Solid_Faced. + In particular, it would help to store the vertices of + Polyhedra as individual Points, rather + than using Reg_Polygons. I'd also + like to find a better way of generating Solids, without using + rotations, if possible. + +
+ +
+
+

Footnotes

[1] Stroustrup, The C++ + Programming Language, + &sect;15.2 + “Multiple Inheritance”, pp. 390–92.

+ +

[2] Cundy and Rollet, Mathematical Models, Chapter 3, + “Polyhedra”, pp. 76–160.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Get-Path.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Get-Path.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Get-Path.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Get-Path.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,64 ---- + + + Get Path - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Line Operators, + Up: Line Reference +


+
+ +

24.5 Get Path

+ +
+ — const function: Path get_path (void)
+

Returns a linear Path with two Points + on the Line. The first Point will be position, and + the second will be position + direction. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Get-Second-Largest-Real.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Get-Second-Largest-Real.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Get-Second-Largest-Real.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Get-Second-Largest-Real.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,100 ---- + + + Get Second Largest Real - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Register Width, + Up: System Information +


+
+ +

15.3 Get Second Largest Real

+ +
+ — Template function: template <class Real> Real get_second_largest (Real MAX_VAL, [bool verbose = false])
+ — Template specialization: float get_second_largest (float, bool)
+ — Template specialization: double get_second_largest (double, bool)
+

get_second_largest returns the second largest floating point + number of the type specified the template paramater Real. + If verbose is true, messages are printed to standard + output. + +

This function is used for setting the value of MAX_REAL. + See Global Constants and Variables. + +

get_second_largest depends on there + being an unsigned integer type with the same length as Real. + This should always be the case for float and double, but + may not be long double. + +

MAX_VAL should be the largest number of type Real on a given + architecture. The GNU C++ + compiler GCC 3.3 does not currently supply + the numeric_limits template, so it is necessary to pass + one of the macros FLT_MAX or DBL_MAX explicitly, depending + on which specialization you use1. + When and if GCC supplies the numeric_limits template, I will + eliminate the MAX_REAL argument. +

+ + + + + + +
+
+

Footnotes

[1] If your system supplies an unsigned integer type with the same + length as long double, then you can instantiate + get_second_largest<long double>() and call + ‘get_second_largest<long double>(LDBL_MAX)’. However, I doubt + that this amount of precision would be worthwhile. If it ever were + required, 3DLDF would have to be changed in other ways, too. In + particular, it would have to use more precise trigonometric functions + for rotations. See Accuracy.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Getting-Shape-Centers-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Getting-Shape-Centers-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Getting-Shape-Centers-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Getting-Shape-Centers-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,131 ---- + + + Getting Shape Centers Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

Getting Shape Centers

+ +
+ — const virtual function: const Point& get_shape_center (const unsigned short shape_type, const unsigned short s)
+

Returns the center of a Shape belonging to the Solid. + Currently, the object can be a Circle, Ellipse, + Rectangle, or Reg_Polygon, and it is accessed through a pointer + on one of the following vectors of pointers to Shape: + circles, ellipses, + rectangles, or reg_polygons. + The type of + object is specified + using the shape_type argument. + The following public static const data members of Solid + can (and probably should) be passed as the shape_type argument: + CIRCLE, ELLIPSE, RECTANGLE, and + REG_POLYGON. + +

The argument s is used to index the vector. + +

This function is called within the more specialized functions in this + section, namely: get_circle_center(), + get_ellipse_center(), get_rectangle_center(), and + get_reg_polygon_center(). I don't expect it to be needed in user + code very often. + +

          Dodecahedron d(origin, 3);
+           d.filldraw();
+           Point C = d.get_shape_center(Solid::REG_POLYGON, 1);
+           C.dotlabel("C");
+ 
+

+
+ [Figure 182. Not displayed.] +
+
+ Fig. 182. +
+

+ + +

Note that this function will have to be changed, if new vectors of + Shape pointers are added to class Solid! +

+ +
+ — const virtual functions: const Point& get_circle_center (const unsigned short s)
+ — : const Point& get_ellipse_center (const unsigned short s)
+ — : const Point& get_rectangle_center (const unsigned short s)
+ — : const Point& get_reg_polygon_center (const unsigned short s)
+

These functions all return the center of the Shape pointed to by a pointer on + one of the vectors of Shapes belonging to the Solid. The argument s + indicates which element on the vector is to be accessed. For example, + get_rectangle_center(2) returns the center of the + Rectangle pointed to by rectangles[2]. + +

          Cuboid c(origin, 3, 4, 5, 0, 30);
+           c.draw();
+           for (int i = 0; i < 6; ++i)
+             c.get_rectangle_center(i).label(i, "");
+ 
+

+
+ [Figure 183. Not displayed.] +
+
+ Fig. 183. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Getting-Shapes-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Getting-Shapes-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Getting-Shapes-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Getting-Shapes-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,140 ---- + + + Getting Shapes Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +

Getting Shapes

+ +

The functions in this section + all return const pointers to Shape, or one of its derived + classes. Therefore, they must be invoked in such a way, that + the const qualifier is not discarded. See + the description of get_reg_polygon_ptr() below, for an example. + +

+ — const virtual function: Shape* get_shape_ptr (const unsigned short shape_type, const unsigned short s)
+

Copies one of the objects belonging to the Solid, and returns a + pointer to Shape that points to the copy. + The object is found by dereferencing one of the pointers on one of the + vectors of pointers belonging to the Solid. + Currently, these + vectors are circles, ellipses, paths, + rectangles, and reg_polygons. The argument + shape_type specifies the vector, and the + argument s specifies which element of the vector should be + accessed. The following public static const data members of + Solid can (and probably should) be passed as the shape_type + argument: CIRCLE, ELLIPSE, PATH, RECTANGLE, + and REG_POLYGON. + +

This function was originally intended to be called within the more + specialized functions in this + section, namely: get_circle_ptr(), get_ellipse_ptr(), + get_path_ptr(), get_rectangle_ptr, and get_reg_polygon_ptr. + However, these functions no longer use get_shape_ptr(), so this + function is probably no longer needed. + +

          Icosahedron I(origin, 3);
+           I.filldraw();
+           Reg_Polygon* t =
+           static_cast<Reg_Polygon*>(I.get_shape_ptr(Solid::REG_POLYGON, 9));
+           t->fill(gray);
+ 
+

+
+ [Figure 184. Not displayed.] +
+
+ Fig. 184. +
+

+ +
+ +
+ — const virtual functions: const Reg_Polygon* get_circle_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_ellipse_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_path_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_rectangle_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_reg_polygon_ptr (const unsigned short s)
+

Each of these functions returns a pointer from one of the vectors of + Shape pointers belonging to the Solid. The argument s + specifies which element of the appropriate vector should be returned. + For example, get_reg_polygon_ptr(2) returns the Reg_Polygon* + in reg_polygons[2]. + +

Since these functions return const pointers, they must be invoked + in such a way, that the const qualifier is not discarded, as + noted at the beginning of this section. The following example + demonstrates two ways of invoking get_reg_polygon_ptr(): + +

          Dodecahedron d(origin, 3);
+           d.draw();
+           const Reg_Polygon* ptr = d.get_reg_polygon_ptr(0);
+           ptr->draw(black, "evenly scaled 4", "pencircle scaled 1mm");
+           Reg_Polygon A = *d.get_reg_polygon_ptr(5);
+           A.fill(gray);
+ 
+

+
+ [Figure 185. Not displayed.] +
+
+ Fig. 185. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Global-Constants-and-Variables.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Global-Constants-and-Variables.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Global-Constants-and-Variables.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Global-Constants-and-Variables.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,194 ---- + + + Global Constants and Variables - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Typedefs and Utility Structures, + Up: Top +


+
+ +

13 Global Constants and Variables

+ +

The global constants and variables described in this chapter are + found in pspglb.web. Others, of types + defined in 3DLDF, are described in subsequent chapters. + +

+ — Constants: bool ldf_real_float
+ — : bool ldf_real_double
+

Set to 0 or 1 to match the values of the preprocessor macros + LDF_REAL_FLOAT and LDF_REAL_DOUBLE. The latter are used + for conditional compilation and determine whether real is + “typedeffed” to float or double, i.e., whether + real is made to be a synonym of float or double + using typedef. + +

ldf_real_float and ldf_real_double can be used to control + conditional expressions in non-conditionally compiled code. +

+ +
+ — Constant: real PI
+

The value of PI + is calculated as + 4.0 * arctan(1.0). + I believe that a preprocessor macro “PI” was + available when I compiled 3DLDF using the DEC C++ + compiler, and that + it wasn't, when I used GNU CC under Linux, but I'm no longer sure. +

+ +
+ — Variable: valarray <real> null_coordinates
+

Contains four elements, all 0. Used for resetting the sets of + coordinates belonging to Points, but only when the DEC C++ + +

compiler is used. This doesn't work when GCC is used. +

+ +
+ — Constant: real INVALID_REAL
+

Actually, INVALID_REAL is the largest possible real value + (i.e., float or double) on a given machine. + So, from the point of view of the compiler, it's not invalid at all. + However, 3DLDF uses it to indicate failure of some kind. For example, + the return value of a function returning real can be compared + with INVALID_REAL to check whether the function succeeded or + failed. + +

An alternative approach would be to use the exception handling + facilities of C++ + . I do use these, but only in a couple of places, + so far. +

+ +
+ — Constant: real_pair INVALID_REAL_PAIR
+

first and second are both INVALID_REAL. +

+ +
+ — Constant: real INVALID_REAL_SHORT
+

first is INVALID_REAL and second is 0. +

+ +
+ — Variable: real MAX_REAL
+

The largest real value permitted in the the elements of + Transforms and the coordinates of + Points. It is the second largest real value (i.e., + float or double) on a given machine (INVALID_REAL + is the largest). + +

MAX_REAL is a variable, but it should be used like a constant. + In other words, users should never reset its value. It can't be + declared const because its value must be calculated using + function calls, which can't be done before the entry point of the + program, i.e., main(). Therefore, the value of MAX_REAL + is calculated at the beginning of main(). +

+ +
+ — Variable: real MAX_REAL_SQRT
+

The square root of MAX_REAL. + +

MAX_REAL_SQRT is a variable, but it should be used like a + constant. In other words, users should never reset its value. It can't + be declared const because its value is calculated using the + sqrt() function, + which can't be done before the entry point of the + program, i.e., main(). Therefore, the value of + MAX_REAL_SQRT is set after MAX_REAL is calculated, at the + beginning of main(). + +

MAX_REAL_SQRT is used in Point::magnitude() + (see Vector Operations). The magnitude of a Point is found + by using the formula + \sqrtx^2 + y^2 + z^2. + x, y, and z are all tested against + MAX_REAL_SQRT to ensure that + x^2, y^2, and z^2 + will all be + less than or equal to MAX_REAL before trying to calculate them. + + +

Metafont implements an operation called Pythagorean addition, + notated as “++”which + can be used to calculate distances without first squaring and then + taking square roots: + 1 + a++b == \sqrt(a^2 + b^2) + and + a++b++c == \sqrt(a^2 + b^2 + c^2). + This makes it possible to calculate distances for greater values of + a, b, and c, that would otherwise cause floating point errors. + Metafont also implements the inverse operation + Pythagorean subtraction, notated as “+-+”: + + + + + + + a+-+b == \sqrt(a^2 - b^2). + Unfortunately, 3DLDF implements neither Pythagorean addition + nor subtraction as yet, but it's on my + list of “things to do”. +

+ + + + + + +
+
+

Footnotes

[1] Knuth, Donald E. The Metafontbook, p. 66.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/I_002fO-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/I_002fO-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/I_002fO-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/I_002fO-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,92 ---- + + + I/O Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ + +

+ Previous: I/O Global Variables, + Up: Input and Output +


+
+ +

17.2 I/O Functions

+ +
+ — Function: void initialize_io (string in_stream_name, string out_stream_name, string tex_stream_name, char* program_name)
+

Opens files with names specified by the first three arguments, and + attaches them to the file streams in_stream, out_stream, and + tex_stream, respectively. Comments are written at the beginning + of the files, containing their names, a datestamp, and the name of the + program used to generate them. +

+ +
+ — Function: void write_footers (void)
+

Writes code at the end of the files attached to in_stream, + out_stream, and tex_stream, before the streams are + closed. Currently, they write comments containing + local variable lists + for use in + Emacs. +

+ +
+ — Inline function: void beginfig (unsigned short i)
+

Writes “beginfig(i)” to out_stream. +

+ +
+ — Inline function: void endfig ([unsigned short i = 0])
+

Writes “endfig()” to out_stream. The argument i + is “syntactic sugar”; it's ignored by endfig(), + but may help the user keep track of what figure is being ended. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/I_002fO-Global-Variables.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/I_002fO-Global-Variables.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/I_002fO-Global-Variables.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/I_002fO-Global-Variables.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,83 ---- + + + I/O Global Variables - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ + +

+ Next: , + Previous: Input and Output, + Up: Input and Output +


+
+ +

17.1 Global Variables

+ +
+ — Variable: ifstream in_stream
+

Intended for inputting files of input code. However, 3DLDF does not + currently have a routine for reading input code. + in_stream is currently attached to the file ldfinput.ldf + by initialize_io() (see I/O Functions). + in_stream is read in character-by-character in main(), + however this serves no useful purpose as yet. +

+ +
+ — Variable: ofstream out_stream
+

Used for writing the file of MetaPost code, which is 3DLDF's output. + Currently attached to the file subpersp.mp by + initialize_io() (see I/O Functions). +

+ +
+ — Variable: ofstream tex_stream
+

TeX code can be written to a file through tex_stream, if + desired. 3DLDF makes no use of it itself. + Currently attached to subpersp.tex by + initialize_io() (see I/O Functions). +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,101 ---- + + + Icosahedron Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Icosahedron Data Members, + Up: Icosahedron +


+
+ +
37.2.3.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Icosahedron (void)
+

Creates an empty Icosahedron. +

+ +
+ — Constructor: void Icosahedron (const Point& p, const real diameter_of_triangle, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Creates an Icosahedron with its center at the origin, where the + triangular faces have enclosing circles of diameter + diameter_of_triangle. If any of angle_x, angle_y, or + angle_z is non-zero, the Icosahedron is rotated by the + amounts specified around the corresponding axes. Finally, if p is + not the origin, the Icosahedron is shifted such that + center comes to lie at p. + +

          Icosahedron i(origin, 3, 0, 10);
+           i.draw();
+ 
+

+
+ [Figure 195. Not displayed.] +
+
+ Fig. 195. +
+

+ +
          i.filldraw();
+ 
+

+
+ [Figure 196. Not displayed.] +
+
+ Fig. 196. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,73 ---- + + + Icosahedron Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +
37.2.3.1 Data Members
+ +
+ — Protected static const variable: real dihedral_angle
+

The angle between the faces of the Icosahedron, namely + 138 degrees + 11' + = \pi - \arcsin(2/3). + +

+ +
+ — Protected variable: real triangle_radius
+

The radius of the circle enclosing a triangular face of + the Icosahedron. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,133 ---- + + + Icosahedron Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Dodecahedron Getstart, + Up: Polyhedron Getstart +


+
+ +

8.2.3 Icosahedron

+ +

An icosahedron has 20 similar regular triangular faces. + The following examples show the same Icosahedron using different + projections: + +

     default_focus.set(3, 0, -10, 2, 0, 10, 10);
+      Icosahedron i(origin, 3);
+      i.draw();
+ 
+

+
+ [Figure 45. Not displayed.] +
+
+ Fig. 45. +
+

+ + +

+
+ [Figure 46. Not displayed.] +
+
+ Fig. 46. +
+

+ + +

+
+ [Figure 47. Not displayed.] +
+
+ Fig. 47. +
+

+ + +

+
+ [Figure 48. Not displayed.] +
+
+ Fig. 48. +
+

+ + +

In [next figure] + , i is filldrawn. In this case, + the surface hiding algorithm has worked properly. + See Surface Hiding. + +

+
+ [Figure 49. Not displayed.] +
+
+ Fig. 49. +
+

+ + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Net.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Net.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron-Net.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron-Net.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,115 ---- + + + Icosahedron Net - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +
37.2.3.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real triangle_diameter, [bool do_half = false])
+

Returns the net, i.e., the two-dimensional pattern of triangles + that can be folded into a model of an icosahedron. The net lies + in the x-z plane. The triangles have enclosing circles of diameter + triangle_diameter. + If the argument do_half = true, only the first half of the + net is created. This is used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Icosahedron; Constructors and Setting Functions. + +

          vector<Reg_Polygon*> vrp = Icosahedron::get_net(1.5);
+           for (vector<Reg_Polygon*>::iterator iter = vrp.begin();
+                iter != vrp.end(); ++iter)
+              (**iter).draw();
+ 
+

+
+ [Figure 197. Not displayed.] +
+
+ Fig. 197. +
+

+ +
+ +
+ — Static function: void draw_net (const real triangle_diameter, [bool portrait = true, [bool make_tabs = true]])
+

Draws the net for an Icosahedron in the x-z plane. The triangles + have enclosing circles of diameter triangle_diameter. + If the argument portrait is true (the default), the net + will be arranged for printing in portrait format. If it's false, + it will be arranged for printing in landscape format. + In portrait format, the center of the bottom right triangle is at the + origin. In landscape format, the center of the bottom left + triangle is at the origin. The triangles are numbered. + +

The argument make_tabs currently has no effect. + When I get around to programming this, it will be used for specifying + whether tabs for gluing and/or sewing a cardboard model should be drawn, + too. + +

          Icosahedron::draw_net(2, false);
+ 
+

+
+ [Figure 198. Not displayed.] +
+
+ Fig. 198. +
+

+ +
+ + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Icosahedron.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Icosahedron.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Icosahedron - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Dodecahedron, + Up: Regular Platonic Polyhedra +


+
+ +

37.2.3 Icosahedron

+ +

Class Icosahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

Icosahedra have 20 regular triangular faces. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Illustrations.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Illustrations.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Illustrations.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Illustrations.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,186 ---- + + + Illustrations - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Manual Conventions, + Up: About This Manual +


+
+ +

1.2.2 Illustrations

+ +

The illustrations in this manual have been created using 3DLDF. The + code that generates them is in the Texinfo files themselves, that + contain the text of the manual. Texinfo is based on TeX, so it's + possible to make use of the latter's facility for writing ASCII text to + files using TeX's \write command. + +

The file 3DLDF-1.1.5.1/CWEB/exampman.web contains the + C++ + code, and the file 3DLDF-1.1.5.1/CWEB/examples.mp + contains the MetaPost code for generating the illustrations. + 3DLDF was built using GCC 2.95 when the illustrations were generated. + For some reason, GCC 3.3 has difficulty with them. It works to generate + them in batches of about 50 with GCC 3.3. + +

MetaPost outputs Encapsulated PostScript files. These can be included + in TeX files, as explained below. However, in order to display the + illustrations in the HTML version of this manual, I had to convert them + to PNG (“Portable Network Graphics”) format. + See Converting EPS Files, for instructions on how to do this. + +

Please note that the illustrations cannot be shown in the Info output + format! + +

If you have problems including the illustrations in the printed version, + for example, if your + installation doesn't have dvips, look for the following lines + in 3DLDF.texi: + +

     \doepsftrue    %% One of these two lines should be commented-out.
+      %\doepsffalse
+ 
+

Now, remove the ‘%’ from in front of ‘\doepsffalse’ and put + one in front of ‘\doepsftrue’. This will prevent the illustrations + from being included. This should only be done as a last resort, + however, because it will make it difficult if + not impossible to understand this manual. + +

The C++ + code in an example is not always the complete code used to + create the illustration that follows it, since the latter may be + cluttered with commands that would detract from the clarity of the + example. The actual code used always follows the example in the Texinfo + source file, so the latter may be referred to, if the reader wishes + to see exactly what code was used to generate the illustration. + +

You may want to skip the following paragraphs in this section, if you're + reading this manual for the + first time. Don't worry if you don't understand it, it's meaning should + become clear after reading the manual and some experience with + using 3DLDF. + +

The file 3DLDF.texi in the directory + 3DLDF-1.1.5.1/DOC/TEXINFO, the driver file for this manual, contains + the following TeX code: + +

     \newif\ifmakeexamples
+      \makeexamplestrue     %% One of these two lines should be commented-out.
+      %\makeexamplesfalse
+ 
+

When texi2dvi is run on 3DLDF.texi, + \makeexamplestrue is not commented-out, and + \makeexamplesfalse is, + the C++ + code for the illustrations is written to the file + examples.web. + If the EPS files don't already exist (in the directory + 3DLDF-1.1.5.1/DOC/TEXINFO/EPS), + the TeX macro \PEX, + which includes them in the Texinfo files, will signal an error each time + it can't find one. Just type ‘s’ at the command line to tell + TeX to keep going. + If you want to be sure that these are indeed the only errors, you can + type ‘<RETURN>’ after each one instead. + +

texi2dvi 3DLDF.texi also generates the file + extext.tex, which contains TeX code for including the + illustrations by themselves. + +

examples.web must now be moved to 3DLDF-1.1.5.1/CWEB/ and + ctangled, examples.c must compiled, + and 3DLDF must be relinked. ctangle examples also generates + the header file example.h, which is included + in main.web. Therefore, if the contents of examples.h have + changed since the last time main.web was ctangled, + main.web will have to be ctangled, and main.c recompiled, + before 3dldf is relinked.1 + +

Running 3dldf and MetaPost now + generates the EPS (Encapsulated PostScript) files + 3DLDFmp.1 through (currently) 3DLDFmp.199 + for the illustrations. They must be moved to + 3DLDF-1.1.5.1/DOC/TEXINFO/EPS. + Now, when texi2dvi 3DLDF.texi is run again, the + dvips command + ‘\epsffile’ includes the EPS files for the illustrations in the + manual. 3DLDF.texi includes the line ‘\input epsf’, so + that ‘\epsffile’ works. + Of course, dvips (or some other program that does the + job) must be used to convert 3DLDF.dvi to a PostScript file. + To see exactly how this is done, take a look at the + .texi source files of this manual.2 + +

In the 3DLDF.texi belonging to the 3DLDF distribution, + \makeexamplestrue will be commented-out, and + makeexamplesfalse won't be, because the EPS files for the + illustrations are included in the distribution. + +

The version of examples.web in 3DLDF-1.1.5.1/CWEB merely + includes the files subex1.web and subex2.web. + If you rename 3DLDF-1.1.5.1/CWEB/exampman.web to examples.web, + you can generate the illustrations. + +

+
+

Footnotes

[1] ctangle creates + <filename>.c from + <filename>.web, + so the compiler must compile the C++ + files + using the -x c++ option. Otherwise, it would handle them as if + they contained C code.

+ +

[2] If you want to try generating the illustrations yourself, you + can save a little run-time by calling tex 3DLDF.texi the + first time, rather than texi2dvi. The latter program runs + TeX twice, because it needs two passes in order to generate the + contents, indexing, and cross reference information (and maybe some + other things, too).

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Initial-version.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Initial-version.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Initial-version.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Initial-version.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,89 ---- + + + Initial version - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Changes in 3DLDF 1.1.4, + Up: Changes +


+
+ +

41.6 3DLDF 1.1.1

+ +

3DLDF 1.1.1 was the first version of 3DLDF since it became a GNU + package (the current version is 1.1.5.1). It is now conformant + to the GNU Coding Standards, except that + a functioning 3DLDF.info cannot be generated from + 3DLDF.texi. The + distribution now includes a configure script, + Makefile.in files, and other files generated by Autoconf and + Automake. Recompilation is now handled by make rather than + the auxilliary program 3DLDFcpl. The files + 3DLDFcpl.web and 3DLDFprc.web have been removed from the + distribution. + +

The extension of the C++ + files generated by ctangle is + changed from c to cxx before they are compiled. + After ctangle is run on a CWEB file, <filename>.c + is compared to the old <filename>.cxx using diff. + Whitespace, comments, and #line preprocessor commands are + ignored. The <filename>.c is only renamed to + <filename>.cxx and compiled if they differ. This way, + changes to the TeX text only in a CWEB file no longer cause + recompilation and relinking. + +

The main Texinfo file is now called 3DLDF.texi. It was formerly + called 3DLDFman.texi. This is because Automake expects this + name. For this reason, the CWEB + file passed as an argument to cweave has been renamed + 3DLDFprg.web. It was formerly called 3DLDF.web. + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Input-and-Output.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Input-and-Output.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Input-and-Output.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Input-and-Output.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,61 ---- + + + Input and Output - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Color Reference, + Up: Top +


+
+ +

17 Input and Output

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Installing-3DLDF.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Installing-3DLDF.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Installing-3DLDF.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Installing-3DLDF.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,100 ---- + + + Installing 3DLDF - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

11.1 Installing 3DLDF

+ +

3DLDF is available for downloading from + http://ftp.gnu.org/gnu/3dldf. + The official 3DLDF website is + http://www.gnu.org/software/3dldf. + The “tarball”, i.e., the compressed archive file + 3DLDF-1.1.5.1.tar.gz unpacks into a directory called + /3DLDF-1.1.5.1/. + +

On a typical Unix-like system, entering the following commands + at the command line in a shell will unpack the 3DLDF distribution. + Please note that the form of the commands may differ on your system. + +

     gunzip 3DLDF-1.1.5.1.tar.gz
+      tar xpvf 3DLDF-1.1.5.1.tar
+ 
+

The ‘p’ option to tar ensures that the files will have + the same permissions as when they were packed. + +

The directory 3DLDF-1.1.5.1/ contains a + configure script, which should + be called from the command line in the shell, using the absolute path of + 3DLDF-1.1.5.1/ as the prefix argument. For example, if + the path is /usr/local/mydir/3DLDF-1.1.5.1/, + configure should be invoked as follows: + +

     cd 3DLDF-1.1.5.1
+      configure --prefix=/usr/local/mydir/3DLDF-1.1.5.1/
+ 
+

configure generates a Makefile + from the Makefile.in in 3DLDF-1.1.5.1/, and + in each of the subdirectories 3DLDF-1.1.5.1/CWEB, + 3DLDF-1.1.5.1/DOC, + and 3DLDF-1.1.5.1/DOC/TEXINFO. + Now, make install causes the 3DLDF to be built. + The executable is called 3dldf. + +

See the files README and INSTALL in the 3DLDF distribution + for more information. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Installing-and-Running-3DLDF.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Installing-and-Running-3DLDF.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Installing-and-Running-3DLDF.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Installing-and-Running-3DLDF.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,61 ---- + + + Installing and Running 3DLDF - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Intersections, + Up: Top +


+
+ +

11 Installing and Running 3DLDF

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,140 ---- + + + Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Pictures, + Up: Top +


+
+ +

10 Intersections

+ +

There are no functions for finding the intersection points of two (or + more) arbitrary Paths. This is impossible, so long as 3DLDF + outputs MetaPost code. + 3DLDF only “knows” about the Points on a + Path; it doesn't actually generate the curve or other figure + that passes through the Points, and consequently doesn't “know” + how it does this. + +

In addition, an arbitrary Path can contain connectors. + In 3DLDF, the connectors are + merely strings and are written verbatim to the output file, + however, in MetaPost they influence the form of a Path. + +

3DLDF can, however, find the intersection points of some + non-arbitrary Paths. So far, it can find the intersection + point of the following combinations of Paths: + +

+

    +
  1. Two linear Paths, i.e., Paths + for which Path::is_linear() returns true + (see Path Reference; Querying). + In addition, the static Point member function + Point::intersection_points() can be called with four Point + arguments. The first and second arguments are treated as the end points + of one line, and the third and fourth arguments as the end points of the + other. + +
  2. A line and a Polygon. Currently, Reg_Polygon and + Rectangle are the only classes derived from Polygon. + +
  3. Two Polygons. + +
  4. A line and a Regular Closed Plane Curve (Reg_Cl_Plane_Curve, + see Regular Closed Plane Curve Reference; Intersections). Currently, + Ellipse and Circle are the only classes derived from + Reg_Cl_Plane_Curve. + +
  5. Two Ellipses. Since a Circle is also an Ellipse, + one or both of the Ellipses may be a Circle. + See Ellipse Reference; Intersections. +
+ +

Adding more functions for finding the intersections of various geometric + figures is one of my main priorities with respect to extending 3DLDF. + +

There are currently no special + functions for finding the intersection points + of a line and a Circle or two Circles. Since the + class Circle is derived from class Ellipse, + Circle::intersection_points() resolves to + Ellipse::intersection_points(), which, in turn, calls + Reg_Cl_Plane_Curve::intersection_points(). + This does the trick, but it's much easier to find the intersections for + Circles that it is for Ellipses. In particular, the + intersections of two coplanar Circles can be found + algebraically, whereas I've had to implement a numerical solution for + the case of two coplanar Ellipses with different centers and/or + axis orientation. It may also be worthwhile to write + a specialization for + finding the intersection points of a Circle and an + Ellipse. + +

The theory of intersections is a fascinating and non-trivial branch of + mathematics.1 + As I learn more about it, I plan to define more + classes to represent various curves (two-dimensional ones to + start with) and functions for finding their intersection points. + + + + + + +

+
+

Footnotes

[1] The books on computer graphics and the fairly elementary + mathematics books that I own or have referred to don't go into + intersections very deeply. One that does is + Fischer, Gerd. Ebene Algebraische Kurven, which is a bit over my + head.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Introduction.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Introduction.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Introduction.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Introduction.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,119 ---- + + + Introduction - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Top, + Up: Top +


+
+ +

1 Introduction

+ +

3DLDF is a free software package for three-dimensional drawing written by + Laurence D. Finston, who is also the author of this manual. + It is written in C++ + using CWEB and it outputs MetaPost code. + +

3DLDF is a GNU package. + It is part of the GNU Project of the + Free Software Foundation + and is published under the GNU General Public License. + See the website http://www.gnu.org for more + information. + 3DLDF is available for downloading from + http://ftp.gnu.org/gnu/3dldf. + The official 3DLDF website is + http://www.gnu.org/software/3dldf. + More information about 3DLDF can be found at the author's website: + http://wwwuser.gwdg.de/~lfinsto1. + +

Please send bug reports to: + +

     bug-3DLDF@gnu.org and
+ 
+ + + +

Two other mailing lists may be of interest to users of 3DLDF: + help-3DLDF@gnu.org is for people to ask other + users for help and info-3DLDF@gnu.org is for sending + announcements to users. To subscribe, send an email to the + appropriate mailing list or lists with the word "subscribe" as the + subject. + The author's website is http://wwwuser.gwdg.de/~lfinsto1. + +

My primary purpose in writing 3DLDF was to make it possible to use + MetaPost for three-dimensional drawing. I've always enjoyed using MetaPost, + and thought it was a shame that I could only use it for making + two-dimensional drawings. 3DLDF is a front-end that operates on + three-dimensional data, performs the necessary calculations for the + projection onto two dimensions, and writes its output in the form of + MetaPost code. + +

While 3DLDF's data types and operations are modelled on those of + Metafont and MetaPost, and while the only form of output 3DLDF currently + produces is MetaPost code, it is nonetheless not in principle tied to + MetaPost. It could be modified to produce PostScript code directly, or + output in other formats. It would also be possible to modify 3DLDF so + that it could be used for creating graphics interactively on a terminal, + by means of an appropriate interface to the computer's graphics + hardware. + +

The name “3DLDF” (“3D” plus the author's initials) was + chosen because, while not pretty, it's unlikely to conflict + with any of the other programs called “3D”-something. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Inverting-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Inverting-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Inverting-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Inverting-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,127 ---- + + + Inverting Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Applying Transforms to Points Intro, + Up: Transforms +


+
+ +

4.2 Inverting Transforms

+ +

Inversion is another operation that can be performed on + Transforms. This makes it possible to reverse the effect of a + Transform, which may represent multiple transformations. + +

     Point p;
+      Transform t;
+      t.shift(1, 2, 3);
+      t.scale(2, 3, 4);
+      t.rotate(45, 45, 30);
+      t.show("t:");
+      -| t:
+         1.22   0.707    1.41       0
+        0.238    2.59    -1.5       0
+        -3.15    1.45       2       0
+        -7.74    10.2    4.41       1
+      p *= t;
+      p.show("p:");
+      -| p: (-7.74, 10.2, 4.41)
+      Transform u;
+      u = t.inverse();
+      u.show("u:");
+      -| u:
+        0.306  0.0265  -0.197 2.85e-09
+        0.177   0.287  0.0906 -1.12e-09
+        0.354  -0.167   0.125       0
+           -1      -2      -3       1
+      p *= u;
+      p.show("p:");
+      -| p: (0, 0, 0)
+      u *= t;
+      u.show("u:");
+      -| u:
+            1       0       0       0
+            0       1       0       0
+            0       0       1       0
+            0       0       0       1
+ 
+

If inverse() is called with no argument, or with the argument + false, it returns a + Transform representing its inverse, and remains unchanged. If it + is called with the argument true, it is set to its inverse. + +

Complete reversal of the transformations applied to a Point, as + in the previous example, probably won't make much sense. However, + partial reversal is a valuable technique. For example, it is used in + rotate() for rotation about a line defined by two Points. + The following example merely demonstrates the basic principle; an + example that does something useful would be too complicated. + + + + +

     Transform t;
+      t.shift(3, 4, 5);
+      t.rotate(45);
+      t.scale(2, 2, 2);
+      Point p;
+      p *= t;
+      p.show("p:");
+      -| p: (6, 12.7279, 1.41421)
+      t.inverse(true);
+      p.rotate(90, 90);
+      p *= t;
+      p.show("p:");
+      -| p: (3.36396, -5.62132, -2.37868)
+ 
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Label-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Label-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Label-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Label-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,123 ---- + + + Label Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Label Reference, + Up: Label Reference +


+
+ +

20.1 Data Members

+ +
+ — Private variable: Point* pt
+

A pointer to the Point representing the location of the + Label. +

+ +
+ — Private variable: bool dot
+

true if the label should be dotted, otherwise + false. + +

dot will be false, if the label was generated + by a call to label() with the “dot” argument + false (the default), true, if + the label was generated by a call to dotlabel(), + or to label() with the “dot” argument + true. +

+ +
+ — Private variable: string text
+

The text of the label. + text is always put between “btex” and “etex” in + the MetaPost code, so that TeX will be used to format the labels. In + particular, this means that TeX's math mode can be used. However, + double backslashes must be used instead of single backslashes, in order + that single backslashes be written to out_stream. + +

          Point P(1, 1, 2);
+           origin.drawarrow(P);
+           P.label("$\\vec{P}$");
+ 
+

+
+ [Figure 76. Not displayed.] +
+
+ Fig. 76. +
+

+ +
+ +
+ — Private variable: string position
+

The position of the text with respect to + *pt. Valid values are as in MetaPost: + “top”, “bot” (bottom), “lft” (left), “rt” + (right), “ulft” (upper left), + “llft” (lower left), “urt” (upper right), + “lrt” (lower right). +

+ +
+ — Public static variable: bool DO_LABELS
+

Enables or disables creation + of Labels. If true, label + and dotlabel() cause Labels to be + created and put onto a Picture. If + false, they are not. Note that it is also + possible to suppress output of existing + Labels when outputting a Picture. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Label-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Label-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Label-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Label-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,88 ---- + + + Label Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transform Reference, + Up: Top +


+
+ +

20 Label Reference

+ +

Class Label is defined in pictures.web. + Point and Picture are friends of Label. + +

Labels can be included in drawings by using the label() and + dotlabel() functions, which are currently defined for the classes + Point and Path, and the classes derived from them. + See Point Reference; Labelling, and + See Path Reference; Labelling. + They are currently not defined for Solid, and its derived classes. + I plan to add them for Solid soon. + +

Users will normally + never need to declare objects of type Label, access its data + members or call its member functions directly. + +

When label() or dotlabel() is invoked, one or more Labels is + allocated dynamically and pointers to the new Labels are placed + onto the vector<Label*> labels of a Picture: + current_picture, by default. There are no explicitly defined + constructors for Label, nor is it intended that Labels + ever be created in any way other than through label() or + dotlabel(). When a Picture is copied, the Labels are + copied, too, and when a Picture is cleared (using + Picture::clear()) or destroyed, the Labels are deallocated + and destroyed. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labeling-Ellipses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labeling-Ellipses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labeling-Ellipses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labeling-Ellipses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,101 ---- + + + Labeling Ellipses - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

31.5 Labeling

+ +
+ — const function: void label ([const string pos = "top", [const bool dot = false, [Picture& picture = current_picture]]])
+

Labels the Points on points, using lowercase letters. + pos is used to position all of the labels. It is currently not + possible to have different positions for the labels. + +

          Ellipse e(origin, 6, 4);
+           e.draw();
+           e.label();
+ 
+

+
+ [Figure 161. Not displayed.] +
+
+ Fig. 161. +
+

+ +
+ +
+ — Inline const function: void dotlabel ([string pos = "top", [Picture& picture = current_picture]])
+

Like label(), except that the Points are dotted. + +

          Ellipse e(origin, 6, 4);
+           e.draw();
+           e.dotlabel();
+ 
+

+
+ [Figure 162. Not displayed.] +
+
+ Fig. 162. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labeling-Points-Intro.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labeling-Points-Intro.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labeling-Points-Intro.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labeling-Points-Intro.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,117 ---- + + + Labeling Points Intro - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Drawing Points Intro, + Up: Drawing and Labeling Points +


+
+ +

5.2 Labeling Points

+ +

The labels in the previous examples were made by using the functions + Point::label() and Point::dotlabel(), which make it + possible to include TeX text in a drawing. + +

label() and dotlabel() take string arguments for + the text of the label and the position of the label with respect to the + Point. The label text is formatted using TeX, so it can contain + math mode material between dollar signs. Please note that double backslashes + must be used, where a single backslash would suffice in a file of + MetaPost code, for example, for TeX control sequences. + Alternatively, a short argument can be used for the label. + +

The position argument is optional, with "top" as the default. If + the empty string "" is used, the label will centered about + the Point itself. This will usually only make sense for + label(), because it would otherwise interfere with the dot. + Valid arguments for the + position are the same as in MetaPost: "top", "bot" + (bottom), "lft" (left), "rt" (right), + "ulft" (upper left), "urt" (upper right), + "llft" (lower left), and "lrt" (lower right). + +

     Point p0;
+      Point p1(1);
+      Point p2(2);
+      Point p3(p0);
+      Point p4(p1);
+      Point p5(p2);
+      p3 *= p4 *= p5.shift(0, 1);
+      p0.draw(p1);
+      p1.draw(p2);
+      p2.draw(p5);
+      p5.draw(p4);
+      p4.draw(p3);
+      p3.draw(p0);
+      p0.label($p_0$, "");
+      p1.dotlabel(1);
+      p2.dotlabel("p2", "bot");
+      p3.dotlabel("This is $p_3$", "lft");
+      p4.label(4);
+      p5.label("$\\leftarrow p_5$", "rt");
+ 
+

+
+ [Figure 8. Not displayed.] +
+
+ Fig. 8. +
+

+ +

For complete descriptions of Point::label() and + Point::dotlabel(), see Points; Labelling. + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labelling-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labelling-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labelling-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labelling-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,78 ---- + + + Labelling Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Drawing and Filling Paths, + Up: Path Reference +


+
+ +

26.13 Labelling

+ +
+ — const function: void label ([unsigned int i = 0, [string position_string = "top", [short text_short = 0, [bool dot = false, [Picture& picture = current_picture]]]]])
+ — const function: void label (Picture& picture, [unsigned int i = 0, [string position_string = "top", [short text_short = 0, [bool dot = false]]]])
+

Calls Point::label() on all of the Points on + points. They are numbered consecutively starting with i. + The other arguments are used for all of the Points, so it's not + possible to specify different positions for the labels for different + Points. dot will normally not be specified, unless a + picture argument is used in the first version. dotlabel() + calls label() with dot = true. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. +

+ +
+ — const function: void dotlabel ([unsigned int i = 0, [string position_string = "top", [short text_short = 0, Picture& picture = current_picture]]])
+ — const function: void dotlabel (Picture& picture, [unsigned int i = 0, [string position_string = "top", [short text_short = 0]]])
+

Like label(), except that the Points are dotted. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labelling-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labelling-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Labelling-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Labelling-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,155 ---- + + + Labelling Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Point Drawing Functions, + Up: Point Reference +


+
+ +

22.19 Labelling

+ +

Labels make it possible to include TeX text within a drawing. + Labels are implemented by means of class Label. + The functions label() and dotlabel(), described in this + section, create objects of type Label, and add them to the + Picture, which was passed to them as an argument + (current_picture, by default). + See Label Reference, for more information. + +

+ — const function: void label (const string text_str, [const string position_str = "top", [const bool dot = false, [Picture& picture = current_picture]]])
+ — const function: void label (const short text_short, [const string position_str = "top", [const bool dot = false, [Picture& picture = current_picture]]])
+

These functions cause a Point to be labelled in the drawing. + The first argument is the text of the label. It can either be a + string, in the first version, or a short, in the second. + It will often be the name of the Point in the C++ + code, for + example, "p0". + It is not possible to automate this kind of + labelling, because it is not possible to access the names of variables + through the variables themselves in C++ + . + +

text_str is always placed between + “btex'' and “etex” in the MetaPost label command + written to out_stream. This makes it possible to include math + mode material in the text of labels, as in the following example. + +

          Point p0(2, 3);
+           p0.label("$p_0$");
+ 
+

+
+ [Figure 101. Not displayed.] +
+
+ Fig. 101. +
+

+ +

If backslashes are needed in the text of the label, then + text_str must contain double backslashes, so that single + backslashes will be written to out_stream. + +

          Point P;
+           Point Q(2, 2);
+           Point R(P.mediate(Q));
+           R.label("$\\overrightarrow{PQ}$", "ulft");
+ 
+

+
+ [Figure 102. Not displayed.] +
+
+ Fig. 102. +
+

+ +

The position argument indicates where the text of the label should + be located relative to the Point. The valid values are the + strings used in MetaPost for this purpose, i.e., ‘top’, ‘bot’, + ‘lft’, ‘rt’, ‘llft’ (lower left), ‘lrt’ (lower + right), ‘ulft’ (upper left), and ‘urt’ (upper right). The + default is ‘top’. 3DLDF does not catch the error if an invalid + position argument is used; the string is written to the + output file and an error will occur when MetaPost is run. + +

The dot argument is used to determine whether the label should be + dotted or not. The default is false. The function + dotlabel() calls label(), passing true as the + latter's dot argument. +

+ +
+ — const function: void dotlabel ([const string text_str, [const string position_str = "top", [Picture& picture = current_picture]]])
+ — const function: void dotlabel (const short text_short, [const string position_str = "top", [Picture& picture = current_picture]])
+

These functions are like label() except that they always produces a + dot. + +

          Point p0(2, 3);
+           p0.dotlabel("$p_0$");
+ 
+

+
+ [Figure 103. Not displayed.] +
+
+ Fig. 103. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Constructors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Constructors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Constructors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Constructors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Line Constructors - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Line Global Constants, + Up: Line Reference +


+
+ +

24.3 Constructors

+ +
+ — Default constructor: void Line (const Point& pos = origin, const Point& dir = origin)
+

Creates a Line, setting position to pos, and + direction to dir. If this function is called with no + arguments, it creates a Line at the origin with no + direction. + +

          Point p(2, 1, 2);
+           Point d(-3, 3, 3.5);
+           Line L0(p, d);
+           Line L1 = p.get_line(d);
+ 
+

+
+ [Figure 104. Not displayed.] +
+
+ Fig. 104. +
+

+ +
+ +
+ — Copy constructor: void Line (const Line& l)
+

Creates a Line, making it a copy of l. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,67 ---- + + + Line Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Line Reference, + Up: Line Reference +


+
+ +

24.1 Data Members

+ +
+ — Public variable: Point position
+

Represents the position vector of the Line. +

+ +
+ — Public variable: Point direction
+

Represents the direction vector of the Line. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Global-Constants.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Global-Constants.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Global-Constants.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Global-Constants.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Line Global Constants - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Line Data Members, + Up: Line Reference +


+
+ +

24.2 Global Constants

+ +
+ — Constant: const Line INVALID_LINE
+

position and direction are both INVALID_POINT. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,64 ---- + + + Line Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Line Constructors, + Up: Line Reference +


+
+ +

24.4 Operators

+ +
+ — Assignment operator: void operator= (const Line& l)
+

Sets *this to l. +

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Line-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Line-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,76 ---- + + + Line Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Focus Reference, + Up: Top +


+
+ +

24 Line Reference

+ +

The struct Line is defined in lines.web. + Lines are not Shapes. They are used for + performing vector operations. A Line is defined by a + Point representing a position vector and a Point + representing a direction vector. + +

See also the descriptions of Point::get_line() in + Points and Lines, and + Path::get_line() in + Path Reference; Querying. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Manual-Conventions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Manual-Conventions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Manual-Conventions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Manual-Conventions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,162 ---- + + + Manual Conventions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: About This Manual, + Up: About This Manual +


+
+ +

1.2.1 Conventions

+ +

Data types are formatted like this: int, + Point, Path. Plurals are formatted in the same way: + ints, Points, Paths. It is poor + typographical practice to typeset a single word using more than one + font, e.g., ints, Points, Paths. This applies to + data types whose plurals do not end in “s” as well, e.g., + the plural of the C++ + class Polyhedron is Polyhedra. + +

When C++ + functions are discussed in this manual, I always include a + pair + of parentheses to make it clear that the item in question is a function + and not a variable, but I generally do not + include the arguments. For example, if I mention the + function + foo(), this doesn't imply that foo() takes no + arguments. If it were appropriate, I would include the argument type: + +

     foo(int)
+ 
+

or the argument type and a placeholder name: + +

     foo(int arg)
+ 
+

or I would write + +

     foo(void)
+ 
+

to indicate that foo() takes no arguments. Also, I + generally don't indicate the return type, unless it is relevant. If it + is a member function + of a class, I may indicate this, + e.g.,, bar_class::foo(), or not, + depending on whether this information is relevant. This convention + differs from that used in the Function Index, which is generated + automatically by Texinfo. There, only the name of the function appears, + without parentheses, parameters, or return values. The class type + of member functions may appear in the Function Index, (e.g., + bar_class::foo), but only in index entries that have been entered + explicitly by the author; such entries are not generated by Texinfo + automatically. + +

Examples are formatted as follows: + +

     Point p0(1, 2, 3);
+      Point p1(5, 6, 7.9);
+      Path pa(p0, p1);
+      p0.show("p0:");
+      -| p0: (1, 2, 3)
+ 
+

The beautiful mathematical typesetting produced by TeX + unfortunately does not appear in the Info and HTML versions of this + manual. In these, the following symbols are used to replace the proper + mathematical symbols. + +

+
^
Precedes a superscript. For example, read ‘a^2’ as + “a squared”. + +
_
Precedes a subscript. For example, read ‘x_1’ as + “x sub one”. + +
*
Multiplication. For example, read ‘x * y’ as + “x times y”. + +
sqrt()
The square root function. For example, read ‘sqrt(x)’ as + “the square root of x”. +
+ +

In addition, examples + can contain the following symbols: + +

+
-|
Indicates output to the terminal when 3DLDF is + run. + +
Indicates a result of some sort. It may precede a illustration + generated by the code in the example. + +
error-->
Indicates that the following text is an error message. +
+ +

This manual does not use all of the symbols provided by Texinfo. If you + find a symbol you don't understand in this manual (which shouldn't + happen), see page 103 of the Texinfo manual. + +

+

+ 
+ 
+ Symbols: +
+
N +
The set of the natural numbers + {0, 1, 2, 3, 4, ...} + +
I +
The set of the integers + {..., -3, -2, -1, 0, 1, 2, 3, 4, ...} + +
R +
The set of the real numbers. +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Matrix-Inversion.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Matrix-Inversion.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Matrix-Inversion.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Matrix-Inversion.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,71 ---- + + + Matrix Inversion - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transform Operators, + Up: Transform Reference +


+
+ +

19.5 Matrix Inversion

+ +
+ — const function: Transform inverse (void)
+ — Function: Transform inverse ([bool assign = false])
+

Returns a Transform T with a T.matrix that is the + inverse of matrix. If assign==true, then + matrix is set to its inverse. + +

In the const version, matrix remains unchanged. + The second should only ever be called with true as its + assign argument. If you're tempted call inverse(false), + you might as well just leave out the argument, which issues a warning + message, and calls the const version. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Metafont-and-MetaPost.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Metafont-and-MetaPost.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Metafont-and-MetaPost.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Metafont-and-MetaPost.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,143 ---- + + + Metafont and MetaPost - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: CWEB Documentation, + Up: Introduction +


+
+ +

1.4 Metafont and MetaPost

+ +

Metafont is a system created by Donald E. Knuth for generating fonts, + in particular for use with TeX, his well-known + typsetting system.1 + Expressed in a + somewhat simplified way, Metafont is a system for programming + curves, which are then digitized and output in the form of + run-time encoded bitmaps. (See Knuth's The Metafontbook for more + information). + +

John D. Hobby modified Metafont's source code to create + MetaPost, which functions in much the same way, but outputs + encapsulated PostScript (EPS) files instead of bitmaps. MetaPost is + very useful for creating graphics and is a convenient + interface to PostScript. It is also easy both to imbed + TeX code in MetaPost programs, for instance, for typesetting + labels, and to include MetaPost graphics in ordinary TeX + files, e.g., by using dvips.2 + Apart from simply printing the PostScript file output by + dvips, there are many programs that can process ordinary + or encapsulated PostScript files and convert them to other formats. + Just two of the many possibilities are ImageMagick and GIMP, both of + which can be used to create animations from MetaPost graphics. + + + +

However, MetaPost inherited a significant limitation from + Metafont: it's not possible to use it for making + three-dimensional graphics, except in a very limited way. + One insuperable problem is the severe limitation on the magnitude + of user-defined numerical variables in Metafont and + MetaPost.3 + This + made sense for Metafont's and MetaPost's original + purposes, but they make it impossible to perform the + calculations needed for 3D graphics. + +

Another problem is the data types defined in Metafont: Points + are represented as pairs of real values and affine + transformations as sets of 6 real values. This corresponds to + the representation of points and affine transformations in the + plane as a two-element vector on the one hand and a six + element matrix on the other. While it is + possible to work around the limitation imposed by having + points be represented by only two values, it is + impracticable in the case of the + transformations. + +

For these reasons, I decided to write a program that would behave more + or less like Metafont, but with suitable extensions, and the ability to + handle three dimensional data; namely 3DLDF. It stores the data and + performs the transformations and other necessary calculations and is not + subject to the limitations of MetaPost and its data types. Upon output, + it performs a perspective transformation, converting the 3D image into a + 2D one. The latter can now be expressed as an ordinary MetaPost + program, so 3DLDF writes its output as MetaPost code to a file. + +

In the following, it may be a little unclear why I sometimes refer to + Metafont and sometimes to MetaPost. The reason is that Metafont + inherited much of its functionality from Metafont. Certain operations + in Metafont have no meaning in MetaPost and so have been removed, while + MetaPost's function of interfacing with PostScript has caused other + operations to be added. For example, in MetaPost, color is a + data type, but not in Metafont. Unless otherwise stated, when I refer to + Metafont, it can be assumed that what I say applies to MetaPost as well. + However, when I refer to MetaPost, it will generally be in connection + with features specific to MetaPost. + +

+
+

Footnotes

[1] Knuth, Donald E. The + TeXbook. Computers and Typesetting; A. + Addison-Wesley Publishing Company. Reading, Massachusetts 1986.

+ +

[2] Rokicki, Tomas. Dvips: A + DVI-to-PostScript Translator February 1997. Available from CTAN. + See Sources of Information.

+ +

[3] “<...> + METAFONT deals only with numbers in a limited + range: A numeric token must be less than 4096, and its value is always + rounded to the nearest multiple of + 1 / 65536.” Knuth, The METAFONTbook, p. 50. +

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Colors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Colors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Colors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Colors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,91 ---- + + + Modifying Colors - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Color Operators, + Up: Color Reference +


+
+ +

16.4 Modifying

+ +
+ — Function: void set_name (const string s)
+

Sets name to s. use_name is not reset. +

+ +
+ — Function: void set_use_name (const bool b)
+

Sets use_name to b. +

+ +
+ — Function: void modify (const real r, [const real g = 0, [const real b = 0]])
+

Adds r, g, and b to red_part, + green_part, and blue_part, respectively. Following the + addition, if red_part, green_part, and/or blue_part + is greater than 1, it is reduced to 1. If it is less than 0, it is + increased to 0. +

+ +
+ — Function: void set_red_part (const real q)
+ — Function: void set_green_part (const real q)
+ — Function: void set_blue_part (const real q)
+

Let p stand for red_part, + green_part, or blue_part, depending upon which function is + used. + If + 0 <= q <= 1, + p is set to q. If + q < 0, p is set to 0. + If q > 1, p is set to 1. +

+ + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Focuses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Focuses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Focuses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Focuses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,63 ---- + + + Modifying Focuses - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Focus Operators, + Up: Focus Reference +


+
+ +

23.5 Modifying

+ +
+ — Function: void reset_angle (const real ang)
+

Resets the value of angle and recalculates the Transforms + transform and persp. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,122 ---- + + + Modifying Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Clearing Paths, + Up: Path Reference +


+
+ +

26.8 Modifying

+ +
+ — Virtual function: bool set_on_free_store ([bool b = true])
+

Sets on_free_store to b. This is used in the + template function create_new(). + See Path Reference; Constructors and Setting Functions. +

+ +
+ — Virtual function: void set_fill_draw_value (const signed short s)
+

Sets fill_draw_value to s, which should be one of + Shape::DRAW, Shape::FILL, Shape::FILLDRAW, + Shape::UNDRAW, Shape::UNFILL, or Shape::UNFILLDRAW. +

+ +
+ — Virtual function: void set_draw_color (const Color& c)
+ — Virtual function: void set_draw_color (const Color * c)
+

Sets draw_color (a pointer to a const Color) to &c + or c, depending on whether the + version with a reference argument or the version with a pointer argument + is used. + +

set_draw_color() is used in the Solid drawing and filling + functions, because Path::draw_color is protected, and + the Solid cannot access it directly. + See Solid Reference; Drawing and Filling. +

+ +
+ — Virtual function: void set_fill_color (const Color& c)
+ — Virtual function: void set_fill_color (const Color* c)
+

Sets fill_color (a pointer to a const Color) to &c + or c, depending on whether the + version with a reference argument or the version with a pointer argument + is used. + +

set_fill_color() is used in the Solid drawing and filling + functions, because + Path::fill_color is protected, and + the Solid cannot access it directly. + See Solid Reference; Drawing and Filling. +

+ +
+ — Virtual function: void set_dash_pattern ([const string s = ""])
+

Sets dashed to s. +

+ +
+ — Virtual function: void set_pen ([const string s = ""])
+

Sets pen to s. +

+ +
+ — Virtual function: void set_connectors ([const string s = ".."])
+

Clears connectors and then pushes s onto it, making s + the only connector. Additional connectors can be added by using + Path::operator+=(const string). + See Path Reference; Operators. + +

I plan to add a version of this function taking a vector of + strings as its argument, to make it possible to set several + connectors at one time. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Pictures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Pictures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Pictures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Pictures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,82 ---- + + + Modifying Pictures - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

21.6 Modifying

+ +
+ — Function: void clear (void)
+

Destroys the Shapes and Labels on the + Picture and removes all the Shape pointers from + shapes and the Label pointers from labels. + All dynamically allocated objects are deallocated, namely the + Shapes, the Labels, and the Points belonging to the + Labels. transform is reset to the identity Transform. +

+ +
+ — Function: void reset_transform (void)
+

Resets transform to the identity Transform. +

+ +
+ — Function: Transform set_transform (const Transform& t)
+

Sets transform to t and returns t. +

+ +
+ — Function: void kill_labels (void)
+

Removes the Labels from the Picture. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Modifying Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.11 Modifying

+ +
+ — Virtual function: bool set_on_free_store ([bool b = true])
+

This function is used in the template function + create_new(). It sets on_free_store to true. + See Point Reference; Data Members, and + Point Reference; Constructors and Setting Functions. +

+ +
+ — Function: void clear (void)
+

Sets all of the coordinates in all of the sets of coordinates (i.e., + world_coordinates, user_coordinates, view_coordinates, and + projective_coordinates) to 0 and resets transform +

+ +
+ — Function: void clean ([int factor = 1])
+

Calls apply_transform() and sets the values of + world_coordinates to 0, whose absolute values are less than + epsilon() * factor + . +

+ +
+ — Function: void reset_transform (void)
+

Sets Transform to the identity Transform. Performed in + apply_transform(), after the latter updates world_coordinates. + Point Reference; Applying Transformations. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Modifying-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Modifying-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Modifying Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Copying Shapes, + Up: Shape Reference +


+
+ +

18.4 Modifying

+ +
+ — Pure virtual function: bool set_on_free_store (bool b = true)
+

Sets the data member on_free_store to b. All classes + derived from Shape must therefore also have a data member + on_free_store. + +

This function is used in the template function + create_new<type>. + See Dynamic Allocation of Shapes, for more information. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Multi_002dThreading.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Multi_002dThreading.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Multi_002dThreading.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Multi_002dThreading.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Multi-Threading - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ + +

+ Previous: Shadows, + Up: Future Plans +


+
+ +

40.4 Multi-Threading

+ +

When 3DLDF is run, there is only one thread of execution. + However, it could benefit from the use of multiple threads. + In particular, it may be faster and more efficient to have + Picture::output() run in its own thread. + In this case, it will no longer be possible to share + current_picture among figures. + +

It may also be + worthwhile to execute the code for “figures”, i.e., the code + between ‘beginfig()’ and ‘endfig()’, inclusive, + in their own threads. This will require some changes in the way data + are handled. For example, if non-constant objects are shared + among figures, there may be no advantage to multi-threading because of + the need to coordinate the access of the threads to the objects. + If threads are used, then non-constant objects should be + declared locally within the figure. They may be locally declared + copies of global objects. Alternatively, beginfig() could be + changed so that objects could be passed to it as arguments, perhaps as + a vector<void*> and/or a vector<Shape*>. + + + + + + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Namespace-Colors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Namespace-Colors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Namespace-Colors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Namespace-Colors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,123 ---- + + + Namespace Colors - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Previous: Defining and Initializing Colors, + Up: Color Reference +


+
+ +

16.8 Namespace Colors.

+ +
+ — Constant: const Color red
+ — Constant: const Color green
+ — Constant: const Color blue
+ — Constant: const Color cyan
+ — Constant: const Color yellow
+ — Constant: const Color magenta
+ — Constant: const Color orange_red
+ — Constant: const Color violet_red
+ — Constant: const Color pink
+ — Constant: const Color green_yellow
+ — Constant: const Color orange
+ — Constant: const Color violet
+ — Constant: const Color purple
+ — Constant: const Color blue_violet
+ — Constant: const Color yellow_green
+ — Constant: const Color black
+ — Constant: const Color white
+ — Constant: const Color gray
+ — Constant: const Color light_gray
+

These constant Colors can be used in drawing and filling + commands. +

+ +
+ — Constant: const Color default_background
+

The default background color. Equal to white per default. +

+ +
+ — Pointer: const Color* background_color
+

Points to default_background by default. +

+ +
+ — Pointer: const Color* default_color
+

Points to black by default. +

+ +
+ — Pointer: const Color* help_color
+

Points to green by default. +

+ +

The following vectors of pointers to Color can be used in the + drawing and filling functions for Solid + (see Solid Reference; Drawing and Filling). + +

+ — Vector: const vector <const Color*> default_color_vector
+

Contains one pointer, namely default_color. +

+ +
+ — Vector: const vector <const Color*> help_color_vector
+

Contains one pointer, namely help_color. +

+ +
+ — Vector: const vector <const Color*> background_color_vector
+

Contains one pointer, namely background_color. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Namespace-Projections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Namespace-Projections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Namespace-Projections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Namespace-Projections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,72 ---- + + + Namespace Projections - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +
21.8.1.1 Namespace Projections
+ +

The namespace Projections is defined in pictures.web. + +

+ — Constant: const unsigned short PERSP
+ — Constant: const unsigned short PARALLEL_X_Y
+ — Constant: const unsigned short PARALLEL_X_Z
+ — Constant: const unsigned short PARALLEL_Z_Y
+ — Constant: const unsigned short AXON
+ — Constant: const unsigned short ISO
+

These constants can be used for the projection argument in + Picture::output(), described in + Picture Reference; Outputting; Functions, + below. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Namespace-Sorting.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Namespace-Sorting.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Namespace-Sorting.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Namespace-Sorting.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Namespace Sorting - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Namespace Projections, + Up: Picture Output Namespaces +


+
+ +
21.8.1.2 Namespace Sorting
+ +

The namespace Sorting is defined in pictures.web. + +

+ — Constant: const unsigned short NO_SORT
+ — Constant: const unsigned short MAX_Z
+ — Constant: const unsigned short MIN_Z
+ — Constant: const unsigned short MEAN_Z
+

These constants can be used for the sort_value argument in + Picture::output(), described in + Picture Reference; Outputting; Functions, + below. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/No-Input-Routine.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/No-Input-Routine.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/No-Input-Routine.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/No-Input-Routine.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,83 ---- + + + No Input Routine - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Accuracy, + Up: Caveats +


+
+ +

1.5.2 No Input Routine

+ +

3DLDF does not yet include a routine for reading input + files. This means that user code must be written in C++ + , + compiled, and linked with the rest of the program. I admit, + this is not ideal, and writing an input routine for user code + is one of the next things I plan to add to 3DLDF. + +

I plan to use Flex and Bison to write the input routine.1 + The syntax of the input code should be as close + as possible to that of MetaPost, while taking account of the + differences between MetaPost and 3DLDF. + +

For the present, however, the use of 3DLDF is limited to + those who feel comfortable using C++ + and compiling and + relinking programs. Please don't be put off by this! It's not so + difficult, and make does most of the work of recompiling and + running 3DLDF. See Installing and Running 3DLDF, for more + information. + +

+
+

Footnotes

[1] Flex is a program for generating text scanners and Bison is a + parser generator. They are available from + http://www.gnu.org.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Labels.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Labels.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Labels.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Labels.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,77 ---- + + + Outputting Labels - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Copying Labels, + Up: Label Reference +


+
+ +

20.3 Outputting

+ +
+ — Function: void output (const Focus& f, const unsigned short proj, real factor, const Transform& t)
+

Writes MetaPost code for the labels to out_stream. + It is called in Picture::output() + (see Picture Reference; Outputting). + Users should never need to call this function directly. + +

When Picture::output() is + invoked, the MetaPost code for Labels is written to out_stream + after the code for the drawing and filling commands. This prevents the + Labels from being covered up. However, they can still be covered + by other Labels, or by Shapes or Labels from + subsequent invocations of Picture::output() within the same + figure (see I/O Functions, for descriptions of beginfig() and + endfig()). +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,123 ---- + + + Outputting Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Querying Paths, + Up: Path Reference +


+
+ +

26.16 Outputting

+ +
+ — Function: bool project (const Focus& f, const unsigned short proj, real factor)
+

Calls Point::project(f, proj, factor) on the + Points on the Path. + If Point::project() fails (i.e., returns false), for any of + the Points, this function + returns false. Otherwise, it returns true. +

+ +
+ — Function: vector<Shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Checks that the Points on points can be projected using + the values for f, proj, and factor. If they can, a + vector<Shape*> containing only this is returned. Called in + Picture::output(). +

+ +
+ — Virtual function: bool set_extremes (void)
+

Sets the appropriate elements in projective_extremes to the + minimum and maximum values of the x, y, and z-coordinates of + the Points on the Path. Used in Picture::output() + for determining whether a Path can be output using the arguments + passed to Picture::output(). +

+ +
+ — Inline const virtual function: const valarray<real> get_extremes (void)
+

Returns projective_extremes. Used in Picture::output(). +

+ +
+ — const virtual function: real get_minimum_z (void)
+ — const virtual function: real get_mean_z (void)
+ — const virtual function: real get_maximum_z (void)
+

These functions return the minimum, mean, or maximum value, + respectively, of the + z-coordinates of the Points on the Path. + Used in the surface hiding algorithm in Picture::output(). +

+ +
+ — Virtual function: void suppress_output (void)
+

Called in Picture::output(). + Sets do_output to + false, if the Path cannot be output using the arguments + passed to Picture::output(). +

+ +
+ — Virtual function: void unsuppress_output (void)
+

Called in Picture::output(). Resets do_output to + true after output() is called on the Shapes on + shapes in a Picture, so that the Path can be output + if Picture::output() is called again, with arguments that allow + the Path to be output. +

+ +
+ — Virtual function: void output (void)
+

Called in Picture::output(). Writes the MetaPost code to + out_stream for drawing, filling, filldrawing, undrawing, + unfilling, or unfilldrawing the Path, if the latter was + projectable using the arguments passed to Picture::output(). +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Pictures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Pictures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Pictures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Pictures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,60 ---- + + + Outputting Pictures - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Showing Pictures, + Up: Picture Reference +


+
+ +

21.8 Outputting

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,137 ---- + + + Outputting Points - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Showing Points, + Up: Point Reference +


+
+ +

22.21 Outputting

+ +
+ — Non-member function: ostream& operator<< (ostream& o, Point& p)
+

Used in Path::output() for writing + the x and y values of the projective_coordinates of Points to + out_stream. See Path Reference; Outputting. + This is a low-level function that ordinary users should never have to + invoke directly. +

+ +
+ — Function: void output (void)
+

Writes the MetaPost code for drawing or undrawing a Point to + out_stream. Called by Picture::output(), when a + Shape on the Picture is a Point. + See Picture Reference; Outputting. +

+ +
+ — Virtual function: void suppress_output (void)
+

Sets do_output to false, which causes a Point + not to be output. This function is called in + Picture::output(), when a Point cannot be projected. + See Picture Reference; Outputting. +

+ +
+ — Virtual function: virtual void unsuppress_output (void)
+

Resets do_output to true, so that a Point can + potentially be output, if Picture::output() is called again for + the Picture the Point is on. + This function is called in + Picture::output(). + See Picture Reference; Outputting. +

+ +
+ — Function: vector<shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Attempts to project the Point + using the arguments passed to Picture::output(), which calls this + function. If extract() succeeds, + it returns a vector<shape*> containing only the Point. + Otherwise, it returns an empty vector<shape*>. +

+ +
+ — Virtual function: bool set_extremes (void)
+

Sets “extreme” values + for x, y, and z in projective_coordinates. This + is, of course, trivial for + Points, because they only have one x, y and z-coordinate. + So the maxima and minima for each coordinate are always the same. +

+ +
+ — Virtual inline const function: valarray <real> get_extremes (void)
+

Returns projective_extremes. +

+ +
+ — Virtual const function: real get_minimum_z (void)
+ — Virtual const function: real get_maximum_z (void)
+ — Virtual const function: real get_mean_z (void)
+

These functions return the minimum, maximum, and mean z-value of the + Point. + get_minimum_z() returns projective_extremes[4], + get_maximum_z() returns projective_extremes[5], and + get_mean_z() returns + (projective_extremes[4] + projective_extremes[5]) / 2. + However, since a Point has only one z-coordinate + (from world_coordinates), these values will all be the same. + +

These functions are pure virtual functions in Shape, and are + called on Points through pointers to Shape. Therefore, + they must be consistent with the versions for other types derived from + Shape. See Shape Reference; Outputting. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,134 ---- + + + Outputting Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Showing Shapes, + Up: Shape Reference +


+
+ +

18.10 Outputting

+ +
+ — Pure virtual function: void output (void)
+

Called by Picture::output() for writing MetaPost code to + out_stream for a Shape pointed to by a pointer on the + vector<Shape*> shapes belonging to the Picture. Such + a Shape will have been created by a drawing or filling + function. +

+ +
+ — Pure virtual function: vector<Shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Called in Picture::output(). It determines whether a + Shape can be output. If it can, and an output() function + for the type of the Shape exists, a vector<Shape*> + containing a pointer to the Shape is returned. + +

On the other + hand, it is possible to define a type derived from Shape, without + an output() function of its own, and not derived from a type that + has one. It may then consist of one or more objects of types that do + have output() functions. In this case, the vector<Shape*> + returned by extract() will contain pointers to all of these + subsidiary Shapes, and Picture::output() will treat them + as independent objects. In particular, if any one of them cannot be + projected using the arguments passed to Picture::output(), this + will have no effect on whether the others are outputted or not. + +

Currently, there are no Shapes without an output() + function, either belonging to the class, or inherited. However, it's + useful to be able to define Shapes in this way, so that they can + be tested without having to define an output() function first. +

+ +
+ — Pure virtual function: bool set_extremes (void)
+

Sets the values of projective_extremes for the Shape. + This is needed in Picture::output() for determining the order in + which objects are output. +

+ +
+ — const pure virtual functions: real get_minimum_z (void)
+ — : real get_maximum_z (void)
+ — : real get_mean_z (void)
+

These functions return the minimum, maximum, and mean z-value + respectively of the projected Points belonging to + the Shape, i.e., from projective_extremes. The values for + the Shapes on the Picture are used for determining the + order in which they are output +

+ +
+ — const pure virtual function: const valarray<real> get_extremes (void)
+

Returns projective_extremes. +

+ +
+ — Pure virtual function: void suppress_output (void)
+

Sets do_output to false. This function is called in + Picture::output(), if a Shape on a Picture cannot + be output using the arguments passed to Picture::output(). +

+ +
+ — Pure virtual function: void unsuppress_output (void)
+

Sets do_output to true. Called in + Picture::output() after output() is called on the Shapes. + This way, output of Shapes that couldn't be output when + Picture::output() was called with a particular set of arguments + won't necessarily be suppressed when + Picture::output() is called again with different arguments. +

+ +

f + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Outputting-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Outputting-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,113 ---- + + + Outputting Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

34.12 Outputting

+ +

The functions in this section are are called, directly or indirectly, by + Picture::output(). + See Picture Reference; Outputting. + +

+ — Virtual function: void output (void)
+

Writes the MetaPost code for drawing, filling, filldrawing, undrawing, + unfilling, or unfilldrawing the Solid to out_stream. +

+ +
+ — Virtual function: void suppress_output (void)
+

Used in Picture::output(). Sets do_output to false, if the + Solid cannot be projected using a particular set of arguments to + Picture::output(). +

+ +
+ — Virtual function: void unsuppress_output (void)
+

Used in Picture::output(). Resets do_output to true, + so that the Solid will be tested for projectability again, if the + Picture it's on is output again. +

+ +
+ — Virtual function: vector<Shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Tests whether all of the Shapes belonging to the Solid are + projectable, using the arguments passed to output(). If it is, + this function returns a + vector of pointers to Shape containing a single pointer to + the Solid. If not, an empty vector is returned. +

+ +
+ — Virtual function: bool set_extremes (void)
+

Sets projective_extremes to contain the maximum and minimum + values for the x, y, and z-coordinates of the Points on the + Shape. Used for determining projectability of a Solid + using a particular set of arguments. +

+ +
+ — const inline virtual function: const valarray<real> get_extremes (void)
+

Returns projective_extremes. +

+ +
+ — const virtual functions: real get_minimum_z (void)
+ — : real get_maximum_z (void)
+ — : real get_mean_z (void)
+

Returns the minimum, maximum, or mean z-value, respectively, of the + Points belonging to the Solid. + Used for surface hiding. + See Surface Hiding. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Parallel-Projections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Parallel-Projections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Parallel-Projections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Parallel-Projections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,132 ---- + + + Parallel Projections - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Projections, + Up: Projections +


+
+ +

9.1.1 Parallel Projections

+ +

When a Picture is projected onto the x-y plane, the + x and y-values from the world_coordinates of the Points + belonging to the objects on the + Picture are copied to + their projective_coordinates, which are + used in the MetaPost code written to out_stream. + If a Picture p contains an object in the x-y plane, + or in a plane parallel to the x-y plane, then + the result of p.output(Projections::PARALLEL_X_Y) is more-or-less + equivalent to just using MetaPost without 3DLDF. + +

     Rectangle r(origin, 3, 3, 90);
+      Circle c(origin, 3, 90);
+      c *= r.shift(0, 0, 5);
+      r.draw();
+      c.draw();
+      current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 53. Not displayed.] +
+
+ Fig. 53. +
+

+ +

If the objects do not lie in the x-y plane, or a plane parallel to the + x-y plane, then the projection will be distorted: + +

     current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 54. Not displayed.] +
+
+ Fig. 54. +
+

+ +

Picture::output() can be called with an additional real + argument factor for magnifying or shrinking the Picture. + + + +

     Rectangle r(origin, 4, 4, 90, 60);
+      Circle c(origin, 4, 90, 60);
+      c *= r.shift(0, 0, 5);
+      r.filldraw(black, gray);
+      c.unfilldraw(black);
+      current_picture.output(Projections::PARALLEL_X_Y, .5);
+      current_picture.shift(2.5);
+      current_picture.output(Projections::PARALLEL_X_Y);
+      current_picture.shift(1);
+      current_picture.output(Projections::PARALLEL_X_Y, 2);
+ 
+

+
+ [Figure 55. Not displayed.] +
+
+ Fig. 55. +
+

+ +

Parallel projection onto the x-z and z-y planes are completely analogous + to parallel projection onto the x-y plane. + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,289 ---- + + + Path Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Path Data Members, + Up: Path Reference +


+
+ +

26.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Path (void)
+

Creates an empty Path with no + Points and no connectors. +

+ +
+ — Constructor: void Path (const Point& p0, const Point& p1)
+

Creates a line (more precisely, a line segment) between p0 + and p1. The single + connector between the two Points is set to "--" and the + data member line_switch (of type bool) is set to + true. There are certain operations on Paths that are only + applicable to lines, so it's necessary to store the information that a + Path is a line.1 + +

          Point A(-2, -2.5, -1);
+           Point B(3, 2, 2.5)
+           Path p(A, B);
+           p.show("p:");
+           -| p:
+              (-2, -2.5, -1) -- (3, 2, 2.5);
+ 
+

+
+ [Figure 110. Not displayed.] +
+
+ Fig. 110. +
+

+ +
+ +
+ — Setting function: void set (const Point& p0, const Point& p1)
+

Corresponds to the constructor above. + +

          Point P0(1, 2, 3);
+           Point P1(3.5, -12, 75);
+           Path q;
+           q.set(P0, P1);
+           q.show("q:");
+           -| q:
+              (1, 2, 3) -- (3.5, -12, 75);
+ 
+
+ +
+ — Constructor: void Path (string connector, bool cycle, Point* p, [...], 0)
+

For Paths with an arbitrary number of Points + and one type of connector. + +

connector is passed unchanged to out_file, so it + must be a valid connector in MetaPost. + +

cycle indicates whether the Path is a cycle or not. + cycle_switch is set to cycle. + See Path Reference; Data Members. + The filling and unfilling functions + only work for + Paths that are cycles. + See Path Reference; Drawing and Filling. + If a Path is a cycle, it is up to the user to make sure that it + has sensible Point and connector values; 3DLDF doesn't check + them. If they are not sensible, for instance, if the Path + crosses itself, and you try to fill it, this will cause an error in + MetaPost. It is possible that a Path will be “sensible” in + some projections and not in others, although I have not tested this. + +

p is a pointer to the first Point that should go onto the + Path. + The ellipsis points (...) represent an arbitrary number of + pointers to Points that should go onto the Path. + The final + argument must be 0, + which is interpreted by the C++ + compiler as the null + pointer.2 + +

It is admittedly a bit + awkward to have to type “&p0” rather than “p0”, and + I have frequently forgotten to do it, which causes a compiler error, + but all of the arguments must be pointers in order to be able to use 0 to + indicate the end of the argument list. Convenience in typing function + calls is not a high priority in 3DLDF, because once I've written + an input routine, these function calls should be generated + automatically. It will be more important to define a convenient syntax + for the input routine. + +

          Point P0;
+           Point P1(2);
+           Point P2(2,2);
+           Point P3(0,2);
+           Path p("..", true, &P0, &P1, &P2, &P3, 0);
+           p.draw();
+           
+           
+ 
+

+
+ [Figure 111. Not displayed.] +
+
+ Fig. 111. +
+

+ +
+ +
+ — Setting function: void set (string connector, bool cycle, Point* p, [...], 0)
+

Corresponds to the constructor above. + +

          Point P[4];
+           P[0].set(2, 1, 3);
+           P[3] = P[2] =  P[1] = P[0];
+           P[3] *= P[2] *=  P[1].rotate(3, 12, 18);
+           P[3] *= P[2].shift(-2, -1, 3);
+           P[3].shear(1.5, .5, 3.5);
+           Path q("...", false, &P[0], &P[1], &P[2], &P[3], 0);
+           q.show("q:");
+           -| q:
+              (2, 1, 3) ... (0.92139, 1.51449, 3.29505) ...
+              (-1.07861, 0.514487, 6.29505) ... (2.84065, -3.26065, 6.29505);
+ 
+

+
+ [Figure 112. Not displayed.] +
+
+ Fig. 112. +
+

+ +
+ +
+ — Constructor: void Path (Point* first_point_ptr, char* s, Point* p, [...], 0)
+

Constructor for Paths with an arbitrary number of Points + and connectors. The first, required, argument is a pointer to a + Point, followed by pointers to char alternating with pointers to + Points.3 + The last argument must be 0, i.e., the null pointer. + +

There is no need to indicate by means of an argument whether the + Path is a cycle or not: If it is, the last argument before the 0 + will be a char* (pointer to char), if not, it will be a + Point*. The data member cycle_switch (of type + bool) will be set to true or false accordingly. + +

          Point A;
+           Point B(2, 0);
+           Point C(3, 2);
+           Point D(1, 3);
+           Path p(&A, "..", &B, "..", &C, "--", &D, "...", 0);
+ 
+

+
+ [Figure 113. Not displayed.] +
+
+ Fig. 113. +
+

+ +
+ +
+ — Setting function: void set (Point *first_point_ptr, string s, Point *p, [...], 0)
+

Corresponds to the constructor above. +

+ +
+ — Copy constructor: void Path (const Path& p)
+

Creates a new Path, making it a copy of p. +

+ +
+ — Template specializations: Path* create_new<Path> (const Path* p)
+ — : Path* create_new<Path> (const Path& p)
+

Pseudo-constructors for dynamic allocation of Paths. + They create a Path on the free store and allocate memory for it using + new(Path). They return a pointer to the new Path. + +

If p is a non-zero pointer or a reference, + the new Path will be a copy of + p. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Path>() as its argument. + See Dynamic Allocation of Shapes, for more information. + +

create_new<Path>() is used in the drawing and filling functions + for copying a Path and putting the copy onto a Picture. + See Path Reference; Drawing and Filling. +

+ +
+
+

Footnotes

[1] It isn't sufficient to check whether a + Path consists of only two Points to determine whether it + is a line or not, since a connector with “curl” could cause it + to be non-linear. On the other hand, Paths containing only + colinear Points and the connector "--" are perfectly + legitimate lines. I'm in the process of changing all of the code that + tests for linearity by checking the value of line_switch, so that + it uses is_linear() instead. When I've done this, it may be + possible to eliminate line_switch. + See Path Reference; Data Members, and + Path Reference; Querying.

+ +

[2] Stroustrup, The C++ + Programming Language, p. 88.

+ +

[3] Where possible, I prefer to use the C++ + data + type string rather than char*, however it was necessary to + use char* here because 0 is not a valid string, even + though string may be implemented as char*, + and 0 must be a valid argument, since it is needed to indicate the end + of the argument list.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,225 ---- + + + Path Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

26.1 Data Members

+ +
+ — Protected variable: bool line_switch
+

true if the Path was created using the constructor + Path(const Point& p0, const Point& p1), directly or indirectly. + See Path Reference; Constructors and Setting Functions. + +

          Point p0;
+           Point p1(1, 1);
+           Point p2(2, 3);
+           Path q0(p0, p1);
+           cout << q0.get_line_switch();
+           -| 1
+           Path q1;
+           q1 = q0;
+           cout << q1.get_line_switch();
+           -| 1
+           Path q2 = p0.draw(p1);
+           cout << q2.get_line_switch();
+           -| 1
+           Path q3("..", false, &p1, &p2, &p0, 0);
+           cout << q3.get_line_switch();
+           -| 0
+ 
+

+
+ [Figure 109. Not displayed.] +
+
+ Fig. 109. +
+

+ +

Some Path functions only work on linear Paths, + so it's necessary to be able to distinguish them from non-linear ones. + The function is_linear() should be enough to ensure that all of + these functions work, so I plan to make line_switch obsolete + soon. However, at the moment, it's still needed. + See Path Reference; Querying. +

+ +
+ — Protected variable: bool cycle_switch
+

true if the Path is cyclical, otherwise + false. +

+ +
+ — Protected variable: bool on_free_store
+

true if the Path was dynamically allocated on the free + store. Otherwise false. Set to true only in + create_new<Path>(), which should be the only way Paths are + ever dynamically allocated. + See Path Reference; Constructors and Setting Functions. +

+ +
+ — Protected variable: bool do_output
+

Used in Picture::output(). Set to false if the Path + isn't projectable using the arguments passed to + Picture::output(). + See Picture Reference; Outputting. +

+ +
+ — Protected variable: signed short fill_draw_value
+

Set in the drawing and filling functions, and + used in Path::output(), to determine what MetaPost code to write + to out_stream. + See Path Reference; Drawing and Filling, + and Path Reference; Outputting. +

+ +
+ — Protected variable: const Color* draw_color
+

Pointer to the Color used if the Path is drawn. +

+ +
+ — Protected variable: const Color* fill_color
+

Pointer to the Color used if the Path is filled. +

+ +
+ — Protected variable: string dashed
+

String written to out_stream for the “dash pattern” in a + MetaPost draw or undraw command. If and only if + dashed is not the empty string, “dashed + <dash pattern>” is written to out_stream. + +

Dash patterns have no meaning inside 3DLDF; dashed, if + non-empty, is written unchanged to out_stream. I may change this + in the future. +

+ +
+ — Protected variable: string pen
+

String written to out_stream for the pen to be used in a + MetaPost draw, undraw, filldraw, or + unfilldraw command. If and only if pen is not the + empty string, “withpen <...>” is written to + out_stream. + +

Pens have no meaning inside 3DLDF; pen, if + non-empty, is written unchanged to out_stream. I may change this + in the future. +

+ +
+ — Protected variable: bool arrow
+

Indicates whether an arrow should be drawn when outputting a + Path. Set to true on a Path created on the free + store and put onto a Picture by drawarrow(). +

+ +
+ — Protected variable: valarray<real> projective_extremes
+

Contains the maxima and minima of the x, y, and z-coordinates of the + projections of Points on a Path using a particular + Focus. Set in set_extremes() and used in + Picture::output() for surface hiding. +

+ +
+ — Protected variable: vector<Point*> points
+

Pointers to the Points on the Path. +

+ +
+ — Protected variable: vector<string> connectors
+

The connectors between the Points on the Path. Connectors + are simply strings in 3DLDF, they are written unchanged to + out_stream. +

+ +
+ — Public static variable: const Color* help_color
+

Pointer to a const Color, which becomes the default for + draw_help(). + See Path Reference; Drawing and Filling. + +

Please note that help_color is a pointer to a + const Color, not a const pointer to a Color or a + const pointer to a const Color! It's easy to get confused + by the syntax for these types of pointers.1 +

+ +
+ — Public static variable: string help_dash_pattern
+

The default dash pattern for draw_help(). +

+ +
+ — Public static variable: bool do_help_lines
+

true if help lines should be output, otherwise false. + If false, a call to draw_help() does not cause a copy of + the Path to be created and put onto a Picture. + See Path Reference; Drawing and Filling. +

+ +
+
+

Footnotes

[1] Stroustrup, The C++ + Programming Language, p. 96.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Destructor.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Destructor.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Destructor.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Destructor.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Path Destructor - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

26.3 Destructor

+ +
+ — virtual Destructor: void ~Path (void)
+

All of the Points on a Path are created by + create_new<Point>(), which allocates them dynamically on + the free store. Therefore, the destructor calls delete() on all + of the pointers on points. Following this, it calls + points.clear() and connectors.clear(). + draw_color and fill_color may or may not have been + allocated on the free store, so ~Path() checks this first, and + deletes them, if they were. Then, it sets them to 0. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,103 ---- + + + Path Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Outputting Paths, + Up: Path Reference +


+
+ +

26.17 Intersections

+ +
+ — Function: bool_point intersection_point (const Path& p, const bool trace)
+

Finds the intersection point, if any, of two linear Paths. + Let bp be the bool_point returned by + this function. bp.pt will contains the + intersection point, if it exists. If not, it will contain + INVALID_POINT. If the intersection point exists and lies on both + of the line segments represented by the Path and p, + bp.b will be true, otherwise, false. + +

This function calls Point::intersection_points(), passing the first + and last Points on *this and p as its arguments. If + the trace argument is false, the version of + Point::intersection_points() that finds the intersection point by + means of a vector calculation is used. If it's true, the version + that finds the intersection point of the traces of the lines on the + major planes is used. + See Point Reference; Intersections. + +

          Point A(-1, -1, -1);
+           Point B(1, 1, 1);
+           Path p0(A, B);
+           Point C(-2, 1, 1);
+           Point D(1.75, 0.25, 0.25);
+           Path p1(C, D);
+           bool_point bp = p0.intersection_point(p1);
+           bp.pt.dotlabel("$i$");
+           bp.pt.show("bp.pt:");
+           -| bp.pt: (0.5, 0.5, 0.5)
+ 
+

+
+ [Figure 138. Not displayed.] +
+
+ Fig. 138. +
+

+ +
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,113 ---- + + + Path Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Path Destructor, + Up: Path Reference +


+
+ +

26.4 Operators

+ +
+ — Virtual function: Transform operator*= (const Transform& t)
+

Calls Point::operator*=(t) on each of the Points + on the Path. + See Point Reference; Operators. + This has the effect of + transforming the entire Path by t. Please note that + Path does not have a transform data member of its own. +

+ +
+ — Function: void operator+= (const Point& pt)
+

Copies pt and pushes a pointer to the copy onto + points. The last connector + in the Path will be used to connect the new Point and the + previous one. + +

          Point A(1, 2, 3);
+           Point B(3, 4, 5);
+           Path q;
+           q += A;
+           q += B;
+           q.show("q:");
+           -| q:
+              (1, 2, 3) -- (3, 4, 5);
+ 
+
+ +
+ — const function: Path operator+ (const Point& pt)
+

Copies the Path and pt, and pushes a pointer to the copy of + pt onto points in the new Path. The + last connector in the new Path will be used to connect the new + Point and the previous one. The Path remains unchanged. +

+ +
+ — Function: void operator&= (const Path& pa)
+

Concatenates two Paths. The result is assigned to *this. + Neither *this nor pa may be cyclical, i.e., + cycle_switch must be false for both Paths. +

+ +
+ — const function: Path operator& (const Path& pa)
+

Returns a Path representing the concatenation of *this and + pa. *this remains unchanged. + Neither *this nor pa may be cyclical, i.e., + cycle_switch must be false for both Paths. +

+ +
+ — Function: void operator+= (const string s)
+

Pushes s onto connectors. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Path-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Path-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,79 ---- + + + Path Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Plane Reference, + Up: Top +


+
+ +

26 Path Reference

+ +

Class Path is defined in paths.web. + It is derived from Shape using protected derivation. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,114 ---- + + + Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Drawing and Labeling Points, + Up: Top +


+
+ +

6 Paths

+ +

Points alone are not enough for making useful drawings. The next + step is to combine them into Paths, which are similar to + Metafont's paths, except that they are three-dimensional. + A Path consists of a number of Points and strings + representing the connectors. The latter are not processed by + 3DLDF, but are passed unchanged to the output file. They must be valid + connectors for MetaPost, e.g.: + +

+

     ..
+      ...
+      --
+      ---
+      &
+      curl{2}..
+      {dir 60}..
+      {z1 - z2}..
+      .. tension 1 and 1.5..
+      ..controls z1 and z2..
+ 
+

Usually, it will only make sense to use .. or , and not + ..., , tension, curl, controls, or any of the + other possibilities, in Paths, unless + you are sure that they will only be viewed with no foreshortening due to + the perspective + projection. This can be the case, when a Path lies in a plane + parallel to one of the major planes, and is projected using parallel + projection onto that plane. Otherwise, + the result of using these connectors is likely to be unsatisfactory, because + MetaPost performs its calculations based purely on the two-dimensional + values of the points in the perspective projection. + While the Points on the Path will be projected correctly, + the course of the Path between these Points is likely to + differ, depending on the values of the Focus + used (see Focuses), so that + different views of the same Path may well be mutually + inconsistent. + This problem doesn't arise with “”, since the perspective + projection does not “unstraighten” straight lines, + but it does with “..”, even without tension, curl, + or controls. + The solution is to use enough Points, since a greater number of + Points on a Path tends to reduce the number + of possible courses through the Points.1 + +

+ +
+
+

Footnotes

[1] I believe that + counter-examples could probably constructed, but for the most common + cases, the principle applies.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Pattern-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Pattern-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Pattern-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Pattern-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Pattern Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Circle Reference, + Up: Top +


+
+ +

33 Pattern Reference

+ +

There is no currently no class “Pattern”. + If it turns out to be + useful for this purpose, I will define a Pattern class, and + perhaps additional derived classes. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Performing-Transformations-on-Ellipses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Performing-Transformations-on-Ellipses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Performing-Transformations-on-Ellipses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Performing-Transformations-on-Ellipses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,79 ---- + + + Performing Transformations on Ellipses - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

31.3 Performing Transformations

+ +
+ — Virtual function: Transform do_transform (const Transform& t, [bool check = false])
+

Performs a transformation on an Ellipse. The Points on + the Ellipse are multiplied by t. + Then, if check is true, + is_elliptical() is called on the Ellipse. + If the transformation has caused it to + become non-elliptical, axis_h and axis_v are set to + INVALID_REAL, and a warning is issued to stderr. + center, focus0, and focus1 are not set to + INVALID_POINT. They may may no longer really be + the center and foci of the (non-elliptical) Ellipse, but they may + have some use for the programmer and/or user. + +

If check is true, and the transformation does not cause + *this to become non-elliptical, + axis_h, axis_v, linear_eccentricity, + numerical_eccentricity, focus0, and + focus1 are recalculated. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Perspective-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Perspective-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Perspective-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Perspective-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,117 ---- + + + Perspective Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Utility Functions, + Up: Utility Functions +


+
+ +

38.1 Perspective Functions

+ +
+ — Function: void persp_0 (const real front_corner_x, const real front_corner_z, const real side_lft, const real side_rt, const real angle_rt, const real f_2_cv, const real gl_2_cv, [const real horizon_lft = 6, [real horizon_rt = 0, [real gl_lft = 0, [real gl_rt = 0]]]])
+

Defined in utility.web. + This function is used for the figure in The Perspective Projection, illustrating a perspective projection as it could be done + by hand. It draws a rectangle in the ground plane and the construction + lines used for putting it into perspective. It also labels the + vanishing and measuring points. + +

The arguments: +

+
const real front_corner_x
The x-coordinate of the front corner of the rectangle. + +
const real front_corner_z
The z-coordinate of the front corner of the rectangle. + +
const real side_lft
The length of the left side of the rectangle. + +
const real side_rt
The length of the right side of the rectangle. + +
const real angle_rt
The angle at which the right side of the rectangle recedes to the + horizon. + +
const real f_2_cv
The distance from the focus to the center of vision. + +
const real gl_2_cv
The distance of the ground line to the center of vision. + +
const real horizon_lft
Default: 6. + The length of the horizon line leftwards of the center of vision. + +
real horizon_rt
Default: 0. + The length of the horizon line rightwards of the center of vision. + +
real gl_lft
Default: 0. + The length of the ground line leftwards of the line from the focus to + the center of vision. + +
real gl_rt
Default: 0. + The length of the ground line rightwards of the line from the focus to + the center of vision. +
+ +

Example: + +

          persp_0(3, 2, 10, 5, 47.5, 7, 5, 8.5, 9.5, 8.5, 9.5);
+ 
+

+
+ [Figure 199. Not displayed.] +
+
+ Fig. 199. +
+

+ +
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Constructors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Constructors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Constructors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Constructors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Picture Constructors - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Picture Global Variables, + Up: Picture Reference +


+
+ +

21.3 Constructors

+ + +
+ — Default constructor: void Picture (void)
+

Creates an empty Picture. +

+ +
+ — Copy constructor: void Picture (const Picture& p)
+

Creates a copy of Picture p. + +

          Circle c(origin, 3);
+           c.draw();
+           current_picture.output(Projections::PARALLEL_X_Z);
+           Picture new_picture(current_picture);
+           new_picture.shift(2);
+           new_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 77. Not displayed.] +
+
+ Fig. 77. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,110 ---- + + + Picture Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Picture Reference, + Up: Picture Reference +


+
+ +

21.1 Data Members

+ +
+ — Private variable: Transform transform
+

Applied to the Shapes on the Picture when the latter is + output. It is initialized as the identity Transform, and can be + modified by the transformation functions, by + Picture::operator*=(const Transform&) + (see Picture Reference; Operators), and by + Picture::set_transform() + (see Picture Reference; Modifying). +

+ +
+ — Private variable: vector<Shape*> shapes
+

Contains pointers to the Shapes on the Picture. + When a drawing or filling function is invoked for a Shape, a copy + is dynamically allocated and a pointer to the copy is placed onto + shapes. +

+ +
+ — Private variable: vector<Label*> labels
+

Contains pointers to the Labels on the Picture. When a + Point is labelled, either directly or through a call to + label() or dotlabel() for another type of + Shape1, + a Label is dynamically allocated, the Point is copied to + *Label::pt, and a pointer to the Label is placed onto + labels. +

+ +
+ — Private variable: bool do_labels
+

Used for enabling or disabling output of Labels when outputting a + Picture. The default value is true. It is set to + false by using suppress_labels() and can be reset to + true by using unsuppress_labels(). + See Picture Reference; Output Functions. + +

Often, when a Picture is copied, transformed, and output again in + a single figure, it's undesirable to have the Labels output again + in their new positions. To avoid this, use suppress_labels() + after outputting the Picture the first time. +

+ +
+
+

Footnotes

[1] label() and dotlabel() + are currently only defined for Point and Path (and the + latter's derived classes), i.e., not for Solid and its derived + classes.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Global-Variables.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Global-Variables.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Global-Variables.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Global-Variables.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,63 ---- + + + Picture Global Variables - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Picture Data Members, + Up: Picture Reference +


+
+ +

21.2 Global Variables

+ +
+ — Variable: Variable Picture current_picture
+

The Picture used as the default by the drawing and filling + functions. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,114 ---- + + + Picture Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

21.4 Operators

+ +
+ — Assignment operator: void operator= (const Picture& p)
+

Makes *this a copy of p, destroying the old contents of *this. +

+ +
+ — Operator: void operator+= (const Picture& p)
+

Adds the contents of p to *this. p remains unchanged. +

+ +
+ — Operator: void operator+= (Shape* s)
+

Puts s onto shapes. Note that the pointer s + itself is put onto shapes, so any allocation and copying must be + performed first. This is a low-level function that users normally won't + need to use directly. +

+ +
+ — Operator: void operator+= (Label* label)
+

Puts label onto labels. + Note that the pointer label + itself is put onto labels, so any allocation and copying must be + performed first. This is a low-level function that users normally won't + need to invoke directly. +

+ +
+ — Operator: Transform operator*= (const Transform& t)
+

Multiplies transform by t. This has the effect of + transforming all of the Shapes on shapes and all of + the Points of the Labels on labels by t upon + output. + +

          Transform t;
+           t.rotate(0, 0, 180);
+           t.shift(3);
+           Reg_Polygon pl(origin, 5, 3, 90);
+           pl.draw();
+           pl.label();
+           current_picture.output(Projections::PARALLEL_X_Y);
+           current_picture *= t;
+           current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 78. Not displayed.] +
+
+ Fig. 78. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Output-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Output-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Output-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Output-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,237 ---- + + + Picture Output Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Picture Output Namespaces, + Up: Outputting Pictures +


+
+ +

21.8.2 Output Functions

+ +
+ — Function: void output (const Focus& f, [const unsigned short projection = Projections::PERSP, [real factor = 1, [const unsigned short sort_value = Sorting::MAX_Z, [const bool do_warnings = true, [const real min_x_proj = -40, [const real max_x_proj = 40, [const real min_y_proj = -40, [const real max_y_proj = 40, [const real min_z_proj = -40, [const real max_z_proj = 40]]]]]]]]]])
+ — Function: void output ([const unsigned short projection = Projections::PERSP, [real factor = 1, [const unsigned short sort_value = Sorting::MAX_Z, [const bool do_warnings = true, [const real min_x_proj = -40, [const real max_x_proj = 40, [const real min_y_proj = -40, [const real max_y_proj = 40, [const real min_z_proj = -40, [const real max_z_proj = 40]]]]]]]]]])
+

These functions create a two-dimensional projection of the objects on the + Picture and write MetaPost code to out_stream for + drawing it. + +

The arguments: + +

+
const Focus& f
The Focus used for projection, also known as the center of + projection, or the camera. + This argument is used in the first version only. + The second version, without a const Focus& f argument, + merely calls the first version and passes it the global variable + default_focus as its first argument, so default_focus is + effectively the default for f. Defining two versions in this way makes it + possible to call + output() with projection as its first (and possibly only) + argument. If instead, f were an optional argument with + default_focus as its default, this wouldn't have been possible. It + also wouldn't be possible to have f have a default in the first + version, and to retain the second version, because the compiler wouldn't + be able to resolve a call to output() with no arguments. + +
const unsigned short projection
Default: Projections::PERSP. + The type of projection. Valid values are const unsigned shorts + defined in namespace Projections + (see Namespace Projections):
+ PERSP for the perspective projection,
+ PARALLEL_X_Y for parallel projection onto the x-y plane,
+ PARALLEL_X_Z for parallel projection onto the x-z plane, and
+ PARALLEL_Z_Y for parallel projection onto the z-y plane. + %% !! TO DO: + I plan to add isometric and axionometric projections soon. + +
real factor
Default: 1. + Passed from output() to + extract() and from there to project(). The + world_coordinates of the Points that are projected are + multiplied by factor, which enlarges or shrinks the projected + image without altering the Picture itself. factor + is probably most useful for parallel projections, where the Focus + f isn't used; with a perspective projection, the parameters of + the Focus can be used to influence the size of the projected + image. + +
const unsigned short sort_value
Default: Sorting::MAX_Z. + The value used should be one of the constants defined in + namespace Sorting, See Namespace Sorting, above. + If MAX_Z (the default) is used, the Shapes on the + Picture are sorted according to the maximum z-value of the + projective_extremes of the Points belonging to the + Shape. If MIN_Z is used, + they are sorted according to the minimum z-value, and + if MEAN_Z is used, they are sorted according to the mean of + the maximum and minimum z-values. If NO_SORT is used, the + Shapes are output in the order in which they were put onto the + Picture. + +

The surface hiding algorithm + implemented in 3DLDF is quite primitive, and doesn't always work right. + For Shapes that intersect, it can't work right. + + I plan to work on improving the surface hiding algorithm soon. This is + not a trivial problem. To solve it properly, each Shape on a + Picture must be tested for intersection with every other + Shape on the Picture. If two or more Shapes intersect, + they must be broken up into smaller objects until there are no more + intersections. I don't expect to have a proper solution soon, but I + expect that I will be able to make some improvements. + See Surface Hiding. + +

const bool do_warnings
Default: true. If true, output() issues warnings + to stderr (standard error output) if a Shape cannot be + output because it lies + outside the limits set by the following arguments. Sometimes, a user + may only want to project a portion of a Picture, in which case + such warnings would not be helpful. In this case, do_warnings + should be false. + +
const real min_x_proj
Default: -40. The minimum x-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[0] of any Point on a + Shape is less than min_x_proj, the Shape will not be + projected at all. + +
const real max_x_proj
Default: 40. + The maximum x-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[0] of any Point on a + Shape is greater than max_x_proj, the Shape will not be + projected at all. + +
const real min_y_proj
Default: -40. + The minimum y-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[1] of any Point on a + Shape is less than min_y_proj, the Shape will not be + projected at all. + +
const real max_y_proj
Default: 40. + The maximum y-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[1] of any Point on a + Shape is greater than max_y_proj, the Shape will not be + projected at all. + +
const real min_z_proj
Default: -40. + The minimum z-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[2] of any Point on a + Shape is less than min_z_proj, the Shape will not be + projected at all. + +
const real max_z_proj
Default: 40. + The maximum z-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[2] of any Point on a + Shape is greater than max_z_proj, the Shape will not be + projected at all. +
+

+ +
+ — Function: void suppress_labels (void)
+

Suppresses output of the Labels on a Picture when + output() is called. This can be useful when a Picture is + output, transformed, and output again, one or more times, in a single figure. + Usually, it will not be desirable to have the Labels output more + than once. + +

In [next figure] + , current_picture is output three times, but the + Labels on it are only output once. + +

          Ellipse e(origin, 3, 5);
+           e.label();
+           e.draw();
+           Point pt0(-3);
+           Point pt1(3);
+           pt0.draw(pt1);
+           Point pt2(0, 0, -4);
+           Point pt3(0, 0, 4);
+           pt2.draw(pt3);
+           pt0.dotlabel("0", "lft");
+           pt1.dotlabel("1", "rt");
+           pt2.dotlabel("2", "bot");
+           pt3.dotlabel("3");
+           current_picture.output(Projections::PARALLEL_X_Z);
+           current_picture.rotate(0, 60);
+           current_picture.suppress_labels();
+           current_picture.output(Projections::PARALLEL_X_Z);
+           current_picture.rotate(0, 60);
+           current_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 79. Not displayed.] +
+
+ Fig. 79. +
+

+ +
+ +
+ — Inline function: void unsuppress_labels (void)
+

Sets do_labels to true. If a Picture contains + Labels, unsuppress_labels() ensures that they will be + output, when Picture::output() is called, so long as there is no + intervening call to suppress_labels() or kill_labels(). +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Output-Namespaces.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Output-Namespaces.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Output-Namespaces.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Output-Namespaces.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Picture Output Namespaces - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Outputting Pictures, + Up: Outputting Pictures +


+
+ +

21.8.1 Namespaces

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Picture-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Picture-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Picture Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Label Reference, + Up: Top +


+
+ +

21 Picture Reference

+ +

Class Picture is defined in pictures.web. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Pictures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Pictures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Pictures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Pictures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,286 ---- + + + Pictures - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Solid Figures, + Up: Top +


+
+ +

9 Pictures

+ +

Applying drawing and filling operations to the drawable objects described + in the previous chapters isn't enough to produce output. These + operations merely modify the Picture object that was passed to + them as an argument (current_picture, by default). + +

Pictures in 3DLDF are quite different from pictures in + MetaPost. + When a drawing or filling operation is applied to an object O, a + copy of O, C, is allocated on the free store, a pointer to + Shape S is pointed at C, and S is pushed onto + the vector<Shape*> shapes on the Picture P, which + was passed as an argument to the drawing or filling command. The + arguments for the pen, + dash pattern, Color, and any others, are used to set the + corresponding data members of C (not O). + +

In order to actually + cause MetaPost code to be written to the output file, it is necessary + to invoke P.output(). Now, the appropriate version of + output() is applied to each of the objects pointed to + by a pointer on P.shapes. output() is a pure + virtual function in Shape, so all classes derived from + Shape must have an output() function. So, if + shapes[0] points to a Path, + Path::output() is called, if + shapes[1] points to a Point, + Point::output() is called, and if shapes[2] points to an + object of a type derived from Solid, Solid::output() is + called. + Point, Path, and Solid are namely the only classes + derived from Shape for which a version of output() is defined. All + other Shapes are derived from one of these classes. + These output() + functions then write the MetaPost code to the + output file through the output file stream out_stream. + +

     beginfig(1);
+      default_focus.set(0, 0, -10, 0, 0, 10, 10);
+      Circle c(origin, 3, 90);
+      c.draw();
+      c.shift(1.5);
+      c.draw();
+      current_picture.output();
+      endfig(1);
+ 
+

+
+ [Figure 50. Not displayed.] +
+
+ Fig. 50. +
+

+ +

The C++ + code for [the previous figure] + starts with the command + beginfig(1) and ends with the command + endfig(1). + They simply write “beginfig(<arg> + )” and + “endfig()” to + out_stream, + The optional + unsigned int argument to endfig() is not written to + out_stream, it's merely + “syntactic sugar” for the user. + + + +

In MetaPost, the endfig command causes output and then clears + currentpicture. This is not the case in 3DLDF, where + Picture::output() and Picture::clear() must + be invoked explicitly: + +

     beginfig(1);
+      Point p0;
+      Point p1(1, 2, 3);
+      p0.draw(p1);
+      current_picture.output();
+      endfig(1);
+      
+      beginfig(2);
+      current_picture.clear();
+      Circle C(origin, 3);
+      C.fill();
+      current_picture.output();
+      endfig(2);
+ 
+

In [next figure] + , two Pictures are used within a single figure. + +

     beginfig(1);
+      Picture my_picture;
+      default_focus.set(0, 0, -10, 0, 0, 10, 10);
+      Circle c(origin, 3, 90);
+      c.draw(my_picture);
+      my_picture.output();
+      c.shift(1.5);
+      c.fill(light_gray);
+      current_picture.output();
+      endfig(1);
+ 
+

+
+ [Figure 51. Not displayed.] +
+
+ Fig. 51. +
+

+ +

Multiple objects, or complex objects made up of sub-objects, can be + stored in a Picture, so that operations can be applied to them + as a group: + +

     default_focus.set(7, 5, -10, 7, 5, 10, 10);
+      Cuboid c0(origin, 5, 5, 5);
+      c0.shift(0, 0, 3);
+      c0.draw();
+      Circle z0(c0.get_rectangle_center(0), 2.5, 90, 0, 0, 64);
+      z0.draw();
+      Circle z1(z0);
+      z1.shift(0, 0, -1);
+      z1.draw();
+      int i;
+      int j = z0.get_size();
+      for (i = 0; i < 8; ++i)
+          z0.get_point(i * j/8).draw(z1.get_point(i * j/8));
+      Cuboid c1(c0.get_rectangle_center(4), 5, 3, 3);
+      c1.shift(0, 2.5);
+      c1.draw();
+      Rectangle r0 = *c1.get_rectangle_ptr(3);
+      Point p[10];
+      for (i = 0; i < 4; ++i)
+        p[i] = r0.get_point(i);
+      p[4] = r0.get_mid_point(0);
+      p[5] = r0.get_mid_point(2);
+      p[6] = p[4].mediate(p[5], 2/3.0);
+      Circle z2(p[6], 2, 90, 90, 0, 16);
+      z2.draw();
+      Circle z3 = z2;
+      z3.shift(3);
+      z3.draw();
+      j = z2.get_size();
+      for (i = 0; i < 8; ++i)
+          z2.get_point(i * j/8).draw(z3.get_point(i * j/8));
+      p[7] = c0.get_rectangle_center(2);
+      p[7].shift(-4);
+      p[8] = c0.get_rectangle_center(3);
+      p[8].shift(4);
+      current_picture.output();
+      current_picture.rotate(45, 45);
+      current_picture.shift(10, 0, 3);
+      current_picture.output();
+ 
+

+
+ [Figure 52. Not displayed.] +
+
+ Fig. 52. +
+

+ +

Let's say the complex object in [the previous figure] + represents a + furnace. From the point of view of 3DLDF, however, it's not an object + at all, and the drawing consists of a collection of unrelated + Cuboids, Circles, Rectangles, and Paths. + If we hadn't put it into a Picture, we could still have rotated + and shifted it, but only by applying the operations to each of the + sub-objects individually. + +

One consequence of the way Pictures are output in 3DLDF is, that + the following code will not work: + +

     beginfig(1);
+      Point p(1, 2);
+      Point q(1, 3);
+      out_stream << "pickup pencircle scaled .5mm;" << endl;
+      origin.draw(p);
+      out_stream << "pickup pensquare xscaled .3mm rotated 30;" << endl;
+      origin.draw(q);
+      current_picture.output();
+      endfig();
+ 
+

This is the MetaPost code that results: + +

     beginfig(1);
+      pickup pencircle scaled .5mm;
+      pickup pensquare xscaled .3mm rotated 30;
+      draw (0.000000cm, -3.000000cm) -- (1.000000cm, -1.000000cm);
+      draw (0.000000cm, -3.000000cm) -- (1.000000cm, 0.000000cm);
+      endfig;
+ 
+

It's perfectly legitimate to write + raw MetaPost code to out_stream, as in lines 4 and 6 of this + example. However, the draw() commands do not cause any output to + out_stream. The MetaPost drawing commands are written to + out_stream when current_picture.output() is called. + Therefore, the pickup commands are “bunched up” before the + drawing commands. + In this example, + setting currentpen to pencircle scaled .5mm has no effect, + because it is immediately reset to + pensquare xscaled .3mm rotated 30 in the MetaPost code, before + the draw commands. + It is not possible to change currentpen in this way within a + Picture. + Since the draw() commands in the 3DLDF + code didn't specify a pen argument, + currentpen with its final value is used for both of the MetaPost + draw commands. For any given invocation of + Picture::output(), there can only be one value of + currentpen. All other pens must be passed as arguments to the + drawing commands. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Figures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Figures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Figures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Figures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Plane Figures - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Paths, + Up: Top +


+
+ +

7 Plane Figures

+ +

3DLDF currently includes the following classes representing plane + geometric figures: Polygon, Reg_Cl_Plane_Curve + (“Regular Closed Plane Curve”), Reg_Polygon (“Regular + Polygon”), Rectangle, Ellipse and + Circle. Polygon and Reg_Cl_Plane_Curve are derived + from Path, Reg_Polygon and Rectangle are derived + from Polygon, and Ellipse and Circle are derived + from Reg_Cl_Plane_Curve. Polygon and + Reg_Cl_Plane_Curve are meant to be used as base classes only, so + objects of these types should normally never be declared. + +

Since Reg_Polygon, Rectangle, Ellipse, and + Circle all ultimately derive from Path, they are really + just special kinds of Path. + In particular, they inherit their drawing and filling functions from + Path, and their transformation functions take the same arguments + as the Path versions. + They also have constructors + and setting functions that work in a similar way, with a few minor + differences, to account for their different natures. + See Polygon Reference, Rectangle Reference, + Ellipse Reference, and Circle Reference, for complete + information on these classes. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,170 ---- + + + Plane Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Planes Returning Information, + Up: Plane Reference +


+
+ +

25.6 Intersections

+ +
+ — const function: bool_point intersection_point (const Point& p0, const Point& p1)
+ — const function: bool_point intersection_point (const Path& p)
+

These functions find the intersection point of the Plane and a + line. In the first version, the + line is defined by the two Point arguments. In the second + version, the Path p must be linear, i.e., + p.is_linear() must be true. + +

Both versions of intersection_point() return a bool_point + bp, where bp.pt is the intersection point, or + INVALID_POINT, if there is none. If an intersection point is + found, bp.b will be true, otherwise false. + Returning a bool_point makes it possible to test for success + without comparing the Point returned against INVALID_POINT. + +

          Point center(2, 2, 3.5);
+           Reg_Polygon h(center, 6, 4, 80, 30, 10);
+           Plane q = h.get_plane();
+           Point P0 = center.mediate(h.get_point(2));
+           P0.shift(5 * (N - center));
+           Point P1(P0);
+           P1.rotate(h.get_point(1), h.get_point(4));
+           P1 = 3 * (P1 - P0);
+           P1.shift(P0);
+           P1.shift(3, -.5, -2);
+           bool_point bp = q.intersection_point(P0, P1);
+           Point i_P = bp.pt;
+           Point P4 = h.get_point(3).mediate(h.get_point(0), .75);
+           P4.shift(N - center);
+           Point P5(P4);
+           P5.rotate(h.get_point(3), h.get_point(0));
+           P4.shift(-1, 2);
+           Path theta(P4, P5);
+           bp = q.intersection_point(theta);
+           Point i_theta = bp.pt;
+           draw_axes();
+ 
+

+
+ [Figure 107. Not displayed.] +
+
+ Fig. 107. +
+

+ +
+ +
+ — const function: Line intersection_line (const Plane& p)
+

Returns a Line l. representing the line of intersection of two + Planes. See Line Reference. + +

In [next figure] + , intersection_line() is used to find the line of + intersection of the Planes derived from the Rectangles + r_0 and r_1 using get_plane() + (see Paths Reference; Querying). + Please note that there is no guarantee that l.position will + be in a convenient place for your drawing. A bit of fiddling was + needed to find the Points P_2 and P_3. + + I plan to add functions for finding the intersection lines of plane + figures, but haven't done so yet. + +

          Rectangle r0(origin, 5, 5, 10, 15, 6);
+           Rectangle r1(origin, 5, 5, 90, 50, 10);
+           r1 *= r0.rotate(30, 30, 30);
+           r1 *= r0.shift(1, -1, 3);
+           Plane q0 = r0.get_plane();
+           Plane q1 = r1.get_plane();
+           Line l = q0.intersection_line(q1);
+           l.show("l:");
+           -| l:
+              position: (0, 11.2193, 20.0759)
+              direction: (0.0466595, -0.570146, -0.796753)
+           Point P0(l.direction);
+           P0.shift(l.position);
+           P0.show("P0:");
+           -| P0: (0.0466595, 10.6491, 19.2791)
+           Point P1(-l.direction);
+           P1.shift(l.position);
+           Point P2(P0 - P1);
+           P2 *= 12.5;
+           P2.shift(P0);
+           cout << P2.is_on_plane(q0);
+           -| 1
+           cout << P2.is_on_plane(q1);
+           -| 1
+           Point P3(P0 - P1);
+           P3 *= 7;
+           P3.shift(P0);
+           cout << P3.is_on_plane(q0);
+           -| 1
+           cout << P3.is_on_plane(q1);
+           -| 1
+ 
+

+
+ [Figure 108. Not displayed.] +
+
+ Fig. 108. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,81 ---- + + + Plane Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Line Reference, + Up: Top +


+
+ +

25 Plane Reference

+ +

The struct Plane is defined in planes.web. + Planes are not Shapes. They are used for + performing vector operations. A Plane is defined by a + Point representing a point on the plane, a Point + representing the normal to the plane, and the distance of the plane from + the origin. + +

The most common use of Planes is to represent the + plane in which an existing plane figure lies. Therefore, they + most likely to be created by using Path::get_plane(). + See Path Reference; Querying. However, class + Plane does have constructors for creating Planes directly, if + desired. + See Planes Reference; Constructors. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Tesselations.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Tesselations.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Plane-Tesselations.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Plane-Tesselations.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,182 ---- + + + Plane Tesselations - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Pattern Reference, + Up: Pattern Reference +


+
+ +

33.1 Plane Tesselations

+ +

3DLDF can be used to make perspective projections of plane tesselations + and other two-dimensional patterns. These can be used for + drawing tiled floors and other architectural items, among other things. + While patterns can be generated by using the basic facilities of C++ + and + 3DLDF without any specially defined functions, it can be useful to + define such functions. + +

3DLDF currently contains only one function for drawing patterns based on + a plane tessellation. I plan to add more soon. + +

+ — Function: unsigned int hex_pattern_1 ([real diameter_outer = 5, [real diameter_middle = 0, [real diameter_inner = 0, [unsigned short first_row = 5, [unsigned short double_rows = 10, [unsigned short row_shift = 2, [Color draw_color_outer = *Colors::default_color, [Color fill_color_outer = *Colors::background_color, [Color draw_color_middle = *Colors::default_color, [Color fill_color_middle = *Colors::background_color, [Color draw_color_inner = *Colors::default_color, [Color fill_color_inner = *Colors::background_color, [string pen_outer = "pencircle scaled .5mm", [string pen_middle = "pencircle scaled .3mm", [string pen_inner = "pencircle scaled .3mm", [Picture& picture = current_picture, [unsigned int max_hexagons = 1000]]]]]]]]]]]]]]]]])
+

Draws a pattern consisting of hexagons forming a tesselation of the x-z + plane, with additional hexagons within them. + +

The arguments: +

+
real diameter_outer
Default: 5. The diameter of the outer hexagon in each set of three + hexagons. The outer hexagons form a tessellation of the plane. + +
real diameter_middle
Default: 0. The diameter of the middle hexagon in a set of three + hexagons. + +
real diameter_inner
Default: 0. The diameter of the inner hexagon in a set of three + hexagons. + +
unsigned short first_row
Default: 5. The number of sets of hexagons in the first single row. + The second single row will have + first_row + 1 sets of hexagons. + +
unsigned short double_rows
Default: 10. The number of double rows drawn. + +
unsigned short row_shift
Default: 2. + For row_shift + != 0, + the number of sets of hexagons in each (single) row is + increased by 2 every row_shift rows. If row_shift == + 0, the number sets of hexagons remains constant. + The rows remain centered around the z-axis. + +
Color draw_color_outer
Default: *Colors::default_color. + The Color used for drawing the outer hexagons. + +
Color fill_color_outer
Default: *Colors::background_color. + The Color used for filling the outer hexagons. + +
Color draw_color_middle
Default: *Colors::default_color. + The Color used for drawing the middle hexagon. + +
Color fill_color_middle
Default: *Colors::background_color. + The Color used for filling the middle hexagons. + +
Color draw_color_inner
Default: *Colors::default_color. + The Color used for drawing the inner hexagons. + +
Color fill_color_inner
Default: *Colors::background_color. + The Color used for filling the inner hexagons. + +
string pen_outer
Default: "pencircle scaled .5mm". + The pen used for drawing the outer hexagons. + +
string pen_middle
Default: "pencircle scaled .3mm". + The pen used for drawing the middle hexagons. + +
string pen_inner
Default: "pencircle scaled .3mm". + The pen used for drawing the inner hexagons. + +
Picture& picture
Default: current_picture. + The Picture onto which the pattern is put. + +
unsigned int max_hexagons
Default: 1000. + The maximum number of hexagons that will be drawn. + +
+ +

Draws a pattern in the x-z plane consisting of hexagons. The outer + hexagons form a tessellation. The middle and inner hexagons fit + within the outer hexagons. The hexagons are drawn in double rows. + The tessellation can be repeated by copying a + double row and shifting the copy to lie directly behind the first double + row. If the Picture with the pattern is projected with the + Focus in front of the pattern, looking in the direction of the back + of the pattern, + the first row of hexagons will appear larger than the rows + behind it. Therefore, in order for the perspective projection of the + pattern to fill a rectangular area on the plane of projection, + it will generally be necessary to increase the number of sets of + hexagons in each double row. On the other hand, if the same number of + sets of hexagons were used in the front double row, as will be needed for the + back double row, many of them would probably be unprojectable. + +

The return value of this function is the number of hexagons drawn. + +

          default_focus.set(0, 10, -10, 0, 10, 25, 10);
+           hex_pattern_1(1, 0, 0, 5, 5);
+ 
+

+
+ [Figure 178. Not displayed.] +
+
+ Fig. 178. +
+

+ +
          default_focus.set(-5, 5, -10, 0, 10, 25, 10);
+           hex_pattern_1(2, 1.5, 1, 2, 5, 2, black, gray, black,
+                         light_gray, black);
+ 
+

+
+ [Figure 179. Not displayed.] +
+
+ Fig. 179. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Constructors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Constructors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Constructors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Constructors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,121 ---- + + + Planes Constructors - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Planes Global Constants, + Up: Plane Reference +


+
+ +

25.3 Constructors

+ +
+ — Default constructor: void Plane (void)
+

Creates a degenerate Plane with + point == normal == origin, and + distance == 0. + +

Planes constructed using this constructor will probably be set + using the assignment operator + or Path::get_plane() + immediately, or + very soon after being declared. + See Planes Reference; Operators, and + Paths Reference; Querying. +

+ +
+ — Copy constructor: void Plane (const Plane& p)
+

Creates a new Plane, making it a copy of p. +

+ +
+ — Constructor: void Plane (const Point& p, const Point& n)
+

If p is not equal to n, this constructor creates a + Plane and sets point to p. normal + is set to n, and made a unit vector. + distance is calculated according to the following formula: + Let n stand for normal, p for point, and d for + distance: + d = -p \dot n. + If d = 0, origin + lies in the Plane. If d > 0, origin lies on the side of the + Plane that normal points to, considered to be “outside”. + If d<0, origin lies on the side of the + Plane that normal does not point to, considered to be + “inside”. + +

However, if p == n, point and normal are + both set to INVALID_POINT, and distance is set to + INVALID_REAL, i.e., *this will be equal to + INVALID_PLANE + (see Planes Reference; Global Constants). + +

          Point P(1, 1, 1);
+           Point N(0, 1);
+           N.rotate(-35, 30, 20);
+           N.show("N:");
+           -| N: (-0.549659, 0.671664, 0.496732)
+           Plane q(P, N);
+           cout << q.distance;
+           -| -0.618736
+ 
+

+
+ [Figure 105. Not displayed.] +
+
+ Fig. 105. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,76 ---- + + + Planes Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Plane Reference, + Up: Plane Reference +


+
+ +

25.1 Data Members

+ +

Because the main purpose of Plane is to + provide information about Shapes, its data members are all + public. + +

+ — Public variable: Point point
+

Represents a point on the plane. +

+ +
+ — Public variable: Point normal
+

Represents the normal to the plane. +

+ +
+ — Public variable: real distance
+

The distance of the plane from the origin. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Global-Constants.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Global-Constants.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Global-Constants.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Global-Constants.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Planes Global Constants - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Planes Data Members, + Up: Plane Reference +


+
+ +

25.2 Global Constants

+ +
+ — Constant: const Plane INVALID_PLANE
+

A Plane with point == normal, and + distance == INVALID_REAL. + +

INVALID_PLANE is returned from Path::get_plane(), if the + Path is not planar. See Path Reference; Querying. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,101 ---- + + + Planes Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Planes Constructors, + Up: Plane Reference +


+
+ +

25.4 Operators

+ +
+ — Assignment operator: const Plane& operator= (const Plane& p)
+

Sets point to p.point, normal to + p.normal, and distance to p.distance. + The return value is p, so that invocations of this function can be + chained. + +

          Point pt(2, 2.3, 6);
+           Point norm(-1, 12, -36);
+           Plane A(pt, norm);
+           Plane B;
+           Plane C;
+           B = C = A;
+           A.show("A:");
+           -| A:
+              normal: (-0.0263432, 0.316118, -0.948354)
+              point: (2, 2.3, 6)
+              distance == 5.01574
+           cout << (A == B && A == C && B == C);
+           -| 1
+ 
+
+ +
+ — const operator: bool operator== (const Plane& p)
+

Equality operator. Compares *this and p, and returns + true, if point == p.point, + normal == p.normal, and + distance == p.distance, + otherwise false. +

+ +
+ — const operator: bool operator!= (const Plane& p)
+

Inequality operator. Compares *this and p and returns + true, if point != + p.point, or + normal != + p.normal, or + distance != + p.distance. + Otherwise, it returns false. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Returning-Information.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Returning-Information.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Returning-Information.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Returning-Information.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,133 ---- + + + Planes Returning Information - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Planes Operators, + Up: Plane Reference +


+
+ +

25.5 Returning Information

+ +
+ — const function: real_short get_distance (const Point& p)
+ — const function: real_short get_distance (void)
+

The version of this function taking a Point argument returns + a real_short r, whose real part + (r.first) represents + the distance of p from the Plane. This value is always + positive. r.second can take on three values: + +

+
0
If the Point lies in the Plane. + +
1
If it lies on the side of the Plane pointed at by the + normal to the Plane, considered to be the “outside”. + +
-1
If it lies on the side of the Plane not pointed at + by the normal to the Plane, considered to be the “inside”. +
+ +

The version taking no argument returns + the absolute of the data member distance and its sign, i.e., the + distance of origin to the Plane, and which side of the + Plane it lies on. + +

It would have been possible to use origin as the default for an + optional Point argument, but I've chosen to overload this + function, because of problems that may arise, when I implement + user_coordinates and view_coordinates + (see Point Reference; Data Members). + +

          Point N(0, 1);
+           N.rotate(-10, 20, 20);
+           Point P(1, 1, 1);
+           Plane q(P, N);
+           Point A(4, -2, 4);
+           Point B(-1, 3, 2);
+           Point C = q.intersection_point(A, B).pt;
+           real_short bp;
+           
+           bp = q.get_distance();
+           cout << bp.first;
+           -| 0.675646
+           cout << bp.second
+           -| -1
+           
+           bp = q.get_distance(A)
+           cout << bp.first;
+           -| 3.40368
+           cout << bp.second;
+           -|  -1
+           
+           bp = q.get_distance(B)
+           cout << bp.first;
+           -| 2.75865
+           cout << bp.second;
+           -| 1
+           
+           bp = q.get_distance(C)
+           cout << bp.first;
+           -| 0
+           cout << bp.second;
+           -| 0
+ 
+

+
+ [Figure 106. Not displayed.] +
+
+ Fig. 106. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Showing.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Showing.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Planes-Showing.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Planes-Showing.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,85 ---- + + + Planes Showing - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Plane Intersections, + Up: Plane Reference +


+
+ +

25.7 Showing

+ +
+ — const function: void show ([string text = ""])
+

Prints information about the Plane to standard output. + If text is not the empty string, it is printed to the + standard output. Otherwise, + ‘Plane:’ is printed. + Following this, + if the Plane is equal to INVALID_PLANE + (see Planes Reference; Global Constants), + a message to this effect is printed to standard output. + Otherwise, normal and + point are shown using Point::show() + (see Point Reference; Showing). Finally, + distance is printed. + +

          Point A(1, 3, 2.5);
+           Rectangle r0(A, 5, 5, 10, 15, 6);
+           Plane p = r0.get_plane();
+           -| p:
+              normal: (-0.0582432, 0.984111, -0.167731)
+              point: (-0.722481, 2.38245, -0.525176)
+              distance == -2.47476
+ 
+
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,121 ---- + + + Point Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.4 Constructors and Setting Functions

+ +
+ — Default constructor: void Point (void)
+

Creates a Point and initializes its x, y, and z-coordinates + to 0. +

+ +
+ — Constructor: void Point (const real x, [const real y = CURR_Y, [const real z = CURR_Z]])
+

Creates a Point and initializes its x, y, and z-coordinates + to the values of the arguments x, y, and z. The + arguments y and z are optional. If they are not specified, + the values of CURR_Y and CURR_Z are used. They are 0 by + default, but can be changed by the user. This can be convenient, if all + of the Points being drawn in a particular section of a program + have the same z or y and z values. +

+ +
+ — Setting function: void set (const real x, [const real y = CURR_Y, [const real z = CURR_Z]])
+

Corresponds to the constructor above, but is used for resetting the coordinates of an existing + Point. +

+ +
+ — Copy constructor: void Point (const Point& p)
+

Creates a Point and copies the values for its x, y, and z-coordinates + from p. +

+ +
+ — Setting function: void set (const Point& p)
+

Corresponds to the copy constructor above, but is used for resetting the coordinates + of an existing Point. This function exists purely as a convenience; + the operator operator=() + (see Point Reference; Operators) + performs exactly the + same function. +

+ +
+ — Template specializations: Point* create_new<Point> (const Point* p)
+ — : Point* create_new<Point> (const Point& p)
+

Pseudo-constructors for dynamic allocation of Points. + They create a Point on the free store and allocate memory for it using + new(Point). They return a pointer to the new Point. + +

If p is a non-zero pointer or a reference, + the new Point will be a copy of + p. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Point>() as its argument. + See Dynamic Allocation of Shapes, for more information. + +

One use for create_new<Point> is in the constructors for + classes of + objects that can contain a variable number of Points, such as + Path and Polygon. Another use is in the drawing and + filling functions, where objects are copied and the copies put onto a + Picture. + +

Programmers who dynamically allocate Points must ensure that they + are deallocated properly using delete! +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,222 ---- + + + Point Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.1 Data Members

+ +
+ — Private variable: valarray<real> world_coordinates
+

The set of four homogeneous coordinates x, y, z, and w that represent + the position of the Point within 3DLDF's global coordinate + system. +

+ +
+ — Private variable: valarray<real> projective_coordinates
+

The set of four homogeneous coordinates x, y, z, and w that represent + the position of the projection of the Point onto a + two-dimensional plane for output. The x and y values are used in the + MetaPost code written to out_stream. The z value is used + in the hidden surface algorithm (which is currently rather primitive and + doesn't work very well. see Surface Hiding). The w value can be + != 1 + , + depending on the projection used; the perspective projection is + non-affine, so w can take on other values. +

+ +
+ — Private variable: valarray<real> user_coordinates
+

A set of four homogeneous coordinates x, y, z, and w. + +

user_coordinates currently has no function. + It is intended for use in user-defined coordinate systems. For example, + a coordinate system could be defined with respect to a plane surface + that isn't parallel to one of the major planes. Such a coordinate + system would be convenient for drawing on the plane. A Transform + would make it possible to convert between user_coordinates and + world_coordinates. +

+ +
+ — Private variable: valarray<real> view_coordinates
+

A set of four homogeneous coordinates x, y, z, and w. + +

view_coordinates currently has no function. It may be useful for + displaying multiple views in an interactive graphical user interface, or + for some other purpose. +

+ +
+ — Private variable: Transform transform
+

Contains the product of the transformations applied to the Point. + When apply_transform() is called for the Point, directly + or indirectly, the world_coordinates are updated and + transform is reset to the identity Transform. + See Point Reference; Applying Transformations. +

+ +
+ — Private variable: bool on_free_store
+

Returns on_free_store. This should only be true if + the Point was dynamically allocated on the + free store. Points should only ever be dynamically + allocated by create_new<Point>(), which + uses set_on_free_store() to set on_free_store + to true. + See Point Reference; Constructors and Setting Functions, and + Point Reference; Modifying. +

+ +
+ — Private variable: signed short drawdot_value
+

Used to tell Point::output() what MetaPost drawing command + (drawdot() or undrawdot()) to write to out_stream + when outputting a Point. + +

When drawdot() or undrawdot() is called on a Point, + the Point is copied and put onto the Picture, which was + passed to + drawdot() or undrawdot() as an argument + (current_picture by + default). drawdot_value is either set to Shape::DRAWDOT + or Shape::UNDRAWDOT on the copy; this->drawdot is + not set. +

+ +
+ — Private variable: const Color* drawdot_color
+

Used to tell Point::output() what string to write to out_stream + for the color when outputting a Point. +

+ +
+ — Private variable: string pen
+

Used to tell Point::output() what string to write to out_stream + for the pen when outputting a Point. +

+ +
+ — Protected variable: valarray<real> projective_extremes
+

A set of 6 real values indicating the maximum and minumum x, y, + and + z-coordinates of the Point. + Used for determining whether a Point is projectable with the + parameters of a particular invocation of Picture::output(). + See Picture Reference; Outputting. + +

Obviously, the maxima and minima + will always be the same for a Point, namely the x, y, and + z-coordinates. + However, set_extremes() and get_extremes(), + the functions that access projective_extremes, are pure virtual + functions in class Shape, + so the Point versions must be consistent with the versions for + other types derived from Shape. +

+ +
+ — Protected variable: bool do_output
+

true by default. Set to false by suppress_output(), + which is called on a Shape by Picture::output(), if the + Shape is not projectable. + See Picture Reference; Outputting. +

+ +
+ — Public static variable: string measurement_units
+

The unit of measurement for all distances within a Picture, + "cm" (for centimeters) by default. The x and y-coordinates of + the projected Points are always followed by measurement_units + when they're written to out_stream. Unlike Metafont, units of + measurement cannot be indicated for individual coordinates. Nor can + measurement_unit be changed within a Picture. + +

When I write an input routine, I plan to make it behave the way Metafont + does, however, 3DLDF will probably also convert all of the input values + to a standard unit, as Metafont does. +

+ +
+ — Public static variable: real CURR_Y
+ — Public static variable: real CURR_Z
+

Default values for the y and z-coordinate of Points, when the + x-coordinate, or the x and y-coordinates only are specified. + Both are 0 by default. + +

These values only used in the constructor and setting function taking + one required real value (for the x-coordinate), and two optional + real values (for the y and z-coordinates). They are not used + when a Point is declared using the + default constructor with no arguments. In this case, the x, y, and + z-coordinates will all be 0. + See Point Reference; Constructors and Setting Functions. + +

          Point A(1);
+           A.show("A:");
+           -| A: (1, 0, 0);
+           CURR_Y = 5;
+           A.set(2);
+           A.show("A:");
+           -| A: (2, 5, 0);
+           CURR_Z = 12;
+           Point B(3);
+           B.show("B:");
+           -| B: (3, 5, 12);
+           Point C;
+           C.show("C:");
+           -| C: (0, 0, 0);
+ 
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Destructor.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Destructor.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Destructor.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Destructor.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,64 ---- + + + Point Destructor - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.5 Destructor

+ +
+ — virtual Destructor: void ~Point (void)
+

This function currently has an empty definition, but its existence + prevents GCC 3.3 from issuing the following warning: + “`class Point' has virtual functions but non-virtual destructor”. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Drawing-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Drawing-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Drawing-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Drawing-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,212 ---- + + + Point Drawing Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Point Intersections, + Up: Point Reference +


+
+ +

22.18 Drawing

+ +

There are two versions for each of the drawing functions. The second + one has the Picture argument picture at the beginning of the + argument list, rather than at the end. This is convenient when passing + a picture argument. Where picture is optional, the default + is always current_picture. + +

+ +

+ — const function: void drawdot ([const Color& ddrawdot_color = *Colors::default_color, [const string ppen = "", [Picture& picture = current_picture]]])
+ — const function: void drawdot ([Picture& picture = current_picture, [const Color& ddrawdot_color = *Colors::default_color, [const string ppen = "", ]]])
+

Draws a dot on picture. If ppen is specified, a “pen + expression” is included in the drawdot command written to + out_stream. Otherwise, MetaPost's currentpen is used. + If ddrawdot_color is specified, the dot will be drawn using that + Color. Otherwise, the Color currently pointed to by the pointer + Colors::default_color will be used. This will normally be + Colors::black. See Color Reference, for more information + about Colors and the namespace Colors. + +

Please note that the “dot” will always be parallel to the plane of + projection. Even where it appears to be a surface, as in [next figure] + , it + is never put into perspective, but will always have the same size and + shape. + +

          Point P(1, 1);
+           P.drawdot(gray, "pensquare scaled 1cm");
+ 
+

+
+ [Figure 96. Not displayed.] +
+
+ Fig. 96. +
+

+ +
+ +
+ — Function: void undrawdot ([string pen = "", [Picture& picture = current_picture]])
+ — Function: void undrawdot ([Picture& picture = current_picture, [string pen = ""]])
+

Undraws a dot on picture. If ppen is specified, a “pen + expression” is included in the undrawdot command written to + out_stream. Otherwise, MetaPost's currentpen is used. + +

          Point P(1, 1);
+           P.drawdot(gray, "pensquare scaled 1cm");
+           P.undrawdot("pencircle scaled .5cm");
+ 
+

+
+ [Figure 97. Not displayed.] +
+
+ Fig. 97. +
+

+ +
+ +
+ — Function: void draw (const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture, [bool aarrow = false]]]]])
+ — Function: void draw (Picture& picture = current_picture, const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [bool aarrow = false]]]])
+

Draws a line from *this to p. + Returns the Path *this -- p1. + See Path Reference; Drawing and Filling, + for more information. + +

          Point P(-1, -1, -1);
+           Point Q(2, 3, 5);
+           P.draw(Q, Colors::gray, "", "pensquare scaled .5cm");
+ 
+

+
+ [Figure 98. Not displayed.] +
+
+ Fig. 98. +
+

+ +
+ +
+ — Function: void undraw (const Point& p, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]])
+ — Function: void undraw (Picture& picture, const Point& p, [string ddashed = "", [string ppen = ""]])
+

Undraws a line from *this to p. + Returns the Path *this -- p1. + See Path Reference; Drawing and Filling, + for more information. + +

          Point P(-1, -1, -1);
+           Point Q(2, 3, 5);
+           P.draw(Q, Colors::gray, "", "pensquare scaled .5cm");
+           P.undraw(Q, "evenly scaled 6", "pencircle scaled .3cm");
+ 
+

+
+ [Figure 99. Not displayed.] +
+
+ Fig. 99. +
+

+ +
+ +

+ +

+ — Function: Path draw_help (const Point& p, [const Color& ddraw_color = *Colors::help_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — Function: Path draw_help (Picture& picture, const Point& p, [const Color& ddraw_color = *Colors::help_color, [string ddashed = "", [string ppen = ""]]])
+

Draws a “help line” from *this to p, but only if the + static Path data member do_help_lines is true. + See Path Reference; Data Members. + +

“Help lines” are lines that are used when constructing a drawing, but + that should not be printed in the final version. +

+ +
+ — Function: Path drawarrow (const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — Function: Path drawarrow (Picture& picture, const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = ""]]])
+

Draws an arrow from *this to p and returns + the Path *this -- p. + The second version is convenient for passing a Picture argument + without having to specify all of the other arguments. + +

          Point P(-3, -2, 1);
+           Point Q(3, 3, 5);
+           P.drawarrow(Q);
+ 
+

+
+ [Figure 100. Not displayed.] +
+
+ Fig. 100. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Global-Constants-and-Variables.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Global-Constants-and-Variables.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Global-Constants-and-Variables.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Global-Constants-and-Variables.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,89 ---- + + + Point Global Constants and Variables - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.3 Global Constants and Variables

+ +
+ — Constant: Point INVALID_POINT
+

The x, y, and z-values in world_coordinates are all INVALID_REAL. +

+ +
+ — Constant: Point origin
+

The x, y, and z-values in world_coordinates are all 0. +

+ +
+ — Constant: bool_point INVALID_BOOL_POINT
+

b is false and pt is INVALID_POINT. +

+ +
+ — Constant: bool_point_pair INVALID_BOOL_POINT_PAIR
+

first and second are both INVALID_BOOL_POINT. +

+ +
+ — Constant: bool_real_point INVALID_BOOL_REAL_POINT
+

b is false, r is INVALID_REAL, and pt + is INVALID_POINT. +

+ +
+ — Constant: bool_point_quadruple INVALID_BOOL_POINT_QUADRUPLE
+

first, second, third, and fourth are all + INVALID_BOOL_POINT. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,119 ---- + + + Point Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Points and Lines, + Up: Point Reference +


+
+ +

22.17 Intersections

+ +
+ — Static function: bool_point intersection_point (Point p0, Point p1, Point q0, Point q1)
+ — Static function: bool_point intersection_point (Point p0, Point p1, Point q0, Point q1, const bool trace)
+

These functions find the intersection point, if any, of the lines determined by + p0 and p1 on the one hand, and q0 and q1 on the other. + +

Let bp be the bool_point returned by + intersection_point(). If an intersection point is found, the + corresponding Point will be stored in bp.pt, otherwise, + bp.pt will be set to INVALID_POINT. If the intersection + point lies on both of the line segments, bp.b will be + true, otherwise, false. + +

The two versions use different methods of finding the intersection + point. The first uses a vector calculation, the second looks for the + intersections of the traces of the lines on the major planes. If the + trace argument is used, the second version will be called, whether + trace is true or false. Ordinarily, there should be + no need to use the trace version. + +

          Point A(-1, -1);
+           Point B(1, 1);
+           Point C(-1, 1);
+           Point D(1, -1);
+           bool_point bp = Point::intersection_point(A, B, C, D);
+           bp.pt.dotlabel("$i$");
+           cout << "bp.b == " << bp.b << endl << flush;
+           -| bp.b == 1
+ 
+

+
+ [Figure 94. Not displayed.] +
+
+ Fig. 94. +
+

+ +
          Point A(.5, .5);
+           Point B(1.5, 1.5);
+           Point C(-1, 1);
+           Point D(1, -1);
+           bool_point bp = Point::intersection_point(A, B, C, D, true);
+           bp.pt.dotlabel("$i$");
+           cout << "bp.b == " << bp.b << endl << flush;
+           -| bp.b == 0
+ 
+

+
+ [Figure 95. Not displayed.] +
+
+ Fig. 95. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,210 ---- + + + Point Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Point Destructor, + Up: Point Reference +


+
+ +

22.6 Operators

+ +
+ — Assignment operator: void operator= (const Point& p)
+

Makes *this a copy of p. +

+ +
+ — Operator: Transform operator*= (const Transform& t)
+

Multiplies transform by t. + By multiplying a Point successively by + one or more Transforms, the effect of the transformations is + “saved up” in transform. Only when an operation that needs + updated values for the world_coordinates is called on a + Point, or the Point is passed as an argument to such an + operation, is the transformation stored in transform applied to + world_coordinates by apply_transform(), + which subsequently, resets transform to + the identity Transform. + See Point Reference; Applying Transformations. +

+ +
+ — const operator: Point operator+ (Point p)
+

Returns a Point with world_coordinates that are the sums of + the corresponding world_coordinates of *this and p, + after they've been updated. + *this remains unchanged; as in many other functions with + Point arguments, p is passed by value, because + apply_transform() must be called on it, in order to update its + world_coordinates. If p were a const Point&, it + would have to copied within the function anyway, because + apply_transform() is a non-const operation. + +

          Point p0(-2, -6, -28);
+           Point p1(3, 14, 92);
+           Point p2(p0 + p1);
+           p2.show("p2:");
+           -| p2: (1, 8, 64)
+ 
+
+ +
+ — Operator: void operator+= (Point p)
+

Adds the updated world_coordinates of p to those of + *this. + Equivalent in effect to shift(p) + In fact, this + function merely calls p.apply_transform() and + Point::shift(real, real, real) with p's x, y, and z + coordinates (from world_coordinates) as its arguments. + See Point Reference; Affine Transformations. +

+ +
+ — const operator: Point operator- (Point p)
+

Returns a Point with world_coordinates representing the + difference between the updated values of + this->world_coordinates and + p.world_coordinates. +

+ +
+ — Operator: void operator-= (Point p)
+

Subtracts the updated values of p.world_coordinates from + those of this->world_coordinates. +

+ +
+ — Operator: real operator*= (const real r)
+

Multiplies the updated x, y, and z coordinates (world_coordinates) of + the Point by r and returns r. This makes it possible to + chain invocations of this function. + +

If P is a Point then + P *= r is + equivalent in its effect to P.scale(r, r, r), + except that + P.world_coordinates is modified directly and immediately, + without changing P.transform. This is possible, because this + function calls apply_transform() to update the + world_coordinates before multiplying them r, so + transform is the identity Transform. + +

          Point P(1, 2, 3);
+           P *= 7;
+           P.show("P:");
+           -| P: (7, 14, 21);
+           Point Q(1.5, 2.7, 13.82);
+           Q *= P *= -1.28;
+           P.show("P:");
+           -| P: (-8.96, -17.92, -26.88)
+           Q.show("Q:");
+           -| Q: (-1.92, -3.456, -17.6896)
+ 
+
+ +
+ — const operator: Point operator* (const real r)
+

Returns a Point with x, y, and z coordinates + (world_coordinates) equal to the updated x, y, and z coordinates + of *this multiplied by r. +

+ +
+ — Non-member operator: Point operator* (const real r, const Point& p)
+

Equivalent to Point::operator*(const real r) (see above), + but with r placed first. +

          Point p0(10, 11, 12);
+           real r = 2.5;
+           Point p1 = r * p0;
+           p1.show();
+           -|Point:
+           -|(25, 27.5, 30)
+ 
+
+ +
+ — const operator: Point operator- (void)
+

Unary minus (prefix). Returns a Point with x, y, and z + coordinates (world_coordinates) equal to the + the x, y, and z-coordinates (world_coordinates) of + *this multiplied by -1. +

+ +
+ — Operator: void operator/= (const real r)
+

Divides the updated x, y, and z coordinates (world_coordinates) of + the Point by r. +

+ +
+ — const operator: Point operator/ (const real r)
+

Returns a Point with x, y, and z coordinates + (world_coordinates) equal to the updated x, y, and z coordinates + of *this + divided by r. +

+ +
+ — Operator: bool operator== (Point p)
+ — const operator: bool operator== (const Point& p)
+

Equality comparison for Points. These functions return + true if the updated values of the world_coordinates of the two + Points differ by less than the value returned by + Point::epsilon(), otherwise false. + See Point Reference; Returning Information. +

+ +
+ — const operator: bool operator!= (const Point& p)
+

Inequality comparison for Points. Returns false if + *this == p, otherwise true. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,86 ---- + + + Point Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Picture Reference, + Up: Top +


+
+ +

22 Point Reference

+ +

Class Point is defined in points.web. + It is derived from Shape using protected derivation. + The function + Transform Transform::align_with_axis(Point, Point, char) + is a friend of Point. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Typedefs-and-Utility-Structures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Typedefs-and-Utility-Structures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Point-Typedefs-and-Utility-Structures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Point-Typedefs-and-Utility-Structures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,147 ---- + + + Point Typedefs and Utility Structures - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

22.2 Typedefs and Utility Structures

+ +
+ — typedef: point_pair first second
+

Synonymous with pair<Point, Point>. +

+ +
+ — struct: bool_point b pt
+

b is a bool and pt is a Point. + bool_point also contains two constructors and an assignment + operator, described below. +

+ +
+ — Default constructor: void bool_point (void)
+

Creates a bool_point and sets b to false and + pt to INVALID_POINT. +

+ +
+ — Default constructor: void bool_point (bool bb, const Point& ppt)
+

Creates a bool_point and sets b to bb and pt + to ppt. +

+ +
+ — Assignment operator: void bool_point::operator= (const bool_point& bp)
+

Sets b to + bp.b and pt to bp.pt. +

+ +
+ — typedef: bool_point_pair first second
+

Synonymous with pair <bool_point, bool_point>. +

+ +
+ — struct: bool_point_quadruple first second third fourth
+

This structure contains four bool_points. It also has two + constructors and an assignment operator, described below. +

+ +
+ — Default constructor: void bool_point_quadruple (void)
+

Creates a bool_point_quadruple, and sets + first, second, third, and fourth all to + INVALID_BOOL_POINT. +

+ +
+ — Constructor: void bool_point_quadruple (bool_point a, bool_point b, bool_point c, bool_point d)
+

Creates a bool_point_quadruple and sets + first to a, second to b, third to + c, and fourth to d. +

+ +
+ — Assignment operator: void bool_point_quadruple::operator= (const bool_point_quadruple& arg)
+

Makes *this a copy of arg. +

+ +
+ — struct: bool_real_point b r pt
+

b is a bool, r is a real, and pt is a + Point. bool_real_point also contains three constructors + and an assignment operator, described below. +

+ +
+ — Default constructor: void bool_real_point (void)
+

Creates a bool_real_point and sets b to false, + r to INVALID_REAL and pt to INVALID_POINT. +

+ +
+ — Copy constructor: void bool_real_point (const bool_real_point& brp)
+

Creates a bool_real_point and sets b to brp.b, + r to brp.r, and pt to brp.pt. +

+ +
+ — Constructor: void bool_real_point (const bool& bb, const real& rr, const Point& ppt)
+

Creates a bool_real_point and sets b to bb, + r to rr, and pt to ppt. +

+ +
+ — Assignment operator: void bool_real_point::operator= (const bool_real_point& brp)
+

Makes *this a copy of brp. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Points-and-Lines.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Points-and-Lines.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Points-and-Lines.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Points-and-Lines.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,215 ---- + + + Points and Lines - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Vector Operations, + Up: Point Reference +


+
+ +

22.16 Points and Lines

+ +
+ — const function: Line get_line (const Point& p)
+

Returns the Line l corresponding to the line from *this to + p. l.position will be *this, and + l.direction will be p - *this. + See Line Reference. +

+ +
+ — const function: real slope (Point p, [char m = 'x', [char n = 'y']])
+

Returns a real number representing the slope of the trace + of the line defined by + *this and p on the plane indicated by the arguments m + and n. + +

          Point p0(3, 4, 5);
+           Point p1(2, 7, 12);
+           real r = p0.slope(p1, 'x', 'y');
+           ⇒ r == -3
+           r = p0.slope(p1, 'x', 'z');
+           ⇒ r == -7
+           r = p0.slope(p1, 'z', 'y');
+           ⇒ r == 0.428571
+ 
+
+ +
+ — Function: bool_real is_on_segment (Point p0, Point p1)
+ — const function: bool_real is_on_segment (const Point& p0, const Point& p1)
+

These functions return a bool_real, where the bool part is + true, if + the Point lies on the line segment between p0 and p1, + otherwise false. If the Point lies on the line segment, the + real part is a value + r such that + 0 <= r <= 1 + indicating how far the Point is along the way from + p0 to p1. For example, if the Point is half of the way + from p0 to p1, r will be .5. If the Point + does not lie on the line + segment, but on the line passing through p0 and p1, + r will be <0 or >1. + +

If the Point doesn't lie on the line passing through p0 and + p1, + r will be INVALID_REAL. + +

          Point p0(-1, -2, 1);
+           Point p1(3, 2, 5);
+           Point p2(p0.mediate(p1, .75));
+           Point p3(p0.mediate(p1, 1.5));
+           Point p4(p2);
+           p4.shift(-2, 1, -1);
+           bool_real br = p2.is_on_segment(p0, p1);
+           cout << br.first;
+           -| 1
+           cout << br.second;
+           -| 0.75
+           bool_real br = p3.is_on_segment(p0, p1);
+           cout << br.first;
+           -| 0
+           cout << br.second;
+           -| 1.5
+           bool_real br = p4.is_on_segment(p0, p1);
+           cout << br.first;
+           -| 0
+           cout << br.second;
+           -| 3.40282e+38
+           cout << (br.second == INVALID_REAL)
+           -| 1
+ 
+

+
+ [Figure 91. Not displayed.] +
+
+ Fig. 91. +
+

+ +
+ +
+ — const function: bool_real is_on_line (const Point& p0, const Point& p1)
+

Returns a bool_real where the bool part is true, if + the Point lies on the line passing through p0 and p1, + otherwise false. If the Point lies on the line, the + real part is a value r indicating how how far the Point + is along the way from p0 to p1, otherwise + INVALID_REAL. The following + values of r are possible for a call to P.is_on_line(A, B), + where the Point P lies on the line + AB: + +

          P == A —> r== 0.
+           
+           P == B —> r== 1.
+           
+           P lies on the opposite side of A from B —> r < 0.
+           
+           P lies between A and B —> 0 <  r < 1.
+           
+           P lies on the opposite side of A from B —> r > 1
+ 
+
          Point A(-1, -2);
+           Point B(2, 3);
+           Point C(B.mediate(A, 1.25));
+           bool_real br = C.is_on_line(A, B);
+           Point D(A.mediate(B));
+           br = D.is_on_line(A, B);
+           Point E(A.mediate(B, 1.25));
+           br = E.is_on_line(A, B);
+           Point F(D);
+           F.shift(-1, 1);
+           br = F.is_on_line(A, B);
+ 
+

+
+ [Figure 92. Not displayed.] +
+
+ Fig. 92. +
+

+ +
+ +
+ — const function: Point mediate (Point p, [const real r = .5])
+

Returns a Point r of the way from *this to p. + +

          Point p0(-1, 0, -1);
+           Point p1(10, 0, 10);
+           Point p2(5, 5, 5);
+           Point p3 = p0.mediate(p1, 1.5);
+           p3.show("p3:");
+           -| p3: (15.5, 0, 15.5)
+           Point p4 = p0.mediate(p2, 1/3.0);
+           p4.show("p4:");
+           -| p4: (1, 1.66667, 1)
+ 
+

+
+ [Figure 93. Not displayed.] +
+
+ Fig. 93. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,61 ---- + + + Points - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Using 3DLDF, + Up: Top +


+
+ +

2 Points

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,64 ---- + + + Polygon Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Polygon Reference, + Up: Polygon Reference +


+
+ +

27.1 Data Members

+ +
+ — Private variable: Point center
+

The center of the Polygon, if it has one. However, a + Polygon need not have a center. If it doesn't, + center should be set to INVALID_POINT. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,265 ---- + + + Polygon Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +

27.5 Intersections

+ +
+ — const function: bool_point_pair intersection_points (const Point& p0, const Point& p1)
+ — const function: bool_point_pair intersection_points (const Path& p)
+

These functions find the intersections of the + Polygon and a line. + In the first version, the Point arguments are the end points of + the line. The argument to the second version must be a linear + Path. + +

A line and a regular polygon or rectangle1 + can intersect at two points at most. + Let b be a bool_point_pair returned by + intersection_points(). + If no + intersection points are found, b.first.pt and b.second.pt + will be INVALID_POINT, and b.first.b and b.second.b + will be false. If a single intersection point is found, the + corresponding Point will be stored in b.first.pt. If the + Point is on the line segment + p_0p_1 + , + b.first.b will be true, + otherwise false. If a second intersection point is found, it + will be stored in b.second.pt, and b.second.b is set + analogously to b.first.b. + +

When the Point arguments and the Reg_Polygon are coplanar, + as in [next figure] + , two intersection points are possible. In this case, + only intersection points of the line with an edge of the + Reg_Polygon are returned in the bool_point_pair. + +

          Point A(1, 1, 1);
+           Reg_Polygon r(origin, 5, 3);
+           Transform t;
+           t.rotate(15, 12, 11);
+           t.shift(A);
+           Point P(-2, 0, -1);
+           Point Q(2, 0, 1);
+           P *= Q *= r *= t;
+           bool_point_pair bpp = r.intersection_points(P, Q);
+           bpp.first.pt.dotlabel("$f$", "rt");
+           bpp.second.pt.dotlabel("$s$");
+ 
+

+
+ [Figure 139. Not displayed.] +
+
+ Fig. 139. +
+

+ +

In [next figure] + , the lines BC + and + PQ + +

are not coplanar with the Reg_Polygon r. In each case, only + one intersection point is possible, and it can be either an intersection + with an edge of the + Reg_Polygon, or lie within its perimeter. + +

          Point B(r.get_point(3).mediate(r.get_point(4)));
+           Point C(B);
+           B.shift(0, 2, .5);
+           C.shift(0, -2, -.5);
+           Point P(-1, -2, -1);
+           Point Q(0, 2, 1);
+           B *= C *= P *= Q *= r *= t;
+           bool_point_pair bpp = r.intersection_points(B, C);
+           bpp.first.pt.dotlabel("$i_0$", "rt");
+           bpp = r.intersection_points(P, Q);
+           bpp.first.pt.dotlabel("$i_1$", "rt");
+ 
+

+
+ [Figure 140. Not displayed.] +
+
+ Fig. 140. +
+

+ +

In [next figure] + , the intersection point of r with the line + PQ + +

does not lie on the line segment PQ. + +

          bpp = r.intersection_points(P, Q);
+           bpp.first.pt.dotlabel("$i$", "rt");
+           cout << "bpp.first.b == " << bpp.first.b << endl << flush;
+           -| bpp.first.b == 0
+ 
+

+
+ [Figure 141. Not displayed.] +
+
+ Fig. 141. +
+

+ +
+ +
+ — const function: vector<Point> intersection_points (const Polygon& r)
+

Finds the intersection points of two Polygons. + Let v be the vector<Point> returned by + intersection_points(). If the Polygons are coplanar, + v + will contain the intersection points of the edges of the + Polygons, as in [next figure] + . + +

          Rectangle r(origin, 4, 4);
+           Reg_Polygon rp(origin, 5, 5, 0, 36);
+           rp.shift(0, 0, .25);
+           vector <Point> v = r.intersection_points(rp);
+ 
+

+
+ [Figure 142. Not displayed.] +
+
+ Fig. 142. +
+

+ +

If the Polygons lie in parallel planes, there can be no + intersection points. If they lie in non-parallel, non-coplanar planes, + intersection_points() first finds the intersection line of the + two planes. Then it finds the intersection points of this line with the + two Polygons, if they exist. There can no more than four + intersection points, in this case. + v[0] and v[1] will be the + intersection points of the line with *this, while v[2] and + v[3] will be the intersection points of the line with r. If one + or more of the intersection points doesn't exist, the corresponding + member of v will contain INVALID_POINT as a placeholder. + +

          Point A(1, 1, 1);
+           Rectangle r(A, 4, 4);
+           Reg_Polygon p(A, 5, 5);
+           p.rotate(90, 30);
+           p.shift(2, 0, 3);
+           vector <Point> v = r.intersection_points(p);
+ 
+

+
+ [Figure 143. Not displayed.] +
+
+ Fig. 143. +
+

+ +

In [next figure] + , the Rectangle r and the Reg_Polygon p + don't overlap at all, nor does the intersection line of the two planes + intersect with p. However, it does intersect with p at the + labelled Points. + +

          Point A(1, 1, 1);
+           Rectangle r(A, 4, 4);
+           Reg_Polygon p(A, 5, 5);
+           p.rotate(90, 30);
+           p.shift(4, 3, 3);
+           vector <Point> v = r.intersection_points(p);
+           int i = 0;
+           for (vector<Point>::iterator iter = v.begin();
+            iter != v.end(); ++iter)
+            iter->dotlabel(i++, "bot");
+ 
+

+
+ [Figure 144. Not displayed.] +
+
+ Fig. 144. +
+

+ +
+ + + + + + +
+
+

Footnotes

[1] Reg_Polygon and Rectangle are currently the only + classes derived from Polygon.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Polygon Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Polygon Data Members, + Up: Polygon Reference +


+
+ +

27.2 Operators

+ +
+ — Virtual operator: Transform operator*= (const Transform& t)
+

Multiplies a Polygon by the Transform t. + Similar to Path::operator*=(const Transform& t), except that + center is transformed as well. + See Path Reference; Operators. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polygon-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polygon-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,72 ---- + + + Polygon Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Path Reference, + Up: Top +


+
+ +

27 Polygon Reference

+ +

Class Polygon is defined in polygons.web, and + is derived from Path, using public derivation. + +

Polygon is mainly intended for use as a base class for more + specialized kinds of polygons. Currently, the classes + Reg_Polygon (regular polygon) and Rectangle are defined. + See Regular Polygon Reference, and Rectangle Reference. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polyhedron-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polyhedron-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polyhedron-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polyhedron-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,83 ---- + + + Polyhedron Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

37.1 Data Members

+ +
+ — Protected variable: unsigned short number_of_polygon_types
+

The number of different types of polygon making up the faces of a + Polyhedron. The Platonic polyhedra have only one type of face, + while the Archimedean can have more. +

+ +
+ — Protected variable: real face_radius
+

The radius of the sphere that touches the centers of the polygonal faces + of the polyhedron (Inkugel, in German). +

+ +
+ — Protected variable: real edge_radius
+

The radius of the sphere that touches the centers of the edges of the + polyhedron. + +

+ +
+ — Protected variable: real vertex_radius
+

The radius of the sphere touching the vertices of the polyhedron + (Umkugel, in German). +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polyhedron-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polyhedron-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polyhedron-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polyhedron-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,81 ---- + + + Polyhedron Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Cuboid Getstart, + Up: Solid Figures +


+
+ +

8.2 Polyhedron

+ +

The class Polyhedron is meant for use only as a base class; + no objects of type Polyhedron should be declared. Instead, there + is a class for each of the different drawable polyhedra. Currently, + 3DLDF defines only three: Tetrahedron, Dodecahedron, and + Icosahedron. There's no need for a Cube class, because + cubes can be drawn using Cuboid (see Cuboid Getstart). + +

Polyhedra have a high priority in my plans for 3DLDF. + I intend to add Octahedron soon, which will complete the set of regular + Platonic polyhedra. Then I will begin adding the semi-regular + Archimedean polyhedra, and their duals. + +

The constructors for the classes derived from Polyhedron follow + the pattern familiar from the classes already described. The constructors + for the classes described below have identical arguments: First, a + Point specifying the center, then a real for the + diameter of the surrounding circle (Umkreis, in German) of one of + its polygonal faces, followed by three + real arguments for the angles of rotation about the main axes. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polyhedron-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polyhedron-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Polyhedron-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Polyhedron-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,71 ---- + + + Polyhedron Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Cuboid Reference, + Up: Top +


+
+ +

37 Polyhedron Reference

+ +

Class Polyhedron is defined in polyhed.web. + It is derived from Solid_Faced using public derivation. It is + intended for use as a base class for specific types of polyhedra. + Currently, the classes Tetrahedron, Dodecahedron, + Icosahedron, and Trunc_Octahedron (truncated octahedron) + are derived from Polyhedron. + +

There is a great deal of work left to do on the polyhedra. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ports.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ports.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Ports.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Ports.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,117 ---- + + + Ports - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Caveats, + Up: Introduction +


+
+ +

1.6 Ports

+ +

I originally developed 3DLDF on a DECalpha Personal Workstation with two + processors running under the operating system Tru64 Unix 5.1, using the + DEC C++ + compiler. + I then ported it to a PC Pentium 4 running under Linux 2.4, using + the GNU C++ + compiler + GCC 2.95.3, and a PC Pentium II XEON under Linux 2.4, using GCC 3.3. + I am currently only maintaining the last version. I do not believe that + it's worthwhile to maintain a version for GCC 2.95. While I would like + 3DLDF to run on as many platforms as possible, I would + rather spend my time developing it than porting it. + This is something where I would be grateful for help from other + programmers. + +

Although I am no longer supporting ports to other systems, + I have left some conditionally compiled code for + managing platform dependencies in the CWEB sources of 3DLDF. This may + make it easier for other people who want to port 3DLDF to other + platforms. + +

Currently, the files io.web, loader.web, main.web, + points.web, + and pspglb.web contain conditionally compiled code, depending on + which compiler, or in the case of GCC, which version of the compiler, is + used. The DEC C++ + compiler defines the preprocessor macro + ‘__DECCXX’ and GCC defines ‘__GNUC__’. In order to + distinguish between GCC 2.95.3 and GCC 3.3, I've added the macros + ‘LDF_GCC_2_95’ and ‘LDF_GCC_3_3’ in loader.web, which + should be defined or undefined, depending on which compiler you're + using. In the distribution, ‘LDF_GCC_3_3’ is defined and + ‘LDF_GCC_2_95’ is undefined, so if you want to try using GCC 2.95, you'll + have to change this (it's not guaranteed to work). + +

3DLDF 1.1.5.1 now uses Autoconf and Automake, and the + configure script generates a config.h file, which is now + included in loader.web. Some of + the preprocessor macros defined in config.h are used to + conditionally include library header files, but so far, there is no error + handling code for the case that a file can't be included. I hope to improve the + way 3DLDF works together with Autoconf and Automake in the near future. + +

3DLDF 1.1.5 is the first release that contains template functions. + Template instantiation differs from compiler to compiler, so using + template functions will tend to make 3DLDF less portable. + See Template Functions, for more information. + I am no longer able to build 3DLDF on the DECalpha Personal Workstation. + I'm fairly sure that it would be possible to port it, but + I don't plan to do this, since Tru64 Unix 5.1 and the DEC C++ + +

compiler are non-free software. + + + + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Projecting-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Projecting-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Projecting-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Projecting-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,73 ---- + + + Projecting Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

22.14 Projecting

+ +
+ — Function: bool project (const Focus& f, [const unsigned short proj = Projections::PERSP, [real factor = 1]])
+ — Function: bool project ([const unsigned short& proj = Projections::PERSP, [real factor = 1]])
+

These functions calculate projective_coordinates. + proj indicates which projection is to be performed. + If it is Projections::PERSP, then f indicates which + Focus is to be used (in the first version), or the global variable + default_focus is used (in the second). If + Projections::PARALLEL_X_Y, Projections::PARALLEL_X_Z, or + Projections::PARALLEL_Z_Y is used, f is ignored, since + these projections don't use a Focus. Currently, no other + projections are defined. The x and y coordinates in + projective_coordinates are multiplied by factor with the default + being 1. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Projections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Projections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Projections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Projections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,106 ---- + + + Projections - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Pictures, + Up: Pictures +


+
+ +

9.1 Projections

+ +

In order for a 3D graphic program to be useful, it must be able to + make two-dimensional projections of its three-dimensional constructions + so that they + can be displayed on computer screens and printed out. + These are some of the possible projections: + +

+
• Parallel projection onto one of the major planes
These projections are trivial, and can be performed by 3DLDF. They are + discussed in the following section. + +
• Parallel projection onto another plane
+ I haven't programmed these projections yet, but they might be useful, so + I probably will, when I get around to it. + +
• The perspective projection
This is the projection most people think of, when they think of + 3D-graphics. It is discussed in + detail in The Perspective Projection. + +
• The isometric and axonometric projections
+ These projections are important for engineering and drafting. I have + not yet implemented them in 3DLDF, but they are on my list of “Things + To Do”. + +
+ +

The function Picture::output() takes a const unsigned + short argument specifying the projection to be used. The user should + probably avoid using explicit unsigned shorts, but should use the + constants defined for this purpose in the + namespace Projections.1 + The constants are PERSP, PARALLEL_X_Y, + PARALLEL_X_Z, + PARALLEL_Z_Y, AXON, and ISO. The latter two should + not be used, because the axonometric and isometric projections have not + yet been implemented. + +

+ +
+
+

Footnotes

[1] Namespaces are described in + Stroustrup, The C++ + Programming Language, Chapter 8.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Circles.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Circles.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Circles.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Circles.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,99 ---- + + + Querying Circles - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Circle Operators, + Up: Circle Reference +


+
+ +

32.4 Querying

+ +
+ — const function: bool is_circular (void)
+

Returns true if the Circle is circular, otherwise + false. + +

Certain transformations, such as shearing and scaling, can cause + Circles to become non-circular. + +

          Circle c(origin, 3, 90);
+           cout << c.is_circular();
+           -| 1
+           
+           Circle d = c;
+           d.shift(2.5);
+           d.scale(2, 3);
+           cout << d.is_circular();
+           -| 0
+ 
+

+
+ [Figure 176. Not displayed.] +
+
+ Fig. 176. +
+

+ +
+ +
+ — Inline function: real get_radius (void)
+

Returns radius. +

+ +
+ — Inline function: real get_diameter (void)
+

Returns + 2 * radius. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Colors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Colors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Colors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Colors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Querying Colors - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Showing Colors, + Up: Color Reference +


+
+ +

16.6 Querying

+ +
+ — const function: bool is_on_free_store (void)
+

Returns on_free_store. This will only be true, if the + Color was created by create_new<Color>(). + See Color Reference; Constructors and Setting Functions. +

+ +
+ — Inline const function: real get_red_part ([bool decimal = false])
+ — Inline const function: real get_green_part ([bool decimal = false])
+ — Inline const function: real get_blue_part ([bool decimal = false])
+

These functions return the red_part, green_part, or + blue_part of the Color, respectively. If decimal is + false (the default), the actual real value of the “part” + is returned. Otherwise, the corresponding whole number + n such that + 0 <= n <= 255 + is returned. +

+ +
+ — const function: bool get_use_name (void)
+

Returns use_name. +

+ +
+ — Inline const function: string get_name (void)
+

Returns name. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Ellipses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Ellipses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Ellipses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Ellipses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,104 ---- + + + Querying Ellipses - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

31.7 Querying

+ +
+ — const function: bool is_elliptical (void)
+

Returns true if the Ellipse is elliptical, otherwise + false. + +

Certain transformations, such as shearing and scaling, can cause + Ellipses to become non-elliptical. +

+ +
+ — Inline const function: bool is_quadratic (void)
+

Returns true, because the equation + for an ellipse in the x-y plane with its center at the + origin is the quadratic equation + x^2/a^2 + y^2/b^2 = 1 + where a is half the horizontal axis + and b is half the vertical axis. + +

          Ellipse e(origin, 5, 2, 90);
+           e.draw();
+           Point P(e.angle_point(-35));
+           cout << ((P.get_x() * P.get_x())
+                    / (e.get_axis_h()/2 * e.get_axis_h()/2))
+                   + ((P.get_y() * P.get_y())
+                      / (e.get_axis_v()/2 * e.get_axis_v()/2));
+           -| 1
+ 
+

+
+ [Figure 163. Not displayed.] +
+
+ Fig. 163. +
+

+ +
+ +
+ — const virtual functions: bool is_cubic (void)
+ — : bool is_quartic (void)
+

These functions both return false, because the equation of an + ellipse is neither a cubic nor a quartic function. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Focuses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Focuses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Focuses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Focuses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,99 ---- + + + Querying Focuses - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Modifying Focuses, + Up: Focus Reference +


+
+ +

23.6 Querying

+ +
+ — Inline const function: const Point& get_position (void)
+

Returns position. +

+ +
+ — Inline const function: const Point& get_direction (void)
+

Returns direction. +

+ +
+ — Inline const function: const real& get_distance (void)
+

Returns distance. +

+ +
+ — Inline const function: const Point& get_up (void)
+

Returns up. +

+ +
+ — Inline const function: const Transform& get_transform (void)
+

Returns transform. +

+ +
+ — Inline const function: const real& get_transform_element (const unsigned int row, const unsigned int column)
+

Returns an element of transform, given two unsigned ints for the row + and the column. +

+ +
+ — Inline const function: const Transform& get_persp (void)
+

Returns persp. +

+ +
+ — Inline const function: const real& get_persp_element (const unsigned int row, const unsigned int column)
+

Returns an element of persp, given two unsigned ints for the row + and the column. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,241 ---- + + + Querying Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Showing Paths, + Up: Path Reference +


+
+ +

26.15 Querying

+ + + +
+ — const function: bool is_on_free_store (void)
+

Returns true, if the Path was dynamically allocated on the + free store, otherwise false. +

+ +
+ — const virtual function: bool is_planar ([const bool verbose = false, [string text = ""]])
+

Uses get_normal() to determine + whether the Path is planar or not. Returns true, if it is, + otherwise false. If verbose is true, text is written to + standard output, or “Path:”, if text is the empty string, + followed by a message saying whether the Path is planar or not. +

+ +
+ — const function: bool is_linear ([const bool verbose = false, [string text = ""]])
+

Returns true, if line_switch is true. Otherwise, + is_linear() uses get_normal() to determine whether the + Path is linear. If it is, is_linear() returns + true, otherwise false. +

+ +
+ — Inline const function: bool is_cycle (void)
+

Returns true if the Path is cyclical, i.e., + cycle_switch = true, otherwise false. Only cyclical + Paths are fillable. +

+ +
+ — Inline function: int size (void)
+

Returns the number of Points on points, i.e., + points.size(). +

+ +
+ — Inline const function: bool get_line_switch (void)
+

Returns the value of line_switch. line_switch is only + true, if the Path was created, directly or indirectly, using the + constructor taking two Point arguments only. + See Path Reference; Constructors and Setting Functions. +

+ +
+ — Function: real slope ([char a = 'x', [char b = 'y']])
+

Returns the slope of the Path in the plane indicated by the + arguments, if is_linear() returns true. Otherwise, + slope() issues an error message and returns INVALID_REAL. +

+ +
+ — const function: Path subpath (size_t start, size_t end, [const bool cycle = false, [const string connector = ""]])
+

Returns a new Path using points[start] through + points[end - 1]. If cycle is true, then the new + Path will be a cycle, whether + *this is or not. One optional connector + argument can be used. If it is, it will be the only connector. + Otherwise, the appropriate connectors from *this are used. + +

start must be < end. It is not possible to + have start > end, even if *this is a cycle. +

+ +
+ — const function: const Point& get_point (const unsigned short a)
+

Returns the Point *points[a], if a < + points.size() and the Path is non-empty, otherwise + INVALID_POINT. +

+ +
+ — const function: const Point& get_last_point (void)
+

Returns the Point pointed to by the last pointer on points. + Equivalent to get_point(get_size() - 1), but more convenient to + type. Returns INVALID_POINT, if the Path is empty. +

+ +
+ — const inline virtual function: size_t get_size (void)
+

Returns points.size(). +

+ +
+ — const function: Line get_line (void)
+

Returns a Line corresponding to the Path, if the latter is + linear. Otherwise, INVALID_LINE is returned. + See Line Reference. +

+ +
+ — const virtual function: Point get_normal (void)
+

Returns a Point representing a unit vector in the direction of the + normal to the plane of the Path, or INVALID_POINT, if + the Path is non-planar. + +

          Point P(1, 1, 1);
+           Rectangle r(P, 4, 4, 30, 30, 30);
+           Point N = r.get_normal();
+ 
+

+
+ [Figure 136. Not displayed.] +
+
+ Fig. 136. +
+

+ +

In 3DLDF, plane figures generally have constructors taking a |Point| + argument for the center, a variable number of |real| arguments for the + dimensions, and three |real| arguments for the rotation about the major + axes. The object is first created in the x-z plane, and the + Points are generated to be traversed in the counter-clockwise + direction, when seen from a Point with a positive y-coordinate. + If no rotation is specified, the normal will point in the direction of + the positive y-axis. If non-zero arguments are used for rotation, the + normal will be rotated accordingly. This direction considered to be + “outside”. However, according to Huw + Jones, Computer Graphics Through Key Mathematics, p. 197, + “outside” is considered to be the side of a plane, where the + Points are meant to be traversed in the clockwise direction. + I hope that no problems arise from this discrepancy! +

+ +
+ — const virtual function: Plane get_plane (void)
+

Creates and returns a Plane p corresponding to the Path, + if the latter is planar, otherwise INVALID_PLANE. + If the Path is planar, p.point will be the + Point pointed to by this->points[0]. + See Plane Reference. + +

          Point P(1, 1, 1);
+           Rectangle r(P, 4, 4, 45, 20, 15);
+           Plane q = r.get_plane();
+           q.show("q:");
+           -| q:
+              normal: (0.0505914, 0.745607, -0.664463)
+              point: (0.0178869, -0.727258, -1.01297)
+              distance == -0.131735
+ 
+

+
+ [Figure 137. Not displayed.] +
+
+ Fig. 137. +
+

+ +
+ +
+ — Function: void set_cycle ([const bool c = true])
+

Sets cycle_switch to c. +

+ +
+ — Function: Path reverse (bool assign)
+ — const function: Path reverse (void)
+

These functions return a Path with the same Points and + connectors as *this, but in reversed order. + reverse() can only be applied to non-cyclical Paths. If + *this is a cycle, reverse() issues an error message and + returns *this unreversed. + +

If the first version is called with assign = true, + *this itself is reversed. If *this should remain + unchanged, the const version without an argument should be + called. If, on the other hand, the first version is called with + assign = false, a warning message is issued, but the + reversed Path is returned just the same, leaving *this + unchanged. + + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,144 ---- + + + Querying Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Copying Points, + Up: Point Reference +


+
+ +

22.8 Querying

+ +
+ — inline function: bool is_identity (void)
+

Returns true if transform is the identity Transform. +

+ +
+ — const inline function: Transform get_transform (void)
+

Returns transform. +

+ +
+ — const function: bool is_on_free_store (void)
+

Returns true if memory for the Point has been dynamically + allocated on the + free store, i.e., if the Point has been created using + create_new<Point>(). + See Point Reference; Constructors and Setting Functions. +

+ +
+ — const function: bool is_on_plane (const Plane& p)
+

Returns true, if the Point lies on the + Plane p, otherwise false. + +

Planes are conceived of as having infinite extension, so while + the Point C in [next figure] + does not lie within + the Rectangle r, it does lie on q, so + C.is_on_plane(q) returns + true.1 + +

          Point P(1, 1, 1);
+           Rectangle r(P, 4, 4, 20, 45, 35);
+           Plane q = r.get_plane();
+           Point A(2, 0, 2);
+           Point B(2, 1.64143, 2);
+           Point C(0.355028, 2.2185, 6.48628);
+           cout << A.is_on_plane(q);
+           -| 0
+           cout << B.is_on_plane(q);
+           -| 1
+           cout << "C.is_on_plane(q)";
+           -| 1
+ 
+

+
+ [Figure 80. Not displayed.] +
+
+ Fig. 80. +
+

+ +
+ +
+ — const function: bool is_in_triangle (const Point& p0, const Point& p1, const Point& p2, [bool verbose = false, [bool test_points = true]])
+

Returns true, if *this lies within the triangle determined by + the three Point arguments, otherwise false. + +

If the code calling is_in_triangle() has ensured that + p_0, p_1, and p_2 determine a plane, i.e., that they are not + colinear, and that *this lies in that plane, then + false can be passed to is_in_triangle() as its + test_points argument. + +

If the verbose argument is true, information resulting from + the execution of the function are printed to standard output or standard + error. + +

This function is needed for determining whether a line intersects with a + polygon. +

+ +
+
+

Footnotes

[1] It's unlikely that Points will lie on a Plane, + unless the user constructs the case specially. + In [next figure] + , the coordinates for B and C were found by using + Plane::intersection_point(). + See Planes; Intersections.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Polygons.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Polygons.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Polygons.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Polygons.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Querying Polygons - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

27.3 Querying

+ +
+ — Virtual function: const Point& get_center (void)
+ — const function: Point get_center (void)
+

These functions return center. If the Polygon doesn't + contain any Points, a warning is issued, and INVALID_POINT + is returned. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Rectangles.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Rectangles.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Rectangles.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Rectangles.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,75 ---- + + + Querying Rectangles - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

29.5 Querying

+ +
+ — const functions: real get_axis_h (void)
+ — : real get_axis_v (void)
+

These functions return axis_h and axis_v, respectively. + +

Please note, that axis_h and axis_v are currently not + recalculated, when a Rectangle is transformed. I plan to do + something about this soon. +

+ +
+ — const function: bool is_rectangular (void)
+

Returns true, if the Rectangle is rectangular, otherwise + false. Transformations, such as shearing, can cause + Rectangles to become non-rectangular. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Closed-Plane-Curves.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Closed-Plane-Curves.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Closed-Plane-Curves.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Closed-Plane-Curves.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,126 ---- + + + Querying Regular Closed Plane Curves - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

30.2 Querying

+ +
+ — const inline virtual functions: bool is_quadratic (void)
+ — : bool is_cubic (void)
+ — : bool is_quartic (void)
+

These functions all return false. They are intended to be + overloaded by member functions of derived classes. +

+ +
+ — const inline virtual function: real_triple get_coefficients (real Slope, real v_intercept)
+

Returns a real_triple with all three values == + INVALID_REAL. Intended to be overloaded by member functions of + derived classes. +

+ +
+ — const inline virtual function: pair<real, real> solve (char axis_unknown, real known)
+

Returns a pair<real, real> with first = + second = INVALID_REAL. + Intended to be overloaded by member functions of + derived classes. +

+ +
+ — const virtual function: signed short location (Point ref_pt, Point p)
+

Returns a signed short indicating the location of p with + respect to the Reg_Cl_Plane_Curve, which must be planar. + The Reg_Cl_Plane_Curve constructors should ensure that + Reg_Cl_Plane_Curves are, but there is no guarantee that they will + not have been manipulated into a non-planar state, by shearing, for + example. + +

The argument ref_pt is used within the function for + shifting a copy of the Reg_Cl_Plane_Curve to a convenient + position. It need not be the |center| of the Reg_Cl_Plane_Curve, + however, classes derived from Reg_Cl_Plane_Curve will probably + have their own versions of location(), which will pass center + as the ref_pt argument to this function. + Reg_Cl_Plane_Curves need not have a meaningful |center|. + +

location() returns the following values: +

+
-1
p and *this are coplanar, and p lies + outside the perimeter of *this. + +
0
p and *this are coplanar, and p lies on the perimeter + of *this. + +
1
p and *this are coplanar, and p lies inside + the perimeter of *this. + +
-2
p and *this are not coplanar. + +
-3
Something has gone terribly wrong. + +
-4
The normal to *this has 0 magnitude, i.e., the + |Points| on *this are colinear. + +
-5
An error occurred in putting *this in one of + the major planes. +
+

+ +
+ — Virtual function: Point angle_point (real angle)
+

Returns INVALID_POINT. Intended to be overloaded by member functions of + derived classes. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Polygons.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Polygons.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Polygons.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Regular-Polygons.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Querying Regular Polygons - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

28.4 Querying

+ +
+ — const inline function: real get_radius (void)
+

Returns radius. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,63 ---- + + + Querying Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Clearing Shapes, + Up: Shape Reference +


+
+ +

18.8 Querying

+ +
+ — const pure virtual function: bool is_on_free_store (void)
+

Returns true if the object was allocated on the free store, + otherwise false. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Querying Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

34.7 Querying

+ +
+ — const virtual function: bool is_on_free_store (void)
+

Returns the value of on_free_store; true, if the + Solid was dynamically allocated on the free store, otherwise + false. + Solids, and objects of classes derived from Solid, + should only ever be allocated on the free store by + a specialization of the template function create_new(). + See Solid Reference; Constructors and Setting Functions. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Querying-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Querying-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,88 ---- + + + Querying Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

19.7 Querying

+ +
+ — Function: bool is_identity (void)
+

Returns true if *this is the identity Transform, + otherwise false. This function has both a const and a + non-const version. In the non-const version, + clean() is called on *this before comparing the elements of + matrix with 1 (for the main diagonal) and 0 (for the other + elements). In the const version, *this is copied, + clean() is called on the copy, and the elements of the copy's + matrix are compared with 0 and 1. +

+ +
+ — const function: real get_element (const unsigned short row, const unsigned short col)
+

Returns the value stored in the element of matrix indicated by the arguments. + +

          Transform t;
+           t.shift(1, 2, 3);
+           t.scale(2.5, -1.2, 4);
+           t.rotate(30, 15, 60);
+           t.show("t:");
+           -| t:
+               1.21    2.09   0.647       0
+              0.822  -0.654    0.58       0
+              -2.18   0.224    3.35       0
+              -3.69    1.45    11.8       1
+           cout << t.get_element(2, 1);
+           -| 0.224
+ 
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,130 ---- + + + Rectangle Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Rectangle Data Members, + Up: Rectangle Reference +


+
+ +

29.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Rectangle (void)
+

Creates an empty Rectangle. +

+ +
+ — Constructor: void Rectangle (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Creates a Rectangle in the x-z plane, centered at the origin, + with width == aaxis_h + (in the + or - x + direction), + and height == aaxis_v + (in the + + or - z + direction). + If one or more of the arguments + angle_x, angle_y, or angle_z are used, it is rotated + by those amounts around the appropriate axes. + Finally, the Rectangle is shifted such that + its center lies at ccenter. + +

          Point C(-1, -1, 1);
+           Rectangle r(C, 3, 4, 30, 30, 30);
+ 
+

+
+ [Figure 151. Not displayed.] +
+
+ Fig. 151. +
+

+ +
+ +
+ — Setting function: void set (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Corresponds to the constructor described above. +

+ +
+ — Constructor: void Rectangle (const Point& p0, const Point& p1, const Point& p2, const Point& p3)
+

Creates Rectangle using four Point + arguments. The order of the arguments must correspond with a path + around the Rectangle. + +

This function does not currently check that the arguments yield a valid + Rectangle, therefore all code using it must ensure that they do. + +

+ +
+ — Setting function: void set (const Point& pt0, const Point& pt1, const Point& pt2, const Point& pt3)
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Rectangle* create_new<Rectangle> (const Rectangle* r)
+ — : Rectangle* create_new<Rectangle> (const Rectangle& r)
+

Pseudo-constructors for dynamic allocation of Rectangles. + They create a Rectangle on the free store and allocate memory for it using + new(Rectangle). They return a pointer to the new Rectangle. + +

If r is a non-zero pointer or a reference, + the new Rectangle will be a copy of + r. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Rectangle>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,79 ---- + + + Rectangle Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

29.1 Data Members

+ +
+ — Private variables: real axis_h
+ — : real axis_v
+

The lengths of the horizontal and vertical axes, respectively, of the + Rectangle. Actually, + they are merely the horizontal and vertical axes by convention, since + there are no restrictions on the orientation of an Rectangle. + +

Please note that axis_h and axis_v are currently not + recalculated, when a Rectangle is transformed. I plan to do + something about this soon. +

+ +
+ — Private variable: bool on_free_store
+

true, if the Rectangle was dynamically allocated on the + free store, otherwise false. Dynamic allocation of + Rectangles should only be + performed by create_new<Rectangle>(), which sets + on_free_store to true. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Rectangle Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

29.3 Operators

+ +
+ — Assignment Operator: const Rectangle& operator= (const Rectangle& r)
+

Makes the Rectangle a copy of r. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangle-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangle-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,78 ---- + + + Rectangle Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Regular Polygon Reference, + Up: Top +


+
+ +

29 Rectangle Reference

+ +

Class Rectangle is defined in rectangs.web, and + is derived from Polygon, using public derivation. + +

As noted above in Polygon Reference; Affine Transformations, class Rectangle, + like class Reg_Polygon, + currently inherits its transformation functions and + operator*=(const Transform&) from Polygon. Consequently, + the data members of a Rectangle, except for center, are + not recalculated when it's transformed. I plan to change this soon! It + will also be necessary to add the function + Rectangle::is_rectangular(), in order to test whether a + Rectangle is still rectangular. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangles-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangles-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangles-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangles-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,190 ---- + + + Rectangles Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Regular Polygons Getstart, + Up: Plane Figures +


+
+ +

7.2 Rectangles

+ +

A Rectangle can be constructed in the x-z plane by specifying a + center Point, the width, and the height: + +

     Rectangle r(origin, 2, 3);
+      r.draw();
+ 
+

+
+ [Figure 27. Not displayed.] +
+
+ Fig. 27. +
+

+ +

Three additional arguments can be used to specify rotation about the x, + y, and z-axes respectively: + +

     Rectangle r(origin, 2, 3, 30, 45, 15);
+      r.draw();
+ 
+

+
+ [Figure 28. Not displayed.] +
+
+ Fig. 28. +
+

+ +

If a Point p other than the origin is specified as the center of + the Rectangle, the latter is first created in the x-z plane, + centered about the origin, as above. Then, any rotations specified are + performed. Finally, the Rectangle is shifted such that its center + comes to lie at p: + +

     Point p0(.5, 1, 3);
+      Rectangle r(p0, 4, 2, 30, 30, 30);
+      r.draw();
+ 
+

+
+ [Figure 29. Not displayed.] +
+
+ Fig. 29. +
+

+ +

This constructor has a corresponding setting function: + +

     Rectangle r;
+      for (int i = 0; i < 180; i += 30)
+        {
+          r.set(origin, 4, 2, i);
+          r.draw();
+        }
+ 
+

+
+ [Figure 30. Not displayed.] +
+
+ Fig. 30. +
+

+ +

Rectangles can also be specified using four Points as + arguments, whereby they must be ordered so that they are contiguous in + the resulting Rectangle: + +

     Point pt[4];
+      pt[0].shift(-1, -2);
+      pt[2] = pt[1] = pt[0];
+      pt[1].rotate(180);
+      pt[3] = pt[1];
+      pt[2] *= pt[3].rotate(0, 180);
+      Rectangle r(pt[0], pt[2], pt[3], pt[1]);
+      r.draw();
+ 
+

+
+ [Figure 31. Not displayed.] +
+
+ Fig. 31. +
+

+ +

This constructor checks whether the Point arguments are coplanar, + however, it does not check whether they are really the corners of a + valid rectangle; the user, or the code that calls this function, must + ensure that they are. In the following + example, r, although not rectangular, is a Rectangle, as + far as 3DLDF is concerned: + +

     pt[0].shift(0, -1);
+      pt[3].shift(0, 1);
+      Rectangle q(pt[0], pt[2], pt[3], pt[1]);
+      q.draw();
+ 
+

+
+ [Figure 32. Not displayed.] +
+
+ Fig. 32. +
+

+ +

This constructor is not really intended to be used directly, but should + mostly be called from within other functions, that should ensure that + the arguments produce a rectangular Rectangle. There is also no + guarantee that transformations or other functions called on + Rectangle, Circle, or other classes representing + geometric figures won't cause them to become non-rectangular, + non-circular, or otherwise irregular. Sometimes, this might even be + desirable. I plan to add the function + Rectangle::is_rectangular() soon, so that users can test + Rectangles for rectangularity. + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangles-for-Ellipses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangles-for-Ellipses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rectangles-for-Ellipses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rectangles-for-Ellipses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,152 ---- + + + Rectangles for Ellipses - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Previous: Solving Ellipses, + Up: Ellipse Reference +


+
+ +

31.11 Rectangles

+ +
+ — const function: Rectangle out_rectangle (void)
+

Returns the Rectangle that surrounds the Ellipse. + +

          Ellipse e(origin, 3, 4, 45, 30, 17);
+           e.shift(1, -1, 2);
+           Rectangle r = e.out_rectangle();
+           r.filldraw(black, gray);
+           e.unfilldraw(black);
+ 
+

+
+ [Figure 172. Not displayed.] +
+
+ Fig. 172. +
+

+ +
+ +
+ — const function: Rectangle in_rectangle (void)
+

Returns the Rectangle enclosed within the Ellipse. + +

          Rectangle r = e.in_rectangle();
+           e.filldraw(black, gray);
+           r.unfilldraw(black);
+ 
+

+
+ [Figure 173. Not displayed.] +
+
+ Fig. 173. +
+

+ +
+ +
+ — const function: Rectangle draw_out_rectangle ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Rectangle that surrounds the Ellipse. The arguments + are like those of Path::draw(). + The return value is the surrounding Rectangle. + See Path Reference; Drawing and Filling. + +

          Ellipse e(origin, 2.5, 5, 10, 12, 15.5);
+           e.shift(-1, 1, 1);
+           e.draw_out_rectangle(black, "evenly", "pencircle scaled .3mm");
+ 
+

+
+ [Figure 174. Not displayed.] +
+
+ Fig. 174. +
+

+ +
+ +
+ — const function: Rectangle draw_in_rectangle ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Rectangle enclosed within the Ellipse. The arguments + are like those of Path::draw(). + The return value is the enclosed Rectangle. + See Path Reference; Drawing and Filling. + +

          Ellipse e(origin, 3.5, 6, 10, 12, 15.5);
+           e.shift(-1, 1, 1);
+           e.draw_in_rectangle(black, "evenly", "pencircle scaled .3mm");
+ 
+

+
+ [Figure 175. Not displayed.] +
+
+ Fig. 175. +
+

+ +
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Register-Width.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Register-Width.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Register-Width.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Register-Width.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Register Width - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Endianness, + Up: System Information +


+
+ +

15.2 Register Width

+ +
+ — Function: unsigned short get_register_width (void)
+

Returns the register width of the CPU of the system on which 3DLDF is + being run. This will normally be either 32 or 64 bits. + +

This is the C++ + code: + +

          return (sizeof(void*) * CHAR_BIT);
+ 
+

This assumes that an address will be the same size as the processor's + registers, and that CHAR_BIT will be the number of bits in a + byte. These are reasonable assumptions that apply to all architectures + I know about. + +

This function is called by is_32_bit() and is_64_bit(). +

+ +
+ — Function: bool is_32_bit (void)
+

Returns true if the CPU of the system on which 3DLDF is being run + has a register width of 32 bits, otherwise false. +

+ +
+ — Function: bool is_64_bit (void)
+

Returns true if the CPU of the system on which 3DLDF is being run + has a register width of 64 bits, otherwise false. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Regular Closed Plane Curve Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

30.1 Data Members

+ +
+ — Protected variable: Point center
+

The center of the Reg_Cl_Plane_Curve, if it has one. +

+ +
+ — Protected variable: unsigned short number_of_points
+

The number of Points on points in a + Reg_Cl_Plane_Curve. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Intersections.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Intersections.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Intersections.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Intersections.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,146 ---- + + + Regular Closed Plane Curve Intersections - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

30.3 Intersections

+ +
+ — const function: bool_point_pair intersection_points (Point ref_pt, Point p0, Point p1)
+ — const function: bool_point_pair intersection_points (const Point& ref_pt, const Path& p)
+

The version of this function taking Point arguments finds the + intersection points, if any, of the + Reg_Cl_Plane_Curve and the line + p + that passes through the Points + p_0 + and + p_1. + In the other version, the Path argument must be a linear + Path, and its first and last Points are passed to the + first version of this function as p0 and p1, respectively. + +

Let + C + be the Reg_Cl_Plane_Curve. + C and p can intersect at at most two intersection points + i_1 and i_2. + Let bpp be the return + value of this function. + The intersection points need not be on the line segment + between pt0 and pt1. + bpp.first.pt will be set + to the first intersection point if it exists, or INVALID_POINT if + it doesn't. If the first intersection point exists and is on the line + segment between pt0 and pt1 + +

In [next figure] + , the line AB + is normal to the + Ellipse e, or, to put it another way, AB + is + perpendicular to the plane of e. The intersection point i_0 lies + within the perimeter of e. + +

The line DE + is skew to the plane of e, and + intersects e at i_1, on the perimeter of e. + +

          Point p0(2, 2, 3);
+           Ellipse e(p0, 3, 4, 30, -60, -5.2);
+           Point p1 = p0.mediate(e.get_point(11), .5);
+           Point A = e.get_normal();
+           A *= 2.5;
+           A.shift(p1);
+           Point B = A.mediate(p1, 2);
+           bool_point_pair bpp = e.intersection_points(A, B);
+           Point C(0, 2, 0);
+           Point D(0, -3.5, 0);
+           C *= D.rotate(2, 0, -5);
+           C *= D.shift(e.get_point(4));
+           bpp = e.intersection_points(C, D);
+ 
+

+
+ [Figure 154. Not displayed.] +
+
+ Fig. 154. +
+

+ +

In [next figure] + , q and e are coplanar. In this case, + only the intersections of q with the perimeter of e are returned by + intersection_points(). + +

          A = p0.mediate(e.get_point(3), 1.5);
+           B = p0.mediate(e.get_point(11), 1.5);
+           Path q(A, B);
+           bpp = e.intersection_points(q);
+ 
+

+
+ [Figure 155. Not displayed.] +
+
+ Fig. 155. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,115 ---- + + + Regular Closed Plane Curve Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Rectangle Reference, + Up: Top +


+
+ +

30 Regular Closed Plane Curve Reference

+ +

Class Reg_Cl_Plane_Curve is defined in curves.web. + It is derived from Path using public derivation. + +

Reg_Cl_Plane_Curve is not called + “Regular_Closed_Plane_Curve” because the longer name + causes too many “Overfull boxes”1 + in the CWEAVE output of the program code. + See CWEB Documentation. + +

Reg_Cl_Plane_Curve is meant to be used as a base class; no + objects should be declared of type Reg_Cl_Plane_Curve. + Currently, class Ellipses is derived from + Reg_Cl_Plane_Curve and class Circle is derived from + Ellipse. + +

At present, I have no fixed definition of what constitutes + “regularity” as far as Reg_Cl_Plane_Curves are concerned. + Ellipses and circles are “regular” in the sense that they have axes of + symmetry. There must be an equation for a Reg_Cl_Plane_Curve, + such as + x^2 + y^2 = r^2 + for a circle. + A derived class should have a solve() function that uses this + equation. Reg_Cl_Plane_Curve::intersection_points() in turn uses + solve() to find the intersection points of a line with the + Reg_Cl_Plane_Curve. This way, the derived classes don't need + their own functions for finding their intersections with a line. + However, such functions can be added, if desired. + +

It is assumed that classes derived from Reg_Cl_Plane_Curve are + fillable, which implies that they must be closed Paths. + Reg_Cl_Plane_Curves inherit their drawing and filling functions + from Path. + +

The constructors and setting functions of classes derived from + Reg_Cl_Plane_Curve must ensure that the resulting geometric + figures are planar, convex, and that the number of Points they contain is + a multiple of 4. The latter assumption is of importance in + intersection_points(), segment(), half(), and + quarter(). + See Regular Closed Plane Curve Reference; Intersections, and + Regular Closed Plane Curve Reference; Segments. + +

+ +
+
+

Footnotes

[1] If you don't + know what “overfull boxes” are, don't worry about it. It has to do with + TeX's line and page breaking algorithms. If you want to know more, + see Knuth, Donald E., The TeXbook.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Segments.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Segments.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Segments.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Closed-Plane-Curve-Segments.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,152 ---- + + + Regular Closed Plane Curve Segments - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +

30.4 Segments

+ +
+ — const function: Path segment (unsigned int factor, [real angle = 0, [bool closed = true]])
+

Returns a Path representing a segment of the Reg_Cl_Plane_Curve. + factor must be + >1 and <= number_of_points. If it is not, an error message is + issued and an empty Path is returned. + +

If angle is non-zero, the segment Path is rotated by + angle about a line from center in the direction of the + normal to the plane of the Reg_Cl_Plane_Curve. + Please note, that a Reg_Cl_Plane_Curve must have a meaningful + center, in order for rotation to work. + If the absolute value of + angle >360, a warning is issued, and + fmod(angle, 360) is used. + +

If closed is true, the Path will be a cycle, with + the ends of the curved segment joined using the connector ‘--’. + The curved segment is joined to the line using ‘&’ on each side. + +

          Circle c(origin, 4, 30, 30, 30);
+           Path p = c.segment(3, 130);
+           p.show("p:");
+           -| p:
+           points.size() == 8
+           connectors.size() == 8(-0.00662541, -0.888379, -1.79185) ..
+           (0.741088, -0.673392, -1.73128) ..
+           (1.37598, -0.355887, -1.40714) ..
+           (1.80139, 0.0157987, -0.868767) ..
+           (1.95255, 0.385079, -0.198137) .. (1.80646, 0.695735, 0.502658) &
+           (1.80646, 0.695735, 0.502658) --
+           (-0.00662541, -0.888379, -1.79185) & cycle;
+ 
+

+
+ [Figure 156. Not displayed.] +
+
+ Fig. 156. +
+

+ +
+ +
+ — const inline function: Path half ([real angle = 0, [bool closed = true]])
+

Returns a Path using half of the Points on the + Reg_Cl_Plane_Curve. + The effect of the arguments angle and closed is similar to + that in segment(), above. + +

          Ellipse e(origin, 3, 5, 20, 15, 12.5);
+           Path p = e.half(0, false);
+ 
+

+
+ [Figure 157. Not displayed.] +
+
+ Fig. 157. +
+

+ +
+ +
+ — const inline function: Path quarter ([real angle = 0, [bool closed = true]])
+

Returns a Path using a quarter of the Points on the + Reg_Cl_Plane_Curve. + The effect of the arguments angle and closed is similar to + that in segment(), above. + +

          Ellipse e(origin, 3, 5, 60, 5, 2.5);
+           Path p = e.quarter(180, false);
+ 
+

+
+ [Figure 158. Not displayed.] +
+
+ Fig. 158. +
+

+ +
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Platonic-Polyhedra.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Platonic-Polyhedra.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Platonic-Polyhedra.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Platonic-Polyhedra.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,70 ---- + + + Regular Platonic Polyhedra - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

37.2 Regular Platonic Polyhedra

+ +

3DLDF currently has classes for three of the five regular Platonic + polyhedra: Tetrahedron, Dodecahedron, and + Icosahedron. There is no need for a special Cube class, + because cubes can be created using Cuboid with equal width, + height, and depth arguments (see Cuboid Reference). Octahedron is + missing at the moment, but I plan to add it soon. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,136 ---- + + + Regular Polygon Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

28.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Reg_Polygon (void)
+

Creates an empty Reg_Polygon. +

+ +
+ — Constructor: void Reg_Polygon (const Point& ccenter, const unsigned short ssides, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Creates a Reg_Polygon in the x-z plane, centered at the origin, + with the number of sides specified by ssides and with + radius = ddiameter / 2. + +

The Reg_Polygon is rotated + about the x, y, and z-axes in that order by the angles given by + angle_x, angle_y, and angle_z, respectively, if any + one of them is non-zero. Finally, the + Reg_Polygon is shifted such that its center is located at + ccenter. + +

          Reg_Polygon r(origin, 3, 2.75, 10, 15, 12.5);
+           r.draw();
+ 
+

+
+ [Figure 145. Not displayed.] +
+
+ Fig. 145. +
+

+ +
+ +
+ — Setting function: void set (const Point& ccenter, const unsigned short ssides, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Corresponds to the constructor above. + +

A Reg_Polygon can theoretically have any number of sides, however + I haven't tested it for unreasonably large values. The following + example demonstrates that set() can be used to change a + Reg_Polygon. + +

          Reg_Polygon r;
+           real j = .5;
+           for (int i = 3; i <= 16; ++i)
+             {
+               r.set(origin, i, j);
+               r.draw();
+               j += .5;
+             }
+ 
+

+
+ [Figure 146. Not displayed.] +
+
+ Fig. 146. +
+

+ +
+ +
+ — Template specializations: Reg_Polygon* create_new<Reg_Polygon> (const Reg_Polygon* r)
+ — : Reg_Polygon* create_new<Reg_Polygon> (const Reg_Polygon& r)
+

Pseudo-constructors for dynamic allocation of Reg_Polygons. + They create a Reg_Polygon on the free store and allocate memory for it using + new(Reg_Polygon). They return a pointer to the new Reg_Polygon. + If r is a non-zero pointer or a reference, + the new Reg_Polygon will be a copy of + r. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Reg_Polygon>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Regular Polygon Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

28.1 Data Members

+ +
+ — Private variable: real internal_angle
+

The angle at the center of the Reg_Polygon of the triangle formed + by the center and two adjacent corners. + If n is the number of sides of a Reg_Polygon, + internal_angle will be 360.0/n, so internal_angle + will be 120 for a regular triangle, 90 for a square, 72 for a pentagon, + etc. + +

+ +
+ — Private variable: real radius
+

The radius of the surrounding circle for a Reg_Polygon (Umkreis). +

+ +
+ — Private variable: unsigned short sides
+

The number of sides of a Reg_Polygon. +

+ +
+ — Private variable: bool on_free_store
+

true, if the Reg_Polygon was dynamically allocated on the + free store, otherwise false. Dynamic allocation of + Reg_Polygons should only be + performed by create_new<Reg_Polygon>(), which sets + on_free_store to true. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Regular Polygon Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

28.3 Operators

+ +
+ — Operator: const Reg_Polygon& operator= (const Reg_Polygon& p)
+

Makes the Reg_Polygon a copy of p. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygon-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,77 ---- + + + Regular Polygon Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Polygon Reference, + Up: Top +


+
+ +

28 Regular Polygon Reference

+ +

Class Reg_Polygon is defined in polygons.web, and + is derived from Polygon, using public derivation. + +

As noted above in Polygon Reference; Affine Transformations, class Reg_Polygon, + like class Rectangle, + currently inherits its transformation functions and + operator*=(const Transform&) from Polygon. Consequently, + the data members of a Reg_Polygon, except for center, are + not recalculated when it's transformed. I plan to change this soon! It + will also be necessary to add the function + Reg_Polygon::is_reg_polygonal(), in order to test whether a + Reg_Polygon is still regular and polygonal. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygons-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygons-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Regular-Polygons-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Regular-Polygons-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,201 ---- + + + Regular Polygons Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Plane Figures, + Up: Plane Figures +


+
+ +

7.1 Regular Polygons

+ +

The following example creates a pentagon in the x-z plane, centered + about the origin, whose enclosing circle has a radius equal to 3cm. + +

     default_focus.set(2, 3, -10, 2, 3, 10, 10);
+      Reg_Polygon p(origin, 5, 3);
+      p.draw();
+ 
+

+
+ [Figure 20. Not displayed.] +
+
+ Fig. 20. +
+

+ +

Three additional arguments cause the pentagon to be rotated about the x, + y, and z axes by the amount indicated. In this example, it's rotated + 90 degrees + +

about the x-axis, so that it comes to lie in the x-y plane: + +

     Reg_Polygon p(origin, 5, 3, 90);
+      p.draw();
+ 
+

+
+ [Figure 21. Not displayed.] +
+
+ Fig. 21. +
+

+ +

In this example, it's rotated + 36 degrees + +

about the y-axis, so that it appears to point in the opposite + direction from the first example: +

     Reg_Polygon p(origin, 5, 3, 0, 36);
+      p.draw();
+ 
+

+
+ [Figure 22. Not displayed.] +
+
+ Fig. 22. +
+

+ +

In this example, it's rotated + 90 degrees + +

about the z-axis, so that it lies in the z-y plane: + +

     Reg_Polygon p(origin, 5, 3, 0, 0, 90);
+      p.draw();
+ 
+

+
+ [Figure 23. Not displayed.] +
+
+ Fig. 23. +
+

+ +

In this example, it's rotated + 45 degrees + +

about the x, y, and z-axes in that order: + +

     Reg_Polygon p(origin, 5, 3, 45, 45, 45);
+      p.draw();
+ 
+

+
+ [Figure 24. Not displayed.] +
+
+ Fig. 24. +
+

+ +

Reg_Polygons need not be centered about the origin. If + another Point pt is used as the first argument, the Reg_Polygon + is first created with its center at the origin, then the specified + rotations, if any, are performed. Finally, the Reg_Polygon is + shifted such that its center comes to lie on pt: + +

     Point P(-2, 1, 1);
+      Reg_Polygon hex(P, 6, 4, 60, 30, 30);
+      hex.draw();
+ 
+

+
+ [Figure 25. Not displayed.] +
+
+ Fig. 25. +
+

+ +

In the following example, the Reg_Polygon polygon is first + declared using the default constructor, which creates an empty + Reg_Polygon. Then, the polygon is repeatedly changed using + the setting function corresponding to the constructor used in the + previous examples. [next figure] + demonstrates that a given + Reg_Polygon need not always have the same number of sides. + +

     Point p(0, -3);
+      Reg_Polygon polygon;
+      for (int i = 3; i < 9; ++i)
+        {
+          polygon.set(p, i, 3);
+          polygon.draw();
+          p.shift(0, 1);
+        }
+ 
+

+
+ [Figure 26. Not displayed.] +
+
+ Fig. 26. +
+

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Resetting-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Resetting-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Resetting-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Resetting-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,62 ---- + + + Resetting Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

19.12 Resetting

+ +
+ — Function: void reset (void)
+

Resets matrix to the identity matrix. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Coordinates.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Coordinates.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Coordinates.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Coordinates.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,152 ---- + + + Returning Coordinates - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Querying Points, + Up: Point Reference +


+
+ +

22.9 Returning Coordinates

+ +

The functions in this section return either a single coordinate or a set of + coordinates. Each has + a const and a non-const version. + +

The arguments are the same, with one exception: + +

+
char c
Only in get_coord(). Indicates which coordinate should be + returned. Valid values are 'x', 'X', 'y', + 'Y', 'z', 'Z', 'w', and 'W'. + +
char coords
Indicates the set of coordinates which should be returned or from which + the coordinate to be returned should be chosen from. Valid values are + 'w' for world_coordinates (the default), 'p' for + projective_coordinates, 'u' for user_coordinates, + and 'v' for view_coordinates. + +
const bool do_persp
Only relevant if projective_coordinates, or one of its elements + is to be returned. If true, the + default, then project() is called, thereby generating values for + projective_coordinates. If do_persp is false, then + projective_coordinates, or one of its elements, is + returned unchanged, which may sometimes be useful. + +
const bool do_apply
If true (the default), apply_transform() is called, + thereby updating the world_coordinates. Otherwise, it's not, so + that the values stored in world_coordinates remain unchanged. + Note that if coords is 'p' and do_persp is true, + apply_transform() will be called in project() + whether do_apply is true or false. If for some + reason, one wanted get projective_coordinates, or one of its + values, based on the + projection of world_coordinates without first updating them, one + would have to call reset_transform() before calling one of + these functions. It would probably be a good idea to save transform + before doing so. + +
Focus* f
Indicates what Focus is to be used for projection. + Only relevant if coords is 'p', i.e., + projective_coordinates, or one of its elements, is to be + returned. The default is 0, in which case f points to the global + variable default_focus. + +
const unsigned short proj
Indicates what form of projection is to be used. + Only relevant if coords is 'p', i.e., + projective_coordinates, or one of its elements, is to be + returned. The default is Projections::PERSP, which causes the + perspective projection to be applied. + +
real factor
Passed to project(). The values of the x and y coordinates in + projective_coordinates are multiplied by factor. + Only relevant if coords is 'p', i.e., + projective_coordinates, or one of its elements, is to be + returned. The default is 1. +
+ +
+ — Function: valarray <real> get_all_coords ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns one of the sets of coordinates; world_coordinates by + default. + Returns a complete set of coordinates: 'w' for world_coordinates, + 'p' for projective_coordinates, 'u' for + user_coordinates, or'v' for view_coordinates. +

+ +
+ — Function: real get_coord (char c, [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns one coordinate, x, y, z, or w, from the set of + coordinates indicated (or world_coordinates, by default). +

+ +
+ — Function: real get_x ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the x-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ +
+ — Function: real get_y ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the y-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ +
+ — Function: real get_z ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the z-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ +
+ — Function: real get_w ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the w-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Returning Elements and Information Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Querying Solids, + Up: Solid Reference +


+
+ +

34.8 Returning Elements and Information

+ +
+ — const virtual function: const Point& get_center (void)
+

Returns center. If the Solid doesn't + have a meaningful center, the return value will probably be + INVALID_POINT. +

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-for-Ellipses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-for-Ellipses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-for-Ellipses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Elements-and-Information-for-Ellipses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,223 ---- + + + Returning Elements and Information for Ellipses - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Querying Ellipses, + Up: Ellipse Reference +


+
+ +

31.8 Returning Elements and Information

+ +
+ — Virtual function: Point& get_center (void)
+ — const virtual function: Point get_center (void)
+

These functions return center. + +

+ +
+ — Function: const Point& get_focus (const unsigned short s)
+ — const function: Point get_focus (const unsigned short s)
+

These functions return focus0 or focus1, depending on the + value of s, which must be 0 or 1. If s is not 0 or 1, + get_focus() returns INVALID_POINT. + +

+ +
+ — const function: real get_linear_eccentricity (void)
+

Returns linear_eccentricity. + +

+ +
+ — const function: real get_numerical_eccentricity (void)
+

Returns numerical_eccentricity. + +

+ +
+ — Function: real get_axis_v (void)
+ — const function: real get_axis_v (void)
+

Calculates and returns the value of axis_h. + +

get_axis_v() first checks if the Ellipse is still + elliptical, using is_elliptical() + (see Ellipse Reference; Querying). + Operations such as scale() and shear() can + cause an Ellipse to become non-elliptical. + If this is the case, this function returns INVALID_REAL. + +

If the Ellipse is still elliptical, axis_v is + recalculated and returned. In the non-const version, + axis_v is also reset to the new value. +

+ +
+ — Function: real get_axis_h (void)
+ — const function: real get_axis_h (void)
+

Calculates and returns the value of axis_h. + +

get_axis_h() first checks if the Ellipse is still + elliptical, using is_elliptical() + (see Ellipse Reference; Querying). + Operations such as scale() and shear() can + cause an Ellipse to become non-elliptical. + If this is the case, this function returns INVALID_REAL. + +

If the Ellipse is still elliptical, axis_h is + recalculated and returned. In the non-const version, + axis_h is also reset to the new value. +

+ +
+ — const virtual function: signed short location (Point p)
+

Returns a value l indicating the location of the Point argument + p with respect to the Ellipse. + +

Let e stand for the Ellipse. + The return values are as follows: + +

+
0
p lies on the perimeter of e. + +
1
p lies in the plane of e, within its perimeter. + +
-1
p lies in the plane of e, outside its perimeter. + +
-2
p and e do not lie in the same plane. + +
-3
e is not elliptical, possibly due to having been transformed. +
+ +
          Ellipse e(origin, 3, 5, 45, 15, 3);
+           e.shift(2, 1, 1);
+           Point A = e.get_point(7);
+           cout << e.location(A);
+           -| 0
+           Point B = center.mediate(e.get_point(2));
+           cout << e.location(B);
+           -| 1
+           Point C = center.mediate(e.get_point(2), 1.5);
+           cout << e.location(C);
+           -| -1
+           Point D = A;
+           D.shift(-2, 0, 4);
+           e.location(D);
+           -| WARNING! In Ellipse::location():
+              Point doesn't lie in plane of Ellipse.
+              Returning -2.
+           e.scale(1.5, 0, 1.5);
+           e.location(A);
+           -| WARNING! In Ellipse::do_transform(const Transform&):
+              This transformation has made *this non-elliptical!
+           
+              ERROR! In Ellipse::location():
+              Ellipse is non-elliptical. Returning -3.
+ 
+

+
+ [Figure 164. Not displayed.] +
+
+ Fig. 164. +
+

+ +
+ +
+ — const function: Point angle_point (real angle)
+

Returns a point on the Ellipse given an angle. + A Point p is set to the zeroth Point on the Ellipse + and rotated about the line from the center of the Ellipse in the + direction of the normal to the plane of the Ellipse. + Then, the intersection of the ray from the center through + p and the perimeter of the Ellipse is returned. + +

          Ellipse e(origin, 6, 4);
+           Point P = e.angle_point(135);
+           current_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 165. Not displayed.] +
+
+ Fig. 165. +
+

+ +

[next figure] + demonstrates, that the rotation is unfortunately not always + in the direction one would prefer. I don't have a solution to this + problem yet. + +

          Ellipse e(origin, 6, 4, 90);
+           Point P = e.angle_point(135);
+           Point Q = e.angle_point(-135);
+ 
+

+
+ [Figure 166. Not displayed.] +
+
+ Fig. 166. +
+

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,118 ---- + + + Returning Information for Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Returning Coordinates, + Up: Point Reference +


+
+ +

22.10 Returning Information

+ +
+ — Static function: real epsilon (void)
+

Returns the positive real value of smallest magnitude + \epsilon that should be used as a coordinate value in a + Point. + A coordinate of a Point may also contain + -\epsilon. + +

The value \epsilon is used for testing the equality of + Points in Point::operator==() + (see Point Reference; Operators): + +

Let \epsilon be the value returned by epsilon(), + P and Q be + Points, and P_x, Q_x, P_y, Q_y, + P_z, and Q_z the updated x, y, and z-coordinates of P and Q, + respectively. + If and only if + ||P_x| - |Q_x|| < \epsilon, ||P_y| - |Q_y|| < \epsilon, + and + ||P_z| - |Q_z|| < \epsilon, then + P = Q. + +

epsilon() returns different values, depending on whether + real is float or double: + If real is float (the default), epsilon() + returns 0.00001. + If real is double, it returns 0.000000001. + +

Please note: I haven't tested whether 0.000000001 is a good + value yet, so users should be aware of this if they set real to + double!1 + The way to test this is to start with two Points + P and Q at different locations. + Then they should be transformed using different rotations in such a way + that they should end up at the same location. + Let \epsilon stand for the value returned by epsilon(), + and let x, y, and y stand for + the world_coordinates of the Points after + apply_transform() has been called on them. + If x_P = x_Q, y_P = y_Q, and + z_P = z_Q, + \epsilon is a good value. + +

Rotation causes a significant loss of precision to due to the use of the + sin() and cos() functions. Therefore, neither + Point::epsilon() nor Transform::epsilon() + (see Tranform Reference; Returning Information) + can be as small as I'd like them to be. If they are two + small, operations that test for equality of Transforms and + Points will return false for objects that should be + equal. +

+ +
+
+

Footnotes

[1] For that matter, I haven't really tested whether 0.00001 is a + good value when real is float.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Information-for-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,107 ---- + + + Returning Information for Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Querying Transforms, + Up: Transform Reference +


+
+ +

19.8 Returning Information

+ +
+ — Static function: real epsilon (void)
+

Returns the positive real value of smallest magnitude + \epsilon which an element of a Transform should + contain. An element of a Transform may also contain + -\epsilon. + +

The value \epsilon is used for in the + function clean() (see Transform Reference; Cleaning). + It will also be used for comparing Transforms, when I've added + the equality operator Transform::operator==(). + +

epsilon() returns different values, depending on whether + real is float or double: + If real is float (the default), epsilon() + returns 0.00001. + If real is double, it returns 0.000000001. + +

Please note: I haven't tested whether 0.000000001 is a good + value yet, so users should be aware of this if they set real to + double!1 + The way to test this is to transform two different + Transforms + t_1 and t_2 + using different rotations in such a way that the end + result should be the same for both Transforms. + Let \epsilon stand for the value returned by epsilon(). + If for all sets of + corresponding elements E_1 and E_2 of t_1 and + t_2, ||E_1| - |E_2|| \le \epsilon, then + \epsilon is a good value. + + It will be easier to test this when I've added + Transform::operator==(). + +

Rotation causes a significant loss of precision to due to the use of the + sin() and cos() functions. Therefore, neither + Transform::epsilon() nor Point::epsilon() + (see Point Reference; Returning Information) can be as small as I'd like them to be. If they are two + small, operations that test for equality of Transforms and + Points will return false for objects that should be equal. +

+ +
+
+

Footnotes

[1] For that matter, I haven't really tested whether 0.00001 is a + good value when real is float.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Points-for-Rectangles.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Points-for-Rectangles.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Returning-Points-for-Rectangles.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Returning-Points-for-Rectangles.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,71 ---- + + + Returning Points for Rectangles - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Rectangle Operators, + Up: Rectangle Reference +


+
+ +

29.4 Returning Points

+ +
+ — Function: Point corner (unsigned short c)
+

Returns the corner Point indicated by the argument c, which must be + between 0 and 3. + +

+ +
+ — const function: Point mid_point (unsigned short m)
+

Returns the mid-point of one of the sides. The argument c must be + between 0 and 3. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rotating-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rotating-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Rotating-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Rotating-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,154 ---- + + + Rotating Points - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Shearing Points, + Up: Transforming Points +


+
+ +

3.4 Rotating

+ + +

The function rotate() rotates a Point about one or more of + the main axes. + It takes three real arguments, specifying the + angles of rotation in degrees about the x, y, and z-axes respectively. + Only the first argument is required, the other two are 0 by default. If + rotation about the y-axis, or the y and z-axes only are required, then 0 + must be used as a placeholder for the first and possibly the second + argument. + +

     Point p(0, 1);
+      p.rotate(90);
+      p.show("p:");
+      -| p: (0, 0, -1)
+      p.rotate(0, 90);
+      p.show("p:");
+      -| p: (1, 0, 0)
+      p.rotate(0, 0, 90);
+      p.show("p:");
+      -| p: (0, 1, 0)
+ 
+

The rotations are performed successively about the + x, y, and z-axes. However, rotation is not a commutative + operation, so if rotation about the main axes in a different + order is required, then rotate() must be invoked more than once: + +

     Point A(2, 3, 4);
+      Point B(A);
+      A.rotate(30, 60, 90);
+      A.show("A:");
+      -| A: (-4.59808, -0.700962, 2.7141)
+      B.rotate(0, 0, 90);
+      B.rotate(0, 60);
+      B.rotate(30);
+      B.show("B:");
+      -| B: (-4.9641, 1.43301, -1.51795)
+ 
+

Rotation need not be about the main axes; it can also be performed + about a line defined by two Points. The function rotate() + with two Point arguments and a real argument for the + angle of rotation (in degrees) about the axis. The real argument + is optional, with + 180 degrees + +

as the default. + + + + +

     Point p0 (-1.06066, 0, 1.06066);
+      Point p1 (1.06066, 0, -1.06066);
+      p1 *= p0.rotate(0, 30, 30);
+      p0.show("p0:");
+      -| p0: (-1.25477, -0.724444, 0.388228)
+      p1.show("p1:");
+      -| p1: (1.25477, 0.724444, -0.388228)
+      p0.draw(p1);
+      Point p2(1.06066, 0, 1.06066);
+      p2.show("p2:");
+      -| p2: (1.06066, 0, 1.06066)
+      Point p3(p2);
+      p3.rotate(p1, p0, 45);
+      p3.show("p3:");
+      -| p3 (1.09721, 1.15036, 1.17879)
+      Point p4(p2);
+      p4.rotate(p1, p0, 90);
+      p4.show("p4:");
+      -| p4: (0.882625, 2.05122, 0.485242)
+      Point p5(p2);
+      p5.rotate(p1, p0, 135);
+      p5.show("p5:");
+      -| p5: (0.542606, 2.17488, -0.613716)
+      Point p6(p2);
+      p6.rotate(p1, p0);
+      p6.show("p6:");
+      -| p6: (0.276332, 1.44889, -1.47433)
+ 
+

+
+ [Figure 2. Not displayed.] +
+
+ Fig. 2. +
+

+ +

I have sometimes gotten erroneous results using rotate() for + rotation about two Points. It's usually worked to reverse the + order of the Point arguments, or to change sign of the angle + argument. I think I've fixed the problem, though. + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Roulettes-and-Involutes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Roulettes-and-Involutes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Roulettes-and-Involutes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Roulettes-and-Involutes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,74 ---- + + + Roulettes and Involutes - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Previous: Plane Tesselations, + Up: Pattern Reference +


+
+ +

33.2 Roulettes and Involutes

+ +
+ “A roulette is the curve generated by a point which is carried by + a curve which rolls on a fixed curve. [...] The locus of a point + carried by a circle rolling on a straight line is a trochoid. If + the point is inside the circle the trochoid has inflexions; if it is + outside the circle, but rigidly attached to it, the trochoid has loops. + [...] In the particular case when the point is on the circumference + of the rolling circle the roulette is a cycloid. When the circle + rolls on the outside of another circle the corresponding curves are the + epitrochoids and epicycloids; if it rolls on the inside, + they are the hypotrochoids and hypocycloids.” +
H. Martyn Cundy and A. P. Rollett, Mathematical Models, p. 46. +
+
+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Running-3DLDF.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Running-3DLDF.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Running-3DLDF.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Running-3DLDF.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,207 ---- + + + Running 3DLDF - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Installing 3DLDF, + Up: Installing and Running 3DLDF +


+
+ +

11.2 Running 3DLDF

+ +

To use 3DLDF, call + make run from the command line in the + shell. The working directory should be + 3DLDF-1.1.5.1/ or 3DLDF-1.1.5.1/CWEB. + Either will work, but the latter may be more convenient, because + this is the location of the CWEB, TeX and MetaPost files that you'll + be editing. + Alternatively, call ldfr, which is merely a + shell script that calls make run. + This takes care of running 3dldf, MetaPost, TeX, + and dvips, producing a PostScript file containing your + drawings. You can display the latter on your terminal using Ghostview + or some other + PostScript viewer, print it out, and whatever else you like to do with + PostScript files. + +

However, you can also perform the actions performed by + make run by hand, by writing your own shell + scripts, by defining Emacs-Lisp commands, or in other ways. Even if you + choose to use make run, it's important to understand what it + does. The following explains how to do this by hand. + +

The CWEB source files for 3DLDF are in the subdirectory + 3DLDF-1.1.5.1/CWEB/. They + must be ctangled, and the resulting C++ + files must be + compiled and + linked, in order to create the executable file 3dldf. + The C++ + files and header files generated by ctangle, + the object files generated by the compiler, and the executable + 3dldf all reside in 3DLDF-1.1.5.1/CWEB/. Therefore, the + latter must be your working directory. + +

Since 3DLDF has no input routine as yet, + as explained in No Input Routine, + it is necessary to add C++ + code to the function main() in + main.web, and/or in a separate function in another file. In the + latter case, the function containing the user code must be invoked in + main(). Look for the line “Your code here!” in + main.web. + +

This is an example of what you could write in main(). + Feel free to make it more complicated, if you wish. + +

     beginfig(1);
+      default_focus.set(2, 3, -10, 2, 3, 10, 20);
+      Rectangle R(origin, 5, 3);
+      Circle C(origin, 3, 90);
+      C.half(180).filldraw(black, light_gray);
+      R.filldraw();
+      C.half().filldraw(black, light_gray);
+      Point p = C.get_point(4);
+      p.shift(0, -.5 * p.get_y());
+      p.label("$C$", "");
+      Point q = R.get_mid_point(0);
+      q.shift(0, 0, -.5 * q.get_z());
+      q.label("$R$", "");
+      current_picture.output(default_focus, PERSP, 1, NO_SORT);
+      endfig(1);
+ 
+

+
+ [Figure 72. Not displayed.] +
+
+ Fig. 72. +
+

+ +
    +
  1. Save main.web, and any other CWEB files you've changed. + Since these files have changed, they must be ctangled, and the + resulting C++ + files must be recompiled. If you've changed any files + other than + main.web, ctangle will also generate a header + file for each of these files. If a header file differs from the version + that existed before ctangle was run, all of the C++ + files + that depend on it must be recompiled. Then 3dldf must be + relinked. To do this, call make 3dldf from the command line. + +

    If you've made any errors in typing your code, the + compiler should have issued error messages, so go back into + the appropriate CWEB file and correct your errors. Then call + make 3dldf again. + +

  2. Call CWEB/3dldf at the command line. It writes a + file of MetaPost code called 3DLDFput.mp. + +
  3. Run MetaPost on the file 3DLDFmp.mp, which inputs + 3DLDFput.mp. + +
              mpost 3DLDFput
    + 
    +

    The result is an Encapsulated PostScript file + 3DLDFput.<integer> for each figure in your drawing. + +

  4. The file 3DLDFtex.tex should contain code for including the + 3DLDFput.<integer> files. This is an example taken from + the 3DLDFtex.tex included in the distribution. + You may change it to suit your purposes. + +
              \vbox to \vsize{\vskip 2cm
    +           \line{\hskip 2cm Figure 1.\hss}%
    +           \vfil
    +           \line{\hskip 2cm\epsffile{3DLDFmp.1}\hss}%
    +           \vss}
    + 
    +
  5. Run TeX on 3DLDFtex.tex to produce the DVI file, + 3DLDFtex.dvi. + +
              tex 3DLDFtex
    + 
    +
  6. Run dvips on the DVI file to produce the PostScript file, + 3DLDFtex.ps. + +
              dvips -o 3DLDFtex.ps 3DLDFtex
    + 
    +
  7. 3DLDFtex.ps can be viewed using Ghostview, it can be printed using + lpr (on a Unix-like system), you can convert it to PDF with + ps2pdf, or to some other format using the appropriate program. +
+ +

I sincerely hope that it worked. If it didn't, ask your local computer + wizard for help. + +

On the computer I'm using, I found that special arguments for + setting landscape and papersize in TeX files for + DIN A3 landscape didn't work. Ghostview cut off the right sides of the + drawings. Nor did it work to call + dvips -t landscape -t a3. + This caused an error message which said that + landscape would be ignored. When I called dvips + with the -t landscape option alone, it worked, and + Ghostview showed the entire drawing. + +

Another problem was Adobe Acrobat. It would display the entire DIN A3 + page, but not always in landscape format. I was unable to find a way of + rotating the pages in Acrobat. I finally found out, that if I included + even a single letter of text in a label, Acrobat would display the + document correctly. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Scaling-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Scaling-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Scaling-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Scaling-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,82 ---- + + + Scaling Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Shifting Points, + Up: Transforming Points +


+
+ +

3.2 Scaling

+ +

The function scale() takes three real arguments. + The x, y, and z-coordinates of the Point are + multiplied by the first, second, and third arguments respectively. Only + the first argument is required; the default for the others is 1. + +

If one wants to perform scaling in either the y-dimension only, or the y + and z-dimensions only, a dummy argument of 1 must be passed for + scaling in the x-dimension. Similarly, if one wants to perform scaling + in the z-dimension only, dummy arguments of 1 must be passed for scaling + in the x and y-dimensions. + +

     Point p0(1, 2, 3);
+      p0.scale(2, 3, 4);
+      p0.show("p0:");
+      -| p0: (2, 6, 12)
+      p0.scale(2);
+      p0.show("p0:");
+      -| p0: (4, 6, 12)
+      p0.scale(1, 3);
+      p0.show("p0:");
+      -| p0: (4, 18, 12)
+      p0.scale(1, 1, 3);
+      p0.show("p0:");
+      -| p0: (4, 18, 36)
+ 
+ + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Semi_002dRegular-Archimedean-Polyhedra.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Semi_002dRegular-Archimedean-Polyhedra.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Semi_002dRegular-Archimedean-Polyhedra.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Semi_002dRegular-Archimedean-Polyhedra.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Semi-Regular Archimedean Polyhedra - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ + +

+ Previous: Regular Platonic Polyhedra, + Up: Polyhedron Reference +


+
+ +

37.3 Semi-Regular Archimedean Polyhedra

+ +

Once I've added class Octahedron, the only Platonic polyhedron I + haven't programmed yet, I plan to start adding classes + for the semi-regular Archimedean polyhedra. + +

+ + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Setting-Solid-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Setting-Solid-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Setting-Solid-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Setting-Solid-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Setting Solid Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Copying Solids, + Up: Solid Reference +


+
+ +

34.6 Setting Members

+ +
+ — Virtual function: bool set_on_free_store ([bool b = true])
+

Sets on_free_store to b. This function is + called in the template function + create_new(). + See Solid Reference; Constructors and Setting Functions. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Setting-Values-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Setting-Values-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Setting-Values-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Setting-Values-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,72 ---- + + + Setting Values Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Matrix Inversion, + Up: Transform Reference +


+
+ +

19.6 Setting Values

+ +
+ — Function: void set_element (const unsigned short row, const unsigned short col, real r)
+

Sets the element of matrix indicated by the arguments to r. + +

          Transform t;
+           t.set_element(0, 2, -3.45569);
+           t.show("t:");
+           -| t:
+                 1       0   -3.46       0
+                 0       1       0       0
+                 0       0       1       0
+                 0       0       0       1
+ 
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Setting-and-Assigning-to-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Setting-and-Assigning-to-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Setting-and-Assigning-to-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Setting-and-Assigning-to-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,99 ---- + + + Setting and Assigning to Points - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Declaring and Initializing Points, + Up: Points +


+
+ +

2.2 Setting and Assigning to Points

+ +

It is possible to change the value of the coordinates of Points + by using the assignment operator = + (Point::operator=()) or the function Point::set() + (with appropriate arguments): + +

     Point pt0(2, 3.3, 7);
+      Point pt1;
+      pt1 = pt0;
+      pt0.set(34, 99, 107.5);
+      pt0.show("pt0:");
+      -| pt0: (34, 99, 107.5)
+      pt1.show("pt1:");
+      -| pt1: (2, 3.3, 7)
+ 
+

In this example, pt0 is initialized with the coordinates (2, 3.3, 7), + and pt1 with the coordinates (0, 0, 0). + pt1 = pt0 causes pt1 to have the same coordinates as + pt0, then the coordinates of pt0 are changed to (34, + 99, 107.5). This doesn't affect pt1, whose coordinates remain + (2, 3.3, 7). + +

Another way of declaring and initializing Points is by using the + copy constructor: + +

     Point pt0(1, 3.5, 19);
+      Point pt1(pt0);
+      Point pt2 = pt0;
+      Point pt3;
+      pt3 = pt0;
+ 
+

In this example, pt1 and pt2 are both declared and + initialized using the copy constructor; Point pt2 = pt0 does not + invoke the assignment operator. pt3, on the other hand, is + declared using the default constructor, and not initialized. In the + following line, pt3 = pt0 does invoke the assignment operator, + thus resetting the coordinate values of pt3 to those of + pt0. + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shadows.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shadows.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shadows.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shadows.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,94 ---- + + + Shadows - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Curves and Surfaces, + Up: Future Plans +


+
+ +

40.3 Shadows, Reflections, and Rendering

+ +

Shadows and reflections are closely related to transformations and + projections. + A shadow is the projection of the outline of an object onto a surface or + surfaces, and reflection in a plane is an affine transformation. + +

3D rendering software generally implements shadows, or more generally, + shading, reflections, and certain other effects using methods + involving the calculation of individual pixel values. + Surface hiding is also often implemented at the pixel level. + 3DLDF does no scan converting ((see Accuracy), and hence + no calculation of pixel values at all, so these methods cannot be + used in 3DLDF at present. + +

However, it is possible to define functions for generating + shadows and reflections within 3DLDF by other means. + +

I have defined the function Point::reflect() for reflecting a + Point in a Plane, and have begun definining versions for + other classes. + +

However, in order for reflections to work, I must define functions for + breaking up objects into smaller units. This is also necessary for + surface hiding to work properly. + +

For MetaPost output, I will have to implement shadows, reflections, and + surface hiding in this way. However, 3DLDF could be made to produce + output in other formats. There are two possibilities: implementing + rendering functionality within 3DLDF, or interfacing to + existing rendering software. If I decide to do the latter, there are + again two possibilities: having 3DLDF write output in a format that a + renderer can input, or linking to a library supplied by a rendering + package. + +

I haven't yet decided which course to pursue. However, in the long run, + I'd like it to be possible to use 3DLDF for fancier graphics than is + currently possible using MetaPost and PostScript alone. + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shape-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shape-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shape-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shape-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,73 ---- + + + Shape Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Shape Reference, + Up: Shape Reference +


+
+ +

18.1 Data Members

+ +
+ — Protected static constants: signed short DRAWDOT
+ — : signed short DRAW
+ — : signed short FILL
+ — : signed short FILLDRAW
+ — : signed short UNDRAWDOT
+ — : signed short UNDRAW
+ — : signed short UNFILL
+ — : signed short UNFILLDRAW
+

Values used in the output() functions of the classes derived from + Shape. For example, in Path, if the data member + fill_draw_value = DRAW, then the MetaPost command + draw is written to out_stream when that Path is + output. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shape-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shape-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shape-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shape-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,61 ---- + + + Shape Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Shape Data Members, + Up: Shape Reference +


+
+ +

18.2 Operators

+ +
+ — Pure virtual function: Transform operator*= (const Transform& t)
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shape-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shape-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shape-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shape-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,85 ---- + + + Shape Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Input and Output, + Up: Top +


+
+ +

18 Shape Reference

+ +

Class Shape is defined in shapes.web. + +

Shape is an abstract class, which means that + all of its member functions are pure virtual functions, and + that it's only used as a base class, i.e., no objects of type + Shape may be declared. + +

All of the “drawable” types in 3DLDF, Point, + Path, Ellipse, etc., are derived from Shape. + +

Deriving all of the drawable types from Shape makes it possible + to handle objects of different types in the same way. This is + especially important in the Picture functions, where objects of + various types (but all derived from Shape) are accessed through + pointers to Shape. See Picture Reference. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shearing-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shearing-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shearing-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shearing-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,108 ---- + + + Shearing Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Scaling Points, + Up: Transforming Points +


+
+ +

3.3 Shearing

+ +

Shearing is more complicated than shifting or scaling. The function + shear() takes six real arguments. + If p is a Point, then p.shear(a, b, c, d, e, f) sets + x_p to x_p + ay_p + bz_p, y_p to + y_p + cx_p + dz_p, and + z_p to z_p + ex_p + fy_p. + In this way, each coordinate of a Point is modified based on the + values of the other two coordinates, whereby the influence of the + other coordinates on the new value is weighted according to the + arguments. + +

     Point p(1, 1, 1);
+      p.shear(1);
+      p.show("p:");
+      -| p: (2, 1, 1)
+      p.set(1, 1, 1);
+      p.shear(1, 1);
+      p.show("p:");
+      -| p: (3, 1, 1)
+      p.set(1, 1, 1);
+      p.shear(1, 1, 2, 2, 3, 3);
+      p.show("p:");
+      -| p: (3, 5, 7)
+ 
+ + +

[next figure] + demonstrates the effect of shearing the points of a rectangle + in the x-y plane. + +

     Point P0;
+      Point P1(3);
+      Point P2(3, 3);
+      Point P3(0, 3);
+      Rectangle r(p0, p1, p2, p3);
+      r.draw();
+      Rectangle q(r);
+      q.shear(1.5);
+      q.draw(black, "evenly");
+ 
+

+
+ [Figure 1. Not displayed.] +
+
+ Fig. 1. +
+

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shifting-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shifting-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Shifting-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Shifting-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,105 ---- + + + Shifting Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transforming Points, + Up: Transforming Points +


+
+ +

3.1 Shifting

+ +

The function + shift() + adds its arguments to the corresponding + world_coordinates of a Point. In the following example, + the function show() is used to print the world_coordinates + of p0 to standard output. + +

     Point p0(0, 0, 0);
+      p0.shift(1, 2, 3);
+      p0.show("p0:");
+      -| p0: (1, 2, 3)
+      p0.shift(10);
+      p0.show("p0:");
+      -| p0: (11, 2, 3)
+      p0.shift(0, 20);
+      p0.show("p0:");
+      -| p0: (11, 22, 3)
+      p0.shift(0, 0, 30);
+      p0.show("p0:");
+      -| p0: (11, 22, 33)
+ 
+

shift takes three real arguments, whereby the second and + third are optional. To shift a Point in the direction of + the positive or negative y-axis, and/or the positive or negative z-axis + only, then a 0 argument for the + x direction, and possibly one for the y direction + must be used as placeholders, as in the example above. + +

shift() can be invoked with a Point argument + instead of real arguments. In this case, the x, y, and + z-coordinates of the argument are used for shifting the Point: + +

     Point a(10, 10, 10);
+      Point b(1, 2, 3);
+      a.shift(b);
+      a.show("a:")
+      -| a: (11, 12, 13)
+ 
+

Another way of shifting Points is to use the binary += + operator (Point::operator+=()) with a Point + argument. + +

     Point a0(1, 1, 1);
+      Point a1(2, 2, 2);
+      a0 += a1;
+      a0.show("a0:");
+      -| a0: (3, 3, 3)
+ 
+ + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Colors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Colors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Colors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Colors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Showing Colors - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Modifying Colors, + Up: Color Reference +


+
+ +

16.5 Showing

+ +
+ — const function: void show ([string text = ""])
+

Prints information about the Color to standard output. + If text is not the empty string, prints text on a + line of its own. Otherwise, it prints “Color:”. Then it prints + name, use_name, red_part, green_part, and + blue_part. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Focuses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Focuses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Focuses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Focuses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Showing Focuses - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Querying Focuses, + Up: Focus Reference +


+
+ +

23.7 Showing

+ +
+ — const function: void show ([const string text_str = "Focus:", [const bool show_transforms = false]])
+

Prints text_str to standard output (stdout), then calls + Point::show() on position, direction, and + up. Then the values of distance, axis, and + angle are printed to stdout. If show_transforms is + true, transform and persp are shown as well. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Paths.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Paths.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Paths.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Paths.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,151 ---- + + + Showing Paths - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Labelling Paths, + Up: Path Reference +


+
+ +

26.14 Showing

+ +
+ — const function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [const real factor = 1]]]]]]])
+

Prints information about the Path to standard output + (stdout). text is simply printed out, unless it's the + empty string, in which case "Path:" is printed out. + coords indicates which set of coordinates should be shown. Valid values are + 'w' for the world_coordinates, 'p' for the + projective_coordinates, 'u' for the + user_coordinates, and 'v' for the view_coordinates, + whereby the latter two are currently not in use + (see Point Reference; Data Members). + If do_apply is true, apply_transform() is called + on each Point, updating its world_coordinates and + resetting its transform. Otherwise, + it's not. + The arguments do_persp, f, proj, and factor are only + relevant when showing projective_coordinates. If do_persp + is true, the Points are projected using the values of + f, proj, and factor + (see Path Reference; Outputting). + Otherwise, the values currently + stored in projective_coordinates are shown. + The Points and connectors are printed out alternately to standard + output, followed by the word “cycle”, if cycle_switch = true.1 + +

          default_focus.set(0, 3, -10, 0, 3, 10, 10);
+           Reg_Polygon r(origin, 5, 3, 45);
+           r.fill(gray);
+           Point p[10];
+           for (int i = 0; i < 5; ++i)
+               p[i] = r.get_point(i);
+           p[5] = Point::intersection_point(p[4], p[0], p[2], p[1]).pt;
+           p[6] = Point::intersection_point(p[0], p[1], p[2], p[3]).pt;
+           p[7] = Point::intersection_point(p[1], p[2], p[4], p[3]).pt;
+           p[8] = Point::intersection_point(p[2], p[3], p[0], p[4]).pt;
+           p[9] = Point::intersection_point(p[3], p[4], p[0], p[1]).pt;
+           Path q("--", true, &p[0], &p[5], &p[1], &p[6], &p[2], &p[7],
+                  &p[3], &p[8], &p[4], &p[9], 0);
+           q.draw();
+           q.show("q:");
+           -| q:
+           fill_draw_value == 0
+           (0, 1.06066, 1.06066)
+           -- (-2.30826, 2.24651, 2.24651)
+           -- (-1.42658, 0.327762, 0.327762)
+           -- (-3.73485, -0.858092, -0.858092)
+           -- (-0.881678, -0.858092, -0.858092)
+           -- (4.92996e-07, -2.77684, -2.77684)
+           -- (0.881678, -0.858092, -0.858092)
+           -- (3.73485, -0.858092, -0.858092)
+           -- (1.42658, 0.327762, 0.327762)
+           -- (2.30826, 2.24651, 2.24651) -- cycle;
+           q.show("q:", 'p');
+           -| q:
+           fill_draw_value == 0
+           Projective coordinates.
+           (0, -1.75337, 0.0958948)
+           -- (-1.88483, -0.615265, 0.183441)
+           -- (-1.38131, -2.58743, 0.031736)
+           -- (-4.08541, -4.22023, -0.0938636)
+           -- (-0.964435, -4.22023, -0.0938636)
+           -- (0, -7.99767, -0.384436)
+           -- (0.964436, -4.22023, -0.0938636)
+           -- (4.08541, -4.22023, -0.0938636)
+           -- (1.38131, -2.58743, 0.031736)
+           -- (1.88483, -0.615266, 0.183441) -- cycle;
+ 
+

+
+ [Figure 135. Not displayed.] +
+
+ Fig. 135. +
+

+ +
+ +
+ — Function: void show_colors ([bool = false])
+

Shows the values of draw_color and fill_color. These will + normally be 0, unless the Path is on a Picture. +

+ +
+
+

Footnotes

[1] The following example shows only one Point per + line. In actual use, two Points are shown, but this causes + overfull boxes in Texinfo.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Pictures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Pictures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Pictures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Pictures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,88 ---- + + + Showing Pictures - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Modifying Pictures, + Up: Picture Reference +


+
+ +

21.7 Showing

+ +
+ — Function: void show ([string text = "", [bool stop = false]])
+

Prints information about the Picture to standard output. + +

show() first prints the string "Showing Picture:" to + standard output, followed by text, if the latter is not the empty + string ("")1. + Then it calls transform.show(), prints the size of shapes and + labels, and the value of do_labels. Then it calls + show() on each of the Shapes on shapes. Since + show() is a virtual function in class Shape, the + appropriate show() is called for each Shape, i.e., + Point::show() for a Point, Path::show() for a + Path, etc. If stop is true, execution stops and the + user is requested to type <RETURN> to continue. Finally, the string + "Done showing picture." is printed to standard output. +

+ +
+ — Function: void show_transform ([string text = "Transform from Picture:"])
+

Calls transform.show(), passing text as the argument to the + latter function. +

+ +
+
+

Footnotes

[1] Actually, it's printed to standard output + even if it is the empty string, you just don't see it.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,91 ---- + + + Showing Points - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Labelling Points, + Up: Point Reference +


+
+ +

22.20 Showing

+ +
+ — const function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::persp, [const real factor = 1]]]]]]])
+

Prints text followed by the values of a set of coordinates to + standard output (stdout). The other arguments are similar to + those used in the functions described in Returning Coordinates. + +

          Point P(1, 3, 5);
+           P.rotate(15, 67, 98);
+           P.show("P:");
+           -| P: (-3.68621, -3.89112, 2.50421)
+ 
+
+ +
+ — Function: void show_transform ([string text = ""])
+

Prints text to standard output (stdout), + or "transform:", if text is the empty string (the + default), and then + calls transform.show(). + +

          Point A(-1, 1, 1);
+           Point B(13, 12, 6);
+           Point Q(31, 17.31, 6);
+           Q.rotate(A, B, 32);
+           Q.show_transform("Q.transform:");
+           -| Q.transform:
+              Transform:
+                0.935   0.212  -0.284       0
+              -0.0749   0.902   0.426       0
+                0.346  -0.377   0.859       0
+               -0.336   0.687  -0.569       1
+ 
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Shapes.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Shapes.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Shapes.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Shapes.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,65 ---- + + + Showing Shapes - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Querying Shapes, + Up: Shape Reference +


+
+ +

18.9 Showing

+ +
+ — const pure virtual function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = 0, [const real factor = 1]]]]]]])
+

Prints information about an object to standard output. + See the descriptions of show() for the classes derived from + Shape for more information. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Solids.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Solids.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Solids.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Solids.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Showing Solids - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

34.9 Showing

+ +
+ — const virtual function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [const real factor = 1]]]]]]])
+

Prints text and the value of on_free_store to the standard + output (stdout), and then calls + show() on the objects pointed to by the pointers on + paths, circles, ellipses, reg_polygons, and + rectangles, unless the vectors are empty. The arguments are + passed to Path::show(), Ellipse::show(), etc. If a vector + is empty, a message to this effect is printed to the standard output. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing-Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing-Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,84 ---- + + + Showing Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

19.9 Showing

+ +
+ — const function: void show ([string text = ""])
+

If the optional argument text is used, and is not the empty + string (""), text is printed on a line of its own to + the standard output first. Otherwise, "Transform:" is printed + on a line of its own to the standard output. + Then, the elements of matrix are printed to standard output. + +

          Transform t;
+           t.show("t:");
+           -| t:
+                 1       0       0       0
+                 0       1       0       0
+                 0       0       1       0
+                 0       0       0       1
+           t.scale(1, 2, 3);
+           t.shift(1, 1, 1);
+           t.rotate(90, 90, 90);
+           t.show("t:");
+           -| t:
+                 0       0       1       0
+                 0       2       0       0
+                -3       0       0       0
+                -1       1       1       1
+ 
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Showing.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Showing.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,87 ---- + + + Showing - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Get Path, + Up: Line Reference +


+
+ +

24.6 Showing

+ +
+ — Function: void show ([string text = ""])
+

If text is not the empty string (the default), it is + printed on a line of its own to standard output. Otherwise, ‘Line:’ + is printed. Following this, Point::show() is called on + position and direction. + +

          Point p(1, -2, 3);
+           Point d(-12.3, 21, 36.002);
+           Line L0(p, d);
+           L0.show("L0:");
+           -| L0:
+              position: (1, -2, 3)
+              direction: (-12.3, 21, 36.002)
+           Line L1 = p.get_line(d);
+           L1.show("L1:");
+           -| L1:
+              position: (1, -2, 3)
+              direction: (-13.3, 23, 33.002)
+           Path q = L1.get_path();
+           q.show("q:");
+           -| q:
+              fill_draw_value == 0
+              (1, -2, 3) -- (-12.3, 21, 36.002);
+ 
+
+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,82 ---- + + + Solid Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Solid Data Members, + Up: Solid Reference +


+
+ +

34.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Solid (void)
+

Creates an empty Solid. +

+ +
+ — Copy constructor: void Solid (const Solid& s)
+

Creates a new Solid and makes it a copy of s. +

+ +
+ — Template specializations: Solid* create_new<Solid> (const Solid* s)
+ — : Solid* create_new<Solid> (const Solid& s)
+

Pseudo-constructors for dynamic allocation of Solids. + They create a Solid on the free store and allocate memory for it using + new(Solid). They return a pointer to the new Solid. + +

If s is a non-zero pointer or a reference, + the new Solid will be a copy of + s. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Solid>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,114 ---- + + + Solid Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

34.1 Data Members

+ +
+ — Protected variable: bool on_free_store
+

true, if the Solid was dynamically allocated on the free + store, otherwise false. Solids should only be allocated + on the free store by create_new<Solid>(), or analogous functions + for derived classes. + See Solid Reference; Constructors and Setting Functions. +

+ +
+ — Protected variable: Point center
+

The center of the Solid. An object of a type derived from + Solid need not have a meaningful center. However, many + do, so it's convenient to be able to access it using the member + functions of Solid. +

+ +
+ — Protected variable: bool do_output
+

Set to false in Picture::output(), if the Solid + cannot be projected using the arguments of that particular invocation of + output(). Reset to true at the end of + Picture::output(), so that the Solid will be tested for + projectability again, if output() is called on the + Picture again. +

+ +
+ — Protected variables: vector<Path*> paths
+ — : vector<Circle*> circles
+ — : vector<Ellipse*> ellipses
+ — : vector <Reg_Polygon*> reg_polygons
+ — : vector<Rectangle*> rectangles
+

Vectors of pointers to the Paths, Circles, + Ellipses, Reg_Polygons, and Rectangles, + respectively, belonging to the Solid, if any exist. +

+ +
+ — Protected variable: valarray<real> projective_extremes
+

The maximum and minimum values for the x, y, and z-coordinates of the + Points belonging to the Solid. Used in + Picture::output() for testing whether a Solid is + projectable using a particular set of arguments. +

+ +
+ — Public static const variables: unsigned short CIRCLE
+ — : unsigned short ELLIPSE
+ — : unsigned short PATH
+ — : unsigned short RECTANGLE
+ — : unsigned short REG_POLYGON
+

Used as arguments in the functions get_shape_ptr() and + get_shape_center() + (see Returning Elements and Information). +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Destructor.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Destructor.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Destructor.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Destructor.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,64 ---- + + + Solid Destructor - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

34.3 Destructor

+ +
+ — virtual Destructor: void ~Solid (void)
+

This function currently has an empty definition, but its existence + prevents GCC 3.3 from issuing the following warning: + “`class Solid' has virtual functions but non-virtual destructor”. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Figures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Figures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Figures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Figures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,61 ---- + + + Solid Figures - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Plane Figures, + Up: Top +


+
+ +

8 Solid Figures

+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,69 ---- + + + Solid Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Solid Destructor, + Up: Solid Reference +


+
+ +

34.4 Operators

+ +
+ — Virtual function: const Solid& operator= (const Solid& s)
+

Assignment operator. Makes *this a copy of s, discarding + the old contents of *this. +

+ +
+ — Virtual function: Transform operator*= (const Transform& t)
+

Multiplication by a Transform. All of the Shapes that + make up the Solid are transformed by t. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,79 ---- + + + Solid Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Pattern Reference, + Up: Top +


+
+ +

34 Solid Reference

+ +

Class Solid is defined in solids.web. + It's derived from Shape using public derivation. It is intended + to be used as a base class for + more specialized classes representing solid figures, e.g., cuboids, + polyhedra, solids of rotation, etc. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid_005fFaced-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid_005fFaced-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solid_005fFaced-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solid_005fFaced-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,76 ---- + + + Solid_Faced Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ + +

+ Previous: Faced Solid Reference, + Up: Faced Solid Reference +


+
+ +

35.1 Data Members

+ +
+ — Protected variable: unsigned short faces
+

The number of faces of the Solid_Faced. +

+ +
+ — Protected variable: unsigned short vertices
+

The number of vertices of the Solid_Faced. +

+ +
+ — Protected variable: unsigned short edges
+

The number of edges of the Solid_Faced. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solving-Ellipses.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solving-Ellipses.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Solving-Ellipses.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Solving-Ellipses.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,112 ---- + + + Solving Ellipses - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Ellipse Intersections, + Up: Ellipse Reference +


+
+ +

31.10 Solving

+ +
+ — const function: real_pair solve (char axis_unknown, real known)
+

Returns two possible values for either the horizontal or vertical + coordinate. This function assumes that the Ellipse lies in a major + plane with center at the origin. Code that calls it must ensure + that these conditions are fulfilled. + + +

solve() is called in + Reg_Cl_Plane_Curve::intersection_points(Point, Point, Point) and + Reg_Cl_Plane_Curve::location(), and + resolves to this function, when these functions are called on an + Ellipse. However, Ellipse::location() overloads + Reg_Cl_Plane_Curve::location(), so the latter won't normally be + called on an Ellipse. + See Regular Closed Plane Curve Reference; Intersections, and + Regular Closed Plane Curve Reference; Querying. + +

+ +
+ — const function: real_triple get_coefficients (real Slope, real v_intercept)
+
+

Let x and y stand for the x and y-coordinates of a point on an + ellipse in the x-y plane, a for half of the horizontal axis + (axis_h / 2), + and b for half of the vertical axis + (axis_v / 2). + +

Further, let y = mx + i be the equation of a line in + the x-y plane, where m is the slope and i the + y-intercept. + +

This function returns the coefficients of the quadratic equation + that results from replacing y with mx + i + in the equation for the ellipse + +

          x^2/a^2 + y^2/b^2 = 1
+
+

namely +

          x^2/a^2 + (mx + i)^2/b^2 - 1 = 0
+           == (b^2x + a^2m^2)x^2 + 2a^2imx + (a^2i^2 - a^2b^2) = 0.
+ 
+

The coefficients are returned in the real_triple in the order + one would expect: r.first is the coefficient of x^2, r.second of + x and r.third of the constant term + (x^0 == 1). + +

get_coefficients() is called in + Reg_Cl_Plane_Curve::intersection_points(Point, Point, Point), and + resolves to this function, when the latter is called on an + Ellipse. + See Regular Closed Plane Curve Reference; Intersections. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Sources-of-Information.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Sources-of-Information.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Sources-of-Information.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Sources-of-Information.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,117 ---- + + + Sources of Information - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Introduction, + Up: Introduction +


+
+ +

1.1 Sources of Information

+ +

This handbook, and the use of 3DLDF itself, presuppose at least some + familiarity on the part of the reader with Metafont, MetaPost, + CWEB, and C++ + . If you are not familiar with any or all of them, I + recommend the following sources of information: + +

+ 
+ 
+ + Knuth, Donald Ervin. + The METAFONTbook. + Computers and Typesetting; C. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. +
+ 
+ 
+ +

Hobby, John D. + A User's Manual for MetaPost. + AT & T Bell Laboratories. + Murray Hill, NJ. No date. +

+ 
+ 
+ +

Knuth, Donald E. and Silvio Levy. + The CWEB System of Structured Documentation. + Version 3.64—February 2002. +

+ 
+ 
+ +

Stroustrup, Bjarne. + The C++ + Programming Language. + Special Edition. + Reading, Massachusetts 2000. + Addison-Wesley. + ISBN 0-201-70073-5. +

+ 
+ 
+ +

The manuals for MetaPost and CWEB are available from the Comprehensive + TeX Archive Network (CTAN). See one of the following web sites for + more information: + +

+
Germany
http://dante.ctan.org, http://ftp.dante.de
+ http://www.dante.de. + +
United Kingdom
http://www.cam.ctan.org
+ http://ftp.tex.ac.uk. + +
USA
http://www.tug.ctan.org
+ http://www.ctan.tug.org. +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Surface-Hiding.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Surface-Hiding.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Surface-Hiding.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Surface-Hiding.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,355 ---- + + + Surface Hiding - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Focuses Getstart, + Up: Pictures +


+
+ +

9.3 Surface Hiding

+ + + + +

In [next figure] + , Circle c lies in front of Rectangle + r. + Since c is drawn and not filled, r is visible behind + c. + +

     default_focus.set(1, 3, -5, 0, 3, 5, 10);
+      Point p(0, -2, 5);
+      Rectangle r(p, 3, 4, 90);
+      r.draw();
+      Point q(2, -2, 3);
+      Circle c(q, 3, 90);
+      c.draw();
+      current_picture.output();
+ 
+

+
+ [Figure 64. Not displayed.] +
+
+ Fig. 64. +
+

+ +

If instead, c is filled or filldrawn, only the parts of r that are not + covered by c should be visible: + +

     r.draw();
+      c.filldraw();
+ 
+

+
+ [Figure 65. Not displayed.] +
+
+ Fig. 65. +
+

+ +

What parts of r are covered depend on the point of view, i.e., + the position and direction of the Focus used for outputting the + Picture: + +

     default_focus.set(8, 0, -5, 5, 3, 5, 10);
+ 
+

+
+ [Figure 66. Not displayed.] +
+
+ Fig. 66. +
+

+ +

Determining what objects cover other objects in a program for 3D + graphics is called + surface hiding, + and is performed by a + hidden surface algorithm. 3DLDF currently has a very primitive + hidden surface algorithm that only works for the most simple cases. + +

The hidden surface algorithm used in 3DLDF is a + painter's algorithm, which means that the objects that are + furthest away from the Focus are drawn first, followed by the + objects that are closer, which may thereby cover them. In order to make + this possible, the Shapes on a Picture must be sorted + before they are output. They are sorted according to the z-values in + the projective_coordinates of the Points belonging to the + Shape. This may seem strange, since the + projection is two-dimensional and only the x and y-values from + projective_coordinates are written to out_stream. + However, the perspective transformation also produces a z-coordinate, + which indicates the distance of the Points from the Focus + in the z-dimension. + +

The problem is, that all Shapes, except Points themselves, + consist of multiple Points, that may have different + z-coordinates. 3DLDF currently does not yet have a satisfactory way of + dealing with this situtation. In order to try to cope with it, the user + can specify four different ways of sorting the Shapes: They + can be sorted according to the maximum z-coordinate, the + minimum z-coordinate, the mean of the maximum and minimum z-coordinate + (max + min) / 2, + and not sorted. + In the last case, the Shapes are output in the order of the + drawing and filling commands in the user code. + The z-coordinates referred to are those in + projective_coordinates, and will have been calculated for a + particular Focus. + +

The function Picture::output() takes a + const unsigned short sort_value argument that specifies + which style of sorting + should be used. The namespace Sorting contains the following + constants which should be used for sort_value: MAX_Z, + MIN_Z, MEAN_Z, and NO_SORT. The default is + MAX_Z. + +

3DLDF's primitive hidden surface algorithm cannot work for + objects that intersect. The following examples demonstrate why not: + +

     using namespace Sorting;
+      using namespace Colors;
+      using namespace Projections;
+      default_focus.set(5, 3, -10, 3, 1, 1, 10, 180);
+      Rectangle r0(origin, 3, 4, 45);
+      Rectangle r1(origin, 2, 6, -45);
+      r0.draw();
+      r1.draw();
+      current_picture.output(default_focus, PERSP, 1, MAX_Z);
+      r0.show("r0:");
+      -| r0:
+      fill_draw_value == 0
+      (-1.5, -1.41421, -1.41421) -- (1.5, -1.41421, -1.41421) --
+      (1.5, 1.41421, 1.41421) -- (-1.5, 1.41421, 1.41421)
+      -- cycle;
+      
+      r0.show("r0:", 'p');
+      -| r0:
+      fill_draw_value == 0
+      Perspective coordinates.
+      (-5.05646, -4.59333, -0.040577) -- (-2.10249, -4.86501, -0.102123) --
+      (-1.18226, -1.33752, 0.156559) -- (-3.51276, -1.2796, 0.193084)
+      -- cycle;
+      
+      r1.show("r1:");
+      -| r1:
+      fill_draw_value == 0
+      (-1, 2.12132, -2.12132) -- (1, 2.12132, -2.12132) --
+      (1, -2.12132, 2.12132) -- (-1, -2.12132, 2.12132)
+      -- cycle;
+      
+      r1.show("r1:", 'p');
+      -| r1:
+      fill_draw_value == 0
+      Perspective coordinates.
+      (-5.09222, -0.995681, -0.133156) -- (-2.98342, -1.03775, -0.181037) --
+      (-1.39791, -4.05125, 0.208945) -- (-2.87319, -3.93975, 0.230717)
+      -- cycle;
+ 
+

+
+ [Figure 67. Not displayed.] +
+
+ Fig. 67. +
+

+ +

In [the previous figure] + , the Rectangles r_0 and r_1 intersect along the + x-axis. The z-values of the world_coordinates of r_0 are + -1.41421 and 1.41421 (two Points each), while those of r_1 + are 2.12132 and -2.12132. So r_1 has two Points with + z-coordinates greater than the z-coordinate of any Point + on r_0, and two Points with z-coordinates less than the + z-coordinate of any Point on r_0. The + Points on r_0 and r_1 all have different z-values in + their projective_coordinates, but r_1 still has a Point + with a z-coordinate greater than that of any of the Points on + r_0, and one with a z-coordinate less than that of any of the + Points on r_0. + +

In [next figure] + , the Shapes on current_picture are sorted + according to the maximum z-values of the projective_coordinates + of the Points belonging to the Shapes. r_1 is + filled and drawn first, + because it has the Point with the positive z-coordinate of + greatest magnitude. + When subsequently r_0 is drawn, it covers part of the top of + r_1, which lies in front of r_0, and should be visible: + +

     current_picture.output(default_focus, PERSP, 1, MAX_Z);
+ 
+

+
+ [Figure 68. Not displayed.] +
+
+ Fig. 68. +
+

+ +

In [next figure] + , the Shapes on current_picture are sorted + according to the minimum z-values of the projective_coordinates + of the Points belonging to the Shapes. r1 is drawn + and filled last, because + it has the Point with the negative z-coordinate of greatest + magnitude. + It thereby covers the bottom part of + r0, which lies in front of r1, and should be visible. + +

     current_picture.output(default_focus, PERSP, 1, MIN_Z);
+ 
+

+
+ [Figure 69. Not displayed.] +
+
+ Fig. 69. +
+

+ +

Neither sorting by the mean z-value in the + projective_coordinates, nor suppressing sorting does any good. + In each case, one Rectangle is always drawn and filled last, + covering parts of the other that lie in front of the first. + +

3DLDF's hidden surface algorithm will fail wherever objects intersect, + not just where one extends past the other in both the positive and + negative z-directions. + +

     Rectangle r(origin, 3, 4, 45);
+      Circle c(origin, 2, -45);
+      r.filldraw();
+      c.filldraw(black, gray);
+      current_picture.output(default_focus, PERSP, 1, NO_SORT);
+ 
+

+
+ [Figure 70. Not displayed.] +
+
+ Fig. 70. +
+

+ +

Even where objects don't intersect, their projections may. In order to + handle these cases properly, it is necessary to break up the + Shapes on a Picture into smaller Shapes, until + there are none that intersect or whose projections intersect. Then, any + of the three methods of sorting described above can be used to sort the + Shapes, and they can be output. + +

Before this can be done, 3DLDF must be able to find the intersections of + all of the different kinds of Shapes. If 3DLDF converted solids + to polyhedra and curves to sequences of line segments, this would reduce + to the problem of finding the intersections of lines and planes, however + it does not yet do this. + +

Even if it did, a fully functional hidden surface algorithm must compare + each Shape on a Picture with every other Shape. + Therefore, for n Shapes, there will be + n! / ((n - r)! r!) + (possibly time-consuming) comparisons. + +

+
+ [Figure 71. Not displayed.] +
+
+ Fig. 71. +
+

+ + + + +

Clearly, such a hidden surface + algorithm would considerably increase run-time. + +

Currently, all of the Shapes on a Picture are output, as + long as they lie completely within the boundaries passed as arguments to + Picture::output(). + See Pictures; Outputting. It + would be more efficient to suppress output for them, if they are + completely covered by other objects. This also requires comparisions, + and could be implemented together with a fully-functional hidden surface + algorithm. + +

Shadows, reflections, highlights and shading are all effects requiring + comparing each Shape with every other Shape, and could + greatly increase run-time. + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/System-Information.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/System-Information.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/System-Information.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/System-Information.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,90 ---- + + + System Information - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Dynamic Allocation of Shapes, + Up: Top +


+
+ +

15 System Information

+ +

The functions described in this chapter are all declared in the + namespace System. They are for finding out information + about the system on which 3DLDF is being run. They are declared and + defined in pspglb.web, except for the template function + get_second_largest(), which is declared and defined in + gsltmplt.web. + +

There are two reasons for this. The first is that template definitions + must be available + in the compilation units where specializations are instantiated. + I therefore write the template definition of get_second_largest() + to gsltmplt.h, so it can be included by the CWEB files that need + it, currently main.web only. If I + wrote it to pspglb.h, it would be included by all of the CWEB + files except for loader.web, causing unnecessarily bloated object + code. + +

The other reason is because of the way way 3DLDF is built using Automake + and make. I originally tried to define get_second_largest() + in pspglb.web and wrote the definition to gsltmplt.cc, + which is no problem with CWEB. However, I was unable to express the + dependencies among the CWEB, C++ + , and object files in such a way that + 3DLDF was built properly. + +

Therefore all template functions will be put into files either by + themselves, or in small groups. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Template-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Template-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Template-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Template-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,110 ---- + + + Template Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Installing 3DLDF, + Up: Installing 3DLDF +


+
+ +

11.1.1 Template Functions

+ +

3DLDF 1.1.5 is the first release that contains template functions, + namely + template <class C> C* create_new(), which is defined in + creatnew.web, and + template <class Real> Real get_second_largest(), which is defined + in gsltmplt.web. + See Dynamic Allocation of Shapes, and + Get Second Largest Real. + +

In order for template functions to be instantiated correctly, their + definitions must be available in each compilation unit where + specializations are declared or used. For non-template functions, it + suffices for their declarations to be available, and their + definitions are found at link-time. For this reason, the + definitions of create_new() and get_second_largest() are + in their own CWEB files, and are written to their own header files. The + latter are included in the other CWEB files that need them. + +

In addition, ‘AM_CXXFLAGS = -frepo’ has been added to the file + Makefile.am in 3DLDF-1.1.5/CWEB/, so that the C++ + +

compiler is called using the ‘-frepo’ option. + The manual Using and Porting the GNU Compiler + Collection explains this as follows: + +

+ “Compile your template-using code with ‘-frepo’. The compiler will + generate files with the extension .rpo listing all of the template + instantiations used in the corresponding object files which could be + instantiated there; the link wrapper, ‘collect2’, will then update the + .rpo files to tell the compiler where to place those instantiations and + rebuild any affected object files. The link-time overhead is negligible + after the first pass, as the compiler will continue to place the + instantiations in the same files.”1 +
+ +

The first time the executable 3dldf is built, the files that use + the template functions are recompiled one or more times, and the linker + is also called several times. This doesn't happen anymore, once the + .rpo files exist. + +

Template instantiation differs from compiler to compiler, so using + template functions will tend to make 3DLDF less portable. I am no + longer able to compile it on the DECalpha Personal Workstation I had + been using with the DEC C++ + compiler. + See Ports, for more information. + +

+
+

Footnotes

[1] Stallman, Richard M. Using and Porting the GNU Compiler + Collection, p. 285.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,112 ---- + + + Tetrahedron Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Tetrahedron Data Members, + Up: Tetrahedron +


+
+ +
37.2.1.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Tetrahedron (void)
+

Creates an empty Tetrahedron. +

+ +
+ — Constructor: void Tetrahedron (const Point& p, const real diameter_of_triangle, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Creates a Tetrahedron with its center at the origin. + The faces have enclosing circles of diameter + diameter_of_triangle. If any of angle_x, angle_y, or + angle_z is non-zero, the Tetrahedron is rotated by the + amounts specified around the corresponding axes. Finally, if p is + not the origin, the Tetrahedron is shifted such that + center comes to lie at p. + +

The center of a Tetrahedron is the intersection of the line + segments connecting the vertices with the centers of the opposite + faces. + +

          Tetrahedron t(origin, 3);
+           t.draw();
+ 
+

+
+ [Figure 187. Not displayed.] +
+
+ Fig. 187. +
+

+ +
          Point P(1, 0, 1);
+           Tetrahedron t(P, 2.75, 30, 32.5, 20);
+           t.draw();
+ 
+

+
+ [Figure 188. Not displayed.] +
+
+ Fig. 188. +
+

+ +
+ +
+ — Setting function: void set (const Point& p, const real diameter_of_triangle, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Corresponds to the constructor above. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,78 ---- + + + Tetrahedron Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +
37.2.1.1 Data Members
+ +
+ — Protected static const variable: real dihedral_angle
+

The angle in radians between the faces of the Tetrahedron, namely + 70 degrees + 32' + . + Only + the Platonic polyhedra have a single dihedral angle, so + dihedral_angle is not a member of + Polyhedron. This means that it must be a member of all of the + classes representing Platonic polyhedra. + +

+ +
+ — Protected variable: real triangle_radius
+

The radius of the circle enclosing a triangular face of the + Tetrahedron. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Getstart.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Getstart.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Getstart.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Getstart.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,78 ---- + + + Tetrahedron Getstart - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Polyhedron Getstart, + Up: Polyhedron Getstart +


+
+ +

8.2.1 Tetrahedron

+ +

The center of a tetrahedron is the intersection of the lines from a + vertex to the center of the opposite side. At least, in 3DLDF, this is + the center of a Tetrahedron. I'm not 100 degrees + certain + that this is mathematically correct. + +

     Tetrahedron t(origin, 4);
+      t.draw();
+      t.get_center().dotlabel("$c$");
+ 
+

+
+ [Figure 39. Not displayed.] +
+
+ Fig. 39. +
+

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Net.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Net.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Net.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron-Net.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,141 ---- + + + Tetrahedron Net - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +
37.2.1.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real triangle_diameter)
+

Returns the net of the Tetrahedron, i.e., the + two-dimensional pattern of triangles that can be folded into + a model of a tetrahedron.1 + The net lies in the x-z plane. The triangles + have enclosing circles of diameter triangle_diameter. The center + of the middle triangle is at the origin. + +

          vector<Reg_Polygon*> vrp = Tetrahedron::get_net(2);
+           for (vector<Reg_Polygon*>::iterator iter = vrp.begin();
+                iter != vrp.end();
+                ++iter)
+             {
+               (**iter).draw();
+             }
+ 
+

+
+ [Figure 189. Not displayed.] +
+
+ Fig. 189. +
+

+ +

This function is used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Tetrahedron; Constructors and Setting Functions. + The constructor starts with the net and rotates three of the triangles + about the adjacent vertices of the middle triangle. Currently, all of + the Polyhedron constructors work this way. + However, this is not ideal, because rotation uses the sine and cosine + functions, which cause inaccuracies to creep in. + I think there must be a better way of constructing Polyhedra, but + I haven't found one yet. + +

The Polyhedron constructors are also especially + sensitive to changes made to Transform::align_with_axis(). + I have already had to rewrite them twice, and since + Transform::align_with_axis() may need to be changed or rewritten + again, it's possible that the Polyhedron constructors will have + to be, too. It has also occurred in the past, that the Polyhedra + were constructed correctly on one platform, using a particular compiler, + but not on another platform, using a different compiler. +

+ +
+ — Static function: void draw_net (const real triangle_diameter, [bool make_tabs = true])
+

Draws the net for a Tetrahedron in the x-y plane. + The triangles + have enclosing circles of diameter triangle_diameter. The + origin is used as the center of the middle triangle. + The centers of the triangles are numbered. + If the argument make_tabs is used, tabs for gluing and/or sewing a + cardboard model of the Tetrahedron together will be drawn, too. + The dots on the tabs mark where to stick the needle through, when sewing + the model together (I've had good results with sewing). + +

          Tetrahedron::draw_net(3, true);
+ 
+

+
+ [Figure 190. Not displayed.] +
+
+ Fig. 190. +
+

+ +

The net is drawn in the x-y plane, because it currently doesn't work to + draw it in the x-z plane. I haven't gotten around to fixing this + problem yet. +

+ +
+
+

Footnotes

[1] Albrecht Dürer invented this method of constructing polyhedra. + +

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Tetrahedron.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Tetrahedron.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,66 ---- + + + Tetrahedron - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Regular Platonic Polyhedra, + Up: Regular Platonic Polyhedra +


+
+ +

37.2.1 Tetrahedron

+ +

Class Tetrahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/The-Perspective-Projection.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/The-Perspective-Projection.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/The-Perspective-Projection.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/The-Perspective-Projection.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,247 ---- + + + The Perspective Projection - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Previous: Parallel Projections, + Up: Projections +


+
+ +

9.1.2 The Perspective Projection

+ +

The perspective projection obeys the laws of + linear perspective. + In 3DLDF, it is performed by means of a + transformation, whose effect is, to the + best of my knowledge, + exactly equivalent to the result of a perspective projection done by + hand using vanishing points and rulers. + +

It is very helpful to the artist to understand the laws of linear + perspective, and to know how to make a perspective drawing by hand.1 + However, it is a very tedious and error-prone procedure (I know, I've + done it). One of my main motivations for writing 3DLDF was so I + wouldn't have to do it anymore. + + + + + + +

[next figure] + shows a perspective construction, the way it + could be done by hand. + The point of view, or focus is located 6cm from + the picture plane, and 4cm above the ground (or x-z) plane at the point + (0, 4, -6). + The rectangle R lies in the ground plane, with the point r_0 at + (2, 0, 1.5). The right side of R, with length = 2cm + lies at an angle + of 40 to the ground line, which corresponds to the intersection line + of the ground plane with the picture plane, and the left side, with + length = 5cm, at an angle of + 90 degrees - 40 degrees = 50 degrees + to the ground line. + + + +

+
+ [Figure 56. Not displayed.] +
+
+ Fig. 56. +
+

+ +

While it's possible to use 3DLDF to make a perspective construction + in the traditional way, as [the previous figure] + shows, the code for [next figure] + +

achieves the same result more efficiently: + +

     default_focus.set(0, 4, -6, 0, 4, 6, 6);
+      Rectangle r(origin, 2, 5, 0, 40);
+      Point p(2, 0, 1.5);
+      r.shift(p - r.get_point(0));
+      r.draw();
+ 
+

+
+ [Figure 57. Not displayed.] +
+
+ Fig. 57. +
+

+ +

In [the second-to-last figure] + , it was + convenient to start with the corner point r_0; + if we needed the center of R, it would have to be found from the + corner points. + However, in 3DLDF, Rectangles are most often constructed about + the center. Therefore, in [next figure] + , R is first + constructed about the origin, with the + rotation about the y-axis passed as an argument to the constructor. + It is then shifted such that *(R.points[0]), the first + (or zeroth, if you will) Point on R comes to lie at + (2, 0, 1.5). + +

Unlike the other transformations currently + used in 3DLDF, the perspective transformation is non-affine. Affine + transformations maintain parallelity of lines, while the rules of + perspective state that parallel lines, with one exception, appear to + recede toward a + + + + vanishing point.2 + +

In [the second-to-last figure] + , the lines + from r_0 to r_1 and from r_3 to r_2 + appear to vanish + toward the right-hand 40 degrees + vanishing point, while + the lines from r_0 to r_3 and from r_1 to r_2 + appear to vanish + toward the left-hand 50 degrees + vanishing point. + The lower the angle of a + vanishing point, the further away it is from the center of vision, as + [next figure] + shows: + +

+
+ [Figure 58. Not displayed.] +
+
+ Fig. 58. +
+

+ +

In [the previous figure] + , the 0.5 degrees + vanishing point is nearly + 5 and 3/4 + meters away from the CV, and a + line receding to it will be very + nearly horizontal. However, the distance from the focus to the CV is + only 5cm. As this distance increases, the distance from the + CV to a given vanishing point increases proportionately. + If the distance is 30cm, a more reasonable value + for a drawing, then the x-coordinate of VP 10 degrees + is 170.138cm, that + of VP 5 degrees + is 342.902cm, and that of VP 0.5 degrees + is 3437.66cm! + This is the reason + why perspective drawings done by hand rarely contain lines receding to + the horizon at low angles. + +

This problem doesn't arise when the perspective transformation is + used. In this case, any angle can be calculated as easily as any other: + +

     default_focus.set(0, 4, -6, 0, 4, 6, 6);
+      Rectangle r;
+      Point center(0, 2);
+      r.set(center, 2, 5, 0, 0, 0.5);
+      r.draw();
+      
+      r.set(center, 2, 5, 0, 0, 2.5);
+      r.draw();
+      
+      r.set(center, 2, 5, 0, 0, 5);
+      r.draw();
+      current_picture.output();
+ 
+

+
+ [Figure 59. Not displayed.] +
+
+ Fig. 59. +
+

+ +
+
+

Footnotes

[1] There are many books on linear perspective for artists. + I've found Gwen White's Perspective. A Guide for Artists, + Architects and Designers to be particularly good. Vredeman de Vries, + Perspective contains beautiful examples of perspective + constructions.

+ +

[2] (I believe the following to be correct, but I'm not entirely sure.) + Let vector v be the line of sight. By definition, the plane of + projection will be a plane p, such that vector v is normal to + p. Let q_0 and q_1 be planes such that + q_0 == q_1 or q_0 || q_1, and q_0 is + perpendicular to p. + It follows that q_1 is perpendicular to p. + Let l_0 and l_1 be lines, such that l_0 != l_1, + l_0 || l_1, l_0 lies within q_0, l_1 lies + within q_1, + l_0 is perpendicular to vector v, and l_1 is perpendicular + to vector v. + Under these circumstances, the projections of l_0 and l_1 + in p will also be parallel. +

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Constructors.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Constructors.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Constructors.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Constructors.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,78 ---- + + + Transform Constructors - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

19.3 Constructors

+ +
+ — Default constructor: void Transform (void)
+

Creates a Transform containing the identity matrix. +

+ +
+ — Constructor: void Transform (real r)
+

Creates a Transform and sets all of the elements of matrix + to r. Currently, this + constructor is never used, but who knows? Maybe someday it will be + useful for something. +

+ +
+ — Constructor: void Transform (real r0_0, real r0_1, real r2, real r0_2, real r0_3, real r1_0, real r1_1, real r1_2, real r1_3, real r2_0, real r2_1, real r2_2, real r2_3, real r3_0, real r3_1, real r3_2, real r3_3)
+

Each of the sixteen real arguments is + assigned to the corresponding element of matrix: + matrix[0][0] = r0_0, matrix[0][1] = r0_1, etc. + Useful for specifying a transformation matrix completely. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,64 ---- + + + Transform Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +

19.1 Data Members

+ +
+ — Private variable: Matrix matrix
+

A 4 X 4 + +

matrix of real representing the actual transformation matrix. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Global-Variables-and-Constants.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Global-Variables-and-Constants.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Global-Variables-and-Constants.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Global-Variables-and-Constants.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,84 ---- + + + Transform Global Variables and Constants - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transform Data Members, + Up: Transform Reference +


+
+ +

19.2 Global Variables and Constants

+ +
+ — Variable: Transform user_transform
+

Currently has no function. It is intended to be used for transforming + the coordinates of Points between the world coordinate system + (WCS) and a user coordinate system (UCS), when routines for managing + user coordinate systems are implemented. +

+ +
+ — Constant: const Transform INVALID_TRANSFORM
+

Every member of matrix in INVALID_TRANSFORM is + equal to INVALID_REAL. +

+ +
+ — Constant: const Transform IDENTITY_TRANSFORM
+

Homogeneous coordinates and Transforms are unchanged by + multiplication with IDENTITY_TRANSFORM. + matrix is an identity matrix: +

          1 0 0 0
+           0 1 0 0
+           0 0 1 0
+           0 0 0 1
+ 
+

See Transforms. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Operators.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Operators.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Operators.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Operators.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,228 ---- + + + Transform Operators - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transform Constructors, + Up: Transform Reference +


+
+ +

19.4 Operators

+ +
+ — Assignment operator: Transform operator= (const Transform& t)
+

Sets *this to t and returns t. Returning *this + would, of course, have exactly the same effect. +

+ +
+ — Operator: real operator*= (real r)
+

Multiplication with assignment by a scalar. + This operator multiplies each element + E + of matrix by + the scalar r. + The return value is r. This makes it possible to + chain invocations of this function: + For a_x, b_x, c_x, ..., p_x in R + , + x in N + +

          Transform T0(a_0, b_0, c_0, d_0,
+                        e_0, f_0, g_0, h_0,
+                        i_0, j_0, k_0 l_0,
+                        m_0, n_0, o_0, p_0);
+           Transform T1(a_1, b_1, c_1, d_1,
+                        e_1, f_1, g_1, h_1,
+                        i_1, j_1, k_1 l_1,
+                        m_1, n_1, o_1, p_1);
+           Transform T2(a_2, b_2, c_2, d_2,
+                        e_2, f_2, g_2, h_2,
+                        i_2, j_2, k_2 l_2,
+                        m_2, n_2, o_2, p_2);
+           real r = 5;
+ 
+

Let M_0, M_1, and M_2 stand for + T0.matrix, T1.matrix, and T2.matrix + respectively: + +

          M_0 =
+           a_0 b_0 c_0 d_0
+           e_0 f_0 g_0 h_0
+           i_0 j_0 k_0 l_0
+           m_0 m_0 o_0 p_0
+           
+           M_1 =
+           a_1 b_1 c_1 d_1
+           e_1 f_1 g_1 h_1
+           i_1 j_1 k_1 l_1
+           m_1 m_1 o_1 p_1
+           
+           M_2 =
+           a_2 b_2 c_2 d_2
+           e_2 f_2 g_2 h_2
+           i_2 j_2 k_2 l_2
+           m_2 m_2 o_2 p_2
+ 
+
          T0 *= T1 *= T2 *= r;
+ 
+

Now,
+

          M_0 =
+           5a_0 5b_0 5c_0 5d_0
+           5e_0 5f_0 5g_0 5h_0
+           5i_0 5j_0 5k_0 5l_0
+           5m_0 5m_0 5o_0 5p_0
+           
+           M_1 =
+           5a_1 5b_1 5c_1 5d_1
+           5e_1 5f_1 5g_1 5h_1
+           5i_1 5j_1 5k_1 5l_1
+           5m_1 5m_1 5o_1 5p_1
+           
+           M_2 =
+           5a_2 5b_2 5c_2 5d_2
+           5e_2 5f_2 5g_2 5h_2
+           5i_2 5j_2 5k_2 5l_2
+           5m_2 5m_2 5o_2 5p_2
+ 
+

This function is not currently used anywhere, but it may turn out to be + useful for something. +

+ +
+ — const operator: Transform operator* (const real r)
+

Multiplication of a Transform by a scalar without assignment. + The return value is a Transform + A. + If this.matrix has elements + E_T, then A.matrix has elements E_A such that + E_A = r * E_T + +

for all E. +

+ +
+ — Operator: Transform operator*= (const Transform& t)
+

Performs matrix multiplication on matrix and + t.matrix. The result is assigned to matrix. + t is returned, not *this! This makes it possible to + chain invocations of this function: + +

          Transform a;
+           a.shift(1, 1, 1);
+           Transform b;
+           b.rotate(0, 90);
+           Transform c;
+           c.shear(5, 4);
+           Transform d;
+           d.scale(3, 4, 5);
+ 
+

Let a_m, b_m, and c_m stand for + a.matrix, b.matrix, c.matrix, and d.matrix + respectively: +

          a_m =
+           1        0        0        0
+           0        1        0        0
+           0        0        1        0
+           1        1        1        1
+           
+           b_m =
+            0.5      0.5        0.707      0
+            0.146    0.854     -0.5        0
+           -0.854    0.146      0.5        0
+            0        0          0          1
+           
+           c_m =
+            1       12       14        0
+           10        1       15        0
+           11       13        1        0
+            0        0        0        1
+           
+           d_m =
+           3        0        0        0
+           0        4        0        0
+           0        0        5        0
+           0        0        0        1
+ 
+

a *= b *= c *= d;
+ a, b, and c are transformed by d, which + remains unchanged. + +

Now, +

          a_m =
+           3        0        0        0
+           0        4        0        0
+           0        0        5        0
+           3        4        5        1
+           
+           b_m =
+            1.5     2       3.54  0
+           -0.439   3.41   -2.5   0
+           -2.56    0.586   2.5   0
+            0       0       0     1
+           
+           c_m =
+            3       48       70        0
+           30        4       75        0
+           33       52        5        0
+            0        0        0        1
+ 
+

d_m is unchanged. + +

+ +
+ — const operator: Transform operator* (const Transform t)
+

Multiplication of a Transform by another Transform without + assignment. + The return value is a Transform whose matrix contains + values that are the result of the matrix multiplication of + matrix and t.matrix. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Reference.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Reference.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transform-Reference.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transform-Reference.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,75 ---- + + + Transform Reference - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Shape Reference, + Up: Top +


+
+ +

19 Transform Reference

+ +

Class Transform is defined in transfor.web. + Point is a friend of Transform. + +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transforming-Points.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transforming-Points.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transforming-Points.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transforming-Points.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,118 ---- + + + Transforming Points - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Points, + Up: Top +


+
+ +

3 Transforming Points

+ +

Points don't always have to remain in the same place. There are + various ways of moving or transforming them: +

    +
  • Shifting. This is often called “translating”, but the operation in Metafont + that performs translation is called shift, so I call it “shifting”. + +
  • Scaling. + +
  • Shearing. + +
  • Rotating about an axis. + +
+ +

class Point has several member functions + for applying these affine transformations1 + to a Point. + Most of the arguments to these functions are of + type real. As you may know, there is no such data type in C++ + . + I have defined real using typedef to be either + float or double, depending on the value of a preprocessor + switch for conditional compilation.2 + 3DLDF uses many real values and I wanted to be able to + change the precision used by making one change (in the file + pspglb.web) rather than having to examine all the places in the + program where float or double are used. Unfortunately, + setting real to double currently doesn't work. + +

+ +
+
+

Footnotes

[1] Affine transformations are operations + that have the property that parallelity of + lines is maintained. That is, if two lines (each determined by two + points) are parallel before the transformation, they will also be + parallel after + the transformation. Affine transformations are discussed in many books + about computer graphics and geometry. For 3DLDF, I've mostly used + Jones, Computer Graphics through Key Mathematics and Salomon, + Computer Graphics and Geometric Modeling.

+ +

[2] I try to avoid the use of + preprocessor macros as much as possible, for the reasons given by + Stroustrup in the The C++ + Programming Language, + section + 7.8, + pp. 160–163, and + Design and Evolution of C++ + , Chapter 18, pp. 423–426. + However, conditional compilation is one of + the tasks that only the preprocessor can perform.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transforms.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transforms.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Transforms.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Transforms.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,196 ---- + + + Transforms - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Transforming Points, + Up: Top +


+
+ +

4 Transforms

+ +

When Points are transformed using shift(), shear(), + or one of the other transformation functions, the + world_coordinates are not modified directly. Instead, + another data member of class Point is used to store the + information about the transformation, namely transform of + type class Transform. A Transform object has a single + data element of type Matrix and a number of member functions. A + Matrix is + simply a + 4 X 4 + array1 + of reals + defined using typedef real Matrix[4][4]. + Such a matrix suffices for performing all + of the transformations (affine and perspective) possible in + three-dimensional space.2 + Any combination of transformations can be represented by a single + transformation matrix. This means that consecutive transformations + of a Point can be “saved up” and applied to its coordinates + all at once when needed, rather than updating them for each + transformation. + +

Transforms work by performing matrix multiplication of + Matrix with the homogeneous world_coordinates of + Points. + If a set of homogeneous coordinates + \alpha = (x, y, z, w) + and +

     Matrix M =
+      a e i m
+      b f j n
+      c g k o
+      d h l p
+ 
+

then the set of homogeneous coordinates \beta resulting from + multiplying \alpha and M is calculated as follows: +

     \beta = \alpha\times M = ((xa + yb + zc + wd),  (xe + yf + zg + wh),
+      (xi + yj + zk + wl), (xm + yn + zo + wp))
+ 
+

Please note that each coordinate of \beta can be influenced by all of the + coordinates of \alpha. + +

Operations on + matrices are very important in computer graphics applications and are + described in many books about computer graphics and geometry. For + 3DLDF, I've mostly used Huw Jones' + Computer Graphics through Key Mathematics + and David Salomon's Computer Graphics and Geometric Modeling. + +

It is often useful to declare and use Transform objects in 3DLDF, + just as it is for transforms in Metafont. Transformations can be + stored in Transforms and then be used to transform Points + by means of Point::operator*=(const Transform&). + +

     1. Transform t;
+      2. t.shift(0, 1);
+      3. Point p(1, 0, 0);
+      4. p *= t;
+      5. p.show("p:");
+      -| p: (1, 1, 0)
+ 
+

When a Transform is declared (line 1), it is + initialized to an identity matrix. All identity matrices are + square, all of the elements of the main diagonal (upper left to lower + right) are 1, and all of the other elements are 0. + So a + 4 X 4 + identity matrix, as used in 3DLDF, looks like this: +

     1 0 0 0
+      0 1 0 0
+      0 0 1 0
+      0 0 0 1
+ 
+

If a matrix A is multiplied with an identity matrix I, the result is + identical to A, i.e., + A * I = A. + This is the salient property of an identity matrix. + +

The same affine transformations are applied in the same way to + Transforms as they are to Points, i.e., the functions + scale(), shift(), + shear(), and rotate() + correspond to the Point + versions of these functions, and they take the same arguments: + +

     Point p;
+      Transform t;
+      p.shift(3, 4, 5);
+      t.shift(3, 4, 5);
+      ⇒ p.transform == t
+      p.show_transform("p:");
+      -| p:
+         Transform:
+               0   0.707   0.707       0
+          -0.866   0.354  -0.354       0
+            -0.5  -0.612   0.612       0
+               0       0       0       1
+      t.show("t:");
+      -| t:
+               0   0.707   0.707       0
+          -0.866   0.354  -0.354       0
+            -0.5  -0.612   0.612       0
+               0       0       0       1
+      
+ 
+ + +
+
+

Footnotes

[1] It is unfortunate that + the terms “array”, “matrix”, and “vector” have different meanings + in C++ + and in normal mathematical usage. However, in practice, these + discrepancies turn out not to cause many problems. Stroustrup, + The C++ + Programming Language, section + 22.4, p. 662.

+ +

[2] In fact, none of the operations for + transformations require all of the elements of a + 4 X 4 + matrix. In many + 3D graphics programs, the matrix operations are modified to use smaller + transformation matrices, which reduces the storage requirements of the + program. This is a bit tricky, because the affine transformations and + the perspective transformation use different elements of the matrix. I + consider that the risk of something going wrong, possibly producing + hard-to-find bugs, outweighs any benefits from saving memory (which + is usually no longer at a premium, anyway). In addition, there may be + some interesting non-affine transformations that would be worth + implementing. Therefore, I've decided to + use full + 4 X 4 + matrices in 3DLDF.

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Constructors-and-Setting-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Constructors-and-Setting-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Constructors-and-Setting-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Constructors-and-Setting-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,76 ---- + + + Truncated Octahedron Constructors and Setting Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +
37.3.1.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Trunc_Octahedron (void)
+

Creates an empty Trunc_Octahedron. +

+ +
+ — Constructor: void Trunc_Octahedron (const Point& p, const real diameter_of_hexagon, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

This function does not yet exist! + When it does, it will create a Trunc_Octahedron with its center + at the origin, where the + hexagonal and square faces have enclosing circles of diameter + diameter_of_hexagon. If any of angle_x, angle_y, or + angle_z is non-zero, the Trunc_Octahedron will be rotated + by the amounts specified around the corresponding axes. Finally, + if p is not the origin, the Trunc_Octahedron will be + shifted such that center comes to lie at p. +

+ + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Data-Members.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Data-Members.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Data-Members.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Data-Members.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,83 ---- + + + Truncated Octahedron Data Members - 3DLDF User and Reference Manual + + + + + + + + + + + + + + + +
37.3.1.1 Data Members
+ +
+ — Protected static const variable: real angle_hex_square
+

The angle between the hexagonal and the square faces of the truncated + octahedron, namely + 125 degrees + 16' + . + +

+ +
+ — Protected static const variable: real angle_hex_hex
+

The angle between the hexagonal faces of the truncated + octahedron, namely + 109 degrees + 28' + . + +

+ +
+ — Protected variable: real hexagon_radius
+

The radius of the circle enclosing a hexagonal or square face of the + Trunc_Octahedron. +

+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Net.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Net.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Net.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron-Net.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,73 ---- + + + Truncated Octahedron Net - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +
37.3.1.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real hexagon_diameter, [bool do_half = false])
+

This function does not yet exist! + When it does, it will return the net, i.e., the two-dimensional + pattern of hexagons and squares that can be folded into + a model of a truncated octahedron. The net will lie in the x-z plane. + The hexagons and squares will + have enclosing circles of diameter hexagon_diameter. + If the argument do_half is true, only the first half of the + net will be created. This will be used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Truncated Octahedron Constructors and Setting Functions. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Truncated-Octahedron.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,68 ---- + + + Truncated Octahedron - 3DLDF User and Reference Manual + + + + + + + + + + + + + + +

37.3.1 Truncated Octahedron

+ +

Class Trunc_Octahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

Trunc_Octahedron does not yet have a functioning constructor, so + it cannot be used as yet. + +

+ + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Typedefs-and-Utility-Structures.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Typedefs-and-Utility-Structures.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Typedefs-and-Utility-Structures.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Typedefs-and-Utility-Structures.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,128 ---- + + + Typedefs and Utility Structures - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Installing and Running 3DLDF, + Up: Top +


+
+ +

12 Typedefs and Utility Structures

+ +

3DLDF defines a number of data types for various reasons, e.g., for the + sake of convenience, for use in conditional compilation, or as return + values of functions. Some of these data types can be defined using + typedef, while others are defined as structs. + +

The typedefs and utility structures described in this chapter are + found in pspglb.web. Others, that contain objects of types + defined in 3DLDF, are described in subsequent chapters. + +

+ — typedef: real
+

Synonymous either with float or double, depending on the + values of the preprocessor variables LDF_REAL_FLOAT and + LDF_REAL_DOUBLE. The meaning of real is determined by + means of conditional compilation. If real is float, 3DLDF + will require less memory than if real is double, but its + calculations will be less precise. real is “typedeffed” to + float by default. +

+ +
+ — typedef: real_pair first second
+

Synonymous with pair<real, real>. +

+ +
+ — struct: real_triple first second third
+

All three data elements of real_triple are reals. + It also has two constructors, described below. There are no other + member functions. +

+ +
+ — Constructor: void real_triple (void)
+ — Constructor: void real_triple (real a, real b, real c)
+

The constructor taking no arguments sets first, second, + and third to 0. The constructor taking three real + arguments sets first to a, second to b, and + third to c. +

+ +
+ — typedef: Matrix
+

A Matrix is a 4 X 4 + array of real, e.g., + Matrix M; == real M[4][4]. + It is used in class Transform for storing transformation + matrices. See Transforms, and See Transform Reference, for more + information. +

+ +
+ — typedef: real_short first second
+

Synonymous with pair<real, signed short>. + It is the return type of Plane::get_distance(). +

+ +
+ — typedef: bool_pair first second
+

Synonymous with pair<bool, bool>. +

+ +
+ — typedef: bool_real first second
+

Synonymous with pair<bool, real>. +

+ + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Using-3DLDF.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Using-3DLDF.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Using-3DLDF.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Using-3DLDF.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,72 ---- + + + Using 3DLDF - 3DLDF User and Reference Manual + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Contributing to 3DLDF, + Up: Top +


+
+ +

Using 3DLDF

+ +

Since 3DLDF does not yet have an input routine, user code must be + written in C++ + (in main.web, or some other file) and compiled. + Then, 3DLDF must be relinked, together with the new file of object + code resulting from the compilation. + For now, the important point is that the text of + the examples in this manual represent C++ + code. + See Installing and Running 3DLDF, for more information. + + + + + + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Utility-Functions.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Utility-Functions.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Utility-Functions.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Utility-Functions.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,96 ---- + + + Utility Functions - 3DLDF User and Reference Manual + + + + + + + + + + + + +

+ +

+ Next: , + Previous: Polyhedron Reference, + Up: Top +


+
+ +

38 Utility Functions

+ +
+ — Function: double trunc (double d)
+

Defined in pspglb.web. + For some reason, when I compile 3DLDF using GNU CC on a PC Pentium II + XEON under Linux 2.4.4 i686, the standard library function + trunc() is not available. Therefore, I've had to write one. + + This is a kludge! + Someday, I'll have to try to find a better solution to this problem. +

+ +
+ — Function: pair<real, real> solve_quadratic (real a, real b, real c)
+

Defined in pspglb.web. + This function tries to find the solutions S_0 and S_1 to the + quadratic equation + ax^2 + bx + c according to the formulae + S_0 == -b + sqrt(b^2 - 4ac) / 2a) and + S_1 == -b - sqrt( b^2 - 4ac) / 2a. + Let r stand for the return value. If S_0 cannot be found, + r.first will be INVALID_REAL, otherwise S_0. + If S_1 cannot be found, + r.second will be INVALID_REAL, otherwise S_1. + +

          (x + 4)(x + 2) = x^2 + 6x + 8 = 0
+ 
+
          real_pair r = solve_quadratic(1, 6, 8);
+           ⇒ r.first == -2
+           ⇒ r.second == -4
+ 
+
          real_pair r = solve_quadratic(1, -2, 4);
+           ⇒ r.first == INVALID_REAL
+           ⇒ r.second == INVALID_REAL
+ 
+
+ + + + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Vector-Operations.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Vector-Operations.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/Vector-Operations.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/Vector-Operations.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,277 ---- + + + Vector Operations - 3DLDF User and Reference Manual + + + + + + + + + + + + + +
+ +

+ Next: , + Previous: Projecting Points, + Up: Point Reference +


+
+ +

22.15 Vector Operations

+ +

Mathematically speaking, vectors and points are not the same. However, + they can both be represented as triples of real numbers (in a + three-dimensional Cartesian space). It is sometimes convenient to treat + points as though they were vectors, and vice versa. In particular, it + is convenient to use the same data type, namely class Point, to + represent both points and vectors in 3DLDF. + +

+ — const function: real dot_product (Point p)
+

Returns the dot or scalar product of *this and p. + +

If P and Q are Points, +

          P \dot Q = x_P * x_Q + y_P * y_Q + z_P * z_Q = |P||Q| * cos(\theta)
+ 
+

where |P| + and |Q| are the magnitudes of + P and Q, respectively, and \theta + is the angle between P and Q. + +

Since +

          \theta = arccos(P \dot Q / |P||Q|),
+ 
+

the dot product can be used for finding the angle between two vectors. + +

          Point P(1, -1, -1);
+           Point Q(3, 2, 5);
+           cout << P.angle(Q);
+           -| 112.002
+           cout << P.dot_product(Q);
+           -| -4
+           real P_Q_angle = (180.0 / PI)
+                            * acos(P.dot_product(Q)
+                            / (P.magnitude() * Q.magnitude()));
+           cout << P_Q_angle;
+           -| 112.002
+ 
+

+
+ [Figure 86. Not displayed.] +
+
+ Fig. 86. +
+

+ +

If the angle \theta between two vectors P and Q is + 90 degrees + , then + \cos(\theta) is 0, so + P \dot Q + will also be 0. Therefore, + dot_product() can be used as a test for the orthogonality of vectors. + +

          Point P(2);
+           Point Q(P);
+           Point Q0(P0);
+           Q0 *= Q.rotate(0, 0, 90);
+           P *= Q.rotate(0, 45, 45);
+           P *= Q.rotate(45);
+           cout << P.angle(Q);
+           -| 90
+           cout << P.dot_product(Q);
+           -| 0
+ 
+

+
+ [Figure 87. Not displayed.] +
+
+ Fig. 87. +
+

+ +
+ +
+ — const function: Point cross_product (Point p)
+

Returns the cross or vector product of *this and p. + +

If P and Q are Points, + +

          P * Q = ((y_P * z_Q - z_P * y_Q), (z_P * x_Q - x_P * z_Q),
+           (x_P * y_Q - y_P * x_Q)) = |P||Q| * sin(\theta) * n,
+ 
+

where |P| and |Q| are the magnitudes of + P and Q, respectively, + \theta is the angle between P and Q, and n + is a unit vector + perpendicular to both P and Q in the direction of a + right-hand screw from P towards Q. Therefore, + cross_product() can be used to find the normals to planes. + +

          Point P(2, 2, 2);
+           Point Q(-2, 2, 2);
+           Point n = P.cross_product(Q);
+           n.show("n:");
+           -| n: (0, -8, 8)
+           real theta = (PI / 180.0) * P.angle(Q);
+           cout << theta;
+           -| 1.23096
+           real n_mag = P.magnitude() * Q.magnitude() * sin(theta);
+           cout << n_mag;
+           -| 11.3137
+           n /= n_mag;
+           cout << n.magnitude();
+           -| 1
+ 
+

+
+ [Figure 88. Not displayed.] +
+
+ Fig. 88. +
+

+ +

If + \theta = 0 degrees or 180 degrees, + \sin(\theta) will be 0, and + P * Q + will be (0, 0, 0). + The cross product thus provides a test for parallel vectors. + +

          Point P(1, 2, 1);
+           Point Q(P);
+           Point R;
+           R *= Q.shift(-3, -1, 1);
+           Point s(Q - R);
+           Point n = P.cross_product(s);
+           n.show("n:");
+           -| n: (0, 0, 0)
+ 
+

+
+ [Figure 89. Not displayed.] +
+
+ Fig. 89. +
+

+ +
+ +
+ — const function: real magnitude (void)
+

Returns the magnitude of the Point. This is its distance from + origin and is equal to + sqrt(x^2 + y^2 + z^2). + +

          Point P(13, 15.7, 22);
+           cout << P.magnitude();
+           -| 29.9915
+ 
+
+ +
+ — const function: real angle (Point p)
+

Returns the angle in degrees between two Points. + +

          Point P(3.75, -1.25, 6.25);
+           Point Q(-5, 2.5, 6.25);
+           real angle = P.angle(Q);
+           cout << angle;
+           -| 73.9084
+           Point n = origin.get_normal(P, Q);
+           n.show("n:");
+           -| n: (0.393377, 0.91788, -0.0524503)
+ 
+

+
+ [Figure 90. Not displayed.] +
+
+ Fig. 90. +
+

+ +
+ +
+ — Function: Point unit_vector (const bool assign, [const bool silent = false])
+ — const function: Point unit_vector (void)
+

These functions return a Point with the x, y, and z-coordinates + of world_coordinates divided by the magnitude of the Point. + The magnitude of the resulting Point is thus 1. The first + version assigns the result to *this and should only ever be + called with assign = true. Calling it with the + argument false is equivalent to calling the const version, + with no assignment. If unit_vector() is called with assign + and silent both false, it issues a warning message is + issued and the const version is called. If silent is + true, the message is suppressed. + +

          Point P(21, 45.677, 91);
+           Point Q = P.unit_vector();
+           Q.show("Q:");
+           -| Q: (0.201994, 0.439357, 0.875308)
+           P.rotate(30, 25, 10);
+           P.show("P:");
+           P: (-19.3213, 82.9627, 59.6009)
+           cout << P.magnitude();
+           -| 103.963
+           P.unit_vector(true);
+           P.show("P:");
+           -| P: (-0.185847, 0.797999, 0.573287)
+           cout << P.magnitude();
+           -| 1
+ 
+
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/index.html 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/index.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF/3DLDF/index.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF/3DLDF/index.html Wed Nov 13 19:06:17 2013 *************** *** 0 **** --- 1,1148 ---- + + + 3DLDF User and Reference Manual + + + + + + + + + + +

3DLDF User and Reference Manual

+ + + + +
+

Table of Contents

+ +
+ + +
+ +

+ Next: , + Previous: (dir), + Up: (dir) +


+
+ +

This is the 3DLDF User and Reference Manual, edition 1.1.5.1 for + 3DLDF 1.1.5.1.
This manual was last updated on + 16 January 2004.
+ 3DLDF is a GNU package for three-dimensional drawing with MetaPost + output. + The author is Laurence D. Finston. + +

Copyright © 2003, 2004 , 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 The Free Software Foundation + +

+ Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled + “GNU Free Documentation License”. +
+ +

Please note that the figures cannot be shown in the Info output + format. + +

+

Introduction + +

+ +

About This Manual + +

+ +

Caveats + +

+ +

Points + +

+ +

Transforms + +

+ +

Drawing and Labeling Points + +

+ +

Paths + +

+ +

Plane Figures + +

+ +

Solid Figures + +

+ +

Polyhedron + +

+ +

Pictures + +

+ +

Projections + +

+ +

Installing and Running 3DLDF + +

+ +

Installing 3DLDF + +

+ +

Running 3DLDF + +

+ +

Converting EPS Files + +

+ +

System Information + +

+ +

Color Reference + +

+ +

Input and Output + +

+ +

Shape Reference + +

+ +

Transform Reference + +

+ +

Label Reference + +

+ +

Picture Reference + +

+ +

Outputting + +

+ +

Namespaces + +

+ +

Point Reference + +

+ +

Focus Reference + +

+ +

Line Reference + +

+ +

Plane Reference + +

+ +

Path Reference + +

+ +

Polygon Reference + +

+ +

Regular Polygon Reference + +

+ +

Rectangle Reference + +

+ +

Regular Closed Plane Curve Reference + +

+ +

Ellipse Reference + +

+ +

Circle Reference + +

+ +

Pattern Reference + +

+ +

Roulettes and Involutes + +

+ +

Solid Reference + +

+ +

Returning Elements and Information + +

+ +

Faced Solid Reference + +

+ +

Cuboid Reference + +

+ +

Polyhedron Reference + +

+ +

Regular Platonic Polyhedra + +

+ +

Tetrahedron + +

+ +

Dodecahedron + +

+ +

Icosahedron + +

+ +

Semi-Regular Archimedean Polyhedra + +

+ +

Truncated Octahedron + +

+ +

Utility Functions + +

+ +

Future Plans + +

+ +

Changes + +

+ + + + + + + + + + + + + + + + + + + + Binary files 3DLDF-2.0.2/doc/old_doc/3DLDF.dvi and 3DLDF-2.0.3/doc/old_doc/3DLDF.dvi differ diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF.html 3DLDF-2.0.3/doc/old_doc/3DLDF.html *** 3DLDF-2.0.2/doc/old_doc/3DLDF.html Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF.html Wed Nov 13 19:06:23 2013 *************** *** 0 **** --- 1,20710 ---- + + + 3DLDF User and Reference Manual + + + + + + + + + + +

3DLDF User and Reference Manual

+ + + + +
+

Table of Contents

+ +
+ + +
+ +


+ Next: , + Previous: (dir), + Up: (dir) + +
+ +

This is the 3DLDF User and Reference Manual, edition 1.1.5.1 for + 3DLDF 1.1.5.1.
This manual was last updated on + 16 January 2004.
+ 3DLDF is a GNU package for three-dimensional drawing with MetaPost + output. + The author is Laurence D. Finston. + +

Copyright © 2003, 2004 , 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 The Free Software Foundation + +

+ Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled + “GNU Free Documentation License”. +
+ +

Please note that the figures cannot be shown in the Info output + format. + +

+

Introduction + +

+ +

About This Manual + +

+ +

Caveats + +

+ +

Points + +

+ +

Transforms + +

+ +

Drawing and Labeling Points + +

+ +

Paths + +

+ +

Plane Figures + +

+ +

Solid Figures + +

+ +

Polyhedron + +

+ +

Pictures + +

+ +

Projections + +

+ +

Installing and Running 3DLDF + +

+ +

Installing 3DLDF + +

+ +

Running 3DLDF + +

+ +

Converting EPS Files + +

+ +

System Information + +

+ +

Color Reference + +

+ +

Input and Output + +

+ +

Shape Reference + +

+ +

Transform Reference + +

+ +

Label Reference + +

+ +

Picture Reference + +

+ +

Outputting + +

+ +

Namespaces + +

+ +

Point Reference + +

+ +

Focus Reference + +

+ +

Line Reference + +

+ +

Plane Reference + +

+ +

Path Reference + +

+ +

Polygon Reference + +

+ +

Regular Polygon Reference + +

+ +

Rectangle Reference + +

+ +

Regular Closed Plane Curve Reference + +

+ +

Ellipse Reference + +

+ +

Circle Reference + +

+ +

Pattern Reference + +

+ +

Roulettes and Involutes + +

+ +

Solid Reference + +

+ +

Returning Elements and Information + +

+ +

Faced Solid Reference + +

+ +

Cuboid Reference + +

+ +

Polyhedron Reference + +

+ +

Regular Platonic Polyhedra + +

+ +

Tetrahedron + +

+ +

Dodecahedron + +

+ +

Icosahedron + +

+ +

Semi-Regular Archimedean Polyhedra + +

+ +

Truncated Octahedron + +

+ +

Utility Functions + +

+ +

Future Plans + +

+ +

Changes + +

+ + + + + + + + + + + + + + + + + + +
+ +


+ Next: , + Previous: Top, + Up: Top + +
+ +

1 Introduction

+ +

3DLDF is a free software package for three-dimensional drawing written by + Laurence D. Finston, who is also the author of this manual. + It is written in C++ + using CWEB and it outputs MetaPost code. + +

3DLDF is a GNU package. + It is part of the GNU Project of the + Free Software Foundation + and is published under the GNU General Public License. + See the website http://www.gnu.org for more + information. + 3DLDF is available for downloading from + http://ftp.gnu.org/gnu/3dldf. + The official 3DLDF website is + http://www.gnu.org/software/3dldf. + More information about 3DLDF can be found at the author's website: + http://wwwuser.gwdg.de/~lfinsto1. + +

Please send bug reports to: + +

     bug-3DLDF@gnu.org and
+ 
+ + + +

Two other mailing lists may be of interest to users of 3DLDF: + help-3DLDF@gnu.org is for people to ask other + users for help and info-3DLDF@gnu.org is for sending + announcements to users. To subscribe, send an email to the + appropriate mailing list or lists with the word "subscribe" as the + subject. + The author's website is http://wwwuser.gwdg.de/~lfinsto1. + +

My primary purpose in writing 3DLDF was to make it possible to use + MetaPost for three-dimensional drawing. I've always enjoyed using MetaPost, + and thought it was a shame that I could only use it for making + two-dimensional drawings. 3DLDF is a front-end that operates on + three-dimensional data, performs the necessary calculations for the + projection onto two dimensions, and writes its output in the form of + MetaPost code. + +

While 3DLDF's data types and operations are modelled on those of + Metafont and MetaPost, and while the only form of output 3DLDF currently + produces is MetaPost code, it is nonetheless not in principle tied to + MetaPost. It could be modified to produce PostScript code directly, or + output in other formats. It would also be possible to modify 3DLDF so + that it could be used for creating graphics interactively on a terminal, + by means of an appropriate interface to the computer's graphics + hardware. + +

The name “3DLDF” (“3D” plus the author's initials) was + chosen because, while not pretty, it's unlikely to conflict + with any of the other programs called “3D”-something. + +

+ +
+ +


+ Next: , + Previous: Introduction, + Up: Introduction + +
+ +

1.1 Sources of Information

+ +

This handbook, and the use of 3DLDF itself, presuppose at least some + familiarity on the part of the reader with Metafont, MetaPost, + CWEB, and C++ + . If you are not familiar with any or all of them, I + recommend the following sources of information: + +

+ 
+ 
+ + Knuth, Donald Ervin. + The METAFONTbook. + Computers and Typesetting; C. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. +
+ 
+ 
+ +

Hobby, John D. + A User's Manual for MetaPost. + AT & T Bell Laboratories. + Murray Hill, NJ. No date. +

+ 
+ 
+ +

Knuth, Donald E. and Silvio Levy. + The CWEB System of Structured Documentation. + Version 3.64—February 2002. +

+ 
+ 
+ +

Stroustrup, Bjarne. + The C++ + Programming Language. + Special Edition. + Reading, Massachusetts 2000. + Addison-Wesley. + ISBN 0-201-70073-5. +

+ 
+ 
+ +

The manuals for MetaPost and CWEB are available from the Comprehensive + TeX Archive Network (CTAN). See one of the following web sites for + more information: + +

+
Germany
http://dante.ctan.org, http://ftp.dante.de
+ http://www.dante.de. + +
United Kingdom
http://www.cam.ctan.org
+ http://ftp.tex.ac.uk. + +
USA
http://www.tug.ctan.org
+ http://www.ctan.tug.org. +
+ +
+ +


+ Next: , + Previous: Sources of Information, + Up: Introduction + +
+ +

1.2 About This Manual

+ +

This manual has been created using + Texinfo, a documentation system which is part of the GNU Project, whose + main sponsor is the Free Software Foundation. + Texinfo can be used to generate online and printed documentation from + the same input files. + +

For more information about Texinfo, see: + +

+ 
+ 
+ + Stallmann, Richard M. and Robert J. Chassell. + Texinfo. The GNU Documentation Format. + The Free Software Foundation. Boston 1999. +
+ 
+ 
+ +

For more information about the GNU Project and the Free Software + Foundation, see the following web site: http://www.gnu.org. + +

The edition of this manual is + 1.1.5.1 and it documents version 1.1.5.1 of 3DLDF. + The edition number of the manual and the version number of the program + are the same (as of 16 January 2004), + but may diverge at a later date. + +

Note that “I”, “me”, etc., in this manual refers to + Laurence D. Finston, so far the sole author of + both 3DLDF and this manual. “Currently” and similar formulations + refer to version 1.1.5.1 of 3DLDF as of + 16 January 2004. + +

This manual is intended for both beginning and advanced users of 3DLDF. + So, if there's something you don't understand, it's probably best to + skip it and come back to it later. + Some of the more difficult points, or ones that presuppose familiarity + with features not yet described, are in the footnotes. + + + + + + + + +

I firmly believe that an adequate program with good documentation is + more useful than a great program with poor or no documentation. The + ideal case, of course, is a great program with great documentation. I'm + sorry to say, that this manual is not yet as good as I'd like it to be. + I apologize for the number of typos and other errors. I hope they don't + detract too much from its usefulness. I would have liked to have + proofread and corrected it again before publication, but for reasons + external to 3DLDF, it is necessary for me to publish now. I plan to set + up an errata list on + the official 3DLDF website, + and/or + my own website. + +

Unless I've left anything out by mistake, this manual documents all of + the data types, constants and variables, namespaces, and functions + defined in 3DLDF. However, some of the descriptions are terser than I + would like, and I'd like to have more examples and illustrations. There + is also more to be said on a number of topics touched on in this + manual, and some topics I haven't touched on at all. In general, while + I've tried to give complete information on the “what and how”, the + “why and wherefore” has sometimes gotten short shrift. + I hope to correct these defects in future editions. + +

+ +
+ +


+ Next: , + Previous: About This Manual, + Up: About This Manual + +
+ +

1.2.1 Conventions

+ +

Data types are formatted like this: int, + Point, Path. Plurals are formatted in the same way: + ints, Points, Paths. It is poor + typographical practice to typeset a single word using more than one + font, e.g., ints, Points, Paths. This applies to + data types whose plurals do not end in “s” as well, e.g., + the plural of the C++ + class Polyhedron is Polyhedra. + +

When C++ + functions are discussed in this manual, I always include a + pair + of parentheses to make it clear that the item in question is a function + and not a variable, but I generally do not + include the arguments. For example, if I mention the + function + foo(), this doesn't imply that foo() takes no + arguments. If it were appropriate, I would include the argument type: + +

     foo(int)
+ 
+

or the argument type and a placeholder name: + +

     foo(int arg)
+ 
+

or I would write + +

     foo(void)
+ 
+

to indicate that foo() takes no arguments. Also, I + generally don't indicate the return type, unless it is relevant. If it + is a member function + of a class, I may indicate this, + e.g.,, bar_class::foo(), or not, + depending on whether this information is relevant. This convention + differs from that used in the Function Index, which is generated + automatically by Texinfo. There, only the name of the function appears, + without parentheses, parameters, or return values. The class type + of member functions may appear in the Function Index, (e.g., + bar_class::foo), but only in index entries that have been entered + explicitly by the author; such entries are not generated by Texinfo + automatically. + +

Examples are formatted as follows: + +

     Point p0(1, 2, 3);
+      Point p1(5, 6, 7.9);
+      Path pa(p0, p1);
+      p0.show("p0:");
+      -| p0: (1, 2, 3)
+ 
+

The beautiful mathematical typesetting produced by TeX + unfortunately does not appear in the Info and HTML versions of this + manual. In these, the following symbols are used to replace the proper + mathematical symbols. + +

+
^
Precedes a superscript. For example, read ‘a^2’ as + “a squared”. + +
_
Precedes a subscript. For example, read ‘x_1’ as + “x sub one”. + +
*
Multiplication. For example, read ‘x * y’ as + “x times y”. + +
sqrt()
The square root function. For example, read ‘sqrt(x)’ as + “the square root of x”. +
+ +

In addition, examples + can contain the following symbols: + +

+
-|
Indicates output to the terminal when 3DLDF is + run. + +
Indicates a result of some sort. It may precede a illustration + generated by the code in the example. + +
error-->
Indicates that the following text is an error message. +
+ +

This manual does not use all of the symbols provided by Texinfo. If you + find a symbol you don't understand in this manual (which shouldn't + happen), see page 103 of the Texinfo manual. + +

+

+ 
+ 
+ Symbols: +
+
N +
The set of the natural numbers + {0, 1, 2, 3, 4, ...} + +
I +
The set of the integers + {..., -3, -2, -1, 0, 1, 2, 3, 4, ...} + +
R +
The set of the real numbers. +
+ +
+ +


+ Previous: Manual Conventions, + Up: About This Manual + +
+ +

1.2.2 Illustrations

+ +

The illustrations in this manual have been created using 3DLDF. The + code that generates them is in the Texinfo files themselves, that + contain the text of the manual. Texinfo is based on TeX, so it's + possible to make use of the latter's facility for writing ASCII text to + files using TeX's \write command. + +

The file 3DLDF-1.1.5.1/CWEB/exampman.web contains the + C++ + code, and the file 3DLDF-1.1.5.1/CWEB/examples.mp + contains the MetaPost code for generating the illustrations. + 3DLDF was built using GCC 2.95 when the illustrations were generated. + For some reason, GCC 3.3 has difficulty with them. It works to generate + them in batches of about 50 with GCC 3.3. + +

MetaPost outputs Encapsulated PostScript files. These can be included + in TeX files, as explained below. However, in order to display the + illustrations in the HTML version of this manual, I had to convert them + to PNG (“Portable Network Graphics”) format. + See Converting EPS Files, for instructions on how to do this. + +

Please note that the illustrations cannot be shown in the Info output + format! + +

If you have problems including the illustrations in the printed version, + for example, if your + installation doesn't have dvips, look for the following lines + in 3DLDF.texi: + +

     \doepsftrue    %% One of these two lines should be commented-out.
+      %\doepsffalse
+ 
+

Now, remove the ‘%’ from in front of ‘\doepsffalse’ and put + one in front of ‘\doepsftrue’. This will prevent the illustrations + from being included. This should only be done as a last resort, + however, because it will make it difficult if + not impossible to understand this manual. + +

The C++ + code in an example is not always the complete code used to + create the illustration that follows it, since the latter may be + cluttered with commands that would detract from the clarity of the + example. The actual code used always follows the example in the Texinfo + source file, so the latter may be referred to, if the reader wishes + to see exactly what code was used to generate the illustration. + +

You may want to skip the following paragraphs in this section, if you're + reading this manual for the + first time. Don't worry if you don't understand it, it's meaning should + become clear after reading the manual and some experience with + using 3DLDF. + +

The file 3DLDF.texi in the directory + 3DLDF-1.1.5.1/DOC/TEXINFO, the driver file for this manual, contains + the following TeX code: + +

     \newif\ifmakeexamples
+      \makeexamplestrue     %% One of these two lines should be commented-out.
+      %\makeexamplesfalse
+ 
+

When texi2dvi is run on 3DLDF.texi, + \makeexamplestrue is not commented-out, and + \makeexamplesfalse is, + the C++ + code for the illustrations is written to the file + examples.web. + If the EPS files don't already exist (in the directory + 3DLDF-1.1.5.1/DOC/TEXINFO/EPS), + the TeX macro \PEX, + which includes them in the Texinfo files, will signal an error each time + it can't find one. Just type ‘s’ at the command line to tell + TeX to keep going. + If you want to be sure that these are indeed the only errors, you can + type ‘<RETURN>’ after each one instead. + +

texi2dvi 3DLDF.texi also generates the file + extext.tex, which contains TeX code for including the + illustrations by themselves. + +

examples.web must now be moved to 3DLDF-1.1.5.1/CWEB/ and + ctangled, examples.c must compiled, + and 3DLDF must be relinked. ctangle examples also generates + the header file example.h, which is included + in main.web. Therefore, if the contents of examples.h have + changed since the last time main.web was ctangled, + main.web will have to be ctangled, and main.c recompiled, + before 3dldf is relinked.1 + +

Running 3dldf and MetaPost now + generates the EPS (Encapsulated PostScript) files + 3DLDFmp.1 through (currently) 3DLDFmp.199 + for the illustrations. They must be moved to + 3DLDF-1.1.5.1/DOC/TEXINFO/EPS. + Now, when texi2dvi 3DLDF.texi is run again, the + dvips command + ‘\epsffile’ includes the EPS files for the illustrations in the + manual. 3DLDF.texi includes the line ‘\input epsf’, so + that ‘\epsffile’ works. + Of course, dvips (or some other program that does the + job) must be used to convert 3DLDF.dvi to a PostScript file. + To see exactly how this is done, take a look at the + .texi source files of this manual.2 + +

In the 3DLDF.texi belonging to the 3DLDF distribution, + \makeexamplestrue will be commented-out, and + makeexamplesfalse won't be, because the EPS files for the + illustrations are included in the distribution. + +

The version of examples.web in 3DLDF-1.1.5.1/CWEB merely + includes the files subex1.web and subex2.web. + If you rename 3DLDF-1.1.5.1/CWEB/exampman.web to examples.web, + you can generate the illustrations. + +

+ +


+ Next: , + Previous: About This Manual, + Up: Introduction + +
+ +

1.3 CWEB Documentation

+ +

As mentioned above, 3DLDF has been programmed using CWEB, which is a + “literate programming” tool developed by + Donald E. Knuth and Silvio Levy. See Sources of Information, for a + reference to the CWEB manual. + Knuth's TeX—The Program and + Metafont—The Program both include a section + “How to read a WEB” (pp. x–xv, in both volumes). + +

CWEB files combine source code + and documentation. Running ctangle on a CWEB file, + for example, main.web, produces the file main.c containing + C or C++ + code. Running cweave main.web creates a + TeX file with pretty-printed source code and nicely formatted + documentation. I find that using CWEB makes it more natural to + document my code as I write it, and makes the source files easier to + read when editing them. It does have certain consequences + with regard to compilation, but these are taken care of by make. + See Adding a File, and Changes, for more + information. + +

The CWEB files in the directory 3DLDF-1.1.5.1/CWEB/ contain the + source code for 3DLDF. The file 3DLDFprg.web in this directory + is only ever used for cweaving; it is never ctangled and contains no + C++ + code for compilation. It does, however, include all of the other + CWEB files, so that cweave 3DLDFprg.web generates the TeX file + containing the complete documentation of the source code of 3DLDF. + +

The files 3DLDF-1.1.5.1/CWEB/3DLDFprg.tex, + 3DLDF-1.1.5.1/CWEB/3DLDFprg.dvi, and + 3DLDF-1.1.5.1/CWEB/3DLDFprg.ps are + included in the distribution of 3DLDF as a + convenience. However, users may generate them themselves, should there + be some reason for doing so, by entering make ps + from the command line of a shell from the working + directory 3DLDF-1.1.5.1/ or 3DLDF-1.1.5.1/CWEB. + Alternatively, the user may generate them + by hand from the working directory 3DLDF-1.1.5.1/CWEB/ in the + following way: + +

    +
  1. cweave 3DLDFprg.web + generates 3DLDFprg.tex. + +
  2. tex 3DLDFprg or tex 3DLDFprg.tex generates + 3DLDFprg.dvi. + +
  3. dvips -o 3DLDFprg.ps 3DLDFprg (possibly with additional options) + generates 3DLDFprg.ps. + +
  4. lpr -P<print queue> 3DLDFprg.ps + sends 3DLDFprg.ps to a printer, on a UNIX or UNIX-like system. +
+ +

The individual commands may differ, depending on the system you're + using. + +

+ +


+ Next: , + Previous: CWEB Documentation, + Up: Introduction + +
+ +

1.4 Metafont and MetaPost

+ +

Metafont is a system created by Donald E. Knuth for generating fonts, + in particular for use with TeX, his well-known + typsetting system.3 + Expressed in a + somewhat simplified way, Metafont is a system for programming + curves, which are then digitized and output in the form of + run-time encoded bitmaps. (See Knuth's The Metafontbook for more + information). + +

John D. Hobby modified Metafont's source code to create + MetaPost, which functions in much the same way, but outputs + encapsulated PostScript (EPS) files instead of bitmaps. MetaPost is + very useful for creating graphics and is a convenient + interface to PostScript. It is also easy both to imbed + TeX code in MetaPost programs, for instance, for typesetting + labels, and to include MetaPost graphics in ordinary TeX + files, e.g., by using dvips.4 + Apart from simply printing the PostScript file output by + dvips, there are many programs that can process ordinary + or encapsulated PostScript files and convert them to other formats. + Just two of the many possibilities are ImageMagick and GIMP, both of + which can be used to create animations from MetaPost graphics. + + + +

However, MetaPost inherited a significant limitation from + Metafont: it's not possible to use it for making + three-dimensional graphics, except in a very limited way. + One insuperable problem is the severe limitation on the magnitude + of user-defined numerical variables in Metafont and + MetaPost.5 + This + made sense for Metafont's and MetaPost's original + purposes, but they make it impossible to perform the + calculations needed for 3D graphics. + +

Another problem is the data types defined in Metafont: Points + are represented as pairs of real values and affine + transformations as sets of 6 real values. This corresponds to + the representation of points and affine transformations in the + plane as a two-element vector on the one hand and a six + element matrix on the other. While it is + possible to work around the limitation imposed by having + points be represented by only two values, it is + impracticable in the case of the + transformations. + +

For these reasons, I decided to write a program that would behave more + or less like Metafont, but with suitable extensions, and the ability to + handle three dimensional data; namely 3DLDF. It stores the data and + performs the transformations and other necessary calculations and is not + subject to the limitations of MetaPost and its data types. Upon output, + it performs a perspective transformation, converting the 3D image into a + 2D one. The latter can now be expressed as an ordinary MetaPost + program, so 3DLDF writes its output as MetaPost code to a file. + +

In the following, it may be a little unclear why I sometimes refer to + Metafont and sometimes to MetaPost. The reason is that Metafont + inherited much of its functionality from Metafont. Certain operations + in Metafont have no meaning in MetaPost and so have been removed, while + MetaPost's function of interfacing with PostScript has caused other + operations to be added. For example, in MetaPost, color is a + data type, but not in Metafont. Unless otherwise stated, when I refer to + Metafont, it can be assumed that what I say applies to MetaPost as well. + However, when I refer to MetaPost, it will generally be in connection + with features specific to MetaPost. + +

+ +


+ Next: , + Previous: Metafont and MetaPost, + Up: Introduction + +
+ +

1.5 Caveats

+ + + +
+ +


+ Next: , + Previous: Caveats, + Up: Caveats + +
+ +

1.5.1 Accuracy

+ +

When 3DLDF is run, it uses the three-dimensional data contained in the + user code to create a two-dimensional projection. + Currently, this can be a perspective projection, or a parallel + projection onto one of the major planes. MetaPost code representing + this projection is then written to the output file. + 3DLDF does no scan conversion,6 + so all of the curves in the projection are + generated by means of the algorithms MetaPost inherited from Metafont. + These algorithms, however, are designed to find the + “most pleasing curve”7 + given one or more two-dimensional points and connectors; they do not + account for the the fact that the two-dimensional points are projections + of three-dimensional ones. This can lead to unsatisfactory results, + especially where extreme foreshortening occurs. In particular, + ‘curl’, dir, ‘tension’, and control points should be + used cautiously, or avoided altogether, when specifying connectors. + +

3DLDF operates on + the assumption that, given an adequate number of points, + MetaPost will produce an adequate approximation to the desired + curve in perspective, since the greater the number of + points given for a curve, the less “choice” MetaPost has for + the path through them. My experience with 3DLDF bears this + out. Generally, the curves look quite good. Where problems arise, + it usually helps to increase the number of points in a curve. + +

A more serious problem is the imprecision resulting from the operation + of rotation. Rotations use the trigonometric functions, which return + approximate values. This has the result that points that should have + identical coordinate values, sometimes do not. + This has consequences for the functions that compare points. + The more rotations + are applied to points, the greater the divergence between their actual + coordinate values, and the values they should have. So far, I haven't + found a solution for this problem. On the other hand, it hasn't + yet affected the usability of 3DLDF. + +

+ +


+ Previous: Accuracy, + Up: Caveats + +
+ +

1.5.2 No Input Routine

+ +

3DLDF does not yet include a routine for reading input + files. This means that user code must be written in C++ + , + compiled, and linked with the rest of the program. I admit, + this is not ideal, and writing an input routine for user code + is one of the next things I plan to add to 3DLDF. + +

I plan to use Flex and Bison to write the input routine.8 + The syntax of the input code should be as close + as possible to that of MetaPost, while taking account of the + differences between MetaPost and 3DLDF. + +

For the present, however, the use of 3DLDF is limited to + those who feel comfortable using C++ + and compiling and + relinking programs. Please don't be put off by this! It's not so + difficult, and make does most of the work of recompiling and + running 3DLDF. See Installing and Running 3DLDF, for more + information. + +

+ +


+ Previous: Caveats, + Up: Introduction + +
+ +

1.6 Ports

+ +

I originally developed 3DLDF on a DECalpha Personal Workstation with two + processors running under the operating system Tru64 Unix 5.1, using the + DEC C++ + compiler. + I then ported it to a PC Pentium 4 running under Linux 2.4, using + the GNU C++ + compiler + GCC 2.95.3, and a PC Pentium II XEON under Linux 2.4, using GCC 3.3. + I am currently only maintaining the last version. I do not believe that + it's worthwhile to maintain a version for GCC 2.95. While I would like + 3DLDF to run on as many platforms as possible, I would + rather spend my time developing it than porting it. + This is something where I would be grateful for help from other + programmers. + +

Although I am no longer supporting ports to other systems, + I have left some conditionally compiled code for + managing platform dependencies in the CWEB sources of 3DLDF. This may + make it easier for other people who want to port 3DLDF to other + platforms. + +

Currently, the files io.web, loader.web, main.web, + points.web, + and pspglb.web contain conditionally compiled code, depending on + which compiler, or in the case of GCC, which version of the compiler, is + used. The DEC C++ + compiler defines the preprocessor macro + ‘__DECCXX’ and GCC defines ‘__GNUC__’. In order to + distinguish between GCC 2.95.3 and GCC 3.3, I've added the macros + ‘LDF_GCC_2_95’ and ‘LDF_GCC_3_3’ in loader.web, which + should be defined or undefined, depending on which compiler you're + using. In the distribution, ‘LDF_GCC_3_3’ is defined and + ‘LDF_GCC_2_95’ is undefined, so if you want to try using GCC 2.95, you'll + have to change this (it's not guaranteed to work). + +

3DLDF 1.1.5.1 now uses Autoconf and Automake, and the + configure script generates a config.h file, which is now + included in loader.web. Some of + the preprocessor macros defined in config.h are used to + conditionally include library header files, but so far, there is no error + handling code for the case that a file can't be included. I hope to improve the + way 3DLDF works together with Autoconf and Automake in the near future. + +

3DLDF 1.1.5 is the first release that contains template functions. + Template instantiation differs from compiler to compiler, so using + template functions will tend to make 3DLDF less portable. + See Template Functions, for more information. + I am no longer able to build 3DLDF on the DECalpha Personal Workstation. + I'm fairly sure that it would be possible to port it, but + I don't plan to do this, since Tru64 Unix 5.1 and the DEC C++ + +

compiler are non-free software. + + + + + + + + + + +

+ +


+ Next: , + Previous: Introduction, + Up: Top + +
+ +

1.7 Contributing to 3DLDF

+ +

So far, I've been the sole author and user of 3DLDF. + I would be very interested in having other programmers contribute to + it. I would be particularly interested in help in making 3DLDF conform + as closely as possible to the GNU Coding Standards. I would be + grateful if someone would write proper Automake and Autoconf files, + since I haven't yet learned how to do so (I'm working on it). + +

See Introduction, for information on how to contact the author. + + + +

+ +


+ Next: , + Previous: Contributing to 3DLDF, + Up: Top + +
+ +

Using 3DLDF

+ +

Since 3DLDF does not yet have an input routine, user code must be + written in C++ + (in main.web, or some other file) and compiled. + Then, 3DLDF must be relinked, together with the new file of object + code resulting from the compilation. + For now, the important point is that the text of + the examples in this manual represent C++ + code. + See Installing and Running 3DLDF, for more information. + + + + + + + +

+ +


+ Next: , + Previous: Using 3DLDF, + Up: Top + +
+ +

2 Points

+ + + +
+ +


+ Next: , + Previous: Points, + Up: Points + +
+ +

2.1 Declaring and Initializing Points

+ +

The most basic drawable object in 3DLDF is class Point. It is + analogous to pair in Metafont. For example, in Metafont one + can define a pair using the “z” syntax as + follows: + +

     z0 = (1cm, 1cm);
+ 
+

There are other ways of defining pairs in Metafont (and + MetaPost), but this is the usual way. + +

In 3DLDF, a Point is declared and initialized as follows: + +

     Point pt0(1, 2, 3);
+ 
+

This simple example demonstrates several differences between Metafont + and 3DLDF. First of all, there is no analog in 3DLDF to Metafont's + “z” syntax. + If I want to have Points called “pt0”, “pt1”, + “pt2”, etc., then I must declare each of them to be a + Point: + +

     Point pt0(10, 15, 2);
+      Point pt1(13, 41, 5.5);
+      Point pt2(62.9, 7.02, 8);
+ 
+

Alternatively, I could declare an array of Points: + +

     Point pt[3];
+ 
+

Now I can refer to pt[0], pt[1], and pt[2]. + +

In the Metafont example, the x and y-coordinates of the pair z0 + are specified using the unit of measurement, in this case, centimeters. + This is currently not possible in 3DLDF. The current unit of + measurement is stored in the static variable Point::measurement_units, + which is a string. Its default value is "cm" for + “centimeters”. + At present, it is best to stick with one unit of measurement for a + drawing. + After I've defined an input routine, 3DLDF should handle + units of measurement in the same way that Metafont does. + +

Another difference is that the Points pt0, pt1, and + pt2 have three coordinates, x, y, and z, whereas z0 has + only two, x and y. Actually, the difference goes deeper than this. In + Metafont, a pair has two parts, xpart and ypart, + which can be examined by the user. In 3DLDF, a Point contains + the following sets of coordinates: + +

     world_coordinates
+      user_coordinates
+      view_coordinates
+      projective_coordinates
+ 
+

These are sets of 3-dimensional homogeneous coordinates, which + means that they contain four coordinates: x, y, z, and w. Homogeneous + coordinates are used in the affine and perspective transformations + (see Transforms). + +

Currently, only world_coordinates and + projective_coordinates are used in 3DLDF. + The world_coordinates refer to the position of a Point in + 3DLDF's basic, unchanging coordinate system. + The projective_coordinates are the coordinates of the + two-dimensional projection of the Point onto a plane. + This projection is what is ultimately printed out or displayed on the + computer screen. Please note, that when the coordinates of a + Point are referred to in this manual, the + world_coordinates are meant, unless otherwise stated. + +

Points can be declared and their values can be set in different + ways. + +

     Point pt0;
+      Point pt1(1);
+      Point pt2(2.3, 52);
+      Point pt3(4.5, 7, 13.205);
+ 
+

pt0 is declared without any arguments, i.e., using the default + constructor, so the values of its x, y, and + z-coordinates are all 0. + +

pt1 is declared and initialized with one argument for the x-coordinate, + so its y and z-coordinates are initialized with the values of + CURR_Y and CURR_Z respectively. + The latter are static constant data members + of class Point, whose values are 0 by default. They can be reset + by the user, who should + make sure that they have sensible values. + +

pt2 is declared and initialized with two arguments for its x and + y-coordinates, so its z-coordinate is initialized to the value of + CURR_Z. Finally, pt3 has an argument for each of its + coordinates. + +

Please note that pt0 is constructed using a the default + constructor, whereas the other Points are constructed using a + constructor with one required argument (for the x-coordinate), and two + optional arguments (for the y and z-coordinates). The default + constructor always sets all the coordinates to 0, irrespective of the + values of CURR_Y and CURR_Z. + +

+ +


+ Previous: Declaring and Initializing Points, + Up: Points + +
+ +

2.2 Setting and Assigning to Points

+ +

It is possible to change the value of the coordinates of Points + by using the assignment operator = + (Point::operator=()) or the function Point::set() + (with appropriate arguments): + +

     Point pt0(2, 3.3, 7);
+      Point pt1;
+      pt1 = pt0;
+      pt0.set(34, 99, 107.5);
+      pt0.show("pt0:");
+      -| pt0: (34, 99, 107.5)
+      pt1.show("pt1:");
+      -| pt1: (2, 3.3, 7)
+ 
+

In this example, pt0 is initialized with the coordinates (2, 3.3, 7), + and pt1 with the coordinates (0, 0, 0). + pt1 = pt0 causes pt1 to have the same coordinates as + pt0, then the coordinates of pt0 are changed to (34, + 99, 107.5). This doesn't affect pt1, whose coordinates remain + (2, 3.3, 7). + +

Another way of declaring and initializing Points is by using the + copy constructor: + +

     Point pt0(1, 3.5, 19);
+      Point pt1(pt0);
+      Point pt2 = pt0;
+      Point pt3;
+      pt3 = pt0;
+ 
+

In this example, pt1 and pt2 are both declared and + initialized using the copy constructor; Point pt2 = pt0 does not + invoke the assignment operator. pt3, on the other hand, is + declared using the default constructor, and not initialized. In the + following line, pt3 = pt0 does invoke the assignment operator, + thus resetting the coordinate values of pt3 to those of + pt0. + + + + + + + +

+ +


+ Next: , + Previous: Points, + Up: Top + +
+ +

3 Transforming Points

+ +

Points don't always have to remain in the same place. There are + various ways of moving or transforming them: +

    +
  • Shifting. This is often called “translating”, but the operation in Metafont + that performs translation is called shift, so I call it “shifting”. + +
  • Scaling. + +
  • Shearing. + +
  • Rotating about an axis. + +
+ +

class Point has several member functions + for applying these affine transformations9 + to a Point. + Most of the arguments to these functions are of + type real. As you may know, there is no such data type in C++ + . + I have defined real using typedef to be either + float or double, depending on the value of a preprocessor + switch for conditional compilation.10 + 3DLDF uses many real values and I wanted to be able to + change the precision used by making one change (in the file + pspglb.web) rather than having to examine all the places in the + program where float or double are used. Unfortunately, + setting real to double currently doesn't work. + +

+ +
+ +


+ Next: , + Previous: Transforming Points, + Up: Transforming Points + +
+ +

3.1 Shifting

+ +

The function + shift() + adds its arguments to the corresponding + world_coordinates of a Point. In the following example, + the function show() is used to print the world_coordinates + of p0 to standard output. + +

     Point p0(0, 0, 0);
+      p0.shift(1, 2, 3);
+      p0.show("p0:");
+      -| p0: (1, 2, 3)
+      p0.shift(10);
+      p0.show("p0:");
+      -| p0: (11, 2, 3)
+      p0.shift(0, 20);
+      p0.show("p0:");
+      -| p0: (11, 22, 3)
+      p0.shift(0, 0, 30);
+      p0.show("p0:");
+      -| p0: (11, 22, 33)
+ 
+

shift takes three real arguments, whereby the second and + third are optional. To shift a Point in the direction of + the positive or negative y-axis, and/or the positive or negative z-axis + only, then a 0 argument for the + x direction, and possibly one for the y direction + must be used as placeholders, as in the example above. + +

shift() can be invoked with a Point argument + instead of real arguments. In this case, the x, y, and + z-coordinates of the argument are used for shifting the Point: + +

     Point a(10, 10, 10);
+      Point b(1, 2, 3);
+      a.shift(b);
+      a.show("a:")
+      -| a: (11, 12, 13)
+ 
+

Another way of shifting Points is to use the binary += + operator (Point::operator+=()) with a Point + argument. + +

     Point a0(1, 1, 1);
+      Point a1(2, 2, 2);
+      a0 += a1;
+      a0.show("a0:");
+      -| a0: (3, 3, 3)
+ 
+
+ +


+ Next: , + Previous: Shifting Points, + Up: Transforming Points + +
+ +

3.2 Scaling

+ +

The function scale() takes three real arguments. + The x, y, and z-coordinates of the Point are + multiplied by the first, second, and third arguments respectively. Only + the first argument is required; the default for the others is 1. + +

If one wants to perform scaling in either the y-dimension only, or the y + and z-dimensions only, a dummy argument of 1 must be passed for + scaling in the x-dimension. Similarly, if one wants to perform scaling + in the z-dimension only, dummy arguments of 1 must be passed for scaling + in the x and y-dimensions. + +

     Point p0(1, 2, 3);
+      p0.scale(2, 3, 4);
+      p0.show("p0:");
+      -| p0: (2, 6, 12)
+      p0.scale(2);
+      p0.show("p0:");
+      -| p0: (4, 6, 12)
+      p0.scale(1, 3);
+      p0.show("p0:");
+      -| p0: (4, 18, 12)
+      p0.scale(1, 1, 3);
+      p0.show("p0:");
+      -| p0: (4, 18, 36)
+ 
+
+ +


+ Next: , + Previous: Scaling Points, + Up: Transforming Points + +
+ +

3.3 Shearing

+ +

Shearing is more complicated than shifting or scaling. The function + shear() takes six real arguments. + If p is a Point, then p.shear(a, b, c, d, e, f) sets + x_p to x_p + ay_p + bz_p, y_p to + y_p + cx_p + dz_p, and + z_p to z_p + ex_p + fy_p. + In this way, each coordinate of a Point is modified based on the + values of the other two coordinates, whereby the influence of the + other coordinates on the new value is weighted according to the + arguments. + +

     Point p(1, 1, 1);
+      p.shear(1);
+      p.show("p:");
+      -| p: (2, 1, 1)
+      p.set(1, 1, 1);
+      p.shear(1, 1);
+      p.show("p:");
+      -| p: (3, 1, 1)
+      p.set(1, 1, 1);
+      p.shear(1, 1, 2, 2, 3, 3);
+      p.show("p:");
+      -| p: (3, 5, 7)
+ 
+ + +

[next figure] + demonstrates the effect of shearing the points of a rectangle + in the x-y plane. + +

     Point P0;
+      Point P1(3);
+      Point P2(3, 3);
+      Point P3(0, 3);
+      Rectangle r(p0, p1, p2, p3);
+      r.draw();
+      Rectangle q(r);
+      q.shear(1.5);
+      q.draw(black, "evenly");
+ 
+

+
+ [Figure 1. Not displayed.] +
+
+ Fig. 1. +
+

+ +
+ +


+ Previous: Shearing Points, + Up: Transforming Points + +
+ +

3.4 Rotating

+ + +

The function rotate() rotates a Point about one or more of + the main axes. + It takes three real arguments, specifying the + angles of rotation in degrees about the x, y, and z-axes respectively. + Only the first argument is required, the other two are 0 by default. If + rotation about the y-axis, or the y and z-axes only are required, then 0 + must be used as a placeholder for the first and possibly the second + argument. + +

     Point p(0, 1);
+      p.rotate(90);
+      p.show("p:");
+      -| p: (0, 0, -1)
+      p.rotate(0, 90);
+      p.show("p:");
+      -| p: (1, 0, 0)
+      p.rotate(0, 0, 90);
+      p.show("p:");
+      -| p: (0, 1, 0)
+ 
+

The rotations are performed successively about the + x, y, and z-axes. However, rotation is not a commutative + operation, so if rotation about the main axes in a different + order is required, then rotate() must be invoked more than once: + +

     Point A(2, 3, 4);
+      Point B(A);
+      A.rotate(30, 60, 90);
+      A.show("A:");
+      -| A: (-4.59808, -0.700962, 2.7141)
+      B.rotate(0, 0, 90);
+      B.rotate(0, 60);
+      B.rotate(30);
+      B.show("B:");
+      -| B: (-4.9641, 1.43301, -1.51795)
+ 
+

Rotation need not be about the main axes; it can also be performed + about a line defined by two Points. The function rotate() + with two Point arguments and a real argument for the + angle of rotation (in degrees) about the axis. The real argument + is optional, with + 180 degrees + +

as the default. + + + + +

     Point p0 (-1.06066, 0, 1.06066);
+      Point p1 (1.06066, 0, -1.06066);
+      p1 *= p0.rotate(0, 30, 30);
+      p0.show("p0:");
+      -| p0: (-1.25477, -0.724444, 0.388228)
+      p1.show("p1:");
+      -| p1: (1.25477, 0.724444, -0.388228)
+      p0.draw(p1);
+      Point p2(1.06066, 0, 1.06066);
+      p2.show("p2:");
+      -| p2: (1.06066, 0, 1.06066)
+      Point p3(p2);
+      p3.rotate(p1, p0, 45);
+      p3.show("p3:");
+      -| p3 (1.09721, 1.15036, 1.17879)
+      Point p4(p2);
+      p4.rotate(p1, p0, 90);
+      p4.show("p4:");
+      -| p4: (0.882625, 2.05122, 0.485242)
+      Point p5(p2);
+      p5.rotate(p1, p0, 135);
+      p5.show("p5:");
+      -| p5: (0.542606, 2.17488, -0.613716)
+      Point p6(p2);
+      p6.rotate(p1, p0);
+      p6.show("p6:");
+      -| p6: (0.276332, 1.44889, -1.47433)
+ 
+

+
+ [Figure 2. Not displayed.] +
+
+ Fig. 2. +
+

+ +

I have sometimes gotten erroneous results using rotate() for + rotation about two Points. It's usually worked to reverse the + order of the Point arguments, or to change sign of the angle + argument. I think I've fixed the problem, though. + + + + + + + +

+ +


+ Next: , + Previous: Transforming Points, + Up: Top + +
+ +

4 Transforms

+ +

When Points are transformed using shift(), shear(), + or one of the other transformation functions, the + world_coordinates are not modified directly. Instead, + another data member of class Point is used to store the + information about the transformation, namely transform of + type class Transform. A Transform object has a single + data element of type Matrix and a number of member functions. A + Matrix is + simply a + 4 X 4 + array11 + of reals + defined using typedef real Matrix[4][4]. + Such a matrix suffices for performing all + of the transformations (affine and perspective) possible in + three-dimensional space.12 + Any combination of transformations can be represented by a single + transformation matrix. This means that consecutive transformations + of a Point can be “saved up” and applied to its coordinates + all at once when needed, rather than updating them for each + transformation. + +

Transforms work by performing matrix multiplication of + Matrix with the homogeneous world_coordinates of + Points. + If a set of homogeneous coordinates + \alpha = (x, y, z, w) + and +

     Matrix M =
+      a e i m
+      b f j n
+      c g k o
+      d h l p
+ 
+

then the set of homogeneous coordinates \beta resulting from + multiplying \alpha and M is calculated as follows: +

     \beta = \alpha\times M = ((xa + yb + zc + wd),  (xe + yf + zg + wh),
+      (xi + yj + zk + wl), (xm + yn + zo + wp))
+ 
+

Please note that each coordinate of \beta can be influenced by all of the + coordinates of \alpha. + +

Operations on + matrices are very important in computer graphics applications and are + described in many books about computer graphics and geometry. For + 3DLDF, I've mostly used Huw Jones' + Computer Graphics through Key Mathematics + and David Salomon's Computer Graphics and Geometric Modeling. + +

It is often useful to declare and use Transform objects in 3DLDF, + just as it is for transforms in Metafont. Transformations can be + stored in Transforms and then be used to transform Points + by means of Point::operator*=(const Transform&). + +

     1. Transform t;
+      2. t.shift(0, 1);
+      3. Point p(1, 0, 0);
+      4. p *= t;
+      5. p.show("p:");
+      -| p: (1, 1, 0)
+ 
+

When a Transform is declared (line 1), it is + initialized to an identity matrix. All identity matrices are + square, all of the elements of the main diagonal (upper left to lower + right) are 1, and all of the other elements are 0. + So a + 4 X 4 + identity matrix, as used in 3DLDF, looks like this: +

     1 0 0 0
+      0 1 0 0
+      0 0 1 0
+      0 0 0 1
+ 
+

If a matrix A is multiplied with an identity matrix I, the result is + identical to A, i.e., + A * I = A. + This is the salient property of an identity matrix. + +

The same affine transformations are applied in the same way to + Transforms as they are to Points, i.e., the functions + scale(), shift(), + shear(), and rotate() + correspond to the Point + versions of these functions, and they take the same arguments: + +

     Point p;
+      Transform t;
+      p.shift(3, 4, 5);
+      t.shift(3, 4, 5);
+      ⇒ p.transform == t
+      p.show_transform("p:");
+      -| p:
+         Transform:
+               0   0.707   0.707       0
+          -0.866   0.354  -0.354       0
+            -0.5  -0.612   0.612       0
+               0       0       0       1
+      t.show("t:");
+      -| t:
+               0   0.707   0.707       0
+          -0.866   0.354  -0.354       0
+            -0.5  -0.612   0.612       0
+               0       0       0       1
+      
+ 
+ + +
+ +


+ Next: , + Previous: Transforms, + Up: Transforms + +
+ +

4.1 Applying Transforms to Points

+ +

A Transform t is applied to a + Point P using the binary *= operation + (Point::operator*=(const Transform&)) + which performs matrix multiplication of P.transform by t. + See Point Reference; Operators. + +

     Point P(0, 1);
+      Transform t;
+      t.rotate(90);
+      t.show("t:");
+      -| t:
+         1       0       0       0
+         0       0      -1       0
+         0       1       0       0
+         0       0       0       1
+      P *= t;
+      P.show_transform("P:");
+      -| P:
+      Transform:
+         1       0       0       0
+         0       0      -1       0
+         0       1       0       0
+         0       0       0       1
+      P.show("P:");
+      -| P: (0, 0, -1)
+ 
+

In the example above, there is no real need to use a Transform, + since P.rotate(90) could have been called directly. + As constructions become more complex, the power of Transforms + becomes clear: + + + +

     1. Point p0(0, 0, 0);
+      2. Point p1(10, 5, 10);
+      3. Point p2(16, 14, 32);
+      4. Point p3(25, 50, 99);
+      5. Point p4(12, 6, 88);
+      6. Transform a;
+      7. a.shift(2, 3, 4);
+      8. a.scale(1, 3, 1);
+      9. p2 *= p3 *= a;
+      10. a.rotate(p0, p1, 75);
+      11. p4 *= a;
+      12. p2.show("p2:");
+         -| p2: (18, 51, 36)
+      13. p3.show("p3:");
+         -| p3: (27, 159, 103)
+      14. p4.show("p4:");
+         -| p4: (24.4647, -46.2869, 81.5353)
+ 
+ + +

In this example, a is shifted and scaled, and a is applied + to both in line 9. This works, because + the binary operation + operator*=(const Transform& t) returns t, + making it possible to chain invocations of *=. + Following this, a is rotated + 75 degrees + +

about the line through p_0 and p_1. + Finally, all three transformations, which are stored in a, are + applied to p_4. + +

+ +


+ Previous: Applying Transforms to Points Intro, + Up: Transforms + +
+ +

4.2 Inverting Transforms

+ +

Inversion is another operation that can be performed on + Transforms. This makes it possible to reverse the effect of a + Transform, which may represent multiple transformations. + +

     Point p;
+      Transform t;
+      t.shift(1, 2, 3);
+      t.scale(2, 3, 4);
+      t.rotate(45, 45, 30);
+      t.show("t:");
+      -| t:
+         1.22   0.707    1.41       0
+        0.238    2.59    -1.5       0
+        -3.15    1.45       2       0
+        -7.74    10.2    4.41       1
+      p *= t;
+      p.show("p:");
+      -| p: (-7.74, 10.2, 4.41)
+      Transform u;
+      u = t.inverse();
+      u.show("u:");
+      -| u:
+        0.306  0.0265  -0.197 2.85e-09
+        0.177   0.287  0.0906 -1.12e-09
+        0.354  -0.167   0.125       0
+           -1      -2      -3       1
+      p *= u;
+      p.show("p:");
+      -| p: (0, 0, 0)
+      u *= t;
+      u.show("u:");
+      -| u:
+            1       0       0       0
+            0       1       0       0
+            0       0       1       0
+            0       0       0       1
+ 
+

If inverse() is called with no argument, or with the argument + false, it returns a + Transform representing its inverse, and remains unchanged. If it + is called with the argument true, it is set to its inverse. + +

Complete reversal of the transformations applied to a Point, as + in the previous example, probably won't make much sense. However, + partial reversal is a valuable technique. For example, it is used in + rotate() for rotation about a line defined by two Points. + The following example merely demonstrates the basic principle; an + example that does something useful would be too complicated. + + + + +

     Transform t;
+      t.shift(3, 4, 5);
+      t.rotate(45);
+      t.scale(2, 2, 2);
+      Point p;
+      p *= t;
+      p.show("p:");
+      -| p: (6, 12.7279, 1.41421)
+      t.inverse(true);
+      p.rotate(90, 90);
+      p *= t;
+      p.show("p:");
+      -| p: (3.36396, -5.62132, -2.37868)
+ 
+ + + + + + +
+ +


+ Next: , + Previous: Transforms, + Up: Top + +
+ +

5 Drawing and Labeling Points

+ + + + + +

5.1 Drawing Points

+ +

It's all very well to declare Points, place them at particular + locations, print their locations to standard output, and transform them, + but none of these operations produce any MetaPost output. + In order to do this, the first step is to use drawing and + filling commands. The drawing and filling commands in 3DLDF are + modelled on those in Metafont. + +

The following example demonstrates how to draw a dot specifying a + Color (see Color Reference) and a + pen13. + +

     Point P(0, 1);
+      P.drawdot(Colors::black, "pencircle scaled 3mm");
+ 
+

+
+ [Figure 3. Not displayed.] +
+
+ Fig. 3. +
+

+ +

In drawdot(), a Color argument precedes the + string argument for the pen, so “Colors::black” must be + specified as a placeholder in the call to + drawdot().14 + +

The following example “undraws” a dot at the same location using a + smaller pen. undraw() does not take a Color argument. + +

     p.undrawdot("pencircle scaled 2mm");
+ 
+

+
+ [Figure 4. Not displayed.] +
+
+ Fig. 4. +
+

+ +

For complete descriptions of drawdot() and undrawdot(), + see Point Reference; Drawing. + +

Drawing and undrawing dots is not very exciting. In order to make a + proper drawing it is necessary to connect the Points. The most + basic way of doing this is to use the Point member function + draw() with a Point argument: + +

     Point p0;
+      Point p1(2, 2);
+      p0.draw(p1);
+ 
+

+
+ [Figure 5. Not displayed.] +
+
+ Fig. 5. +
+

+ +

p0.draw(p1) is equivalent in its effect to + p1.draw(p0). + +

The function Point::draw() takes a required Point& + argument (a reference15 + to a Point) an optional Color + argument, and optional string arguments for + the dash pattern and the + pen. The string arguments, if present, are passed unchanged to + the output file. + The empty string following the + argument p1 is a placeholder for the dash pattern argument, which + isn't used here. + +

     p0.draw(p1, Colors::gray, "", "pensquare scaled .5cm rotated 45");
+ 
+

+
+ [Figure 6. Not displayed.] +
+
+ Fig. 6. +
+

+ +

The function Point::undraw() takes a required Point& + argument and + optional string arguments for the dash pattern and the + pen. Unlike Point::draw(), a Color argument would have no + meaning for Point::undraw(). + The string arguments are passed unchanged to the output file. + +

undraw() can be used to “hollow out” the region + drawn in [the previous figure] + . Since a dash pattern is used, portions + of the middle of the region are not undrawn. + +

     p0.undraw(p1, "evenly scaled 6", "pencircle scaled .2cm");
+ 
+

+
+ [Figure 7. Not displayed.] +
+
+ Fig. 7. +
+

+ +

For complete descriptions of draw() and undraw(), + see Point Reference; Drawing. + +

+ +


+ Previous: Drawing Points Intro, + Up: Drawing and Labeling Points + +
+ +

5.2 Labeling Points

+ +

The labels in the previous examples were made by using the functions + Point::label() and Point::dotlabel(), which make it + possible to include TeX text in a drawing. + +

label() and dotlabel() take string arguments for + the text of the label and the position of the label with respect to the + Point. The label text is formatted using TeX, so it can contain + math mode material between dollar signs. Please note that double backslashes + must be used, where a single backslash would suffice in a file of + MetaPost code, for example, for TeX control sequences. + Alternatively, a short argument can be used for the label. + +

The position argument is optional, with "top" as the default. If + the empty string "" is used, the label will centered about + the Point itself. This will usually only make sense for + label(), because it would otherwise interfere with the dot. + Valid arguments for the + position are the same as in MetaPost: "top", "bot" + (bottom), "lft" (left), "rt" (right), + "ulft" (upper left), "urt" (upper right), + "llft" (lower left), and "lrt" (lower right). + +

     Point p0;
+      Point p1(1);
+      Point p2(2);
+      Point p3(p0);
+      Point p4(p1);
+      Point p5(p2);
+      p3 *= p4 *= p5.shift(0, 1);
+      p0.draw(p1);
+      p1.draw(p2);
+      p2.draw(p5);
+      p5.draw(p4);
+      p4.draw(p3);
+      p3.draw(p0);
+      p0.label($p_0$, "");
+      p1.dotlabel(1);
+      p2.dotlabel("p2", "bot");
+      p3.dotlabel("This is $p_3$", "lft");
+      p4.label(4);
+      p5.label("$\\leftarrow p_5$", "rt");
+ 
+

+
+ [Figure 8. Not displayed.] +
+
+ Fig. 8. +
+

+ +

For complete descriptions of Point::label() and + Point::dotlabel(), see Points; Labelling. + + + + + + + +

+ +


+ Next: , + Previous: Drawing and Labeling Points, + Up: Top + +
+ +

6 Paths

+ +

Points alone are not enough for making useful drawings. The next + step is to combine them into Paths, which are similar to + Metafont's paths, except that they are three-dimensional. + A Path consists of a number of Points and strings + representing the connectors. The latter are not processed by + 3DLDF, but are passed unchanged to the output file. They must be valid + connectors for MetaPost, e.g.: + +

+

     ..
+      ...
+      --
+      ---
+      &
+      curl{2}..
+      {dir 60}..
+      {z1 - z2}..
+      .. tension 1 and 1.5..
+      ..controls z1 and z2..
+ 
+

Usually, it will only make sense to use .. or , and not + ..., , tension, curl, controls, or any of the + other possibilities, in Paths, unless + you are sure that they will only be viewed with no foreshortening due to + the perspective + projection. This can be the case, when a Path lies in a plane + parallel to one of the major planes, and is projected using parallel + projection onto that plane. Otherwise, + the result of using these connectors is likely to be unsatisfactory, because + MetaPost performs its calculations based purely on the two-dimensional + values of the points in the perspective projection. + While the Points on the Path will be projected correctly, + the course of the Path between these Points is likely to + differ, depending on the values of the Focus + used (see Focuses), so that + different views of the same Path may well be mutually + inconsistent. + This problem doesn't arise with “”, since the perspective + projection does not “unstraighten” straight lines, + but it does with “..”, even without tension, curl, + or controls. + The solution is to use enough Points, since a greater number of + Points on a Path tends to reduce the number + of possible courses through the Points.16 + +

+ +
+ +


+ Next: , + Previous: Paths, + Up: Paths + +
+ +

6.1 Declaring and Initializing Paths

+ +

There are various ways of declaring and initializing Paths. The + simplest is to use the constructor taking two Point arguments: + +

     Point A;
+      Point B(2, 2);
+      Path p(A, B);
+      p.draw();
+ 
+

+
+ [Figure 9. Not displayed.] +
+
+ Fig. 9. +
+

+ +

Paths created in this way are important, because they are + guaranteed to be linear, as long as no operations are performed on them + that cause them to become non-linear. + Linear Paths can be used to find intersections. + See Path Intersections. + +

Paths can be declared and initialized using a single connector + and an arbitrary number of Points. The first argument is a + string specifying the connector. It is followed by a + bool, indicating whether the + Path is cyclical or not. Then, an arbitrary number of + pointers to Point follow. The last argument must be 0.17 + +

     Point p[3];
+      p[0].shift(1);
+      p[1].set(1, 2, 2);
+      p[2].set(1, 0, 2);
+      Path pa("--", true, &p[0], &p[1], &p[2], 0);
+      pa.draw();
+ 
+

+
+ [Figure 10. Not displayed.] +
+
+ Fig. 10. +
+

+ +

Another constructor must be used for Paths with + more than one connector and an arbitrary number of Points. + The argument list starts with a pointer to Point, followed by + string for the first connector. Then, + pointer to Point arguments alternate with string arguments + for the connectors. + Again, the list of arguments ends in 0. There is no + need for a bool to indicate whether the Path is cyclical + or not; if it is, the last non-zero argument will be a connector, + otherwise, it will be a pointer to Point. + +

     Point p[8];
+      p[0].set(-2);
+      p[1].set(2);
+      p[2].set(0, 0, -2);
+      p[3].set(0, 0, 2);
+      p[4] = p[0].mediate(p[2]);
+      p[5] = p[2].mediate(p[1]);
+      p[6] = p[1].mediate(p[3]);
+      p[7] = p[3].mediate(p[0]);
+      p[4] *= p[5] *= p[6] *= p[7].shift(0, 1);
+      Path pa(&p[0], "..", &p[4], "...", &p[2],
+              "..", &p[5], "...", &p[1], "..", &p[6],
+              "...", &p[3], "..", &p[7], "...", 0);
+      pa.draw();
+ 
+

+
+ [Figure 11. Not displayed.] +
+
+ Fig. 11. +
+

+ +

As mentioned above (see Accuracy), specifying connectors is + problematic for three-dimensional Paths, + because MetaPost ultimately calculates the “most pleasing curve” + based on the two-dimensional points in the MetaPost code written by + 3DLDF.18 + For this reason, it's advisable to avoid specifying ‘curl’, + ‘dir’, ‘tension’ or control points in connectors. + The more Points a (3DLDF) Path or other object contains, + the less freedom MetaPost has to determine the (MetaPost) path + through them. + So a three-dimensional Path or + other object in 3DLDF should have enough Points to ensure + satisfactory results. The Path in [the previous figure] + does not + really have enough Points. It may require some trial and error + to determine + what a sufficient number of Points is in a given case. + +

Paths are very flexible, but not always convenient. 3DLDF + provides a number of classes representing common geometric + Shapes, which will be described in subsequent sections, and I + intend to add more in the course of time. + +

+ +


+ Previous: Declaring and Initializing Paths, + Up: Paths + +
+ +

6.2 Drawing and Filling Paths

+ +

The easiest way to draw a Path is with no arguments. + +

     Point pt[5];
+      pt[0].set(-1, -2);
+      pt[1].set(0, -3);
+      pt[2].set(1, 0);
+      pt[3].set(2, 1);
+      pt[4].set(-1, 2);
+      Path pa("..", true, &pt[0], &pt[1], &pt[2], &pt[3], &pt[4], 0);
+      pa.draw();
+ 
+

+
+ [Figure 12. Not displayed.] +
+
+ Fig. 12. +
+

+ +

Since pa is closed, it can be filled as well as drawn. The + following example uses fill() with a Color argument, in + order to avoid having a large splotch of black on the page. + Common Colors are declared in the namespace Colors. + See Color Reference. + +

     pa.fill(Colors::gray);
+ 
+

+
+ [Figure 13. Not displayed.] +
+
+ Fig. 13. +
+

+ +

Closed Paths can be filled and drawn, using the function + filldraw(). This function draws the Path using the pen + specified, or MetaPost's currentpen by default. A Color + for drawing the Path can also be specified, otherwise, the + default color (currently Colors::black) is used. + In addition, the Path is filled using a second Color, + which can be specified, or the background_color + (Colors::background_color), by default. + Filling a Path using the background color causes it to hide + objects that lie behind it. + See Surface Hiding, for a description of the surface hiding + algorithm, and examples. Currently, this algorithm is quite primitive + and only works + for simple cases. + +

     Point p0(-3, 0, 1);
+      Point p1(3, 1, 1);
+      p0.draw(p1);
+      pa.filldraw();
+ 
+

+
+ [Figure 14. Not displayed.] +
+
+ Fig. 14. +
+

+ +

The following example uses arguments for the Colors used for + drawing and filling, and the pen. The empty string argument before the + pen argument is a placeholder for the dash pattern argument. + +

     pa.filldraw(black, gray, "",
+         "pensquare xscaled 3mm yscaled 1mm rotated 60");
+ 
+

+
+ [Figure 15. Not displayed.] +
+
+ Fig. 15. +
+

+ +

Paths can also be “undrawn”, “unfilled”, and “unfilldrawn”, + using the corresponding functions: + +

     pa.fill(gray);
+      p0.undraw(p1, "", "pencircle scaled 3mm");
+ 
+

+
+ [Figure 16. Not displayed.] +
+
+ Fig. 16. +
+

+ +
     pa.fill(gray);
+      Path q;
+      q = pa;
+      q.scale(.5, .5);
+      q.unfill();
+ 
+

+
+ [Figure 17. Not displayed.] +
+
+ Fig. 17. +
+

+ +

The function unfilldraw() takes a Color argument for + drawing the Path, which is *Colors::background_color by + default. This makes it possible to unfill the Path while drawing + the outline with a visible Color. On the other hand, it also + makes it necessary to specify *Colors::background_color or + Colors::white, if the user wants to use the dash pattern and/or + pen arguments, without drawing the Path. + +

     pa.fill(gray);
+      q.unfilldraw(white, "", "pensquare xscaled 3mm yscaled 1mm");
+ 
+

+
+ [Figure 18. Not displayed.] +
+
+ Fig. 18. +
+

+ +

The following example demonstrates the use of unfilldraw() with + black as its Color argument. Unfortunately, it also + demonstrates one of the limitations of the surface hiding algorith: The + line from p0 to p1 is hidden by the + filled Path pa. Since the portion of pa covered by + Path q has been unfilled, + the line from p_0 to p_1 + should be visible as it passes through q. However, from the + point of view of 3DLDF, there is no relationship between pa and + q; nor does it “know” whether a Path has been filled or + unfilled. If it's on a Picture, it will hide objects lying + behind it, unless the surface hiding algorithm fails for another + reason. See Surface Hiding, for more information. + +

     p0.draw(p1);
+      pa.fill(gray);
+      q.unfilldraw(black, "", "pensquare xscaled 3mm yscaled 1mm");
+ 
+

+
+ [Figure 19. Not displayed.] +
+
+ Fig. 19. +
+

+ +

See Paths; Drawing and Filling, for more + information, and complete descriptions of the functions. + + + + + + + +

+ +


+ Next: , + Previous: Paths, + Up: Top + +
+ +

7 Plane Figures

+ +

3DLDF currently includes the following classes representing plane + geometric figures: Polygon, Reg_Cl_Plane_Curve + (“Regular Closed Plane Curve”), Reg_Polygon (“Regular + Polygon”), Rectangle, Ellipse and + Circle. Polygon and Reg_Cl_Plane_Curve are derived + from Path, Reg_Polygon and Rectangle are derived + from Polygon, and Ellipse and Circle are derived + from Reg_Cl_Plane_Curve. Polygon and + Reg_Cl_Plane_Curve are meant to be used as base classes only, so + objects of these types should normally never be declared. + +

Since Reg_Polygon, Rectangle, Ellipse, and + Circle all ultimately derive from Path, they are really + just special kinds of Path. + In particular, they inherit their drawing and filling functions from + Path, and their transformation functions take the same arguments + as the Path versions. + They also have constructors + and setting functions that work in a similar way, with a few minor + differences, to account for their different natures. + See Polygon Reference, Rectangle Reference, + Ellipse Reference, and Circle Reference, for complete + information on these classes. + +

+ +
+ +


+ Next: , + Previous: Plane Figures, + Up: Plane Figures + +
+ +

7.1 Regular Polygons

+ +

The following example creates a pentagon in the x-z plane, centered + about the origin, whose enclosing circle has a radius equal to 3cm. + +

     default_focus.set(2, 3, -10, 2, 3, 10, 10);
+      Reg_Polygon p(origin, 5, 3);
+      p.draw();
+ 
+

+
+ [Figure 20. Not displayed.] +
+
+ Fig. 20. +
+

+ +

Three additional arguments cause the pentagon to be rotated about the x, + y, and z axes by the amount indicated. In this example, it's rotated + 90 degrees + +

about the x-axis, so that it comes to lie in the x-y plane: + +

     Reg_Polygon p(origin, 5, 3, 90);
+      p.draw();
+ 
+

+
+ [Figure 21. Not displayed.] +
+
+ Fig. 21. +
+

+ +

In this example, it's rotated + 36 degrees + +

about the y-axis, so that it appears to point in the opposite + direction from the first example: +

     Reg_Polygon p(origin, 5, 3, 0, 36);
+      p.draw();
+ 
+

+
+ [Figure 22. Not displayed.] +
+
+ Fig. 22. +
+

+ +

In this example, it's rotated + 90 degrees + +

about the z-axis, so that it lies in the z-y plane: + +

     Reg_Polygon p(origin, 5, 3, 0, 0, 90);
+      p.draw();
+ 
+

+
+ [Figure 23. Not displayed.] +
+
+ Fig. 23. +
+

+ +

In this example, it's rotated + 45 degrees + +

about the x, y, and z-axes in that order: + +

     Reg_Polygon p(origin, 5, 3, 45, 45, 45);
+      p.draw();
+ 
+

+
+ [Figure 24. Not displayed.] +
+
+ Fig. 24. +
+

+ +

Reg_Polygons need not be centered about the origin. If + another Point pt is used as the first argument, the Reg_Polygon + is first created with its center at the origin, then the specified + rotations, if any, are performed. Finally, the Reg_Polygon is + shifted such that its center comes to lie on pt: + +

     Point P(-2, 1, 1);
+      Reg_Polygon hex(P, 6, 4, 60, 30, 30);
+      hex.draw();
+ 
+

+
+ [Figure 25. Not displayed.] +
+
+ Fig. 25. +
+

+ +

In the following example, the Reg_Polygon polygon is first + declared using the default constructor, which creates an empty + Reg_Polygon. Then, the polygon is repeatedly changed using + the setting function corresponding to the constructor used in the + previous examples. [next figure] + demonstrates that a given + Reg_Polygon need not always have the same number of sides. + +

     Point p(0, -3);
+      Reg_Polygon polygon;
+      for (int i = 3; i < 9; ++i)
+        {
+          polygon.set(p, i, 3);
+          polygon.draw();
+          p.shift(0, 1);
+        }
+ 
+

+
+ [Figure 26. Not displayed.] +
+
+ Fig. 26. +
+

+ +
+ +


+ Next: , + Previous: Regular Polygons Getstart, + Up: Plane Figures + +
+ +

7.2 Rectangles

+ +

A Rectangle can be constructed in the x-z plane by specifying a + center Point, the width, and the height: + +

     Rectangle r(origin, 2, 3);
+      r.draw();
+ 
+

+
+ [Figure 27. Not displayed.] +
+
+ Fig. 27. +
+

+ +

Three additional arguments can be used to specify rotation about the x, + y, and z-axes respectively: + +

     Rectangle r(origin, 2, 3, 30, 45, 15);
+      r.draw();
+ 
+

+
+ [Figure 28. Not displayed.] +
+
+ Fig. 28. +
+

+ +

If a Point p other than the origin is specified as the center of + the Rectangle, the latter is first created in the x-z plane, + centered about the origin, as above. Then, any rotations specified are + performed. Finally, the Rectangle is shifted such that its center + comes to lie at p: + +

     Point p0(.5, 1, 3);
+      Rectangle r(p0, 4, 2, 30, 30, 30);
+      r.draw();
+ 
+

+
+ [Figure 29. Not displayed.] +
+
+ Fig. 29. +
+

+ +

This constructor has a corresponding setting function: + +

     Rectangle r;
+      for (int i = 0; i < 180; i += 30)
+        {
+          r.set(origin, 4, 2, i);
+          r.draw();
+        }
+ 
+

+
+ [Figure 30. Not displayed.] +
+
+ Fig. 30. +
+

+ +

Rectangles can also be specified using four Points as + arguments, whereby they must be ordered so that they are contiguous in + the resulting Rectangle: + +

     Point pt[4];
+      pt[0].shift(-1, -2);
+      pt[2] = pt[1] = pt[0];
+      pt[1].rotate(180);
+      pt[3] = pt[1];
+      pt[2] *= pt[3].rotate(0, 180);
+      Rectangle r(pt[0], pt[2], pt[3], pt[1]);
+      r.draw();
+ 
+

+
+ [Figure 31. Not displayed.] +
+
+ Fig. 31. +
+

+ +

This constructor checks whether the Point arguments are coplanar, + however, it does not check whether they are really the corners of a + valid rectangle; the user, or the code that calls this function, must + ensure that they are. In the following + example, r, although not rectangular, is a Rectangle, as + far as 3DLDF is concerned: + +

     pt[0].shift(0, -1);
+      pt[3].shift(0, 1);
+      Rectangle q(pt[0], pt[2], pt[3], pt[1]);
+      q.draw();
+ 
+

+
+ [Figure 32. Not displayed.] +
+
+ Fig. 32. +
+

+ +

This constructor is not really intended to be used directly, but should + mostly be called from within other functions, that should ensure that + the arguments produce a rectangular Rectangle. There is also no + guarantee that transformations or other functions called on + Rectangle, Circle, or other classes representing + geometric figures won't cause them to become non-rectangular, + non-circular, or otherwise irregular. Sometimes, this might even be + desirable. I plan to add the function + Rectangle::is_rectangular() soon, so that users can test + Rectangles for rectangularity. + +

+ +


+ Next: , + Previous: Rectangles Getstart, + Up: Plane Figures + +
+ +

7.3 Ellipses

+ +

Ellipse has a constructor similar to those for + Reg_Polygon and Rectangle. The first argument is the + center of the Ellipse, and the following two specify the lengths + of the horizontal and vertical axes respectively. The Ellipse is + first created in the x-z plane, centered about the origin. The + horizontal axis lies along the x-axis and the vertical axis lies along + the z-axis. The three subsequent arguments specify the amounts of + rotation about the x, y, and z-axes respectively and default to 0. + Finally, + Ellipse is shifted such that its center comes to lie at the + Point specified in the first argument. + +

     Point pt(-1, 1, 1);
+      Ellipse e(pt, 3, 6, 90);
+      e.draw();
+ 
+

+
+ [Figure 33. Not displayed.] +
+
+ Fig. 33. +
+

+ +

As you may expect, this constructor has a corresponding setting + function: + + +

     Ellipse e;
+      real h_save = 1.5;
+      real v_save = 2;
+      real h = h_save;
+      real v = v_save;
+      Point p(-1);
+      for (int i = 0; i < 5; ++i)
+        {
+            e.set(p, h, v, 90);
+            e.draw();
+            h_save += .25;
+            v_save += .25;
+            h *= sqrt(h_save);
+            v *= sqrt(v_save);
+            p.shift(0, 0, 2);
+        }
+ 
+

+
+ [Figure 34. Not displayed.] +
+
+ Fig. 34. +
+

+ +
+ +


+ Previous: Ellipses Getstart, + Up: Plane Figures + +
+ +

7.4 Circles

+ +

Circles are constructed just like Ellipses, except that + the vertical and horizontal axes are per definition the same, so + there's only one argument for the diameter, instead of two for the + horizontal and vertical axes: + +

     Point P(0, 2, 1);
+      Circle c(P, 3.5, 90, 90);
+      c.draw();
+ 
+

+
+ [Figure 35. Not displayed.] +
+
+ Fig. 35. +
+

+ +

This constructor, too, has a corresponding setting function: + +

     Circle c;
+      Point p(-1, 0, 5);
+      for (int i = 0; i < 16; ++i)
+        {
+            c.set(p, 5, i * 22.5, 0, 0, 64);
+            c.draw();
+        }
+ 
+

+
+ [Figure 36. Not displayed.] +
+
+ Fig. 36. +
+

+ +

In the preceding example, the last argument to set(), namely “64”, + is for the number of Points used for constructing the perimeter + of the Circle. The default value is 16, however, if it is used, + foreshortening distorts the most nearly horizontal Circle. + Increasing the number of points used improves its appearance. However, + there may be a limit to how much improvement is possible. + See Accuracy. + + + + + + + +

+ +


+ Next: , + Previous: Plane Figures, + Up: Top + +
+ +

8 Solid Figures

+ + + +
+ +


+ Next: , + Previous: Solid Figures, + Up: Solid Figures + +
+ +

8.1 Cuboids

+ +

A cuboid is a solid figure consisting of six rectangular faces + that meet at right angles. A cube is a special form of cuboid, whose + faces are all squares. The constructor for the class Cuboid + follows the pattern familiar from the constructors for the plane + figures: The first argument is the center of the Cuboid, + followed by three real arguments for the height, width, and + depth, and then three more real arguments for the angles of + rotation about the x, y, and z-axes. The Cuboid is first + constructed with its center at the origin. Its width, height, and depth + are measured along the x, y, and z-axes respectively. If rotations are + specified, it is rotated about the x, y, z-axes in that order. Finally, + it is shifted such that its center comes to lie on its Point + argument, if the latter is not the origin. + +

If the width, height, and depth arguments are equal, the Cuboid + is a cube: + +

     Cuboid c0(origin, 3, 3, 3, 0, 30);
+      c0.draw();
+ 
+

+
+ [Figure 37. Not displayed.] +
+
+ Fig. 37. +
+

+ +

In the following example, the Cuboid is “filldrawn”, so that + the lines dilineating the hidden surfaces of the Cuboid are + covered. + +

     Cuboid c1(origin, 3, 4, 5, 0, 30);
+      c1.filldraw();
+ 
+

+
+ [Figure 38. Not displayed.] +
+
+ Fig. 38. +
+

+ +
+ +


+ Previous: Cuboid Getstart, + Up: Solid Figures + +
+ +

8.2 Polyhedron

+ +

The class Polyhedron is meant for use only as a base class; + no objects of type Polyhedron should be declared. Instead, there + is a class for each of the different drawable polyhedra. Currently, + 3DLDF defines only three: Tetrahedron, Dodecahedron, and + Icosahedron. There's no need for a Cube class, because + cubes can be drawn using Cuboid (see Cuboid Getstart). + +

Polyhedra have a high priority in my plans for 3DLDF. + I intend to add Octahedron soon, which will complete the set of regular + Platonic polyhedra. Then I will begin adding the semi-regular + Archimedean polyhedra, and their duals. + +

The constructors for the classes derived from Polyhedron follow + the pattern familiar from the classes already described. The constructors + for the classes described below have identical arguments: First, a + Point specifying the center, then a real for the + diameter of the surrounding circle (Umkreis, in German) of one of + its polygonal faces, followed by three + real arguments for the angles of rotation about the main axes. + +

+ +
+ +


+ Next: , + Previous: Polyhedron Getstart, + Up: Polyhedron Getstart + +
+ +

8.2.1 Tetrahedron

+ +

The center of a tetrahedron is the intersection of the lines from a + vertex to the center of the opposite side. At least, in 3DLDF, this is + the center of a Tetrahedron. I'm not 100 degrees + certain + that this is mathematically correct. + +

     Tetrahedron t(origin, 4);
+      t.draw();
+      t.get_center().dotlabel("$c$");
+ 
+

+
+ [Figure 39. Not displayed.] +
+
+ Fig. 39. +
+

+ +
+ +


+ Next: , + Previous: Tetrahedron Getstart, + Up: Polyhedron Getstart + +
+ +

8.2.2 Dodecahedron

+ +

A dodecahedron has 12 similar regular pentagonal faces. + The following examples show the same Dodecahedron using different + projections: + +

     default_focus.set(2, 5, -10, 2, 5, 10, 10);
+      Dodecahedron d(origin, 3);
+      d.draw();
+ 
+

+
+ [Figure 40. Not displayed.] +
+
+ Fig. 40. +
+

+ + +

+
+ [Figure 41. Not displayed.] +
+
+ Fig. 41. +
+

+ + +

Please note that the Dodecahedron in [next figure] + is drawn, and not + filldrawn! + +

+
+ [Figure 42. Not displayed.] +
+
+ Fig. 42. +
+

+ + +

+
+ [Figure 43. Not displayed.] +
+
+ Fig. 43. +
+

+ + +

In [next figure] + , d is filldrawn. In this case, + the surface hiding algorithm has worked properly. + See Surface Hiding. + +

+
+ [Figure 44. Not displayed.] +
+
+ Fig. 44. +
+

+ +
+ +


+ Previous: Dodecahedron Getstart, + Up: Polyhedron Getstart + +
+ +

8.2.3 Icosahedron

+ +

An icosahedron has 20 similar regular triangular faces. + The following examples show the same Icosahedron using different + projections: + +

     default_focus.set(3, 0, -10, 2, 0, 10, 10);
+      Icosahedron i(origin, 3);
+      i.draw();
+ 
+

+
+ [Figure 45. Not displayed.] +
+
+ Fig. 45. +
+

+ + +

+
+ [Figure 46. Not displayed.] +
+
+ Fig. 46. +
+

+ + +

+
+ [Figure 47. Not displayed.] +
+
+ Fig. 47. +
+

+ + +

+
+ [Figure 48. Not displayed.] +
+
+ Fig. 48. +
+

+ + +

In [next figure] + , i is filldrawn. In this case, + the surface hiding algorithm has worked properly. + See Surface Hiding. + +

+
+ [Figure 49. Not displayed.] +
+
+ Fig. 49. +
+

+ + + + + + + +
+ +


+ Next: , + Previous: Solid Figures, + Up: Top + +
+ +

9 Pictures

+ +

Applying drawing and filling operations to the drawable objects described + in the previous chapters isn't enough to produce output. These + operations merely modify the Picture object that was passed to + them as an argument (current_picture, by default). + +

Pictures in 3DLDF are quite different from pictures in + MetaPost. + When a drawing or filling operation is applied to an object O, a + copy of O, C, is allocated on the free store, a pointer to + Shape S is pointed at C, and S is pushed onto + the vector<Shape*> shapes on the Picture P, which + was passed as an argument to the drawing or filling command. The + arguments for the pen, + dash pattern, Color, and any others, are used to set the + corresponding data members of C (not O). + +

In order to actually + cause MetaPost code to be written to the output file, it is necessary + to invoke P.output(). Now, the appropriate version of + output() is applied to each of the objects pointed to + by a pointer on P.shapes. output() is a pure + virtual function in Shape, so all classes derived from + Shape must have an output() function. So, if + shapes[0] points to a Path, + Path::output() is called, if + shapes[1] points to a Point, + Point::output() is called, and if shapes[2] points to an + object of a type derived from Solid, Solid::output() is + called. + Point, Path, and Solid are namely the only classes + derived from Shape for which a version of output() is defined. All + other Shapes are derived from one of these classes. + These output() + functions then write the MetaPost code to the + output file through the output file stream out_stream. + +

     beginfig(1);
+      default_focus.set(0, 0, -10, 0, 0, 10, 10);
+      Circle c(origin, 3, 90);
+      c.draw();
+      c.shift(1.5);
+      c.draw();
+      current_picture.output();
+      endfig(1);
+ 
+

+
+ [Figure 50. Not displayed.] +
+
+ Fig. 50. +
+

+ +

The C++ + code for [the previous figure] + starts with the command + beginfig(1) and ends with the command + endfig(1). + They simply write “beginfig(<arg> + )” and + “endfig()” to + out_stream, + The optional + unsigned int argument to endfig() is not written to + out_stream, it's merely + “syntactic sugar” for the user. + + + +

In MetaPost, the endfig command causes output and then clears + currentpicture. This is not the case in 3DLDF, where + Picture::output() and Picture::clear() must + be invoked explicitly: + +

     beginfig(1);
+      Point p0;
+      Point p1(1, 2, 3);
+      p0.draw(p1);
+      current_picture.output();
+      endfig(1);
+      
+      beginfig(2);
+      current_picture.clear();
+      Circle C(origin, 3);
+      C.fill();
+      current_picture.output();
+      endfig(2);
+ 
+

In [next figure] + , two Pictures are used within a single figure. + +

     beginfig(1);
+      Picture my_picture;
+      default_focus.set(0, 0, -10, 0, 0, 10, 10);
+      Circle c(origin, 3, 90);
+      c.draw(my_picture);
+      my_picture.output();
+      c.shift(1.5);
+      c.fill(light_gray);
+      current_picture.output();
+      endfig(1);
+ 
+

+
+ [Figure 51. Not displayed.] +
+
+ Fig. 51. +
+

+ +

Multiple objects, or complex objects made up of sub-objects, can be + stored in a Picture, so that operations can be applied to them + as a group: + +

     default_focus.set(7, 5, -10, 7, 5, 10, 10);
+      Cuboid c0(origin, 5, 5, 5);
+      c0.shift(0, 0, 3);
+      c0.draw();
+      Circle z0(c0.get_rectangle_center(0), 2.5, 90, 0, 0, 64);
+      z0.draw();
+      Circle z1(z0);
+      z1.shift(0, 0, -1);
+      z1.draw();
+      int i;
+      int j = z0.get_size();
+      for (i = 0; i < 8; ++i)
+          z0.get_point(i * j/8).draw(z1.get_point(i * j/8));
+      Cuboid c1(c0.get_rectangle_center(4), 5, 3, 3);
+      c1.shift(0, 2.5);
+      c1.draw();
+      Rectangle r0 = *c1.get_rectangle_ptr(3);
+      Point p[10];
+      for (i = 0; i < 4; ++i)
+        p[i] = r0.get_point(i);
+      p[4] = r0.get_mid_point(0);
+      p[5] = r0.get_mid_point(2);
+      p[6] = p[4].mediate(p[5], 2/3.0);
+      Circle z2(p[6], 2, 90, 90, 0, 16);
+      z2.draw();
+      Circle z3 = z2;
+      z3.shift(3);
+      z3.draw();
+      j = z2.get_size();
+      for (i = 0; i < 8; ++i)
+          z2.get_point(i * j/8).draw(z3.get_point(i * j/8));
+      p[7] = c0.get_rectangle_center(2);
+      p[7].shift(-4);
+      p[8] = c0.get_rectangle_center(3);
+      p[8].shift(4);
+      current_picture.output();
+      current_picture.rotate(45, 45);
+      current_picture.shift(10, 0, 3);
+      current_picture.output();
+ 
+

+
+ [Figure 52. Not displayed.] +
+
+ Fig. 52. +
+

+ +

Let's say the complex object in [the previous figure] + represents a + furnace. From the point of view of 3DLDF, however, it's not an object + at all, and the drawing consists of a collection of unrelated + Cuboids, Circles, Rectangles, and Paths. + If we hadn't put it into a Picture, we could still have rotated + and shifted it, but only by applying the operations to each of the + sub-objects individually. + +

One consequence of the way Pictures are output in 3DLDF is, that + the following code will not work: + +

     beginfig(1);
+      Point p(1, 2);
+      Point q(1, 3);
+      out_stream << "pickup pencircle scaled .5mm;" << endl;
+      origin.draw(p);
+      out_stream << "pickup pensquare xscaled .3mm rotated 30;" << endl;
+      origin.draw(q);
+      current_picture.output();
+      endfig();
+ 
+

This is the MetaPost code that results: + +

     beginfig(1);
+      pickup pencircle scaled .5mm;
+      pickup pensquare xscaled .3mm rotated 30;
+      draw (0.000000cm, -3.000000cm) -- (1.000000cm, -1.000000cm);
+      draw (0.000000cm, -3.000000cm) -- (1.000000cm, 0.000000cm);
+      endfig;
+ 
+

It's perfectly legitimate to write + raw MetaPost code to out_stream, as in lines 4 and 6 of this + example. However, the draw() commands do not cause any output to + out_stream. The MetaPost drawing commands are written to + out_stream when current_picture.output() is called. + Therefore, the pickup commands are “bunched up” before the + drawing commands. + In this example, + setting currentpen to pencircle scaled .5mm has no effect, + because it is immediately reset to + pensquare xscaled .3mm rotated 30 in the MetaPost code, before + the draw commands. + It is not possible to change currentpen in this way within a + Picture. + Since the draw() commands in the 3DLDF + code didn't specify a pen argument, + currentpen with its final value is used for both of the MetaPost + draw commands. For any given invocation of + Picture::output(), there can only be one value of + currentpen. All other pens must be passed as arguments to the + drawing commands. + +

+ +
+ +


+ Next: , + Previous: Pictures, + Up: Pictures + +
+ +

9.1 Projections

+ +

In order for a 3D graphic program to be useful, it must be able to + make two-dimensional projections of its three-dimensional constructions + so that they + can be displayed on computer screens and printed out. + These are some of the possible projections: + +

+
• Parallel projection onto one of the major planes
These projections are trivial, and can be performed by 3DLDF. They are + discussed in the following section. + +
• Parallel projection onto another plane
+ I haven't programmed these projections yet, but they might be useful, so + I probably will, when I get around to it. + +
• The perspective projection
This is the projection most people think of, when they think of + 3D-graphics. It is discussed in + detail in The Perspective Projection. + +
• The isometric and axonometric projections
+ These projections are important for engineering and drafting. I have + not yet implemented them in 3DLDF, but they are on my list of “Things + To Do”. + +
+ +

The function Picture::output() takes a const unsigned + short argument specifying the projection to be used. The user should + probably avoid using explicit unsigned shorts, but should use the + constants defined for this purpose in the + namespace Projections.19 + The constants are PERSP, PARALLEL_X_Y, + PARALLEL_X_Z, + PARALLEL_Z_Y, AXON, and ISO. The latter two should + not be used, because the axonometric and isometric projections have not + yet been implemented. + +

+ +
+ +


+ Next: , + Previous: Projections, + Up: Projections + +
+ +

9.1.1 Parallel Projections

+ +

When a Picture is projected onto the x-y plane, the + x and y-values from the world_coordinates of the Points + belonging to the objects on the + Picture are copied to + their projective_coordinates, which are + used in the MetaPost code written to out_stream. + If a Picture p contains an object in the x-y plane, + or in a plane parallel to the x-y plane, then + the result of p.output(Projections::PARALLEL_X_Y) is more-or-less + equivalent to just using MetaPost without 3DLDF. + +

     Rectangle r(origin, 3, 3, 90);
+      Circle c(origin, 3, 90);
+      c *= r.shift(0, 0, 5);
+      r.draw();
+      c.draw();
+      current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 53. Not displayed.] +
+
+ Fig. 53. +
+

+ +

If the objects do not lie in the x-y plane, or a plane parallel to the + x-y plane, then the projection will be distorted: + +

     current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 54. Not displayed.] +
+
+ Fig. 54. +
+

+ +

Picture::output() can be called with an additional real + argument factor for magnifying or shrinking the Picture. + + + +

     Rectangle r(origin, 4, 4, 90, 60);
+      Circle c(origin, 4, 90, 60);
+      c *= r.shift(0, 0, 5);
+      r.filldraw(black, gray);
+      c.unfilldraw(black);
+      current_picture.output(Projections::PARALLEL_X_Y, .5);
+      current_picture.shift(2.5);
+      current_picture.output(Projections::PARALLEL_X_Y);
+      current_picture.shift(1);
+      current_picture.output(Projections::PARALLEL_X_Y, 2);
+ 
+

+
+ [Figure 55. Not displayed.] +
+
+ Fig. 55. +
+

+ +

Parallel projection onto the x-z and z-y planes are completely analogous + to parallel projection onto the x-y plane. + +

+ +


+ Previous: Parallel Projections, + Up: Projections + +
+ +

9.1.2 The Perspective Projection

+ +

The perspective projection obeys the laws of + linear perspective. + In 3DLDF, it is performed by means of a + transformation, whose effect is, to the + best of my knowledge, + exactly equivalent to the result of a perspective projection done by + hand using vanishing points and rulers. + +

It is very helpful to the artist to understand the laws of linear + perspective, and to know how to make a perspective drawing by hand.20 + However, it is a very tedious and error-prone procedure (I know, I've + done it). One of my main motivations for writing 3DLDF was so I + wouldn't have to do it anymore. + + + + + + +

[next figure] + shows a perspective construction, the way it + could be done by hand. + The point of view, or focus is located 6cm from + the picture plane, and 4cm above the ground (or x-z) plane at the point + (0, 4, -6). + The rectangle R lies in the ground plane, with the point r_0 at + (2, 0, 1.5). The right side of R, with length = 2cm + lies at an angle + of 40 to the ground line, which corresponds to the intersection line + of the ground plane with the picture plane, and the left side, with + length = 5cm, at an angle of + 90 degrees - 40 degrees = 50 degrees + to the ground line. + + + +

+
+ [Figure 56. Not displayed.] +
+
+ Fig. 56. +
+

+ +

While it's possible to use 3DLDF to make a perspective construction + in the traditional way, as [the previous figure] + shows, the code for [next figure] + +

achieves the same result more efficiently: + +

     default_focus.set(0, 4, -6, 0, 4, 6, 6);
+      Rectangle r(origin, 2, 5, 0, 40);
+      Point p(2, 0, 1.5);
+      r.shift(p - r.get_point(0));
+      r.draw();
+ 
+

+
+ [Figure 57. Not displayed.] +
+
+ Fig. 57. +
+

+ +

In [the second-to-last figure] + , it was + convenient to start with the corner point r_0; + if we needed the center of R, it would have to be found from the + corner points. + However, in 3DLDF, Rectangles are most often constructed about + the center. Therefore, in [next figure] + , R is first + constructed about the origin, with the + rotation about the y-axis passed as an argument to the constructor. + It is then shifted such that *(R.points[0]), the first + (or zeroth, if you will) Point on R comes to lie at + (2, 0, 1.5). + +

Unlike the other transformations currently + used in 3DLDF, the perspective transformation is non-affine. Affine + transformations maintain parallelity of lines, while the rules of + perspective state that parallel lines, with one exception, appear to + recede toward a + + + + vanishing point.21 + +

In [the second-to-last figure] + , the lines + from r_0 to r_1 and from r_3 to r_2 + appear to vanish + toward the right-hand 40 degrees + vanishing point, while + the lines from r_0 to r_3 and from r_1 to r_2 + appear to vanish + toward the left-hand 50 degrees + vanishing point. + The lower the angle of a + vanishing point, the further away it is from the center of vision, as + [next figure] + shows: + +

+
+ [Figure 58. Not displayed.] +
+
+ Fig. 58. +
+

+ +

In [the previous figure] + , the 0.5 degrees + vanishing point is nearly + 5 and 3/4 + meters away from the CV, and a + line receding to it will be very + nearly horizontal. However, the distance from the focus to the CV is + only 5cm. As this distance increases, the distance from the + CV to a given vanishing point increases proportionately. + If the distance is 30cm, a more reasonable value + for a drawing, then the x-coordinate of VP 10 degrees + is 170.138cm, that + of VP 5 degrees + is 342.902cm, and that of VP 0.5 degrees + is 3437.66cm! + This is the reason + why perspective drawings done by hand rarely contain lines receding to + the horizon at low angles. + +

This problem doesn't arise when the perspective transformation is + used. In this case, any angle can be calculated as easily as any other: + +

     default_focus.set(0, 4, -6, 0, 4, 6, 6);
+      Rectangle r;
+      Point center(0, 2);
+      r.set(center, 2, 5, 0, 0, 0.5);
+      r.draw();
+      
+      r.set(center, 2, 5, 0, 0, 2.5);
+      r.draw();
+      
+      r.set(center, 2, 5, 0, 0, 5);
+      r.draw();
+      current_picture.output();
+ 
+

+
+ [Figure 59. Not displayed.] +
+
+ Fig. 59. +
+

+ +
+ +


+ Next: , + Previous: Projections, + Up: Pictures + +
+ +

9.2 Focuses

+ +

The perspective transformation requires a focus; as a consequence, + outputting a Picture requires an object of class + Focus. + Picture::output() takes an optional pointer-to-Focus + argument, which is 0 by default. If the default is used, (or 0 is + passed explicitly), the global variable default_focus is used. + See Focus Reference; Global Variables. + +

A Focus can be thought of as the observer of a scene, or a + camera. It contains a Point position for its location with + respect to 3DLDF's coordinate system, and a Point direction, + specifying the direction where the observer is looking, or where the + camera is pointed. The Focus can be rotated freely about the + line + PD, + where P stands for position and + D + for direction, + so a Focus contains a third Point up, to indicate which + direction will be “up” on the projection, when a Picture is + projected. + +

The projection plane q + will always be perpendicular to + the line PD, + or to put it another way, + the line PD, + is normal to q. + +

Unlike the traditional perspective construction, where the distance from + the focus to the center of vision fixes both the location of the focus + in space, and its distance to the + picture plane,22 + these two parameters can be set independently when the perspective + transformation is used. + The distance from a Focus to the picture plane is stored in the + data member distance, of type real. + +

A Focus can be declared using two Point arguments for + position and direction, and a real argument for + distance, in that order. + +

     Point pos(0, 5, -10);
+      Point dir(0, 5, 10);
+      Focus f(pos, dir, 10);
+      
+      Point center(2, 0, 3);
+      Rectangle r(center, 3, 3);
+      r.draw();
+      current_picture.output(f);
+ 
+

+
+ [Figure 60. Not displayed.] +
+
+ Fig. 60. +
+

+ +

The “up” direction is calculated by the Focus constructor + automatically. An optional argument can be used to specify the angle by + which to rotate the Focus about + the line PD. + +

     Point pos(0, 5, -10);
+      Point dir(0, 5, 10);
+      Focus f(pos, dir, 10, 30);
+      Point center(2, 0, 3);
+      Rectangle r(center, 3, 3);
+      r.draw();
+      current_picture.output(f);
+ 
+

+
+ [Figure 61. Not displayed.] +
+
+ Fig. 61. +
+

+ +

Alternatively, a Focus can be declared using three real + arguments each for the x, y, and z-coordinates of position and + direction, respectively, followed by the real arguments + for distance and the angle of rotation: + +

     Focus f(3, 5, -5, 0, 3, 0, 10, 10);
+      Point center(2, 0, 3);
+      Rectangle r(center, 3, 3);
+      r.draw();
+      current_picture.output(f);
+ 
+

+
+ [Figure 62. Not displayed.] +
+
+ Fig. 62. +
+

+ +

Focuses contain two Transforms, transform and persp. + A Focus can be located anywhere in 3DLDF's coordinate system. + However, performing the perspective projection is more convenient, if + position and direction both lie on one of the major axes, + and the plane of projection corresponds to one of the major planes. + transform is the transformation which would have this affect on + the Focus, and is calculated by the Focus constructor. + When a Picture is output using that Focus, + transform is applied to all of the Shapes on the + Picture, maintaining the relationship between the Focus + and the Shapes, while making it easier to calculate the + projection. The Focus need never be + transformed by transform. + The actual perspective transformation is stored + in persp. + +

Focuses can be moved by using one of the setting functions, which + take the same arguments as the constructors. + + Currently, there are no affine transformation functions for moving + Focuses, but I plan to add them soon. If 3DLDF is used for + making + animation, resetting the Focus can be used to simulate camera + movements: + +

     beginfig(1);
+      Point pos(2, 10, 3);
+      Point dir(2, -10, 3);
+      Focus f;
+      Point center(2, 0, 3);
+      for (int i = 0; i < 5; ++i)
+        {
+          f.set(pos, dir, 10, (15 * i));
+          Rectangle r(center, 3, 3);
+          r.draw();
+          current_picture.output(f);
+          current_picture.clear();
+          pos.shift(1, 1, 0);
+          dir.rotate(0, 0, 10);
+        }
+      endfig(1);
+ 
+

+
+ [Figure 63. Not displayed.] +
+
+ Fig. 63. +
+

+ +

In [the previous figure] + , current_picture is output 5 times within a single + MetaPost figure. Since the file passed to MetaPost is called + persp.mp, the file of Encapsulated PostScript (EPS) code + containing [the previous figure] + is called persp.1. + To use this technique for making an animation, it's necessary to output + the Picture into multiple MetaPost figures. + +

     Point pos(2, 10, 3);
+      Point dir(2, -10, 3);
+      Focus f;
+      Point center(2, 0, 3);
+      for (int i = 0; i < 5; ++i)
+        {
+          f.set(pos, dir, 10, (15 * i));
+          Rectangle r(center, 3, 3);
+          r.draw();
+          beginfig(i+1);
+          current_picture.output(f);
+          endfig();
+          current_picture.clear();
+          pos.shift(1, 1, 0);
+          dir.rotate(0, 0, 10);
+        }
+ 
+

Now, running MetaPost on persp.mp generates the EPS files + persp.1, persp.2, persp.3, persp.4, and + persp.5, containing the five separate drawings of r. + + + +

+ +


+ Previous: Focuses Getstart, + Up: Pictures + +
+ +

9.3 Surface Hiding

+ + + + +

In [next figure] + , Circle c lies in front of Rectangle + r. + Since c is drawn and not filled, r is visible behind + c. + +

     default_focus.set(1, 3, -5, 0, 3, 5, 10);
+      Point p(0, -2, 5);
+      Rectangle r(p, 3, 4, 90);
+      r.draw();
+      Point q(2, -2, 3);
+      Circle c(q, 3, 90);
+      c.draw();
+      current_picture.output();
+ 
+

+
+ [Figure 64. Not displayed.] +
+
+ Fig. 64. +
+

+ +

If instead, c is filled or filldrawn, only the parts of r that are not + covered by c should be visible: + +

     r.draw();
+      c.filldraw();
+ 
+

+
+ [Figure 65. Not displayed.] +
+
+ Fig. 65. +
+

+ +

What parts of r are covered depend on the point of view, i.e., + the position and direction of the Focus used for outputting the + Picture: + +

     default_focus.set(8, 0, -5, 5, 3, 5, 10);
+ 
+

+
+ [Figure 66. Not displayed.] +
+
+ Fig. 66. +
+

+ +

Determining what objects cover other objects in a program for 3D + graphics is called + surface hiding, + and is performed by a + hidden surface algorithm. 3DLDF currently has a very primitive + hidden surface algorithm that only works for the most simple cases. + +

The hidden surface algorithm used in 3DLDF is a + painter's algorithm, which means that the objects that are + furthest away from the Focus are drawn first, followed by the + objects that are closer, which may thereby cover them. In order to make + this possible, the Shapes on a Picture must be sorted + before they are output. They are sorted according to the z-values in + the projective_coordinates of the Points belonging to the + Shape. This may seem strange, since the + projection is two-dimensional and only the x and y-values from + projective_coordinates are written to out_stream. + However, the perspective transformation also produces a z-coordinate, + which indicates the distance of the Points from the Focus + in the z-dimension. + +

The problem is, that all Shapes, except Points themselves, + consist of multiple Points, that may have different + z-coordinates. 3DLDF currently does not yet have a satisfactory way of + dealing with this situtation. In order to try to cope with it, the user + can specify four different ways of sorting the Shapes: They + can be sorted according to the maximum z-coordinate, the + minimum z-coordinate, the mean of the maximum and minimum z-coordinate + (max + min) / 2, + and not sorted. + In the last case, the Shapes are output in the order of the + drawing and filling commands in the user code. + The z-coordinates referred to are those in + projective_coordinates, and will have been calculated for a + particular Focus. + +

The function Picture::output() takes a + const unsigned short sort_value argument that specifies + which style of sorting + should be used. The namespace Sorting contains the following + constants which should be used for sort_value: MAX_Z, + MIN_Z, MEAN_Z, and NO_SORT. The default is + MAX_Z. + +

3DLDF's primitive hidden surface algorithm cannot work for + objects that intersect. The following examples demonstrate why not: + +

     using namespace Sorting;
+      using namespace Colors;
+      using namespace Projections;
+      default_focus.set(5, 3, -10, 3, 1, 1, 10, 180);
+      Rectangle r0(origin, 3, 4, 45);
+      Rectangle r1(origin, 2, 6, -45);
+      r0.draw();
+      r1.draw();
+      current_picture.output(default_focus, PERSP, 1, MAX_Z);
+      r0.show("r0:");
+      -| r0:
+      fill_draw_value == 0
+      (-1.5, -1.41421, -1.41421) -- (1.5, -1.41421, -1.41421) --
+      (1.5, 1.41421, 1.41421) -- (-1.5, 1.41421, 1.41421)
+      -- cycle;
+      
+      r0.show("r0:", 'p');
+      -| r0:
+      fill_draw_value == 0
+      Perspective coordinates.
+      (-5.05646, -4.59333, -0.040577) -- (-2.10249, -4.86501, -0.102123) --
+      (-1.18226, -1.33752, 0.156559) -- (-3.51276, -1.2796, 0.193084)
+      -- cycle;
+      
+      r1.show("r1:");
+      -| r1:
+      fill_draw_value == 0
+      (-1, 2.12132, -2.12132) -- (1, 2.12132, -2.12132) --
+      (1, -2.12132, 2.12132) -- (-1, -2.12132, 2.12132)
+      -- cycle;
+      
+      r1.show("r1:", 'p');
+      -| r1:
+      fill_draw_value == 0
+      Perspective coordinates.
+      (-5.09222, -0.995681, -0.133156) -- (-2.98342, -1.03775, -0.181037) --
+      (-1.39791, -4.05125, 0.208945) -- (-2.87319, -3.93975, 0.230717)
+      -- cycle;
+ 
+

+
+ [Figure 67. Not displayed.] +
+
+ Fig. 67. +
+

+ +

In [the previous figure] + , the Rectangles r_0 and r_1 intersect along the + x-axis. The z-values of the world_coordinates of r_0 are + -1.41421 and 1.41421 (two Points each), while those of r_1 + are 2.12132 and -2.12132. So r_1 has two Points with + z-coordinates greater than the z-coordinate of any Point + on r_0, and two Points with z-coordinates less than the + z-coordinate of any Point on r_0. The + Points on r_0 and r_1 all have different z-values in + their projective_coordinates, but r_1 still has a Point + with a z-coordinate greater than that of any of the Points on + r_0, and one with a z-coordinate less than that of any of the + Points on r_0. + +

In [next figure] + , the Shapes on current_picture are sorted + according to the maximum z-values of the projective_coordinates + of the Points belonging to the Shapes. r_1 is + filled and drawn first, + because it has the Point with the positive z-coordinate of + greatest magnitude. + When subsequently r_0 is drawn, it covers part of the top of + r_1, which lies in front of r_0, and should be visible: + +

     current_picture.output(default_focus, PERSP, 1, MAX_Z);
+ 
+

+
+ [Figure 68. Not displayed.] +
+
+ Fig. 68. +
+

+ +

In [next figure] + , the Shapes on current_picture are sorted + according to the minimum z-values of the projective_coordinates + of the Points belonging to the Shapes. r1 is drawn + and filled last, because + it has the Point with the negative z-coordinate of greatest + magnitude. + It thereby covers the bottom part of + r0, which lies in front of r1, and should be visible. + +

     current_picture.output(default_focus, PERSP, 1, MIN_Z);
+ 
+

+
+ [Figure 69. Not displayed.] +
+
+ Fig. 69. +
+

+ +

Neither sorting by the mean z-value in the + projective_coordinates, nor suppressing sorting does any good. + In each case, one Rectangle is always drawn and filled last, + covering parts of the other that lie in front of the first. + +

3DLDF's hidden surface algorithm will fail wherever objects intersect, + not just where one extends past the other in both the positive and + negative z-directions. + +

     Rectangle r(origin, 3, 4, 45);
+      Circle c(origin, 2, -45);
+      r.filldraw();
+      c.filldraw(black, gray);
+      current_picture.output(default_focus, PERSP, 1, NO_SORT);
+ 
+

+
+ [Figure 70. Not displayed.] +
+
+ Fig. 70. +
+

+ +

Even where objects don't intersect, their projections may. In order to + handle these cases properly, it is necessary to break up the + Shapes on a Picture into smaller Shapes, until + there are none that intersect or whose projections intersect. Then, any + of the three methods of sorting described above can be used to sort the + Shapes, and they can be output. + +

Before this can be done, 3DLDF must be able to find the intersections of + all of the different kinds of Shapes. If 3DLDF converted solids + to polyhedra and curves to sequences of line segments, this would reduce + to the problem of finding the intersections of lines and planes, however + it does not yet do this. + +

Even if it did, a fully functional hidden surface algorithm must compare + each Shape on a Picture with every other Shape. + Therefore, for n Shapes, there will be + n! / ((n - r)! r!) + (possibly time-consuming) comparisons. + +

+
+ [Figure 71. Not displayed.] +
+
+ Fig. 71. +
+

+ + + + +

Clearly, such a hidden surface + algorithm would considerably increase run-time. + +

Currently, all of the Shapes on a Picture are output, as + long as they lie completely within the boundaries passed as arguments to + Picture::output(). + See Pictures; Outputting. It + would be more efficient to suppress output for them, if they are + completely covered by other objects. This also requires comparisions, + and could be implemented together with a fully-functional hidden surface + algorithm. + +

Shadows, reflections, highlights and shading are all effects requiring + comparing each Shape with every other Shape, and could + greatly increase run-time. + + + + + + +

+ +


+ Next: , + Previous: Pictures, + Up: Top + +
+ +

10 Intersections

+ +

There are no functions for finding the intersection points of two (or + more) arbitrary Paths. This is impossible, so long as 3DLDF + outputs MetaPost code. + 3DLDF only “knows” about the Points on a + Path; it doesn't actually generate the curve or other figure + that passes through the Points, and consequently doesn't “know” + how it does this. + +

In addition, an arbitrary Path can contain connectors. + In 3DLDF, the connectors are + merely strings and are written verbatim to the output file, + however, in MetaPost they influence the form of a Path. + +

3DLDF can, however, find the intersection points of some + non-arbitrary Paths. So far, it can find the intersection + point of the following combinations of Paths: + +

+

    +
  1. Two linear Paths, i.e., Paths + for which Path::is_linear() returns true + (see Path Reference; Querying). + In addition, the static Point member function + Point::intersection_points() can be called with four Point + arguments. The first and second arguments are treated as the end points + of one line, and the third and fourth arguments as the end points of the + other. + +
  2. A line and a Polygon. Currently, Reg_Polygon and + Rectangle are the only classes derived from Polygon. + +
  3. Two Polygons. + +
  4. A line and a Regular Closed Plane Curve (Reg_Cl_Plane_Curve, + see Regular Closed Plane Curve Reference; Intersections). Currently, + Ellipse and Circle are the only classes derived from + Reg_Cl_Plane_Curve. + +
  5. Two Ellipses. Since a Circle is also an Ellipse, + one or both of the Ellipses may be a Circle. + See Ellipse Reference; Intersections. +
+ +

Adding more functions for finding the intersections of various geometric + figures is one of my main priorities with respect to extending 3DLDF. + +

There are currently no special + functions for finding the intersection points + of a line and a Circle or two Circles. Since the + class Circle is derived from class Ellipse, + Circle::intersection_points() resolves to + Ellipse::intersection_points(), which, in turn, calls + Reg_Cl_Plane_Curve::intersection_points(). + This does the trick, but it's much easier to find the intersections for + Circles that it is for Ellipses. In particular, the + intersections of two coplanar Circles can be found + algebraically, whereas I've had to implement a numerical solution for + the case of two coplanar Ellipses with different centers and/or + axis orientation. It may also be worthwhile to write + a specialization for + finding the intersection points of a Circle and an + Ellipse. + +

The theory of intersections is a fascinating and non-trivial branch of + mathematics.23 + As I learn more about it, I plan to define more + classes to represent various curves (two-dimensional ones to + start with) and functions for finding their intersection points. + + + + + + +

+ +


+ Next: , + Previous: Intersections, + Up: Top + +
+ +

11 Installing and Running 3DLDF

+ + + + + +

11.1 Installing 3DLDF

+ +

3DLDF is available for downloading from + http://ftp.gnu.org/gnu/3dldf. + The official 3DLDF website is + http://www.gnu.org/software/3dldf. + The “tarball”, i.e., the compressed archive file + 3DLDF-1.1.5.1.tar.gz unpacks into a directory called + /3DLDF-1.1.5.1/. + +

On a typical Unix-like system, entering the following commands + at the command line in a shell will unpack the 3DLDF distribution. + Please note that the form of the commands may differ on your system. + +

     gunzip 3DLDF-1.1.5.1.tar.gz
+      tar xpvf 3DLDF-1.1.5.1.tar
+ 
+

The ‘p’ option to tar ensures that the files will have + the same permissions as when they were packed. + +

The directory 3DLDF-1.1.5.1/ contains a + configure script, which should + be called from the command line in the shell, using the absolute path of + 3DLDF-1.1.5.1/ as the prefix argument. For example, if + the path is /usr/local/mydir/3DLDF-1.1.5.1/, + configure should be invoked as follows: + +

     cd 3DLDF-1.1.5.1
+      configure --prefix=/usr/local/mydir/3DLDF-1.1.5.1/
+ 
+

configure generates a Makefile + from the Makefile.in in 3DLDF-1.1.5.1/, and + in each of the subdirectories 3DLDF-1.1.5.1/CWEB, + 3DLDF-1.1.5.1/DOC, + and 3DLDF-1.1.5.1/DOC/TEXINFO. + Now, make install causes the 3DLDF to be built. + The executable is called 3dldf. + +

See the files README and INSTALL in the 3DLDF distribution + for more information. + +

+ +
+ +


+ Previous: Installing 3DLDF, + Up: Installing 3DLDF + +
+ +

11.1.1 Template Functions

+ +

3DLDF 1.1.5 is the first release that contains template functions, + namely + template <class C> C* create_new(), which is defined in + creatnew.web, and + template <class Real> Real get_second_largest(), which is defined + in gsltmplt.web. + See Dynamic Allocation of Shapes, and + Get Second Largest Real. + +

In order for template functions to be instantiated correctly, their + definitions must be available in each compilation unit where + specializations are declared or used. For non-template functions, it + suffices for their declarations to be available, and their + definitions are found at link-time. For this reason, the + definitions of create_new() and get_second_largest() are + in their own CWEB files, and are written to their own header files. The + latter are included in the other CWEB files that need them. + +

In addition, ‘AM_CXXFLAGS = -frepo’ has been added to the file + Makefile.am in 3DLDF-1.1.5/CWEB/, so that the C++ + +

compiler is called using the ‘-frepo’ option. + The manual Using and Porting the GNU Compiler + Collection explains this as follows: + +

+ “Compile your template-using code with ‘-frepo’. The compiler will + generate files with the extension .rpo listing all of the template + instantiations used in the corresponding object files which could be + instantiated there; the link wrapper, ‘collect2’, will then update the + .rpo files to tell the compiler where to place those instantiations and + rebuild any affected object files. The link-time overhead is negligible + after the first pass, as the compiler will continue to place the + instantiations in the same files.”24 +
+ +

The first time the executable 3dldf is built, the files that use + the template functions are recompiled one or more times, and the linker + is also called several times. This doesn't happen anymore, once the + .rpo files exist. + +

Template instantiation differs from compiler to compiler, so using + template functions will tend to make 3DLDF less portable. I am no + longer able to compile it on the DECalpha Personal Workstation I had + been using with the DEC C++ + compiler. + See Ports, for more information. + +

+ +


+ Previous: Installing 3DLDF, + Up: Installing and Running 3DLDF + +
+ +

11.2 Running 3DLDF

+ +

To use 3DLDF, call + make run from the command line in the + shell. The working directory should be + 3DLDF-1.1.5.1/ or 3DLDF-1.1.5.1/CWEB. + Either will work, but the latter may be more convenient, because + this is the location of the CWEB, TeX and MetaPost files that you'll + be editing. + Alternatively, call ldfr, which is merely a + shell script that calls make run. + This takes care of running 3dldf, MetaPost, TeX, + and dvips, producing a PostScript file containing your + drawings. You can display the latter on your terminal using Ghostview + or some other + PostScript viewer, print it out, and whatever else you like to do with + PostScript files. + +

However, you can also perform the actions performed by + make run by hand, by writing your own shell + scripts, by defining Emacs-Lisp commands, or in other ways. Even if you + choose to use make run, it's important to understand what it + does. The following explains how to do this by hand. + +

The CWEB source files for 3DLDF are in the subdirectory + 3DLDF-1.1.5.1/CWEB/. They + must be ctangled, and the resulting C++ + files must be + compiled and + linked, in order to create the executable file 3dldf. + The C++ + files and header files generated by ctangle, + the object files generated by the compiler, and the executable + 3dldf all reside in 3DLDF-1.1.5.1/CWEB/. Therefore, the + latter must be your working directory. + +

Since 3DLDF has no input routine as yet, + as explained in No Input Routine, + it is necessary to add C++ + code to the function main() in + main.web, and/or in a separate function in another file. In the + latter case, the function containing the user code must be invoked in + main(). Look for the line “Your code here!” in + main.web. + +

This is an example of what you could write in main(). + Feel free to make it more complicated, if you wish. + +

     beginfig(1);
+      default_focus.set(2, 3, -10, 2, 3, 10, 20);
+      Rectangle R(origin, 5, 3);
+      Circle C(origin, 3, 90);
+      C.half(180).filldraw(black, light_gray);
+      R.filldraw();
+      C.half().filldraw(black, light_gray);
+      Point p = C.get_point(4);
+      p.shift(0, -.5 * p.get_y());
+      p.label("$C$", "");
+      Point q = R.get_mid_point(0);
+      q.shift(0, 0, -.5 * q.get_z());
+      q.label("$R$", "");
+      current_picture.output(default_focus, PERSP, 1, NO_SORT);
+      endfig(1);
+ 
+

+
+ [Figure 72. Not displayed.] +
+
+ Fig. 72. +
+

+ +
    +
  1. Save main.web, and any other CWEB files you've changed. + Since these files have changed, they must be ctangled, and the + resulting C++ + files must be recompiled. If you've changed any files + other than + main.web, ctangle will also generate a header + file for each of these files. If a header file differs from the version + that existed before ctangle was run, all of the C++ + files + that depend on it must be recompiled. Then 3dldf must be + relinked. To do this, call make 3dldf from the command line. + +

    If you've made any errors in typing your code, the + compiler should have issued error messages, so go back into + the appropriate CWEB file and correct your errors. Then call + make 3dldf again. + +

  2. Call CWEB/3dldf at the command line. It writes a + file of MetaPost code called 3DLDFput.mp. + +
  3. Run MetaPost on the file 3DLDFmp.mp, which inputs + 3DLDFput.mp. + +
              mpost 3DLDFput
    + 
    +

    The result is an Encapsulated PostScript file + 3DLDFput.<integer> for each figure in your drawing. + +

  4. The file 3DLDFtex.tex should contain code for including the + 3DLDFput.<integer> files. This is an example taken from + the 3DLDFtex.tex included in the distribution. + You may change it to suit your purposes. + +
              \vbox to \vsize{\vskip 2cm
    +           \line{\hskip 2cm Figure 1.\hss}%
    +           \vfil
    +           \line{\hskip 2cm\epsffile{3DLDFmp.1}\hss}%
    +           \vss}
    + 
    +
  5. Run TeX on 3DLDFtex.tex to produce the DVI file, + 3DLDFtex.dvi. + +
              tex 3DLDFtex
    + 
    +
  6. Run dvips on the DVI file to produce the PostScript file, + 3DLDFtex.ps. + +
              dvips -o 3DLDFtex.ps 3DLDFtex
    + 
    +
  7. 3DLDFtex.ps can be viewed using Ghostview, it can be printed using + lpr (on a Unix-like system), you can convert it to PDF with + ps2pdf, or to some other format using the appropriate program. +
+ +

I sincerely hope that it worked. If it didn't, ask your local computer + wizard for help. + +

On the computer I'm using, I found that special arguments for + setting landscape and papersize in TeX files for + DIN A3 landscape didn't work. Ghostview cut off the right sides of the + drawings. Nor did it work to call + dvips -t landscape -t a3. + This caused an error message which said that + landscape would be ignored. When I called dvips + with the -t landscape option alone, it worked, and + Ghostview showed the entire drawing. + +

Another problem was Adobe Acrobat. It would display the entire DIN A3 + page, but not always in landscape format. I was unable to find a way of + rotating the pages in Acrobat. I finally found out, that if I included + even a single letter of text in a label, Acrobat would display the + document correctly. + +

+ +
+ +


+ Next: , + Previous: Running 3DLDF, + Up: Running 3DLDF + +
+ +

11.2.1 Converting EPS Files

+ +

ImageMagick is a + “collection of tools and libraries” for image manipulation. + It provides a `convert' utility which can convert images from one + format to another. It can convert structured PostScript (PS) to + to Portable Network Graphics (PNG), but not + EPS (Encapsulated PostScript) to PNG. Nor can it convert EPS to + structured PostScript. + +

It is possible to have MetaPost generate structured PostScript directly + by including the command ‘prologues:=1;’ at the beginning of the + MetaPost input. + However, this “generally doesn't work when you use TeX + fonts.”25 + This is a significant problem if your labels contain math mode + material, and you haven't already taken steps to ensure that appropriate + fonts will be used in the PS output. + +

In the following, I describe the only way I've found to convert + an EPS image to PNG format while still using TeX fonts. There may be + other and better ways of doing this, but I haven't found them. + +

    +
  1. Assume the EPS image is in the file 3DLDFmp.1 + Include the EPS image in a TeX file + which looks like this: + +
              \advance\voffset by -1in
    +           \advance\hoffset by -1in
    +           \nopagenumbers
    +           \input epsf
    +           \epsfverbosetrue
    +           \def\epsfsize#1#2{#1}
    +           \setbox0=\vbox{\epsffile{3DLDFmp.1}}
    +           \vsize=\ht0
    +           \hsize=\wd0
    +           \special{papersize=\the\wd0,\the\ht0}
    +           \box0
    +           \bye
    + 
    +

    Do not name this file 3DLDFmp.1.tex! + While this worked fine for me on a DECalpha Personal Workstation + running under Tru64 Unix 5.1, with TeX, Version 3.1415 + (C version 6.1), and dvipsk 5.58f, + it failed on a PC Pentium II XEON under Linux 2.4, + with TeX, Version 3.14159 (Web2C 7.4.5), and + dvips(k) 5.92b, kpathsea version 3.4.5, + with the following error message: +

              “No BoundingBox comment found in file examples.1; using defaults”
    + 
    +

    The resulting PS image had the wrong size and the + the graphic was positioned improperly. + +

    Apparently, it confuses the EPSF macros when the name of an + included image is the same as ‘\jobname’. + So, for this example, let's call it 3DLDFmp.1_.tex. + +

    You don't really need to call the macro ‘\epsfverbosetrue’. If you + do, it will print the measurements of the bounding box and other information + to standard output.26 + +

  2. Run ‘tex 3DLDFmp.1_.tex’. + +
  3. Run ‘dvips -o 3DLDF.1.ps 3DLDFmp.1_.dvi’. + +
  4. Run ‘convert 3DLDF.1.ps 3DLDFmp.1.png’. +
+ +

ImageMagick + supplies a `display' utility, which can be used to display the + PNG image: + +

     display 3DLDFmp.1.png
+ 
+

It can be included in an HTML document as follows: + +

     <img src="3DLDFmp.1.png"
+               alt="[Fig. 1]."
+ 
+

Please note! The PNG files for this manual are now called + filename 3DLDF1.png, 3DLDF2.png, ..., + 3DLDF199.png, + because I wasn't able to write files + with names like 3DLDFmp.<number>.png to a CD-R (Compact + Disk, Recordable), when `number' had more than one digit. + +

+ +
+ +


+ Previous: Converting EPS Files, + Up: Converting EPS Files + +
+ +
11.2.1.1 Emacs-Lisp Functions
+ +

The file 3DLDF-1.1.5.1/CWEB/cnepspng.el contains + definitions of two Emacs-Lisp functions that can be used to + convert Encapsulated PostScript (EPS) files to structured PostScript + (PS) and Portable Network Graphics (PNG) files. + +

+ — Emacs-Lisp function: convert-eps filename do-not-delete-files
+

Converts an EPS image file to the PS and PNG formats. + +

If called interactively, convert-eps prompts for the + filename, including the extension, of an + EPS image file. It follows the procedure described above in + Converting EPS Files, to create + filename.ps and filename.png. + +

If do-not-delete-files is nil, + the .tex, .dvi, and .log files will be deleted. + This is the case when convert-eps is called interactively + with no prefix argument. + If convert-eps is called interactively with a prefix + argument, or non-interactively with a non-nil + do-not-delete-files argument, these files will not be deleted. +

+ +
+ — Emacs-Lisp function: convert-eps-loop arg start end
+

Converts a set of EPS image files to the PS and PNG formats. + The files + must all have the same filename, and the extensions must form a range of + positive integers. For example, convert-eps-loop can be + used to convert the files 3DLDFmp.1, 3DLDFmp.2, and + 3DLDFmp.3 to 3DLDFmp.1.ps, 3DLDFmp.2.ps, and + 3DLDFmp.3.ps on the one hand, and + 3DLDFmp.1.png, 3DLDFmp.2.png, + 3DLDFmp.3.png on the other. + +

If convert-eps-loop is called interactively, + it prompts for filename with no extension + and the starting and ending numbers of the range. + +

For all i \in \INT and start \le i \le end, + convert-eps-loop checks whether a file named + filename.i exists. If it does, + it calls convert-eps, passing + filename.i as the latter's filename argument. + +

do-not-delete-files is also passed to convert-eps. If + it's nil, + the .tex, .dvi, and .log files will be deleted. + This is the case when convert-eps-loop is called interactively + with no prefix argument. + If convert-eps-loop is called interactively with a prefix + argument, or non-interactively with a non-nil + do-not-delete-files argument, these files will not be deleted. +

+ +
+ +


+ Previous: Converting EPS Files, + Up: Running 3DLDF + +
+ +

11.2.2 Command Line Arguments

+ +

3dldf can be called with the following + command line arguments. + +

+
--help
Prints information about the valid command line options to standard + output and exits with return value 0. + +
--silent
Suppresses some output to standard output + and standard error when 3dldf is run + +
--verbose
Causes status information to be printed to standard output + when 3dldf is run. + +
--version
Prints the version number of 3DLDF + to standard output and exits with return value 0. +
+ +

Currently, 3dldf can only handle long options. ‘-’ + cannot be substituted for ‘--’. However, the names of the options + themselves can be abbreviated, as long as the abbreviation is + unambigous. For example, ‘3dldf --h’ and ‘3dldf --verb’ are + valid, but ‘3dldf --ver’ is not. + + + + + + + + + + + + + + + + + +

+ +


+ Next: , + Previous: Installing and Running 3DLDF, + Up: Top + +
+ +

12 Typedefs and Utility Structures

+ +

3DLDF defines a number of data types for various reasons, e.g., for the + sake of convenience, for use in conditional compilation, or as return + values of functions. Some of these data types can be defined using + typedef, while others are defined as structs. + +

The typedefs and utility structures described in this chapter are + found in pspglb.web. Others, that contain objects of types + defined in 3DLDF, are described in subsequent chapters. + +

+ — typedef: real
+

Synonymous either with float or double, depending on the + values of the preprocessor variables LDF_REAL_FLOAT and + LDF_REAL_DOUBLE. The meaning of real is determined by + means of conditional compilation. If real is float, 3DLDF + will require less memory than if real is double, but its + calculations will be less precise. real is “typedeffed” to + float by default. +

+ +
+ — typedef: real_pair first second
+

Synonymous with pair<real, real>. +

+ +
+ — struct: real_triple first second third
+

All three data elements of real_triple are reals. + It also has two constructors, described below. There are no other + member functions. +

+ +
+ — Constructor: void real_triple (void)
+ — Constructor: void real_triple (real a, real b, real c)
+

The constructor taking no arguments sets first, second, + and third to 0. The constructor taking three real + arguments sets first to a, second to b, and + third to c. +

+ +
+ — typedef: Matrix
+

A Matrix is a 4 X 4 + array of real, e.g., + Matrix M; == real M[4][4]. + It is used in class Transform for storing transformation + matrices. See Transforms, and See Transform Reference, for more + information. +

+ +
+ — typedef: real_short first second
+

Synonymous with pair<real, signed short>. + It is the return type of Plane::get_distance(). +

+ +
+ — typedef: bool_pair first second
+

Synonymous with pair<bool, bool>. +

+ +
+ — typedef: bool_real first second
+

Synonymous with pair<bool, real>. +

+ + + + + + +
+ +


+ Next: , + Previous: Typedefs and Utility Structures, + Up: Top + +
+ +

13 Global Constants and Variables

+ +

The global constants and variables described in this chapter are + found in pspglb.web. Others, of types + defined in 3DLDF, are described in subsequent chapters. + +

+ — Constants: bool ldf_real_float
+ — : bool ldf_real_double
+

Set to 0 or 1 to match the values of the preprocessor macros + LDF_REAL_FLOAT and LDF_REAL_DOUBLE. The latter are used + for conditional compilation and determine whether real is + “typedeffed” to float or double, i.e., whether + real is made to be a synonym of float or double + using typedef. + +

ldf_real_float and ldf_real_double can be used to control + conditional expressions in non-conditionally compiled code. +

+ +
+ — Constant: real PI
+

The value of PI + is calculated as + 4.0 * arctan(1.0). + I believe that a preprocessor macro “PI” was + available when I compiled 3DLDF using the DEC C++ + compiler, and that + it wasn't, when I used GNU CC under Linux, but I'm no longer sure. +

+ +
+ — Variable: valarray <real> null_coordinates
+

Contains four elements, all 0. Used for resetting the sets of + coordinates belonging to Points, but only when the DEC C++ + +

compiler is used. This doesn't work when GCC is used. +

+ +
+ — Constant: real INVALID_REAL
+

Actually, INVALID_REAL is the largest possible real value + (i.e., float or double) on a given machine. + So, from the point of view of the compiler, it's not invalid at all. + However, 3DLDF uses it to indicate failure of some kind. For example, + the return value of a function returning real can be compared + with INVALID_REAL to check whether the function succeeded or + failed. + +

An alternative approach would be to use the exception handling + facilities of C++ + . I do use these, but only in a couple of places, + so far. +

+ +
+ — Constant: real_pair INVALID_REAL_PAIR
+

first and second are both INVALID_REAL. +

+ +
+ — Constant: real INVALID_REAL_SHORT
+

first is INVALID_REAL and second is 0. +

+ +
+ — Variable: real MAX_REAL
+

The largest real value permitted in the the elements of + Transforms and the coordinates of + Points. It is the second largest real value (i.e., + float or double) on a given machine (INVALID_REAL + is the largest). + +

MAX_REAL is a variable, but it should be used like a constant. + In other words, users should never reset its value. It can't be + declared const because its value must be calculated using + function calls, which can't be done before the entry point of the + program, i.e., main(). Therefore, the value of MAX_REAL + is calculated at the beginning of main(). +

+ +
+ — Variable: real MAX_REAL_SQRT
+

The square root of MAX_REAL. + +

MAX_REAL_SQRT is a variable, but it should be used like a + constant. In other words, users should never reset its value. It can't + be declared const because its value is calculated using the + sqrt() function, + which can't be done before the entry point of the + program, i.e., main(). Therefore, the value of + MAX_REAL_SQRT is set after MAX_REAL is calculated, at the + beginning of main(). + +

MAX_REAL_SQRT is used in Point::magnitude() + (see Vector Operations). The magnitude of a Point is found + by using the formula + \sqrtx^2 + y^2 + z^2. + x, y, and z are all tested against + MAX_REAL_SQRT to ensure that + x^2, y^2, and z^2 + will all be + less than or equal to MAX_REAL before trying to calculate them. + + +

Metafont implements an operation called Pythagorean addition, + notated as “++”which + can be used to calculate distances without first squaring and then + taking square roots: + 27 + a++b == \sqrt(a^2 + b^2) + and + a++b++c == \sqrt(a^2 + b^2 + c^2). + This makes it possible to calculate distances for greater values of + a, b, and c, that would otherwise cause floating point errors. + Metafont also implements the inverse operation + Pythagorean subtraction, notated as “+-+”: + + + + + + + a+-+b == \sqrt(a^2 - b^2). + Unfortunately, 3DLDF implements neither Pythagorean addition + nor subtraction as yet, but it's on my + list of “things to do”. +

+ + + + + + +
+ +


+ Next: , + Previous: Global Constants and Variables, + Up: Top + +
+ +

14 Dynamic Allocation of Shapes

+ +
+ — Template function: template <class C> C* create_new (const C* arg)
+ — Template function: template <class C> C* create_new (const C& arg)
+

These functions dynamically allocate an object derived from + Shape on the free store, + returning a pointer to the type of the Shape and setting + on_free_store to true. + +

If a non-zero pointer or a reference is passed to create_new(), + the new object will be a copy of arg. + +

It is not possible to instantiate more than one specialization of + create_new() that takes no argument, because calls to these + functions would be ambiguous. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to create_new() + as its argument. + +

create_new is called like this: + +

          Point* p = create_new<Point>(0);
+           p->show("*p:");
+           -| *p: (0, 0, 0)
+           
+           Color c(.3, .5, .25);
+           Color* d = create_new<Color>(c);
+           d->show("*d:");
+           -|
+           *d:
+           name ==
+           use_name == 0
+           red_part == 0.3
+           green_part == 0.5
+           blue_part == 0.25
+           
+           
+           Point a0(3, 2.5, 6);
+           Point a1(10, 11, 14);
+           Path q(a0, a1);
+           Path* r = create_new<Path>(&q);
+           r->show("*r:");
+           -|
+           *r:
+           points.size() == 2
+           connectors.size() == 1
+           (3, 2.5, 6) -- (10, 11, 14);
+ 
+

Specializations of this template function are currently declared for + Color, Point, Path, Reg_Polygon, + Rectangle, Ellipse, Circle, Solid, and + Cuboid. +

+ + + + + + +
+ +


+ Next: , + Previous: Dynamic Allocation of Shapes, + Up: Top + +
+ +

15 System Information

+ +

The functions described in this chapter are all declared in the + namespace System. They are for finding out information + about the system on which 3DLDF is being run. They are declared and + defined in pspglb.web, except for the template function + get_second_largest(), which is declared and defined in + gsltmplt.web. + +

There are two reasons for this. The first is that template definitions + must be available + in the compilation units where specializations are instantiated. + I therefore write the template definition of get_second_largest() + to gsltmplt.h, so it can be included by the CWEB files that need + it, currently main.web only. If I + wrote it to pspglb.h, it would be included by all of the CWEB + files except for loader.web, causing unnecessarily bloated object + code. + +

The other reason is because of the way way 3DLDF is built using Automake + and make. I originally tried to define get_second_largest() + in pspglb.web and wrote the definition to gsltmplt.cc, + which is no problem with CWEB. However, I was unable to express the + dependencies among the CWEB, C++ + , and object files in such a way that + 3DLDF was built properly. + +

Therefore all template functions will be put into files either by + themselves, or in small groups. + +

+ +
+ +


+ Next: , + Previous: System Information, + Up: System Information + +
+ +

15.1 Endianness

+ +
+ — Function: signed short get_endianness ([const bool verbose = false])
+

Returns the following values: + +

+
0
if the processor is little-endian. + +
1
if the processor is big-endian. + +
-1
if the endianness cannot be determined. + +
+ +

It is called by is_little_endian() and + is_big_endian(). + +

If verbose is true, messages are printed to standard + output. + +

This function has been adapted from + Harbison, Samuel P., and Guy L. Steele Jr. + C, A Reference Manual, pp. 163–164. + This book has the clearest explanation of endianness that I've found so + far. + +

This is the C++ + code: + +

          signed short
+           System::get_endianness(const bool verbose)
+           {
+             union {
+               long Long;
+               char Char[sizeof(long)];
+             } u;
+             u.Long = 1;
+             if (u.Char[0] == 1)
+               {
+                 if (verbose)
+                   cout << "Processor is little-endian."
+                        << endl << endl << flush;
+                 return 0;
+               }
+             else if (u.Char[sizeof(long) - 1] == 1)
+               {
+                 if (verbose)
+                   cout << "Processor is big-endian."
+                        << endl << endl << flush;
+                 return 1;
+               }
+             else
+               {
+                 cerr << "ERROR! In System::get_endianness():\n"
+                      << "Can't determine endianness. Returning -1"
+                      << endl << endl << flush;
+                 return -1;
+               }
+           }
+ 
+
+ +
+ — Function: bool is_big_endian ([const bool verbose = false])
+

Returns true if the processor is big-endian, otherwise false. + If verbose is true, messages are printed to standard + output. +

+ +
+ — Function: bool is_little_endian ([const bool verbose = false])
+

Returns true if the processor is little-endian, otherwise false. + If verbose is true, messages are printed to standard + output. +

+ +
+ +


+ Next: , + Previous: Endianness, + Up: System Information + +
+ +

15.2 Register Width

+ +
+ — Function: unsigned short get_register_width (void)
+

Returns the register width of the CPU of the system on which 3DLDF is + being run. This will normally be either 32 or 64 bits. + +

This is the C++ + code: + +

          return (sizeof(void*) * CHAR_BIT);
+ 
+

This assumes that an address will be the same size as the processor's + registers, and that CHAR_BIT will be the number of bits in a + byte. These are reasonable assumptions that apply to all architectures + I know about. + +

This function is called by is_32_bit() and is_64_bit(). +

+ +
+ — Function: bool is_32_bit (void)
+

Returns true if the CPU of the system on which 3DLDF is being run + has a register width of 32 bits, otherwise false. +

+ +
+ — Function: bool is_64_bit (void)
+

Returns true if the CPU of the system on which 3DLDF is being run + has a register width of 64 bits, otherwise false. +

+ +
+ +


+ Previous: Register Width, + Up: System Information + +
+ +

15.3 Get Second Largest Real

+ +
+ — Template function: template <class Real> Real get_second_largest (Real MAX_VAL, [bool verbose = false])
+ — Template specialization: float get_second_largest (float, bool)
+ — Template specialization: double get_second_largest (double, bool)
+

get_second_largest returns the second largest floating point + number of the type specified the template paramater Real. + If verbose is true, messages are printed to standard + output. + +

This function is used for setting the value of MAX_REAL. + See Global Constants and Variables. + +

get_second_largest depends on there + being an unsigned integer type with the same length as Real. + This should always be the case for float and double, but + may not be long double. + +

MAX_VAL should be the largest number of type Real on a given + architecture. The GNU C++ + compiler GCC 3.3 does not currently supply + the numeric_limits template, so it is necessary to pass + one of the macros FLT_MAX or DBL_MAX explicitly, depending + on which specialization you use28. + When and if GCC supplies the numeric_limits template, I will + eliminate the MAX_REAL argument. +

+ + + + + + +
+ +


+ Next: , + Previous: System Information, + Up: Top + +
+ +

16 Color Reference

+ +

Class Color is defined in colors.web. + +

+ + + +

16.1 Data Members

+ +
+ — Variable: string name
+

The name of the Color. +

+ +
+ — Variable: bool use_name
+

If true, name is written to out_stream when the + Color is used for drawing or filling. Otherwise, the + RGB (red-green-blue) values are written to out_stream. +

+ +
+ — Variable: bool on_free_store
+

true, if the Color has been created by + create_new<Color>(), which allocates memory for the + Color on the free store. Otherwise false. + Colors should only ever be dynamically allocated by using + create_new<Color>(). + See Color Reference;;Constructors and Setting Functions. +

+ +
+ — Variable: real red_part
+ — Variable: real green_part
+ — Variable: real blue_part
+

The RGB (red-green-blue) values of the Color. + A real value r is valid for these variables if and + only if + 0 <= r <= 1. +

+ +
+ +


+ Next: , + Previous: Color Data Members, + Up: Color Reference + +
+ +

16.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Color (void)
+

Creates a Color and initializes its red_part, + green_part, and blue_part to 0. use_name and + on_free_store are set to false. +

+ +
+ — Copy constructor: void Color (const Color& c, [const string n = "", [const bool u = true]])
+

Creates a Color and makes it a copy of c. If n is + not the empty string and u is true, use_name is set + to true. Otherwise, its set to false. +

+ +
+ — Constructor: void Color (const string n, const unsigned short r, const unsigned short g, const unsigned short b, [const bool u = true])
+

Creates a Color with name n. Its red_part, + green_part, and blue_part are set to + r/255.0, g/255.0, and b/255.0, + respectively. + use_name is set to u. +

+ +
+ — Setting function: void set (const string n, const unsigned short r, const unsigned short g, const unsigned short b, [const bool u = false])
+

Corresponds to the constructor above, except that u is false by default. +

+ +
+ — Constructor: void Color (const real r, const real g, const real b)
+

Creates an unnamed Color using the real values r, + g, and b for its red_part, green_part, and + blue_part, respectively. +

+ +
+ — Setting function: void set (const real r, const real g, const real b)
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Color* create_new<Color> (const Color* c)
+ — : Color* create_new<Color> (const Color& c)
+

Pseudo-constructors for dynamic allocation of Colors. + They create a Color on the free store and allocate memory for it using + new(Color). They return a pointer to the new Color. + +

If c is a non-zero pointer or a reference, + the new Color will be a copy of + c. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Color>() as its argument. + See Dynamic Allocation of Shapes, for more information. + + +

This function is used in the drawing and filling functions for + Path and Solid. Point::drawdot() should be changed + to use it too, but I haven't gotten around to doing this yet. +

+ + + +

16.3 Operators

+ +
+ — Assignment operator: void operator= (const Color& c)
+

Sets name to the empty string, use_name to + false, and red_part, green_part, and + blue_part to c.red_part, c.green_part, and + c.blue_part, respectively. +

+ +
+ — const operator: bool operator== (const Color& c)
+

Equality operator. Returns true, if the red_parts, + green_parts, and blue_parts of *this and c + are equal, otherwise false. The names and + use_names are not compared. +

+ +
+ — const operator: bool operator!= (const Color& c)
+

Inequality operator. Returns false, if the red_parts, + green_parts, and blue_parts of *this and c + are equal, otherwise true. The names and + use_names are not compared. +

+ +
+ — Non-member function: ostream& operator<< (ostream& o, const Color& c)
+

Output operator. Writes the MetaPost code for the Color to + out_stream when a Picture is output. This occurs when + the Color has been used as an argument to + drawing or filling functions. + +

If use_name is true, name is written to + out_stream. Otherwise, + “(red_part, green_part, blue_part)” is written to + out_stream. +

+ +
+ +


+ Next: , + Previous: Color Operators, + Up: Color Reference + +
+ +

16.4 Modifying

+ +
+ — Function: void set_name (const string s)
+

Sets name to s. use_name is not reset. +

+ +
+ — Function: void set_use_name (const bool b)
+

Sets use_name to b. +

+ +
+ — Function: void modify (const real r, [const real g = 0, [const real b = 0]])
+

Adds r, g, and b to red_part, + green_part, and blue_part, respectively. Following the + addition, if red_part, green_part, and/or blue_part + is greater than 1, it is reduced to 1. If it is less than 0, it is + increased to 0. +

+ +
+ — Function: void set_red_part (const real q)
+ — Function: void set_green_part (const real q)
+ — Function: void set_blue_part (const real q)
+

Let p stand for red_part, + green_part, or blue_part, depending upon which function is + used. + If + 0 <= q <= 1, + p is set to q. If + q < 0, p is set to 0. + If q > 1, p is set to 1. +

+ + +
+ +


+ Next: , + Previous: Modifying Colors, + Up: Color Reference + +
+ +

16.5 Showing

+ +
+ — const function: void show ([string text = ""])
+

Prints information about the Color to standard output. + If text is not the empty string, prints text on a + line of its own. Otherwise, it prints “Color:”. Then it prints + name, use_name, red_part, green_part, and + blue_part. +

+ +
+ +


+ Next: , + Previous: Showing Colors, + Up: Color Reference + +
+ +

16.6 Querying

+ +
+ — const function: bool is_on_free_store (void)
+

Returns on_free_store. This will only be true, if the + Color was created by create_new<Color>(). + See Color Reference; Constructors and Setting Functions. +

+ +
+ — Inline const function: real get_red_part ([bool decimal = false])
+ — Inline const function: real get_green_part ([bool decimal = false])
+ — Inline const function: real get_blue_part ([bool decimal = false])
+

These functions return the red_part, green_part, or + blue_part of the Color, respectively. If decimal is + false (the default), the actual real value of the “part” + is returned. Otherwise, the corresponding whole number + n such that + 0 <= n <= 255 + is returned. +

+ +
+ — const function: bool get_use_name (void)
+

Returns use_name. +

+ +
+ — Inline const function: string get_name (void)
+

Returns name. +

+ +
+ +


+ Next: , + Previous: Querying Colors, + Up: Color Reference + +
+ +

16.7 Defining and Initializing Colors

+ +
+ — const function: void define_color_mp ()
+

Writes MetaPost code to out_stream, in order to define objects of + type color within MetaPost, and set their redparts, + greenparts, and blueparts. +

+ +
+ — Static function: void initialize_colors (void)
+

Calls define_color_mp() (described above) for the + Colors that are defined in namespace Colors + (see Namespace Colors). +

+ +
+ +


+ Previous: Defining and Initializing Colors, + Up: Color Reference + +
+ +

16.8 Namespace Colors.

+ +
+ — Constant: const Color red
+ — Constant: const Color green
+ — Constant: const Color blue
+ — Constant: const Color cyan
+ — Constant: const Color yellow
+ — Constant: const Color magenta
+ — Constant: const Color orange_red
+ — Constant: const Color violet_red
+ — Constant: const Color pink
+ — Constant: const Color green_yellow
+ — Constant: const Color orange
+ — Constant: const Color violet
+ — Constant: const Color purple
+ — Constant: const Color blue_violet
+ — Constant: const Color yellow_green
+ — Constant: const Color black
+ — Constant: const Color white
+ — Constant: const Color gray
+ — Constant: const Color light_gray
+

These constant Colors can be used in drawing and filling + commands. +

+ +
+ — Constant: const Color default_background
+

The default background color. Equal to white per default. +

+ +
+ — Pointer: const Color* background_color
+

Points to default_background by default. +

+ +
+ — Pointer: const Color* default_color
+

Points to black by default. +

+ +
+ — Pointer: const Color* help_color
+

Points to green by default. +

+ +

The following vectors of pointers to Color can be used in the + drawing and filling functions for Solid + (see Solid Reference; Drawing and Filling). + +

+ — Vector: const vector <const Color*> default_color_vector
+

Contains one pointer, namely default_color. +

+ +
+ — Vector: const vector <const Color*> help_color_vector
+

Contains one pointer, namely help_color. +

+ +
+ — Vector: const vector <const Color*> background_color_vector
+

Contains one pointer, namely background_color. +

+ + + + + + +
+ +


+ Next: , + Previous: Color Reference, + Up: Top + +
+ +

17 Input and Output

+ + + +
+ + +


+ Next: , + Previous: Input and Output, + Up: Input and Output + +
+ +

17.1 Global Variables

+ +
+ — Variable: ifstream in_stream
+

Intended for inputting files of input code. However, 3DLDF does not + currently have a routine for reading input code. + in_stream is currently attached to the file ldfinput.ldf + by initialize_io() (see I/O Functions). + in_stream is read in character-by-character in main(), + however this serves no useful purpose as yet. +

+ +
+ — Variable: ofstream out_stream
+

Used for writing the file of MetaPost code, which is 3DLDF's output. + Currently attached to the file subpersp.mp by + initialize_io() (see I/O Functions). +

+ +
+ — Variable: ofstream tex_stream
+

TeX code can be written to a file through tex_stream, if + desired. 3DLDF makes no use of it itself. + Currently attached to subpersp.tex by + initialize_io() (see I/O Functions). +

+ +
+ + +


+ Previous: I/O Global Variables, + Up: Input and Output + +
+ +

17.2 I/O Functions

+ +
+ — Function: void initialize_io (string in_stream_name, string out_stream_name, string tex_stream_name, char* program_name)
+

Opens files with names specified by the first three arguments, and + attaches them to the file streams in_stream, out_stream, and + tex_stream, respectively. Comments are written at the beginning + of the files, containing their names, a datestamp, and the name of the + program used to generate them. +

+ +
+ — Function: void write_footers (void)
+

Writes code at the end of the files attached to in_stream, + out_stream, and tex_stream, before the streams are + closed. Currently, they write comments containing + local variable lists + for use in + Emacs. +

+ +
+ — Inline function: void beginfig (unsigned short i)
+

Writes “beginfig(i)” to out_stream. +

+ +
+ — Inline function: void endfig ([unsigned short i = 0])
+

Writes “endfig()” to out_stream. The argument i + is “syntactic sugar”; it's ignored by endfig(), + but may help the user keep track of what figure is being ended. +

+ + + + + + +
+ +


+ Next: , + Previous: Input and Output, + Up: Top + +
+ +

18 Shape Reference

+ +

Class Shape is defined in shapes.web. + +

Shape is an abstract class, which means that + all of its member functions are pure virtual functions, and + that it's only used as a base class, i.e., no objects of type + Shape may be declared. + +

All of the “drawable” types in 3DLDF, Point, + Path, Ellipse, etc., are derived from Shape. + +

Deriving all of the drawable types from Shape makes it possible + to handle objects of different types in the same way. This is + especially important in the Picture functions, where objects of + various types (but all derived from Shape) are accessed through + pointers to Shape. See Picture Reference. + +

+ +
+ +


+ Next: , + Previous: Shape Reference, + Up: Shape Reference + +
+ +

18.1 Data Members

+ +
+ — Protected static constants: signed short DRAWDOT
+ — : signed short DRAW
+ — : signed short FILL
+ — : signed short FILLDRAW
+ — : signed short UNDRAWDOT
+ — : signed short UNDRAW
+ — : signed short UNFILL
+ — : signed short UNFILLDRAW
+

Values used in the output() functions of the classes derived from + Shape. For example, in Path, if the data member + fill_draw_value = DRAW, then the MetaPost command + draw is written to out_stream when that Path is + output. +

+ +
+ +


+ Next: , + Previous: Shape Data Members, + Up: Shape Reference + +
+ +

18.2 Operators

+ +
+ — Pure virtual function: Transform operator*= (const Transform& t)
+
+ +
+ +


+ Next: , + Previous: Shape Operators, + Up: Shape Reference + +
+ +

18.3 Copying

+ +
+ — const pure virtual function: Shape* get_copy (void)
+

Copies an object, allocating memory on the free store for the copy, + and returns a pointer to Shape for accessing the copy. + +

Used in the drawing and filling functions for copying the Shape, + and putting a pointer to the copy onto the vector<Shape*> shapes + of the Picture. +

+ +
+ +


+ Next: , + Previous: Copying Shapes, + Up: Shape Reference + +
+ +

18.4 Modifying

+ +
+ — Pure virtual function: bool set_on_free_store (bool b = true)
+

Sets the data member on_free_store to b. All classes + derived from Shape must therefore also have a data member + on_free_store. + +

This function is used in the template function + create_new<type>. + See Dynamic Allocation of Shapes, for more information. + +

+ + + +

18.5 Affine Transformations

+ +
+ — Pure virtual functions: Transform rotate (const real x, const real y, const real z)
+ — : Transform scale (real x, real y, real z)
+ — : Transform shear (real xy, real xz, real yx, real yz, real zx, real zy)
+ — : Transform shift (real x, real y, real z)
+ — : Transform rotate (const Point& p0, const Point& p1, const real r)
+

See Point Reference; Affine Transformations. +

+ +
+ +


+ Next: , + Previous: Affine Transformations for Shapes, + Up: Shape Reference + +
+ +

18.6 Applying Transformations

+ +
+ — Pure virtual function: void apply_transform (void)
+

Applies the Transform stored in the transform data member + of the Points belonging to the Shape to their + world_coordinates. The transforms are subsequently reset + to the identity Transform. +

+ +
+ +


+ Next: , + Previous: Applying Transformations to Shapes, + Up: Shape Reference + +
+ +

18.7 Clearing

+ +
+ — Pure virtual function: void clear (void)
+

The precise definition of this function will depend on the nature of the + derived class. In general, it will call the destructor on dynamically + allocated objects belonging to the Shape, and deallocate the + memory they occupied. +

+ +
+ +


+ Next: , + Previous: Clearing Shapes, + Up: Shape Reference + +
+ +

18.8 Querying

+ +
+ — const pure virtual function: bool is_on_free_store (void)
+

Returns true if the object was allocated on the free store, + otherwise false. +

+ +
+ +


+ Next: , + Previous: Querying Shapes, + Up: Shape Reference + +
+ +

18.9 Showing

+ +
+ — const pure virtual function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = 0, [const real factor = 1]]]]]]])
+

Prints information about an object to standard output. + See the descriptions of show() for the classes derived from + Shape for more information. + +

+ +
+ +


+ Previous: Showing Shapes, + Up: Shape Reference + +
+ +

18.10 Outputting

+ +
+ — Pure virtual function: void output (void)
+

Called by Picture::output() for writing MetaPost code to + out_stream for a Shape pointed to by a pointer on the + vector<Shape*> shapes belonging to the Picture. Such + a Shape will have been created by a drawing or filling + function. +

+ +
+ — Pure virtual function: vector<Shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Called in Picture::output(). It determines whether a + Shape can be output. If it can, and an output() function + for the type of the Shape exists, a vector<Shape*> + containing a pointer to the Shape is returned. + +

On the other + hand, it is possible to define a type derived from Shape, without + an output() function of its own, and not derived from a type that + has one. It may then consist of one or more objects of types that do + have output() functions. In this case, the vector<Shape*> + returned by extract() will contain pointers to all of these + subsidiary Shapes, and Picture::output() will treat them + as independent objects. In particular, if any one of them cannot be + projected using the arguments passed to Picture::output(), this + will have no effect on whether the others are outputted or not. + +

Currently, there are no Shapes without an output() + function, either belonging to the class, or inherited. However, it's + useful to be able to define Shapes in this way, so that they can + be tested without having to define an output() function first. +

+ +
+ — Pure virtual function: bool set_extremes (void)
+

Sets the values of projective_extremes for the Shape. + This is needed in Picture::output() for determining the order in + which objects are output. +

+ +
+ — const pure virtual functions: real get_minimum_z (void)
+ — : real get_maximum_z (void)
+ — : real get_mean_z (void)
+

These functions return the minimum, maximum, and mean z-value + respectively of the projected Points belonging to + the Shape, i.e., from projective_extremes. The values for + the Shapes on the Picture are used for determining the + order in which they are output +

+ +
+ — const pure virtual function: const valarray<real> get_extremes (void)
+

Returns projective_extremes. +

+ +
+ — Pure virtual function: void suppress_output (void)
+

Sets do_output to false. This function is called in + Picture::output(), if a Shape on a Picture cannot + be output using the arguments passed to Picture::output(). +

+ +
+ — Pure virtual function: void unsuppress_output (void)
+

Sets do_output to true. Called in + Picture::output() after output() is called on the Shapes. + This way, output of Shapes that couldn't be output when + Picture::output() was called with a particular set of arguments + won't necessarily be suppressed when + Picture::output() is called again with different arguments. +

+ +

f + + + + + +

+ +


+ Next: , + Previous: Shape Reference, + Up: Top + +
+ +

19 Transform Reference

+ +

Class Transform is defined in transfor.web. + Point is a friend of Transform. + +

+ + + +

19.1 Data Members

+ +
+ — Private variable: Matrix matrix
+

A 4 X 4 + +

matrix of real representing the actual transformation matrix. +

+ +
+ +


+ Next: , + Previous: Transform Data Members, + Up: Transform Reference + +
+ +

19.2 Global Variables and Constants

+ +
+ — Variable: Transform user_transform
+

Currently has no function. It is intended to be used for transforming + the coordinates of Points between the world coordinate system + (WCS) and a user coordinate system (UCS), when routines for managing + user coordinate systems are implemented. +

+ +
+ — Constant: const Transform INVALID_TRANSFORM
+

Every member of matrix in INVALID_TRANSFORM is + equal to INVALID_REAL. +

+ +
+ — Constant: const Transform IDENTITY_TRANSFORM
+

Homogeneous coordinates and Transforms are unchanged by + multiplication with IDENTITY_TRANSFORM. + matrix is an identity matrix: +

          1 0 0 0
+           0 1 0 0
+           0 0 1 0
+           0 0 0 1
+ 
+

See Transforms. +

+ + + +

19.3 Constructors

+ +
+ — Default constructor: void Transform (void)
+

Creates a Transform containing the identity matrix. +

+ +
+ — Constructor: void Transform (real r)
+

Creates a Transform and sets all of the elements of matrix + to r. Currently, this + constructor is never used, but who knows? Maybe someday it will be + useful for something. +

+ +
+ — Constructor: void Transform (real r0_0, real r0_1, real r2, real r0_2, real r0_3, real r1_0, real r1_1, real r1_2, real r1_3, real r2_0, real r2_1, real r2_2, real r2_3, real r3_0, real r3_1, real r3_2, real r3_3)
+

Each of the sixteen real arguments is + assigned to the corresponding element of matrix: + matrix[0][0] = r0_0, matrix[0][1] = r0_1, etc. + Useful for specifying a transformation matrix completely. +

+ +
+ +


+ Next: , + Previous: Transform Constructors, + Up: Transform Reference + +
+ +

19.4 Operators

+ +
+ — Assignment operator: Transform operator= (const Transform& t)
+

Sets *this to t and returns t. Returning *this + would, of course, have exactly the same effect. +

+ +
+ — Operator: real operator*= (real r)
+

Multiplication with assignment by a scalar. + This operator multiplies each element + E + of matrix by + the scalar r. + The return value is r. This makes it possible to + chain invocations of this function: + For a_x, b_x, c_x, ..., p_x in R + , + x in N + +

          Transform T0(a_0, b_0, c_0, d_0,
+                        e_0, f_0, g_0, h_0,
+                        i_0, j_0, k_0 l_0,
+                        m_0, n_0, o_0, p_0);
+           Transform T1(a_1, b_1, c_1, d_1,
+                        e_1, f_1, g_1, h_1,
+                        i_1, j_1, k_1 l_1,
+                        m_1, n_1, o_1, p_1);
+           Transform T2(a_2, b_2, c_2, d_2,
+                        e_2, f_2, g_2, h_2,
+                        i_2, j_2, k_2 l_2,
+                        m_2, n_2, o_2, p_2);
+           real r = 5;
+ 
+

Let M_0, M_1, and M_2 stand for + T0.matrix, T1.matrix, and T2.matrix + respectively: + +

          M_0 =
+           a_0 b_0 c_0 d_0
+           e_0 f_0 g_0 h_0
+           i_0 j_0 k_0 l_0
+           m_0 m_0 o_0 p_0
+           
+           M_1 =
+           a_1 b_1 c_1 d_1
+           e_1 f_1 g_1 h_1
+           i_1 j_1 k_1 l_1
+           m_1 m_1 o_1 p_1
+           
+           M_2 =
+           a_2 b_2 c_2 d_2
+           e_2 f_2 g_2 h_2
+           i_2 j_2 k_2 l_2
+           m_2 m_2 o_2 p_2
+ 
+
          T0 *= T1 *= T2 *= r;
+ 
+

Now,
+

          M_0 =
+           5a_0 5b_0 5c_0 5d_0
+           5e_0 5f_0 5g_0 5h_0
+           5i_0 5j_0 5k_0 5l_0
+           5m_0 5m_0 5o_0 5p_0
+           
+           M_1 =
+           5a_1 5b_1 5c_1 5d_1
+           5e_1 5f_1 5g_1 5h_1
+           5i_1 5j_1 5k_1 5l_1
+           5m_1 5m_1 5o_1 5p_1
+           
+           M_2 =
+           5a_2 5b_2 5c_2 5d_2
+           5e_2 5f_2 5g_2 5h_2
+           5i_2 5j_2 5k_2 5l_2
+           5m_2 5m_2 5o_2 5p_2
+ 
+

This function is not currently used anywhere, but it may turn out to be + useful for something. +

+ +
+ — const operator: Transform operator* (const real r)
+

Multiplication of a Transform by a scalar without assignment. + The return value is a Transform + A. + If this.matrix has elements + E_T, then A.matrix has elements E_A such that + E_A = r * E_T + +

for all E. +

+ +
+ — Operator: Transform operator*= (const Transform& t)
+

Performs matrix multiplication on matrix and + t.matrix. The result is assigned to matrix. + t is returned, not *this! This makes it possible to + chain invocations of this function: + +

          Transform a;
+           a.shift(1, 1, 1);
+           Transform b;
+           b.rotate(0, 90);
+           Transform c;
+           c.shear(5, 4);
+           Transform d;
+           d.scale(3, 4, 5);
+ 
+

Let a_m, b_m, and c_m stand for + a.matrix, b.matrix, c.matrix, and d.matrix + respectively: +

          a_m =
+           1        0        0        0
+           0        1        0        0
+           0        0        1        0
+           1        1        1        1
+           
+           b_m =
+            0.5      0.5        0.707      0
+            0.146    0.854     -0.5        0
+           -0.854    0.146      0.5        0
+            0        0          0          1
+           
+           c_m =
+            1       12       14        0
+           10        1       15        0
+           11       13        1        0
+            0        0        0        1
+           
+           d_m =
+           3        0        0        0
+           0        4        0        0
+           0        0        5        0
+           0        0        0        1
+ 
+

a *= b *= c *= d;
+ a, b, and c are transformed by d, which + remains unchanged. + +

Now, +

          a_m =
+           3        0        0        0
+           0        4        0        0
+           0        0        5        0
+           3        4        5        1
+           
+           b_m =
+            1.5     2       3.54  0
+           -0.439   3.41   -2.5   0
+           -2.56    0.586   2.5   0
+            0       0       0     1
+           
+           c_m =
+            3       48       70        0
+           30        4       75        0
+           33       52        5        0
+            0        0        0        1
+ 
+

d_m is unchanged. + +

+ +
+ — const operator: Transform operator* (const Transform t)
+

Multiplication of a Transform by another Transform without + assignment. + The return value is a Transform whose matrix contains + values that are the result of the matrix multiplication of + matrix and t.matrix. +

+ +
+ +


+ Next: , + Previous: Transform Operators, + Up: Transform Reference + +
+ +

19.5 Matrix Inversion

+ +
+ — const function: Transform inverse (void)
+ — Function: Transform inverse ([bool assign = false])
+

Returns a Transform T with a T.matrix that is the + inverse of matrix. If assign==true, then + matrix is set to its inverse. + +

In the const version, matrix remains unchanged. + The second should only ever be called with true as its + assign argument. If you're tempted call inverse(false), + you might as well just leave out the argument, which issues a warning + message, and calls the const version. +

+ +
+ +


+ Next: , + Previous: Matrix Inversion, + Up: Transform Reference + +
+ +

19.6 Setting Values

+ +
+ — Function: void set_element (const unsigned short row, const unsigned short col, real r)
+

Sets the element of matrix indicated by the arguments to r. + +

          Transform t;
+           t.set_element(0, 2, -3.45569);
+           t.show("t:");
+           -| t:
+                 1       0   -3.46       0
+                 0       1       0       0
+                 0       0       1       0
+                 0       0       0       1
+ 
+
+ + + +

19.7 Querying

+ +
+ — Function: bool is_identity (void)
+

Returns true if *this is the identity Transform, + otherwise false. This function has both a const and a + non-const version. In the non-const version, + clean() is called on *this before comparing the elements of + matrix with 1 (for the main diagonal) and 0 (for the other + elements). In the const version, *this is copied, + clean() is called on the copy, and the elements of the copy's + matrix are compared with 0 and 1. +

+ +
+ — const function: real get_element (const unsigned short row, const unsigned short col)
+

Returns the value stored in the element of matrix indicated by the arguments. + +

          Transform t;
+           t.shift(1, 2, 3);
+           t.scale(2.5, -1.2, 4);
+           t.rotate(30, 15, 60);
+           t.show("t:");
+           -| t:
+               1.21    2.09   0.647       0
+              0.822  -0.654    0.58       0
+              -2.18   0.224    3.35       0
+              -3.69    1.45    11.8       1
+           cout << t.get_element(2, 1);
+           -| 0.224
+ 
+
+ +
+ +


+ Next: , + Previous: Querying Transforms, + Up: Transform Reference + +
+ +

19.8 Returning Information

+ +
+ — Static function: real epsilon (void)
+

Returns the positive real value of smallest magnitude + \epsilon which an element of a Transform should + contain. An element of a Transform may also contain + -\epsilon. + +

The value \epsilon is used for in the + function clean() (see Transform Reference; Cleaning). + It will also be used for comparing Transforms, when I've added + the equality operator Transform::operator==(). + +

epsilon() returns different values, depending on whether + real is float or double: + If real is float (the default), epsilon() + returns 0.00001. + If real is double, it returns 0.000000001. + +

Please note: I haven't tested whether 0.000000001 is a good + value yet, so users should be aware of this if they set real to + double!29 + The way to test this is to transform two different + Transforms + t_1 and t_2 + using different rotations in such a way that the end + result should be the same for both Transforms. + Let \epsilon stand for the value returned by epsilon(). + If for all sets of + corresponding elements E_1 and E_2 of t_1 and + t_2, ||E_1| - |E_2|| \le \epsilon, then + \epsilon is a good value. + + It will be easier to test this when I've added + Transform::operator==(). + +

Rotation causes a significant loss of precision to due to the use of the + sin() and cos() functions. Therefore, neither + Transform::epsilon() nor Point::epsilon() + (see Point Reference; Returning Information) can be as small as I'd like them to be. If they are two + small, operations that test for equality of Transforms and + Points will return false for objects that should be equal. +

+ + + +

19.9 Showing

+ +
+ — const function: void show ([string text = ""])
+

If the optional argument text is used, and is not the empty + string (""), text is printed on a line of its own to + the standard output first. Otherwise, "Transform:" is printed + on a line of its own to the standard output. + Then, the elements of matrix are printed to standard output. + +

          Transform t;
+           t.show("t:");
+           -| t:
+                 1       0       0       0
+                 0       1       0       0
+                 0       0       1       0
+                 0       0       0       1
+           t.scale(1, 2, 3);
+           t.shift(1, 1, 1);
+           t.rotate(90, 90, 90);
+           t.show("t:");
+           -| t:
+                 0       0       1       0
+                 0       2       0       0
+                -3       0       0       0
+                -1       1       1       1
+ 
+
+ + + +

19.10 Affine Transformations

+ +

The affine transformation functions use their arguments to create a new + Transform t (local to the function) representing the + appropriate transformation. Then, *this is multiplied by t + and t is returned. + Returning t instead of *this makes it possible to put the + affine transformation function at the end of a chain of invocations of + Transform::operator*=(): + +

     Transform t0, t1, t2, t3;
+      ...
+      t0 *= t1 *= t2 *= t3.scale(2, 3.5, 9);
+ 
+

t0, t1, and t2 are all multiplied by the + Transform with +

     matrix =
+      2   0    0  0
+      0   3.5  0  0
+      0   0    9  0
+      0   0    0  1
+ 
+

representing the scaling operation, not t3, which may + represent a combination of transformations. + +

+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Creates a Transform t representing the scaling operation locally, + multiplies *this by t, and returns t. + A Transform representing scaling only, when applied to a + Point p, will cause its x-coordinate to be multiplied by + x, its y-coordinate to be multiplied by y, and its + z-coordinate to be multiplied by z. + +

          Transform t;
+           t.scale(x, y, z);
+ 
+
t.matrix =
+           x 0 0 0
+           0 y 0 0
+           0 0 z 0
+           0 0 0 1
+ 
+
          Transform t;
+           t.scale(12.5, 20, 1.3);
+           t.show("t:");
+           -| t:
+              12.5       0       0       0
+                 0      20       0       0
+                 0       0     1.3       0
+                 0       0       0       1
+ 
+
+ +
+ — Function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+

Creates a Transform t representing the shearing operation locally, + multiplies *this by t, and returns t. + +

When applied to a Point, shearing causes each coordinate to be + modified according to the values of the other coordinates and the + arguments to shear: + +

          Point p(x,y,z);
+           Transform t;
+           t.shear(a, b, c, d, e, f);
+           p *= t;
+ 
+
          ⇒ p = ((x + ay + bz), (y + cx + dz), (z + ex + fy))
+ 
+
          Transform t;
+           t.shear(2, 3, 4, 5, 6, 7);
+           t.show("t:");
+           -| t:
+                 1       4       6       0
+                 2       1       7       0
+                 3       5       1       0
+                 0       0       0       1
+ 
+
+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Function: Transform shift (const Point& p)
+
+

These functions create a Transform t representing the shifting + operation locally, multiplies *this by t, and returns t. + +

The version with the argument const Point& p + passes the updated x, y, and z-coordinates of p (from + world_coordinates) to the + version with three real arguments. + +

When a Transform representing a single shifting operation only + is applied to a Point, the x, + y, and z arguments are added to the corresponding + coordinates of the Point: + +

          Point p(x,y,z);
+           Transform t;
+           t.shift(a, b, c);
+           p *= t;
+ 
+
          ⇒ p = (x + a, y + b, z + c)
+ 
+
+ +
+ — Function: Transform shift_times (real x, [real y = 1, [real z = 1]])
+

Multiplies the corresponding elements of matrix by + the real arguments, i.e., + matrix[3][0] is multiplied by x, + matrix[3][1] is multiplied by y, and + matrix[3][2] is multiplied by z. Returns *this. + +

Ordinary shifting is additive, so a special function is needed to + multiply the elements of matrix responsible for shifting. + The effect of shift_times() is to modify a Transform + representing a shifting operation such that the direction of the shift + is maintained, while changing the distance. + +

If the Transform represents other operations in addition to + shifting, e.g., scaling and/or shearing, the effect of + shift_times() may be unpredictable.30 + +

          Transform t;
+           t.shift(1, 2, 3);
+ 
+
t.matrix =
+           1 0 0 0
+           0 1 0 0
+           0 0 1 0
+           1 2 3 1
+ 
+
          t.shift_times(2, 2, 2);
+ 
+
t.matrix =
+           1 0 0 0
+           0 1 0 0
+           0 0 1 0
+           2 4 6 1
+ 
+
          Rectangle r[4];
+           r[0].set(origin, 1, 1, 90);
+           r[3] = r[2] = r[1] = r[0];
+           Transform t;
+           t.shift(1.5, 1.5);
+           r[0] *= t;
+           r[0].draw();
+           t.shift_times(1.5, 1.5);
+           r[1] *= t;
+           r[1].draw();
+           t.shift_times(1.5, 1.5);
+           r[2] *= t;
+           r[2].draw();
+           t.shift_times(1.5, 1.5);
+           r[3] *= t;
+           r[3].draw();
+ 
+

+
+ [Figure 73. Not displayed.] +
+
+ Fig. 73. +
+

+ +
          Cuboid c(origin, 1, 1, 1);
+           c.draw();
+           Transform t;
+           t.rotate(30, 30, 30);
+           t.shift(1, 0, 1);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+           t.shift_times(1.5, 0, 1.5);
+           c *= t;
+           c.draw();
+ 
+

+
+ [Figure 74. Not displayed.] +
+
+ Fig. 74. +
+

+ +
+ +
+ — Function: Transform rotate (real x, [real y = 0, [real z = 0]])
+

Rotation around the main axes. + Creates a Transform t representing the rotation, + multiplies *this by t, and returns t. +

+ +
+ — Function: Transform rotate (Point p0, Point p1, [const real angle = 180])
+

Rotation around an arbitrary axis. The Point arguments represent + the end points of the axis, and angle is the angle of rotation. + Since 180 degrees + rotation is needed so often, 180 is the default for + angle. +

+ +
+ — Function: Transform rotate (const Path& p, [const real angle = 180])
+

Rotation around an arbitrary axis. Path argument. + The Path p must be linear, i.e., p.is_linear() must + return true. See Path Reference; Querying. +

+ + + +

19.11 Alignment with an Axis

+ +
+ — Function: Transform align_with_axis (Point p0, Point p1, [char axis = 'z'])
+

Returns the Transform that would align the line through p0 + and p1 with the major axis denoted by the axis argument. + The default is the z-axis. This function is used in the functions that + find intersections. + +

          Point P0(1, 1, 1);
+           Point P1(2, 3, 4);
+           P0.draw(P1);
+           P0.dotlabel("$P_0$");
+           P1.dotlabel("$P_1$");
+           Transform t;
+           t.align_with_axis(P0, P1, 'z');
+           P0 *= P1 *= t;
+           t.show("t:");
+           -| t:
+                0.949  -0.169   0.267       0
+                    0   0.845   0.535       0
+               -0.316  -0.507   0.802       0
+               -0.632  -0.169    -1.6       1
+           P0.show("P0:");
+           -| P0: (0, 0, 0)
+           P1.show("P1:");
+           -| P1: (0, 0, 3.74)
+ 
+

The following example shows how align_with_axis() can be used for + putting plane figures into a + major plane. + +

          default_focus.set(2, 3, -10, 2, 3, 10, 10);
+           Circle c(origin, 3, 75, 25, 6);
+           c.shift(2, 3);
+           c.draw();
+           Point n = c.get_normal();
+           n.shift(c.get_center());
+           Transform t;
+           t.align_with_axis(c.get_center(), n, 'y');
+           t.show("t:");
+           -| t:
+             0.686   0.379  -0.621       0
+             0.543     0.3   0.784       0
+             0.483  -0.875       0       0
+                -3   -1.66   -1.11       1
+           n *= c *= t;
+           c.draw();
+           c.show("c:");
+           -| c:
+           fill_draw_value == 0
+           (1.31, 0, -0.728) .. (1.49, 0, -0.171) ..
+           (1.44, 0, 0.413) .. (1.17, 0, 0.933) ..
+           (0.728, 0, 1.31) .. (0.171, 0, 1.49) ..
+           (-0.413, 0, 1.44) .. (-0.933, 0, 1.17) ..
+           (-1.31, 0, 0.728) .. (-1.49, 0, 0.171) ..
+           (-1.44, 0, -0.413) .. (-1.17, 0, -0.933) ..
+           (-0.728, 0, -1.31) .. (-0.171, 0, -1.49) ..
+           (0.413, 0, -1.44) .. (0.933, 0, -1.17) .. cycle;
+           n.show("n:");
+           -| n: (0, 1, 0)
+ 
+

+
+ [Figure 75. Not displayed.] +
+
+ Fig. 75. +
+

+ +
+ + + +

19.12 Resetting

+ +
+ — Function: void reset (void)
+

Resets matrix to the identity matrix. +

+ +
+ +


+ Previous: Resetting Transforms, + Up: Transform Reference + +
+ +

19.13 Cleaning

+ +
+ — Function: void clean (void)
+

Sets elements in matrix whose absolute values are + < epsilon() to 0. +

+ + + + + + +
+ +


+ Next: , + Previous: Transform Reference, + Up: Top + +
+ +

20 Label Reference

+ +

Class Label is defined in pictures.web. + Point and Picture are friends of Label. + +

Labels can be included in drawings by using the label() and + dotlabel() functions, which are currently defined for the classes + Point and Path, and the classes derived from them. + See Point Reference; Labelling, and + See Path Reference; Labelling. + They are currently not defined for Solid, and its derived classes. + I plan to add them for Solid soon. + +

Users will normally + never need to declare objects of type Label, access its data + members or call its member functions directly. + +

When label() or dotlabel() is invoked, one or more Labels is + allocated dynamically and pointers to the new Labels are placed + onto the vector<Label*> labels of a Picture: + current_picture, by default. There are no explicitly defined + constructors for Label, nor is it intended that Labels + ever be created in any way other than through label() or + dotlabel(). When a Picture is copied, the Labels are + copied, too, and when a Picture is cleared (using + Picture::clear()) or destroyed, the Labels are deallocated + and destroyed. + +

+ +
+ +


+ Next: , + Previous: Label Reference, + Up: Label Reference + +
+ +

20.1 Data Members

+ +
+ — Private variable: Point* pt
+

A pointer to the Point representing the location of the + Label. +

+ +
+ — Private variable: bool dot
+

true if the label should be dotted, otherwise + false. + +

dot will be false, if the label was generated + by a call to label() with the “dot” argument + false (the default), true, if + the label was generated by a call to dotlabel(), + or to label() with the “dot” argument + true. +

+ +
+ — Private variable: string text
+

The text of the label. + text is always put between “btex” and “etex” in + the MetaPost code, so that TeX will be used to format the labels. In + particular, this means that TeX's math mode can be used. However, + double backslashes must be used instead of single backslashes, in order + that single backslashes be written to out_stream. + +

          Point P(1, 1, 2);
+           origin.drawarrow(P);
+           P.label("$\\vec{P}$");
+ 
+

+
+ [Figure 76. Not displayed.] +
+
+ Fig. 76. +
+

+ +
+ +
+ — Private variable: string position
+

The position of the text with respect to + *pt. Valid values are as in MetaPost: + “top”, “bot” (bottom), “lft” (left), “rt” + (right), “ulft” (upper left), + “llft” (lower left), “urt” (upper right), + “lrt” (lower right). +

+ +
+ — Public static variable: bool DO_LABELS
+

Enables or disables creation + of Labels. If true, label + and dotlabel() cause Labels to be + created and put onto a Picture. If + false, they are not. Note that it is also + possible to suppress output of existing + Labels when outputting a Picture. +

+ +
+ +


+ Next: , + Previous: Label Data Members, + Up: Label Reference + +
+ +

20.2 Copying

+ +
+ — const Function: Label* get_copy (void)
+

Creates a copy of the Label and returns a pointer to the copy. + Called in Picture::operator=() and Picture::operator+=() + where Pictures are copied. + Users should never need to call this function directly. + See Picture Reference; Operators. + +

This function dynamically allocates a new + Label and a new Point within the Label, and copies + the strings from *this to the new Label. The + standard library functions for strings take care of the + allocation for the string members of Label. +

+ +
+ +


+ Previous: Copying Labels, + Up: Label Reference + +
+ +

20.3 Outputting

+ +
+ — Function: void output (const Focus& f, const unsigned short proj, real factor, const Transform& t)
+

Writes MetaPost code for the labels to out_stream. + It is called in Picture::output() + (see Picture Reference; Outputting). + Users should never need to call this function directly. + +

When Picture::output() is + invoked, the MetaPost code for Labels is written to out_stream + after the code for the drawing and filling commands. This prevents the + Labels from being covered up. However, they can still be covered + by other Labels, or by Shapes or Labels from + subsequent invocations of Picture::output() within the same + figure (see I/O Functions, for descriptions of beginfig() and + endfig()). +

+ + + + + + +
+ +


+ Next: , + Previous: Label Reference, + Up: Top + +
+ +

21 Picture Reference

+ +

Class Picture is defined in pictures.web. + +

+ +
+ +


+ Next: , + Previous: Picture Reference, + Up: Picture Reference + +
+ +

21.1 Data Members

+ +
+ — Private variable: Transform transform
+

Applied to the Shapes on the Picture when the latter is + output. It is initialized as the identity Transform, and can be + modified by the transformation functions, by + Picture::operator*=(const Transform&) + (see Picture Reference; Operators), and by + Picture::set_transform() + (see Picture Reference; Modifying). +

+ +
+ — Private variable: vector<Shape*> shapes
+

Contains pointers to the Shapes on the Picture. + When a drawing or filling function is invoked for a Shape, a copy + is dynamically allocated and a pointer to the copy is placed onto + shapes. +

+ +
+ — Private variable: vector<Label*> labels
+

Contains pointers to the Labels on the Picture. When a + Point is labelled, either directly or through a call to + label() or dotlabel() for another type of + Shape31, + a Label is dynamically allocated, the Point is copied to + *Label::pt, and a pointer to the Label is placed onto + labels. +

+ +
+ — Private variable: bool do_labels
+

Used for enabling or disabling output of Labels when outputting a + Picture. The default value is true. It is set to + false by using suppress_labels() and can be reset to + true by using unsuppress_labels(). + See Picture Reference; Output Functions. + +

Often, when a Picture is copied, transformed, and output again in + a single figure, it's undesirable to have the Labels output again + in their new positions. To avoid this, use suppress_labels() + after outputting the Picture the first time. +

+ +
+ +


+ Next: , + Previous: Picture Data Members, + Up: Picture Reference + +
+ +

21.2 Global Variables

+ +
+ — Variable: Variable Picture current_picture
+

The Picture used as the default by the drawing and filling + functions. +

+ +
+ +


+ Next: , + Previous: Picture Global Variables, + Up: Picture Reference + +
+ +

21.3 Constructors

+ + +
+ — Default constructor: void Picture (void)
+

Creates an empty Picture. +

+ +
+ — Copy constructor: void Picture (const Picture& p)
+

Creates a copy of Picture p. + +

          Circle c(origin, 3);
+           c.draw();
+           current_picture.output(Projections::PARALLEL_X_Z);
+           Picture new_picture(current_picture);
+           new_picture.shift(2);
+           new_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 77. Not displayed.] +
+
+ Fig. 77. +
+

+ +
+ + + +

21.4 Operators

+ +
+ — Assignment operator: void operator= (const Picture& p)
+

Makes *this a copy of p, destroying the old contents of *this. +

+ +
+ — Operator: void operator+= (const Picture& p)
+

Adds the contents of p to *this. p remains unchanged. +

+ +
+ — Operator: void operator+= (Shape* s)
+

Puts s onto shapes. Note that the pointer s + itself is put onto shapes, so any allocation and copying must be + performed first. This is a low-level function that users normally won't + need to use directly. +

+ +
+ — Operator: void operator+= (Label* label)
+

Puts label onto labels. + Note that the pointer label + itself is put onto labels, so any allocation and copying must be + performed first. This is a low-level function that users normally won't + need to invoke directly. +

+ +
+ — Operator: Transform operator*= (const Transform& t)
+

Multiplies transform by t. This has the effect of + transforming all of the Shapes on shapes and all of + the Points of the Labels on labels by t upon + output. + +

          Transform t;
+           t.rotate(0, 0, 180);
+           t.shift(3);
+           Reg_Polygon pl(origin, 5, 3, 90);
+           pl.draw();
+           pl.label();
+           current_picture.output(Projections::PARALLEL_X_Y);
+           current_picture *= t;
+           current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 78. Not displayed.] +
+
+ Fig. 78. +
+

+ +
+ +
+ +


+ Next: , + Previous: Picture Operators, + Up: Picture Reference + +
+ +

21.5 Affine Transformations

+ +

The functions in this section all operate on the transform data + member of the Picture and return a Transform representing the + transformation—not transform. + +

+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Performs transform.scale(x, y, z) and returns + the result. This has the effect of scaling + all of the elements of shapes and labels. +

+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+

Performs transform.shift(x, y, z) and returns + the result. This has the effect of shifting + all of the Shapes and Labels on the Picture. +

+ +
+ — Function: Transform shift (const Point& p)
+

Performs transform.shift(p) and returns + the result. This has the effect of shifting + all of the Shapes and Labels on the Picture by the + x, y, and z-coordinates of p. +

+ +
+ — Function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+

Performs transform.rotate(x, y, z) and returns + the result. This has the effect of rotating + all of the elements of shapes and labels. +

+ +
+ — Function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180]);
+

Performs transform.rotate(p0, p1, angle) and returns + the result. This has the effect of rotating + all of the elements of shapes and labels about the line + from p_0 to p_1. +

+ + + +

21.6 Modifying

+ +
+ — Function: void clear (void)
+

Destroys the Shapes and Labels on the + Picture and removes all the Shape pointers from + shapes and the Label pointers from labels. + All dynamically allocated objects are deallocated, namely the + Shapes, the Labels, and the Points belonging to the + Labels. transform is reset to the identity Transform. +

+ +
+ — Function: void reset_transform (void)
+

Resets transform to the identity Transform. +

+ +
+ — Function: Transform set_transform (const Transform& t)
+

Sets transform to t and returns t. +

+ +
+ — Function: void kill_labels (void)
+

Removes the Labels from the Picture. +

+ +
+ +


+ Next: , + Previous: Modifying Pictures, + Up: Picture Reference + +
+ +

21.7 Showing

+ +
+ — Function: void show ([string text = "", [bool stop = false]])
+

Prints information about the Picture to standard output. + +

show() first prints the string "Showing Picture:" to + standard output, followed by text, if the latter is not the empty + string ("")32. + Then it calls transform.show(), prints the size of shapes and + labels, and the value of do_labels. Then it calls + show() on each of the Shapes on shapes. Since + show() is a virtual function in class Shape, the + appropriate show() is called for each Shape, i.e., + Point::show() for a Point, Path::show() for a + Path, etc. If stop is true, execution stops and the + user is requested to type <RETURN> to continue. Finally, the string + "Done showing picture." is printed to standard output. +

+ +
+ — Function: void show_transform ([string text = "Transform from Picture:"])
+

Calls transform.show(), passing text as the argument to the + latter function. +

+ +
+ +


+ Previous: Showing Pictures, + Up: Picture Reference + +
+ +

21.8 Outputting

+ + + +
+ +


+ Next: , + Previous: Outputting Pictures, + Up: Outputting Pictures + +
+ +

21.8.1 Namespaces

+ + + + + +
21.8.1.1 Namespace Projections
+ +

The namespace Projections is defined in pictures.web. + +

+ — Constant: const unsigned short PERSP
+ — Constant: const unsigned short PARALLEL_X_Y
+ — Constant: const unsigned short PARALLEL_X_Z
+ — Constant: const unsigned short PARALLEL_Z_Y
+ — Constant: const unsigned short AXON
+ — Constant: const unsigned short ISO
+

These constants can be used for the projection argument in + Picture::output(), described in + Picture Reference; Outputting; Functions, + below. +

+ +
+ +


+ Previous: Namespace Projections, + Up: Picture Output Namespaces + +
+ +
21.8.1.2 Namespace Sorting
+ +

The namespace Sorting is defined in pictures.web. + +

+ — Constant: const unsigned short NO_SORT
+ — Constant: const unsigned short MAX_Z
+ — Constant: const unsigned short MIN_Z
+ — Constant: const unsigned short MEAN_Z
+

These constants can be used for the sort_value argument in + Picture::output(), described in + Picture Reference; Outputting; Functions, + below. +

+ +
+ +


+ Previous: Picture Output Namespaces, + Up: Outputting Pictures + +
+ +

21.8.2 Output Functions

+ +
+ — Function: void output (const Focus& f, [const unsigned short projection = Projections::PERSP, [real factor = 1, [const unsigned short sort_value = Sorting::MAX_Z, [const bool do_warnings = true, [const real min_x_proj = -40, [const real max_x_proj = 40, [const real min_y_proj = -40, [const real max_y_proj = 40, [const real min_z_proj = -40, [const real max_z_proj = 40]]]]]]]]]])
+ — Function: void output ([const unsigned short projection = Projections::PERSP, [real factor = 1, [const unsigned short sort_value = Sorting::MAX_Z, [const bool do_warnings = true, [const real min_x_proj = -40, [const real max_x_proj = 40, [const real min_y_proj = -40, [const real max_y_proj = 40, [const real min_z_proj = -40, [const real max_z_proj = 40]]]]]]]]]])
+

These functions create a two-dimensional projection of the objects on the + Picture and write MetaPost code to out_stream for + drawing it. + +

The arguments: + +

+
const Focus& f
The Focus used for projection, also known as the center of + projection, or the camera. + This argument is used in the first version only. + The second version, without a const Focus& f argument, + merely calls the first version and passes it the global variable + default_focus as its first argument, so default_focus is + effectively the default for f. Defining two versions in this way makes it + possible to call + output() with projection as its first (and possibly only) + argument. If instead, f were an optional argument with + default_focus as its default, this wouldn't have been possible. It + also wouldn't be possible to have f have a default in the first + version, and to retain the second version, because the compiler wouldn't + be able to resolve a call to output() with no arguments. + +
const unsigned short projection
Default: Projections::PERSP. + The type of projection. Valid values are const unsigned shorts + defined in namespace Projections + (see Namespace Projections):
+ PERSP for the perspective projection,
+ PARALLEL_X_Y for parallel projection onto the x-y plane,
+ PARALLEL_X_Z for parallel projection onto the x-z plane, and
+ PARALLEL_Z_Y for parallel projection onto the z-y plane. + %% !! TO DO: + I plan to add isometric and axionometric projections soon. + +
real factor
Default: 1. + Passed from output() to + extract() and from there to project(). The + world_coordinates of the Points that are projected are + multiplied by factor, which enlarges or shrinks the projected + image without altering the Picture itself. factor + is probably most useful for parallel projections, where the Focus + f isn't used; with a perspective projection, the parameters of + the Focus can be used to influence the size of the projected + image. + +
const unsigned short sort_value
Default: Sorting::MAX_Z. + The value used should be one of the constants defined in + namespace Sorting, See Namespace Sorting, above. + If MAX_Z (the default) is used, the Shapes on the + Picture are sorted according to the maximum z-value of the + projective_extremes of the Points belonging to the + Shape. If MIN_Z is used, + they are sorted according to the minimum z-value, and + if MEAN_Z is used, they are sorted according to the mean of + the maximum and minimum z-values. If NO_SORT is used, the + Shapes are output in the order in which they were put onto the + Picture. + +

The surface hiding algorithm + implemented in 3DLDF is quite primitive, and doesn't always work right. + For Shapes that intersect, it can't work right. + + I plan to work on improving the surface hiding algorithm soon. This is + not a trivial problem. To solve it properly, each Shape on a + Picture must be tested for intersection with every other + Shape on the Picture. If two or more Shapes intersect, + they must be broken up into smaller objects until there are no more + intersections. I don't expect to have a proper solution soon, but I + expect that I will be able to make some improvements. + See Surface Hiding. + +

const bool do_warnings
Default: true. If true, output() issues warnings + to stderr (standard error output) if a Shape cannot be + output because it lies + outside the limits set by the following arguments. Sometimes, a user + may only want to project a portion of a Picture, in which case + such warnings would not be helpful. In this case, do_warnings + should be false. + +
const real min_x_proj
Default: -40. The minimum x-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[0] of any Point on a + Shape is less than min_x_proj, the Shape will not be + projected at all. + +
const real max_x_proj
Default: 40. + The maximum x-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[0] of any Point on a + Shape is greater than max_x_proj, the Shape will not be + projected at all. + +
const real min_y_proj
Default: -40. + The minimum y-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[1] of any Point on a + Shape is less than min_y_proj, the Shape will not be + projected at all. + +
const real max_y_proj
Default: 40. + The maximum y-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[1] of any Point on a + Shape is greater than max_y_proj, the Shape will not be + projected at all. + +
const real min_z_proj
Default: -40. + The minimum z-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[2] of any Point on a + Shape is less than min_z_proj, the Shape will not be + projected at all. + +
const real max_z_proj
Default: 40. + The maximum z-coordinate of the projection of a + Shape such that the Shape can be output. + If projective_coordinates[2] of any Point on a + Shape is greater than max_z_proj, the Shape will not be + projected at all. +
+

+ +
+ — Function: void suppress_labels (void)
+

Suppresses output of the Labels on a Picture when + output() is called. This can be useful when a Picture is + output, transformed, and output again, one or more times, in a single figure. + Usually, it will not be desirable to have the Labels output more + than once. + +

In [next figure] + , current_picture is output three times, but the + Labels on it are only output once. + +

          Ellipse e(origin, 3, 5);
+           e.label();
+           e.draw();
+           Point pt0(-3);
+           Point pt1(3);
+           pt0.draw(pt1);
+           Point pt2(0, 0, -4);
+           Point pt3(0, 0, 4);
+           pt2.draw(pt3);
+           pt0.dotlabel("0", "lft");
+           pt1.dotlabel("1", "rt");
+           pt2.dotlabel("2", "bot");
+           pt3.dotlabel("3");
+           current_picture.output(Projections::PARALLEL_X_Z);
+           current_picture.rotate(0, 60);
+           current_picture.suppress_labels();
+           current_picture.output(Projections::PARALLEL_X_Z);
+           current_picture.rotate(0, 60);
+           current_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 79. Not displayed.] +
+
+ Fig. 79. +
+

+ +
+ +
+ — Inline function: void unsuppress_labels (void)
+

Sets do_labels to true. If a Picture contains + Labels, unsuppress_labels() ensures that they will be + output, when Picture::output() is called, so long as there is no + intervening call to suppress_labels() or kill_labels(). +

+ + + + + + +
+ +


+ Next: , + Previous: Picture Reference, + Up: Top + +
+ +

22 Point Reference

+ +

Class Point is defined in points.web. + It is derived from Shape using protected derivation. + The function + Transform Transform::align_with_axis(Point, Point, char) + is a friend of Point. + +

+ + + +

22.1 Data Members

+ +
+ — Private variable: valarray<real> world_coordinates
+

The set of four homogeneous coordinates x, y, z, and w that represent + the position of the Point within 3DLDF's global coordinate + system. +

+ +
+ — Private variable: valarray<real> projective_coordinates
+

The set of four homogeneous coordinates x, y, z, and w that represent + the position of the projection of the Point onto a + two-dimensional plane for output. The x and y values are used in the + MetaPost code written to out_stream. The z value is used + in the hidden surface algorithm (which is currently rather primitive and + doesn't work very well. see Surface Hiding). The w value can be + != 1 + , + depending on the projection used; the perspective projection is + non-affine, so w can take on other values. +

+ +
+ — Private variable: valarray<real> user_coordinates
+

A set of four homogeneous coordinates x, y, z, and w. + +

user_coordinates currently has no function. + It is intended for use in user-defined coordinate systems. For example, + a coordinate system could be defined with respect to a plane surface + that isn't parallel to one of the major planes. Such a coordinate + system would be convenient for drawing on the plane. A Transform + would make it possible to convert between user_coordinates and + world_coordinates. +

+ +
+ — Private variable: valarray<real> view_coordinates
+

A set of four homogeneous coordinates x, y, z, and w. + +

view_coordinates currently has no function. It may be useful for + displaying multiple views in an interactive graphical user interface, or + for some other purpose. +

+ +
+ — Private variable: Transform transform
+

Contains the product of the transformations applied to the Point. + When apply_transform() is called for the Point, directly + or indirectly, the world_coordinates are updated and + transform is reset to the identity Transform. + See Point Reference; Applying Transformations. +

+ +
+ — Private variable: bool on_free_store
+

Returns on_free_store. This should only be true if + the Point was dynamically allocated on the + free store. Points should only ever be dynamically + allocated by create_new<Point>(), which + uses set_on_free_store() to set on_free_store + to true. + See Point Reference; Constructors and Setting Functions, and + Point Reference; Modifying. +

+ +
+ — Private variable: signed short drawdot_value
+

Used to tell Point::output() what MetaPost drawing command + (drawdot() or undrawdot()) to write to out_stream + when outputting a Point. + +

When drawdot() or undrawdot() is called on a Point, + the Point is copied and put onto the Picture, which was + passed to + drawdot() or undrawdot() as an argument + (current_picture by + default). drawdot_value is either set to Shape::DRAWDOT + or Shape::UNDRAWDOT on the copy; this->drawdot is + not set. +

+ +
+ — Private variable: const Color* drawdot_color
+

Used to tell Point::output() what string to write to out_stream + for the color when outputting a Point. +

+ +
+ — Private variable: string pen
+

Used to tell Point::output() what string to write to out_stream + for the pen when outputting a Point. +

+ +
+ — Protected variable: valarray<real> projective_extremes
+

A set of 6 real values indicating the maximum and minumum x, y, + and + z-coordinates of the Point. + Used for determining whether a Point is projectable with the + parameters of a particular invocation of Picture::output(). + See Picture Reference; Outputting. + +

Obviously, the maxima and minima + will always be the same for a Point, namely the x, y, and + z-coordinates. + However, set_extremes() and get_extremes(), + the functions that access projective_extremes, are pure virtual + functions in class Shape, + so the Point versions must be consistent with the versions for + other types derived from Shape. +

+ +
+ — Protected variable: bool do_output
+

true by default. Set to false by suppress_output(), + which is called on a Shape by Picture::output(), if the + Shape is not projectable. + See Picture Reference; Outputting. +

+ +
+ — Public static variable: string measurement_units
+

The unit of measurement for all distances within a Picture, + "cm" (for centimeters) by default. The x and y-coordinates of + the projected Points are always followed by measurement_units + when they're written to out_stream. Unlike Metafont, units of + measurement cannot be indicated for individual coordinates. Nor can + measurement_unit be changed within a Picture. + +

When I write an input routine, I plan to make it behave the way Metafont + does, however, 3DLDF will probably also convert all of the input values + to a standard unit, as Metafont does. +

+ +
+ — Public static variable: real CURR_Y
+ — Public static variable: real CURR_Z
+

Default values for the y and z-coordinate of Points, when the + x-coordinate, or the x and y-coordinates only are specified. + Both are 0 by default. + +

These values only used in the constructor and setting function taking + one required real value (for the x-coordinate), and two optional + real values (for the y and z-coordinates). They are not used + when a Point is declared using the + default constructor with no arguments. In this case, the x, y, and + z-coordinates will all be 0. + See Point Reference; Constructors and Setting Functions. + +

          Point A(1);
+           A.show("A:");
+           -| A: (1, 0, 0);
+           CURR_Y = 5;
+           A.set(2);
+           A.show("A:");
+           -| A: (2, 5, 0);
+           CURR_Z = 12;
+           Point B(3);
+           B.show("B:");
+           -| B: (3, 5, 12);
+           Point C;
+           C.show("C:");
+           -| C: (0, 0, 0);
+ 
+
+ + + +

22.2 Typedefs and Utility Structures

+ +
+ — typedef: point_pair first second
+

Synonymous with pair<Point, Point>. +

+ +
+ — struct: bool_point b pt
+

b is a bool and pt is a Point. + bool_point also contains two constructors and an assignment + operator, described below. +

+ +
+ — Default constructor: void bool_point (void)
+

Creates a bool_point and sets b to false and + pt to INVALID_POINT. +

+ +
+ — Default constructor: void bool_point (bool bb, const Point& ppt)
+

Creates a bool_point and sets b to bb and pt + to ppt. +

+ +
+ — Assignment operator: void bool_point::operator= (const bool_point& bp)
+

Sets b to + bp.b and pt to bp.pt. +

+ +
+ — typedef: bool_point_pair first second
+

Synonymous with pair <bool_point, bool_point>. +

+ +
+ — struct: bool_point_quadruple first second third fourth
+

This structure contains four bool_points. It also has two + constructors and an assignment operator, described below. +

+ +
+ — Default constructor: void bool_point_quadruple (void)
+

Creates a bool_point_quadruple, and sets + first, second, third, and fourth all to + INVALID_BOOL_POINT. +

+ +
+ — Constructor: void bool_point_quadruple (bool_point a, bool_point b, bool_point c, bool_point d)
+

Creates a bool_point_quadruple and sets + first to a, second to b, third to + c, and fourth to d. +

+ +
+ — Assignment operator: void bool_point_quadruple::operator= (const bool_point_quadruple& arg)
+

Makes *this a copy of arg. +

+ +
+ — struct: bool_real_point b r pt
+

b is a bool, r is a real, and pt is a + Point. bool_real_point also contains three constructors + and an assignment operator, described below. +

+ +
+ — Default constructor: void bool_real_point (void)
+

Creates a bool_real_point and sets b to false, + r to INVALID_REAL and pt to INVALID_POINT. +

+ +
+ — Copy constructor: void bool_real_point (const bool_real_point& brp)
+

Creates a bool_real_point and sets b to brp.b, + r to brp.r, and pt to brp.pt. +

+ +
+ — Constructor: void bool_real_point (const bool& bb, const real& rr, const Point& ppt)
+

Creates a bool_real_point and sets b to bb, + r to rr, and pt to ppt. +

+ +
+ — Assignment operator: void bool_real_point::operator= (const bool_real_point& brp)
+

Makes *this a copy of brp. +

+ + + +

22.3 Global Constants and Variables

+ +
+ — Constant: Point INVALID_POINT
+

The x, y, and z-values in world_coordinates are all INVALID_REAL. +

+ +
+ — Constant: Point origin
+

The x, y, and z-values in world_coordinates are all 0. +

+ +
+ — Constant: bool_point INVALID_BOOL_POINT
+

b is false and pt is INVALID_POINT. +

+ +
+ — Constant: bool_point_pair INVALID_BOOL_POINT_PAIR
+

first and second are both INVALID_BOOL_POINT. +

+ +
+ — Constant: bool_real_point INVALID_BOOL_REAL_POINT
+

b is false, r is INVALID_REAL, and pt + is INVALID_POINT. +

+ +
+ — Constant: bool_point_quadruple INVALID_BOOL_POINT_QUADRUPLE
+

first, second, third, and fourth are all + INVALID_BOOL_POINT. +

+ + + +

22.4 Constructors and Setting Functions

+ +
+ — Default constructor: void Point (void)
+

Creates a Point and initializes its x, y, and z-coordinates + to 0. +

+ +
+ — Constructor: void Point (const real x, [const real y = CURR_Y, [const real z = CURR_Z]])
+

Creates a Point and initializes its x, y, and z-coordinates + to the values of the arguments x, y, and z. The + arguments y and z are optional. If they are not specified, + the values of CURR_Y and CURR_Z are used. They are 0 by + default, but can be changed by the user. This can be convenient, if all + of the Points being drawn in a particular section of a program + have the same z or y and z values. +

+ +
+ — Setting function: void set (const real x, [const real y = CURR_Y, [const real z = CURR_Z]])
+

Corresponds to the constructor above, but is used for resetting the coordinates of an existing + Point. +

+ +
+ — Copy constructor: void Point (const Point& p)
+

Creates a Point and copies the values for its x, y, and z-coordinates + from p. +

+ +
+ — Setting function: void set (const Point& p)
+

Corresponds to the copy constructor above, but is used for resetting the coordinates + of an existing Point. This function exists purely as a convenience; + the operator operator=() + (see Point Reference; Operators) + performs exactly the + same function. +

+ +
+ — Template specializations: Point* create_new<Point> (const Point* p)
+ — : Point* create_new<Point> (const Point& p)
+

Pseudo-constructors for dynamic allocation of Points. + They create a Point on the free store and allocate memory for it using + new(Point). They return a pointer to the new Point. + +

If p is a non-zero pointer or a reference, + the new Point will be a copy of + p. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Point>() as its argument. + See Dynamic Allocation of Shapes, for more information. + +

One use for create_new<Point> is in the constructors for + classes of + objects that can contain a variable number of Points, such as + Path and Polygon. Another use is in the drawing and + filling functions, where objects are copied and the copies put onto a + Picture. + +

Programmers who dynamically allocate Points must ensure that they + are deallocated properly using delete! +

+ + + +

22.5 Destructor

+ +
+ — virtual Destructor: void ~Point (void)
+

This function currently has an empty definition, but its existence + prevents GCC 3.3 from issuing the following warning: + “`class Point' has virtual functions but non-virtual destructor”. +

+ +
+ +


+ Next: , + Previous: Point Destructor, + Up: Point Reference + +
+ +

22.6 Operators

+ +
+ — Assignment operator: void operator= (const Point& p)
+

Makes *this a copy of p. +

+ +
+ — Operator: Transform operator*= (const Transform& t)
+

Multiplies transform by t. + By multiplying a Point successively by + one or more Transforms, the effect of the transformations is + “saved up” in transform. Only when an operation that needs + updated values for the world_coordinates is called on a + Point, or the Point is passed as an argument to such an + operation, is the transformation stored in transform applied to + world_coordinates by apply_transform(), + which subsequently, resets transform to + the identity Transform. + See Point Reference; Applying Transformations. +

+ +
+ — const operator: Point operator+ (Point p)
+

Returns a Point with world_coordinates that are the sums of + the corresponding world_coordinates of *this and p, + after they've been updated. + *this remains unchanged; as in many other functions with + Point arguments, p is passed by value, because + apply_transform() must be called on it, in order to update its + world_coordinates. If p were a const Point&, it + would have to copied within the function anyway, because + apply_transform() is a non-const operation. + +

          Point p0(-2, -6, -28);
+           Point p1(3, 14, 92);
+           Point p2(p0 + p1);
+           p2.show("p2:");
+           -| p2: (1, 8, 64)
+ 
+
+ +
+ — Operator: void operator+= (Point p)
+

Adds the updated world_coordinates of p to those of + *this. + Equivalent in effect to shift(p) + In fact, this + function merely calls p.apply_transform() and + Point::shift(real, real, real) with p's x, y, and z + coordinates (from world_coordinates) as its arguments. + See Point Reference; Affine Transformations. +

+ +
+ — const operator: Point operator- (Point p)
+

Returns a Point with world_coordinates representing the + difference between the updated values of + this->world_coordinates and + p.world_coordinates. +

+ +
+ — Operator: void operator-= (Point p)
+

Subtracts the updated values of p.world_coordinates from + those of this->world_coordinates. +

+ +
+ — Operator: real operator*= (const real r)
+

Multiplies the updated x, y, and z coordinates (world_coordinates) of + the Point by r and returns r. This makes it possible to + chain invocations of this function. + +

If P is a Point then + P *= r is + equivalent in its effect to P.scale(r, r, r), + except that + P.world_coordinates is modified directly and immediately, + without changing P.transform. This is possible, because this + function calls apply_transform() to update the + world_coordinates before multiplying them r, so + transform is the identity Transform. + +

          Point P(1, 2, 3);
+           P *= 7;
+           P.show("P:");
+           -| P: (7, 14, 21);
+           Point Q(1.5, 2.7, 13.82);
+           Q *= P *= -1.28;
+           P.show("P:");
+           -| P: (-8.96, -17.92, -26.88)
+           Q.show("Q:");
+           -| Q: (-1.92, -3.456, -17.6896)
+ 
+
+ +
+ — const operator: Point operator* (const real r)
+

Returns a Point with x, y, and z coordinates + (world_coordinates) equal to the updated x, y, and z coordinates + of *this multiplied by r. +

+ +
+ — Non-member operator: Point operator* (const real r, const Point& p)
+

Equivalent to Point::operator*(const real r) (see above), + but with r placed first. +

          Point p0(10, 11, 12);
+           real r = 2.5;
+           Point p1 = r * p0;
+           p1.show();
+           -|Point:
+           -|(25, 27.5, 30)
+ 
+
+ +
+ — const operator: Point operator- (void)
+

Unary minus (prefix). Returns a Point with x, y, and z + coordinates (world_coordinates) equal to the + the x, y, and z-coordinates (world_coordinates) of + *this multiplied by -1. +

+ +
+ — Operator: void operator/= (const real r)
+

Divides the updated x, y, and z coordinates (world_coordinates) of + the Point by r. +

+ +
+ — const operator: Point operator/ (const real r)
+

Returns a Point with x, y, and z coordinates + (world_coordinates) equal to the updated x, y, and z coordinates + of *this + divided by r. +

+ +
+ — Operator: bool operator== (Point p)
+ — const operator: bool operator== (const Point& p)
+

Equality comparison for Points. These functions return + true if the updated values of the world_coordinates of the two + Points differ by less than the value returned by + Point::epsilon(), otherwise false. + See Point Reference; Returning Information. +

+ +
+ — const operator: bool operator!= (const Point& p)
+

Inequality comparison for Points. Returns false if + *this == p, otherwise true. +

+ +
+ +


+ Next: , + Previous: Point Operators, + Up: Point Reference + +
+ +

22.7 Copying

+ +
+ — const function: Shape* get_copy (void)
+

Creates a copy of the Point, and allocates memory for it on the + free store using create_new<Point>(). + It returns a pointer to Shape that points to the new Point. + This function is used in the drawing commands for putting Points + onto Pictures. + See Point Reference; Drawing. +

+ +
+ +


+ Next: , + Previous: Copying Points, + Up: Point Reference + +
+ +

22.8 Querying

+ +
+ — inline function: bool is_identity (void)
+

Returns true if transform is the identity Transform. +

+ +
+ — const inline function: Transform get_transform (void)
+

Returns transform. +

+ +
+ — const function: bool is_on_free_store (void)
+

Returns true if memory for the Point has been dynamically + allocated on the + free store, i.e., if the Point has been created using + create_new<Point>(). + See Point Reference; Constructors and Setting Functions. +

+ +
+ — const function: bool is_on_plane (const Plane& p)
+

Returns true, if the Point lies on the + Plane p, otherwise false. + +

Planes are conceived of as having infinite extension, so while + the Point C in [next figure] + does not lie within + the Rectangle r, it does lie on q, so + C.is_on_plane(q) returns + true.33 + +

          Point P(1, 1, 1);
+           Rectangle r(P, 4, 4, 20, 45, 35);
+           Plane q = r.get_plane();
+           Point A(2, 0, 2);
+           Point B(2, 1.64143, 2);
+           Point C(0.355028, 2.2185, 6.48628);
+           cout << A.is_on_plane(q);
+           -| 0
+           cout << B.is_on_plane(q);
+           -| 1
+           cout << "C.is_on_plane(q)";
+           -| 1
+ 
+

+
+ [Figure 80. Not displayed.] +
+
+ Fig. 80. +
+

+ +
+ +
+ — const function: bool is_in_triangle (const Point& p0, const Point& p1, const Point& p2, [bool verbose = false, [bool test_points = true]])
+

Returns true, if *this lies within the triangle determined by + the three Point arguments, otherwise false. + +

If the code calling is_in_triangle() has ensured that + p_0, p_1, and p_2 determine a plane, i.e., that they are not + colinear, and that *this lies in that plane, then + false can be passed to is_in_triangle() as its + test_points argument. + +

If the verbose argument is true, information resulting from + the execution of the function are printed to standard output or standard + error. + +

This function is needed for determining whether a line intersects with a + polygon. +

+ +
+ +


+ Next: , + Previous: Querying Points, + Up: Point Reference + +
+ +

22.9 Returning Coordinates

+ +

The functions in this section return either a single coordinate or a set of + coordinates. Each has + a const and a non-const version. + +

The arguments are the same, with one exception: + +

+
char c
Only in get_coord(). Indicates which coordinate should be + returned. Valid values are 'x', 'X', 'y', + 'Y', 'z', 'Z', 'w', and 'W'. + +
char coords
Indicates the set of coordinates which should be returned or from which + the coordinate to be returned should be chosen from. Valid values are + 'w' for world_coordinates (the default), 'p' for + projective_coordinates, 'u' for user_coordinates, + and 'v' for view_coordinates. + +
const bool do_persp
Only relevant if projective_coordinates, or one of its elements + is to be returned. If true, the + default, then project() is called, thereby generating values for + projective_coordinates. If do_persp is false, then + projective_coordinates, or one of its elements, is + returned unchanged, which may sometimes be useful. + +
const bool do_apply
If true (the default), apply_transform() is called, + thereby updating the world_coordinates. Otherwise, it's not, so + that the values stored in world_coordinates remain unchanged. + Note that if coords is 'p' and do_persp is true, + apply_transform() will be called in project() + whether do_apply is true or false. If for some + reason, one wanted get projective_coordinates, or one of its + values, based on the + projection of world_coordinates without first updating them, one + would have to call reset_transform() before calling one of + these functions. It would probably be a good idea to save transform + before doing so. + +
Focus* f
Indicates what Focus is to be used for projection. + Only relevant if coords is 'p', i.e., + projective_coordinates, or one of its elements, is to be + returned. The default is 0, in which case f points to the global + variable default_focus. + +
const unsigned short proj
Indicates what form of projection is to be used. + Only relevant if coords is 'p', i.e., + projective_coordinates, or one of its elements, is to be + returned. The default is Projections::PERSP, which causes the + perspective projection to be applied. + +
real factor
Passed to project(). The values of the x and y coordinates in + projective_coordinates are multiplied by factor. + Only relevant if coords is 'p', i.e., + projective_coordinates, or one of its elements, is to be + returned. The default is 1. +
+ +
+ — Function: valarray <real> get_all_coords ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns one of the sets of coordinates; world_coordinates by + default. + Returns a complete set of coordinates: 'w' for world_coordinates, + 'p' for projective_coordinates, 'u' for + user_coordinates, or'v' for view_coordinates. +

+ +
+ — Function: real get_coord (char c, [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns one coordinate, x, y, z, or w, from the set of + coordinates indicated (or world_coordinates, by default). +

+ +
+ — Function: real get_x ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the x-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ +
+ — Function: real get_y ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the y-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ +
+ — Function: real get_z ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the z-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ +
+ — Function: real get_w ([char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [real factor = 1]]]]]])
+

Returns the w-coordinate from the set of coordinates indicated (or + world_coordinates, by default). +

+ +
+ +


+ Next: , + Previous: Returning Coordinates, + Up: Point Reference + +
+ +

22.10 Returning Information

+ +
+ — Static function: real epsilon (void)
+

Returns the positive real value of smallest magnitude + \epsilon that should be used as a coordinate value in a + Point. + A coordinate of a Point may also contain + -\epsilon. + +

The value \epsilon is used for testing the equality of + Points in Point::operator==() + (see Point Reference; Operators): + +

Let \epsilon be the value returned by epsilon(), + P and Q be + Points, and P_x, Q_x, P_y, Q_y, + P_z, and Q_z the updated x, y, and z-coordinates of P and Q, + respectively. + If and only if + ||P_x| - |Q_x|| < \epsilon, ||P_y| - |Q_y|| < \epsilon, + and + ||P_z| - |Q_z|| < \epsilon, then + P = Q. + +

epsilon() returns different values, depending on whether + real is float or double: + If real is float (the default), epsilon() + returns 0.00001. + If real is double, it returns 0.000000001. + +

Please note: I haven't tested whether 0.000000001 is a good + value yet, so users should be aware of this if they set real to + double!34 + The way to test this is to start with two Points + P and Q at different locations. + Then they should be transformed using different rotations in such a way + that they should end up at the same location. + Let \epsilon stand for the value returned by epsilon(), + and let x, y, and y stand for + the world_coordinates of the Points after + apply_transform() has been called on them. + If x_P = x_Q, y_P = y_Q, and + z_P = z_Q, + \epsilon is a good value. + +

Rotation causes a significant loss of precision to due to the use of the + sin() and cos() functions. Therefore, neither + Point::epsilon() nor Transform::epsilon() + (see Tranform Reference; Returning Information) + can be as small as I'd like them to be. If they are two + small, operations that test for equality of Transforms and + Points will return false for objects that should be + equal. +

+ + + +

22.11 Modifying

+ +
+ — Virtual function: bool set_on_free_store ([bool b = true])
+

This function is used in the template function + create_new(). It sets on_free_store to true. + See Point Reference; Data Members, and + Point Reference; Constructors and Setting Functions. +

+ +
+ — Function: void clear (void)
+

Sets all of the coordinates in all of the sets of coordinates (i.e., + world_coordinates, user_coordinates, view_coordinates, and + projective_coordinates) to 0 and resets transform +

+ +
+ — Function: void clean ([int factor = 1])
+

Calls apply_transform() and sets the values of + world_coordinates to 0, whose absolute values are less than + epsilon() * factor + . +

+ +
+ — Function: void reset_transform (void)
+

Sets Transform to the identity Transform. Performed in + apply_transform(), after the latter updates world_coordinates. + Point Reference; Applying Transformations. +

+ + + +

22.12 Affine Transformations

+ +
+ — Function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — Function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+ — Function: Transform rotate (const Path& p, [const real angle = 180])
+

Each of these functions calls the corresponding version of + Transform::rotate(), and returns its + return value, namely, a Transform representing the rotation + only. + +

In the first version, taking three real arguments, the + Point is rotated x degrees around the x-axis, y + degrees around the y-axis, and z degrees around the z-axis in + that order. + +

          Point p0(1, 0, 2);
+           p0.rotate(90);
+           p0.show("p0:")
+           -| p0: (1, 2, 0)
+           Point p1(-1, 1, 1);
+           p1.rotate(-90, 90, 90);
+           p1.show("pt1:");
+           -| p1: (1, -1, -1)
+ 
+

+
+ [Figure 81. Not displayed.] +
+
+ Fig. 81. +
+

+ +

Please note that rotations are not commutative operations. Nor are they + commutative with other transformations. + So, if you want to rotate a Point about the x, y and z-axes in + that order, + you can do so with a single invocation of rotate(), as in + the previous example. + However, if you want to rotate a Point first about the + y-axis and then about the x-axis, you must invoke rotate() twice. + +

          Point pt0(1, 1, 1);
+           pt0.rotate(0, 45);
+           pt0.rotate(45);
+           pt0.show("pt0:");
+           -| pt0: (0, 1.70711, 0.292893)
+ 
+

In the version taking two Point arguments p0 and p1, + and a real argument angle, the Point is rotated + angle degrees around the axis determined + by p0 and p1, 180 degrees + by default. + +

          Point P(2, 0, 0);
+           Point A;
+           Point B(2, 2, 2);
+           P.rotate(A, B, 180);
+ 
+

+
+ [Figure 82. Not displayed.] +
+
+ Fig. 82. +
+

+ +
+ +
+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Calls transform.scale(x, y, z) and returns its + return value, namely, a Transform representing the scaling operation + only. + +

Scaling causes the x-coordinate of the Point to be multiplied by + x, the y-coordinate of the Point to be multiplied by + y, and the z-coordinate of the Point to be multiplied by + z. + +

          Point p0(1, 0, 3);
+           p0.scale(4);
+           p0.show("p0:");
+           -| p0: (4, 0, 3)
+           Point p1(-2, -1, -2);
+           p1.scale(-2, -3, -4);
+           p1.show("p1:");
+           -| p1: (4, 3, 8)
+ 
+

+
+ [Figure 83. Not displayed.] +
+
+ Fig. 83. +
+

+ +
+ +
+ — Function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+

Calls transform.shear() with the same arguments + and returns its + return value, namely, a Transform representing the shearing operation + only. + +

Shearing modifies each coordinate of a Point + proportionately to the values of the other two coordinates. + Let x_0, y_0, and z_0 stand for the coordinates of + a Point P before P.shear(\alpha, \beta, + \gamma, \delta, \epsilon, \zeta + ), + and x_1, y_1, and z_1 + for its coordinates afterwards. + +

          x_1 == x_0 + \alpha y + \beta z
+           y_1 == y_0 + \gamma x + \delta z
+           z_1 == z_0 + \epsilon x + \zeta y
+ 
+

[next figure] + demonstrates the effect of shearing the four + Points of a + 3 * 3 + +

Rectangle (i.e., a square) r in the x-y plane using only an + xy argument, making it non-rectangular. + +

          Point P0;
+           Point P1(3);
+           Point P2(3, 3);
+           Point P3(0, 3);
+           Rectangle r(p0, p1, p2, p3);
+           r.draw();
+           r.shear(1.5);
+           r.draw(black, "evenly");
+ 
+

+
+ [Figure 84. Not displayed.] +
+
+ Fig. 84. +
+

+ +
+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Function: Transform shift (const Point& p)
+

Each of these functions calls the corresponding version of + Transform::shift() on transform, and returns its return + value, namely, a Transform representing the shifting operation + only. + +

The Point is shifted x units in the direction of the + positive x-axis, y units in the direction of the + positive y-axis, and z units in the direction of the + positive z-axis. + +

          p0(1, 2, 3);
+           p0.shift(2, 3, 5);
+           p0.show("p0:");
+           -| p0: (3, 5, 8)
+ 
+
+ +
+ — Function: Transform shift_times (real x, [real y = 1, [real z = 1]])
+ — Function: Transform shift_times (const Point& p)
+

Each of these functions calls the corresponding version of + Transform::shift_times() on transform and + returns its return value, namely the new value of transform. + +

shift_times() makes it possible to increase the magnitude of a + shift applied to a Point, while maintaining its direction. + Please note that shift_times() will only have an effect + if it's called after a call to + shift() and before transform is reset. + This is performed by reset_transform(), which is called in + apply_transform(), and can also be called directly. + See Transform Reference; Resetting, and + Point Reference; Applying Transformations. + +

          Point P;
+           P.drawdot();
+           P.shift(1, 1, 1);
+           P.drawdot();
+           P.shift_times(2, 2, 2);
+           P.drawdot();
+           P.shift_times(2, 2, 2);
+           P.drawdot();
+           P.shift_times(2, 2, 2);
+           P.drawdot();
+ 
+

+
+ [Figure 85. Not displayed.] +
+
+ Fig. 85. +
+

+ +
+ + + +

22.13 Applying Transformations

+ +
+ — Function: void apply_transform (void)
+

Updates world_coordinates by multiplying it by transform, + which is subsequently reset to the identity Transform. +

+ + + +

22.14 Projecting

+ +
+ — Function: bool project (const Focus& f, [const unsigned short proj = Projections::PERSP, [real factor = 1]])
+ — Function: bool project ([const unsigned short& proj = Projections::PERSP, [real factor = 1]])
+

These functions calculate projective_coordinates. + proj indicates which projection is to be performed. + If it is Projections::PERSP, then f indicates which + Focus is to be used (in the first version), or the global variable + default_focus is used (in the second). If + Projections::PARALLEL_X_Y, Projections::PARALLEL_X_Z, or + Projections::PARALLEL_Z_Y is used, f is ignored, since + these projections don't use a Focus. Currently, no other + projections are defined. The x and y coordinates in + projective_coordinates are multiplied by factor with the default + being 1. +

+ +
+ +


+ Next: , + Previous: Projecting Points, + Up: Point Reference + +
+ +

22.15 Vector Operations

+ +

Mathematically speaking, vectors and points are not the same. However, + they can both be represented as triples of real numbers (in a + three-dimensional Cartesian space). It is sometimes convenient to treat + points as though they were vectors, and vice versa. In particular, it + is convenient to use the same data type, namely class Point, to + represent both points and vectors in 3DLDF. + +

+ — const function: real dot_product (Point p)
+

Returns the dot or scalar product of *this and p. + +

If P and Q are Points, +

          P \dot Q = x_P * x_Q + y_P * y_Q + z_P * z_Q = |P||Q| * cos(\theta)
+ 
+

where |P| + and |Q| are the magnitudes of + P and Q, respectively, and \theta + is the angle between P and Q. + +

Since +

          \theta = arccos(P \dot Q / |P||Q|),
+ 
+

the dot product can be used for finding the angle between two vectors. + +

          Point P(1, -1, -1);
+           Point Q(3, 2, 5);
+           cout << P.angle(Q);
+           -| 112.002
+           cout << P.dot_product(Q);
+           -| -4
+           real P_Q_angle = (180.0 / PI)
+                            * acos(P.dot_product(Q)
+                            / (P.magnitude() * Q.magnitude()));
+           cout << P_Q_angle;
+           -| 112.002
+ 
+

+
+ [Figure 86. Not displayed.] +
+
+ Fig. 86. +
+

+ +

If the angle \theta between two vectors P and Q is + 90 degrees + , then + \cos(\theta) is 0, so + P \dot Q + will also be 0. Therefore, + dot_product() can be used as a test for the orthogonality of vectors. + +

          Point P(2);
+           Point Q(P);
+           Point Q0(P0);
+           Q0 *= Q.rotate(0, 0, 90);
+           P *= Q.rotate(0, 45, 45);
+           P *= Q.rotate(45);
+           cout << P.angle(Q);
+           -| 90
+           cout << P.dot_product(Q);
+           -| 0
+ 
+

+
+ [Figure 87. Not displayed.] +
+
+ Fig. 87. +
+

+ +
+ +
+ — const function: Point cross_product (Point p)
+

Returns the cross or vector product of *this and p. + +

If P and Q are Points, + +

          P * Q = ((y_P * z_Q - z_P * y_Q), (z_P * x_Q - x_P * z_Q),
+           (x_P * y_Q - y_P * x_Q)) = |P||Q| * sin(\theta) * n,
+ 
+

where |P| and |Q| are the magnitudes of + P and Q, respectively, + \theta is the angle between P and Q, and n + is a unit vector + perpendicular to both P and Q in the direction of a + right-hand screw from P towards Q. Therefore, + cross_product() can be used to find the normals to planes. + +

          Point P(2, 2, 2);
+           Point Q(-2, 2, 2);
+           Point n = P.cross_product(Q);
+           n.show("n:");
+           -| n: (0, -8, 8)
+           real theta = (PI / 180.0) * P.angle(Q);
+           cout << theta;
+           -| 1.23096
+           real n_mag = P.magnitude() * Q.magnitude() * sin(theta);
+           cout << n_mag;
+           -| 11.3137
+           n /= n_mag;
+           cout << n.magnitude();
+           -| 1
+ 
+

+
+ [Figure 88. Not displayed.] +
+
+ Fig. 88. +
+

+ +

If + \theta = 0 degrees or 180 degrees, + \sin(\theta) will be 0, and + P * Q + will be (0, 0, 0). + The cross product thus provides a test for parallel vectors. + +

          Point P(1, 2, 1);
+           Point Q(P);
+           Point R;
+           R *= Q.shift(-3, -1, 1);
+           Point s(Q - R);
+           Point n = P.cross_product(s);
+           n.show("n:");
+           -| n: (0, 0, 0)
+ 
+

+
+ [Figure 89. Not displayed.] +
+
+ Fig. 89. +
+

+ +
+ +
+ — const function: real magnitude (void)
+

Returns the magnitude of the Point. This is its distance from + origin and is equal to + sqrt(x^2 + y^2 + z^2). + +

          Point P(13, 15.7, 22);
+           cout << P.magnitude();
+           -| 29.9915
+ 
+
+ +
+ — const function: real angle (Point p)
+

Returns the angle in degrees between two Points. + +

          Point P(3.75, -1.25, 6.25);
+           Point Q(-5, 2.5, 6.25);
+           real angle = P.angle(Q);
+           cout << angle;
+           -| 73.9084
+           Point n = origin.get_normal(P, Q);
+           n.show("n:");
+           -| n: (0.393377, 0.91788, -0.0524503)
+ 
+

+
+ [Figure 90. Not displayed.] +
+
+ Fig. 90. +
+

+ +
+ +
+ — Function: Point unit_vector (const bool assign, [const bool silent = false])
+ — const function: Point unit_vector (void)
+

These functions return a Point with the x, y, and z-coordinates + of world_coordinates divided by the magnitude of the Point. + The magnitude of the resulting Point is thus 1. The first + version assigns the result to *this and should only ever be + called with assign = true. Calling it with the + argument false is equivalent to calling the const version, + with no assignment. If unit_vector() is called with assign + and silent both false, it issues a warning message is + issued and the const version is called. If silent is + true, the message is suppressed. + +

          Point P(21, 45.677, 91);
+           Point Q = P.unit_vector();
+           Q.show("Q:");
+           -| Q: (0.201994, 0.439357, 0.875308)
+           P.rotate(30, 25, 10);
+           P.show("P:");
+           P: (-19.3213, 82.9627, 59.6009)
+           cout << P.magnitude();
+           -| 103.963
+           P.unit_vector(true);
+           P.show("P:");
+           -| P: (-0.185847, 0.797999, 0.573287)
+           cout << P.magnitude();
+           -| 1
+ 
+
+ +
+ +


+ Next: , + Previous: Vector Operations, + Up: Point Reference + +
+ +

22.16 Points and Lines

+ +
+ — const function: Line get_line (const Point& p)
+

Returns the Line l corresponding to the line from *this to + p. l.position will be *this, and + l.direction will be p - *this. + See Line Reference. +

+ +
+ — const function: real slope (Point p, [char m = 'x', [char n = 'y']])
+

Returns a real number representing the slope of the trace + of the line defined by + *this and p on the plane indicated by the arguments m + and n. + +

          Point p0(3, 4, 5);
+           Point p1(2, 7, 12);
+           real r = p0.slope(p1, 'x', 'y');
+           ⇒ r == -3
+           r = p0.slope(p1, 'x', 'z');
+           ⇒ r == -7
+           r = p0.slope(p1, 'z', 'y');
+           ⇒ r == 0.428571
+ 
+
+ +
+ — Function: bool_real is_on_segment (Point p0, Point p1)
+ — const function: bool_real is_on_segment (const Point& p0, const Point& p1)
+

These functions return a bool_real, where the bool part is + true, if + the Point lies on the line segment between p0 and p1, + otherwise false. If the Point lies on the line segment, the + real part is a value + r such that + 0 <= r <= 1 + indicating how far the Point is along the way from + p0 to p1. For example, if the Point is half of the way + from p0 to p1, r will be .5. If the Point + does not lie on the line + segment, but on the line passing through p0 and p1, + r will be <0 or >1. + +

If the Point doesn't lie on the line passing through p0 and + p1, + r will be INVALID_REAL. + +

          Point p0(-1, -2, 1);
+           Point p1(3, 2, 5);
+           Point p2(p0.mediate(p1, .75));
+           Point p3(p0.mediate(p1, 1.5));
+           Point p4(p2);
+           p4.shift(-2, 1, -1);
+           bool_real br = p2.is_on_segment(p0, p1);
+           cout << br.first;
+           -| 1
+           cout << br.second;
+           -| 0.75
+           bool_real br = p3.is_on_segment(p0, p1);
+           cout << br.first;
+           -| 0
+           cout << br.second;
+           -| 1.5
+           bool_real br = p4.is_on_segment(p0, p1);
+           cout << br.first;
+           -| 0
+           cout << br.second;
+           -| 3.40282e+38
+           cout << (br.second == INVALID_REAL)
+           -| 1
+ 
+

+
+ [Figure 91. Not displayed.] +
+
+ Fig. 91. +
+

+ +
+ +
+ — const function: bool_real is_on_line (const Point& p0, const Point& p1)
+

Returns a bool_real where the bool part is true, if + the Point lies on the line passing through p0 and p1, + otherwise false. If the Point lies on the line, the + real part is a value r indicating how how far the Point + is along the way from p0 to p1, otherwise + INVALID_REAL. The following + values of r are possible for a call to P.is_on_line(A, B), + where the Point P lies on the line + AB: + +

          P == A —> r== 0.
+           
+           P == B —> r== 1.
+           
+           P lies on the opposite side of A from B —> r < 0.
+           
+           P lies between A and B —> 0 <  r < 1.
+           
+           P lies on the opposite side of A from B —> r > 1
+ 
+
          Point A(-1, -2);
+           Point B(2, 3);
+           Point C(B.mediate(A, 1.25));
+           bool_real br = C.is_on_line(A, B);
+           Point D(A.mediate(B));
+           br = D.is_on_line(A, B);
+           Point E(A.mediate(B, 1.25));
+           br = E.is_on_line(A, B);
+           Point F(D);
+           F.shift(-1, 1);
+           br = F.is_on_line(A, B);
+ 
+

+
+ [Figure 92. Not displayed.] +
+
+ Fig. 92. +
+

+ +
+ +
+ — const function: Point mediate (Point p, [const real r = .5])
+

Returns a Point r of the way from *this to p. + +

          Point p0(-1, 0, -1);
+           Point p1(10, 0, 10);
+           Point p2(5, 5, 5);
+           Point p3 = p0.mediate(p1, 1.5);
+           p3.show("p3:");
+           -| p3: (15.5, 0, 15.5)
+           Point p4 = p0.mediate(p2, 1/3.0);
+           p4.show("p4:");
+           -| p4: (1, 1.66667, 1)
+ 
+

+
+ [Figure 93. Not displayed.] +
+
+ Fig. 93. +
+

+ +
+ +
+ +


+ Next: , + Previous: Points and Lines, + Up: Point Reference + +
+ +

22.17 Intersections

+ +
+ — Static function: bool_point intersection_point (Point p0, Point p1, Point q0, Point q1)
+ — Static function: bool_point intersection_point (Point p0, Point p1, Point q0, Point q1, const bool trace)
+

These functions find the intersection point, if any, of the lines determined by + p0 and p1 on the one hand, and q0 and q1 on the other. + +

Let bp be the bool_point returned by + intersection_point(). If an intersection point is found, the + corresponding Point will be stored in bp.pt, otherwise, + bp.pt will be set to INVALID_POINT. If the intersection + point lies on both of the line segments, bp.b will be + true, otherwise, false. + +

The two versions use different methods of finding the intersection + point. The first uses a vector calculation, the second looks for the + intersections of the traces of the lines on the major planes. If the + trace argument is used, the second version will be called, whether + trace is true or false. Ordinarily, there should be + no need to use the trace version. + +

          Point A(-1, -1);
+           Point B(1, 1);
+           Point C(-1, 1);
+           Point D(1, -1);
+           bool_point bp = Point::intersection_point(A, B, C, D);
+           bp.pt.dotlabel("$i$");
+           cout << "bp.b == " << bp.b << endl << flush;
+           -| bp.b == 1
+ 
+

+
+ [Figure 94. Not displayed.] +
+
+ Fig. 94. +
+

+ +
          Point A(.5, .5);
+           Point B(1.5, 1.5);
+           Point C(-1, 1);
+           Point D(1, -1);
+           bool_point bp = Point::intersection_point(A, B, C, D, true);
+           bp.pt.dotlabel("$i$");
+           cout << "bp.b == " << bp.b << endl << flush;
+           -| bp.b == 0
+ 
+

+
+ [Figure 95. Not displayed.] +
+
+ Fig. 95. +
+

+ +
+ +
+ +


+ Next: , + Previous: Point Intersections, + Up: Point Reference + +
+ +

22.18 Drawing

+ +

There are two versions for each of the drawing functions. The second + one has the Picture argument picture at the beginning of the + argument list, rather than at the end. This is convenient when passing + a picture argument. Where picture is optional, the default + is always current_picture. + +

+ +

+ — const function: void drawdot ([const Color& ddrawdot_color = *Colors::default_color, [const string ppen = "", [Picture& picture = current_picture]]])
+ — const function: void drawdot ([Picture& picture = current_picture, [const Color& ddrawdot_color = *Colors::default_color, [const string ppen = "", ]]])
+

Draws a dot on picture. If ppen is specified, a “pen + expression” is included in the drawdot command written to + out_stream. Otherwise, MetaPost's currentpen is used. + If ddrawdot_color is specified, the dot will be drawn using that + Color. Otherwise, the Color currently pointed to by the pointer + Colors::default_color will be used. This will normally be + Colors::black. See Color Reference, for more information + about Colors and the namespace Colors. + +

Please note that the “dot” will always be parallel to the plane of + projection. Even where it appears to be a surface, as in [next figure] + , it + is never put into perspective, but will always have the same size and + shape. + +

          Point P(1, 1);
+           P.drawdot(gray, "pensquare scaled 1cm");
+ 
+

+
+ [Figure 96. Not displayed.] +
+
+ Fig. 96. +
+

+ +
+ +
+ — Function: void undrawdot ([string pen = "", [Picture& picture = current_picture]])
+ — Function: void undrawdot ([Picture& picture = current_picture, [string pen = ""]])
+

Undraws a dot on picture. If ppen is specified, a “pen + expression” is included in the undrawdot command written to + out_stream. Otherwise, MetaPost's currentpen is used. + +

          Point P(1, 1);
+           P.drawdot(gray, "pensquare scaled 1cm");
+           P.undrawdot("pencircle scaled .5cm");
+ 
+

+
+ [Figure 97. Not displayed.] +
+
+ Fig. 97. +
+

+ +
+ +
+ — Function: void draw (const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture, [bool aarrow = false]]]]])
+ — Function: void draw (Picture& picture = current_picture, const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [bool aarrow = false]]]])
+

Draws a line from *this to p. + Returns the Path *this -- p1. + See Path Reference; Drawing and Filling, + for more information. + +

          Point P(-1, -1, -1);
+           Point Q(2, 3, 5);
+           P.draw(Q, Colors::gray, "", "pensquare scaled .5cm");
+ 
+

+
+ [Figure 98. Not displayed.] +
+
+ Fig. 98. +
+

+ +
+ +
+ — Function: void undraw (const Point& p, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]])
+ — Function: void undraw (Picture& picture, const Point& p, [string ddashed = "", [string ppen = ""]])
+

Undraws a line from *this to p. + Returns the Path *this -- p1. + See Path Reference; Drawing and Filling, + for more information. + +

          Point P(-1, -1, -1);
+           Point Q(2, 3, 5);
+           P.draw(Q, Colors::gray, "", "pensquare scaled .5cm");
+           P.undraw(Q, "evenly scaled 6", "pencircle scaled .3cm");
+ 
+

+
+ [Figure 99. Not displayed.] +
+
+ Fig. 99. +
+

+ +
+ +

+ +

+ — Function: Path draw_help (const Point& p, [const Color& ddraw_color = *Colors::help_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — Function: Path draw_help (Picture& picture, const Point& p, [const Color& ddraw_color = *Colors::help_color, [string ddashed = "", [string ppen = ""]]])
+

Draws a “help line” from *this to p, but only if the + static Path data member do_help_lines is true. + See Path Reference; Data Members. + +

“Help lines” are lines that are used when constructing a drawing, but + that should not be printed in the final version. +

+ +
+ — Function: Path drawarrow (const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — Function: Path drawarrow (Picture& picture, const Point& p, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = ""]]])
+

Draws an arrow from *this to p and returns + the Path *this -- p. + The second version is convenient for passing a Picture argument + without having to specify all of the other arguments. + +

          Point P(-3, -2, 1);
+           Point Q(3, 3, 5);
+           P.drawarrow(Q);
+ 
+

+
+ [Figure 100. Not displayed.] +
+
+ Fig. 100. +
+

+ +
+ +
+ +


+ Next: , + Previous: Point Drawing Functions, + Up: Point Reference + +
+ +

22.19 Labelling

+ +

Labels make it possible to include TeX text within a drawing. + Labels are implemented by means of class Label. + The functions label() and dotlabel(), described in this + section, create objects of type Label, and add them to the + Picture, which was passed to them as an argument + (current_picture, by default). + See Label Reference, for more information. + +

+ — const function: void label (const string text_str, [const string position_str = "top", [const bool dot = false, [Picture& picture = current_picture]]])
+ — const function: void label (const short text_short, [const string position_str = "top", [const bool dot = false, [Picture& picture = current_picture]]])
+

These functions cause a Point to be labelled in the drawing. + The first argument is the text of the label. It can either be a + string, in the first version, or a short, in the second. + It will often be the name of the Point in the C++ + code, for + example, "p0". + It is not possible to automate this kind of + labelling, because it is not possible to access the names of variables + through the variables themselves in C++ + . + +

text_str is always placed between + “btex'' and “etex” in the MetaPost label command + written to out_stream. This makes it possible to include math + mode material in the text of labels, as in the following example. + +

          Point p0(2, 3);
+           p0.label("$p_0$");
+ 
+

+
+ [Figure 101. Not displayed.] +
+
+ Fig. 101. +
+

+ +

If backslashes are needed in the text of the label, then + text_str must contain double backslashes, so that single + backslashes will be written to out_stream. + +

          Point P;
+           Point Q(2, 2);
+           Point R(P.mediate(Q));
+           R.label("$\\overrightarrow{PQ}$", "ulft");
+ 
+

+
+ [Figure 102. Not displayed.] +
+
+ Fig. 102. +
+

+ +

The position argument indicates where the text of the label should + be located relative to the Point. The valid values are the + strings used in MetaPost for this purpose, i.e., ‘top’, ‘bot’, + ‘lft’, ‘rt’, ‘llft’ (lower left), ‘lrt’ (lower + right), ‘ulft’ (upper left), and ‘urt’ (upper right). The + default is ‘top’. 3DLDF does not catch the error if an invalid + position argument is used; the string is written to the + output file and an error will occur when MetaPost is run. + +

The dot argument is used to determine whether the label should be + dotted or not. The default is false. The function + dotlabel() calls label(), passing true as the + latter's dot argument. +

+ +
+ — const function: void dotlabel ([const string text_str, [const string position_str = "top", [Picture& picture = current_picture]]])
+ — const function: void dotlabel (const short text_short, [const string position_str = "top", [Picture& picture = current_picture]])
+

These functions are like label() except that they always produces a + dot. + +

          Point p0(2, 3);
+           p0.dotlabel("$p_0$");
+ 
+

+
+ [Figure 103. Not displayed.] +
+
+ Fig. 103. +
+

+ +
+ +
+ +


+ Next: , + Previous: Labelling Points, + Up: Point Reference + +
+ +

22.20 Showing

+ +
+ — const function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::persp, [const real factor = 1]]]]]]])
+

Prints text followed by the values of a set of coordinates to + standard output (stdout). The other arguments are similar to + those used in the functions described in Returning Coordinates. + +

          Point P(1, 3, 5);
+           P.rotate(15, 67, 98);
+           P.show("P:");
+           -| P: (-3.68621, -3.89112, 2.50421)
+ 
+
+ +
+ — Function: void show_transform ([string text = ""])
+

Prints text to standard output (stdout), + or "transform:", if text is the empty string (the + default), and then + calls transform.show(). + +

          Point A(-1, 1, 1);
+           Point B(13, 12, 6);
+           Point Q(31, 17.31, 6);
+           Q.rotate(A, B, 32);
+           Q.show_transform("Q.transform:");
+           -| Q.transform:
+              Transform:
+                0.935   0.212  -0.284       0
+              -0.0749   0.902   0.426       0
+                0.346  -0.377   0.859       0
+               -0.336   0.687  -0.569       1
+ 
+
+ +
+ +


+ Previous: Showing Points, + Up: Point Reference + +
+ +

22.21 Outputting

+ +
+ — Non-member function: ostream& operator<< (ostream& o, Point& p)
+

Used in Path::output() for writing + the x and y values of the projective_coordinates of Points to + out_stream. See Path Reference; Outputting. + This is a low-level function that ordinary users should never have to + invoke directly. +

+ +
+ — Function: void output (void)
+

Writes the MetaPost code for drawing or undrawing a Point to + out_stream. Called by Picture::output(), when a + Shape on the Picture is a Point. + See Picture Reference; Outputting. +

+ +
+ — Virtual function: void suppress_output (void)
+

Sets do_output to false, which causes a Point + not to be output. This function is called in + Picture::output(), when a Point cannot be projected. + See Picture Reference; Outputting. +

+ +
+ — Virtual function: virtual void unsuppress_output (void)
+

Resets do_output to true, so that a Point can + potentially be output, if Picture::output() is called again for + the Picture the Point is on. + This function is called in + Picture::output(). + See Picture Reference; Outputting. +

+ +
+ — Function: vector<shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Attempts to project the Point + using the arguments passed to Picture::output(), which calls this + function. If extract() succeeds, + it returns a vector<shape*> containing only the Point. + Otherwise, it returns an empty vector<shape*>. +

+ +
+ — Virtual function: bool set_extremes (void)
+

Sets “extreme” values + for x, y, and z in projective_coordinates. This + is, of course, trivial for + Points, because they only have one x, y and z-coordinate. + So the maxima and minima for each coordinate are always the same. +

+ +
+ — Virtual inline const function: valarray <real> get_extremes (void)
+

Returns projective_extremes. +

+ +
+ — Virtual const function: real get_minimum_z (void)
+ — Virtual const function: real get_maximum_z (void)
+ — Virtual const function: real get_mean_z (void)
+

These functions return the minimum, maximum, and mean z-value of the + Point. + get_minimum_z() returns projective_extremes[4], + get_maximum_z() returns projective_extremes[5], and + get_mean_z() returns + (projective_extremes[4] + projective_extremes[5]) / 2. + However, since a Point has only one z-coordinate + (from world_coordinates), these values will all be the same. + +

These functions are pure virtual functions in Shape, and are + called on Points through pointers to Shape. Therefore, + they must be consistent with the versions for other types derived from + Shape. See Shape Reference; Outputting. +

+ + + + + + +
+ +


+ Next: , + Previous: Point Reference, + Up: Top + +
+ +

23 Focus Reference

+ +

Class Focus is defined in points.web. + Focuses are used when creating a perspective projection. + They represent the center of projection and can be thought of like a + camera viewing the scene. + +

+ +
+ +


+ Next: , + Previous: Focus Reference, + Up: Focus Reference + +
+ +

23.1 Data Members

+ +
+ — Private variable: Point position
+

The location of the Focus in the world coordinate system. +

+ +
+ — Private variable: Point direction
+

The direction of view from position into the scene. +

+ +
+ — Private variable: Point up
+

The direction that will be at the top of the projected drawing. +

+ +
+ — Private variable: real distance
+

The distance of the Focus from the plane of projection. +

+ +
+ — Private variable: real angle
+

Used for determining the up direction. +

+ +
+ — Private variable: char axis
+

The main axis onto which the Focus is transformed in order to + perform the perspective projection, z by default. + +

It will normally not matter which axis is used, but it might be + advantageous to use a particular axis in some special situations. +

+ +
+ — Private variable: Transform transform
+

The Transform, which will be applied to the Shapes on the + Picture, when the latter is output. The effect of this is + equivalent to transforming the Focus, so that it lies on a major + axis. + +

          Focus f(5, 5, -10, 2, 4, 10, 10, 180);
+           ⇒
+ 
+
          f.transform ==
+            0.989  -0.00733  -0.148  0
+            0       0.999    -0.0494 0
+            0.148   0.0488    0.988  0
+           -3.4    -4.47      0.865  1
+           
+ 
+
+ +
+ — Private variable: Transform persp
+

The Transform representing the perspective transformation for a + particular Focus. + Let d stand for distance, then +

          persp ==
+           1 0 0  0
+           0 1 0  0
+           0 0 0 1/d
+           0 0 0  1
+ 
+
+ + + +

23.2 Global Variables

+ +
+ — Variable: Focus default_focus
+

Effectively, the default Focus in Picture::output(). + See Picture Reference; Outputting; Functions. + It's not really the default, but the version of + output() that doesn't take a + Focus argument calls another version + that does take one, passing default_focus to the + latter as its Focus argument. + +

It's necessary to do this in such a roundabout way, + because Picture::output() must be declared before + class Focus is completely defined and default_focus is declared. + +

The declaration ‘Focus& f = default_focus;’ makes f a + reference to default_focus, i.e., it makes f another name + for default_focus. This may be convenient, if you don't feel + like typing default_focus. +

+ +
+ +


+ Next: , + Previous: Focus Global Variables, + Up: Focus Reference + +
+ +

23.3 Constructors and Setting Functions

+ +
+ — Default constructor: void Focus (void)
+

Creates an empty Focus +

+ +
+ — Constructor: void Focus (const real pos_x, const real pos_y, const real pos_z, const real dir_x, const real dir_y, const real dir_z, const real dist, [const real ang = 0, [char ax = 'z']])
+

Constructs a Focus using the first three real arguments as + the x, y, and z-coordinates of position, and the fourth through the + sixth argument as the x, y, and z-coordinates of direction. dist + specifies the distance of the Focus + from the plane of projection, ang the angle of rotation, which affects which + direction is considered to be “up”, and ax the major axis to + which the Focus is aligned. +

+ +
+ — Setting function: void set (const real pos_x, const real pos_y, const real pos_z, const real dir_x, const real dir_y, const real dir_z, const real dist, [const real ang = 0, [char ax = 'z']])
+

Resets an existing Focus. Corresponds to the constructor above. +

+ +
+ — Constructor: void Focus (const Point& pos, const Point& dir, const real dist, [const real ang = 0, [char ax = 'z']])
+

Constructs a Focus using Point arguments for + position and direction. Otherwise, the arguments of this constructor + correspond to those of the one above. +

+ +
+ — Setting function: void set (const Point& pos, const Point& dir, const real dist, [const real ang = 0, [char ax = 'z']])
+

Resets an existing Focus. Corresponds to the constructor above. +

+ + + +

23.4 Operators

+ +
+ — Assignment operator: const Focus& operator= (const Focus& f)
+

Sets the Focus to f. +

+ +
+ +


+ Next: , + Previous: Focus Operators, + Up: Focus Reference + +
+ +

23.5 Modifying

+ +
+ — Function: void reset_angle (const real ang)
+

Resets the value of angle and recalculates the Transforms + transform and persp. +

+ +
+ +


+ Next: , + Previous: Modifying Focuses, + Up: Focus Reference + +
+ +

23.6 Querying

+ +
+ — Inline const function: const Point& get_position (void)
+

Returns position. +

+ +
+ — Inline const function: const Point& get_direction (void)
+

Returns direction. +

+ +
+ — Inline const function: const real& get_distance (void)
+

Returns distance. +

+ +
+ — Inline const function: const Point& get_up (void)
+

Returns up. +

+ +
+ — Inline const function: const Transform& get_transform (void)
+

Returns transform. +

+ +
+ — Inline const function: const real& get_transform_element (const unsigned int row, const unsigned int column)
+

Returns an element of transform, given two unsigned ints for the row + and the column. +

+ +
+ — Inline const function: const Transform& get_persp (void)
+

Returns persp. +

+ +
+ — Inline const function: const real& get_persp_element (const unsigned int row, const unsigned int column)
+

Returns an element of persp, given two unsigned ints for the row + and the column. +

+ +
+ +


+ Previous: Querying Focuses, + Up: Focus Reference + +
+ +

23.7 Showing

+ +
+ — const function: void show ([const string text_str = "Focus:", [const bool show_transforms = false]])
+

Prints text_str to standard output (stdout), then calls + Point::show() on position, direction, and + up. Then the values of distance, axis, and + angle are printed to stdout. If show_transforms is + true, transform and persp are shown as well. +

+ + + + + + +
+ +


+ Next: , + Previous: Focus Reference, + Up: Top + +
+ +

24 Line Reference

+ +

The struct Line is defined in lines.web. + Lines are not Shapes. They are used for + performing vector operations. A Line is defined by a + Point representing a position vector and a Point + representing a direction vector. + +

See also the descriptions of Point::get_line() in + Points and Lines, and + Path::get_line() in + Path Reference; Querying. + +

+ +
+ +


+ Next: , + Previous: Line Reference, + Up: Line Reference + +
+ +

24.1 Data Members

+ +
+ — Public variable: Point position
+

Represents the position vector of the Line. +

+ +
+ — Public variable: Point direction
+

Represents the direction vector of the Line. +

+ +
+ +


+ Next: , + Previous: Line Data Members, + Up: Line Reference + +
+ +

24.2 Global Constants

+ +
+ — Constant: const Line INVALID_LINE
+

position and direction are both INVALID_POINT. +

+ +
+ +


+ Next: , + Previous: Line Global Constants, + Up: Line Reference + +
+ +

24.3 Constructors

+ +
+ — Default constructor: void Line (const Point& pos = origin, const Point& dir = origin)
+

Creates a Line, setting position to pos, and + direction to dir. If this function is called with no + arguments, it creates a Line at the origin with no + direction. + +

          Point p(2, 1, 2);
+           Point d(-3, 3, 3.5);
+           Line L0(p, d);
+           Line L1 = p.get_line(d);
+ 
+

+
+ [Figure 104. Not displayed.] +
+
+ Fig. 104. +
+

+ +
+ +
+ — Copy constructor: void Line (const Line& l)
+

Creates a Line, making it a copy of l. +

+ +
+ +


+ Next: , + Previous: Line Constructors, + Up: Line Reference + +
+ +

24.4 Operators

+ +
+ — Assignment operator: void operator= (const Line& l)
+

Sets *this to l. +

+ + + +
+ +


+ Next: , + Previous: Line Operators, + Up: Line Reference + +
+ +

24.5 Get Path

+ +
+ — const function: Path get_path (void)
+

Returns a linear Path with two Points + on the Line. The first Point will be position, and + the second will be position + direction. +

+ +
+ +


+ Previous: Get Path, + Up: Line Reference + +
+ +

24.6 Showing

+ +
+ — Function: void show ([string text = ""])
+

If text is not the empty string (the default), it is + printed on a line of its own to standard output. Otherwise, ‘Line:’ + is printed. Following this, Point::show() is called on + position and direction. + +

          Point p(1, -2, 3);
+           Point d(-12.3, 21, 36.002);
+           Line L0(p, d);
+           L0.show("L0:");
+           -| L0:
+              position: (1, -2, 3)
+              direction: (-12.3, 21, 36.002)
+           Line L1 = p.get_line(d);
+           L1.show("L1:");
+           -| L1:
+              position: (1, -2, 3)
+              direction: (-13.3, 23, 33.002)
+           Path q = L1.get_path();
+           q.show("q:");
+           -| q:
+              fill_draw_value == 0
+              (1, -2, 3) -- (-12.3, 21, 36.002);
+ 
+
+ + + + + + +
+ +


+ Next: , + Previous: Line Reference, + Up: Top + +
+ +

25 Plane Reference

+ +

The struct Plane is defined in planes.web. + Planes are not Shapes. They are used for + performing vector operations. A Plane is defined by a + Point representing a point on the plane, a Point + representing the normal to the plane, and the distance of the plane from + the origin. + +

The most common use of Planes is to represent the + plane in which an existing plane figure lies. Therefore, they + most likely to be created by using Path::get_plane(). + See Path Reference; Querying. However, class + Plane does have constructors for creating Planes directly, if + desired. + See Planes Reference; Constructors. + +

+ +
+ +


+ Next: , + Previous: Plane Reference, + Up: Plane Reference + +
+ +

25.1 Data Members

+ +

Because the main purpose of Plane is to + provide information about Shapes, its data members are all + public. + +

+ — Public variable: Point point
+

Represents a point on the plane. +

+ +
+ — Public variable: Point normal
+

Represents the normal to the plane. +

+ +
+ — Public variable: real distance
+

The distance of the plane from the origin. +

+ +
+ +


+ Next: , + Previous: Planes Data Members, + Up: Plane Reference + +
+ +

25.2 Global Constants

+ +
+ — Constant: const Plane INVALID_PLANE
+

A Plane with point == normal, and + distance == INVALID_REAL. + +

INVALID_PLANE is returned from Path::get_plane(), if the + Path is not planar. See Path Reference; Querying. +

+ +
+ +


+ Next: , + Previous: Planes Global Constants, + Up: Plane Reference + +
+ +

25.3 Constructors

+ +
+ — Default constructor: void Plane (void)
+

Creates a degenerate Plane with + point == normal == origin, and + distance == 0. + +

Planes constructed using this constructor will probably be set + using the assignment operator + or Path::get_plane() + immediately, or + very soon after being declared. + See Planes Reference; Operators, and + Paths Reference; Querying. +

+ +
+ — Copy constructor: void Plane (const Plane& p)
+

Creates a new Plane, making it a copy of p. +

+ +
+ — Constructor: void Plane (const Point& p, const Point& n)
+

If p is not equal to n, this constructor creates a + Plane and sets point to p. normal + is set to n, and made a unit vector. + distance is calculated according to the following formula: + Let n stand for normal, p for point, and d for + distance: + d = -p \dot n. + If d = 0, origin + lies in the Plane. If d > 0, origin lies on the side of the + Plane that normal points to, considered to be “outside”. + If d<0, origin lies on the side of the + Plane that normal does not point to, considered to be + “inside”. + +

However, if p == n, point and normal are + both set to INVALID_POINT, and distance is set to + INVALID_REAL, i.e., *this will be equal to + INVALID_PLANE + (see Planes Reference; Global Constants). + +

          Point P(1, 1, 1);
+           Point N(0, 1);
+           N.rotate(-35, 30, 20);
+           N.show("N:");
+           -| N: (-0.549659, 0.671664, 0.496732)
+           Plane q(P, N);
+           cout << q.distance;
+           -| -0.618736
+ 
+

+
+ [Figure 105. Not displayed.] +
+
+ Fig. 105. +
+

+ +
+ +
+ +


+ Next: , + Previous: Planes Constructors, + Up: Plane Reference + +
+ +

25.4 Operators

+ +
+ — Assignment operator: const Plane& operator= (const Plane& p)
+

Sets point to p.point, normal to + p.normal, and distance to p.distance. + The return value is p, so that invocations of this function can be + chained. + +

          Point pt(2, 2.3, 6);
+           Point norm(-1, 12, -36);
+           Plane A(pt, norm);
+           Plane B;
+           Plane C;
+           B = C = A;
+           A.show("A:");
+           -| A:
+              normal: (-0.0263432, 0.316118, -0.948354)
+              point: (2, 2.3, 6)
+              distance == 5.01574
+           cout << (A == B && A == C && B == C);
+           -| 1
+ 
+
+ +
+ — const operator: bool operator== (const Plane& p)
+

Equality operator. Compares *this and p, and returns + true, if point == p.point, + normal == p.normal, and + distance == p.distance, + otherwise false. +

+ +
+ — const operator: bool operator!= (const Plane& p)
+

Inequality operator. Compares *this and p and returns + true, if point != + p.point, or + normal != + p.normal, or + distance != + p.distance. + Otherwise, it returns false. +

+ +
+ +


+ Next: , + Previous: Planes Operators, + Up: Plane Reference + +
+ +

25.5 Returning Information

+ +
+ — const function: real_short get_distance (const Point& p)
+ — const function: real_short get_distance (void)
+

The version of this function taking a Point argument returns + a real_short r, whose real part + (r.first) represents + the distance of p from the Plane. This value is always + positive. r.second can take on three values: + +

+
0
If the Point lies in the Plane. + +
1
If it lies on the side of the Plane pointed at by the + normal to the Plane, considered to be the “outside”. + +
-1
If it lies on the side of the Plane not pointed at + by the normal to the Plane, considered to be the “inside”. +
+ +

The version taking no argument returns + the absolute of the data member distance and its sign, i.e., the + distance of origin to the Plane, and which side of the + Plane it lies on. + +

It would have been possible to use origin as the default for an + optional Point argument, but I've chosen to overload this + function, because of problems that may arise, when I implement + user_coordinates and view_coordinates + (see Point Reference; Data Members). + +

          Point N(0, 1);
+           N.rotate(-10, 20, 20);
+           Point P(1, 1, 1);
+           Plane q(P, N);
+           Point A(4, -2, 4);
+           Point B(-1, 3, 2);
+           Point C = q.intersection_point(A, B).pt;
+           real_short bp;
+           
+           bp = q.get_distance();
+           cout << bp.first;
+           -| 0.675646
+           cout << bp.second
+           -| -1
+           
+           bp = q.get_distance(A)
+           cout << bp.first;
+           -| 3.40368
+           cout << bp.second;
+           -|  -1
+           
+           bp = q.get_distance(B)
+           cout << bp.first;
+           -| 2.75865
+           cout << bp.second;
+           -| 1
+           
+           bp = q.get_distance(C)
+           cout << bp.first;
+           -| 0
+           cout << bp.second;
+           -| 0
+ 
+

+
+ [Figure 106. Not displayed.] +
+
+ Fig. 106. +
+

+ +
+ +
+ +


+ Next: , + Previous: Planes Returning Information, + Up: Plane Reference + +
+ +

25.6 Intersections

+ +
+ — const function: bool_point intersection_point (const Point& p0, const Point& p1)
+ — const function: bool_point intersection_point (const Path& p)
+

These functions find the intersection point of the Plane and a + line. In the first version, the + line is defined by the two Point arguments. In the second + version, the Path p must be linear, i.e., + p.is_linear() must be true. + +

Both versions of intersection_point() return a bool_point + bp, where bp.pt is the intersection point, or + INVALID_POINT, if there is none. If an intersection point is + found, bp.b will be true, otherwise false. + Returning a bool_point makes it possible to test for success + without comparing the Point returned against INVALID_POINT. + +

          Point center(2, 2, 3.5);
+           Reg_Polygon h(center, 6, 4, 80, 30, 10);
+           Plane q = h.get_plane();
+           Point P0 = center.mediate(h.get_point(2));
+           P0.shift(5 * (N - center));
+           Point P1(P0);
+           P1.rotate(h.get_point(1), h.get_point(4));
+           P1 = 3 * (P1 - P0);
+           P1.shift(P0);
+           P1.shift(3, -.5, -2);
+           bool_point bp = q.intersection_point(P0, P1);
+           Point i_P = bp.pt;
+           Point P4 = h.get_point(3).mediate(h.get_point(0), .75);
+           P4.shift(N - center);
+           Point P5(P4);
+           P5.rotate(h.get_point(3), h.get_point(0));
+           P4.shift(-1, 2);
+           Path theta(P4, P5);
+           bp = q.intersection_point(theta);
+           Point i_theta = bp.pt;
+           draw_axes();
+ 
+

+
+ [Figure 107. Not displayed.] +
+
+ Fig. 107. +
+

+ +
+ +
+ — const function: Line intersection_line (const Plane& p)
+

Returns a Line l. representing the line of intersection of two + Planes. See Line Reference. + +

In [next figure] + , intersection_line() is used to find the line of + intersection of the Planes derived from the Rectangles + r_0 and r_1 using get_plane() + (see Paths Reference; Querying). + Please note that there is no guarantee that l.position will + be in a convenient place for your drawing. A bit of fiddling was + needed to find the Points P_2 and P_3. + + I plan to add functions for finding the intersection lines of plane + figures, but haven't done so yet. + +

          Rectangle r0(origin, 5, 5, 10, 15, 6);
+           Rectangle r1(origin, 5, 5, 90, 50, 10);
+           r1 *= r0.rotate(30, 30, 30);
+           r1 *= r0.shift(1, -1, 3);
+           Plane q0 = r0.get_plane();
+           Plane q1 = r1.get_plane();
+           Line l = q0.intersection_line(q1);
+           l.show("l:");
+           -| l:
+              position: (0, 11.2193, 20.0759)
+              direction: (0.0466595, -0.570146, -0.796753)
+           Point P0(l.direction);
+           P0.shift(l.position);
+           P0.show("P0:");
+           -| P0: (0.0466595, 10.6491, 19.2791)
+           Point P1(-l.direction);
+           P1.shift(l.position);
+           Point P2(P0 - P1);
+           P2 *= 12.5;
+           P2.shift(P0);
+           cout << P2.is_on_plane(q0);
+           -| 1
+           cout << P2.is_on_plane(q1);
+           -| 1
+           Point P3(P0 - P1);
+           P3 *= 7;
+           P3.shift(P0);
+           cout << P3.is_on_plane(q0);
+           -| 1
+           cout << P3.is_on_plane(q1);
+           -| 1
+ 
+

+
+ [Figure 108. Not displayed.] +
+
+ Fig. 108. +
+

+ +
+ +
+ +


+ Previous: Plane Intersections, + Up: Plane Reference + +
+ +

25.7 Showing

+ +
+ — const function: void show ([string text = ""])
+

Prints information about the Plane to standard output. + If text is not the empty string, it is printed to the + standard output. Otherwise, + ‘Plane:’ is printed. + Following this, + if the Plane is equal to INVALID_PLANE + (see Planes Reference; Global Constants), + a message to this effect is printed to standard output. + Otherwise, normal and + point are shown using Point::show() + (see Point Reference; Showing). Finally, + distance is printed. + +

          Point A(1, 3, 2.5);
+           Rectangle r0(A, 5, 5, 10, 15, 6);
+           Plane p = r0.get_plane();
+           -| p:
+              normal: (-0.0582432, 0.984111, -0.167731)
+              point: (-0.722481, 2.38245, -0.525176)
+              distance == -2.47476
+ 
+
+ + + + + + +
+ +


+ Next: , + Previous: Plane Reference, + Up: Top + +
+ +

26 Path Reference

+ +

Class Path is defined in paths.web. + It is derived from Shape using protected derivation. + +

+ + + +

26.1 Data Members

+ +
+ — Protected variable: bool line_switch
+

true if the Path was created using the constructor + Path(const Point& p0, const Point& p1), directly or indirectly. + See Path Reference; Constructors and Setting Functions. + +

          Point p0;
+           Point p1(1, 1);
+           Point p2(2, 3);
+           Path q0(p0, p1);
+           cout << q0.get_line_switch();
+           -| 1
+           Path q1;
+           q1 = q0;
+           cout << q1.get_line_switch();
+           -| 1
+           Path q2 = p0.draw(p1);
+           cout << q2.get_line_switch();
+           -| 1
+           Path q3("..", false, &p1, &p2, &p0, 0);
+           cout << q3.get_line_switch();
+           -| 0
+ 
+

+
+ [Figure 109. Not displayed.] +
+
+ Fig. 109. +
+

+ +

Some Path functions only work on linear Paths, + so it's necessary to be able to distinguish them from non-linear ones. + The function is_linear() should be enough to ensure that all of + these functions work, so I plan to make line_switch obsolete + soon. However, at the moment, it's still needed. + See Path Reference; Querying. +

+ +
+ — Protected variable: bool cycle_switch
+

true if the Path is cyclical, otherwise + false. +

+ +
+ — Protected variable: bool on_free_store
+

true if the Path was dynamically allocated on the free + store. Otherwise false. Set to true only in + create_new<Path>(), which should be the only way Paths are + ever dynamically allocated. + See Path Reference; Constructors and Setting Functions. +

+ +
+ — Protected variable: bool do_output
+

Used in Picture::output(). Set to false if the Path + isn't projectable using the arguments passed to + Picture::output(). + See Picture Reference; Outputting. +

+ +
+ — Protected variable: signed short fill_draw_value
+

Set in the drawing and filling functions, and + used in Path::output(), to determine what MetaPost code to write + to out_stream. + See Path Reference; Drawing and Filling, + and Path Reference; Outputting. +

+ +
+ — Protected variable: const Color* draw_color
+

Pointer to the Color used if the Path is drawn. +

+ +
+ — Protected variable: const Color* fill_color
+

Pointer to the Color used if the Path is filled. +

+ +
+ — Protected variable: string dashed
+

String written to out_stream for the “dash pattern” in a + MetaPost draw or undraw command. If and only if + dashed is not the empty string, “dashed + <dash pattern>” is written to out_stream. + +

Dash patterns have no meaning inside 3DLDF; dashed, if + non-empty, is written unchanged to out_stream. I may change this + in the future. +

+ +
+ — Protected variable: string pen
+

String written to out_stream for the pen to be used in a + MetaPost draw, undraw, filldraw, or + unfilldraw command. If and only if pen is not the + empty string, “withpen <...>” is written to + out_stream. + +

Pens have no meaning inside 3DLDF; pen, if + non-empty, is written unchanged to out_stream. I may change this + in the future. +

+ +
+ — Protected variable: bool arrow
+

Indicates whether an arrow should be drawn when outputting a + Path. Set to true on a Path created on the free + store and put onto a Picture by drawarrow(). +

+ +
+ — Protected variable: valarray<real> projective_extremes
+

Contains the maxima and minima of the x, y, and z-coordinates of the + projections of Points on a Path using a particular + Focus. Set in set_extremes() and used in + Picture::output() for surface hiding. +

+ +
+ — Protected variable: vector<Point*> points
+

Pointers to the Points on the Path. +

+ +
+ — Protected variable: vector<string> connectors
+

The connectors between the Points on the Path. Connectors + are simply strings in 3DLDF, they are written unchanged to + out_stream. +

+ +
+ — Public static variable: const Color* help_color
+

Pointer to a const Color, which becomes the default for + draw_help(). + See Path Reference; Drawing and Filling. + +

Please note that help_color is a pointer to a + const Color, not a const pointer to a Color or a + const pointer to a const Color! It's easy to get confused + by the syntax for these types of pointers.35 +

+ +
+ — Public static variable: string help_dash_pattern
+

The default dash pattern for draw_help(). +

+ +
+ — Public static variable: bool do_help_lines
+

true if help lines should be output, otherwise false. + If false, a call to draw_help() does not cause a copy of + the Path to be created and put onto a Picture. + See Path Reference; Drawing and Filling. +

+ +
+ +


+ Next: , + Previous: Path Data Members, + Up: Path Reference + +
+ +

26.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Path (void)
+

Creates an empty Path with no + Points and no connectors. +

+ +
+ — Constructor: void Path (const Point& p0, const Point& p1)
+

Creates a line (more precisely, a line segment) between p0 + and p1. The single + connector between the two Points is set to "--" and the + data member line_switch (of type bool) is set to + true. There are certain operations on Paths that are only + applicable to lines, so it's necessary to store the information that a + Path is a line.36 + +

          Point A(-2, -2.5, -1);
+           Point B(3, 2, 2.5)
+           Path p(A, B);
+           p.show("p:");
+           -| p:
+              (-2, -2.5, -1) -- (3, 2, 2.5);
+ 
+

+
+ [Figure 110. Not displayed.] +
+
+ Fig. 110. +
+

+ +
+ +
+ — Setting function: void set (const Point& p0, const Point& p1)
+

Corresponds to the constructor above. + +

          Point P0(1, 2, 3);
+           Point P1(3.5, -12, 75);
+           Path q;
+           q.set(P0, P1);
+           q.show("q:");
+           -| q:
+              (1, 2, 3) -- (3.5, -12, 75);
+ 
+
+ +
+ — Constructor: void Path (string connector, bool cycle, Point* p, [...], 0)
+

For Paths with an arbitrary number of Points + and one type of connector. + +

connector is passed unchanged to out_file, so it + must be a valid connector in MetaPost. + +

cycle indicates whether the Path is a cycle or not. + cycle_switch is set to cycle. + See Path Reference; Data Members. + The filling and unfilling functions + only work for + Paths that are cycles. + See Path Reference; Drawing and Filling. + If a Path is a cycle, it is up to the user to make sure that it + has sensible Point and connector values; 3DLDF doesn't check + them. If they are not sensible, for instance, if the Path + crosses itself, and you try to fill it, this will cause an error in + MetaPost. It is possible that a Path will be “sensible” in + some projections and not in others, although I have not tested this. + +

p is a pointer to the first Point that should go onto the + Path. + The ellipsis points (...) represent an arbitrary number of + pointers to Points that should go onto the Path. + The final + argument must be 0, + which is interpreted by the C++ + compiler as the null + pointer.37 + +

It is admittedly a bit + awkward to have to type “&p0” rather than “p0”, and + I have frequently forgotten to do it, which causes a compiler error, + but all of the arguments must be pointers in order to be able to use 0 to + indicate the end of the argument list. Convenience in typing function + calls is not a high priority in 3DLDF, because once I've written + an input routine, these function calls should be generated + automatically. It will be more important to define a convenient syntax + for the input routine. + +

          Point P0;
+           Point P1(2);
+           Point P2(2,2);
+           Point P3(0,2);
+           Path p("..", true, &P0, &P1, &P2, &P3, 0);
+           p.draw();
+           
+           
+ 
+

+
+ [Figure 111. Not displayed.] +
+
+ Fig. 111. +
+

+ +
+ +
+ — Setting function: void set (string connector, bool cycle, Point* p, [...], 0)
+

Corresponds to the constructor above. + +

          Point P[4];
+           P[0].set(2, 1, 3);
+           P[3] = P[2] =  P[1] = P[0];
+           P[3] *= P[2] *=  P[1].rotate(3, 12, 18);
+           P[3] *= P[2].shift(-2, -1, 3);
+           P[3].shear(1.5, .5, 3.5);
+           Path q("...", false, &P[0], &P[1], &P[2], &P[3], 0);
+           q.show("q:");
+           -| q:
+              (2, 1, 3) ... (0.92139, 1.51449, 3.29505) ...
+              (-1.07861, 0.514487, 6.29505) ... (2.84065, -3.26065, 6.29505);
+ 
+

+
+ [Figure 112. Not displayed.] +
+
+ Fig. 112. +
+

+ +
+ +
+ — Constructor: void Path (Point* first_point_ptr, char* s, Point* p, [...], 0)
+

Constructor for Paths with an arbitrary number of Points + and connectors. The first, required, argument is a pointer to a + Point, followed by pointers to char alternating with pointers to + Points.38 + The last argument must be 0, i.e., the null pointer. + +

There is no need to indicate by means of an argument whether the + Path is a cycle or not: If it is, the last argument before the 0 + will be a char* (pointer to char), if not, it will be a + Point*. The data member cycle_switch (of type + bool) will be set to true or false accordingly. + +

          Point A;
+           Point B(2, 0);
+           Point C(3, 2);
+           Point D(1, 3);
+           Path p(&A, "..", &B, "..", &C, "--", &D, "...", 0);
+ 
+

+
+ [Figure 113. Not displayed.] +
+
+ Fig. 113. +
+

+ +
+ +
+ — Setting function: void set (Point *first_point_ptr, string s, Point *p, [...], 0)
+

Corresponds to the constructor above. +

+ +
+ — Copy constructor: void Path (const Path& p)
+

Creates a new Path, making it a copy of p. +

+ +
+ — Template specializations: Path* create_new<Path> (const Path* p)
+ — : Path* create_new<Path> (const Path& p)
+

Pseudo-constructors for dynamic allocation of Paths. + They create a Path on the free store and allocate memory for it using + new(Path). They return a pointer to the new Path. + +

If p is a non-zero pointer or a reference, + the new Path will be a copy of + p. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Path>() as its argument. + See Dynamic Allocation of Shapes, for more information. + +

create_new<Path>() is used in the drawing and filling functions + for copying a Path and putting the copy onto a Picture. + See Path Reference; Drawing and Filling. +

+ + + +

26.3 Destructor

+ +
+ — virtual Destructor: void ~Path (void)
+

All of the Points on a Path are created by + create_new<Point>(), which allocates them dynamically on + the free store. Therefore, the destructor calls delete() on all + of the pointers on points. Following this, it calls + points.clear() and connectors.clear(). + draw_color and fill_color may or may not have been + allocated on the free store, so ~Path() checks this first, and + deletes them, if they were. Then, it sets them to 0. +

+ +
+ +


+ Next: , + Previous: Path Destructor, + Up: Path Reference + +
+ +

26.4 Operators

+ +
+ — Virtual function: Transform operator*= (const Transform& t)
+

Calls Point::operator*=(t) on each of the Points + on the Path. + See Point Reference; Operators. + This has the effect of + transforming the entire Path by t. Please note that + Path does not have a transform data member of its own. +

+ +
+ — Function: void operator+= (const Point& pt)
+

Copies pt and pushes a pointer to the copy onto + points. The last connector + in the Path will be used to connect the new Point and the + previous one. + +

          Point A(1, 2, 3);
+           Point B(3, 4, 5);
+           Path q;
+           q += A;
+           q += B;
+           q.show("q:");
+           -| q:
+              (1, 2, 3) -- (3, 4, 5);
+ 
+
+ +
+ — const function: Path operator+ (const Point& pt)
+

Copies the Path and pt, and pushes a pointer to the copy of + pt onto points in the new Path. The + last connector in the new Path will be used to connect the new + Point and the previous one. The Path remains unchanged. +

+ +
+ — Function: void operator&= (const Path& pa)
+

Concatenates two Paths. The result is assigned to *this. + Neither *this nor pa may be cyclical, i.e., + cycle_switch must be false for both Paths. +

+ +
+ — const function: Path operator& (const Path& pa)
+

Returns a Path representing the concatenation of *this and + pa. *this remains unchanged. + Neither *this nor pa may be cyclical, i.e., + cycle_switch must be false for both Paths. +

+ +
+ — Function: void operator+= (const string s)
+

Pushes s onto connectors. +

+ +
+ +


+ Next: , + Previous: Path Operators, + Up: Path Reference + +
+ +

26.5 Appending

+ +
+ — Function: Path append (const Path& pa, [string connector = "–", [bool assign = true]])
+

Appends pa to *this using connector to join them and + returns the resulting Path. If + assign == true, then the return value is + assigned to *this, otherwise, *this remains unchanged. + +

If necessary, a const version could be added, for + const Paths. + +

          Point A(-2, 2);
+           Point B(-2, -2);
+           Point C(2, -2);
+           Point D(2, 2);
+           Path q("--", false, &A, &B, &C, &D, 0);
+           Point E(1, 2);
+           Point F(0, 4);
+           Point G(-.5, 3);
+           Path r("..", false, &E, &F, &G, 0);
+           q.append(r, "..", true);
+           q += "..";
+           q += "--";
+           q.set_cycle();
+           q.show("q:");
+           -| q:
+              (-2, 2, 0) -- (-2, -2, 0) --
+              (2, -2, 0) -- (2, 2, 0) ..
+              (1, 2, 0) .. (0, 4, 0) ..
+              (-0.5, 3, 0) -- cycle;
+ 
+

+
+ [Figure 114. Not displayed.] +
+
+ Fig. 114. +
+

+ +
+ +
+ +


+ Next: , + Previous: Appending to Paths, + Up: Path Reference + +
+ +

26.6 Copying

+ +
+ — const virtual function: Shape* get_copy (void)
+

Creates a copy of the Path using create_new<Path>(), which + returns a pointer to Path. get_copy() then + casts this pointer to a pointer to Shape and returns it. + +

This function is used when copying Pictures and in + Solid::output(), where objects of types derived from Shape + must be handled in the same way, without their actual types being known. +

+ +
+ +


+ Next: , + Previous: Copying Paths, + Up: Path Reference + +
+ +

26.7 Clearing

+ +
+ — Virtual function: void clear (void)
+

Does the same thing the destructor ~Path() does: + Calls delete() on the pointers to Points on points, + clears points and connectors, deletes draw_color + and fill_color, if they point to Colors that were + allocated on the free store, and sets them to 0. + +

clear() is a pure virtual function in class Shape, + so Path must be have a clear() function. + It is needed, because it is sometimes called through a + pointer to Shape, so that ~Path() cannot be accessed. + At least, so far I haven't found a way to call a destructor through the + virtual function facility. +

+ +
+ +


+ Next: , + Previous: Clearing Paths, + Up: Path Reference + +
+ +

26.8 Modifying

+ +
+ — Virtual function: bool set_on_free_store ([bool b = true])
+

Sets on_free_store to b. This is used in the + template function create_new(). + See Path Reference; Constructors and Setting Functions. +

+ +
+ — Virtual function: void set_fill_draw_value (const signed short s)
+

Sets fill_draw_value to s, which should be one of + Shape::DRAW, Shape::FILL, Shape::FILLDRAW, + Shape::UNDRAW, Shape::UNFILL, or Shape::UNFILLDRAW. +

+ +
+ — Virtual function: void set_draw_color (const Color& c)
+ — Virtual function: void set_draw_color (const Color * c)
+

Sets draw_color (a pointer to a const Color) to &c + or c, depending on whether the + version with a reference argument or the version with a pointer argument + is used. + +

set_draw_color() is used in the Solid drawing and filling + functions, because Path::draw_color is protected, and + the Solid cannot access it directly. + See Solid Reference; Drawing and Filling. +

+ +
+ — Virtual function: void set_fill_color (const Color& c)
+ — Virtual function: void set_fill_color (const Color* c)
+

Sets fill_color (a pointer to a const Color) to &c + or c, depending on whether the + version with a reference argument or the version with a pointer argument + is used. + +

set_fill_color() is used in the Solid drawing and filling + functions, because + Path::fill_color is protected, and + the Solid cannot access it directly. + See Solid Reference; Drawing and Filling. +

+ +
+ — Virtual function: void set_dash_pattern ([const string s = ""])
+

Sets dashed to s. +

+ +
+ — Virtual function: void set_pen ([const string s = ""])
+

Sets pen to s. +

+ +
+ — Virtual function: void set_connectors ([const string s = ".."])
+

Clears connectors and then pushes s onto it, making s + the only connector. Additional connectors can be added by using + Path::operator+=(const string). + See Path Reference; Operators. + +

I plan to add a version of this function taking a vector of + strings as its argument, to make it possible to set several + connectors at one time. +

+ +
+ +


+ Next: , + Previous: Modifying Paths, + Up: Path Reference + +
+ +

26.9 Affine Transformations

+ +
+ — Virtual function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+

Creates a Transform t locally and calls + t.rotate(x, y, z). + t is then applied to all of the Points on points. + The return value is t. +

+ +
+ — Function: Transform scale (real x, [real y = 1, [real z = 1]])
+

Creates a Transform t locally and calls + t.scale(x, y, z). + t is then applied to all of the Points on points. + The return value is t. + +

The Points on the Path are scaled according to the + arguments: + +

          Point pt[8];
+           pt[0] = (-1, -1);
+           for (int i = 1; i < 8; ++i)
+             {
+               pt[i] = pt[0];
+               pt[i].rotate(0, 0, i * 45);
+             }
+           Path p("--", true, &pt[0], &pt[1], &pt[2], &pt[3],
+                  &pt[4], &pt[5], &pt[6],
+                  &pt[7], 0);
+           p.draw();
+           p.scale(2, 2);
+           p.draw();
+ 
+

+
+ [Figure 115. Not displayed.] +
+
+ Fig. 115. +
+

+ +
+ +
+ — Function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+

Creates a Transform t locally and calls + t.shear(xy, xz, yx, yz, zx, zy). + t is then applied to all of the Points on points. + The return value is t. + +

          Point p0;
+           Point p1(1);
+           Point p2(1, 1);
+           Point p3(0, 1);
+           Path q("--", true, &p0, &p1, &p2, &p3, 0);
+           q.rotate(0, 45);
+           q.shift(1);
+           q.filldraw(black, light_gray);
+           q.shear(1.5, 2, 2.5, 3, 3.5, 5);
+           q.filldraw(black, light_gray);
+ 
+

+
+ [Figure 116. Not displayed.] +
+
+ Fig. 116. +
+

+ +
+ +
+ — Function: Transform shift (real x, [real y = 0, [real z = 0]])
+

Creates a Transform t locally and calls + t.shift(x, y, z). + t is then applied to all of the Points on points. + The return value is t. + +

Shifts each of the Points on the Path according to the + arguments. + +

          default_focus.set(5, 10, -10, 0, 10, 10, 10);
+           Point pt[6];
+           pt[0].set(-2, -2);
+           pt[1].set(0, -3);
+           pt[2].set(2, -2);
+           pt[3].set(2, 2);
+           pt[4].set(0, 3);
+           pt[5].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2],
+                  &pt[3], &pt[4], &pt[5], 0);
+           p.draw();
+           p.shift(3, 3, 3);
+           p.draw();
+ 
+

+
+ [Figure 117. Not displayed.] +
+
+ Fig. 117. +
+

+ +
+ +
+ — Function: Transform shift (const Point& p)
+

Creates a Transform t locally and calls + t.shift(p). + t is then applied to all of the Points on points. + The return value is t. + +

This version of shift() uses the x, y, and z-coordinates of the + Point p to shift the Path. + +

          default_focus.set(5, 10, -10, 0, 10, 10, 10);
+           Point pt[6];
+           pt[0].set(-2, -2);
+           pt[1].set(0, -3);
+           pt[2].set(2, -2);
+           pt[3].set(2, 2);
+           pt[4].set(0, 3);
+           pt[5].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2],
+                  &pt[3], &pt[4], &pt[5], 0);
+           p.draw();
+           Point s(1, 1, 1);
+           p.shift(s);
+           p.draw();
+ 
+

+
+ [Figure 118. Not displayed.] +
+
+ Fig. 118. +
+

+ +
+ +
+ — Virtual function: void shift_times (real x, [real y = 1, [real z = 1]])
+ — Virtual function: void shift_times (const Point& p)
+

Each of these functions calls the corresponding version of + Point::shift_times() on all of the + Points on points. + See Point Reference; Affine Transformations. + The return value is void, + because there is no guarantee that all of the Points on a + Path will have identical transform members (although it's + likely). + +

Please note that shift_times() will only have an effect on + the Points on a Path if it's called after a call to + shift() and before an operation is applied that causes + Point::apply_transform() to be called. +

+ +
+ — Virtual function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+

Creates a Transform t locally and calls + t.rotate(p0, p1, angle). + t is then applied to all of the Points on points. + The return value is t. +

+ +
+ — Function: Transform rotate (const Path& p, [const real angle = 180])
+

If p.is_linear() returns true, this function + creates a Transform t locally and calls + t.rotate(p, angle). + t is then applied to all of the Points on points. + The return value is t. + Otherwise, it issues an error message and returns + INVALID_TRANSFORM. +

+ + + +

26.10 Aligning with an Axis

+ +
+ — const function: Transform align_with_axis ([const char axis = 'z'])
+ — Function: Transform align_with_axis (bool assign, [const char axis = 'z'])
+ — Function: Transform align_with_axis (const Point& p0, const Point& p1, const char axis)
+

These functions return the Transform which, if applied to the + Path, would align it with the major axis indicated by the + axis argument. + +

The first and second versions can only be called + for Paths where line_switch is true. The first + version is const, so the Path remains unchanged. The second + version should only be called with assign = true, so that the + Transform is applied to the Path, actually aligning it with + the axis indicated. If the second version is called with + assign = false, a warning message is issued to the standard error + output (stderr), since one might as well use the first version in + this case, but it won't do any harm. The third version creates a + Transform t locally that would align the line from p0 to + p1 with the axis indicated, and applies t to the Path. + +

          Point A(2, 3, 2);
+           Point B(-1, 1, 3);
+           Path p(A, B);
+           Transform t = p.align_with_axis(true, 'z');
+           t.show("t:");
+           -| t:
+               -0.316   0.507  -0.802       0
+                    0  -0.845  -0.535       0
+               -0.949  -0.169   0.267       0
+                 2.53    1.86    2.67       1
+           p *= t;
+           p.show("p:");
+           -| p:
+              (2.53, 1.86, 2.67) -- (-1.02, 1.23, 3.67);
+           
+           Point C(1);
+           C *= t.inverse();
+           
+           Path q;
+           q += "..";
+           q += C;
+           
+           for (int i = 0; i < 15; ++i)
+             {
+               C.rotate(A, B, 360.0/16);
+               q += C;
+             }
+           q.set_cycle(true);
+           q.show("q:");
+           -| q:
+              (1.68, 3, 1.05) .. (1.9, 2.68, 1.06) ..
+              (2.13, 2.4, 1.21) .. (2.35, 2.22, 1.48) ..
+              (2.51, 2.15, 1.83) .. (2.59, 2.22, 2.21) ..
+              (2.58, 2.4, 2.55) .. (2.49, 2.68, 2.81) ..
+              (2.32, 3, 2.95) .. (2.1, 3.32, 2.94) ..
+              (1.87, 3.6, 2.79) .. (1.65, 3.78, 2.52) ..
+              (1.49, 3.85, 2.17) .. (1.41, 3.78, 1.79) ..
+              (1.42, 3.6, 1.45) .. (1.51, 3.32, 1.19) .. cycle;
+           q.align_with_axis(A, B, 'z');
+           q.show("q:");
+           -| q:
+              (1, 0, 0) .. (0.924, 0.383, 0) ..
+              (0.707, 0.707, 0) .. (0.383, 0.924, 0) ..
+              (0, 1, 0) .. (-0.383, 0.924, 0) ..
+              (-0.707, 0.707, 0) .. (-0.924, 0.383, 0) ..
+              (-1, 0, 0) .. (-0.924, -0.383, 0) ..
+              (-0.707, -0.707, 0) .. (-0.383, -0.924, 0) ..
+              (0, -1, 0) .. (0.383, -0.924, 0) ..
+              (0.707, -0.707, 0) .. (0.924, -0.383, 0) .. cycle;
+ 
+

+
+ [Figure 119. Not displayed.] +
+
+ Fig. 119. +
+

+ +
+ + + +

26.11 Applying Transformations

+ +
+ — Virtual function: void apply_transform (void)
+

Calls Point::apply_transform() on all of the Points on + points. + See Point Reference; Applying Transformations. +

+ +
+ +


+ Next: , + Previous: Applying Transformations to Paths, + Up: Path Reference + +
+ +

26.12 Drawing and Filling

+ +
+ — const virtual function: void draw ([const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]]])
+ — const Virtual function: void draw (Picture& picture, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = ""]]])
+

Allocates a copy of the Path on the free store, puts a pointer to + the copy on picture.shapes, sets + its fill_draw_value to DRAW, and + the values of its + draw_color, dashed, and pen according to the + arguments. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

All of the arguments to draw() are optional, so it can be invoked + as follows: + +

          Point A;
+           Point B(2);
+           Point C(3, 3);
+           Point D(1, 2);
+           Point E(-1, 1);
+           Path p("..", true, &A, &B, &C, &D, &E, 0);
+           p.draw();
+ 
+

+
+ [Figure 120. Not displayed.] +
+
+ Fig. 120. +
+

+ +

The arguments: + +

+
ddraw_color
Used to specify a color for the + Path. ddraw_color is a reference to a Color. + Colors are described in Color Reference. + +

The most basic Colors are predefined in 3DLDF (in the + namespace Colors), and + users may create new Colors and specify their red-green-blue + values. + +

The Path p could be drawn in red by calling + p.draw(Colors::red). This manual isn't intended to be printed in + color, so there's no figure to demonstrate this. However, gray values + can be printed on non-color printers. + +

               using namespace Colors;
+                p.draw(gray, "", "pencircle scaled .25mm");
+ 
+

+
+ [Figure 121. Not displayed.] +
+
+ Fig. 121. +
+

+ +
ddashed
A string representing a “dash pattern”, as defined in + MetaPost39. + Dash patterns have no meaning in 3DLDF, they are simply strings + that are written unchanged to out_stream. + +
               p.draw(black, "evenly");
+ 
+

+
+ [Figure 122. Not displayed.] +
+
+ Fig. 122. +
+

+ +
ppen
A string representing a “pen”, as defined in Metafont and + MetaPost40. + Pens have no meaning in 3DLDF, they are simply strings + that are written unchanged to out_stream. + +
               p.draw(black, "", "pensquare xscaled 3mm
+                       yscaled .25mm scaled .5mm");
+ 
+

+
+ [Figure 123. Not displayed.] +
+
+ Fig. 123. +
+

+ +
picture
Indicates the Picture on which the Path should be + drawn. + +

The two versions of draw() differ in the position of the + picture argument: In the first version, it's the last argument, + while in the second version, it's the first argument. If a + picture argument is used, it's often more convenient to use the second + version. + +

The following example puts Path p onto temp_picture. It + also demonstrates how the labels are put onto temp_picture, and + how temp_picture is output. In + the previous examples, the commands for making the labels and outputting + current_picture were left out in order to reduce clutter. + See Point Reference; Labelling, and + Picture Reference; Outputting; Output Functions. + +

               Picture temp_picture;
+                p.draw(temp_picture);
+                A.dotlabel("A", "bot", temp_picture);
+                B.dotlabel("B", "bot", temp_picture);
+                C.dotlabel("C", "top", temp_picture);
+                D.dotlabel("D", "top", temp_picture);
+                E.dotlabel("E", "lft", temp_picture);
+                temp_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 124. Not displayed.] +
+
+ Fig. 124. +
+

+ +
+

+ +
+ — const function: void draw_help ([const Color& ddraw_color = *help_color, [string ddashed = help_dash_pattern, [string ppen = "", [Picture& picture = current_picture]]]])
+ — const function: void draw_help (Picture& picture, [const Color& ddraw_color = *help_color, [string ddashed = help_dash_pattern, [string ppen = ""]]])
+

This functions are for drawing help lines. + They are like draw(), except that draw_help() returns immediately, + if do_help_lines (a static data member in + Path) is false. + Also, the defaults for ddraw_color and + ddashed differ from those for draw(). +

+ +
+ — const virtual function: void drawarrow ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — const virtual function: void drawarrow (Picture& picture, [const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = ""]]])
+

Like draw(), except that the MetaPost command drawarrow is + written to out_stream when picture + is output. + The second version is convenient for passing a Picture argument + without having to specify all of the other arguments. + + + +

          Point m;
+           Point n(2, 2);
+           m.dotlabel("$m$", "bot");
+           n.dotlabel("$n$");
+           m.drawarrow(n);
+ 
+

+
+ [Figure 125. Not displayed.] +
+
+ Fig. 125. +
+

+ +
+ +
+ — Non-member function: void draw_axes ([real dist = 2.5, [string pos_x = "bot", [string pos_y = "lft", [string pos_z = "bot", [const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string ppen = "", [const Point& shift_x = origin, [const Point& shift_y = origin, [const Point& shift_z = origin, [Picture& picture = current_picture]]]]]]]]]]])
+ — Non-member function: void draw_axes (const Color& ddraw_color, [real dist = 2.5, [string pos_x = "bot", [string pos_y = "lft", [string pos_z = "bot", [const string ddashed = "", [const string ppen = "", [const Point& shift_x = origin, [const Point& shift_y = origin, [const Point& shift_z = origin, [Picture& picture = current_picture]]]]]]]]]])
+

These functions draw lines centered on the origin, and ending in arrows in the + directions of the positive x, + y, and z-axes, and labels them with the appropriate letters. + draw_axes() is used in + many of the figures in this handbook. It can be helpful in determining + whether a Focus has a good “up” direction. + See Focus Reference; Data Members. + +

In the first version, all of the arguments are optional. In the second + version, ddraw_color is required and has been moved to the front + of the argument list. This version is often convenient, when a + Color other than the default is desired. + +

The arguments: +

+
dist
The length of the lines drawn. The default is 2.5. The value 0 can be + used as a dummy argument, if the default for dist is desired, but + other arguments must be specified. + +
pos_x
pos_y
pos_z
The position arguments for the labelling commands for each of the axes. + The defaults are "bot" for the x and z-axes, and "lft" for + the y-axis. + The usual strings for the + position of labels can be used, + namely: "top", "bot", "lft", + "rt", "ulft", "urt", "llft", + "lrt", and "". If "" is used, that axis is not + drawn. This can be useful for parallel projections onto one of the + major planes41. + In addition, "d" can be used to indicate that the default should + be used for that label. This can be useful if one needs a placeholder, + but doesn't remember what the default is for that label. + +
               draw_axes(0, "bot", "rt", "");
+                current_picture.output(Projections::PARALLEL_X_Y);
+ 
+

+
+ [Figure 126. Not displayed.] +
+
+ Fig. 126. +
+

+ +

In addition, the arguments shift_x, shift_y, + and shift_z can be used to adjust the positions of the labels + further (see below). + +

ddraw_color
ddashed
ppen
Arguments for the drawarrow() command, described above, in this + section. + +
shift_x
shift_y
shift_z
Offsets for the labels. These arguments make it possible to adjust the + positions of the labels. The defaults are origin, so no shifting + takes place, if they are used. In [next figure] + , + draw_axes is called without any arguments, so the defaults + are used. + +
               draw_axes();
+ 
+

+
+ [Figure 127. Not displayed.] +
+
+ Fig. 127. +
+

+ +

In [next figure] + , the Point P is used to shift the labels. + Please note that placeholders must be used for the first arguments. + +

               Point P(.5, .5, .5);
+                draw_axes(0, "d", "d", "d", black, "", "", P, -P, P);
+ 
+

+
+ [Figure 128. Not displayed.] +
+
+ Fig. 128. +
+

+ +

Please note that the Points used for placing the labels are + three-dimensional Points, whether the shift_x, + shift_y, and/or shift_z arguments are used or not. + It is not currently possible to adjust the positions of the + labels on the two-dimensional projection itself. This would + probably be more useful, but would require changing the way + Picture::output() functions. + +

picture
The Picture, onto which the Paths and Labels are put. +
+

+ +
+ — const function: void fill ([const Color& ffill_color = *Colors::default_color, [Picture& picture = current_picture]])
+ — Function: void fill (Picture& picture, [const Color& ffill_color = *Colors::default_color])
+
+

Allocates a copy of the Path on the free store, puts a pointer to + it onto picture.shapes, sets + its fill_draw_value to FILL, and + its fill_color to *ffill_color. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

The arguments are similar to those of draw(), except that the + Color argument is called ffill_color instead of + ddraw_color. + +

          p.fill(gray);
+ 
+

+
+ [Figure 129. Not displayed.] +
+
+ Fig. 129. +
+

+ +
+ +
+ — const function: void filldraw ([const Color& ddraw_color = *Colors::default_color, [const Color& ffill_color = *Colors::background_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]]])
+ — const function: void filldraw (Picture& picture, [const Color& ddraw_color = *Colors::default_color, [const Color& ffill_color = *Colors::background_color, [string ddashed = "", [string ppen = ""]]]])
+

Allocates a copy of the Path on the free store, puts a pointer to + the copy onto picture.shapes, sets + its fill_draw_value to FILLDRAW, + its draw_color and fill_color to + *ddraw_color and *ffill_color, respectively, + its dashed to ddashed, and its pen + to ppen. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

The arguments are similar to those of draw() and fill(), + except that both ddraw_color and ffill_color are used. + +

3DLDF's filldraw() differs from Metafont's and MetaPost's + filldraw commands: In Metafont and MetaPost, filldrawing + is equivalent to filling a path and then drawing its + border using the pen. + Metafont does not have colors. While MetaPost does, its filldraw + command does not foresee the use of different colors for drawing and + filling. + +

          p.filldraw(black, gray, "", "pencircle scaled 2mm");
+ 
+

+
+ [Figure 130. Not displayed.] +
+
+ Fig. 130. +
+

+ +

It can often be useful to draw the outline of a Path, but to have + it hide objects that lie behind it. This is why the default for + ffill_color is *Colors::background_color. + +

          default_focus.set(3, 0, -10, 3, 10, 10, 10);
+           Point p[8];
+           p[0] = p[1] = p[2] = p[3] = p[4]
+                = p[5] = p[6] = p[7].set(-1,-1, 5);
+           p[1] *= p[2] *= p[3] *= p[4] *= p[5]
+                *= p[6] *= p[7].rotate(0, 0, 45);
+           p[2] *= p[3] *= p[4]
+                *= p[5] *= p[6] *= p[7].rotate(0, 0, 45);
+           p[3] *= p[4] *= p[5] *= p[6]
+                *= p[7].rotate(0, 0, 45);
+           p[4] *= p[5] *= p[6] *= p[7].rotate(0, 0, 45);
+           p[5] *= p[6] *= p[7].rotate(0, 0, 45);
+           p[6] *= p[7].rotate(0, 0, 45);
+           p[7].rotate(0, 0, 45);
+           Path r0("..", true, &p[0], &p[1], &p[2],
+                   &p[3], &p[4], &p[5], &p[6], &p[7], 0);
+           r0.filldraw(black, light_gray);
+           r0.scale(2, .5);
+           r0.shift(0, 0, -2.5);
+           r0.filldraw(black, gray);
+           r0.scale(.25, 3);
+           r0.shift(0, 0, -2.5);
+           r0.filldraw();
+ 
+

+
+ [Figure 131. Not displayed.] +
+
+ Fig. 131. +
+

+ +
+ +
+ — Function: void undraw ([string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]])
+ — Function: void undraw (Picture& picture, [string ddashed = "", [string ppen = ""]])
+

Allocates a copy of the Path on the free store, puts a pointer to + it on picture.shapes, sets + its fill_draw_value to UNDRAW, and + the values of its + dashed and pen according to the + arguments. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

This function “undraws” a Path. This is equivalent to drawing + the Path using the background color + (*Colors::background_color). + +

Undrawing is useful for removing a portion of a Path. + + +

          Point P0(1, 1);
+           Point P1(2, 1);
+           Point P2(2, 3);
+           Point P3(-1, 1);
+           Path p("--", false, &origin, &P0, &P1, &P2, &P3, 0);
+           p.draw(black, "", "pencircle scaled 3mm");
+           p.undraw("", "pencircle scaled 1mm");
+ 
+

+
+ [Figure 132. Not displayed.] +
+
+ Fig. 132. +
+

+ +
+ +
+ — Function: void unfill ([Picture& picture = current_picture])
+

Allocates a copy of the Path on the free store, puts a pointer to + it on picture.shapes and sets + its fill_draw_value to UNFILL + +

This function is useful for removing a portion of a filled region. + +

          Point pt[4];
+           pt[0].set(-2, -2);
+           pt[1].set(2, -2);
+           pt[2].set(2, 2);
+           pt[3].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2], &pt[3], 0);
+           p.draw();
+           p.dotlabel();
+           p.filldraw(black, gray);
+           p.scale(.5, .5);
+           p.unfill();
+ 
+

+
+ [Figure 133. Not displayed.] +
+
+ Fig. 133. +
+

+ +
+ +
+ — Function: void unfilldraw ([const Color& ddraw_color = *Colors::background_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+ — Function: void unfilldraw (Picture& picture, [const Color& ddraw_color = *Colors::background_color, [string ddashed = "", [string ppen = ""]]])
+

Allocates a copy of the Path on the free store, puts a pointer to + it on picture.shapes, sets + its fill_draw_value to UNFILLDRAW, and + the values of its + draw_color, dashed, and pen according to the + arguments. While the default for ddraw_color is + *Colors::background_color, any other Color can be used, + so that unfilldraw() can unfill a Path and draw an outline + around it. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. + +

This function is similar to unfill() + (see Path Reference; Drawing and Filling), + except that the outline of the Path will be “undrawn” using the + pen specified with the ppen argument, or MetaPost's + currentpen, if no ppen argument is specified. In addition, + the Path will be drawn using the Color specified in the + ddraw_color argument. Since the default is + *Colors::background_color, the Path will be “undrawn” + unless a different Color is specified. + +

          Point pt[6];
+           pt[0].set(-2, -2);
+           pt[1].set(0, -3);
+           pt[2].set(2, -2);
+           pt[3].set(2, 2);
+           pt[4].set(0, 3);
+           pt[5].set(-2, 2);
+           Path p("--", true, &pt[0], &pt[1], &pt[2],
+                  &pt[3], &pt[4], &pt[5], 0);
+           p.fill(gray);
+           p.scale(.5, .5);
+           p.unfilldraw(black, "", "pensquare xscaled 3mm");
+ 
+

+
+ [Figure 134. Not displayed.] +
+
+ Fig. 134. +
+

+ +
+ +
+ +


+ Next: , + Previous: Drawing and Filling Paths, + Up: Path Reference + +
+ +

26.13 Labelling

+ +
+ — const function: void label ([unsigned int i = 0, [string position_string = "top", [short text_short = 0, [bool dot = false, [Picture& picture = current_picture]]]]])
+ — const function: void label (Picture& picture, [unsigned int i = 0, [string position_string = "top", [short text_short = 0, [bool dot = false]]]])
+

Calls Point::label() on all of the Points on + points. They are numbered consecutively starting with i. + The other arguments are used for all of the Points, so it's not + possible to specify different positions for the labels for different + Points. dot will normally not be specified, unless a + picture argument is used in the first version. dotlabel() + calls label() with dot = true. + +

The second version is convenient for passing a + Picture argument without having to specify all of the other arguments. +

+ +
+ — const function: void dotlabel ([unsigned int i = 0, [string position_string = "top", [short text_short = 0, Picture& picture = current_picture]]])
+ — const function: void dotlabel (Picture& picture, [unsigned int i = 0, [string position_string = "top", [short text_short = 0]]])
+

Like label(), except that the Points are dotted. +

+ +
+ +


+ Next: , + Previous: Labelling Paths, + Up: Path Reference + +
+ +

26.14 Showing

+ +
+ — const function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [const real factor = 1]]]]]]])
+

Prints information about the Path to standard output + (stdout). text is simply printed out, unless it's the + empty string, in which case "Path:" is printed out. + coords indicates which set of coordinates should be shown. Valid values are + 'w' for the world_coordinates, 'p' for the + projective_coordinates, 'u' for the + user_coordinates, and 'v' for the view_coordinates, + whereby the latter two are currently not in use + (see Point Reference; Data Members). + If do_apply is true, apply_transform() is called + on each Point, updating its world_coordinates and + resetting its transform. Otherwise, + it's not. + The arguments do_persp, f, proj, and factor are only + relevant when showing projective_coordinates. If do_persp + is true, the Points are projected using the values of + f, proj, and factor + (see Path Reference; Outputting). + Otherwise, the values currently + stored in projective_coordinates are shown. + The Points and connectors are printed out alternately to standard + output, followed by the word “cycle”, if cycle_switch = true.42 + +

          default_focus.set(0, 3, -10, 0, 3, 10, 10);
+           Reg_Polygon r(origin, 5, 3, 45);
+           r.fill(gray);
+           Point p[10];
+           for (int i = 0; i < 5; ++i)
+               p[i] = r.get_point(i);
+           p[5] = Point::intersection_point(p[4], p[0], p[2], p[1]).pt;
+           p[6] = Point::intersection_point(p[0], p[1], p[2], p[3]).pt;
+           p[7] = Point::intersection_point(p[1], p[2], p[4], p[3]).pt;
+           p[8] = Point::intersection_point(p[2], p[3], p[0], p[4]).pt;
+           p[9] = Point::intersection_point(p[3], p[4], p[0], p[1]).pt;
+           Path q("--", true, &p[0], &p[5], &p[1], &p[6], &p[2], &p[7],
+                  &p[3], &p[8], &p[4], &p[9], 0);
+           q.draw();
+           q.show("q:");
+           -| q:
+           fill_draw_value == 0
+           (0, 1.06066, 1.06066)
+           -- (-2.30826, 2.24651, 2.24651)
+           -- (-1.42658, 0.327762, 0.327762)
+           -- (-3.73485, -0.858092, -0.858092)
+           -- (-0.881678, -0.858092, -0.858092)
+           -- (4.92996e-07, -2.77684, -2.77684)
+           -- (0.881678, -0.858092, -0.858092)
+           -- (3.73485, -0.858092, -0.858092)
+           -- (1.42658, 0.327762, 0.327762)
+           -- (2.30826, 2.24651, 2.24651) -- cycle;
+           q.show("q:", 'p');
+           -| q:
+           fill_draw_value == 0
+           Projective coordinates.
+           (0, -1.75337, 0.0958948)
+           -- (-1.88483, -0.615265, 0.183441)
+           -- (-1.38131, -2.58743, 0.031736)
+           -- (-4.08541, -4.22023, -0.0938636)
+           -- (-0.964435, -4.22023, -0.0938636)
+           -- (0, -7.99767, -0.384436)
+           -- (0.964436, -4.22023, -0.0938636)
+           -- (4.08541, -4.22023, -0.0938636)
+           -- (1.38131, -2.58743, 0.031736)
+           -- (1.88483, -0.615266, 0.183441) -- cycle;
+ 
+

+
+ [Figure 135. Not displayed.] +
+
+ Fig. 135. +
+

+ +
+ +
+ — Function: void show_colors ([bool = false])
+

Shows the values of draw_color and fill_color. These will + normally be 0, unless the Path is on a Picture. +

+ +
+ +


+ Next: , + Previous: Showing Paths, + Up: Path Reference + +
+ +

26.15 Querying

+ + + +
+ — const function: bool is_on_free_store (void)
+

Returns true, if the Path was dynamically allocated on the + free store, otherwise false. +

+ +
+ — const virtual function: bool is_planar ([const bool verbose = false, [string text = ""]])
+

Uses get_normal() to determine + whether the Path is planar or not. Returns true, if it is, + otherwise false. If verbose is true, text is written to + standard output, or “Path:”, if text is the empty string, + followed by a message saying whether the Path is planar or not. +

+ +
+ — const function: bool is_linear ([const bool verbose = false, [string text = ""]])
+

Returns true, if line_switch is true. Otherwise, + is_linear() uses get_normal() to determine whether the + Path is linear. If it is, is_linear() returns + true, otherwise false. +

+ +
+ — Inline const function: bool is_cycle (void)
+

Returns true if the Path is cyclical, i.e., + cycle_switch = true, otherwise false. Only cyclical + Paths are fillable. +

+ +
+ — Inline function: int size (void)
+

Returns the number of Points on points, i.e., + points.size(). +

+ +
+ — Inline const function: bool get_line_switch (void)
+

Returns the value of line_switch. line_switch is only + true, if the Path was created, directly or indirectly, using the + constructor taking two Point arguments only. + See Path Reference; Constructors and Setting Functions. +

+ +
+ — Function: real slope ([char a = 'x', [char b = 'y']])
+

Returns the slope of the Path in the plane indicated by the + arguments, if is_linear() returns true. Otherwise, + slope() issues an error message and returns INVALID_REAL. +

+ +
+ — const function: Path subpath (size_t start, size_t end, [const bool cycle = false, [const string connector = ""]])
+

Returns a new Path using points[start] through + points[end - 1]. If cycle is true, then the new + Path will be a cycle, whether + *this is or not. One optional connector + argument can be used. If it is, it will be the only connector. + Otherwise, the appropriate connectors from *this are used. + +

start must be < end. It is not possible to + have start > end, even if *this is a cycle. +

+ +
+ — const function: const Point& get_point (const unsigned short a)
+

Returns the Point *points[a], if a < + points.size() and the Path is non-empty, otherwise + INVALID_POINT. +

+ +
+ — const function: const Point& get_last_point (void)
+

Returns the Point pointed to by the last pointer on points. + Equivalent to get_point(get_size() - 1), but more convenient to + type. Returns INVALID_POINT, if the Path is empty. +

+ +
+ — const inline virtual function: size_t get_size (void)
+

Returns points.size(). +

+ +
+ — const function: Line get_line (void)
+

Returns a Line corresponding to the Path, if the latter is + linear. Otherwise, INVALID_LINE is returned. + See Line Reference. +

+ +
+ — const virtual function: Point get_normal (void)
+

Returns a Point representing a unit vector in the direction of the + normal to the plane of the Path, or INVALID_POINT, if + the Path is non-planar. + +

          Point P(1, 1, 1);
+           Rectangle r(P, 4, 4, 30, 30, 30);
+           Point N = r.get_normal();
+ 
+

+
+ [Figure 136. Not displayed.] +
+
+ Fig. 136. +
+

+ +

In 3DLDF, plane figures generally have constructors taking a |Point| + argument for the center, a variable number of |real| arguments for the + dimensions, and three |real| arguments for the rotation about the major + axes. The object is first created in the x-z plane, and the + Points are generated to be traversed in the counter-clockwise + direction, when seen from a Point with a positive y-coordinate. + If no rotation is specified, the normal will point in the direction of + the positive y-axis. If non-zero arguments are used for rotation, the + normal will be rotated accordingly. This direction considered to be + “outside”. However, according to Huw + Jones, Computer Graphics Through Key Mathematics, p. 197, + “outside” is considered to be the side of a plane, where the + Points are meant to be traversed in the clockwise direction. + I hope that no problems arise from this discrepancy! +

+ +
+ — const virtual function: Plane get_plane (void)
+

Creates and returns a Plane p corresponding to the Path, + if the latter is planar, otherwise INVALID_PLANE. + If the Path is planar, p.point will be the + Point pointed to by this->points[0]. + See Plane Reference. + +

          Point P(1, 1, 1);
+           Rectangle r(P, 4, 4, 45, 20, 15);
+           Plane q = r.get_plane();
+           q.show("q:");
+           -| q:
+              normal: (0.0505914, 0.745607, -0.664463)
+              point: (0.0178869, -0.727258, -1.01297)
+              distance == -0.131735
+ 
+

+
+ [Figure 137. Not displayed.] +
+
+ Fig. 137. +
+

+ +
+ +
+ — Function: void set_cycle ([const bool c = true])
+

Sets cycle_switch to c. +

+ +
+ — Function: Path reverse (bool assign)
+ — const function: Path reverse (void)
+

These functions return a Path with the same Points and + connectors as *this, but in reversed order. + reverse() can only be applied to non-cyclical Paths. If + *this is a cycle, reverse() issues an error message and + returns *this unreversed. + +

If the first version is called with assign = true, + *this itself is reversed. If *this should remain + unchanged, the const version without an argument should be + called. If, on the other hand, the first version is called with + assign = false, a warning message is issued, but the + reversed Path is returned just the same, leaving *this + unchanged. + + +

+ +
+ +


+ Next: , + Previous: Querying Paths, + Up: Path Reference + +
+ +

26.16 Outputting

+ +
+ — Function: bool project (const Focus& f, const unsigned short proj, real factor)
+

Calls Point::project(f, proj, factor) on the + Points on the Path. + If Point::project() fails (i.e., returns false), for any of + the Points, this function + returns false. Otherwise, it returns true. +

+ +
+ — Function: vector<Shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Checks that the Points on points can be projected using + the values for f, proj, and factor. If they can, a + vector<Shape*> containing only this is returned. Called in + Picture::output(). +

+ +
+ — Virtual function: bool set_extremes (void)
+

Sets the appropriate elements in projective_extremes to the + minimum and maximum values of the x, y, and z-coordinates of + the Points on the Path. Used in Picture::output() + for determining whether a Path can be output using the arguments + passed to Picture::output(). +

+ +
+ — Inline const virtual function: const valarray<real> get_extremes (void)
+

Returns projective_extremes. Used in Picture::output(). +

+ +
+ — const virtual function: real get_minimum_z (void)
+ — const virtual function: real get_mean_z (void)
+ — const virtual function: real get_maximum_z (void)
+

These functions return the minimum, mean, or maximum value, + respectively, of the + z-coordinates of the Points on the Path. + Used in the surface hiding algorithm in Picture::output(). +

+ +
+ — Virtual function: void suppress_output (void)
+

Called in Picture::output(). + Sets do_output to + false, if the Path cannot be output using the arguments + passed to Picture::output(). +

+ +
+ — Virtual function: void unsuppress_output (void)
+

Called in Picture::output(). Resets do_output to + true after output() is called on the Shapes on + shapes in a Picture, so that the Path can be output + if Picture::output() is called again, with arguments that allow + the Path to be output. +

+ +
+ — Virtual function: void output (void)
+

Called in Picture::output(). Writes the MetaPost code to + out_stream for drawing, filling, filldrawing, undrawing, + unfilling, or unfilldrawing the Path, if the latter was + projectable using the arguments passed to Picture::output(). +

+ +
+ +


+ Previous: Outputting Paths, + Up: Path Reference + +
+ +

26.17 Intersections

+ +
+ — Function: bool_point intersection_point (const Path& p, const bool trace)
+

Finds the intersection point, if any, of two linear Paths. + Let bp be the bool_point returned by + this function. bp.pt will contains the + intersection point, if it exists. If not, it will contain + INVALID_POINT. If the intersection point exists and lies on both + of the line segments represented by the Path and p, + bp.b will be true, otherwise, false. + +

This function calls Point::intersection_points(), passing the first + and last Points on *this and p as its arguments. If + the trace argument is false, the version of + Point::intersection_points() that finds the intersection point by + means of a vector calculation is used. If it's true, the version + that finds the intersection point of the traces of the lines on the + major planes is used. + See Point Reference; Intersections. + +

          Point A(-1, -1, -1);
+           Point B(1, 1, 1);
+           Path p0(A, B);
+           Point C(-2, 1, 1);
+           Point D(1.75, 0.25, 0.25);
+           Path p1(C, D);
+           bool_point bp = p0.intersection_point(p1);
+           bp.pt.dotlabel("$i$");
+           bp.pt.show("bp.pt:");
+           -| bp.pt: (0.5, 0.5, 0.5)
+ 
+

+
+ [Figure 138. Not displayed.] +
+
+ Fig. 138. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Path Reference, + Up: Top + +
+ +

27 Polygon Reference

+ +

Class Polygon is defined in polygons.web, and + is derived from Path, using public derivation. + +

Polygon is mainly intended for use as a base class for more + specialized kinds of polygons. Currently, the classes + Reg_Polygon (regular polygon) and Rectangle are defined. + See Regular Polygon Reference, and Rectangle Reference. + +

+ +
+ +


+ Next: , + Previous: Polygon Reference, + Up: Polygon Reference + +
+ +

27.1 Data Members

+ +
+ — Private variable: Point center
+

The center of the Polygon, if it has one. However, a + Polygon need not have a center. If it doesn't, + center should be set to INVALID_POINT. +

+ +
+ +


+ Next: , + Previous: Polygon Data Members, + Up: Polygon Reference + +
+ +

27.2 Operators

+ +
+ — Virtual operator: Transform operator*= (const Transform& t)
+

Multiplies a Polygon by the Transform t. + Similar to Path::operator*=(const Transform& t), except that + center is transformed as well. + See Path Reference; Operators. +

+ + + +

27.3 Querying

+ +
+ — Virtual function: const Point& get_center (void)
+ — const function: Point get_center (void)
+

These functions return center. If the Polygon doesn't + contain any Points, a warning is issued, and INVALID_POINT + is returned. +

+ +
+ +


+ Next: , + Previous: Querying Polygons, + Up: Polygon Reference + +
+ +

27.4 Affine Transformations

+ +
+ — Virtual function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — Virtual function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+ — Virtual function: Transform rotate (const Path& p, [const real angle = 180])
+ — Virtual function: Transform scale (real x, [real y = 1, [real z = 1]])
+ — Virtual function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+ — Virtual function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Virtual function: Transform shift (const Point& p)
+ — Virtual function: void shift_times (real x, [real y = 1, [real z = 1]])
+ — Virtual function: void shift_times (const Point& p)
+

The affine transformation functions for Polygon differ from the + Path versions only in that center is transformed as well. + See Path Reference; Affine Transformations. + +

Please note, that the classes currently derived from Polygon, + namely Reg_Polygon and Rectangle, currently inherit these + functions from Polygon. The problem with this is, that they have + data members, which are not recalculated when a Reg_Polygon or + Rectangle is transformed. I plan to do something about this soon! + It will also be necessary to add the function + Reg_Polygon::is_reg_polygonal(), in order to test whether operations + on a Reg_Polygon have caused it to become + irregular and/or non-polygonal. Similarly, the function + Rectangle::is_rectangular() must be added, to test whether + operations on a Rectangle has caused it to become + non-rectangular. + See Regular Polygon Reference; Data Members, and Rectangle Reference; Data Members. +

+ + + +

27.5 Intersections

+ +
+ — const function: bool_point_pair intersection_points (const Point& p0, const Point& p1)
+ — const function: bool_point_pair intersection_points (const Path& p)
+

These functions find the intersections of the + Polygon and a line. + In the first version, the Point arguments are the end points of + the line. The argument to the second version must be a linear + Path. + +

A line and a regular polygon or rectangle43 + can intersect at two points at most. + Let b be a bool_point_pair returned by + intersection_points(). + If no + intersection points are found, b.first.pt and b.second.pt + will be INVALID_POINT, and b.first.b and b.second.b + will be false. If a single intersection point is found, the + corresponding Point will be stored in b.first.pt. If the + Point is on the line segment + p_0p_1 + , + b.first.b will be true, + otherwise false. If a second intersection point is found, it + will be stored in b.second.pt, and b.second.b is set + analogously to b.first.b. + +

When the Point arguments and the Reg_Polygon are coplanar, + as in [next figure] + , two intersection points are possible. In this case, + only intersection points of the line with an edge of the + Reg_Polygon are returned in the bool_point_pair. + +

          Point A(1, 1, 1);
+           Reg_Polygon r(origin, 5, 3);
+           Transform t;
+           t.rotate(15, 12, 11);
+           t.shift(A);
+           Point P(-2, 0, -1);
+           Point Q(2, 0, 1);
+           P *= Q *= r *= t;
+           bool_point_pair bpp = r.intersection_points(P, Q);
+           bpp.first.pt.dotlabel("$f$", "rt");
+           bpp.second.pt.dotlabel("$s$");
+ 
+

+
+ [Figure 139. Not displayed.] +
+
+ Fig. 139. +
+

+ +

In [next figure] + , the lines BC + and + PQ + +

are not coplanar with the Reg_Polygon r. In each case, only + one intersection point is possible, and it can be either an intersection + with an edge of the + Reg_Polygon, or lie within its perimeter. + +

          Point B(r.get_point(3).mediate(r.get_point(4)));
+           Point C(B);
+           B.shift(0, 2, .5);
+           C.shift(0, -2, -.5);
+           Point P(-1, -2, -1);
+           Point Q(0, 2, 1);
+           B *= C *= P *= Q *= r *= t;
+           bool_point_pair bpp = r.intersection_points(B, C);
+           bpp.first.pt.dotlabel("$i_0$", "rt");
+           bpp = r.intersection_points(P, Q);
+           bpp.first.pt.dotlabel("$i_1$", "rt");
+ 
+

+
+ [Figure 140. Not displayed.] +
+
+ Fig. 140. +
+

+ +

In [next figure] + , the intersection point of r with the line + PQ + +

does not lie on the line segment PQ. + +

          bpp = r.intersection_points(P, Q);
+           bpp.first.pt.dotlabel("$i$", "rt");
+           cout << "bpp.first.b == " << bpp.first.b << endl << flush;
+           -| bpp.first.b == 0
+ 
+

+
+ [Figure 141. Not displayed.] +
+
+ Fig. 141. +
+

+ +
+ +
+ — const function: vector<Point> intersection_points (const Polygon& r)
+

Finds the intersection points of two Polygons. + Let v be the vector<Point> returned by + intersection_points(). If the Polygons are coplanar, + v + will contain the intersection points of the edges of the + Polygons, as in [next figure] + . + +

          Rectangle r(origin, 4, 4);
+           Reg_Polygon rp(origin, 5, 5, 0, 36);
+           rp.shift(0, 0, .25);
+           vector <Point> v = r.intersection_points(rp);
+ 
+

+
+ [Figure 142. Not displayed.] +
+
+ Fig. 142. +
+

+ +

If the Polygons lie in parallel planes, there can be no + intersection points. If they lie in non-parallel, non-coplanar planes, + intersection_points() first finds the intersection line of the + two planes. Then it finds the intersection points of this line with the + two Polygons, if they exist. There can no more than four + intersection points, in this case. + v[0] and v[1] will be the + intersection points of the line with *this, while v[2] and + v[3] will be the intersection points of the line with r. If one + or more of the intersection points doesn't exist, the corresponding + member of v will contain INVALID_POINT as a placeholder. + +

          Point A(1, 1, 1);
+           Rectangle r(A, 4, 4);
+           Reg_Polygon p(A, 5, 5);
+           p.rotate(90, 30);
+           p.shift(2, 0, 3);
+           vector <Point> v = r.intersection_points(p);
+ 
+

+
+ [Figure 143. Not displayed.] +
+
+ Fig. 143. +
+

+ +

In [next figure] + , the Rectangle r and the Reg_Polygon p + don't overlap at all, nor does the intersection line of the two planes + intersect with p. However, it does intersect with p at the + labelled Points. + +

          Point A(1, 1, 1);
+           Rectangle r(A, 4, 4);
+           Reg_Polygon p(A, 5, 5);
+           p.rotate(90, 30);
+           p.shift(4, 3, 3);
+           vector <Point> v = r.intersection_points(p);
+           int i = 0;
+           for (vector<Point>::iterator iter = v.begin();
+            iter != v.end(); ++iter)
+            iter->dotlabel(i++, "bot");
+ 
+

+
+ [Figure 144. Not displayed.] +
+
+ Fig. 144. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Polygon Reference, + Up: Top + +
+ +

28 Regular Polygon Reference

+ +

Class Reg_Polygon is defined in polygons.web, and + is derived from Polygon, using public derivation. + +

As noted above in Polygon Reference; Affine Transformations, class Reg_Polygon, + like class Rectangle, + currently inherits its transformation functions and + operator*=(const Transform&) from Polygon. Consequently, + the data members of a Reg_Polygon, except for center, are + not recalculated when it's transformed. I plan to change this soon! It + will also be necessary to add the function + Reg_Polygon::is_reg_polygonal(), in order to test whether a + Reg_Polygon is still regular and polygonal. + +

+ + + +

28.1 Data Members

+ +
+ — Private variable: real internal_angle
+

The angle at the center of the Reg_Polygon of the triangle formed + by the center and two adjacent corners. + If n is the number of sides of a Reg_Polygon, + internal_angle will be 360.0/n, so internal_angle + will be 120 for a regular triangle, 90 for a square, 72 for a pentagon, + etc. + +

+ +
+ — Private variable: real radius
+

The radius of the surrounding circle for a Reg_Polygon (Umkreis). +

+ +
+ — Private variable: unsigned short sides
+

The number of sides of a Reg_Polygon. +

+ +
+ — Private variable: bool on_free_store
+

true, if the Reg_Polygon was dynamically allocated on the + free store, otherwise false. Dynamic allocation of + Reg_Polygons should only be + performed by create_new<Reg_Polygon>(), which sets + on_free_store to true. +

+ + + +

28.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Reg_Polygon (void)
+

Creates an empty Reg_Polygon. +

+ +
+ — Constructor: void Reg_Polygon (const Point& ccenter, const unsigned short ssides, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Creates a Reg_Polygon in the x-z plane, centered at the origin, + with the number of sides specified by ssides and with + radius = ddiameter / 2. + +

The Reg_Polygon is rotated + about the x, y, and z-axes in that order by the angles given by + angle_x, angle_y, and angle_z, respectively, if any + one of them is non-zero. Finally, the + Reg_Polygon is shifted such that its center is located at + ccenter. + +

          Reg_Polygon r(origin, 3, 2.75, 10, 15, 12.5);
+           r.draw();
+ 
+

+
+ [Figure 145. Not displayed.] +
+
+ Fig. 145. +
+

+ +
+ +
+ — Setting function: void set (const Point& ccenter, const unsigned short ssides, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Corresponds to the constructor above. + +

A Reg_Polygon can theoretically have any number of sides, however + I haven't tested it for unreasonably large values. The following + example demonstrates that set() can be used to change a + Reg_Polygon. + +

          Reg_Polygon r;
+           real j = .5;
+           for (int i = 3; i <= 16; ++i)
+             {
+               r.set(origin, i, j);
+               r.draw();
+               j += .5;
+             }
+ 
+

+
+ [Figure 146. Not displayed.] +
+
+ Fig. 146. +
+

+ +
+ +
+ — Template specializations: Reg_Polygon* create_new<Reg_Polygon> (const Reg_Polygon* r)
+ — : Reg_Polygon* create_new<Reg_Polygon> (const Reg_Polygon& r)
+

Pseudo-constructors for dynamic allocation of Reg_Polygons. + They create a Reg_Polygon on the free store and allocate memory for it using + new(Reg_Polygon). They return a pointer to the new Reg_Polygon. + If r is a non-zero pointer or a reference, + the new Reg_Polygon will be a copy of + r. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Reg_Polygon>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + +

28.3 Operators

+ +
+ — Operator: const Reg_Polygon& operator= (const Reg_Polygon& p)
+

Makes the Reg_Polygon a copy of p. +

+ + + +

28.4 Querying

+ +
+ — const inline function: real get_radius (void)
+

Returns radius. +

+ + + +

28.5 Circles

+ +
+ — const function: Circle in_circle (void)
+

Returns the enclosed Circle of the Reg_Polygon. + +

          Point P(0, -1, 1);
+           Reg_Polygon h(P, 6, 4, 15, 12, 11.5);
+           h.filldraw(black, gray);
+           Circle c = h.in_circle();
+           c.unfilldraw(black);
+ 
+

+
+ [Figure 147. Not displayed.] +
+
+ Fig. 147. +
+

+ +
+ +
+ — const function: Circle draw_in_circle ([const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = "", [Picture& picture = current_picture]]])
+ — const function: Circle draw_in_circle ([Picture& picture = current_picture, [const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = ""]]])
+

Draws and returns the enclosed Circle of the Reg_Polygon. + +

          Point P(0, 1, 1);
+           Reg_Polygon h(P, 7, 4, 80, 2, 5);
+           h.draw(black, "evenly");
+           h.draw_in_circle();
+ 
+

+
+ [Figure 148. Not displayed.] +
+
+ Fig. 148. +
+

+ +
+ +
+ — const function: Circle out_circle (void)
+

Returns the surrounding Circle of the Reg_Polygon. + +

          Point P(0, -1, 1);
+           Reg_Polygon h(P, 6, 4, 15, 12, 11.5);
+           Circle c = h.out_circle();
+           c.filldraw(black, gray);
+           h.unfilldraw(black);
+ 
+

+
+ [Figure 149. Not displayed.] +
+
+ Fig. 149. +
+

+ +
+ +
+ — const function: Circle draw_out_circle ([const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = "", [Picture& picture = current_picture]]])
+ — const function: Circle draw_out_circle ([Picture& picture = current_picture, [const Color& ddraw_color = *Colors::default_color, [const string ddashed = "", [const string] ppen = ""]]])
+

Draws and returns the surrounding Circle of the Reg_Polygon. + +

          Point P(0, 1, 1);
+           Reg_Polygon h(P, 7, 4, 80, 2, 5);
+           h.draw(black, "evenly");
+           h.draw_out_circle();
+ 
+

+
+ [Figure 150. Not displayed.] +
+
+ Fig. 150. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Regular Polygon Reference, + Up: Top + +
+ +

29 Rectangle Reference

+ +

Class Rectangle is defined in rectangs.web, and + is derived from Polygon, using public derivation. + +

As noted above in Polygon Reference; Affine Transformations, class Rectangle, + like class Reg_Polygon, + currently inherits its transformation functions and + operator*=(const Transform&) from Polygon. Consequently, + the data members of a Rectangle, except for center, are + not recalculated when it's transformed. I plan to change this soon! It + will also be necessary to add the function + Rectangle::is_rectangular(), in order to test whether a + Rectangle is still rectangular. + +

+ + + +

29.1 Data Members

+ +
+ — Private variables: real axis_h
+ — : real axis_v
+

The lengths of the horizontal and vertical axes, respectively, of the + Rectangle. Actually, + they are merely the horizontal and vertical axes by convention, since + there are no restrictions on the orientation of an Rectangle. + +

Please note that axis_h and axis_v are currently not + recalculated, when a Rectangle is transformed. I plan to do + something about this soon. +

+ +
+ — Private variable: bool on_free_store
+

true, if the Rectangle was dynamically allocated on the + free store, otherwise false. Dynamic allocation of + Rectangles should only be + performed by create_new<Rectangle>(), which sets + on_free_store to true. +

+ +
+ +


+ Next: , + Previous: Rectangle Data Members, + Up: Rectangle Reference + +
+ +

29.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Rectangle (void)
+

Creates an empty Rectangle. +

+ +
+ — Constructor: void Rectangle (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Creates a Rectangle in the x-z plane, centered at the origin, + with width == aaxis_h + (in the + or - x + direction), + and height == aaxis_v + (in the + + or - z + direction). + If one or more of the arguments + angle_x, angle_y, or angle_z are used, it is rotated + by those amounts around the appropriate axes. + Finally, the Rectangle is shifted such that + its center lies at ccenter. + +

          Point C(-1, -1, 1);
+           Rectangle r(C, 3, 4, 30, 30, 30);
+ 
+

+
+ [Figure 151. Not displayed.] +
+
+ Fig. 151. +
+

+ +
+ +
+ — Setting function: void set (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Corresponds to the constructor described above. +

+ +
+ — Constructor: void Rectangle (const Point& p0, const Point& p1, const Point& p2, const Point& p3)
+

Creates Rectangle using four Point + arguments. The order of the arguments must correspond with a path + around the Rectangle. + +

This function does not currently check that the arguments yield a valid + Rectangle, therefore all code using it must ensure that they do. + +

+ +
+ — Setting function: void set (const Point& pt0, const Point& pt1, const Point& pt2, const Point& pt3)
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Rectangle* create_new<Rectangle> (const Rectangle* r)
+ — : Rectangle* create_new<Rectangle> (const Rectangle& r)
+

Pseudo-constructors for dynamic allocation of Rectangles. + They create a Rectangle on the free store and allocate memory for it using + new(Rectangle). They return a pointer to the new Rectangle. + +

If r is a non-zero pointer or a reference, + the new Rectangle will be a copy of + r. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Rectangle>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + +

29.3 Operators

+ +
+ — Assignment Operator: const Rectangle& operator= (const Rectangle& r)
+

Makes the Rectangle a copy of r. +

+ +
+ +


+ Next: , + Previous: Rectangle Operators, + Up: Rectangle Reference + +
+ +

29.4 Returning Points

+ +
+ — Function: Point corner (unsigned short c)
+

Returns the corner Point indicated by the argument c, which must be + between 0 and 3. + +

+ +
+ — const function: Point mid_point (unsigned short m)
+

Returns the mid-point of one of the sides. The argument c must be + between 0 and 3. + +

+ + + +

29.5 Querying

+ +
+ — const functions: real get_axis_h (void)
+ — : real get_axis_v (void)
+

These functions return axis_h and axis_v, respectively. + +

Please note, that axis_h and axis_v are currently not + recalculated, when a Rectangle is transformed. I plan to do + something about this soon. +

+ +
+ — const function: bool is_rectangular (void)
+

Returns true, if the Rectangle is rectangular, otherwise + false. Transformations, such as shearing, can cause + Rectangles to become non-rectangular. + +

+ +
+ +


+ Previous: Querying Rectangles, + Up: Rectangle Reference + +
+ +

29.6 Ellipses

+ +
+ — const function: Ellipse out_ellipse (void)
+

Returns the smallest Ellipse that surrounds the Rectangle. + +

          Point P(-1, -1, 3);
+           Rectangle r(P, 3, 4, 60, 30, 15);
+           Ellipse e = r.out_ellipse();
+           e.filldraw(black, gray);
+           r.unfilldraw(black);
+ 
+

+
+ [Figure 152. Not displayed.] +
+
+ Fig. 152. +
+

+ +
+ +
+ — const function: Ellipse in_ellipse (void)
+

Returns the Ellipse enclosed by the Rectangle. + +

          Point P(-1, -1, 3);
+           Rectangle r(P, 3, 4, 60, 30, 15);
+           Ellipse e = r.in_ellipse();
+           r.filldraw(black, gray);
+           e.unfilldraw(black);
+ 
+

+
+ [Figure 153. Not displayed.] +
+
+ Fig. 153. +
+

+ +
+ +
+ — const function: Ellipse draw_out_ellipse ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the smallest Ellipse that surrounds the Rectangle. + The arguments are like those of Path::draw() + (see Path Reference; Drawing and Filling). + The return value is the surrounding Ellipse. +

+ +
+ — const function: Ellipse draw_in_ellipse ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Ellipse enclosed by the Rectangle. + The arguments are like those of Path::draw() + (see Path Reference; Drawing and Filling). + The return value is the enclosed Ellipse. +

+ + + + + + +
+ +


+ Next: , + Previous: Rectangle Reference, + Up: Top + +
+ +

30 Regular Closed Plane Curve Reference

+ +

Class Reg_Cl_Plane_Curve is defined in curves.web. + It is derived from Path using public derivation. + +

Reg_Cl_Plane_Curve is not called + “Regular_Closed_Plane_Curve” because the longer name + causes too many “Overfull boxes”44 + in the CWEAVE output of the program code. + See CWEB Documentation. + +

Reg_Cl_Plane_Curve is meant to be used as a base class; no + objects should be declared of type Reg_Cl_Plane_Curve. + Currently, class Ellipses is derived from + Reg_Cl_Plane_Curve and class Circle is derived from + Ellipse. + +

At present, I have no fixed definition of what constitutes + “regularity” as far as Reg_Cl_Plane_Curves are concerned. + Ellipses and circles are “regular” in the sense that they have axes of + symmetry. There must be an equation for a Reg_Cl_Plane_Curve, + such as + x^2 + y^2 = r^2 + for a circle. + A derived class should have a solve() function that uses this + equation. Reg_Cl_Plane_Curve::intersection_points() in turn uses + solve() to find the intersection points of a line with the + Reg_Cl_Plane_Curve. This way, the derived classes don't need + their own functions for finding their intersections with a line. + However, such functions can be added, if desired. + +

It is assumed that classes derived from Reg_Cl_Plane_Curve are + fillable, which implies that they must be closed Paths. + Reg_Cl_Plane_Curves inherit their drawing and filling functions + from Path. + +

The constructors and setting functions of classes derived from + Reg_Cl_Plane_Curve must ensure that the resulting geometric + figures are planar, convex, and that the number of Points they contain is + a multiple of 4. The latter assumption is of importance in + intersection_points(), segment(), half(), and + quarter(). + See Regular Closed Plane Curve Reference; Intersections, and + Regular Closed Plane Curve Reference; Segments. + +

+ + + +

30.1 Data Members

+ +
+ — Protected variable: Point center
+

The center of the Reg_Cl_Plane_Curve, if it has one. +

+ +
+ — Protected variable: unsigned short number_of_points
+

The number of Points on points in a + Reg_Cl_Plane_Curve. +

+ + + +

30.2 Querying

+ +
+ — const inline virtual functions: bool is_quadratic (void)
+ — : bool is_cubic (void)
+ — : bool is_quartic (void)
+

These functions all return false. They are intended to be + overloaded by member functions of derived classes. +

+ +
+ — const inline virtual function: real_triple get_coefficients (real Slope, real v_intercept)
+

Returns a real_triple with all three values == + INVALID_REAL. Intended to be overloaded by member functions of + derived classes. +

+ +
+ — const inline virtual function: pair<real, real> solve (char axis_unknown, real known)
+

Returns a pair<real, real> with first = + second = INVALID_REAL. + Intended to be overloaded by member functions of + derived classes. +

+ +
+ — const virtual function: signed short location (Point ref_pt, Point p)
+

Returns a signed short indicating the location of p with + respect to the Reg_Cl_Plane_Curve, which must be planar. + The Reg_Cl_Plane_Curve constructors should ensure that + Reg_Cl_Plane_Curves are, but there is no guarantee that they will + not have been manipulated into a non-planar state, by shearing, for + example. + +

The argument ref_pt is used within the function for + shifting a copy of the Reg_Cl_Plane_Curve to a convenient + position. It need not be the |center| of the Reg_Cl_Plane_Curve, + however, classes derived from Reg_Cl_Plane_Curve will probably + have their own versions of location(), which will pass center + as the ref_pt argument to this function. + Reg_Cl_Plane_Curves need not have a meaningful |center|. + +

location() returns the following values: +

+
-1
p and *this are coplanar, and p lies + outside the perimeter of *this. + +
0
p and *this are coplanar, and p lies on the perimeter + of *this. + +
1
p and *this are coplanar, and p lies inside + the perimeter of *this. + +
-2
p and *this are not coplanar. + +
-3
Something has gone terribly wrong. + +
-4
The normal to *this has 0 magnitude, i.e., the + |Points| on *this are colinear. + +
-5
An error occurred in putting *this in one of + the major planes. +
+

+ +
+ — Virtual function: Point angle_point (real angle)
+

Returns INVALID_POINT. Intended to be overloaded by member functions of + derived classes. +

+ + + +

30.3 Intersections

+ +
+ — const function: bool_point_pair intersection_points (Point ref_pt, Point p0, Point p1)
+ — const function: bool_point_pair intersection_points (const Point& ref_pt, const Path& p)
+

The version of this function taking Point arguments finds the + intersection points, if any, of the + Reg_Cl_Plane_Curve and the line + p + that passes through the Points + p_0 + and + p_1. + In the other version, the Path argument must be a linear + Path, and its first and last Points are passed to the + first version of this function as p0 and p1, respectively. + +

Let + C + be the Reg_Cl_Plane_Curve. + C and p can intersect at at most two intersection points + i_1 and i_2. + Let bpp be the return + value of this function. + The intersection points need not be on the line segment + between pt0 and pt1. + bpp.first.pt will be set + to the first intersection point if it exists, or INVALID_POINT if + it doesn't. If the first intersection point exists and is on the line + segment between pt0 and pt1 + +

In [next figure] + , the line AB + is normal to the + Ellipse e, or, to put it another way, AB + is + perpendicular to the plane of e. The intersection point i_0 lies + within the perimeter of e. + +

The line DE + is skew to the plane of e, and + intersects e at i_1, on the perimeter of e. + +

          Point p0(2, 2, 3);
+           Ellipse e(p0, 3, 4, 30, -60, -5.2);
+           Point p1 = p0.mediate(e.get_point(11), .5);
+           Point A = e.get_normal();
+           A *= 2.5;
+           A.shift(p1);
+           Point B = A.mediate(p1, 2);
+           bool_point_pair bpp = e.intersection_points(A, B);
+           Point C(0, 2, 0);
+           Point D(0, -3.5, 0);
+           C *= D.rotate(2, 0, -5);
+           C *= D.shift(e.get_point(4));
+           bpp = e.intersection_points(C, D);
+ 
+

+
+ [Figure 154. Not displayed.] +
+
+ Fig. 154. +
+

+ +

In [next figure] + , q and e are coplanar. In this case, + only the intersections of q with the perimeter of e are returned by + intersection_points(). + +

          A = p0.mediate(e.get_point(3), 1.5);
+           B = p0.mediate(e.get_point(11), 1.5);
+           Path q(A, B);
+           bpp = e.intersection_points(q);
+ 
+

+
+ [Figure 155. Not displayed.] +
+
+ Fig. 155. +
+

+ +
+ + + +

30.4 Segments

+ +
+ — const function: Path segment (unsigned int factor, [real angle = 0, [bool closed = true]])
+

Returns a Path representing a segment of the Reg_Cl_Plane_Curve. + factor must be + >1 and <= number_of_points. If it is not, an error message is + issued and an empty Path is returned. + +

If angle is non-zero, the segment Path is rotated by + angle about a line from center in the direction of the + normal to the plane of the Reg_Cl_Plane_Curve. + Please note, that a Reg_Cl_Plane_Curve must have a meaningful + center, in order for rotation to work. + If the absolute value of + angle >360, a warning is issued, and + fmod(angle, 360) is used. + +

If closed is true, the Path will be a cycle, with + the ends of the curved segment joined using the connector ‘--’. + The curved segment is joined to the line using ‘&’ on each side. + +

          Circle c(origin, 4, 30, 30, 30);
+           Path p = c.segment(3, 130);
+           p.show("p:");
+           -| p:
+           points.size() == 8
+           connectors.size() == 8(-0.00662541, -0.888379, -1.79185) ..
+           (0.741088, -0.673392, -1.73128) ..
+           (1.37598, -0.355887, -1.40714) ..
+           (1.80139, 0.0157987, -0.868767) ..
+           (1.95255, 0.385079, -0.198137) .. (1.80646, 0.695735, 0.502658) &
+           (1.80646, 0.695735, 0.502658) --
+           (-0.00662541, -0.888379, -1.79185) & cycle;
+ 
+

+
+ [Figure 156. Not displayed.] +
+
+ Fig. 156. +
+

+ +
+ +
+ — const inline function: Path half ([real angle = 0, [bool closed = true]])
+

Returns a Path using half of the Points on the + Reg_Cl_Plane_Curve. + The effect of the arguments angle and closed is similar to + that in segment(), above. + +

          Ellipse e(origin, 3, 5, 20, 15, 12.5);
+           Path p = e.half(0, false);
+ 
+

+
+ [Figure 157. Not displayed.] +
+
+ Fig. 157. +
+

+ +
+ +
+ — const inline function: Path quarter ([real angle = 0, [bool closed = true]])
+

Returns a Path using a quarter of the Points on the + Reg_Cl_Plane_Curve. + The effect of the arguments angle and closed is similar to + that in segment(), above. + +

          Ellipse e(origin, 3, 5, 60, 5, 2.5);
+           Path p = e.quarter(180, false);
+ 
+

+
+ [Figure 158. Not displayed.] +
+
+ Fig. 158. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Regular Closed Plane Curve Reference, + Up: Top + +
+ +

31 Ellipse Reference

+ +

Class Ellipse is defined in ellipses.web. + It is derived from Reg_Cl_Plane_Curve using public derivation. + +

+ + + +

31.1 Data Members

+ +
+ — Protected variables: Point focus0
+ — : Point focus1
+

The foci of the Ellipse. They are located on the major axis of + the Ellipse at a distance of linear_eccentricity from + center, on opposite sides of the minor axis. +

+ +
+ — Protected variable: real linear_eccentricity
+

The linear eccentricity of the Ellipse e, such that + e = \sqrta^2 - b^2, + where a and b are half the lengths of the major + and minor axes, respectively. Let h stand for axis_h and v + for axis_v. If h>v, then a = h/2 and b = v/2. If v>h, + then a =v/2 and b = h/2. If h = v, then the Ellipse is + circular (but not an object of type Circle!), and a = b = v/2 = h/2. + +

The linear eccentricity is the distance along the major axis of the + Ellipse from center to focus0 and focus1. + +

+ +
+ — Protected variable: real numerical_eccentricity
+

The numerical eccentricity \epsilon of the Ellipse, + such + that \epsilon = e/a < 1, where e is the linear eccentricity of the + Ellipse, and a is half the length of the major axis of the + Ellipse. +

+ +
+ — Protected variables: real axis_h
+ — : real axis_v
+

The horizontal and vertical axes, respectively, of the Ellipse. + +

Actually, they are only or vertical + horizontal by convention, since there are no restrictions on the + orientation of an Ellipse. +

+ +
+ — Protected static variable: unsigned short DEFAULT_NUMBER_OF_POINTS
+

The number of Points on an Ellipse, unless another number + is specified when an Ellipse constructor is invoked. +

+ + + +

31.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Ellipse (void)
+

Creates an empty Ellipse. +

+ +
+ — Constructor: void Ellipse (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0, [const unsigned short nnumber_of_points = DEFAULT_NUMBER_OF_POINTS]]]])
+

Creates an Ellipse in the x-z plane, centered at the origin, with + its horizontal axis + == aaxis_h and its vertical axis == aaxis_v. If + any of the arguments angle_x, angle_y, or angle_z is + non-zero, the Ellipse is rotated about the x, y, and z-axis in + that order, by the amounts indicated by the corresponding arguments. + Finally, the Ellipse is shifted such that its + center comes to lie at ccenter. + +

          Ellipse e(origin, 6, 4);
+           e.draw();
+ 
+

+
+ [Figure 159. Not displayed.] +
+
+ Fig. 159. +
+

+ +
          Point P(1, 1, 1);
+           Ellipse e(P, 6, 4, 15, 12, 11);
+           e.draw();
+ 
+

+
+ [Figure 160. Not displayed.] +
+
+ Fig. 160. +
+

+ +
+ +
+ — Setting function: void set (const Point& ccenter, const real aaxis_h, const real aaxis_v, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0, [const unsigned short nnumber_of_points = DEFAULT_NUMBER_OF_POINTS]]]])
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Ellipse* create_new<Ellipse> (const Ellipse* e)
+ — : Ellipse* create_new<Ellipse> (const Ellipse& e)
+

Pseudo-constructors for dynamic allocation of Ellipses. + They create a Ellipse on the free store and allocate memory for it using + new(Ellipse). They return a pointer to the new Ellipse. + +

If e is a non-zero pointer or a reference, + the new Ellipse will be a copy of + e. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Ellipse>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + +

31.3 Performing Transformations

+ +
+ — Virtual function: Transform do_transform (const Transform& t, [bool check = false])
+

Performs a transformation on an Ellipse. The Points on + the Ellipse are multiplied by t. + Then, if check is true, + is_elliptical() is called on the Ellipse. + If the transformation has caused it to + become non-elliptical, axis_h and axis_v are set to + INVALID_REAL, and a warning is issued to stderr. + center, focus0, and focus1 are not set to + INVALID_POINT. They may may no longer really be + the center and foci of the (non-elliptical) Ellipse, but they may + have some use for the programmer and/or user. + +

If check is true, and the transformation does not cause + *this to become non-elliptical, + axis_h, axis_v, linear_eccentricity, + numerical_eccentricity, focus0, and + focus1 are recalculated. + +

+ + + +

31.4 Operators

+ +
+ — Assignment operator: Ellipse& operator= (const Ellipse& e)
+

Makes the Ellipse a copy of e. +

+ +
+ — Virtual function: Transform operator*= (const Transform& t)
+

Calls do_transform(t, true), and returns the latter's return + value. + See Ellipse Reference; Performing Transformations. +

+ + + +

31.5 Labeling

+ +
+ — const function: void label ([const string pos = "top", [const bool dot = false, [Picture& picture = current_picture]]])
+

Labels the Points on points, using lowercase letters. + pos is used to position all of the labels. It is currently not + possible to have different positions for the labels. + +

          Ellipse e(origin, 6, 4);
+           e.draw();
+           e.label();
+ 
+

+
+ [Figure 161. Not displayed.] +
+
+ Fig. 161. +
+

+ +
+ +
+ — Inline const function: void dotlabel ([string pos = "top", [Picture& picture = current_picture]])
+

Like label(), except that the Points are dotted. + +

          Ellipse e(origin, 6, 4);
+           e.draw();
+           e.dotlabel();
+ 
+

+
+ [Figure 162. Not displayed.] +
+
+ Fig. 162. +
+

+ +
+ +
+ +


+ Next: , + Previous: Labeling Ellipses, + Up: Ellipse Reference + +
+ +

31.6 Affine Transformations

+ +
+ — Virtual function: Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — Virtual function: Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+ — Virtual function: Transform rotate (const Path& p, [const real angle = 180])
+ — Virtual function: Transform scale (real x, [real y = 1, [real z = 1]])
+ — Virtual function: Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+ — Virtual function: Transform shift (real x, [real y = 0, [real z = 0]])
+ — Virtual function: Transform shift (const Point& p)
+ — Virtual function: void shift_times (real x, [real y = 1, [real z = 1]])
+ — Virtual function: void shift_times (const Point& p)
+

These create a Transform t locally, and call + do_transform(t). + See Ellipse Reference; Performing Transformations. + +

Rotating and shifting an Ellipse neither change the size of an + Ellipse, nor cause it to become + non-elliptical. However, scaling and shearing can have these effects. + For this reason, in scale() and shear(), + do_transform() is called with true as its check + argument, while it is false in rotate(), shift(), + and shift_times(). + +

If scaling or shearing is performed on an Ellipse, and it is + still elliptical after the transformation, focus0, focus1, + axis_h, axis_v, linear_eccentricity, and + numerical_eccentricity are all + recalculated. If the Ellipse is non-elliptical after the + transformation, axis_h, axis_v, + linear_eccentricity, and numerical_eccentricity + are all set to INVALID_REAL. center, focus0, and + focus1 are not set to INVALID_POINT. Although they are no + longer the center and foci of an elliptical Ellipse, they may + still have some use for the user or programmer. +

+ + + +

31.7 Querying

+ +
+ — const function: bool is_elliptical (void)
+

Returns true if the Ellipse is elliptical, otherwise + false. + +

Certain transformations, such as shearing and scaling, can cause + Ellipses to become non-elliptical. +

+ +
+ — Inline const function: bool is_quadratic (void)
+

Returns true, because the equation + for an ellipse in the x-y plane with its center at the + origin is the quadratic equation + x^2/a^2 + y^2/b^2 = 1 + where a is half the horizontal axis + and b is half the vertical axis. + +

          Ellipse e(origin, 5, 2, 90);
+           e.draw();
+           Point P(e.angle_point(-35));
+           cout << ((P.get_x() * P.get_x())
+                    / (e.get_axis_h()/2 * e.get_axis_h()/2))
+                   + ((P.get_y() * P.get_y())
+                      / (e.get_axis_v()/2 * e.get_axis_v()/2));
+           -| 1
+ 
+

+
+ [Figure 163. Not displayed.] +
+
+ Fig. 163. +
+

+ +
+ +
+ — const virtual functions: bool is_cubic (void)
+ — : bool is_quartic (void)
+

These functions both return false, because the equation of an + ellipse is neither a cubic nor a quartic function. +

+ +
+ +


+ Next: , + Previous: Querying Ellipses, + Up: Ellipse Reference + +
+ +

31.8 Returning Elements and Information

+ +
+ — Virtual function: Point& get_center (void)
+ — const virtual function: Point get_center (void)
+

These functions return center. + +

+ +
+ — Function: const Point& get_focus (const unsigned short s)
+ — const function: Point get_focus (const unsigned short s)
+

These functions return focus0 or focus1, depending on the + value of s, which must be 0 or 1. If s is not 0 or 1, + get_focus() returns INVALID_POINT. + +

+ +
+ — const function: real get_linear_eccentricity (void)
+

Returns linear_eccentricity. + +

+ +
+ — const function: real get_numerical_eccentricity (void)
+

Returns numerical_eccentricity. + +

+ +
+ — Function: real get_axis_v (void)
+ — const function: real get_axis_v (void)
+

Calculates and returns the value of axis_h. + +

get_axis_v() first checks if the Ellipse is still + elliptical, using is_elliptical() + (see Ellipse Reference; Querying). + Operations such as scale() and shear() can + cause an Ellipse to become non-elliptical. + If this is the case, this function returns INVALID_REAL. + +

If the Ellipse is still elliptical, axis_v is + recalculated and returned. In the non-const version, + axis_v is also reset to the new value. +

+ +
+ — Function: real get_axis_h (void)
+ — const function: real get_axis_h (void)
+

Calculates and returns the value of axis_h. + +

get_axis_h() first checks if the Ellipse is still + elliptical, using is_elliptical() + (see Ellipse Reference; Querying). + Operations such as scale() and shear() can + cause an Ellipse to become non-elliptical. + If this is the case, this function returns INVALID_REAL. + +

If the Ellipse is still elliptical, axis_h is + recalculated and returned. In the non-const version, + axis_h is also reset to the new value. +

+ +
+ — const virtual function: signed short location (Point p)
+

Returns a value l indicating the location of the Point argument + p with respect to the Ellipse. + +

Let e stand for the Ellipse. + The return values are as follows: + +

+
0
p lies on the perimeter of e. + +
1
p lies in the plane of e, within its perimeter. + +
-1
p lies in the plane of e, outside its perimeter. + +
-2
p and e do not lie in the same plane. + +
-3
e is not elliptical, possibly due to having been transformed. +
+ +
          Ellipse e(origin, 3, 5, 45, 15, 3);
+           e.shift(2, 1, 1);
+           Point A = e.get_point(7);
+           cout << e.location(A);
+           -| 0
+           Point B = center.mediate(e.get_point(2));
+           cout << e.location(B);
+           -| 1
+           Point C = center.mediate(e.get_point(2), 1.5);
+           cout << e.location(C);
+           -| -1
+           Point D = A;
+           D.shift(-2, 0, 4);
+           e.location(D);
+           -| WARNING! In Ellipse::location():
+              Point doesn't lie in plane of Ellipse.
+              Returning -2.
+           e.scale(1.5, 0, 1.5);
+           e.location(A);
+           -| WARNING! In Ellipse::do_transform(const Transform&):
+              This transformation has made *this non-elliptical!
+           
+              ERROR! In Ellipse::location():
+              Ellipse is non-elliptical. Returning -3.
+ 
+

+
+ [Figure 164. Not displayed.] +
+
+ Fig. 164. +
+

+ +
+ +
+ — const function: Point angle_point (real angle)
+

Returns a point on the Ellipse given an angle. + A Point p is set to the zeroth Point on the Ellipse + and rotated about the line from the center of the Ellipse in the + direction of the normal to the plane of the Ellipse. + Then, the intersection of the ray from the center through + p and the perimeter of the Ellipse is returned. + +

          Ellipse e(origin, 6, 4);
+           Point P = e.angle_point(135);
+           current_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 165. Not displayed.] +
+
+ Fig. 165. +
+

+ +

[next figure] + demonstrates, that the rotation is unfortunately not always + in the direction one would prefer. I don't have a solution to this + problem yet. + +

          Ellipse e(origin, 6, 4, 90);
+           Point P = e.angle_point(135);
+           Point Q = e.angle_point(-135);
+ 
+

+
+ [Figure 166. Not displayed.] +
+
+ Fig. 166. +
+

+ +
+ + + +

31.9 Intersections

+ +
+ — const virtual function: bool_point_pair intersection_points (const Point& p0, const Point& p1)
+ — const virtual function: bool_point_pair intersection_points (const Path& p)
+

These functions return the intersection points of a line with an + Ellipse. In the first version, the line is specified by the two + Point arguments. + In the second version, p.is_linear() must return true, + otherwise, intersection_points() issues an error message and + returns INVALID_BOOL_POINT_PAIR. + +

If the line and the Ellipse are coplanar, there can be at most two + intersection points. Otherwise, there can be at most one. + +

          Ellipse e(origin, 5, 7, 30, 30, 30);
+           e.shift(3, 0, 3);
+           Point p0 = e.get_center().mediate(e.get_point(3));
+           Point normal = e.get_normal();
+           Point A = normal;
+           A *= 2.5;
+           A.shift(p0);
+           Point B = normal;
+           B *= -2.5;
+           B.shift(p0);
+           bool_point_pair bpp = e.intersection_points(A, B);
+           bpp.first.pt.dotlabel("$i_0$", "rt");
+           Point C = e.get_point(15).mediate(e.get_point(11), 1.25);
+           Point D = e.get_point(11).mediate(e.get_point(15), 1.5);
+           Path q = C.draw(D);
+           bpp = e.intersection_points(q);
+           bpp.first.pt.dotlabel("$i_1$", "llft");
+           bpp.second.pt.dotlabel("$i_2$", "ulft");
+ 
+

+
+ [Figure 167. Not displayed.] +
+
+ Fig. 167. +
+

+ +
+ +
+ — const virtual function: bool_point_quadruple intersection_points (Ellipse e, [const real step = 3, [bool verbose = false]])
+

Returns the intersection points of two Ellipses. Two Ellipses + can intersect at at most four points. + +

Let bpq be the bool_point_quadruple returned by + intersection_points(). If one or more intersection points are + found, the corresponding Points are stored in the + pt elements of the four bool_points belonging to + bpq, otherwise INVALID_POINT. If a Point is found, the + b element of the bool_point will be true, otherwise + false. + +

The step argument is used when the Ellipses are coplanar + and either have different centers or the vertical axis of one Ellipse is + colinear with the horizontal axis of the other (and vice versa). In + these cases, the intersection points must be found by an iterative + routine. A Point p travels around the perimeter of *this, + and its location with respect to e is tested. step is the + angle of rotation used for stepping around the perimeter of + *this. The default value, 3, should be adequate, unless the + Ellipses differ greatly in size. + +

If the verbose argument is true, + intersection_points() will print information about the + intersection points to standard output. + +

In [next figure] + , the Ellipses e and f both lie in the x-z + plane, are centered at the origin, and intersect at four points. + +

          Ellipse e(origin, 5, 2);
+           Ellipse f(origin, 2, 5);
+           bool_point_quadruple bpq = e.intersection_points(f);
+           bpq.first.pt.dotlabel(1, "llft");
+           bpq.second.pt.dotlabel(2, "urt");
+           bpq.third.pt.dotlabel(3, "ulft");
+           bpq.fourth.pt.dotlabel(4, "lrt");
+ 
+

+
+ [Figure 168. Not displayed.] +
+
+ Fig. 168. +
+

+ +

In [next figure] + , e and f are coplanar, but don't lie in a major plane, + have different centers, and only intersect at two points. + +

          Ellipse e(origin, 4, 2);
+           Ellipse f(origin, 2, 5);
+           f.shift(0, 0, 1);
+           f.rotate(0, 15);
+           f.shift(1, 0, 1);
+           e *= f.shift(-.25, 1, -1);
+           e *= f.rotate(10, -12.5, 3);
+           bool_point_quadruple bpq = e.intersection_points(f, true);
+           bpq.first.pt.dotlabel(1, "urt");
+           bpq.second.pt.dotlabel(2, "ulft");
+ 
+

+
+ [Figure 169. Not displayed.] +
+
+ Fig. 169. +
+

+ +

If the planes of the Ellipses are parallel, there are, of course, + no intersection points. If the Ellipses are non-coplanar, and + their planes are not parallel to each other, + intersection_points() first finds the line of intersection of the + planes of the Ellipses. It then returns the Points of + intersection of this line with the Ellipses, if they exist. If + the verbose argument is true, information about the + Points is printed to standard output. + +

In [next figure] + , the two Ellipses lie in skew planes. The plane + of f intersects with e at the Points labelled “1” and “2”, + while the plane of e intersects with f at the Points labelled + “3” and “4”. + +

          Ellipse e(origin, 5, 3);
+           Ellipse f(origin, 2, 5);
+           f.rotate(0, 0, 30);
+           f.rotate(0, 10);
+           f.rotate(45);
+           f.shift(1.5, 1);
+           bool_point_quadruple bpq = e.intersection_points(f, true);
+           bpq.first.pt.dotlabel(1);
+           bpq.second.pt.dotlabel(2);
+           bpq.third.pt.dotlabel(3, "rt");
+           bpq.fourth.pt.dotlabel(4, "urt");
+           -| First point lies on the perimeter of *this.
+              First point lies inside e.
+              Second point lies on the perimeter of *this.
+              Second point lies outside e.
+              Third point lies outside *this.
+              Third point lies on the perimeter of e.
+              Fourth point lies inside *this.
+              Fourth point lies on the perimeter of e.
+ 
+

+
+ [Figure 170. Not displayed.] +
+
+ Fig. 170. +
+

+ +

In [next figure] + , the two Ellipses lie in skew planes. The plane of + f intersects with e at the Points labelled “1” and “2”. + The plane of e does not intersect with f, so bpq.third.pt + and bpq.fourth.pt are INVALID_POINT. + +

          Ellipse e(origin, 5, 3);
+           Ellipse f(origin, 2, 5, 45);
+           f.shift(0, 2.5, 3);
+           bool_point_quadruple bpq = e.intersection_points(f, true);
+           bpq.first.pt.dotlabel(1);
+           bpq.second.pt.dotlabel(2);
+           -| First point lies on the perimeter of *this.
+              First point lies outside e.
+              Second point lies on the perimeter of *this.
+              Second point lies outside e.
+              Third intersection point is INVALID_POINT.
+              Fourth intersection point is INVALID_POINT.
+ 
+

+
+ [Figure 171. Not displayed.] +
+
+ Fig. 171. +
+

+ +
+ +
+ +


+ Next: , + Previous: Ellipse Intersections, + Up: Ellipse Reference + +
+ +

31.10 Solving

+ +
+ — const function: real_pair solve (char axis_unknown, real known)
+

Returns two possible values for either the horizontal or vertical + coordinate. This function assumes that the Ellipse lies in a major + plane with center at the origin. Code that calls it must ensure + that these conditions are fulfilled. + + +

solve() is called in + Reg_Cl_Plane_Curve::intersection_points(Point, Point, Point) and + Reg_Cl_Plane_Curve::location(), and + resolves to this function, when these functions are called on an + Ellipse. However, Ellipse::location() overloads + Reg_Cl_Plane_Curve::location(), so the latter won't normally be + called on an Ellipse. + See Regular Closed Plane Curve Reference; Intersections, and + Regular Closed Plane Curve Reference; Querying. + +

+ +
+ — const function: real_triple get_coefficients (real Slope, real v_intercept)
+
+

Let x and y stand for the x and y-coordinates of a point on an + ellipse in the x-y plane, a for half of the horizontal axis + (axis_h / 2), + and b for half of the vertical axis + (axis_v / 2). + +

Further, let y = mx + i be the equation of a line in + the x-y plane, where m is the slope and i the + y-intercept. + +

This function returns the coefficients of the quadratic equation + that results from replacing y with mx + i + in the equation for the ellipse + +

          x^2/a^2 + y^2/b^2 = 1
+
+

namely +

          x^2/a^2 + (mx + i)^2/b^2 - 1 = 0
+           == (b^2x + a^2m^2)x^2 + 2a^2imx + (a^2i^2 - a^2b^2) = 0.
+ 
+

The coefficients are returned in the real_triple in the order + one would expect: r.first is the coefficient of x^2, r.second of + x and r.third of the constant term + (x^0 == 1). + +

get_coefficients() is called in + Reg_Cl_Plane_Curve::intersection_points(Point, Point, Point), and + resolves to this function, when the latter is called on an + Ellipse. + See Regular Closed Plane Curve Reference; Intersections. +

+ +
+ +


+ Previous: Solving Ellipses, + Up: Ellipse Reference + +
+ +

31.11 Rectangles

+ +
+ — const function: Rectangle out_rectangle (void)
+

Returns the Rectangle that surrounds the Ellipse. + +

          Ellipse e(origin, 3, 4, 45, 30, 17);
+           e.shift(1, -1, 2);
+           Rectangle r = e.out_rectangle();
+           r.filldraw(black, gray);
+           e.unfilldraw(black);
+ 
+

+
+ [Figure 172. Not displayed.] +
+
+ Fig. 172. +
+

+ +
+ +
+ — const function: Rectangle in_rectangle (void)
+

Returns the Rectangle enclosed within the Ellipse. + +

          Rectangle r = e.in_rectangle();
+           e.filldraw(black, gray);
+           r.unfilldraw(black);
+ 
+

+
+ [Figure 173. Not displayed.] +
+
+ Fig. 173. +
+

+ +
+ +
+ — const function: Rectangle draw_out_rectangle ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Rectangle that surrounds the Ellipse. The arguments + are like those of Path::draw(). + The return value is the surrounding Rectangle. + See Path Reference; Drawing and Filling. + +

          Ellipse e(origin, 2.5, 5, 10, 12, 15.5);
+           e.shift(-1, 1, 1);
+           e.draw_out_rectangle(black, "evenly", "pencircle scaled .3mm");
+ 
+

+
+ [Figure 174. Not displayed.] +
+
+ Fig. 174. +
+

+ +
+ +
+ — const function: Rectangle draw_in_rectangle ([const Color& ddraw_color = *Colors::default_color, [string ddashed = "", [string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Rectangle enclosed within the Ellipse. The arguments + are like those of Path::draw(). + The return value is the enclosed Rectangle. + See Path Reference; Drawing and Filling. + +

          Ellipse e(origin, 3.5, 6, 10, 12, 15.5);
+           e.shift(-1, 1, 1);
+           e.draw_in_rectangle(black, "evenly", "pencircle scaled .3mm");
+ 
+

+
+ [Figure 175. Not displayed.] +
+
+ Fig. 175. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Ellipse Reference, + Up: Top + +
+ +

32 Circle Reference

+ +

Class Circle is defined in circles.web. + It is derived from Ellipse, using public derivation. + +

Since Circle is just a special kind of Ellipse, there is + often no need to define special functions for Circles. + +

Currently, Circle inherits the transformation functions and + operator*=(const Transform&) from Ellipse. Consequently, + the data member radius, described below, + is not recalculated, when transformations + are performed on a Circle. I plan to change this soon! + +

+ + + +

32.1 Data Members

+ +
+ — Private variable: real radius
+

The radius of the Circle. +

+ +
+ +


+ Next: , + Previous: Circle Data Members, + Up: Circle Reference + +
+ +

32.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Circle (void)
+

Creates an empty Circle. +

+ +
+ — Constructor: void Circle (const Point& ccenter, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0, [const unsigned short nnumber_of_points = DEFAULT_NUMBER_OF_POINTS]]]])
+

Creates a Circle with radius == + ddiameter/2 in the x-z plane and centered at the origin + with nnumber_of_points Points. If any of the arguments + angle_x, angle_y, or angle_z is + != 0, + the Circle is rotated around the major axes by the angles + indicated by the arguments. Finally, the + Circle is shifted such that center comes to lie at + ccenter. +

+ +
+ — Setting function: void set (const Point& ccenter, const real ddiameter, [const real angle_x = 0, [const real angle_y = 0, [const real angle_z = 0]]])
+

Corresponds to the constructor above. +

+ +
+ — Template specializations: Circle* create_new<Circle> (const Circle* c)
+ — : Circle* create_new<Circle> (const Circle& c)
+

Pseudo-constructors for dynamic allocation of Circles. + They create a Circle on the free store and allocate memory for it using + new(Circle). They return a pointer to the new Circle. + +

If c is a non-zero pointer or a reference, + the new Circle will be a copy of + c. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Circle>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + +

32.3 Operators

+ +
+ — Assignment operator: Circle& operator= (const Circle& c)
+

Makes the Circle a copy of c. +

+ +
+ — Assignment operator: Circle& operator= (const Ellipse& e)
+

Makes the Circle a copy of e, if e is circular. + radius is set to e.axis_v / 2 and + *this is returned. + +

If e is not circular, this function issues an error message and returns *this. +

+ +
+ +


+ Next: , + Previous: Circle Operators, + Up: Circle Reference + +
+ +

32.4 Querying

+ +
+ — const function: bool is_circular (void)
+

Returns true if the Circle is circular, otherwise + false. + +

Certain transformations, such as shearing and scaling, can cause + Circles to become non-circular. + +

          Circle c(origin, 3, 90);
+           cout << c.is_circular();
+           -| 1
+           
+           Circle d = c;
+           d.shift(2.5);
+           d.scale(2, 3);
+           cout << d.is_circular();
+           -| 0
+ 
+

+
+ [Figure 176. Not displayed.] +
+
+ Fig. 176. +
+

+ +
+ +
+ — Inline function: real get_radius (void)
+

Returns radius. +

+ +
+ — Inline function: real get_diameter (void)
+

Returns + 2 * radius. +

+ +
+ +


+ Previous: Querying Circles, + Up: Circle Reference + +
+ +

32.5 Intersections

+ +
+ — Virtual const function: bool_point_quadruple intersection_points (const Circle& c, [const bool verbose = false])
+

Returns the intersection points of two Circles. + +

If the Circles are coplanar, they can intersect at at most two + points. There is an easy algebraic solution for this, so in this case, + this function is faster than Ellipse::intersection_points(Ellipse, + bool), which uses an iterative procedure to find the points. + +

If the Circles are non-coplanar, the intersection points of each + Circle with the plane of the other Circle are returned, so + a maximum of four Points can be found. + + +

          Circle t(origin, 5, 90);
+           Circle c(origin, 3, 90);
+           c.shift(3);
+           c.rotate(0, 0, 45);
+           bool_point_quadruple bpq = t.intersection_points(c);
+           bpq.first.pt.dotlabel("$f$");
+           bpq.second.pt.dotlabel("$s$");
+ 
+

+
+ [Figure 177. Not displayed.] +
+
+ Fig. 177. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Circle Reference, + Up: Top + +
+ +

33 Pattern Reference

+ +

There is no currently no class “Pattern”. + If it turns out to be + useful for this purpose, I will define a Pattern class, and + perhaps additional derived classes. + +

+ +
+ +


+ Next: , + Previous: Pattern Reference, + Up: Pattern Reference + +
+ +

33.1 Plane Tesselations

+ +

3DLDF can be used to make perspective projections of plane tesselations + and other two-dimensional patterns. These can be used for + drawing tiled floors and other architectural items, among other things. + While patterns can be generated by using the basic facilities of C++ + and + 3DLDF without any specially defined functions, it can be useful to + define such functions. + +

3DLDF currently contains only one function for drawing patterns based on + a plane tessellation. I plan to add more soon. + +

+ — Function: unsigned int hex_pattern_1 ([real diameter_outer = 5, [real diameter_middle = 0, [real diameter_inner = 0, [unsigned short first_row = 5, [unsigned short double_rows = 10, [unsigned short row_shift = 2, [Color draw_color_outer = *Colors::default_color, [Color fill_color_outer = *Colors::background_color, [Color draw_color_middle = *Colors::default_color, [Color fill_color_middle = *Colors::background_color, [Color draw_color_inner = *Colors::default_color, [Color fill_color_inner = *Colors::background_color, [string pen_outer = "pencircle scaled .5mm", [string pen_middle = "pencircle scaled .3mm", [string pen_inner = "pencircle scaled .3mm", [Picture& picture = current_picture, [unsigned int max_hexagons = 1000]]]]]]]]]]]]]]]]])
+

Draws a pattern consisting of hexagons forming a tesselation of the x-z + plane, with additional hexagons within them. + +

The arguments: +

+
real diameter_outer
Default: 5. The diameter of the outer hexagon in each set of three + hexagons. The outer hexagons form a tessellation of the plane. + +
real diameter_middle
Default: 0. The diameter of the middle hexagon in a set of three + hexagons. + +
real diameter_inner
Default: 0. The diameter of the inner hexagon in a set of three + hexagons. + +
unsigned short first_row
Default: 5. The number of sets of hexagons in the first single row. + The second single row will have + first_row + 1 sets of hexagons. + +
unsigned short double_rows
Default: 10. The number of double rows drawn. + +
unsigned short row_shift
Default: 2. + For row_shift + != 0, + the number of sets of hexagons in each (single) row is + increased by 2 every row_shift rows. If row_shift == + 0, the number sets of hexagons remains constant. + The rows remain centered around the z-axis. + +
Color draw_color_outer
Default: *Colors::default_color. + The Color used for drawing the outer hexagons. + +
Color fill_color_outer
Default: *Colors::background_color. + The Color used for filling the outer hexagons. + +
Color draw_color_middle
Default: *Colors::default_color. + The Color used for drawing the middle hexagon. + +
Color fill_color_middle
Default: *Colors::background_color. + The Color used for filling the middle hexagons. + +
Color draw_color_inner
Default: *Colors::default_color. + The Color used for drawing the inner hexagons. + +
Color fill_color_inner
Default: *Colors::background_color. + The Color used for filling the inner hexagons. + +
string pen_outer
Default: "pencircle scaled .5mm". + The pen used for drawing the outer hexagons. + +
string pen_middle
Default: "pencircle scaled .3mm". + The pen used for drawing the middle hexagons. + +
string pen_inner
Default: "pencircle scaled .3mm". + The pen used for drawing the inner hexagons. + +
Picture& picture
Default: current_picture. + The Picture onto which the pattern is put. + +
unsigned int max_hexagons
Default: 1000. + The maximum number of hexagons that will be drawn. + +
+ +

Draws a pattern in the x-z plane consisting of hexagons. The outer + hexagons form a tessellation. The middle and inner hexagons fit + within the outer hexagons. The hexagons are drawn in double rows. + The tessellation can be repeated by copying a + double row and shifting the copy to lie directly behind the first double + row. If the Picture with the pattern is projected with the + Focus in front of the pattern, looking in the direction of the back + of the pattern, + the first row of hexagons will appear larger than the rows + behind it. Therefore, in order for the perspective projection of the + pattern to fill a rectangular area on the plane of projection, + it will generally be necessary to increase the number of sets of + hexagons in each double row. On the other hand, if the same number of + sets of hexagons were used in the front double row, as will be needed for the + back double row, many of them would probably be unprojectable. + +

The return value of this function is the number of hexagons drawn. + +

          default_focus.set(0, 10, -10, 0, 10, 25, 10);
+           hex_pattern_1(1, 0, 0, 5, 5);
+ 
+

+
+ [Figure 178. Not displayed.] +
+
+ Fig. 178. +
+

+ +
          default_focus.set(-5, 5, -10, 0, 10, 25, 10);
+           hex_pattern_1(2, 1.5, 1, 2, 5, 2, black, gray, black,
+                         light_gray, black);
+ 
+

+
+ [Figure 179. Not displayed.] +
+
+ Fig. 179. +
+

+ +
+ +
+ +


+ Previous: Plane Tesselations, + Up: Pattern Reference + +
+ +

33.2 Roulettes and Involutes

+ +
+ “A roulette is the curve generated by a point which is carried by + a curve which rolls on a fixed curve. [...] The locus of a point + carried by a circle rolling on a straight line is a trochoid. If + the point is inside the circle the trochoid has inflexions; if it is + outside the circle, but rigidly attached to it, the trochoid has loops. + [...] In the particular case when the point is on the circumference + of the rolling circle the roulette is a cycloid. When the circle + rolls on the outside of another circle the corresponding curves are the + epitrochoids and epicycloids; if it rolls on the inside, + they are the hypotrochoids and hypocycloids.” +
H. Martyn Cundy and A. P. Rollett, Mathematical Models, p. 46. +
+
+ + + +
+ +


+ Previous: Roulettes and Involutes, + Up: Roulettes and Involutes + +
+ +

33.2.1 Epicycloids

+ + + +
+ — Function: unsigned int epicycloid_pattern_1 (real diameter_inner, real diameter_outer_start, real diameter_outer_end, real step, int arc_divisions, unsigned int offsets, [vector<const Color*> colors = Colors::default_color_vector])
+

Draws a pattern consisting of epicycloids. The outer circle rolls + around the circumference of the inner circle and a Point on the + outer circle traces an epicycloid. + +

If offsets is greater than 1, the outer circle is rotated + offset times around the center of the inner circle + by + 360 / offsets + (starting from the outer circle's original + position). From each of these new positions, an epicycloid is drawn. + +

While diameter_outer_start is + greater than or equal to diameter_outer_end, the diameter of the + outer circle is reduced by step, and another set of epicycloids is + traced, as described above. Each time the diameter of + the outer circle is reduced, a new Color is taken from + colors for the drawing commands. If there are more iterations + than Colors, the last Color on colors is used for + the remaining iterations. + + +

The arguments: +

+
real diameter_inner
The diameter of the inner circle. + +
real diameter_outer_start
The diameter of the outer circle for the first iteration. It must be + greater than or equal to diameter_outer_end. + +
real diameter_outer_end
The diameter of the outer circle for the last iteration. + It must be + less than or equal to diameter_outer_start. + +
real step
The amount by which the diameter of the outer circle is reduced + upon each iteration. + +
int arc_divisions
The number of divisions of the circle used for calculating Points + on the epicycloid. For instance, if arc_divisions is 90, then + the Path for each epicycloid will only have 4 Points, + since 360 / 90 = 4. + +
unsigned int offsets
The number of epicycloids drawn upon each iteration. Each one is + rotated by 360 / offsets around the center of the inner circle. + offsets must be greater than or equal to 1. + +
vector<const Color*> colors
Default: Colors::default_color_vector. The Colors pointed + to by the pointers on this vector are used for drawing the epicycloids. + One Color is used for each iteration. + +
+ +

Example: +

          epicycloid_pattern_1(5, 3, 3, 1, 72);
+           current_picture.output(Projections::PARALLEL_X_Z);
+ 
+

+
+ [Figure 180. Not displayed.] +
+
+ Fig. 180. +
+

+ +

Example: +

          default_focus.set(2, 5, -10, 2, 5, 10, 10);
+           epicycloid_pattern_1(5, 3, 3, 1, 36);
+           current_picture.output();
+ 
+

+
+ [Figure 181. Not displayed.] +
+
+ Fig. 181. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Pattern Reference, + Up: Top + +
+ +

34 Solid Reference

+ +

Class Solid is defined in solids.web. + It's derived from Shape using public derivation. It is intended + to be used as a base class for + more specialized classes representing solid figures, e.g., cuboids, + polyhedra, solids of rotation, etc. + +

+ + + +

34.1 Data Members

+ +
+ — Protected variable: bool on_free_store
+

true, if the Solid was dynamically allocated on the free + store, otherwise false. Solids should only be allocated + on the free store by create_new<Solid>(), or analogous functions + for derived classes. + See Solid Reference; Constructors and Setting Functions. +

+ +
+ — Protected variable: Point center
+

The center of the Solid. An object of a type derived from + Solid need not have a meaningful center. However, many + do, so it's convenient to be able to access it using the member + functions of Solid. +

+ +
+ — Protected variable: bool do_output
+

Set to false in Picture::output(), if the Solid + cannot be projected using the arguments of that particular invocation of + output(). Reset to true at the end of + Picture::output(), so that the Solid will be tested for + projectability again, if output() is called on the + Picture again. +

+ +
+ — Protected variables: vector<Path*> paths
+ — : vector<Circle*> circles
+ — : vector<Ellipse*> ellipses
+ — : vector <Reg_Polygon*> reg_polygons
+ — : vector<Rectangle*> rectangles
+

Vectors of pointers to the Paths, Circles, + Ellipses, Reg_Polygons, and Rectangles, + respectively, belonging to the Solid, if any exist. +

+ +
+ — Protected variable: valarray<real> projective_extremes
+

The maximum and minimum values for the x, y, and z-coordinates of the + Points belonging to the Solid. Used in + Picture::output() for testing whether a Solid is + projectable using a particular set of arguments. +

+ +
+ — Public static const variables: unsigned short CIRCLE
+ — : unsigned short ELLIPSE
+ — : unsigned short PATH
+ — : unsigned short RECTANGLE
+ — : unsigned short REG_POLYGON
+

Used as arguments in the functions get_shape_ptr() and + get_shape_center() + (see Returning Elements and Information). +

+ +
+ +


+ Next: , + Previous: Solid Data Members, + Up: Solid Reference + +
+ +

34.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Solid (void)
+

Creates an empty Solid. +

+ +
+ — Copy constructor: void Solid (const Solid& s)
+

Creates a new Solid and makes it a copy of s. +

+ +
+ — Template specializations: Solid* create_new<Solid> (const Solid* s)
+ — : Solid* create_new<Solid> (const Solid& s)
+

Pseudo-constructors for dynamic allocation of Solids. + They create a Solid on the free store and allocate memory for it using + new(Solid). They return a pointer to the new Solid. + +

If s is a non-zero pointer or a reference, + the new Solid will be a copy of + s. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Solid>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ + + +

34.3 Destructor

+ +
+ — virtual Destructor: void ~Solid (void)
+

This function currently has an empty definition, but its existence + prevents GCC 3.3 from issuing the following warning: + “`class Solid' has virtual functions but non-virtual destructor”. +

+ +
+ +


+ Next: , + Previous: Solid Destructor, + Up: Solid Reference + +
+ +

34.4 Operators

+ +
+ — Virtual function: const Solid& operator= (const Solid& s)
+

Assignment operator. Makes *this a copy of s, discarding + the old contents of *this. +

+ +
+ — Virtual function: Transform operator*= (const Transform& t)
+

Multiplication by a Transform. All of the Shapes that + make up the Solid are transformed by t. +

+ +
+ +


+ Next: , + Previous: Solid Operators, + Up: Solid Reference + +
+ +

34.5 Copying

+ +
+ — const virtual function: Shape* get_copy (void)
+

Dynamically allocates a new Solid on the free store, using + create_new<Solid>(), and makes it a copy of *this. Then, a + pointer to Shape is pointed at the copy and returned. Used for + putting Solids onto Picture::shapes in the drawing and + filling functions for Solid. + See Solid Reference; Drawing and Filling. +

+ +
+ +


+ Next: , + Previous: Copying Solids, + Up: Solid Reference + +
+ +

34.6 Setting Members

+ +
+ — Virtual function: bool set_on_free_store ([bool b = true])
+

Sets on_free_store to b. This function is + called in the template function + create_new(). + See Solid Reference; Constructors and Setting Functions. +

+ + + +

34.7 Querying

+ +
+ — const virtual function: bool is_on_free_store (void)
+

Returns the value of on_free_store; true, if the + Solid was dynamically allocated on the free store, otherwise + false. + Solids, and objects of classes derived from Solid, + should only ever be allocated on the free store by + a specialization of the template function create_new(). + See Solid Reference; Constructors and Setting Functions. +

+ +
+ +


+ Next: , + Previous: Querying Solids, + Up: Solid Reference + +
+ +

34.8 Returning Elements and Information

+ +
+ — const virtual function: const Point& get_center (void)
+

Returns center. If the Solid doesn't + have a meaningful center, the return value will probably be + INVALID_POINT. +

+ + + + + +

Getting Shape Centers

+ +
+ — const virtual function: const Point& get_shape_center (const unsigned short shape_type, const unsigned short s)
+

Returns the center of a Shape belonging to the Solid. + Currently, the object can be a Circle, Ellipse, + Rectangle, or Reg_Polygon, and it is accessed through a pointer + on one of the following vectors of pointers to Shape: + circles, ellipses, + rectangles, or reg_polygons. + The type of + object is specified + using the shape_type argument. + The following public static const data members of Solid + can (and probably should) be passed as the shape_type argument: + CIRCLE, ELLIPSE, RECTANGLE, and + REG_POLYGON. + +

The argument s is used to index the vector. + +

This function is called within the more specialized functions in this + section, namely: get_circle_center(), + get_ellipse_center(), get_rectangle_center(), and + get_reg_polygon_center(). I don't expect it to be needed in user + code very often. + +

          Dodecahedron d(origin, 3);
+           d.filldraw();
+           Point C = d.get_shape_center(Solid::REG_POLYGON, 1);
+           C.dotlabel("C");
+ 
+

+
+ [Figure 182. Not displayed.] +
+
+ Fig. 182. +
+

+ + +

Note that this function will have to be changed, if new vectors of + Shape pointers are added to class Solid! +

+ +
+ — const virtual functions: const Point& get_circle_center (const unsigned short s)
+ — : const Point& get_ellipse_center (const unsigned short s)
+ — : const Point& get_rectangle_center (const unsigned short s)
+ — : const Point& get_reg_polygon_center (const unsigned short s)
+

These functions all return the center of the Shape pointed to by a pointer on + one of the vectors of Shapes belonging to the Solid. The argument s + indicates which element on the vector is to be accessed. For example, + get_rectangle_center(2) returns the center of the + Rectangle pointed to by rectangles[2]. + +

          Cuboid c(origin, 3, 4, 5, 0, 30);
+           c.draw();
+           for (int i = 0; i < 6; ++i)
+             c.get_rectangle_center(i).label(i, "");
+ 
+

+
+ [Figure 183. Not displayed.] +
+
+ Fig. 183. +
+

+ +
+ + + +

Getting Shapes

+ +

The functions in this section + all return const pointers to Shape, or one of its derived + classes. Therefore, they must be invoked in such a way, that + the const qualifier is not discarded. See + the description of get_reg_polygon_ptr() below, for an example. + +

+ — const virtual function: Shape* get_shape_ptr (const unsigned short shape_type, const unsigned short s)
+

Copies one of the objects belonging to the Solid, and returns a + pointer to Shape that points to the copy. + The object is found by dereferencing one of the pointers on one of the + vectors of pointers belonging to the Solid. + Currently, these + vectors are circles, ellipses, paths, + rectangles, and reg_polygons. The argument + shape_type specifies the vector, and the + argument s specifies which element of the vector should be + accessed. The following public static const data members of + Solid can (and probably should) be passed as the shape_type + argument: CIRCLE, ELLIPSE, PATH, RECTANGLE, + and REG_POLYGON. + +

This function was originally intended to be called within the more + specialized functions in this + section, namely: get_circle_ptr(), get_ellipse_ptr(), + get_path_ptr(), get_rectangle_ptr, and get_reg_polygon_ptr. + However, these functions no longer use get_shape_ptr(), so this + function is probably no longer needed. + +

          Icosahedron I(origin, 3);
+           I.filldraw();
+           Reg_Polygon* t =
+           static_cast<Reg_Polygon*>(I.get_shape_ptr(Solid::REG_POLYGON, 9));
+           t->fill(gray);
+ 
+

+
+ [Figure 184. Not displayed.] +
+
+ Fig. 184. +
+

+ +
+ +
+ — const virtual functions: const Reg_Polygon* get_circle_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_ellipse_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_path_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_rectangle_ptr (const unsigned short s)
+ — : const Reg_Polygon* get_reg_polygon_ptr (const unsigned short s)
+

Each of these functions returns a pointer from one of the vectors of + Shape pointers belonging to the Solid. The argument s + specifies which element of the appropriate vector should be returned. + For example, get_reg_polygon_ptr(2) returns the Reg_Polygon* + in reg_polygons[2]. + +

Since these functions return const pointers, they must be invoked + in such a way, that the const qualifier is not discarded, as + noted at the beginning of this section. The following example + demonstrates two ways of invoking get_reg_polygon_ptr(): + +

          Dodecahedron d(origin, 3);
+           d.draw();
+           const Reg_Polygon* ptr = d.get_reg_polygon_ptr(0);
+           ptr->draw(black, "evenly scaled 4", "pencircle scaled 1mm");
+           Reg_Polygon A = *d.get_reg_polygon_ptr(5);
+           A.fill(gray);
+ 
+

+
+ [Figure 185. Not displayed.] +
+
+ Fig. 185. +
+

+ +
+ + + +

34.9 Showing

+ +
+ — const virtual function: void show ([string text = "", [char coords = 'w', [const bool do_persp = true, [const bool do_apply = true, [Focus* f = 0, [const unsigned short proj = Projections::PERSP, [const real factor = 1]]]]]]])
+

Prints text and the value of on_free_store to the standard + output (stdout), and then calls + show() on the objects pointed to by the pointers on + paths, circles, ellipses, reg_polygons, and + rectangles, unless the vectors are empty. The arguments are + passed to Path::show(), Ellipse::show(), etc. If a vector + is empty, a message to this effect is printed to the standard output. +

+ +
+ +


+ Next: , + Previous: Showing Solids, + Up: Solid Reference + +
+ +

34.10 Affine Transformations

+ +
+ — Virtual functions: Transform scale (real x, [real y = 0, [real z = 0]])
+

Solid. + + — : Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]])
+ — : Transform shift (real x, [real y = 0, [real z = 0]])
+ — : Transform shift (const Point& pt)
+ — : Transform rotate (const real x, [const real y = 0, [const real z = 0]])
+ — : Transform rotate (const Point& p0, const Point& p1, [const real angle = 180])
+

These functions perform the corresponding transformations on all of the + Shapes belonging to the Solid. + See Transform Reference; Affine Transformations. +

+ + + +

34.11 Applying Transformations

+ +
+ — Virtual function: void apply_transform (void)
+

Calls apply_transform() on all of the Shapes belonging to + the Solid. +

+ + + +

34.12 Outputting

+ +

The functions in this section are are called, directly or indirectly, by + Picture::output(). + See Picture Reference; Outputting. + +

+ — Virtual function: void output (void)
+

Writes the MetaPost code for drawing, filling, filldrawing, undrawing, + unfilling, or unfilldrawing the Solid to out_stream. +

+ +
+ — Virtual function: void suppress_output (void)
+

Used in Picture::output(). Sets do_output to false, if the + Solid cannot be projected using a particular set of arguments to + Picture::output(). +

+ +
+ — Virtual function: void unsuppress_output (void)
+

Used in Picture::output(). Resets do_output to true, + so that the Solid will be tested for projectability again, if the + Picture it's on is output again. +

+ +
+ — Virtual function: vector<Shape*> extract (const Focus& f, const unsigned short proj, real factor)
+

Tests whether all of the Shapes belonging to the Solid are + projectable, using the arguments passed to output(). If it is, + this function returns a + vector of pointers to Shape containing a single pointer to + the Solid. If not, an empty vector is returned. +

+ +
+ — Virtual function: bool set_extremes (void)
+

Sets projective_extremes to contain the maximum and minimum + values for the x, y, and z-coordinates of the Points on the + Shape. Used for determining projectability of a Solid + using a particular set of arguments. +

+ +
+ — const inline virtual function: const valarray<real> get_extremes (void)
+

Returns projective_extremes. +

+ +
+ — const virtual functions: real get_minimum_z (void)
+ — : real get_maximum_z (void)
+ — : real get_mean_z (void)
+

Returns the minimum, maximum, or mean z-value, respectively, of the + Points belonging to the Solid. + Used for surface hiding. + See Surface Hiding. +

+ +
+ +


+ Next: , + Previous: Outputting Solids, + Up: Solid Reference + +
+ +

34.13 Drawing and Filling

+ +
+ — const virtual function: void draw ([const vector<const Color*> v = Colors::default_color_vector, [const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]]])
+

Draws the Solid. + +

This function allocates a new Solid, makes it a copy of + *this, and puts a pointer to the copy onto + picture.shapes. The data members of the Shapes + belonging to the copy are set appropriately, so that they can be drawn, + when Picture::output() is called. + +

The Colors used + for drawing the various + Paths, Circles, Ellipses, etc., belonging to the + Solid are passed in v. If the Solid contains more + Shapes than v contains pointers to Color, the + Color pointed to by the last pointer on v is used to draw + the remaining Shapes. + +

Currently, a Solid can + only be drawn with a single dash pattern (ddashed), and + pen (ppen). +

+ +
+ — const virtual function: void fill ([const vector<const Color*> v = Colors::default_color_vector, [Picture& picture = current_picture]])
+

Fills the Solid. + +

This function allocates a new Solid makes it a copy of *this, and puts a + pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be filled, + when Picture::output() is called. + +

The Colors used + for filling the various + Paths, Circles, Ellipses, etc., belonging to the + Solid are passed in v. + If the Solid contains more + Shapes than v contains pointers to Color, the + Color pointed to by the last pointer on v is used to fill + the remaining Shapes. +

+ +
+ — const virtual function: void filldraw ([const vector<const Color*> draw_colors = Colors::default_color_vector, [const vector<const Color*> fill_colors = Colors::background_color_vector, [const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]]]])
+

Filldraws the Solid. + +

This function allocates a new Solid, makes it a copy of *this, and puts a + pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be filldrawn, + when Picture::output() is called. + +

The Colors used + for drawing and filling the various + Paths, Circles, Ellipses, etc., belonging to the + Solid are passed in draw_colors and fill_colors. + If the Solid contains more + Shapes than draw_colors contains pointers to Color, the + Color pointed to by the last pointer on draw_colors is used to draw + the remaining Shapes. The same applies to fill_colors. + +

Currently, a Solid can only be filldrawn with a single dash + pattern (ddashed), and pen (ppen). +

+ +
+ — const virtual function: void undraw ([const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]])
+

Undraws the Solid. + +

This function allocates a new Solid, makes it a copy of *this, and puts a + pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be undrawn, + when Picture::output() is called. + +

A Solid can currently only be undrawn using a single dash + pattern (ddashed), and + pen (ppen). +

+ +
+ — const virtual function: void unfill ([Picture& picture = current_picture])
+

Unfills the Solid. + +

This function allocates a new Solid makes it a copy of + *this, and puts a pointer to it onto picture.shapes. + The data members of the Shapes + belonging to the copy are set appropriately, so that they can be unfilled, + when Picture::output() is called. + +

+ +
+ — const virtual function: void unfilldraw ([const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]])
+ — const virtual function: void undraw ([const string ddashed = "", [const string ppen = "", [Picture& picture = current_picture]]])
+

Unfilldraws the Solid. + +

This function allocates a new Solid, makes it a copy of + *this, and puts a + pointer to it onto picture.shapes. The data members of the + Shapes + belonging to the copy are set appropriately, so that they can be + unfilldrawn, when Picture::output() is called. + +

A Solid can currently only be unfilldrawn using a single dash + pattern (ddashed), and + pen (ppen). +

+ +
+ +


+ Previous: Drawing and Filling Solids, + Up: Solid Reference + +
+ +

34.14 Clearing

+ +
+ — Virtual function: void clear (void)
+

Calls clear() on all the Shapes belonging to the + Solid. + Used in Picture::clear() for deallocating + and destroying Solids. + +

Currently, <Shape>.clear() always resolves to + Path::clear(), since none of the other types of Shape that a + Solid can contain, e.g., Ellipse, Circle, etc., + overloads Path::clear(). +

+ + + + + + +
+ +


+ Next: , + Previous: Solid Reference, + Up: Top + +
+ +

35 Faced Solid Reference

+ +

Class Solid_Faced is defined in solfaced.web. + It is derived from Solid using public derivation. + +

Solid_Faced currently has no member functions. It is intended + for use as a base class. The classes Cuboid and + Polyhedron are derived from Solid_Faced. + See Cuboid Reference, and Polyhedron Reference. + +

+ +
+ + +


+ Previous: Faced Solid Reference, + Up: Faced Solid Reference + +
+ +

35.1 Data Members

+ +
+ — Protected variable: unsigned short faces
+

The number of faces of the Solid_Faced. +

+ +
+ — Protected variable: unsigned short vertices
+

The number of vertices of the Solid_Faced. +

+ +
+ — Protected variable: unsigned short edges
+

The number of edges of the Solid_Faced. +

+ + + + + + +
+ +


+ Next: , + Previous: Faced Solid Reference, + Up: Top + +
+ +

36 Cuboid Reference

+ +

Class Cuboid is defined in cuboid.web. + It is derived from Solid_Faced using public derivation. + +

+ + + +

36.1 Data Members

+ +
+ — Protected variables: real height
+ — : real width
+ — : real depth
+

The height, width, and depth of the Cuboid, respectively. + +

Please note, that “height”, “width”, and + “depth” are conventional terms. There are no restrictions on + the orientation of a Cuboid. +

+ +
+ +


+ Next: , + Previous: Cuboid Data Members, + Up: Cuboid Reference + +
+ +

36.2 Constructors and Setting Functions

+ +
+ — Default constructor: void Cuboid (void)
+

Creates an empty Cuboid. +

+ +
+ — Copy constructor: void Cuboid (const Cuboid& c)
+

Creates a new Cuboid and makes it a copy of c. +

+ +
+ — Constructor: void Cuboid (const Point& c, const real h, const real w, const real d, [const real x = 0, [const real y = 0, [const real z = 0]]])
+

Creates a Cuboid with center at the origin, with + height == h, width == w, and + depth == d. If x, y, or z is + non-zero, the Cuboid is rotated by the amounts indicated around + the corresponding main axes. Finally, the + Cuboid is shifted such that center comes to lie at + c. + +

          Point P(-3, -2, 12);
+           Cuboid c(P, 3, 5, 2.93, 35, 10, 60);
+ 
+

+
+ [Figure 186. Not displayed.] +
+
+ Fig. 186. +
+

+ +
+ +
+ — Template specializations: Cuboid* create_new<Cuboid> (const Cuboid* c)
+ — : Cuboid* create_new<Cuboid> (const Cuboid& c)
+

Pseudo-constructors for dynamic allocation of Cuboids. + They create a Cuboid on the free store and allocate memory for it using + new(Cuboid). They return a pointer to the new Cuboid. + +

If c is a non-zero pointer or a reference, + the new Cuboid will be a copy of + c. If the new object is not meant to be a + copy of an existing one, ‘0’ must be passed to + create_new<Cuboid>() as its argument. + See Dynamic Allocation of Shapes, for more information. +

+ +
+ — Destructor: void ~Cuboid (void)
+

Deallocates the Rectangles pointed to by the pointers on + rectangles (a Solid data member), and calls + rectangles.clear(). Cuboids consist entirely of + Rectangles, so nothing must be done to the other vectors. +

+ + + +

36.3 Operators

+ +
+ — Assignment operator: void operator= (const Cuboid& c)
+

Makes the Cuboid a copy of c. The old contents of *this + are deallocated (where necessary) and discarded. +

+ + + + + + +
+ +


+ Next: , + Previous: Cuboid Reference, + Up: Top + +
+ +

37 Polyhedron Reference

+ +

Class Polyhedron is defined in polyhed.web. + It is derived from Solid_Faced using public derivation. It is + intended for use as a base class for specific types of polyhedra. + Currently, the classes Tetrahedron, Dodecahedron, + Icosahedron, and Trunc_Octahedron (truncated octahedron) + are derived from Polyhedron. + +

There is a great deal of work left to do on the polyhedra. + +

+ + + +

37.1 Data Members

+ +
+ — Protected variable: unsigned short number_of_polygon_types
+

The number of different types of polygon making up the faces of a + Polyhedron. The Platonic polyhedra have only one type of face, + while the Archimedean can have more. +

+ +
+ — Protected variable: real face_radius
+

The radius of the sphere that touches the centers of the polygonal faces + of the polyhedron (Inkugel, in German). +

+ +
+ — Protected variable: real edge_radius
+

The radius of the sphere that touches the centers of the edges of the + polyhedron. + +

+ +
+ — Protected variable: real vertex_radius
+

The radius of the sphere touching the vertices of the polyhedron + (Umkugel, in German). +

+ + + +

37.2 Regular Platonic Polyhedra

+ +

3DLDF currently has classes for three of the five regular Platonic + polyhedra: Tetrahedron, Dodecahedron, and + Icosahedron. There is no need for a special Cube class, + because cubes can be created using Cuboid with equal width, + height, and depth arguments (see Cuboid Reference). Octahedron is + missing at the moment, but I plan to add it soon. + +

+ +
+ +


+ Next: , + Previous: Regular Platonic Polyhedra, + Up: Regular Platonic Polyhedra + +
+ +

37.2.1 Tetrahedron

+ +

Class Tetrahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

+ + + +
37.2.1.1 Data Members
+ +
+ — Protected static const variable: real dihedral_angle
+

The angle in radians between the faces of the Tetrahedron, namely + 70 degrees + 32' + . + Only + the Platonic polyhedra have a single dihedral angle, so + dihedral_angle is not a member of + Polyhedron. This means that it must be a member of all of the + classes representing Platonic polyhedra. + +

+ +
+ — Protected variable: real triangle_radius
+

The radius of the circle enclosing a triangular face of the + Tetrahedron. + +

+ +
+ +


+ Next: , + Previous: Tetrahedron Data Members, + Up: Tetrahedron + +
+ +
37.2.1.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Tetrahedron (void)
+

Creates an empty Tetrahedron. +

+ +
+ — Constructor: void Tetrahedron (const Point& p, const real diameter_of_triangle, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Creates a Tetrahedron with its center at the origin. + The faces have enclosing circles of diameter + diameter_of_triangle. If any of angle_x, angle_y, or + angle_z is non-zero, the Tetrahedron is rotated by the + amounts specified around the corresponding axes. Finally, if p is + not the origin, the Tetrahedron is shifted such that + center comes to lie at p. + +

The center of a Tetrahedron is the intersection of the line + segments connecting the vertices with the centers of the opposite + faces. + +

          Tetrahedron t(origin, 3);
+           t.draw();
+ 
+

+
+ [Figure 187. Not displayed.] +
+
+ Fig. 187. +
+

+ +
          Point P(1, 0, 1);
+           Tetrahedron t(P, 2.75, 30, 32.5, 20);
+           t.draw();
+ 
+

+
+ [Figure 188. Not displayed.] +
+
+ Fig. 188. +
+

+ +
+ +
+ — Setting function: void set (const Point& p, const real diameter_of_triangle, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Corresponds to the constructor above. +

+ + + +
37.2.1.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real triangle_diameter)
+

Returns the net of the Tetrahedron, i.e., the + two-dimensional pattern of triangles that can be folded into + a model of a tetrahedron.45 + The net lies in the x-z plane. The triangles + have enclosing circles of diameter triangle_diameter. The center + of the middle triangle is at the origin. + +

          vector<Reg_Polygon*> vrp = Tetrahedron::get_net(2);
+           for (vector<Reg_Polygon*>::iterator iter = vrp.begin();
+                iter != vrp.end();
+                ++iter)
+             {
+               (**iter).draw();
+             }
+ 
+

+
+ [Figure 189. Not displayed.] +
+
+ Fig. 189. +
+

+ +

This function is used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Tetrahedron; Constructors and Setting Functions. + The constructor starts with the net and rotates three of the triangles + about the adjacent vertices of the middle triangle. Currently, all of + the Polyhedron constructors work this way. + However, this is not ideal, because rotation uses the sine and cosine + functions, which cause inaccuracies to creep in. + I think there must be a better way of constructing Polyhedra, but + I haven't found one yet. + +

The Polyhedron constructors are also especially + sensitive to changes made to Transform::align_with_axis(). + I have already had to rewrite them twice, and since + Transform::align_with_axis() may need to be changed or rewritten + again, it's possible that the Polyhedron constructors will have + to be, too. It has also occurred in the past, that the Polyhedra + were constructed correctly on one platform, using a particular compiler, + but not on another platform, using a different compiler. +

+ +
+ — Static function: void draw_net (const real triangle_diameter, [bool make_tabs = true])
+

Draws the net for a Tetrahedron in the x-y plane. + The triangles + have enclosing circles of diameter triangle_diameter. The + origin is used as the center of the middle triangle. + The centers of the triangles are numbered. + If the argument make_tabs is used, tabs for gluing and/or sewing a + cardboard model of the Tetrahedron together will be drawn, too. + The dots on the tabs mark where to stick the needle through, when sewing + the model together (I've had good results with sewing). + +

          Tetrahedron::draw_net(3, true);
+ 
+

+
+ [Figure 190. Not displayed.] +
+
+ Fig. 190. +
+

+ +

The net is drawn in the x-y plane, because it currently doesn't work to + draw it in the x-z plane. I haven't gotten around to fixing this + problem yet. +

+ +
+ +


+ Next: , + Previous: Tetrahedron, + Up: Regular Platonic Polyhedra + +
+ +

37.2.2 Dodecahedron

+ +

Class Dodecahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

Dodecahedra have 12 regular pentagonal faces. + +

+ + + +
37.2.2.1 Data Members
+ +
+ — Protected static const variable: real dihedral_angle
+

The angle between the faces of the Dodecahedron, + namely + 116 degrees + 34' + = \pi - \arctan(2). + +

+ +
+ — Protected variable: real pentagon_radius
+

The radius of the circle enclosing a pentagonal face of the + Dodecahedron. + +

+ +
+ +


+ Next: , + Previous: Dodecahedron Data Members, + Up: Dodecahedron + +
+ +
37.2.2.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Dodecahedron (void)
+

Creates an empty Dodecahedron. +

+ +
+ — Constructor: void Dodecahedron (const Point& p, const real pentagon_diameter, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Creates a Dodecahedron with its center at the origin, where the + pentagonal faces have enclosing circles of diameter + pentagon_diameter. If any of angle_x, angle_y, or + angle_z is non-zero, the Dodecahedron is rotated by the + amounts specified around the corresponding axes. Finally, if p is + not the origin, the Dodecahedron is shifted such that + center comes to lie at p. + +

          Point P(-1, -2, 4);
+           Dodecahedron d(P, 3, 12.5, 16, 2);
+           d.draw();
+ 
+

+
+ [Figure 191. Not displayed.] +
+
+ Fig. 191. +
+

+ +
          d.filldraw();
+ 
+

+
+ [Figure 192. Not displayed.] +
+
+ Fig. 192. +
+

+ +
+ + + +
37.2.2.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real pentagon_diameter, [bool do_half = false])
+

Returns the net, i.e., the two-dimensional pattern of pentagons + that can be folded into a model of a dodecahedron. The net lies + in the x-z plane. The pentagons have enclosing circles of diameter + pentagon_diameter. The center of the center pentagon of the first + half of the net is at the origin. If the argument + do_half is true, only the first half of the + net is created. This is used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Dodecahedron; Constructors and Setting Functions. + +

          vector<Reg_Polygon*> vrp = Dodecahedron::get_net(1);
+           for(vector<Reg_Polygon*>::iterator iter = vrp.begin();
+               iter != vrp.end(); ++iter)
+                  (**iter).draw();
+ 
+

+
+ [Figure 193. Not displayed.] +
+
+ Fig. 193. +
+

+ +
+ +
+ — Static function: void draw_net (const real pentagon_diameter, [bool portrait = true, [bool make_tabs = true]])
+

Draws the net for a Dodecahedron in the x-z plane. The pentagons + have enclosing circles of diameter pentagon_diameter. The + origin is used as the center of the middle pentagon of the first half of + the net. The centers of the pentagons are numbered. + +

If the argument portrait is true (the default), the net + is arranged for printing in portrait format. If it's false, + it's arranged for printing in landscape format. + +

The argument make_tabs currently has no effect. + When I get around to programming this, it will be used for specifying + whether tabs for gluing and/or sewing a cardboard model should be drawn, + too. + +

          Dodecahedron::draw_net(1, false);
+ 
+

+
+ [Figure 194. Not displayed.] +
+
+ Fig. 194. +
+

+ +
+ +
+ +


+ Previous: Dodecahedron, + Up: Regular Platonic Polyhedra + +
+ +

37.2.3 Icosahedron

+ +

Class Icosahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

Icosahedra have 20 regular triangular faces. + +

+ + + +
37.2.3.1 Data Members
+ +
+ — Protected static const variable: real dihedral_angle
+

The angle between the faces of the Icosahedron, namely + 138 degrees + 11' + = \pi - \arcsin(2/3). + +

+ +
+ — Protected variable: real triangle_radius
+

The radius of the circle enclosing a triangular face of + the Icosahedron. + +

+ +
+ +


+ Next: , + Previous: Icosahedron Data Members, + Up: Icosahedron + +
+ +
37.2.3.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Icosahedron (void)
+

Creates an empty Icosahedron. +

+ +
+ — Constructor: void Icosahedron (const Point& p, const real diameter_of_triangle, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

Creates an Icosahedron with its center at the origin, where the + triangular faces have enclosing circles of diameter + diameter_of_triangle. If any of angle_x, angle_y, or + angle_z is non-zero, the Icosahedron is rotated by the + amounts specified around the corresponding axes. Finally, if p is + not the origin, the Icosahedron is shifted such that + center comes to lie at p. + +

          Icosahedron i(origin, 3, 0, 10);
+           i.draw();
+ 
+

+
+ [Figure 195. Not displayed.] +
+
+ Fig. 195. +
+

+ +
          i.filldraw();
+ 
+

+
+ [Figure 196. Not displayed.] +
+
+ Fig. 196. +
+

+ +
+ + + +
37.2.3.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real triangle_diameter, [bool do_half = false])
+

Returns the net, i.e., the two-dimensional pattern of triangles + that can be folded into a model of an icosahedron. The net lies + in the x-z plane. The triangles have enclosing circles of diameter + triangle_diameter. + If the argument do_half = true, only the first half of the + net is created. This is used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Icosahedron; Constructors and Setting Functions. + +

          vector<Reg_Polygon*> vrp = Icosahedron::get_net(1.5);
+           for (vector<Reg_Polygon*>::iterator iter = vrp.begin();
+                iter != vrp.end(); ++iter)
+              (**iter).draw();
+ 
+

+
+ [Figure 197. Not displayed.] +
+
+ Fig. 197. +
+

+ +
+ +
+ — Static function: void draw_net (const real triangle_diameter, [bool portrait = true, [bool make_tabs = true]])
+

Draws the net for an Icosahedron in the x-z plane. The triangles + have enclosing circles of diameter triangle_diameter. + If the argument portrait is true (the default), the net + will be arranged for printing in portrait format. If it's false, + it will be arranged for printing in landscape format. + In portrait format, the center of the bottom right triangle is at the + origin. In landscape format, the center of the bottom left + triangle is at the origin. The triangles are numbered. + +

The argument make_tabs currently has no effect. + When I get around to programming this, it will be used for specifying + whether tabs for gluing and/or sewing a cardboard model should be drawn, + too. + +

          Icosahedron::draw_net(2, false);
+ 
+

+
+ [Figure 198. Not displayed.] +
+
+ Fig. 198. +
+

+ +
+ + +
+ + +


+ Previous: Regular Platonic Polyhedra, + Up: Polyhedron Reference + +
+ +

37.3 Semi-Regular Archimedean Polyhedra

+ +

Once I've added class Octahedron, the only Platonic polyhedron I + haven't programmed yet, I plan to start adding classes + for the semi-regular Archimedean polyhedra. + +

+ + + + +

37.3.1 Truncated Octahedron

+ +

Class Trunc_Octahedron is defined in polyhed.web. + It is derived from Polyhedron using public derivation. + +

Trunc_Octahedron does not yet have a functioning constructor, so + it cannot be used as yet. + +

+ + + + +
37.3.1.1 Data Members
+ +
+ — Protected static const variable: real angle_hex_square
+

The angle between the hexagonal and the square faces of the truncated + octahedron, namely + 125 degrees + 16' + . + +

+ +
+ — Protected static const variable: real angle_hex_hex
+

The angle between the hexagonal faces of the truncated + octahedron, namely + 109 degrees + 28' + . + +

+ +
+ — Protected variable: real hexagon_radius
+

The radius of the circle enclosing a hexagonal or square face of the + Trunc_Octahedron. +

+ + + +
37.3.1.2 Constructors and Setting Functions
+ +
+ — Default constructor: void Trunc_Octahedron (void)
+

Creates an empty Trunc_Octahedron. +

+ +
+ — Constructor: void Trunc_Octahedron (const Point& p, const real diameter_of_hexagon, [real angle_x = 0, [real angle_y = 0, [real angle_z = 0]]])
+

This function does not yet exist! + When it does, it will create a Trunc_Octahedron with its center + at the origin, where the + hexagonal and square faces have enclosing circles of diameter + diameter_of_hexagon. If any of angle_x, angle_y, or + angle_z is non-zero, the Trunc_Octahedron will be rotated + by the amounts specified around the corresponding axes. Finally, + if p is not the origin, the Trunc_Octahedron will be + shifted such that center comes to lie at p. +

+ + + + +
37.3.1.3 Net
+ +
+ — Static function: vector<Reg_Polygon*> get_net (const real hexagon_diameter, [bool do_half = false])
+

This function does not yet exist! + When it does, it will return the net, i.e., the two-dimensional + pattern of hexagons and squares that can be folded into + a model of a truncated octahedron. The net will lie in the x-z plane. + The hexagons and squares will + have enclosing circles of diameter hexagon_diameter. + If the argument do_half is true, only the first half of the + net will be created. This will be used in the non-default constructor. + See Polyhedron Reference; Regular Platonic Polyhedra; Truncated Octahedron Constructors and Setting Functions. +

+ + + + + + +
+ +


+ Next: , + Previous: Polyhedron Reference, + Up: Top + +
+ +

38 Utility Functions

+ +
+ — Function: double trunc (double d)
+

Defined in pspglb.web. + For some reason, when I compile 3DLDF using GNU CC on a PC Pentium II + XEON under Linux 2.4.4 i686, the standard library function + trunc() is not available. Therefore, I've had to write one. + + This is a kludge! + Someday, I'll have to try to find a better solution to this problem. +

+ +
+ — Function: pair<real, real> solve_quadratic (real a, real b, real c)
+

Defined in pspglb.web. + This function tries to find the solutions S_0 and S_1 to the + quadratic equation + ax^2 + bx + c according to the formulae + S_0 == -b + sqrt(b^2 - 4ac) / 2a) and + S_1 == -b - sqrt( b^2 - 4ac) / 2a. + Let r stand for the return value. If S_0 cannot be found, + r.first will be INVALID_REAL, otherwise S_0. + If S_1 cannot be found, + r.second will be INVALID_REAL, otherwise S_1. + +

          (x + 4)(x + 2) = x^2 + 6x + 8 = 0
+ 
+
          real_pair r = solve_quadratic(1, 6, 8);
+           ⇒ r.first == -2
+           ⇒ r.second == -4
+ 
+
          real_pair r = solve_quadratic(1, -2, 4);
+           ⇒ r.first == INVALID_REAL
+           ⇒ r.second == INVALID_REAL
+ 
+
+ + + +
+ +


+ Previous: Utility Functions, + Up: Utility Functions + +
+ +

38.1 Perspective Functions

+ +
+ — Function: void persp_0 (const real front_corner_x, const real front_corner_z, const real side_lft, const real side_rt, const real angle_rt, const real f_2_cv, const real gl_2_cv, [const real horizon_lft = 6, [real horizon_rt = 0, [real gl_lft = 0, [real gl_rt = 0]]]])
+

Defined in utility.web. + This function is used for the figure in The Perspective Projection, illustrating a perspective projection as it could be done + by hand. It draws a rectangle in the ground plane and the construction + lines used for putting it into perspective. It also labels the + vanishing and measuring points. + +

The arguments: +

+
const real front_corner_x
The x-coordinate of the front corner of the rectangle. + +
const real front_corner_z
The z-coordinate of the front corner of the rectangle. + +
const real side_lft
The length of the left side of the rectangle. + +
const real side_rt
The length of the right side of the rectangle. + +
const real angle_rt
The angle at which the right side of the rectangle recedes to the + horizon. + +
const real f_2_cv
The distance from the focus to the center of vision. + +
const real gl_2_cv
The distance of the ground line to the center of vision. + +
const real horizon_lft
Default: 6. + The length of the horizon line leftwards of the center of vision. + +
real horizon_rt
Default: 0. + The length of the horizon line rightwards of the center of vision. + +
real gl_lft
Default: 0. + The length of the ground line leftwards of the line from the focus to + the center of vision. + +
real gl_rt
Default: 0. + The length of the ground line rightwards of the line from the focus to + the center of vision. +
+ +

Example: + +

          persp_0(3, 2, 10, 5, 47.5, 7, 5, 8.5, 9.5, 8.5, 9.5);
+ 
+

+
+ [Figure 199. Not displayed.] +
+
+ Fig. 199. +
+

+ +
+ + + + + + +
+ +


+ Next: , + Previous: Utility Functions, + Up: Top + +
+ +

39 Adding a File

+ +

Version 1.1.1 was the first version of 3DLDF since it became a GNU + package (the current version is 1.1.5.1). In previous versions, + recompilation was controlled by an + auxilliary program, which I wrote in C++ + using CWEB. However, + in the course of making 3DLDF conformant to the + GNU Coding Standards46, + this has + been changed. Recompilation is now controlled by make, as is + customary. The chapter “Compiling” in previous editions of this + manual, is therefore no longer needed. + +

Nonetheless, using CWEB still has consequences for the way recompilation + must be handled, and it was fairly tricky getting make to work + for 3DLDF. Users who only put code in main.web and/or change + code in existing files won't have to worry about this; + for others, this chapter explains how to add + files to 3DLDF. + +

Let's say you want to add a file widgets.web that defines a + class Widget, and that the latter needs access to + class Rectangle, and is in turn required by class Ellipse. + Code must be added to 3DLDF-1.1.5.1/CWEB/Makefile for + ctangling widgets.web, compiling widgets.cxx, and linking + widgets.o with the other object files to make the executable + 3dldf. + +

The best way to do this is to change + 3DLDF-1.1.5.1/CWEB/Makefile.am and use Automake + to generate a new Makefile.in. Then, configure can be + used to generate a new Makefile. It would be possible to modify + Makefile by hand, but I don't recommend it. The following + assumes that the user has access to Automake. If he or she is using a + GNU/Linux system, this is probably true.47 + +

widgets.web’ must be added between ‘rectangs.web’ and + ‘ellipses.web’ in the following variable declaration in + 3DLDF-1.1.5.1/CWEB/Makefile.am: + +

     3dldf_SOME_CWEBS = pspglb.web io.web colors.web transfor.web \
+                         shapes.web pictures.web points.web \
+                         lines.web planes.web paths.web curves.web \
+                         polygons.web rectangs.web ellipses.web \
+                         circles.web patterns.web solids.web
+                         solfaced.web cuboid.web polyhed.web \
+                         utility.web parser.web examples.web
+ 
+

Now, add ‘widgets.o’ between ‘ellipses.o’ and + ‘rectangs.o’ in the following variable declaration: + +

     3dldf_OBS_REVERSED = main.o examples.o parser.o utility.o \
+                           polyhed.o cuboid.o  solfaced.o solids.o \
+                           patterns.o circles.o ellipses.o rectangs.o \
+                           polygons.o curves.o paths.o \
+                           planes.o lines.o points.o pictures.o shapes.o
+                           transfor.o colors.o io.o pspglb.o
+ 
+

3dldf_OBS_REVERSED is needed, because 3DLDF fails with + a “Segmentation fault”, if + the executable is linked using $(3dldf_OBJECTS). This may cause + problems, if 3dldf isn't built using the GNU C++ + compiler + (GCC). + +

Now add a target for widgets.o between the targets for + rectangs.o and ellipses.o, and add widgets.tim + after rectangs.tim in the list of prerequisites for + ellipses.o: + +

     rectangs.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.cxx
+      
+      ellipses.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.tim ellipses.cxx
+ 
+

This is the result: +

     rectangs.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.cxx
+      
+      widgets.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.tim \
+               widgets.cxx
+      
+      ellipses.o: loader.tim pspglb.tim io.tim colors.tim transfor.tim \
+               shapes.tim pictures.tim points.tim lines.tim planes.tim \
+               paths.tim curves.tim polygons.tim rectangs.tim widgets.tim \
+               ellipses.cxx
+ 
+

In addition, widgets.tim + must be added to the list of prerequisites in all of the following + targets up to and including examples.o. + + + + + + +

+ +


+ Next: , + Previous: Adding a File, + Up: Top + +
+ +

40 Future Plans

+ +

3DLDF is a work-in-progress. In fact, it can never be + finished, because the supply of interesting geometric constructions + is inexhaustible. However, presently 3DLDF still has a number of major + gaps. + +

If you're interesting in contributing to 3DLDF, with respect to one of + the topics below and in the following sections, or if you have ideas + of your own, see Contributing to 3DLDF. + +

    +
  • Input routine. + The lack of one is the most significant + defect in 3DLDF, as mentioned in No Input Routine. + +
  • Port to other platforms. + See Ports. +
+ + + +
+ +


+ Next: , + Previous: Future Plans, + Up: Future Plans + +
+ +

40.1 Geometry

+ +

3DLDF currently provides a set of basic plane and solid geometrical + figures. However, some important ones are still missing. + There are many useful geometrical data types and functions whose + implementation would require no more than elementary geometry. + +

    +
  • Add constructors with a normal vector argument rather than angles of + rotation about the main axes. + +
  • I have started defining class Triangle, which can be used for + calculating triangle solutions. + +
  • Add a class Conic_Section and derive Ellipse + from it. This will be the first case of + multiple inheritance48 + in 3DLDF, since Ellipse is already + derived from Path. See Ellipse Reference. + Add the classes Parabola and Hyperbola. + +
  • Add more functions for finding the intersections of objects of various + types, starting with the plane figures. + In particular, I believe I've found an algebraic solution for + the intersection of an Ellipse and a Circle in a plane, + but I haven't had a chance to try implementing it yet. + +

    If this works, I think it will make it possible to find the intersection + of two coplanar ellipses algebraically, because it will be possible to + transform them both such that one of them becomes circular. + +

  • Class Octahedron will complete the set of regular Platonic + polyhedra. + +
  • Add classes for the Kepler-Poinsot polyhedra, the semi-regular + Archimedean polyhedra, the dual solids, the stellated Archimedean + polyhedra, and the regular compounds.49 + +
  • Add class Ellipsoid and a derived class Sphere. + +
  • Improve the specification of Solid and + Solid_Faced. + In particular, it would help to store the vertices of + Polyhedra as individual Points, rather + than using Reg_Polygons. I'd also + like to find a better way of generating Solids, without using + rotations, if possible. + +
+ +
+ +


+ Next: , + Previous: Geometry, + Up: Future Plans + +
+ +

40.2 Curves and Surfaces

+ +

3D modelling software usually supports the creation and manipulation of + various kinds of spline curves: Bézier curves, + B-splines, and non-uniform rational B-splines or + NURBS. These curves can be used for generating surfaces.50 + +

paths in Metafont and MetaPost are Bézier curves. + It would be possible to implement three-dimensional Bézier curves in + 3DLDF, but unfortunately they are not projectively invariant: + +

Let c_0 represent a Bézier curve in three dimensions, + P the control points of c_0, and + t a projection transformation. + Further, let Q represent the points generated from applying + t to P, and c_1 the curve generated from Q. + Finally, let R represent the points generated from applying + t to all of the points on c_0, and + c_2 the curve through R: + c_1 \not\equiv c_2. + +

NURBS, on the other hand, are projectively invariant,51 + so I will probably + concentrate on implementing them. On the other hand, it would be nice + to be able to implement Metafont's way of specifying paths + using `curl', `tension', and `dir' in 3DLDF. + This may prove to be difficult or impossible. I do not yet know + whether Metafont's path creation algorithm can be generalized to + three dimensions.52 + +

Curves and surfaces are advanced topics, so it may be a while + before I implement them in 3DLDF. + +

+ +


+ Next: , + Previous: Curves and Surfaces, + Up: Future Plans + +
+ +

40.3 Shadows, Reflections, and Rendering

+ +

Shadows and reflections are closely related to transformations and + projections. + A shadow is the projection of the outline of an object onto a surface or + surfaces, and reflection in a plane is an affine transformation. + +

3D rendering software generally implements shadows, or more generally, + shading, reflections, and certain other effects using methods + involving the calculation of individual pixel values. + Surface hiding is also often implemented at the pixel level. + 3DLDF does no scan converting ((see Accuracy), and hence + no calculation of pixel values at all, so these methods cannot be + used in 3DLDF at present. + +

However, it is possible to define functions for generating + shadows and reflections within 3DLDF by other means. + +

I have defined the function Point::reflect() for reflecting a + Point in a Plane, and have begun definining versions for + other classes. + +

However, in order for reflections to work, I must define functions for + breaking up objects into smaller units. This is also necessary for + surface hiding to work properly. + +

For MetaPost output, I will have to implement shadows, reflections, and + surface hiding in this way. However, 3DLDF could be made to produce + output in other formats. There are two possibilities: implementing + rendering functionality within 3DLDF, or interfacing to + existing rendering software. If I decide to do the latter, there are + again two possibilities: having 3DLDF write output in a format that a + renderer can input, or linking to a library supplied by a rendering + package. + +

I haven't yet decided which course to pursue. However, in the long run, + I'd like it to be possible to use 3DLDF for fancier graphics than is + currently possible using MetaPost and PostScript alone. + +

+ + +


+ Previous: Shadows, + Up: Future Plans + +
+ +

40.4 Multi-Threading

+ +

When 3DLDF is run, there is only one thread of execution. + However, it could benefit from the use of multiple threads. + In particular, it may be faster and more efficient to have + Picture::output() run in its own thread. + In this case, it will no longer be possible to share + current_picture among figures. + +

It may also be + worthwhile to execute the code for “figures”, i.e., the code + between ‘beginfig()’ and ‘endfig()’, inclusive, + in their own threads. This will require some changes in the way data + are handled. For example, if non-constant objects are shared + among figures, there may be no advantage to multi-threading because of + the need to coordinate the access of the threads to the objects. + If threads are used, then non-constant objects should be + declared locally within the figure. They may be locally declared + copies of global objects. Alternatively, beginfig() could be + changed so that objects could be passed to it as arguments, perhaps as + a vector<void*> and/or a vector<Shape*>. + + + + + + + + + + + + +

+ +


+ Next: , + Previous: Future Plans, + Up: Top + +
+ +

41 Changes

+ +

Updated 16 January 2004. + +

+ +
+ + +


+ Next: , + Previous: Changes, + Up: Changes + +
+ +

41.1 3DLDF 1.1.5.1

+ +
    +
  • Added missing Texinfo files to the 3dldf_TEXINFOS variable in + 3DLDF-1.1.5.1/DOC/TEXINFO/Makefile.am, and reordered the + filenames. + +
  • Changed the names of the PNG (Portable Network Graphics) files + included in the HTML version of this manual. + Changed the names in the commands for including these + files in the Texinfo files. I wasn't able to write some of the + files with the old names to a CD-R (Compact Disk, Recordable). +
+ +
+ + +


+ Next: , + Previous: Changes in 3DLDF 1.1.5.1, + Up: Changes + +
+ +

41.2 3DLDF 1.1.5

+ +

In release 1.1.5, I've tied up some loose ends. I wanted to do this + before starting on the input routine. + +

    +
  • Added const real step argument to the version of + Ellipse::intersection_points() that takes an Ellipse + argument. + See Ellipse Reference; Intersections. + +
  • It is now possible to “typedef” real to either float + or double. This means that real can now be made a synonym + for either float or double by using a typedef + declaration. real is typedeffed to float by default. + +
  • Added const bool ldf_real_float and + extern const bool ldf_real_double + for use in non-conditionally compiled code. + They are set according to the values + of LDF_REAL_FLOAT and LDF_REAL_DOUBLE. + +
  • Transform::epsilon() and Point::epsilon() now return + different values, depending on the values of the preprocessor macros + LDF_REAL_FLOAT and LDF_REAL_DOUBLE. I have not yet tested + whether good values are returned when real is double. + +
  • MAX_REAL and MAX_REAL_SQRT are no longer constants. + Their values are set at the beginning of main(). However, + users should not change their values. MAX_REAL is the + second-largest float or double on a given machine. This + now works for all common architectures. + +
  • Added namespace System containing the following functions: + get_endianness(), is_big_endian(), + is_little_endian(), get_register_width(), + is_32_bit(), is_64_bit(), and the template function + get_second_largest(). + +

    namespace System and its functions are documented in + system.texi, which is new in edition 1.1.5.1. + +

  • Replaced the various create_new_<type>() functions with the + template function create_new(). The latter is documented in + creatnew.texi, which is new in edition 1.1.5.1. + +
  • Added the file 3DLDF-1.1.5.1/CWEB/cnepspng.el to + the distribution. It contains the definitions of the Emacs-Lisp + functions convert-eps and convert-eps-loop. + See Running 3DLDF; Converting EPS Files; Emacs-Lisp Functions. + +
  • Added the files + 3DLDF-1.1.5.1/CWEB/exampman.web and
    + 3DLDF-1.1.5.1/CWEB/examples.mp to the + distribution. They contain the C++ + and MetaPost code, + respectively, for generating the illustrations in this manual. + +
+ +
+ + +


+ Next: , + Previous: Changes in 3DLDF 1.1.5, + Up: Changes + +
+ +

41.3 3DLDF 1.1.4.2

+ +
    +
  • The illustrations in the HTML output are now scaled to + magstep3. +
+ +
+ + +


+ Next: , + Previous: Changes in 3DLDF 1.1.4.2, + Up: Changes + +
+ +

41.4 3DLDF 1.1.4.1

+ +
    +
  • The HTML output now includes illustrations. +
+ +
+ + +


+ Next: , + Previous: Changes in 3DLDF 1.1.4.1, + Up: Changes + +
+ +

41.5 3DLDF 1.1.4

+ +
    +
  • MAX_REAL is now the second largest float value. However, the + calculation is system dependent, and will only work on 32-bit + little-endian architectures. I will start working on porting this + soon. + +
  • Fixed bug in tsthdweb, that caused files to be compiled more + often than necessary. It will be necessary to keep an eye on this. + +
  • Added Rectangle::is_rectangular(). + +
  • Made mediate() a member function of Point. + +
  • It is now possible to generate this manual in the Info and HTML + formats. +
+ +
+ +


+ Previous: Changes in 3DLDF 1.1.4, + Up: Changes + +
+ +

41.6 3DLDF 1.1.1

+ +

3DLDF 1.1.1 was the first version of 3DLDF since it became a GNU + package (the current version is 1.1.5.1). It is now conformant + to the GNU Coding Standards, except that + a functioning 3DLDF.info cannot be generated from + 3DLDF.texi. The + distribution now includes a configure script, + Makefile.in files, and other files generated by Autoconf and + Automake. Recompilation is now handled by make rather than + the auxilliary program 3DLDFcpl. The files + 3DLDFcpl.web and 3DLDFprc.web have been removed from the + distribution. + +

The extension of the C++ + files generated by ctangle is + changed from c to cxx before they are compiled. + After ctangle is run on a CWEB file, <filename>.c + is compared to the old <filename>.cxx using diff. + Whitespace, comments, and #line preprocessor commands are + ignored. The <filename>.c is only renamed to + <filename>.cxx and compiled if they differ. This way, + changes to the TeX text only in a CWEB file no longer cause + recompilation and relinking. + +

The main Texinfo file is now called 3DLDF.texi. It was formerly + called 3DLDFman.texi. This is because Automake expects this + name. For this reason, the CWEB + file passed as an argument to cweave has been renamed + 3DLDFprg.web. It was formerly called 3DLDF.web. + + + + + + +

+ +


+ Next: , + Previous: Changes, + Up: Top + +
+ +

Bibliography

+ + + + + + + +

Cundy, H. Martyn and A.P. Rollet. + Mathematical Models. + Oxford 1961. + Oxford University Press. + +

     Unfortunately out of print.
+ 
+
+ 
+ 
+ +

Finston, Laurence D. + 3DLDF: The Program. + Göttingen 2003. +

+ 
+ 
+ +

Fischer, Gerd. + Ebene algebraische Kurven. + Vieweg Studium. Aufbaukurs Mathematik. + Friedr. Vieweg & Sohn Verlagsgesellschaft mbH. + Braunschweig/Wiesbaden 1994. +

+ 
+ 
+ +

Gill, Robert W. + Creative Perspective. + London 1975. + Thames and Hudson Ltd. + ISBN 0-500-27056-2. +

+ 
+ 
+ +

Harbison, Samuel P., and Guy L. Steele Jr. + C, A Reference Manual. + Prentice Hall. + Englewood Cliffs, New Jersey 1995. + ISBN 0-13-326232-4 {Case}. + ISBN~0-13-326224-3 {Paperback}. +

+ 
+ 
+ +

Hobby, John D. + Smooth, Easy to Compute Interpolating Splines. + Discrete and Computational Geometery 1(2). + Springer-Verlag. + New York 1986. +

+ 
+ 
+ +

Hobby, John D. + A User's Manual for MetaPost. + AT & T Bell Laboratories. + Murray Hill, NJ. No date. +

+ 
+ 
+ +

Jones, Huw. + Computer Graphics through Key Mathematics. + Springer-Verlag London Limited 2001. + ISBN 1-85233-422-3. +

+ 
+ 
+ +

Knuth, Donald Ervin. + Metafont: The Program. Computers and Typesetting; D. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. + ISBN 0-201-13438-1. +

+ 
+ 
+ +

Knuth, Donald Ervin. + The METAFONTbook. + Computers and Typesetting; C. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. +

+ 
+ 
+ +

Knuth, Donald Ervin. + TeX: The Program. Computers and Typesetting; B. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. + ISBN 0-201-13437-3. +

+ 
+ 
+ +

Knuth, Donald E. The TeXbook. + Computers and Typesetting; A. + Addison Wesley Publishing Company, Inc. + Reading, Massachusetts 1986. +

+ 
+ 
+ +

Knuth, Donald E. and Silvio Levy. + The CWEB System of Structured Documentation. + Version 3.64—February 2002. +

+ 
+ 
+ +

Rokicki, Tomas. + Dvips: A DVI-to-PostScript Translator + for version 5.66a. + February 1997. + http://dante.ctan.org/CTAN/dviware/dvips/ +

+ 
+ 
+ +

Salomon, David. + Computer Graphics and Geometric Modeling. + Berlin 1999. + Springer-Verlag. + ISBN: 0-387-98682-0. +

+ 
+ 
+ +

Stallman, Richard M. and Roland McGrath. + GNU Make. A Program for Directing Recompilation. + make Version 3.79. + Boston 2000. + Free Software Foundation, Inc. + ISBN: 1-882114-80-9. +

+ 
+ 
+ +

Stallman, Richard M. + Using and Porting the GNU Compiler Collection. + For GCC Version 3.3.2. + Boston 2003. + Free Software Foundation, Inc. +

+ 
+ 
+ +

Stroustrup, Bjarne. + The C++ + Programming Language. + Special Edition. + Reading, Massachusetts 2000. + Addison-Wesley. + ISBN 0-201-70073-5. +

+ 
+ 
+ +

Stroustrup, Bjarne. + The Design and Evolution of C++ + . + Reading, Massachusetts 1994. + Addison-Wesley Publishing Company. + ISBN 0-201-54330-3. +

+ 
+ 
+ +

Vredeman de Vries, Jan. + Perspective. + New York 1968. + Dover Publications, Inc. + Standard Book Number: 486-21086-4. + +

     The beautiful perspective constructions in this volume are taken from
+      the original work, first published by Henricus Hondius in Leiden in 1604
+      and 1605.
+ 
+
+ 
+ 
+ +

White, Gwen. + Perspective. A Guide for Artists, Architects and Designers. + London 1968 and 1982. + B T Batsford Ltd. + ISBN 0-7134-3412-0. + +

+ +


+ Next: , + Previous: Bibliography, + Up: Top + +
+ +

Appendix A GNU Free Documentation License

+ + +
Version 1.3, 3 November 2008
+ + + +
     Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+      http://fsf.org/
+      
+      Everyone is permitted to copy and distribute verbatim copies
+      of this license document, but changing it is not allowed.
+ 
+
    +
  1. PREAMBLE + +

    The purpose of this License is to make a manual, textbook, or other + functional and useful document free in the sense of freedom: to + assure everyone the effective freedom to copy and redistribute it, + with or without modifying it, either commercially or noncommercially. + Secondarily, this License preserves for the author and publisher a way + to get credit for their work, while not being considered responsible + for modifications made by others. + +

    This License is a kind of “copyleft”, which means that derivative + works of the document must themselves be free in the same sense. It + complements the GNU General Public License, which is a copyleft + license designed for free software. + +

    We have designed this License in order to use it for manuals for free + software, because free software needs free documentation: a free + program should come with manuals providing the same freedoms that the + software does. But this License is not limited to software manuals; + it can be used for any textual work, regardless of subject matter or + whether it is published as a printed book. We recommend this License + principally for works whose purpose is instruction or reference. + +

  2. APPLICABILITY AND DEFINITIONS + +

    This License applies to any manual or other work, in any medium, that + contains a notice placed by the copyright holder saying it can be + distributed under the terms of this License. Such a notice grants a + world-wide, royalty-free license, unlimited in duration, to use that + work under the conditions stated herein. The “Document”, below, + refers to any such manual or work. Any member of the public is a + licensee, and is addressed as “you”. You accept the license if you + copy, modify or distribute the work in a way requiring permission + under copyright law. + +

    A “Modified Version” of the Document means any work containing the + Document or a portion of it, either copied verbatim, or with + modifications and/or translated into another language. + +

    A “Secondary Section” is a named appendix or a front-matter section + of the Document that deals exclusively with the relationship of the + publishers or authors of the Document to the Document's overall + subject (or to related matters) and contains nothing that could fall + directly within that overall subject. (Thus, if the Document is in + part a textbook of mathematics, a Secondary Section may not explain + any mathematics.) The relationship could be a matter of historical + connection with the subject or with related matters, or of legal, + commercial, philosophical, ethical or political position regarding + them. + +

    The “Invariant Sections” are certain Secondary Sections whose titles + are designated, as being those of Invariant Sections, in the notice + that says that the Document is released under this License. If a + section does not fit the above definition of Secondary then it is not + allowed to be designated as Invariant. The Document may contain zero + Invariant Sections. If the Document does not identify any Invariant + Sections then there are none. + +

    The “Cover Texts” are certain short passages of text that are listed, + as Front-Cover Texts or Back-Cover Texts, in the notice that says that + the Document is released under this License. A Front-Cover Text may + be at most 5 words, and a Back-Cover Text may be at most 25 words. + +

    A “Transparent” copy of the Document means a machine-readable copy, + represented in a format whose specification is available to the + general public, that is suitable for revising the document + straightforwardly with generic text editors or (for images composed of + pixels) generic paint programs or (for drawings) some widely available + drawing editor, and that is suitable for input to text formatters or + for automatic translation to a variety of formats suitable for input + to text formatters. A copy made in an otherwise Transparent file + format whose markup, or absence of markup, has been arranged to thwart + or discourage subsequent modification by readers is not Transparent. + An image format is not Transparent if used for any substantial amount + of text. A copy that is not “Transparent” is called “Opaque”. + +

    Examples of suitable formats for Transparent copies include plain + ascii without markup, Texinfo input format, LaTeX input + format, SGML or XML using a publicly available + DTD, and standard-conforming simple HTML, + PostScript or PDF designed for human modification. Examples + of transparent image formats include PNG, XCF and + JPG. Opaque formats include proprietary formats that can be + read and edited only by proprietary word processors, SGML or + XML for which the DTD and/or processing tools are + not generally available, and the machine-generated HTML, + PostScript or PDF produced by some word processors for + output purposes only. + +

    The “Title Page” means, for a printed book, the title page itself, + plus such following pages as are needed to hold, legibly, the material + this License requires to appear in the title page. For works in + formats which do not have any title page as such, “Title Page” means + the text near the most prominent appearance of the work's title, + preceding the beginning of the body of the text. + +

    The “publisher” means any person or entity that distributes copies + of the Document to the public. + +

    A section “Entitled XYZ” means a named subunit of the Document whose + title either is precisely XYZ or contains XYZ in parentheses following + text that translates XYZ in another language. (Here XYZ stands for a + specific section name mentioned below, such as “Acknowledgements”, + “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” + of such a section when you modify the Document means that it remains a + section “Entitled XYZ” according to this definition. + +

    The Document may include Warranty Disclaimers next to the notice which + states that this License applies to the Document. These Warranty + Disclaimers are considered to be included by reference in this + License, but only as regards disclaiming warranties: any other + implication that these Warranty Disclaimers may have is void and has + no effect on the meaning of this License. + +

  3. VERBATIM COPYING + +

    You may copy and distribute the Document in any medium, either + commercially or noncommercially, provided that this License, the + copyright notices, and the license notice saying this License applies + to the Document are reproduced in all copies, and that you add no other + conditions whatsoever to those of this License. You may not use + technical measures to obstruct or control the reading or further + copying of the copies you make or distribute. However, you may accept + compensation in exchange for copies. If you distribute a large enough + number of copies you must also follow the conditions in section 3. + +

    You may also lend copies, under the same conditions stated above, and + you may publicly display copies. + +

  4. COPYING IN QUANTITY + +

    If you publish printed copies (or copies in media that commonly have + printed covers) of the Document, numbering more than 100, and the + Document's license notice requires Cover Texts, you must enclose the + copies in covers that carry, clearly and legibly, all these Cover + Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on + the back cover. Both covers must also clearly and legibly identify + you as the publisher of these copies. The front cover must present + the full title with all words of the title equally prominent and + visible. You may add other material on the covers in addition. + Copying with changes limited to the covers, as long as they preserve + the title of the Document and satisfy these conditions, can be treated + as verbatim copying in other respects. + +

    If the required texts for either cover are too voluminous to fit + legibly, you should put the first ones listed (as many as fit + reasonably) on the actual cover, and continue the rest onto adjacent + pages. + +

    If you publish or distribute Opaque copies of the Document numbering + more than 100, you must either include a machine-readable Transparent + copy along with each Opaque copy, or state in or with each Opaque copy + a computer-network location from which the general network-using + public has access to download using public-standard network protocols + a complete Transparent copy of the Document, free of added material. + If you use the latter option, you must take reasonably prudent steps, + when you begin distribution of Opaque copies in quantity, to ensure + that this Transparent copy will remain thus accessible at the stated + location until at least one year after the last time you distribute an + Opaque copy (directly or through your agents or retailers) of that + edition to the public. + +

    It is requested, but not required, that you contact the authors of the + Document well before redistributing any large number of copies, to give + them a chance to provide you with an updated version of the Document. + +

  5. MODIFICATIONS + +

    You may copy and distribute a Modified Version of the Document under + the conditions of sections 2 and 3 above, provided that you release + the Modified Version under precisely this License, with the Modified + Version filling the role of the Document, thus licensing distribution + and modification of the Modified Version to whoever possesses a copy + of it. In addition, you must do these things in the Modified Version: + +

      +
    1. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. + +
    2. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. + +
    3. State on the Title page the name of the publisher of the + Modified Version, as the publisher. + +
    4. Preserve all the copyright notices of the Document. + +
    5. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. + +
    6. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. + +
    7. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. + +
    8. Include an unaltered copy of this License. + +
    9. Preserve the section Entitled “History”, Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled “History” in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. + +
    10. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the “History” section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. + +
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve + the Title of the section, and preserve in the section all the + substance and tone of each of the contributor acknowledgements and/or + dedications given therein. + +
    12. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. + +
    13. Delete any section Entitled “Endorsements”. Such a section + may not be included in the Modified Version. + +
    14. Do not retitle any existing section to be Entitled “Endorsements” or + to conflict in title with any Invariant Section. + +
    15. Preserve any Warranty Disclaimers. +
    + +

    If the Modified Version includes new front-matter sections or + appendices that qualify as Secondary Sections and contain no material + copied from the Document, you may at your option designate some or all + of these sections as invariant. To do this, add their titles to the + list of Invariant Sections in the Modified Version's license notice. + These titles must be distinct from any other section titles. + +

    You may add a section Entitled “Endorsements”, provided it contains + nothing but endorsements of your Modified Version by various + parties—for example, statements of peer review or that the text has + been approved by an organization as the authoritative definition of a + standard. + +

    You may add a passage of up to five words as a Front-Cover Text, and a + passage of up to 25 words as a Back-Cover Text, to the end of the list + of Cover Texts in the Modified Version. Only one passage of + Front-Cover Text and one of Back-Cover Text may be added by (or + through arrangements made by) any one entity. If the Document already + includes a cover text for the same cover, previously added by you or + by arrangement made by the same entity you are acting on behalf of, + you may not add another; but you may replace the old one, on explicit + permission from the previous publisher that added the old one. + +

    The author(s) and publisher(s) of the Document do not by this License + give permission to use their names for publicity for or to assert or + imply endorsement of any Modified Version. + +

  6. COMBINING DOCUMENTS + +

    You may combine the Document with other documents released under this + License, under the terms defined in section 4 above for modified + versions, provided that you include in the combination all of the + Invariant Sections of all of the original documents, unmodified, and + list them all as Invariant Sections of your combined work in its + license notice, and that you preserve all their Warranty Disclaimers. + +

    The combined work need only contain one copy of this License, and + multiple identical Invariant Sections may be replaced with a single + copy. If there are multiple Invariant Sections with the same name but + different contents, make the title of each such section unique by + adding at the end of it, in parentheses, the name of the original + author or publisher of that section if known, or else a unique number. + Make the same adjustment to the section titles in the list of + Invariant Sections in the license notice of the combined work. + +

    In the combination, you must combine any sections Entitled “History” + in the various original documents, forming one section Entitled + “History”; likewise combine any sections Entitled “Acknowledgements”, + and any sections Entitled “Dedications”. You must delete all + sections Entitled “Endorsements.” + +

  7. COLLECTIONS OF DOCUMENTS + +

    You may make a collection consisting of the Document and other documents + released under this License, and replace the individual copies of this + License in the various documents with a single copy that is included in + the collection, provided that you follow the rules of this License for + verbatim copying of each of the documents in all other respects. + +

    You may extract a single document from such a collection, and distribute + it individually under this License, provided you insert a copy of this + License into the extracted document, and follow this License in all + other respects regarding verbatim copying of that document. + +

  8. AGGREGATION WITH INDEPENDENT WORKS + +

    A compilation of the Document or its derivatives with other separate + and independent documents or works, in or on a volume of a storage or + distribution medium, is called an “aggregate” if the copyright + resulting from the compilation is not used to limit the legal rights + of the compilation's users beyond what the individual works permit. + When the Document is included in an aggregate, this License does not + apply to the other works in the aggregate which are not themselves + derivative works of the Document. + +

    If the Cover Text requirement of section 3 is applicable to these + copies of the Document, then if the Document is less than one half of + the entire aggregate, the Document's Cover Texts may be placed on + covers that bracket the Document within the aggregate, or the + electronic equivalent of covers if the Document is in electronic form. + Otherwise they must appear on printed covers that bracket the whole + aggregate. + +

  9. TRANSLATION + +

    Translation is considered a kind of modification, so you may + distribute translations of the Document under the terms of section 4. + Replacing Invariant Sections with translations requires special + permission from their copyright holders, but you may include + translations of some or all Invariant Sections in addition to the + original versions of these Invariant Sections. You may include a + translation of this License, and all the license notices in the + Document, and any Warranty Disclaimers, provided that you also include + the original English version of this License and the original versions + of those notices and disclaimers. In case of a disagreement between + the translation and the original version of this License or a notice + or disclaimer, the original version will prevail. + +

    If a section in the Document is Entitled “Acknowledgements”, + “Dedications”, or “History”, the requirement (section 4) to Preserve + its Title (section 1) will typically require changing the actual + title. + +

  10. TERMINATION + +

    You may not copy, modify, sublicense, or distribute the Document + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense, or distribute it is void, and + will automatically terminate your rights under this License. + +

    However, if you cease all violation of this License, then your license + from a particular copyright holder is reinstated (a) provisionally, + unless and until the copyright holder explicitly and finally + terminates your license, and (b) permanently, if the copyright holder + fails to notify you of the violation by some reasonable means prior to + 60 days after the cessation. + +

    Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from that + copyright holder, and you cure the violation prior to 30 days after + your receipt of the notice. + +

    Termination of your rights under this section does not terminate the + licenses of parties who have received copies or rights from you under + this License. If your rights have been terminated and not permanently + reinstated, receipt of a copy of some or all of the same material does + not give you any rights to use it. + +

  11. FUTURE REVISIONS OF THIS LICENSE + +

    The Free Software Foundation may publish new, revised versions + of the GNU Free Documentation License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. See + http://www.gnu.org/copyleft/. + +

    Each version of the License is given a distinguishing version number. + If the Document specifies that a particular numbered version of this + License “or any later version” applies to it, you have the option of + following the terms and conditions either of that specified version or + of any later version that has been published (not as a draft) by the + Free Software Foundation. If the Document does not specify a version + number of this License, you may choose any version ever published (not + as a draft) by the Free Software Foundation. If the Document + specifies that a proxy can decide which future versions of this + License can be used, that proxy's public statement of acceptance of a + version permanently authorizes you to choose that version for the + Document. + +

  12. RELICENSING + +

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any + World Wide Web server that publishes copyrightable works and also + provides prominent facilities for anybody to edit those works. A + public wiki that anybody can edit is an example of such a server. A + “Massive Multiauthor Collaboration” (or “MMC”) contained in the + site means any set of copyrightable works thus published on the MMC + site. + +

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 + license published by Creative Commons Corporation, a not-for-profit + corporation with a principal place of business in San Francisco, + California, as well as future copyleft versions of that license + published by that same organization. + +

    “Incorporate” means to publish or republish a Document, in whole or + in part, as part of another Document. + +

    An MMC is “eligible for relicensing” if it is licensed under this + License, and if all works that were first published under this License + somewhere other than this MMC, and subsequently incorporated in whole + or in part into the MMC, (1) had no cover texts or invariant sections, + and (2) were thus incorporated prior to November 1, 2008. + +

    The operator of an MMC Site may republish an MMC contained in the site + under CC-BY-SA on the same site at any time before August 1, 2009, + provided the MMC is eligible for relicensing. + +

+ +

ADDENDUM: How to use this License for your documents

+ +

To use this License in a document you have written, include a copy of + the License in the document and put the following copyright and + license notices just after the title page: + +

       Copyright (C)  year  your name.
+        Permission is granted to copy, distribute and/or modify this document
+        under the terms of the GNU Free Documentation License, Version 1.3
+        or any later version published by the Free Software Foundation;
+        with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+        Texts.  A copy of the license is included in the section entitled ``GNU
+        Free Documentation License''.
+ 
+

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, + replace the “with...Texts.” line with this: + +

         with the Invariant Sections being list their titles, with
+          the Front-Cover Texts being list, and with the Back-Cover Texts
+          being list.
+ 
+

If you have Invariant Sections without Cover Texts, or some other + combination of the three, merge those two alternatives to suit the + situation. + +

If your document contains nontrivial examples of program code, we + recommend releasing these examples in parallel under your choice of + free software license, such as the GNU General Public License, + to permit their use in free software. + + + + + + + + + + + + + +

+ +


+ Next: , + Previous: GNU Free Documentation License, + Up: Top + +
+ +

Data Type and Variable Index

+ + + + + + +
+ +


+ Next: , + Previous: Data Type and Variable Index, + Up: Top + +
+ +

Function Index

+ + + + + + + + +
+ +


+ Previous: Function Index, + Up: Top + +
+ +

Concept Index

+ + + +
+
+

Footnotes

[1] ctangle creates + <filename>.c from + <filename>.web, + so the compiler must compile the C++ + files + using the -x c++ option. Otherwise, it would handle them as if + they contained C code.

+ +

[2] If you want to try generating the illustrations yourself, you + can save a little run-time by calling tex 3DLDF.texi the + first time, rather than texi2dvi. The latter program runs + TeX twice, because it needs two passes in order to generate the + contents, indexing, and cross reference information (and maybe some + other things, too).

+ +

[3] Knuth, Donald E. The + TeXbook. Computers and Typesetting; A. + Addison-Wesley Publishing Company. Reading, Massachusetts 1986.

+ +

[4] Rokicki, Tomas. Dvips: A + DVI-to-PostScript Translator February 1997. Available from CTAN. + See Sources of Information.

+ +

[5] “<...> + METAFONT deals only with numbers in a limited + range: A numeric token must be less than 4096, and its value is always + rounded to the nearest multiple of + 1 / 65536.” Knuth, The METAFONTbook, p. 50. +

+ +

[6] Scan conversion is the process of digitizing geometric + data. The ultimate result is a + 2 X 2 + map of pixels, which can be used for printing or representing the projection on a + computer screen. The number of pixels per a given unit of measurement + is the resolution of a given output device, e.g., 300 pixels per inch.

+ +

[7] Knuth, The METAFONTbook, Chapter 14, p. 127.

+ +

[8] Flex is a program for generating text scanners and Bison is a + parser generator. They are available from + http://www.gnu.org.

+ +

[9] Affine transformations are operations + that have the property that parallelity of + lines is maintained. That is, if two lines (each determined by two + points) are parallel before the transformation, they will also be + parallel after + the transformation. Affine transformations are discussed in many books + about computer graphics and geometry. For 3DLDF, I've mostly used + Jones, Computer Graphics through Key Mathematics and Salomon, + Computer Graphics and Geometric Modeling.

+ +

[10] I try to avoid the use of + preprocessor macros as much as possible, for the reasons given by + Stroustrup in the The C++ + Programming Language, + section + 7.8, + pp. 160–163, and + Design and Evolution of C++ + , Chapter 18, pp. 423–426. + However, conditional compilation is one of + the tasks that only the preprocessor can perform.

+ +

[11] It is unfortunate that + the terms “array”, “matrix”, and “vector” have different meanings + in C++ + and in normal mathematical usage. However, in practice, these + discrepancies turn out not to cause many problems. Stroustrup, + The C++ + Programming Language, section + 22.4, p. 662.

+ +

[12] In fact, none of the operations for + transformations require all of the elements of a + 4 X 4 + matrix. In many + 3D graphics programs, the matrix operations are modified to use smaller + transformation matrices, which reduces the storage requirements of the + program. This is a bit tricky, because the affine transformations and + the perspective transformation use different elements of the matrix. I + consider that the risk of something going wrong, possibly producing + hard-to-find bugs, outweighs any benefits from saving memory (which + is usually no longer at a premium, anyway). In addition, there may be + some interesting non-affine transformations that would be worth + implementing. Therefore, I've decided to + use full + 4 X 4 + matrices in 3DLDF.

+ +

[13] Pens are a concept from Metafont. In 3DLDF, + there is currently no type “Pen”. Pen arguments to functions + are simply strings, and are written unaltered to out_stream. + For more information about + Metafont's pens, see + Knuth, The Metafontbook, Chapter 4.

+ +

[14] Colors are declared in the + namespace Colors, so if you have + a “using” declaration in the function where you use + drawdot(), you can write “black” instead of + “Colors::black”. For more information about namespaces, see + Stroustrup, The C++ + Programming Language, Chapter 8.

+ +

[15] “A reference is an alternative name for an object. The + main use of references is for specifying arguments and return values for + functions in general and for overloaded operators (Chapter 11) in + particular.” Stroustrup, The C++ + Programming Language, + section + 5.5, p. 97.

+ +

[16] I believe that + counter-examples could probably constructed, but for the most common + cases, the principle applies.

+ +

[17] It's easy to forget to use Point* arguments, rather + than plain Point arguments, and to forget to end the list of + arguments with 0. If plain Point arguments are used, compilation + fails with GCC. With the DEC compiler, compilation succeeds, but a + memory fault error occurs at run-time. If the argument list doesn't end + in 0, neither compiler signals an error, but a memory fault error always + occurs at run-time.

+ +

[18] Knuth, The METAFONTbook, Chapter 14, p. 127.

+ +

[19] Namespaces are described in + Stroustrup, The C++ + Programming Language, Chapter 8.

+ +

[20] There are many books on linear perspective for artists. + I've found Gwen White's Perspective. A Guide for Artists, + Architects and Designers to be particularly good. Vredeman de Vries, + Perspective contains beautiful examples of perspective + constructions.

+ +

[21] (I believe the following to be correct, but I'm not entirely sure.) + Let vector v be the line of sight. By definition, the plane of + projection will be a plane p, such that vector v is normal to + p. Let q_0 and q_1 be planes such that + q_0 == q_1 or q_0 || q_1, and q_0 is + perpendicular to p. + It follows that q_1 is perpendicular to p. + Let l_0 and l_1 be lines, such that l_0 != l_1, + l_0 || l_1, l_0 lies within q_0, l_1 lies + within q_1, + l_0 is perpendicular to vector v, and l_1 is perpendicular + to vector v. + Under these circumstances, the projections of l_0 and l_1 + in p will also be parallel. +

+ +

[22] I believe this + to be true, but I'm not + certain.

+ +

[23] The books on computer graphics and the fairly elementary + mathematics books that I own or have referred to don't go into + intersections very deeply. One that does is + Fischer, Gerd. Ebene Algebraische Kurven, which is a bit over my + head.

+ +

[24] Stallman, Richard M. Using and Porting the GNU Compiler + Collection, p. 285.

+ +

[25] Hobby, A User's Manual for MetaPost, pp. 21–22.

+ +

[26] Rokicki, Dvips: A DVI-to-PostScript Translator, p. 24.

+ +

[27] Knuth, Donald E. The Metafontbook, p. 66.

+ +

[28] If your system supplies an unsigned integer type with the same + length as long double, then you can instantiate + get_second_largest<long double>() and call + ‘get_second_largest<long double>(LDBL_MAX)’. However, I doubt + that this amount of precision would be worthwhile. If it ever were + required, 3DLDF would have to be changed in other ways, too. In + particular, it would have to use more precise trigonometric functions + for rotations. See Accuracy.

+ +

[29] For that matter, I haven't really tested whether 0.00001 is a + good value when real is float.

+ +

[30] For a person, not in the sense of the program behaving + unpredictably.

+ +

[31] label() and dotlabel() + are currently only defined for Point and Path (and the + latter's derived classes), i.e., not for Solid and its derived + classes.

+ +

[32] Actually, it's printed to standard output + even if it is the empty string, you just don't see it.

+ +

[33] It's unlikely that Points will lie on a Plane, + unless the user constructs the case specially. + In [next figure] + , the coordinates for B and C were found by using + Plane::intersection_point(). + See Planes; Intersections.

+ +

[34] For that matter, I haven't really tested whether 0.00001 is a + good value when real is float.

+ +

[35] Stroustrup, The C++ + Programming Language, p. 96.

+ +

[36] It isn't sufficient to check whether a + Path consists of only two Points to determine whether it + is a line or not, since a connector with “curl” could cause it + to be non-linear. On the other hand, Paths containing only + colinear Points and the connector "--" are perfectly + legitimate lines. I'm in the process of changing all of the code that + tests for linearity by checking the value of line_switch, so that + it uses is_linear() instead. When I've done this, it may be + possible to eliminate line_switch. + See Path Reference; Data Members, and + Path Reference; Querying.

+ +

[37] Stroustrup, The C++ + Programming Language, p. 88.

+ +

[38] Where possible, I prefer to use the C++ + data + type string rather than char*, however it was necessary to + use char* here because 0 is not a valid string, even + though string may be implemented as char*, + and 0 must be a valid argument, since it is needed to indicate the end + of the argument list.

+ +

[39] Hobby, A User's Manual for MetaPost, p. 32.

+ +

[40] Knuth, The METAFONTbook, Chapter 4, p. 21ff. + Hobby, A User's Manual for MetaPost, p. 32.

+ +

[41] The usual interpretation of "" as a + position argument to a + labelling command would be to put it directly onto *(Label.pt), + which in this case would put it onto the arrowhead. Since this + will probably never be desirable, I've decided to use "" to + suppress drawing axes. Formerly, draw_axes() used three + additional arguments for this purpose.

+ +

[42] The following example shows only one Point per + line. In actual use, two Points are shown, but this causes + overfull boxes in Texinfo.

+ +

[43] Reg_Polygon and Rectangle are currently the only + classes derived from Polygon.

+ +

[44] If you don't + know what “overfull boxes” are, don't worry about it. It has to do with + TeX's line and page breaking algorithms. If you want to know more, + see Knuth, Donald E., The TeXbook.

+ +

[45] Albrecht Dürer invented this method of constructing polyhedra. + +

+ +

[46] The GNU Coding Standards are available at + http://www.gnu.org/prep/standards_toc.html.

+ +

[47] Automake is available for downloading from + http://ftp.gnu.org/gnu/automake/. The Automake website is at + http://www.gnu.org/software/automake/.

+ +

[48] Stroustrup, The C++ + Programming Language, + &sect;15.2 + “Multiple Inheritance”, pp. 390–92.

+ +

[49] Cundy and Rollet, Mathematical Models, Chapter 3, + “Polyhedra”, pp. 76–160.

+ +

[50] Huw Jones, + Computer Graphics through Key Mathematics, and + David Salomon, + Computer Graphics and Geometric Modeling, are my main sources of + information about spline curves.

+ +

[51] Jones, Huw. + Computer Graphics through Key Mathematics, p. 282.

+ +

[52] Knuth, Donald Ervin. + The METAFONTbook, p. 130, and + Hobby, John D. + Smooth, Easy to Compute Interpolating Splines. + Discrete and Computational Geometery 1(2).

+ +
+ + + diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF.info 3DLDF-2.0.3/doc/old_doc/3DLDF.info *** 3DLDF-2.0.2/doc/old_doc/3DLDF.info Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/old_doc/3DLDF.info Wed Nov 13 19:06:13 2013 *************** *** 0 **** --- 1,374 ---- + This is 3DLDF.info, produced by makeinfo version 4.13 from 3DLDF.texi. + + This is the 3DLDF User and Reference Manual, edition 1.1.5.1 for 3DLDF + 1.1.5.1. + This manual was last updated on 16 January 2004. + 3DLDF is a GNU package for three-dimensional drawing with MetaPost + output. The author is Laurence D. Finston. + + Copyright (C) 2003, 2004 , 2005, 2006, 2007, 2008, 2009, 2010, 2011, + 2012, 2013 The Free Software Foundation + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. A copy of the license is included in the + section entitled "GNU Free Documentation License". + + INFO-DIR-SECTION GNU packages + START-INFO-DIR-ENTRY + * 3DLDF: (3DLDF). 3D drawing with MetaPost output. + END-INFO-DIR-ENTRY + +  + Indirect: + 3DLDF.info-1: 959 + 3DLDF.info-2: 300631 + 3DLDF.info-3: 566065 +  + Tag Table: + (Indirect) + Node: Top959 + Node: Introduction10409 + Node: Sources of Information12848 + Node: About This Manual14155 + Node: Manual Conventions16999 + Node: Illustrations20097 + Ref: Illustrations-Footnote-125071 + Ref: Illustrations-Footnote-225267 + Node: CWEB Documentation25609 + Node: Metafont and MetaPost28050 + Ref: Metafont and MetaPost-Footnote-131637 + Ref: Metafont and MetaPost-Footnote-231771 + Ref: Metafont and MetaPost-Footnote-331905 + Node: Caveats32119 + Node: Accuracy32287 + Ref: Accuracy-Footnote-134427 + Ref: Accuracy-Footnote-234755 + Node: No Input Routine34810 + Ref: No Input Routine-Footnote-135807 + Node: Ports35942 + Node: Contributing to 3DLDF38563 + Node: Using 3DLDF39180 + Node: Points39697 + Node: Declaring and Initializing Points39893 + Node: Setting and Assigning to Points43954 + Node: Transforming Points45422 + Ref: Transforming Points-Footnote-146694 + Ref: Transforming Points-Footnote-247182 + Node: Shifting Points47513 + Node: Scaling Points49015 + Node: Shearing Points50000 + Node: Rotating Points51180 + Node: Transforms53795 + Ref: Transforms-Footnote-157507 + Ref: Transforms-Footnote-257794 + Node: Applying Transforms to Points Intro58543 + Node: Inverting Transforms60491 + Node: Drawing and Labeling Points62545 + Node: Drawing Points Intro62766 + Ref: Drawing Points Intro-Footnote-165619 + Ref: Drawing Points Intro-Footnote-265890 + Ref: Drawing Points Intro-Footnote-366184 + Node: Labeling Points Intro66468 + Node: Paths68305 + Ref: Paths-Footnote-170335 + Node: Declaring and Initializing Paths70457 + Ref: Declaring and Initializing Paths-Footnote-173741 + Ref: Declaring and Initializing Paths-Footnote-274167 + Node: Drawing and Filling Paths Intro74222 + Node: Plane Figures78026 + Node: Regular Polygons Getstart79415 + Node: Rectangles Getstart81785 + Node: Ellipses Getstart84426 + Node: Circles Getstart85777 + Node: Solid Figures86886 + Node: Cuboid Getstart87064 + Node: Polyhedron Getstart88434 + Node: Tetrahedron Getstart89697 + Node: Dodecahedron Getstart90223 + Node: Icosahedron Getstart91005 + Node: Pictures91667 + Node: Projections98286 + Ref: Projections-Footnote-199985 + Node: Parallel Projections100077 + Node: The Perspective Projection101833 + Ref: The Perspective Projection-Footnote-1105966 + Ref: The Perspective Projection-Footnote-2106234 + Node: Focuses Getstart106841 + Ref: Focuses Getstart-Footnote-1112144 + Node: Surface Hiding112205 + Node: Intersections120394 + Ref: Intersections-Footnote-1123540 + Node: Installing and Running 3DLDF123787 + Node: Installing 3DLDF124030 + Node: Template Functions125635 + Ref: Template Functions-Footnote-1127999 + Node: Running 3DLDF128085 + Node: Converting EPS Files133429 + Ref: Converting EPS Files-Footnote-1136732 + Ref: Converting EPS Files-Footnote-2136790 + Node: Converting EPS Files ELISP136855 + Node: Command Line Arguments139308 + Node: Typedefs and Utility Structures140258 + Node: Global Constants and Variables142495 + Ref: Global Constants and Variables-Footnote-1146934 + Node: Dynamic Allocation of Shapes146986 + Node: System Information148797 + Node: Endianness150292 + Node: Register Width152470 + Node: Get Second Largest Real153537 + Ref: Get Second Largest Real-Footnote-1154922 + Node: Color Reference155388 + Node: Color Data Members155792 + Node: Color Constructors and Setting Functions156853 + Node: Color Operators159290 + Node: Modifying Colors160670 + Node: Showing Colors161672 + Node: Querying Colors162124 + Node: Defining and Initializing Colors163256 + Node: Namespace Colors163873 + Node: Input and Output165628 + Node: I/O Global Variables165825 + Node: I/O Functions166832 + Node: Shape Reference168035 + Node: Shape Data Members169091 + Node: Shape Operators169743 + Node: Copying Shapes169960 + Node: Modifying Shapes170463 + Node: Affine Transformations for Shapes170982 + Node: Applying Transformations to Shapes171635 + Node: Clearing Shapes172126 + Node: Querying Shapes172583 + Node: Showing Shapes172881 + Node: Outputting Shapes173442 + Node: Transform Reference176595 + Node: Transform Data Members177242 + Node: Transform Global Variables and Constants177553 + Node: Transform Constructors178522 + Node: Transform Operators179517 + Node: Matrix Inversion184223 + Node: Setting Values Transforms184956 + Node: Querying Transforms185573 + Node: Returning Information for Transforms186853 + Ref: Returning Information for Transforms-Footnote-1188896 + Node: Showing Transforms189001 + Node: Affine Transformations for Transforms190089 + Ref: Affine Transformations for Transforms-Footnote-1196387 + Node: Alignment with an Axis for Transforms196465 + Node: Resetting Transforms198817 + Node: Cleaning Transforms199075 + Node: Label Reference199322 + Node: Label Data Members200733 + Node: Copying Labels202474 + Node: Outputting Labels203236 + Node: Picture Reference204167 + Node: Picture Data Members204580 + Ref: Picture Data Members-Footnote-1206478 + Node: Picture Global Variables206646 + Node: Picture Constructors206956 + Node: Picture Operators207579 + Node: Affine Transformations for Pictures209145 + Node: Modifying Pictures210743 + Node: Showing Pictures211583 + Ref: Showing Pictures-Footnote-1212797 + Node: Outputting Pictures212902 + Node: Picture Output Namespaces213101 + Node: Namespace Projections213337 + Node: Namespace Sorting214055 + Node: Picture Output Functions214630 + Node: Point Reference223267 + Node: Point Data Members224191 + Node: Point Typedefs and Utility Structures230530 + Node: Point Global Constants and Variables233113 + Node: Point Constructors and Setting Functions234053 + Node: Point Destructor236709 + Node: Point Operators237131 + Node: Copying Points242171 + Node: Querying Points242696 + Ref: Querying Points-Footnote-1244973 + Node: Returning Coordinates245229 + Node: Returning Information for Points250281 + Ref: Returning Information for Points-Footnote-1252552 + Node: Modifying Points252657 + Node: Affine Transformations for Points253901 + Node: Applying Transformations to Points259601 + Node: Projecting Points259989 + Node: Vector Operations261023 + Node: Points and Lines266309 + Node: Point Intersections270326 + Node: Point Drawing Functions272236 + Node: Labelling Points277318 + Node: Showing Points280566 + Node: Outputting Points281926 + Node: Focus Reference284941 + Node: Focus Data Members285468 + Node: Focus Global Variables287178 + Node: Focus Constructors and Setting Functions288191 + Node: Focus Operators289962 + Node: Modifying Focuses290228 + Node: Querying Focuses290522 + Node: Showing Focuses291631 + Node: Line Reference292154 + Node: Line Data Members292805 + Node: Line Global Constants293140 + Node: Line Constructors293405 + Node: Line Operators294103 + Node: Get Path294322 + Node: Showing294650 + Node: Plane Reference295553 + Node: Planes Data Members296541 + Node: Planes Global Constants297050 + Node: Planes Constructors297494 + Node: Planes Operators299357 + Node: Planes Returning Information300631 + Node: Plane Intersections302821 + Node: Planes Showing306357 + Node: Path Reference307338 + Node: Path Data Members308013 + Ref: Path Data Members-Footnote-1313122 + Node: Path Constructors and Setting Functions313182 + Ref: Path Constructors and Setting Functions-Footnote-1319141 + Ref: Path Constructors and Setting Functions-Footnote-2319780 + Ref: Path Constructors and Setting Functions-Footnote-3319840 + Node: Path Destructor320154 + Node: Path Operators320855 + Node: Appending to Paths322616 + Node: Copying Paths323755 + Node: Clearing Paths324344 + Node: Modifying Paths325156 + Node: Affine Transformations for Paths327567 + Node: Aligning Paths with an Axis332364 + Node: Applying Transformations to Paths335512 + Node: Drawing and Filling Paths335949 + Ref: Drawing and Filling Paths-Footnote-1352861 + Ref: Drawing and Filling Paths-Footnote-2352915 + Ref: Drawing and Filling Paths-Footnote-3353017 + Node: Labelling Paths353375 + Node: Showing Paths354852 + Ref: Showing Paths-Footnote-1358492 + Node: Querying Paths358638 + Node: Outputting Paths364673 + Node: Path Intersections367183 + Node: Polygon Reference368672 + Node: Polygon Data Members369324 + Node: Polygon Operators369688 + Node: Querying Polygons370121 + Node: Affine Transformations for Polygons370535 + Node: Polygon Intersections372665 + Ref: Polygon Intersections-Footnote-1377821 + Node: Regular Polygon Reference377914 + Node: Regular Polygon Data Members378942 + Node: Regular Polygon Constructors and Setting Functions380002 + Node: Regular Polygon Operators382517 + Node: Querying Regular Polygons382836 + Node: Circles for Regular Polygons383098 + Node: Rectangle Reference385279 + Node: Rectangle Data Members386301 + Node: Rectangle Constructors and Setting Functions387243 + Node: Rectangle Operators389764 + Node: Returning Points for Rectangles390076 + Node: Querying Rectangles390559 + Node: Ellipses for Rectangles391260 + Node: Regular Closed Plane Curve Reference392949 + Ref: Regular Closed Plane Curve Reference-Footnote-1395324 + Node: Regular Closed Plane Curve Data Members395523 + Node: Querying Regular Closed Plane Curves395983 + Node: Regular Closed Plane Curve Intersections398656 + Node: Regular Closed Plane Curve Segments401154 + Node: Ellipse Reference403602 + Node: Ellipse Data Members404242 + Node: Ellipse Constructors and Setting Functions405991 + Node: Performing Transformations on Ellipses408213 + Node: Ellipse Operators409347 + Node: Labeling Ellipses409867 + Node: Affine Transformations for Ellipses410770 + Node: Querying Ellipses412959 + Node: Returning Elements and Information for Ellipses414255 + Node: Ellipse Intersections418752 + Node: Solving Ellipses425230 + Node: Rectangles for Ellipses427532 + Node: Circle Reference429545 + Node: Circle Data Members430334 + Node: Circle Constructors and Setting Functions430585 + Node: Circle Operators432391 + Node: Querying Circles432939 + Node: Circle Intersections433706 + Node: Pattern Reference434811 + Node: Plane Tesselations435186 + Node: Roulettes and Involutes440809 + Node: Epicycloids441790 + Node: Solid Reference444739 + Node: Solid Data Members445533 + Node: Solid Constructors and Setting Functions447726 + Node: Solid Destructor448751 + Node: Solid Operators449173 + Node: Copying Solids449656 + Node: Setting Solid Members450242 + Node: Querying Solids450685 + Node: Returning Elements and Information Solids451348 + Node: Getting Shape Centers Solids451828 + Node: Getting Shapes Solids454229 + Node: Showing Solids457296 + Node: Affine Transformations for Solids458183 + Node: Applying Transformations to Solids459110 + Node: Outputting Solids459464 + Node: Drawing and Filling Solids461549 + Node: Clearing Solids466357 + Node: Faced Solid Reference466893 + Node: Solid_Faced Data Members467422 + Node: Cuboid Reference467855 + Node: Cuboid Data Members468214 + Node: Cuboid Constructors and Setting Functions468690 + Node: Cuboid Operators470613 + Node: Polyhedron Reference470941 + Node: Polyhedron Data Members471599 + Node: Regular Platonic Polyhedra472471 + Node: Tetrahedron473112 + Node: Tetrahedron Data Members473498 + Node: Tetrahedron Constructors and Setting Functions474195 + Node: Tetrahedron Net475658 + Ref: Tetrahedron Net-Footnote-1478599 + Node: Dodecahedron478671 + Node: Dodecahedron Data Members479098 + Node: Dodecahedron Constructors and Setting Functions479591 + Node: Dodecahedron Net480686 + Node: Icosahedron482695 + Node: Icosahedron Data Members483095 + Node: Icosahedron Constructors and Setting Functions483584 + Node: Icosahedron Net484644 + Node: Semi-Regular Archimedean Polyhedra486629 + Node: Truncated Octahedron487037 + Node: Truncated Octahedron Data Members487574 + Node: Truncated Octahedron Constructors and Setting Functions488287 + Node: Truncated Octahedron Net489338 + Node: Utility Functions490293 + Node: Perspective Functions491642 + Node: Adding a File493810 + Ref: Adding a File-Footnote-1498317 + Ref: Adding a File-Footnote-2498413 + Node: Future Plans498569 + Node: Geometry499337 + Ref: Geometry-Footnote-1501422 + Ref: Geometry-Footnote-2501524 + Node: Curves and Surfaces501609 + Ref: Curves and Surfaces-Footnote-1503116 + Ref: Curves and Surfaces-Footnote-2503295 + Ref: Curves and Surfaces-Footnote-3503367 + Node: Shadows503534 + Node: Multi-Threading505479 + Node: Changes506611 + Node: Changes in 3DLDF 1.1.5.1506919 + Node: Changes in 3DLDF 1.1.5507538 + Node: Changes in 3DLDF 1.1.4.2510122 + Node: Changes in 3DLDF 1.1.4.1510365 + Node: Changes in 3DLDF 1.1.4510585 + Node: Initial version511284 + Node: Bibliography512696 + Node: GNU Free Documentation License515808 + Node: Data Type and Variable Index540996 + Node: Function Index566065 + Node: Concept Index609893 +  + End Tag Table Binary files 3DLDF-2.0.2/doc/old_doc/3DLDF.pdf and 3DLDF-2.0.3/doc/old_doc/3DLDF.pdf differ diff -rc2P 3DLDF-2.0.2/doc/old_doc/3DLDF.ps 3DLDF-2.0.3/doc/old_doc/3DLDF.ps *** 3DLDF-2.0.2/doc/old_doc/3DLDF.ps Thu Nov 7 13:47:43 2013 --- 3DLDF-2.0.3/doc/old_doc/3DLDF.ps Wed Nov 13 19:06:41 2013 *************** *** 2,6 **** %%Creator: dvips(k) 5.991 Copyright 2011 Radical Eye Software %%Title: 3DLDF.dvi ! %%CreationDate: Thu Nov 7 14:47:43 2013 %%Pages: 306 %%PageOrder: Ascend --- 2,6 ---- %%Creator: dvips(k) 5.991 Copyright 2011 Radical Eye Software %%Title: 3DLDF.dvi ! %%CreationDate: Wed Nov 13 20:06:41 2013 %%Pages: 306 %%PageOrder: Ascend *************** *** 14,18 **** %DVIPSCommandLine: dvips -o 3DLDF.ps 3DLDF.dvi %DVIPSParameters: dpi=600 ! %DVIPSSource: TeX output 2013.11.07:1447 %%BeginProcSet: tex.pro 0 0 %! --- 14,18 ---- %DVIPSCommandLine: dvips -o 3DLDF.ps 3DLDF.dvi %DVIPSParameters: dpi=600 ! %DVIPSSource: TeX output 2013.11.13:2006 %%BeginProcSet: tex.pro 0 0 %! diff -rc2P 3DLDF-2.0.2/doc/old_doc/Makefile.am 3DLDF-2.0.3/doc/old_doc/Makefile.am *** 3DLDF-2.0.2/doc/old_doc/Makefile.am Mon Nov 4 17:01:37 2013 --- 3DLDF-2.0.3/doc/old_doc/Makefile.am Wed Nov 13 13:15:56 2013 *************** *** 47,51 **** ! all: 3DLDF.dvi 3DLDF.ps 3DLDF.pdf 3DLDF.info 3DLDF.html html-split 3dldf_TEXINFOS = 3DLDF.texi intro.texi contrib.texi using.texi gspoint.texi gstranpt.texi \ --- 47,54 ---- ! # html-split ! # 3DLDF.dvi 3DLDF.ps 3DLDF.pdf 3DLDF.info 3DLDF.html ! ! all: 3dldf_TEXINFOS = 3DLDF.texi intro.texi contrib.texi using.texi gspoint.texi gstranpt.texi \ *************** *** 107,112 **** ps2pdf 3DLDF.ps ! EXTRA_DIST = 3DLDF.ps 3DLDF.pdf 3DLDF.dvi \ ! ChangeLog.dev $(3dldf_TEXINFOS) \ $(3dldf_EPS) $(3dldf_PNG) --- 110,115 ---- ps2pdf 3DLDF.ps ! EXTRA_DIST = 3DLDF.ps 3DLDF.pdf 3DLDF.dvi 3DLDF.info 3DLDF.html \ ! ChangeLog.dev $(3dldf_TEXINFOS) 3DLDF/ \ $(3dldf_EPS) $(3dldf_PNG) *************** *** 115,139 **** echo "distdir = $(distdir)" ! .PHONY : ps ! ps: 3DLDF.ps - 3DLDF.ps : 3DLDF.dvi - @echo Running \"dvips -o 3DLDF.ps 3DLDF.dvi\" - dvips -o 3DLDF.ps 3DLDF.dvi ! 3DLDF.dvi: $(3dldf_TEXINFOS) ! texi2dvi 3DLDF.texi ! 3DLDF.html: $(3dldf_TEXINFOS) ! makeinfo --html --no-split 3DLDF.texi ! 3DLDF.info: $(3dldf_TEXINFOS) ! makeinfo 3DLDF.texi ! .PHONY: html-split - html-split: $(3dldf_TEXINFOS) - makeinfo --html 3DLDF.texi .PHONY : purge --- 118,143 ---- echo "distdir = $(distdir)" ! # .PHONY : ps ! # ps: 3DLDF.ps ! ! # 3DLDF.ps : 3DLDF.dvi ! # @echo Running \"dvips -o 3DLDF.ps 3DLDF.dvi\" ! # dvips -o 3DLDF.ps 3DLDF.dvi + # 3DLDF.dvi: $(3dldf_TEXINFOS) + # texi2dvi 3DLDF.texi ! # 3DLDF.html: $(3dldf_TEXINFOS) ! # makeinfo --html --no-split 3DLDF.texi ! # 3DLDF.info: $(3dldf_TEXINFOS) ! # makeinfo 3DLDF.texi ! # .PHONY: html-split ! # html-split: $(3dldf_TEXINFOS) ! # makeinfo --html 3DLDF.texi .PHONY : purge diff -rc2P 3DLDF-2.0.2/doc/old_doc/Makefile.in 3DLDF-2.0.3/doc/old_doc/Makefile.in *** 3DLDF-2.0.2/doc/old_doc/Makefile.in Sun Nov 10 18:30:13 2013 --- 3DLDF-2.0.3/doc/old_doc/Makefile.in Fri Dec 13 12:29:28 2013 *************** *** 59,62 **** --- 59,65 ---- #### Laurence.Finston@gmx.de + + # html-split + # 3DLDF.dvi 3DLDF.ps 3DLDF.pdf 3DLDF.info 3DLDF.html VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' *************** *** 338,343 **** ./graphics/png/3DLDF1??.png ! EXTRA_DIST = 3DLDF.ps 3DLDF.pdf 3DLDF.dvi \ ! ChangeLog.dev $(3dldf_TEXINFOS) \ $(3dldf_EPS) $(3dldf_PNG) --- 341,346 ---- ./graphics/png/3DLDF1??.png ! EXTRA_DIST = 3DLDF.ps 3DLDF.pdf 3DLDF.dvi 3DLDF.info 3DLDF.html \ ! ChangeLog.dev $(3dldf_TEXINFOS) 3DLDF/ \ $(3dldf_EPS) $(3dldf_PNG) *************** *** 510,513 **** --- 513,518 ---- pdf-am: + ps: ps-am + ps-am: *************** *** 529,533 **** ! all: 3DLDF.dvi 3DLDF.ps 3DLDF.pdf 3DLDF.info 3DLDF.html html-split .PHONY: pdf --- 534,538 ---- ! all: .PHONY: pdf *************** *** 542,565 **** echo "distdir = $(distdir)" ! .PHONY : ps ! ps: 3DLDF.ps ! 3DLDF.ps : 3DLDF.dvi ! @echo Running \"dvips -o 3DLDF.ps 3DLDF.dvi\" ! dvips -o 3DLDF.ps 3DLDF.dvi ! 3DLDF.dvi: $(3dldf_TEXINFOS) ! texi2dvi 3DLDF.texi ! 3DLDF.html: $(3dldf_TEXINFOS) ! makeinfo --html --no-split 3DLDF.texi ! 3DLDF.info: $(3dldf_TEXINFOS) ! makeinfo 3DLDF.texi ! .PHONY: html-split ! html-split: $(3dldf_TEXINFOS) ! makeinfo --html 3DLDF.texi .PHONY : purge --- 547,570 ---- echo "distdir = $(distdir)" ! # .PHONY : ps ! # ps: 3DLDF.ps ! # 3DLDF.ps : 3DLDF.dvi ! # @echo Running \"dvips -o 3DLDF.ps 3DLDF.dvi\" ! # dvips -o 3DLDF.ps 3DLDF.dvi ! # 3DLDF.dvi: $(3dldf_TEXINFOS) ! # texi2dvi 3DLDF.texi ! # 3DLDF.html: $(3dldf_TEXINFOS) ! # makeinfo --html --no-split 3DLDF.texi ! # 3DLDF.info: $(3dldf_TEXINFOS) ! # makeinfo 3DLDF.texi ! # .PHONY: html-split ! # html-split: $(3dldf_TEXINFOS) ! # makeinfo --html 3DLDF.texi .PHONY : purge diff -rc2P 3DLDF-2.0.2/doc/texinfo.tex 3DLDF-2.0.3/doc/texinfo.tex *** 3DLDF-2.0.2/doc/texinfo.tex Thu Jan 1 00:00:00 1970 --- 3DLDF-2.0.3/doc/texinfo.tex Wed Nov 13 11:56:28 2013 *************** *** 0 **** --- 1,10145 ---- + % texinfo.tex -- TeX macros to handle Texinfo files. + % + % Load plain if necessary, i.e., if running under initex. + \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi + % + \def\texinfoversion{2013-09-11.11} + % + % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, + % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + % 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. + % + % This texinfo.tex file is free software: you can redistribute it and/or + % modify it under the terms of the GNU General Public License as + % published by the Free Software Foundation, either version 3 of the + % License, or (at your option) any later version. + % + % This texinfo.tex file is distributed in the hope that it will be + % useful, but WITHOUT ANY WARRANTY; without even the implied warranty + % of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + % General Public License for more details. + % + % You should have received a copy of the GNU General Public License + % along with this program. If not, see . + % + % As a special exception, when this file is read by TeX when processing + % a Texinfo source document, you may use the result without + % restriction. This Exception is an additional permission under section 7 + % of the GNU General Public License, version 3 ("GPLv3"). + % + % Please try the latest version of texinfo.tex before submitting bug + % reports; you can get the latest version from: + % http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or + % http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or + % http://www.gnu.org/software/texinfo/ (the Texinfo home page) + % The texinfo.tex in any given distribution could well be out + % of date, so if that's what you're using, please check. + % + % Send bug reports to bug-texinfo@gnu.org. Please include including a + % complete document in each bug report with which we can reproduce the + % problem. Patches are, of course, greatly appreciated. + % + % To process a Texinfo manual with TeX, it's most reliable to use the + % texi2dvi shell script that comes with the distribution. For a simple + % manual foo.texi, however, you can get away with this: + % tex foo.texi + % texindex foo.?? + % tex foo.texi + % tex foo.texi + % dvips foo.dvi -o # or whatever; this makes foo.ps. + % The extra TeX runs get the cross-reference information correct. + % Sometimes one run after texindex suffices, and sometimes you need more + % than two; texi2dvi does it as many times as necessary. + % + % It is possible to adapt texinfo.tex for other languages, to some + % extent. You can get the existing language-specific files from the + % full Texinfo distribution. + % + % The GNU Texinfo home page is http://www.gnu.org/software/texinfo. + + + \message{Loading texinfo [version \texinfoversion]:} + + % If in a .fmt file, print the version number + % and turn on active characters that we couldn't do earlier because + % they might have appeared in the input file name. + \everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + + \chardef\other=12 + + % We never want plain's \outer definition of \+ in Texinfo. + % For @tex, we can use \tabalign. + \let\+ = \relax + + % Save some plain tex macros whose names we will redefine. + \let\ptexb=\b + \let\ptexbullet=\bullet + \let\ptexc=\c + \let\ptexcomma=\, + \let\ptexdot=\. + \let\ptexdots=\dots + \let\ptexend=\end + \let\ptexequiv=\equiv + \let\ptexexclam=\! + \let\ptexfootnote=\footnote + \let\ptexgtr=> + \let\ptexhat=^ + \let\ptexi=\i + \let\ptexindent=\indent + \let\ptexinsert=\insert + \let\ptexlbrace=\{ + \let\ptexless=< + \let\ptexnewwrite\newwrite + \let\ptexnoindent=\noindent + \let\ptexplus=+ + \let\ptexraggedright=\raggedright + \let\ptexrbrace=\} + \let\ptexslash=\/ + \let\ptexstar=\* + \let\ptext=\t + \let\ptextop=\top + {\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode + + % If this character appears in an error message or help string, it + % starts a new line in the output. + \newlinechar = `^^J + + % Use TeX 3.0's \inputlineno to get the line number, for better error + % messages, but if we're using an old version of TeX, don't do anything. + % + \ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. + \else + \def\linenumber{l.\the\inputlineno:\space} + \fi + + % Set up fixed words for English if not already set. + \ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi + \ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi + \ifx\putworderror\undefined \gdef\putworderror{error}\fi + \ifx\putwordfile\undefined \gdef\putwordfile{file}\fi + \ifx\putwordin\undefined \gdef\putwordin{in}\fi + \ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi + \ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi + \ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi + \ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi + \ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi + \ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi + \ifx\putwordof\undefined \gdef\putwordof{of}\fi + \ifx\putwordon\undefined \gdef\putwordon{on}\fi + \ifx\putwordpage\undefined \gdef\putwordpage{page}\fi + \ifx\putwordsection\undefined \gdef\putwordsection{section}\fi + \ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi + \ifx\putwordsee\undefined \gdef\putwordsee{see}\fi + \ifx\putwordSee\undefined \gdef\putwordSee{See}\fi + \ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi + \ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi + % + \ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi + \ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi + \ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi + \ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi + \ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi + \ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi + \ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi + \ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi + \ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi + \ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi + \ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi + \ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi + % + \ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi + \ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi + \ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi + \ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi + \ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi + + % Since the category of space is not known, we have to be careful. + \chardef\spacecat = 10 + \def\spaceisspace{\catcode`\ =\spacecat} + + % sometimes characters are active, so we need control sequences. + \chardef\ampChar = `\& + \chardef\colonChar = `\: + \chardef\commaChar = `\, + \chardef\dashChar = `\- + \chardef\dotChar = `\. + \chardef\exclamChar= `\! + \chardef\hashChar = `\# + \chardef\lquoteChar= `\` + \chardef\questChar = `\? + \chardef\rquoteChar= `\' + \chardef\semiChar = `\; + \chardef\slashChar = `\/ + \chardef\underChar = `\_ + + % Ignore a token. + % + \def\gobble#1{} + + % The following is used inside several \edef's. + \def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} + + % Hyphenation fixes. + \hyphenation{ + Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script + ap-pen-dix bit-map bit-maps + data-base data-bases eshell fall-ing half-way long-est man-u-script + man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm + par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces + spell-ing spell-ings + stand-alone strong-est time-stamp time-stamps which-ever white-space + wide-spread wrap-around + } + + % Margin to add to right of even pages, to left of odd pages. + \newdimen\bindingoffset + \newdimen\normaloffset + \newdimen\pagewidth \newdimen\pageheight + + % For a final copy, take out the rectangles + % that mark overfull boxes (in case you have decided + % that the text looks ok even though it passes the margin). + % + \def\finalout{\overfullrule=0pt } + + % Sometimes it is convenient to have everything in the transcript file + % and nothing on the terminal. We don't just call \tracingall here, + % since that produces some useless output on the terminal. We also make + % some effort to order the tracing commands to reduce output in the log + % file; cf. trace.sty in LaTeX. + % + \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% + \def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\thisisundefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines16 + }% + + % @errormsg{MSG}. Do the index-like expansions on MSG, but if things + % aren't perfect, it's not the end of the world, being an error message, + % after all. + % + \def\errormsg{\begingroup \indexnofonts \doerrormsg} + \def\doerrormsg#1{\errmessage{#1}} + + % add check for \lastpenalty to plain's definitions. If the last thing + % we did was a \nobreak, we don't want to insert more space. + % + \def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} + \def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} + \def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + + % Do @cropmarks to get crop marks. + % + \newif\ifcropmarks + \let\cropmarks = \cropmarkstrue + % + % Dimensions to add cropmarks at corners. + % Added by P. A. MacKay, 12 Nov. 1986 + % + \newdimen\outerhsize \newdimen\outervsize % set by the paper size routines + \newdimen\cornerlong \cornerlong=1pc + \newdimen\cornerthick \cornerthick=.3pt + \newdimen\topandbottommargin \topandbottommargin=.75in + + % Output a mark which sets \thischapter, \thissection and \thiscolor. + % We dump everything together because we only have one kind of mark. + % This works because we only use \botmark / \topmark, not \firstmark. + % + % A mark contains a subexpression of the \ifcase ... \fi construct. + % \get*marks macros below extract the needed part using \ifcase. + % + % Another complication is to let the user choose whether \thischapter + % (\thissection) refers to the chapter (section) in effect at the top + % of a page, or that at the bottom of a page. The solution is + % described on page 260 of The TeXbook. It involves outputting two + % marks for the sectioning macros, one before the section break, and + % one after. I won't pretend I can describe this better than DEK... + \def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 % 0: top marks (\last...) + \noexpand\or \the\toks4 \the\toks6 % 1: bottom marks (default, \prev...) + \noexpand\else \the\toks8 % 2: color marks + }% + } + % \topmark doesn't work for the very first chapter (after the title + % page or the contents), so we use \firstmark there -- this gets us + % the mark with the chapter defs, unless the user sneaks in, e.g., + % @setcolor (or @url, or @link, etc.) between @contents and the very + % first @chapter. + \def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi + } + \def\getbottomheadingmarks{\ifcase1\botmark\fi} + \def\getcolormarks{\ifcase2\topmark\fi} + + % Avoid "undefined control sequence" errors. + \def\lastchapterdefs{} + \def\lastsectiondefs{} + \def\prevchapterdefs{} + \def\prevsectiondefs{} + \def\lastcolordefs{} + + % Main output routine. + \chardef\PAGE = 255 + \output = {\onepageout{\pagecontents\PAGE}} + + \newbox\headlinebox + \newbox\footlinebox + + % \onepageout takes a vbox as an argument. Note that \pagecontents + % does insertions, but you have to call it yourself. + \def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \def\commmonheadfootline{\let\hsize=\pagewidth \texinfochars} + % + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% + % + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + % We don't want .vr (or whatever) entries like this: + % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} + % "\acronym" won't work when it's read back in; + % it needs to be + % {\code {{\tt \backslashcurfont }acronym} + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingyyy.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 24pt + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \indexdummies + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi + } + + \newinsert\margin \dimen\margin=\maxdimen + + \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} + {\catcode`\@ =11 + \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi + % marginal hacks, juha@viisa.uucp (Juha Takala) + \ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi + \dimen@=\dp#1\relax \unvbox#1\relax + \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi + \ifr@ggedbottom \kern-\dimen@ \vfil \fi} + } + + % Here are the rules for the cropmarks. Note that they are + % offset so that the space between them is truly \outerhsize or \outervsize + % (P. A. MacKay, 12 November, 1986) + % + \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} + \def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} + \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} + \def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + + % Parse an argument, then pass it to #1. The argument is the rest of + % the input line (except we remove a trailing comment). #1 should be a + % macro which expects an ordinary undelimited TeX argument. + % + \def\parsearg{\parseargusing{}} + \def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. + } + + {\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + \argremovecomment #1\comment\ArgTerm% + }% + } + + % First remove any @comment, then any @c comment. + \def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} + \def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} + + % Each occurrence of `\^^M' or `\^^M' is replaced by a single space. + % + % \argremovec might leave us with trailing space, e.g., + % @end itemize @c foo + % This space token undergoes the same procedure and is eventually removed + % by \finishparsearg. + % + \def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} + \def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} + \def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% + \def\temp{#3}% + \ifx\temp\empty + % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: + \let\temp\finishparsearg + \else + \let\temp\argcheckspaces + \fi + % Put the space token in: + \temp#1 #3\ArgTerm + } + + % If a _delimited_ argument is enclosed in braces, they get stripped; so + % to get _exactly_ the rest of the line, we had to prevent such situation. + % We prepended an \empty token at the very beginning and we expand it now, + % just before passing the control to \argtorun. + % (Similarly, we have to think about #3 of \argcheckspacesY above: it is + % either the null string, or it ends with \^^M---thus there is no danger + % that a pair of braces would be stripped. + % + % But first, we have to remove the trailing space token. + % + \def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + + % \parseargdef\foo{...} + % is roughly equivalent to + % \def\foo{\parsearg\Xfoo} + % \def\Xfoo#1{...} + % + % Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my + % favourite TeX trick. --kasal, 16nov03 + + \def\parseargdef#1{% + \expandafter \doparseargdef \csname\string#1\endcsname #1% + } + \def\doparseargdef#1#2{% + \def#2{\parsearg#1}% + \def#1##1% + } + + % Several utility definitions with active space: + { + \obeyspaces + \gdef\obeyedspace{ } + + % Make each space character in the input produce a normal interword + % space in the output. Don't allow a line break at this space, as this + % is used only in environments like @example, where each line of input + % should produce a line of output anyway. + % + \gdef\sepspaces{\obeyspaces\let =\tie} + + % If an index command is used in an @example environment, any spaces + % therein should become regular spaces in the raw index file, not the + % expansion of \tie (\leavevmode \penalty \@M \ ). + \gdef\unsepspaces{\let =\space} + } + + + \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + + % Define the framework for environments in texinfo.tex. It's used like this: + % + % \envdef\foo{...} + % \def\Efoo{...} + % + % It's the responsibility of \envdef to insert \begingroup before the + % actual body; @end closes the group after calling \Efoo. \envdef also + % defines \thisenv, so the current environment is known; @end checks + % whether the environment name matches. The \checkenv macro can also be + % used to check whether the current environment is the one expected. + % + % Non-false conditionals (@iftex, @ifset) don't fit into this, so they + % are not treated as environments; they don't open a group. (The + % implementation of @end takes care not to call \endgroup in this + % special case.) + + + % At run-time, environments start with this: + \def\startenvironment#1{\begingroup\def\thisenv{#1}} + % initialize + \let\thisenv\empty + + % ... but they get defined via ``\envdef\foo{...}'': + \long\def\envdef#1#2{\def#1{\startenvironment#1#2}} + \def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} + + % Check whether we're in the right environment: + \def\checkenv#1{% + \def\temp{#1}% + \ifx\thisenv\temp + \else + \badenverr + \fi + } + + % Environment mismatch, #1 expected: + \def\badenverr{% + \errhelp = \EMsimple + \errmessage{This command can appear only \inenvironment\temp, + not \inenvironment\thisenv}% + } + \def\inenvironment#1{% + \ifx#1\empty + outside of any environment% + \else + in environment \expandafter\string#1% + \fi + } + + % @end foo executes the definition of \Efoo. + % But first, it executes a specialized version of \checkenv + % + \parseargdef\end{% + \if 1\csname iscond.#1\endcsname + \else + % The general wording of \badenverr may not be ideal. + \expandafter\checkenv\csname#1\endcsname + \csname E#1\endcsname + \endgroup + \fi + } + + \newhelp\EMsimple{Press RETURN to continue.} + + + % Be sure we're in horizontal mode when doing a tie, since we make space + % equivalent to this in @example-like environments. Otherwise, a space + % at the beginning of a line will start with \penalty -- and + % since \penalty is valid in vertical mode, we'd end up putting the + % penalty on the vertical list instead of in the new paragraph. + {\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } + } + + % @: forces normal size whitespace following. + \def\:{\spacefactor=1000 } + + % @* forces a line break. + \def\*{\unskip\hfil\break\hbox{}\ignorespaces} + + % @/ allows a line break. + \let\/=\allowbreak + + % @. is an end-of-sentence period. + \def\.{.\spacefactor=\endofsentencespacefactor\space} + + % @! is an end-of-sentence bang. + \def\!{!\spacefactor=\endofsentencespacefactor\space} + + % @? is an end-of-sentence query. + \def\?{?\spacefactor=\endofsentencespacefactor\space} + + % @frenchspacing on|off says whether to put extra space after punctuation. + % + \def\onword{on} + \def\offword{off} + % + \parseargdef\frenchspacing{% + \def\temp{#1}% + \ifx\temp\onword \plainfrenchspacing + \else\ifx\temp\offword \plainnonfrenchspacing + \else + \errhelp = \EMsimple + \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% + \fi\fi + } + + % @w prevents a word break. Without the \leavevmode, @w at the + % beginning of a paragraph, when TeX is still in vertical mode, would + % produce a whole line of output instead of starting the paragraph. + \def\w#1{\leavevmode\hbox{#1}} + + % @group ... @end group forces ... to be all on one page, by enclosing + % it in a TeX vbox. We use \vtop instead of \vbox to construct the box + % to keep its height that of a normal line. According to the rules for + % \topskip (p.114 of the TeXbook), the glue inserted is + % max (\topskip - \ht (first item), 0). If that height is large, + % therefore, no glue is inserted, and the space between the headline and + % the text is small, which looks bad. + % + % Another complication is that the group might be very large. This can + % cause the glue on the previous page to be unduly stretched, because it + % does not have much material. In this case, it's better to add an + % explicit \vfill so that the extra space is at the bottom. The + % threshold for doing this is if the group is more than \vfilllimit + % percent of a page (\vfilllimit can be changed inside of @tex). + % + \newbox\groupbox + \def\vfilllimit{0.7} + % + \envdef\group{% + \ifnum\catcode`\^^M=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + \startsavinginserts + % + \setbox\groupbox = \vtop\bgroup + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment + } + % + % The \vtop produces a box with normal height and large depth; thus, TeX puts + % \baselineskip glue before it, and (when the next line of text is done) + % \lineskip glue after it. Thus, space below is not quite equal to space + % above. But it's pretty close. + \def\Egroup{% + % To get correct interline space between the last line of the group + % and the first line afterwards, we have to propagate \prevdepth. + \endgraf % Not \par, as it may have been set to \lisppar. + \global\dimen1 = \prevdepth + \egroup % End the \vtop. + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \pageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\pageheight + \page + \fi + \fi + \box\groupbox + \prevdepth = \dimen1 + \checkinserts + } + % + % TeX puts in an \escapechar (i.e., `@') at the beginning of the help + % message, so this ends up printing `@group can only ...'. + % + \newhelp\groupinvalidhelp{% + group can only be used in environments such as @example,^^J% + where each line of input produces a line of output.} + + % @need space-in-mils + % forces a page break if there is not space-in-mils remaining. + + \newdimen\mil \mil=0.001in + + \parseargdef\need{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi + } + + % @br forces paragraph break (and is undocumented). + + \let\br = \par + + % @page forces the start of a new page. + % + \def\page{\par\vfill\supereject} + + % @exdent text.... + % outputs text on separate line in roman font, starting at standard page margin + + % This records the amount of indent in the innermost environment. + % That's how much \exdent should take out. + \newskip\exdentamount + + % This defn is used inside fill environments such as @defun. + \parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} + + % This defn is used inside nofill environments such as @example. + \parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + + % @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current + % paragraph. For more general purposes, use the \margin insertion + % class. WHICH is `l' or `r'. Not documented, written for gawk manual. + % + \newskip\inmarginspacing \inmarginspacing=1cm + \def\strutdepth{\dp\strutbox} + % + \def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% + }} + \def\inleftmargin{\doinmargin l} + \def\inrightmargin{\doinmargin r} + % + % @inmargin{TEXT [, RIGHT-TEXT]} + % (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; + % else use TEXT for both). + % + \def\inmargin#1{\parseinmargin #1,,\finish} + \def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp + } + + % @| inserts a changebar to the left of the current line. It should + % surround any changed text. This approach does *not* work if the + % change spans more than two lines of output. To handle that, we would + % have adopt a much more difficult approach (putting marks into the main + % vertical list for the beginning and end of each change). This command + % is not documented, not supported, and doesn't work. + % + \def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% + } + + % @include FILE -- \input text of FILE. + % + \def\include{\parseargusing\filenamecatcodes\includezzz} + \def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable % we want to expand any @value in FILE. + \turnoffactive % and allow special characters in the expansion + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @include of #1^^J}% + \edef\temp{\noexpand\input #1 }% + % + % This trickery is to read FILE outside of a group, in case it makes + % definitions, etc. + \expandafter + }\temp + \popthisfilestack + } + \def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \catcode`-=\other + \catcode`\`=\other + \catcode`\'=\other + } + + \def\pushthisfilestack{% + \expandafter\pushthisfilestackX\popthisfilestack\StackTerm + } + \def\pushthisfilestackX{% + \expandafter\pushthisfilestackY\thisfile\StackTerm + } + \def\pushthisfilestackY #1\StackTerm #2\StackTerm {% + \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% + } + + \def\popthisfilestack{\errthisfilestackempty} + \def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} + % + \def\thisfile{} + + % @center line + % outputs that line, centered. + % + \parseargdef\center{% + \ifhmode + \let\centersub\centerH + \else + \let\centersub\centerV + \fi + \centersub{\hfil \ignorespaces#1\unskip \hfil}% + \let\centersub\relax % don't let the definition persist, just in case + } + \def\centerH#1{{% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break + }} + % + \newcount\centerpenalty + \def\centerV#1{% + % The idea here is the same as in \startdefun, \cartouche, etc.: if + % @center is the first thing after a section heading, we need to wipe + % out the negative parskip inserted by \sectionheading, but still + % prevent a page break here. + \centerpenalty = \lastpenalty + \ifnum\centerpenalty>10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% + } + + % @sp n outputs n lines of vertical space + % + \parseargdef\sp{\vskip #1\baselineskip} + + % @comment ...line which is ignored... + % @c is the same as @comment + % @ignore ... @end ignore is another way to write a comment + % + \def\comment{\begingroup \catcode`\^^M=\other% + \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% + \commentxxx} + {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + % + \let\c=\comment + + % @paragraphindent NCHARS + % We'll use ems for NCHARS, close enough. + % NCHARS can also be the word `asis' or `none'. + % We cannot feasibly implement @paragraphindent asis, though. + % + \def\asisword{asis} % no translation, these are keywords + \def\noneword{none} + % + \parseargdef\paragraphindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent + } + + % @exampleindent NCHARS + % We'll use ems for NCHARS like @paragraphindent. + % It seems @exampleindent asis isn't necessary, but + % I preserve it to make it similar to @paragraphindent. + \parseargdef\exampleindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi + } + + % @firstparagraphindent WORD + % If WORD is `none', then suppress indentation of the first paragraph + % after a section heading. If WORD is `insert', then do indent at such + % paragraphs. + % + % The paragraph indentation is suppressed or not by calling + % \suppressfirstparagraphindent, which the sectioning commands do. + % We switch the definition of this back and forth according to WORD. + % By default, we suppress indentation. + % + \def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} + \def\insertword{insert} + % + \parseargdef\firstparagraphindent{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi + } + + % Here is how we actually suppress indentation. Redefine \everypar to + % \kern backwards by \parindent, and then reset itself to empty. + % + % We also make \indent itself not actually do anything until the next + % paragraph. + % + \gdef\dosuppressfirstparagraphindent{% + \gdef\indent{% + \restorefirstparagraphindent + \indent + }% + \gdef\noindent{% + \restorefirstparagraphindent + \noindent + }% + \global\everypar = {% + \kern -\parindent + \restorefirstparagraphindent + }% + } + + \gdef\restorefirstparagraphindent{% + \global \let \indent = \ptexindent + \global \let \noindent = \ptexnoindent + \global \everypar = {}% + } + + + % @refill is a no-op. + \let\refill=\relax + + % If working on a large document in chapters, it is convenient to + % be able to disable indexing, cross-referencing, and contents, for test runs. + % This is done with @novalidate (before @setfilename). + % + \newif\iflinks \linkstrue % by default we want the aux files. + \let\novalidate = \linksfalse + + % @setfilename is done at the beginning of every texinfo file. + % So open here the files we need to have open while reading the input. + % This makes it possible to make a .fmt file for texinfo. + \def\setfilename{% + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi % \openindices needs to do some work in any case. + \openindices + \let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + \openin 1 texinfo.cnf + \ifeof 1 \else \input texinfo.cnf \fi + \closein 1 + % + \comment % Ignore the actual filename. + } + + % Called from \setfilename. + % + \def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% + } + + % @bye. + \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + + \message{pdf,} + % adobe `portable' document format + \newcount\tempnum + \newcount\lnkcount + \newtoks\filename + \newcount\filenamelength + \newcount\pgn + \newtoks\toksA + \newtoks\toksB + \newtoks\toksC + \newtoks\toksD + \newbox\boxA + \newcount\countA + \newif\ifpdf + \newif\ifpdfmakepagedest + + % when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 + % can be set). So we test for \relax and 0 as well as being undefined. + \ifx\pdfoutput\thisisundefined + \else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi + \fi + + % PDF uses PostScript string constants for the names of xref targets, + % for display in the outlines, and in other places. Thus, we have to + % double any backslashes. Otherwise, a name like "\node" will be + % interpreted as a newline (\n), followed by o, d, e. Not good. + % + % See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and + % related messages. The final outcome is that it is up to the TeX user + % to double the backslashes and otherwise make the string valid, so + % that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to + % do this reliably, so we use it. + + % #1 is a control sequence in which to do the replacements, + % which we \xdef. + \def\txiescapepdf#1{% + \ifx\pdfescapestring\thisisundefined + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi + } + + \newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images + with PDF output, and none of those formats could be found. (.eps cannot + be supported due to the design of the PDF format; use regular TeX (DVI + output) for that.)} + + \ifpdf + % + % Color manipulation macros based on pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead + % of actual black. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + % k sets the color for filling (usual text, etc.); + % K sets the color for stroking (thin rules, e.g., normal _'s). + \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \pdfcatalog{/PageMode /UseOutlines} + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \else \gdef\pdfimgext{PDF}% + \fi + \else \gdef\pdfimgext{pdf}% + \fi + \closein 1 + \endgroup + % + % without \immediate, ancient pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else + {#1.\pdfimgext}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + % + \def\pdfmkdest#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \turnoffactive + \makevalueexpandable + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + }} + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use a color that is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. + \def\urlcolor{\rgbDarkRed} + \def\linkcolor{\rgbDarkRed} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text, which is what will be displayed in the + % outline by the pdf viewer. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node text, + % which might be empty if this toc entry had no corresponding node. + % #4 is the page number + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worth the trouble, since most documents are normally structured. + \edef\pdfoutlinedest{#3}% + \ifx\pdfoutlinedest\empty + \def\pdfoutlinedest{#4}% + \else + \txiescapepdf\pdfoutlinedest + \fi + % + % Also escape PDF chars in the display string. + \edef\pdfoutlinetext{#1}% + \txiescapepdf\pdfoutlinetext + % + \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% + } + % + \def\pdfmakeoutlines{% + \begingroup + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \def\thischapnum{##2}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + }% + \def\numsecentry##1##2##3##4{% + \advancenumber{chap\thischapnum}% + \def\thissecnum{##2}% + \def\thissubsecnum{0}% + }% + \def\numsubsecentry##1##2##3##4{% + \advancenumber{sec\thissecnum}% + \def\thissubsecnum{##2}% + }% + \def\numsubsubsecentry##1##2##3##4{% + \advancenumber{subsec\thissubsecnum}% + }% + \def\thischapnum{0}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \readdatafile{toc}% + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % PDF outlines are displayed using system fonts, instead of + % document fonts. Therefore we cannot use special characters, + % since the encoding is unknown. For example, the eogonek from + % Latin 2 (0xea) gets translated to a | character. Info from + % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + % + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} + \else + % non-pdf mode + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \let\pdfmakeoutlines = \relax + \fi % \ifx\pdfoutput + + + \message{fonts,} + + % Change the current font style to #1, remembering it in \curfontstyle. + % For now, we do not accumulate font styles: @b{@i{foo}} prints foo in + % italics, not bold italics. + % + \def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname ten#1\endcsname % change the current font + } + + % Select #1 fonts with the current style. + % + \def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} + + \def\rm{\fam=0 \setfontstyle{rm}} + \def\it{\fam=\itfam \setfontstyle{it}} + \def\sl{\fam=\slfam \setfontstyle{sl}} + \def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} + \def\tt{\fam=\ttfam \setfontstyle{tt}} + + % Unfortunately, we have to override this for titles and the like, since + % in those cases "rm" is bold. Sigh. + \def\rmisbold{\rm\def\curfontstyle{bf}} + + % Texinfo sort of supports the sans serif font style, which plain TeX does not. + % So we set up a \sf. + \newfam\sffam + \def\sf{\fam=\sffam \setfontstyle{sf}} + \let\li = \sf % Sometimes we call it \li, not \sf. + + % We don't need math for this font style. + \def\ttsl{\setfontstyle{ttsl}} + + + % Set the baselineskip to #1, and the lineskip and strut size + % correspondingly. There is no deep meaning behind these magic numbers + % used as factors; they just match (closely enough) what Knuth defined. + % + \def\lineskipfactor{.08333} + \def\strutheightpercent{.70833} + \def\strutdepthpercent {.29167} + % + % can get a sort of poor man's double spacing by redefining this. + \def\baselinefactor{1} + % + \newdimen\textleading + \def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% + } + + % PDF CMaps. See also LaTeX's t1.cmap. + % + % do nothing with this by default. + \expandafter\let\csname cmapOT1\endcsname\gobble + \expandafter\let\csname cmapOT1IT\endcsname\gobble + \expandafter\let\csname cmapOT1TT\endcsname\gobble + + % if we are producing pdf, and we have \pdffontattr, then define cmaps. + % (\pdffontattr was introduced many years ago, but people still run + % older pdftex's; it's easy to conditionalize, so we do.) + \ifpdf \ifx\pdffontattr\thisisundefined \else + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap + %%DocumentNeededResources: ProcSet (CIDInit) + %%IncludeResource: ProcSet (CIDInit) + %%BeginResource: CMap (TeX-OT1-0) + %%Title: (TeX-OT1-0 TeX OT1 0) + %%Version: 1.000 + %%EndComments + /CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /CIDSystemInfo + << /Registry (TeX) + /Ordering (OT1) + /Supplement 0 + >> def + /CMapName /TeX-OT1-0 def + /CMapType 2 def + 1 begincodespacerange + <00> <7F> + endcodespacerange + 8 beginbfrange + <00> <01> <0393> + <09> <0A> <03A8> + <23> <26> <0023> + <28> <3B> <0028> + <3F> <5B> <003F> + <5D> <5E> <005D> + <61> <7A> <0061> + <7B> <7C> <2013> + endbfrange + 40 beginbfchar + <02> <0398> + <03> <039B> + <04> <039E> + <05> <03A0> + <06> <03A3> + <07> <03D2> + <08> <03A6> + <0B> <00660066> + <0C> <00660069> + <0D> <0066006C> + <0E> <006600660069> + <0F> <00660066006C> + <10> <0131> + <11> <0237> + <12> <0060> + <13> <00B4> + <14> <02C7> + <15> <02D8> + <16> <00AF> + <17> <02DA> + <18> <00B8> + <19> <00DF> + <1A> <00E6> + <1B> <0153> + <1C> <00F8> + <1D> <00C6> + <1E> <0152> + <1F> <00D8> + <21> <0021> + <22> <201D> + <27> <2019> + <3C> <00A1> + <3D> <003D> + <3E> <00BF> + <5C> <201C> + <5F> <02D9> + <60> <2018> + <7D> <02DD> + <7E> <007E> + <7F> <00A8> + endbfchar + endcmap + CMapName currentdict /CMap defineresource pop + end + end + %%EndResource + %%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% + % + % \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap + %%DocumentNeededResources: ProcSet (CIDInit) + %%IncludeResource: ProcSet (CIDInit) + %%BeginResource: CMap (TeX-OT1IT-0) + %%Title: (TeX-OT1IT-0 TeX OT1IT 0) + %%Version: 1.000 + %%EndComments + /CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /CIDSystemInfo + << /Registry (TeX) + /Ordering (OT1IT) + /Supplement 0 + >> def + /CMapName /TeX-OT1IT-0 def + /CMapType 2 def + 1 begincodespacerange + <00> <7F> + endcodespacerange + 8 beginbfrange + <00> <01> <0393> + <09> <0A> <03A8> + <25> <26> <0025> + <28> <3B> <0028> + <3F> <5B> <003F> + <5D> <5E> <005D> + <61> <7A> <0061> + <7B> <7C> <2013> + endbfrange + 42 beginbfchar + <02> <0398> + <03> <039B> + <04> <039E> + <05> <03A0> + <06> <03A3> + <07> <03D2> + <08> <03A6> + <0B> <00660066> + <0C> <00660069> + <0D> <0066006C> + <0E> <006600660069> + <0F> <00660066006C> + <10> <0131> + <11> <0237> + <12> <0060> + <13> <00B4> + <14> <02C7> + <15> <02D8> + <16> <00AF> + <17> <02DA> + <18> <00B8> + <19> <00DF> + <1A> <00E6> + <1B> <0153> + <1C> <00F8> + <1D> <00C6> + <1E> <0152> + <1F> <00D8> + <21> <0021> + <22> <201D> + <23> <0023> + <24> <00A3> + <27> <2019> + <3C> <00A1> + <3D> <003D> + <3E> <00BF> + <5C> <201C> + <5F> <02D9> + <60> <2018> + <7D> <02DD> + <7E> <007E> + <7F> <00A8> + endbfchar + endcmap + CMapName currentdict /CMap defineresource pop + end + end + %%EndResource + %%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% + % + % \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap + %%DocumentNeededResources: ProcSet (CIDInit) + %%IncludeResource: ProcSet (CIDInit) + %%BeginResource: CMap (TeX-OT1TT-0) + %%Title: (TeX-OT1TT-0 TeX OT1TT 0) + %%Version: 1.000 + %%EndComments + /CIDInit /ProcSet findresource begin + 12 dict begin + begincmap + /CIDSystemInfo + << /Registry (TeX) + /Ordering (OT1TT) + /Supplement 0 + >> def + /CMapName /TeX-OT1TT-0 def + /CMapType 2 def + 1 begincodespacerange + <00> <7F> + endcodespacerange + 5 beginbfrange + <00> <01> <0393> + <09> <0A> <03A8> + <21> <26> <0021> + <28> <5F> <0028> + <61> <7E> <0061> + endbfrange + 32 beginbfchar + <02> <0398> + <03> <039B> + <04> <039E> + <05> <03A0> + <06> <03A3> + <07> <03D2> + <08> <03A6> + <0B> <2191> + <0C> <2193> + <0D> <0027> + <0E> <00A1> + <0F> <00BF> + <10> <0131> + <11> <0237> + <12> <0060> + <13> <00B4> + <14> <02C7> + <15> <02D8> + <16> <00AF> + <17> <02DA> + <18> <00B8> + <19> <00DF> + <1A> <00E6> + <1B> <0153> + <1C> <00F8> + <1D> <00C6> + <1E> <0152> + <1F> <00D8> + <20> <2423> + <27> <2019> + <60> <2018> + <7F> <00A8> + endbfchar + endcmap + CMapName currentdict /CMap defineresource pop + end + end + %%EndResource + %%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% + \fi\fi + + + % Set the font macro #1 to the font named \fontprefix#2. + % #3 is the font's design size, #4 is a scale factor, #5 is the CMap + % encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). + % Example: + % #1 = \textrm + % #2 = \rmshape + % #3 = 10 + % #4 = \mainmagstep + % #5 = OT1 + % + \def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% + } + % This is what gets called when #5 of \setfont is empty. + \let\cmap\gobble + % + % (end of cmaps) + + % Use cm as the default font prefix. + % To specify the font prefix, you must define \fontprefix + % before you read in texinfo.tex. + \ifx\fontprefix\thisisundefined + \def\fontprefix{cm} + \fi + % Support font families that don't use the same naming scheme as CM. + \def\rmshape{r} + \def\rmbshape{bx} % where the normal face is bold + \def\bfshape{b} + \def\bxshape{bx} + \def\ttshape{tt} + \def\ttbshape{tt} + \def\ttslshape{sltt} + \def\itshape{ti} + \def\itbshape{bxti} + \def\slshape{sl} + \def\slbshape{bxsl} + \def\sfshape{ss} + \def\sfbshape{ss} + \def\scshape{csc} + \def\scbshape{csc} + + % Definitions for a main text size of 11pt. (The default in Texinfo.) + % + \def\definetextfontsizexi{% + % Text fonts (11.2pt, magstep1). + \def\textnominalsize{11pt} + \edef\mainmagstep{\magstephalf} + \setfont\textrm\rmshape{10}{\mainmagstep}{OT1} + \setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} + \setfont\textbf\bfshape{10}{\mainmagstep}{OT1} + \setfont\textit\itshape{10}{\mainmagstep}{OT1IT} + \setfont\textsl\slshape{10}{\mainmagstep}{OT1} + \setfont\textsf\sfshape{10}{\mainmagstep}{OT1} + \setfont\textsc\scshape{10}{\mainmagstep}{OT1} + \setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} + \font\texti=cmmi10 scaled \mainmagstep + \font\textsy=cmsy10 scaled \mainmagstep + \def\textecsize{1095} + + % A few fonts for @defun names and args. + \setfont\defbf\bfshape{10}{\magstep1}{OT1} + \setfont\deftt\ttshape{10}{\magstep1}{OT1TT} + \setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} + \def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + + % Fonts for indices, footnotes, small examples (9pt). + \def\smallnominalsize{9pt} + \setfont\smallrm\rmshape{9}{1000}{OT1} + \setfont\smalltt\ttshape{9}{1000}{OT1TT} + \setfont\smallbf\bfshape{10}{900}{OT1} + \setfont\smallit\itshape{9}{1000}{OT1IT} + \setfont\smallsl\slshape{9}{1000}{OT1} + \setfont\smallsf\sfshape{9}{1000}{OT1} + \setfont\smallsc\scshape{10}{900}{OT1} + \setfont\smallttsl\ttslshape{10}{900}{OT1TT} + \font\smalli=cmmi9 + \font\smallsy=cmsy9 + \def\smallecsize{0900} + + % Fonts for small examples (8pt). + \def\smallernominalsize{8pt} + \setfont\smallerrm\rmshape{8}{1000}{OT1} + \setfont\smallertt\ttshape{8}{1000}{OT1TT} + \setfont\smallerbf\bfshape{10}{800}{OT1} + \setfont\smallerit\itshape{8}{1000}{OT1IT} + \setfont\smallersl\slshape{8}{1000}{OT1} + \setfont\smallersf\sfshape{8}{1000}{OT1} + \setfont\smallersc\scshape{10}{800}{OT1} + \setfont\smallerttsl\ttslshape{10}{800}{OT1TT} + \font\smalleri=cmmi8 + \font\smallersy=cmsy8 + \def\smallerecsize{0800} + + % Fonts for title page (20.4pt): + \def\titlenominalsize{20pt} + \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} + \setfont\titleit\itbshape{10}{\magstep4}{OT1IT} + \setfont\titlesl\slbshape{10}{\magstep4}{OT1} + \setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} + \setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} + \setfont\titlesf\sfbshape{17}{\magstep1}{OT1} + \let\titlebf=\titlerm + \setfont\titlesc\scbshape{10}{\magstep4}{OT1} + \font\titlei=cmmi12 scaled \magstep3 + \font\titlesy=cmsy10 scaled \magstep4 + \def\titleecsize{2074} + + % Chapter (and unnumbered) fonts (17.28pt). + \def\chapnominalsize{17pt} + \setfont\chaprm\rmbshape{12}{\magstep2}{OT1} + \setfont\chapit\itbshape{10}{\magstep3}{OT1IT} + \setfont\chapsl\slbshape{10}{\magstep3}{OT1} + \setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} + \setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} + \setfont\chapsf\sfbshape{17}{1000}{OT1} + \let\chapbf=\chaprm + \setfont\chapsc\scbshape{10}{\magstep3}{OT1} + \font\chapi=cmmi12 scaled \magstep2 + \font\chapsy=cmsy10 scaled \magstep3 + \def\chapecsize{1728} + + % Section fonts (14.4pt). + \def\secnominalsize{14pt} + \setfont\secrm\rmbshape{12}{\magstep1}{OT1} + \setfont\secit\itbshape{10}{\magstep2}{OT1IT} + \setfont\secsl\slbshape{10}{\magstep2}{OT1} + \setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} + \setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} + \setfont\secsf\sfbshape{12}{\magstep1}{OT1} + \let\secbf\secrm + \setfont\secsc\scbshape{10}{\magstep2}{OT1} + \font\seci=cmmi12 scaled \magstep1 + \font\secsy=cmsy10 scaled \magstep2 + \def\sececsize{1440} + + % Subsection fonts (13.15pt). + \def\ssecnominalsize{13pt} + \setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} + \setfont\ssecit\itbshape{10}{1315}{OT1IT} + \setfont\ssecsl\slbshape{10}{1315}{OT1} + \setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} + \setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} + \setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} + \let\ssecbf\ssecrm + \setfont\ssecsc\scbshape{10}{1315}{OT1} + \font\sseci=cmmi12 scaled \magstephalf + \font\ssecsy=cmsy10 scaled 1315 + \def\ssececsize{1200} + + % Reduced fonts for @acro in text (10pt). + \def\reducednominalsize{10pt} + \setfont\reducedrm\rmshape{10}{1000}{OT1} + \setfont\reducedtt\ttshape{10}{1000}{OT1TT} + \setfont\reducedbf\bfshape{10}{1000}{OT1} + \setfont\reducedit\itshape{10}{1000}{OT1IT} + \setfont\reducedsl\slshape{10}{1000}{OT1} + \setfont\reducedsf\sfshape{10}{1000}{OT1} + \setfont\reducedsc\scshape{10}{1000}{OT1} + \setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} + \font\reducedi=cmmi10 + \font\reducedsy=cmsy10 + \def\reducedecsize{1000} + + \textleading = 13.2pt % line spacing for 11pt CM + \textfonts % reset the current fonts + \rm + } % end of 11pt text font size definitions, \definetextfontsizexi + + + % Definitions to make the main text be 10pt Computer Modern, with + % section, chapter, etc., sizes following suit. This is for the GNU + % Press printing of the Emacs 22 manual. Maybe other manuals in the + % future. Used with @smallbook, which sets the leading to 12pt. + % + \def\definetextfontsizex{% + % Text fonts (10pt). + \def\textnominalsize{10pt} + \edef\mainmagstep{1000} + \setfont\textrm\rmshape{10}{\mainmagstep}{OT1} + \setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} + \setfont\textbf\bfshape{10}{\mainmagstep}{OT1} + \setfont\textit\itshape{10}{\mainmagstep}{OT1IT} + \setfont\textsl\slshape{10}{\mainmagstep}{OT1} + \setfont\textsf\sfshape{10}{\mainmagstep}{OT1} + \setfont\textsc\scshape{10}{\mainmagstep}{OT1} + \setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} + \font\texti=cmmi10 scaled \mainmagstep + \font\textsy=cmsy10 scaled \mainmagstep + \def\textecsize{1000} + + % A few fonts for @defun names and args. + \setfont\defbf\bfshape{10}{\magstephalf}{OT1} + \setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} + \setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} + \def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + + % Fonts for indices, footnotes, small examples (9pt). + \def\smallnominalsize{9pt} + \setfont\smallrm\rmshape{9}{1000}{OT1} + \setfont\smalltt\ttshape{9}{1000}{OT1TT} + \setfont\smallbf\bfshape{10}{900}{OT1} + \setfont\smallit\itshape{9}{1000}{OT1IT} + \setfont\smallsl\slshape{9}{1000}{OT1} + \setfont\smallsf\sfshape{9}{1000}{OT1} + \setfont\smallsc\scshape{10}{900}{OT1} + \setfont\smallttsl\ttslshape{10}{900}{OT1TT} + \font\smalli=cmmi9 + \font\smallsy=cmsy9 + \def\smallecsize{0900} + + % Fonts for small examples (8pt). + \def\smallernominalsize{8pt} + \setfont\smallerrm\rmshape{8}{1000}{OT1} + \setfont\smallertt\ttshape{8}{1000}{OT1TT} + \setfont\smallerbf\bfshape{10}{800}{OT1} + \setfont\smallerit\itshape{8}{1000}{OT1IT} + \setfont\smallersl\slshape{8}{1000}{OT1} + \setfont\smallersf\sfshape{8}{1000}{OT1} + \setfont\smallersc\scshape{10}{800}{OT1} + \setfont\smallerttsl\ttslshape{10}{800}{OT1TT} + \font\smalleri=cmmi8 + \font\smallersy=cmsy8 + \def\smallerecsize{0800} + + % Fonts for title page (20.4pt): + \def\titlenominalsize{20pt} + \setfont\titlerm\rmbshape{12}{\magstep3}{OT1} + \setfont\titleit\itbshape{10}{\magstep4}{OT1IT} + \setfont\titlesl\slbshape{10}{\magstep4}{OT1} + \setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} + \setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} + \setfont\titlesf\sfbshape{17}{\magstep1}{OT1} + \let\titlebf=\titlerm + \setfont\titlesc\scbshape{10}{\magstep4}{OT1} + \font\titlei=cmmi12 scaled \magstep3 + \font\titlesy=cmsy10 scaled \magstep4 + \def\titleecsize{2074} + + % Chapter fonts (14.4pt). + \def\chapnominalsize{14pt} + \setfont\chaprm\rmbshape{12}{\magstep1}{OT1} + \setfont\chapit\itbshape{10}{\magstep2}{OT1IT} + \setfont\chapsl\slbshape{10}{\magstep2}{OT1} + \setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} + \setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} + \setfont\chapsf\sfbshape{12}{\magstep1}{OT1} + \let\chapbf\chaprm + \setfont\chapsc\scbshape{10}{\magstep2}{OT1} + \font\chapi=cmmi12 scaled \magstep1 + \font\chapsy=cmsy10 scaled \magstep2 + \def\chapecsize{1440} + + % Section fonts (12pt). + \def\secnominalsize{12pt} + \setfont\secrm\rmbshape{12}{1000}{OT1} + \setfont\secit\itbshape{10}{\magstep1}{OT1IT} + \setfont\secsl\slbshape{10}{\magstep1}{OT1} + \setfont\sectt\ttbshape{12}{1000}{OT1TT} + \setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} + \setfont\secsf\sfbshape{12}{1000}{OT1} + \let\secbf\secrm + \setfont\secsc\scbshape{10}{\magstep1}{OT1} + \font\seci=cmmi12 + \font\secsy=cmsy10 scaled \magstep1 + \def\sececsize{1200} + + % Subsection fonts (10pt). + \def\ssecnominalsize{10pt} + \setfont\ssecrm\rmbshape{10}{1000}{OT1} + \setfont\ssecit\itbshape{10}{1000}{OT1IT} + \setfont\ssecsl\slbshape{10}{1000}{OT1} + \setfont\ssectt\ttbshape{10}{1000}{OT1TT} + \setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} + \setfont\ssecsf\sfbshape{10}{1000}{OT1} + \let\ssecbf\ssecrm + \setfont\ssecsc\scbshape{10}{1000}{OT1} + \font\sseci=cmmi10 + \font\ssecsy=cmsy10 + \def\ssececsize{1000} + + % Reduced fonts for @acro in text (9pt). + \def\reducednominalsize{9pt} + \setfont\reducedrm\rmshape{9}{1000}{OT1} + \setfont\reducedtt\ttshape{9}{1000}{OT1TT} + \setfont\reducedbf\bfshape{10}{900}{OT1} + \setfont\reducedit\itshape{9}{1000}{OT1IT} + \setfont\reducedsl\slshape{9}{1000}{OT1} + \setfont\reducedsf\sfshape{9}{1000}{OT1} + \setfont\reducedsc\scshape{10}{900}{OT1} + \setfont\reducedttsl\ttslshape{10}{900}{OT1TT} + \font\reducedi=cmmi9 + \font\reducedsy=cmsy9 + \def\reducedecsize{0900} + + \divide\parskip by 2 % reduce space between paragraphs + \textleading = 12pt % line spacing for 10pt CM + \textfonts % reset the current fonts + \rm + } % end of 10pt text font size definitions, \definetextfontsizex + + + % We provide the user-level command + % @fonttextsize 10 + % (or 11) to redefine the text font size. pt is assumed. + % + \def\xiword{11} + \def\xword{10} + \def\xwordpt{10pt} + % + \parseargdef\fonttextsize{% + \def\textsizearg{#1}% + %\wlog{doing @fonttextsize \textsizearg}% + % + % Set \globaldefs so that documents can use this inside @tex, since + % makeinfo 4.8 does not support it, but we need it nonetheless. + % + \begingroup \globaldefs=1 + \ifx\textsizearg\xword \definetextfontsizex + \else \ifx\textsizearg\xiword \definetextfontsizexi + \else + \errhelp=\EMsimple + \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} + \fi\fi + \endgroup + } + + + % In order for the font changes to affect most math symbols and letters, + % we have to define the \textfont of the standard families. Since + % texinfo doesn't allow for producing subscripts and superscripts except + % in the main text, we don't bother to reset \scriptfont and + % \scriptscriptfont (which would also require loading a lot more fonts). + % + \def\resetmathfonts{% + \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy + \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf + \textfont\ttfam=\tentt \textfont\sffam=\tensf + } + + % The font-changing commands redefine the meanings of \tenSTYLE, instead + % of just \STYLE. We do this because \STYLE needs to also set the + % current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire + % \tenSTYLE to set the current font. + % + % Each font-changing command also sets the names \lsize (one size lower) + % and \lllsize (three sizes lower). These relative commands are used in + % the LaTeX logo and acronyms. + % + % This all needs generalizing, badly. + % + \def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy + \let\tenttsl=\textttsl + \def\curfontsize{text}% + \def\lsize{reduced}\def\lllsize{smaller}% + \resetmathfonts \setleading{\textleading}} + \def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \def\curfontsize{title}% + \def\lsize{chap}\def\lllsize{subsec}% + \resetmathfonts \setleading{27pt}} + \def\titlefont#1{{\titlefonts\rmisbold #1}} + \def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy + \let\tenttsl=\chapttsl + \def\curfontsize{chap}% + \def\lsize{sec}\def\lllsize{text}% + \resetmathfonts \setleading{19pt}} + \def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy + \let\tenttsl=\secttsl + \def\curfontsize{sec}% + \def\lsize{subsec}\def\lllsize{reduced}% + \resetmathfonts \setleading{16pt}} + \def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy + \let\tenttsl=\ssecttsl + \def\curfontsize{ssec}% + \def\lsize{text}\def\lllsize{small}% + \resetmathfonts \setleading{15pt}} + \let\subsubsecfonts = \subsecfonts + \def\reducedfonts{% + \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl + \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc + \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy + \let\tenttsl=\reducedttsl + \def\curfontsize{reduced}% + \def\lsize{small}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} + \def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \def\curfontsize{small}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} + \def\smallerfonts{% + \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl + \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc + \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy + \let\tenttsl=\smallerttsl + \def\curfontsize{smaller}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{9.5pt}} + + % Fonts for short table of contents. + \setfont\shortcontrm\rmshape{12}{1000}{OT1} + \setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 + \setfont\shortcontsl\slshape{12}{1000}{OT1} + \setfont\shortconttt\ttshape{12}{1000}{OT1TT} + + % Define these just so they can be easily changed for other fonts. + \def\angleleft{$\langle$} + \def\angleright{$\rangle$} + + % Set the fonts to use with the @small... environments. + \let\smallexamplefonts = \smallfonts + + % About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample + % can fit this many characters: + % 8.5x11=86 smallbook=72 a4=90 a5=69 + % If we use \scriptfonts (8pt), then we can fit this many characters: + % 8.5x11=90+ smallbook=80 a4=90+ a5=77 + % For me, subjectively, the few extra characters that fit aren't worth + % the additional smallness of 8pt. So I'm making the default 9pt. + % + % By the way, for comparison, here's what fits with @example (10pt): + % 8.5x11=71 smallbook=60 a4=75 a5=58 + % --karl, 24jan03. + + % Set up the default fonts, so we can use them for creating boxes. + % + \definetextfontsizexi + + + \message{markup,} + + % Check if we are currently using a typewriter font. Since all the + % Computer Modern typewriter fonts have zero interword stretch (and + % shrink), and it is reasonable to expect all typewriter fonts to have + % this property, we can check that font parameter. + % + \def\ifmonospace{\ifdim\fontdimen3\font=0pt } + + % Markup style infrastructure. \defmarkupstylesetup\INITMACRO will + % define and register \INITMACRO to be called on markup style changes. + % \INITMACRO can check \currentmarkupstyle for the innermost + % style and the set of \ifmarkupSTYLE switches for all styles + % currently in effect. + \newif\ifmarkupvar + \newif\ifmarkupsamp + \newif\ifmarkupkey + %\newif\ifmarkupfile % @file == @samp. + %\newif\ifmarkupoption % @option == @samp. + \newif\ifmarkupcode + \newif\ifmarkupkbd + %\newif\ifmarkupenv % @env == @code. + %\newif\ifmarkupcommand % @command == @code. + \newif\ifmarkuptex % @tex (and part of @math, for now). + \newif\ifmarkupexample + \newif\ifmarkupverb + \newif\ifmarkupverbatim + + \let\currentmarkupstyle\empty + + \def\setupmarkupstyle#1{% + \csname markup#1true\endcsname + \def\currentmarkupstyle{#1}% + \markupstylesetup + } + + \let\markupstylesetup\empty + + \def\defmarkupstylesetup#1{% + \expandafter\def\expandafter\markupstylesetup + \expandafter{\markupstylesetup #1}% + \def#1% + } + + % Markup style setup for left and right quotes. + \defmarkupstylesetup\markupsetuplq{% + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuplqdefault \else \temp \fi + } + + \defmarkupstylesetup\markupsetuprq{% + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuprqdefault \else \temp \fi + } + + { + \catcode`\'=\active + \catcode`\`=\active + + \gdef\markupsetuplqdefault{\let`\lq} + \gdef\markupsetuprqdefault{\let'\rq} + + \gdef\markupsetcodequoteleft{\let`\codequoteleft} + \gdef\markupsetcodequoteright{\let'\codequoteright} + } + + \let\markupsetuplqcode \markupsetcodequoteleft + \let\markupsetuprqcode \markupsetcodequoteright + % + \let\markupsetuplqexample \markupsetcodequoteleft + \let\markupsetuprqexample \markupsetcodequoteright + % + \let\markupsetuplqkbd \markupsetcodequoteleft + \let\markupsetuprqkbd \markupsetcodequoteright + % + \let\markupsetuplqsamp \markupsetcodequoteleft + \let\markupsetuprqsamp \markupsetcodequoteright + % + \let\markupsetuplqverb \markupsetcodequoteleft + \let\markupsetuprqverb \markupsetcodequoteright + % + \let\markupsetuplqverbatim \markupsetcodequoteleft + \let\markupsetuprqverbatim \markupsetcodequoteright + + % Allow an option to not use regular directed right quote/apostrophe + % (char 0x27), but instead the undirected quote from cmtt (char 0x0d). + % The undirected quote is ugly, so don't make it the default, but it + % works for pasting with more pdf viewers (at least evince), the + % lilypond developers report. xpdf does work with the regular 0x27. + % + \def\codequoteright{% + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \else \char'15 \fi + } + % + % and a similar option for the left quote char vs. a grave accent. + % Modern fonts display ASCII 0x60 as a grave accent, so some people like + % the code environments to do likewise. + % + \def\codequoteleft{% + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi + \else \char'22 \fi + } + + % Commands to set the quote options. + % + \parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi + } + % + \parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi + } + + % [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. + \def\noligaturesquoteleft{\relax\lq} + + % Count depth in font-changes, for error checks + \newcount\fontdepth \fontdepth=0 + + % Font commands. + + % #1 is the font command (\sl or \it), #2 is the text to slant. + % If we are in a monospaced environment, however, 1) always use \ttsl, + % and 2) do not add an italic correction. + \def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next + } + \def\smartslanted{\dosmartslant\sl} + \def\smartitalic{\dosmartslant\it} + + % Output an italic correction unless \next (presumed to be the following + % character) is such as not to need one. + \def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ifx\next\.% + \else\ifx\next\comma% + \else\ptexslash + \fi\fi\fi\fi\fi + \aftersmartic + } + + % Unconditional use \ttsl, and no ic. @var is set to this for defuns. + \def\ttslanted#1{{\ttsl #1}} + + % @cite is like \smartslanted except unconditionally use \sl. We never want + % ttsl for book titles, do we? + \def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + + \def\aftersmartic{} + \def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% + } + + \let\i=\smartitalic + \let\slanted=\smartslanted + \let\dfn=\smartslanted + \let\emph=\smartitalic + + % Explicit font changes: @r, @sc, undocumented @ii. + \def\r#1{{\rm #1}} % roman font + \def\sc#1{{\smallcaps#1}} % smallcaps font + \def\ii#1{{\it #1}} % italic font + + % @b, explicit bold. Also @strong. + \def\b#1{{\bf #1}} + \let\strong=\b + + % @sansserif, explicit sans. + \def\sansserif#1{{\sf #1}} + + % We can't just use \exhyphenpenalty, because that only has effect at + % the end of a paragraph. Restore normal hyphenation at the end of the + % group within which \nohyphenation is presumably called. + % + \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} + \def\restorehyphenation{\hyphenchar\font = `- } + + % Set sfcode to normal for the chars that usually have another value. + % Can't use plain's \frenchspacing because it uses the `\x notation, and + % sometimes \x has an active definition that messes things up. + % + \catcode`@=11 + \def\plainfrenchspacing{% + \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m + \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m + \def\endofsentencespacefactor{1000}% for @. and friends + } + \def\plainnonfrenchspacing{% + \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 + \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 + \def\endofsentencespacefactor{3000}% for @. and friends + } + \catcode`@=\other + \def\endofsentencespacefactor{3000}% default + + % @t, explicit typewriter. + \def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null + } + + % @samp. + \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + + % @indicateurl is \samp, that is, with quotes. + \let\indicateurl=\samp + + % @code (and similar) prints in typewriter, but with spaces the same + % size as normal in the surrounding text, without hyphenation, etc. + % This is a subroutine for that. + \def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \plainfrenchspacing + #1% + }% + \null % reset spacefactor to 1000 + } + + % We *must* turn on hyphenation at `-' and `_' in @code. + % (But see \codedashfinish below.) + % Otherwise, it is too hard to avoid overfull hboxes + % in the Emacs manual, the Library manual, etc. + % + % Unfortunately, TeX uses one parameter (\hyphenchar) to control + % both hyphenation at - and hyphenation within words. + % We must therefore turn them both off (\tclose does that) + % and arrange explicitly to hyphenate at a dash. -- rms. + { + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + \global\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\normaldash + \let_\realunder + \fi + % Given -foo (with a single dash), we do not want to allow a break + % after the hyphen. + \global\let\codedashprev=\codedash + % + \codex + } + % + \gdef\codedash{\futurelet\next\codedashfinish} + \gdef\codedashfinish{% + \normaldash % always output the dash character itself. + % + % Now, output a discretionary to allow a line break, unless + % (a) the next character is a -, or + % (b) the preceding character is a -. + % E.g., given --posix, we do not want to allow a break after either -. + % Given --foo-bar, we do want to allow a break between the - and the b. + \ifx\next\codedash \else + \ifx\codedashprev\codedash + \else \discretionary{}{}{}\fi + \fi + % we need the space after the = for the case when \next itself is a + % space token; it would get swallowed otherwise. As in @code{- a}. + \global\let\codedashprev= \next + } + } + \def\normaldash{-} + % + \def\codex #1{\tclose{#1}\endgroup} + + \def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% + } + + % An additional complication: the above will allow breaks after, e.g., + % each of the four underscores in __typeof__. This is bad. + % @allowcodebreaks provides a document-level way to turn breaking at - + % and _ on and off. + % + \newif\ifallowcodebreaks \allowcodebreakstrue + + \def\keywordtrue{true} + \def\keywordfalse{false} + + \parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% + \fi\fi + } + + % For @command, @env, @file, @option quotes seem unnecessary, + % so use \code rather than \samp. + \let\command=\code + \let\env=\code + \let\file=\code + \let\option=\code + + % @uref (abbreviation for `urlref') takes an optional (comma-separated) + % second argument specifying the text to display and an optional third + % arg as text to display instead of (rather than in addition to) the url + % itself. First (mandatory) arg is the url. + % (This \urefnobreak definition isn't used now, leaving it for a while + % for comparison.) + \def\urefnobreak#1{\dourefnobreak #1,,,\finish} + \def\dourefnobreak#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink + \endgroup} + + % This \urefbreak definition is the active one. + \def\urefbreak{\begingroup \urefcatcodes \dourefbreak} + \let\uref=\urefbreak + \def\dourefbreak#1{\urefbreakfinish #1,,,\finish} + \def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink + \endgroup} + + % Allow line breaks around only a few characters (only). + \def\urefcatcodes{% + \catcode\ampChar=\active \catcode\dotChar=\active + \catcode\hashChar=\active \catcode\questChar=\active + \catcode\slashChar=\active + } + { + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} + } + + % we put a little stretch before and after the breakable chars, to help + % line breaking of long url's. The unequal skips make look better in + % cmtt at least, especially for dots. + \def\urefprestretch{\urefprebreak \hskip0pt plus.13em } + \def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } + % + \def\urefcodeamp{\urefprestretch \&\urefpoststretch} + \def\urefcodedot{\urefprestretch .\urefpoststretch} + \def\urefcodehash{\urefprestretch \#\urefpoststretch} + \def\urefcodequest{\urefprestretch ?\urefpoststretch} + \def\urefcodeslash{\futurelet\next\urefcodeslashfinish} + { + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } + } + + % One more complication: by default we'll break after the special + % characters, but some people like to break before the special chars, so + % allow that. Also allow no breaking at all, for manual control. + % + \parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi + } + \def\wordafter{after} + \def\wordbefore{before} + \def\wordnone{none} + + \urefbreakstyle after + + % @url synonym for @uref, since that's how everyone uses it. + % + \let\url=\uref + + % rms does not like angle brackets --karl, 17may97. + % So now @email is just like @uref, unless we are pdf. + % + %\def\email#1{\angleleft{\tt #1}\angleright} + \ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} + \else + \let\email=\uref + \fi + + % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), + % `example' (@kbd uses ttsl only inside of @example and friends), + % or `code' (@kbd uses normal tty font always). + \parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% + \fi\fi\fi + } + \def\worddistinct{distinct} + \def\wordexample{example} + \def\wordcode{code} + + % Default is `distinct'. + \kbdinputstyle distinct + + % @kbd is like @code, except that if the argument is just one @key command, + % then @kbd has no effect. + \def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + + \def\xkey{\key} + \def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + } + + % definition of @key that produces a lozenge. Doesn't adjust to text size. + %\setfont\keyrm\rmshape{8}{1000}{OT1} + %\font\keysy=cmsy9 + %\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% + % \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% + % \vbox{\hrule\kern-0.4pt + % \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% + % \kern-0.4pt\hrule}% + % \kern-.06em\raise0.4pt\hbox{\angleright}}}} + + % definition of @key with no lozenge. If the current font is already + % monospace, don't change it; that way, we respect @kbdinputstyle. But + % if it isn't monospace, then use \tt. + % + \def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} + + % @clicksequence{File @click{} Open ...} + \def\clicksequence#1{\begingroup #1\endgroup} + + % @clickstyle @arrow (by default) + \parseargdef\clickstyle{\def\click{#1}} + \def\click{\arrow} + + % Typeset a dimension, e.g., `in' or `pt'. The only reason for the + % argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. + % + \def\dmn#1{\thinspace #1} + + % @l was never documented to mean ``switch to the Lisp font'', + % and it is not used as such in any manual I can find. We need it for + % Polish suppressed-l. --karl, 22sep96. + %\def\l#1{{\li #1}\null} + + % @acronym for "FBI", "NATO", and the like. + % We print this one point size smaller, since it's intended for + % all-uppercase. + % + \def\acronym#1{\doacronym #1,,\finish} + \def\doacronym#1,#2,#3\finish{% + {\selectfonts\lsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 + } + + % @abbr for "Comput. J." and the like. + % No font change, but don't do end-of-sentence spacing. + % + \def\abbr#1{\doabbr #1,,\finish} + \def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 + } + + % @asis just yields its argument. Used with @table, for example. + % + \def\asis#1{#1} + + % @math outputs its argument in math mode. + % + % One complication: _ usually means subscripts, but it could also mean + % an actual _ character, as in @math{@var{some_variable} + 1}. So make + % _ active, and distinguish by seeing if the current family is \slfam, + % which is what @var uses. + { + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } + } + % Another complication: we want \\ (and @\) to output a math (or tt) \. + % FYI, plain.tex uses \\ as a temporary control sequence (for no + % particular reason), but this is not advertised and we don't care. + % + % The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. + \def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} + % + \def\math{% + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + $\finishmath + } + \def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + + % Some active characters (such as <) are spaced differently in math. + % We have to reset their definitions in case the @math was an argument + % to a command which sets the catcodes (such as @item or @section). + % + { + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } + } + + % ctrl is no longer a Texinfo command, but leave this definition for fun. + \def\ctrl #1{{\tt \rawbackslash \hat}#1} + + % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. + % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, + % except specified as a normal braced arg, so no newlines to worry about. + % + \def\outfmtnametex{tex} + % + \long\def\inlinefmt#1{\doinlinefmt #1,\finish} + \long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi + } + % + % @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if + % FMTNAME is tex, else ELSE-TEXT. + \long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} + \long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi + } + % + % For raw, must switch into @tex before parsing the argument, to avoid + % setting catcodes prematurely. Doing it this way means that, for + % example, @inlineraw{html, foo{bar} gets a parse error instead of being + % ignored. But this isn't important because if people want a literal + % *right* brace they would have to use a command anyway, so they may as + % well use a command to get a left brace too. We could re-use the + % delimiter character idea from \verb, but it seems like overkill. + % + \long\def\inlineraw{\tex \doinlineraw} + \long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} + \def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. + } + + % @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. + % + \long\def\inlineifset#1{\doinlineifset #1,\finish} + \long\def\doinlineifset#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax + \else\ignorespaces#2\fi + } + + % @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. + % + \long\def\inlineifclear#1{\doinlineifclear #1,\finish} + \long\def\doinlineifclear#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi + } + + + \message{glyphs,} + % and logos. + + % @@ prints an @, as does @atchar{}. + \def\@{\char64 } + \let\atchar=\@ + + % @{ @} @lbracechar{} @rbracechar{} all generate brace characters. + % Unless we're in typewriter, use \ecfont because the CM text fonts do + % not have braces, and we don't want to switch into math. + \def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} + \def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} + \let\{=\mylbrace \let\lbracechar=\{ + \let\}=\myrbrace \let\rbracechar=\} + \begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux/toc files. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% + !endgroup + + % @comma{} to avoid , parsing problems. + \let\comma = , + + % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent + % Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. + \let\, = \ptexc + \let\dotaccent = \ptexdot + \def\ringaccent#1{{\accent23 #1}} + \let\tieaccent = \ptext + \let\ubaraccent = \ptexb + \let\udotaccent = \d + + % Other special characters: @questiondown @exclamdown @ordf @ordm + % Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. + \def\questiondown{?`} + \def\exclamdown{!`} + \def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} + \def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} + + % Dotless i and dotless j, used for accents. + \def\imacro{i} + \def\jmacro{j} + \def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi + } + + % The \TeX{} logo, as in plain, but resetting the spacing so that a + % period following counts as ending a sentence. (Idea found in latex.) + % + \edef\TeX{\TeX \spacefactor=1000 } + + % @LaTeX{} logo. Not quite the same results as the definition in + % latex.ltx, since we use a different font for the raised A; it's most + % convenient for us to use an explicitly smaller font, rather than using + % the \scriptstyle font (since we don't reset \scriptstyle and + % \scriptscriptstyle). + % + \def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \selectfonts\lllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX + } + + % Some math mode symbols. + \def\bullet{$\ptexbullet$} + \def\geq{\ifmmode \ge\else $\ge$\fi} + \def\leq{\ifmmode \le\else $\le$\fi} + \def\minus{\ifmmode -\else $-$\fi} + + % @dots{} outputs an ellipsis using the current font. + % We do .5em per period so that it has the same spacing in the cm + % typewriter fonts as three actual period characters; on the other hand, + % in other typewriter fonts three periods are wider than 1.5em. So do + % whichever is larger. + % + \def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% + } + + % @enddots{} is an end-of-sentence ellipsis. + % + \def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor + } + + % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. + % + % Since these characters are used in examples, they should be an even number of + % \tt widths. Each \tt character is 1en, so two makes it 1em. + % + \def\point{$\star$} + \def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} + \def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} + \def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} + \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} + \def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} + + % The @error{} command. + % Adapted from the TeXbook's \boxit. + % + \newbox\errorbox + % + {\tentt \global\dimen0 = 3em}% Width of the box. + \dimen2 = .55pt % Thickness of rules + % The text. (`r' is open on the right, `e' somewhat less so on the left.) + \setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} + % + \setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{% + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} + % + \def\error{\leavevmode\lower.7ex\copy\errorbox} + + % @pounds{} is a sterling sign, which Knuth put in the CM italic font. + % + \def\pounds{{\it\$}} + + % @euro{} comes from a separate font, depending on the current style. + % We use the free feym* fonts from the eurosym package by Henrik + % Theiling, which support regular, slanted, bold and bold slanted (and + % "outlined" (blackboard board, sort of) versions, which we don't need). + % It is available from http://www.ctan.org/tex-archive/fonts/eurosym. + % + % Although only regular is the truly official Euro symbol, we ignore + % that. The Euro is designed to be slightly taller than the regular + % font height. + % + % feymr - regular + % feymo - slanted + % feybr - bold + % feybo - bold slanted + % + % There is no good (free) typewriter version, to my knowledge. + % A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. + % Hmm. + % + % Also doesn't work in math. Do we need to do math with euro symbols? + % Hope not. + % + % + \def\euro{{\eurofont e}} + \def\eurofont{% + % We set the font at each command, rather than predefining it in + % \textfonts and the other font-switching commands, so that + % installations which never need the symbol don't have to have the + % font installed. + % + % There is only one designed size (nominal 10pt), so we always scale + % that to the current nominal size. + % + % By the way, simply using "at 1em" works for cmr10 and the like, but + % does not work for cmbx10 and other extended/shrunken fonts. + % + \def\eurosize{\csname\curfontsize nominalsize\endcsname}% + % + \ifx\curfontstyle\bfstylename + % bold: + \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize + \else + % regular: + \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize + \fi + \thiseurofont + } + + % Glyphs from the EC fonts. We don't use \let for the aliases, because + % sometimes we redefine the original macro, and the alias should reflect + % the redefinition. + % + % Use LaTeX names for the Icelandic letters. + \def\DH{{\ecfont \char"D0}} % Eth + \def\dh{{\ecfont \char"F0}} % eth + \def\TH{{\ecfont \char"DE}} % Thorn + \def\th{{\ecfont \char"FE}} % thorn + % + \def\guillemetleft{{\ecfont \char"13}} + \def\guillemotleft{\guillemetleft} + \def\guillemetright{{\ecfont \char"14}} + \def\guillemotright{\guillemetright} + \def\guilsinglleft{{\ecfont \char"0E}} + \def\guilsinglright{{\ecfont \char"0F}} + \def\quotedblbase{{\ecfont \char"12}} + \def\quotesinglbase{{\ecfont \char"0D}} + % + % This positioning is not perfect (see the ogonek LaTeX package), but + % we have the precomposed glyphs for the most common cases. We put the + % tests to use those glyphs in the single \ogonek macro so we have fewer + % dummy definitions to worry about for index entries, etc. + % + % ogonek is also used with other letters in Lithuanian (IOU), but using + % the precomposed glyphs for those is not so easy since they aren't in + % the same EC font. + \def\ogonek#1{{% + \def\temp{#1}% + \ifx\temp\macrocharA\Aogonek + \else\ifx\temp\macrochara\aogonek + \else\ifx\temp\macrocharE\Eogonek + \else\ifx\temp\macrochare\eogonek + \else + \ecfont \setbox0=\hbox{#1}% + \ifdim\ht0=1ex\accent"0C #1% + \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% + \fi + \fi\fi\fi\fi + }% + } + \def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} + \def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} + \def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} + \def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} + % + % Use the ec* fonts (cm-super in outline format) for non-CM glyphs. + \def\ecfont{% + % We can't distinguish serif/sans and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifmonospace + % typewriter: + \font\thisecfont = ectt\ecsize \space at \nominalsize + \else + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \fi + \thisecfont + } + + % @registeredsymbol - R in a circle. The font for the R should really + % be smaller yet, but lllsize is the best we can do for now. + % Adapted from the plain.tex definition of \copyright. + % + \def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% + \hfil\crcr\Orb}}% + }$% + } + + % @textdegree - the normal degrees sign. + % + \def\textdegree{$^\circ$} + + % Laurent Siebenmann reports \Orb undefined with: + % Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 + % so we'll define it if necessary. + % + \ifx\Orb\thisisundefined + \def\Orb{\mathhexbox20D} + \fi + + % Quotes. + \chardef\quotedblleft="5C + \chardef\quotedblright=`\" + \chardef\quoteleft=`\` + \chardef\quoteright=`\' + + + \message{page headings,} + + \newskip\titlepagetopglue \titlepagetopglue = 1.5in + \newskip\titlepagebottomglue \titlepagebottomglue = 2pc + + % First the title page. Must do @settitle before @titlepage. + \newif\ifseenauthor + \newif\iffinishedtitlepage + + % Do an implicit @contents or @shortcontents after @end titlepage if the + % user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. + % + \newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue + \newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + + \parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + + \envdef\titlepage{% + % Open one extra group, as we want to close it in the middle of \Etitlepage. + \begingroup + \parindent=0pt \textfonts + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \let\page = \oldpage + \page + \null + }% + } + + \def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi + } + + \def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue + } + + % Settings used for typesetting titles: no hyphenation, no indentation, + % don't worry much about spacing, ragged right. This should be used + % inside a \vbox, and fonts need to be set appropriately first. Because + % it is always used for titles, nothing else, we call \rmisbold. \par + % should be specified before the end of the \vbox, since a vbox is a group. + % + \def\raggedtitlesettings{% + \rmisbold + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright + } + + % Macros to be used within @titlepage: + + \let\subtitlerm=\tenrm + \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} + + \parseargdef\title{% + \checkenv\titlepage + \vbox{\titlefonts \raggedtitlesettings #1\par}% + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt + } + + \parseargdef\subtitle{% + \checkenv\titlepage + {\subtitlefont \rightline{#1}}% + } + + % @author should come last, but may come many times. + % It can also be used inside @quotation. + % + \parseargdef\author{% + \def\temp{\quotation}% + \ifx\thisenv\temp + \def\quotationauthor{#1}% printed in \Equotation. + \else + \checkenv\titlepage + \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi + {\secfonts\rmisbold \leftline{#1}}% + \fi + } + + + % Set up page headings and footings. + + \let\thispage=\folio + + \newtoks\evenheadline % headline on even pages + \newtoks\oddheadline % headline on odd pages + \newtoks\evenfootline % footline on even pages + \newtoks\oddfootline % footline on odd pages + + % Now make TeX use those variables + \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} + \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} + \let\HEADINGShook=\relax + + % Commands to set those variables. + % For example, this is what @headings on does + % @evenheading @thistitle|@thispage|@thischapter + % @oddheading @thischapter|@thispage|@thistitle + % @evenfooting @thisfile|| + % @oddfooting ||@thisfile + + + \def\evenheading{\parsearg\evenheadingxxx} + \def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} + \def\evenheadingyyy #1\|#2\|#3\|#4\finish{% + \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \def\oddheading{\parsearg\oddheadingxxx} + \def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} + \def\oddheadingyyy #1\|#2\|#3\|#4\finish{% + \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + + \def\evenfooting{\parsearg\evenfootingxxx} + \def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} + \def\evenfootingyyy #1\|#2\|#3\|#4\finish{% + \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + + \def\oddfooting{\parsearg\oddfootingxxx} + \def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} + \def\oddfootingyyy #1\|#2\|#3\|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -12pt + \global\advance\vsize by -12pt + } + + \parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} + + % @evenheadingmarks top \thischapter <- chapter at the top of a page + % @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page + % + % The same set of arguments for: + % + % @oddheadingmarks + % @evenfootingmarks + % @oddfootingmarks + % @everyheadingmarks + % @everyfootingmarks + + \def\evenheadingmarks{\headingmarks{even}{heading}} + \def\oddheadingmarks{\headingmarks{odd}{heading}} + \def\evenfootingmarks{\headingmarks{even}{footing}} + \def\oddfootingmarks{\headingmarks{odd}{footing}} + \def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } + \def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } + % #1 = even/odd, #2 = heading/footing, #3 = top/bottom. + \def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp + } + + \everyheadingmarks bottom + \everyfootingmarks bottom + + % @headings double turns headings on for double-sided printing. + % @headings single turns headings on for single-sided printing. + % @headings off turns them off. + % @headings on same as @headings double, retained for compatibility. + % @headings after turns on double-sided headings after this page. + % @headings doubleafter turns on double-sided headings after this page. + % @headings singleafter turns on single-sided headings after this page. + % By default, they are off at the start of a document, + % and turned `on' after @end titlepage. + + \def\headings #1 {\csname HEADINGS#1\endcsname} + + \def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% + } + + \def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting + \HEADINGSoff % it's the default + + % When we turn headings on, set the page number to 1. + % For double-sided printing, put current file name in lower left corner, + % chapter name on inside top of right hand pages, document + % title on inside top of left hand pages, and page numbers on outside top + % edge of all pages. + \def\HEADINGSdouble{% + \global\pageno=1 + \global\evenfootline={\hfil} + \global\oddfootline={\hfil} + \global\evenheadline={\line{\folio\hfil\thistitle}} + \global\oddheadline={\line{\thischapter\hfil\folio}} + \global\let\contentsalignmacro = \chapoddpage + } + \let\contentsalignmacro = \chappager + + % For single-sided printing, chapter title goes across top left of page, + % page number on top right. + \def\HEADINGSsingle{% + \global\pageno=1 + \global\evenfootline={\hfil} + \global\oddfootline={\hfil} + \global\evenheadline={\line{\thischapter\hfil\folio}} + \global\oddheadline={\line{\thischapter\hfil\folio}} + \global\let\contentsalignmacro = \chappager + } + \def\HEADINGSon{\HEADINGSdouble} + + \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} + \let\HEADINGSdoubleafter=\HEADINGSafter + \def\HEADINGSdoublex{% + \global\evenfootline={\hfil} + \global\oddfootline={\hfil} + \global\evenheadline={\line{\folio\hfil\thistitle}} + \global\oddheadline={\line{\thischapter\hfil\folio}} + \global\let\contentsalignmacro = \chapoddpage + } + + \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} + \def\HEADINGSsinglex{% + \global\evenfootline={\hfil} + \global\oddfootline={\hfil} + \global\evenheadline={\line{\thischapter\hfil\folio}} + \global\oddheadline={\line{\thischapter\hfil\folio}} + \global\let\contentsalignmacro = \chappager + } + + % Subroutines used in generating headings + % This produces Day Month Year style of output. + % Only define if not already defined, in case a txi-??.tex file has set + % up a different format (e.g., txi-cs.tex does this). + \ifx\today\thisisundefined + \def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} + \fi + + % @settitle line... specifies the title of the document, for headings. + % It generates no output of its own. + \def\thistitle{\putwordNoTitle} + \def\settitle{\parsearg{\gdef\thistitle}} + + + \message{tables,} + % Tables -- @table, @ftable, @vtable, @item(x). + + % default indentation of table text + \newdimen\tableindent \tableindent=.8in + % default indentation of @itemize and @enumerate text + \newdimen\itemindent \itemindent=.3in + % margin between end of table item and start of table text. + \newdimen\itemmargin \itemmargin=.1in + + % used internally for \itemindent minus \itemmargin + \newdimen\itemmax + + % Note @table, @ftable, and @vtable define @item, @itemx, etc., with + % these defs. + % They also define \itemindex + % to index the item name in whatever manner is desired (perhaps none). + + \newif\ifitemxneedsnegativevskip + + \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + + \def\internalBitem{\smallbreak \parsearg\itemzzz} + \def\internalBitemx{\itemxpar \parsearg\itemzzz} + + \def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemindicate{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil\relax + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. However, if + % what follows is an environment such as @example, there will be no + % \parskip glue; then the negative vskip we just inserted would + % cause the example and the item to crash together. So we use this + % bizarre value of 10001 as a signal to \aboveenvbreak to insert + % \parskip glue after all. Section titles are handled this way also. + % + \penalty 10001 + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi + } + + \def\item{\errmessage{@item while not in a list environment}} + \def\itemx{\errmessage{@itemx while not in a list environment}} + + % @table, @ftable, @vtable. + \envdef\table{% + \let\itemindex\gobble + \tablecheck{table}% + } + \envdef\ftable{% + \def\itemindex ##1{\doind {fn}{\code{##1}}}% + \tablecheck{ftable}% + } + \envdef\vtable{% + \def\itemindex ##1{\doind {vr}{\code{##1}}}% + \tablecheck{vtable}% + } + \def\tablecheck#1{% + \ifnum \the\catcode`\^^M=\active + \endgroup + \errmessage{This command won't work in this context; perhaps the problem is + that we are \inenvironment\thisenv}% + \def\next{\doignore{#1}}% + \else + \let\next\tablex + \fi + \next + } + \def\tablex#1{% + \def\itemindicate{#1}% + \parsearg\tabley + } + \def\tabley#1{% + {% + \makevalueexpandable + \edef\temp{\noexpand\tablez #1\space\space\space}% + \expandafter + }\temp \endtablez + } + \def\tablez #1 #2 #3 #4\endtablez{% + \aboveenvbreak + \ifnum 0#1>0 \advance \leftskip by #1\mil \fi + \ifnum 0#2>0 \tableindent=#2\mil \fi + \ifnum 0#3>0 \advance \rightskip by #3\mil \fi + \itemmax=\tableindent + \advance \itemmax by -\itemmargin + \advance \leftskip by \tableindent + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi + \let\item = \internalBitem + \let\itemx = \internalBitemx + } + \def\Etable{\endgraf\afterenvbreak} + \let\Eftable\Etable + \let\Evtable\Etable + \let\Eitemize\Etable + \let\Eenumerate\Etable + + % This is the counter used by @enumerate, which is really @itemize + + \newcount \itemno + + \envdef\itemize{\parsearg\doitemize} + + \def\doitemize#1{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + % + % Try typesetting the item mark that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if + % the user wants an empty mark, they have to say @w{} not just @w. + \def\itemcontents{#1}% + \setbox0 = \hbox{\itemcontents}% + % + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + % + \let\item=\itemizeitem + } + + % Definition of @item while inside @itemize and @enumerate. + % + \def\itemizeitem{% + \advance\itemno by 1 % for enumerations + {\let\par=\endgraf \smallbreak}% reasonable place to break + {% + % If the document has an @itemize directly after a section title, a + % \nobreak will be last on the list, and \sectionheading will have + % done a \vskip-\parskip. In that case, we don't want to zero + % parskip, or the item text will crash with the heading. On the + % other hand, when there is normal text preceding the item (as there + % usually is), we do want to zero parskip, or there would be too much + % space. In that case, we won't have a \nobreak before. At least + % that's the theory. + \ifnum\lastpenalty<10000 \parskip=0in \fi + \noindent + \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% + % + \vadjust{\penalty 1200}}% not good to break after first line of item. + \flushcr + } + + % \splitoff TOKENS\endmark defines \first to be the first token in + % TOKENS, and \rest to be the remainder. + % + \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + + % Allow an optional argument of an uppercase letter, lowercase letter, + % or number, to specify the first label in the enumerated list. No + % argument is the same as `1'. + % + \envparseargdef\enumerate{\enumeratey #1 \endenumeratey} + \def\enumeratey #1 #2\endenumeratey{% + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi + } + + % An @enumerate whose labels are integers. The starting integer is + % given in \thearg. + % + \def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% + } + + % The starting (lowercase) letter is in \thearg. + \def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% + } + + % The starting (uppercase) letter is in \thearg. + \def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% + } + + % Call \doitemize, adding a period to the first argument and supplying the + % common last two arguments. Also subtract one from the initial value in + % \itemno, since @item increments \itemno. + % + \def\startenumeration#1{% + \advance\itemno by -1 + \doitemize{#1.}\flushcr + } + + % @alphaenumerate and @capsenumerate are abbreviations for giving an arg + % to @enumerate. + % + \def\alphaenumerate{\enumerate{a}} + \def\capsenumerate{\enumerate{A}} + \def\Ealphaenumerate{\Eenumerate} + \def\Ecapsenumerate{\Eenumerate} + + + % @multitable macros + % Amy Hendrickson, 8/18/94, 3/6/96 + % + % @multitable ... @end multitable will make as many columns as desired. + % Contents of each column will wrap at width given in preamble. Width + % can be specified either with sample text given in a template line, + % or in percent of \hsize, the current width of text on page. + + % Table can continue over pages but will only break between lines. + + % To make preamble: + % + % Either define widths of columns in terms of percent of \hsize: + % @multitable @columnfractions .25 .3 .45 + % @item ... + % + % Numbers following @columnfractions are the percent of the total + % current hsize to be used for each column. You may use as many + % columns as desired. + + + % Or use a template: + % @multitable {Column 1 template} {Column 2 template} {Column 3 template} + % @item ... + % using the widest term desired in each column. + + % Each new table line starts with @item, each subsequent new column + % starts with @tab. Empty columns may be produced by supplying @tab's + % with nothing between them for as many times as empty columns are needed, + % ie, @tab@tab@tab will produce two empty columns. + + % @item, @tab do not need to be on their own lines, but it will not hurt + % if they are. + + % Sample multitable: + + % @multitable {Column 1 template} {Column 2 template} {Column 3 template} + % @item first col stuff @tab second col stuff @tab third col + % @item + % first col stuff + % @tab + % second col stuff + % @tab + % third col + % @item first col stuff @tab second col stuff + % @tab Many paragraphs of text may be used in any column. + % + % They will wrap at the width determined by the template. + % @item@tab@tab This will be in third column. + % @end multitable + + % Default dimensions may be reset by user. + % @multitableparskip is vertical space between paragraphs in table. + % @multitableparindent is paragraph indent in table. + % @multitablecolmargin is horizontal space to be left between columns. + % @multitablelinespace is space to leave between table items, baseline + % to baseline. + % 0pt means it depends on current normal line spacing. + % + \newskip\multitableparskip + \newskip\multitableparindent + \newdimen\multitablecolspace + \newskip\multitablelinespace + \multitableparskip=0pt + \multitableparindent=6pt + \multitablecolspace=12pt + \multitablelinespace=0pt + + % Macros used to set up halign preamble: + % + \let\endsetuptable\relax + \def\xendsetuptable{\endsetuptable} + \let\columnfractions\relax + \def\xcolumnfractions{\columnfractions} + \newif\ifsetpercent + + % #1 is the @columnfraction, usually a decimal number like .5, but might + % be just 1. We just use it, whatever it is. + % + \def\pickupwholefraction#1 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \setuptable + } + + \newcount\colcount + \def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go + } + + % multitable-only commands. + % + % @headitem starts a heading row, which we typeset in bold. + % Assignments have to be global since we are inside the implicit group + % of an alignment entry. \everycr resets \everytab so we don't have to + % undo it ourselves. + \def\headitemfont{\b}% for people to use in the template row; not changeable + \def\headitem{% + \checkenv\multitable + \crcr + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item + }% + % + % A \tab used to include \hskip1sp. But then the space in a template + % line is not enough. That is bad. So let's go back to just `&' until + % we again encounter the problem the 1sp was intended to solve. + % --karl, nathan@acm.org, 20apr99. + \def\tab{\checkenv\multitable &\the\everytab}% + + % @multitable ... @end multitable definitions: + % + \newtoks\everytab % insert after every tab. + % + \envdef\multitable{% + \vskip\parskip + \startsavinginserts + % + % @item within a multitable starts a normal row. + % We use \def instead of \let so that if one of the multitable entries + % contains an @itemize, we don't choke on the \item (seen as \crcr aka + % \endtemplate) expanding \doitemize. + \def\item{\crcr}% + % + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + % + \everycr = {% + \noalign{% + \global\everytab={}% + \global\colcount=0 % Reset the column counter. + % Check for saved footnotes, etc. + \checkinserts + % Keeps underfull box messages off when table breaks over pages. + %\filbreak + % Maybe so, but it also creates really weird page breaks when the + % table breaks over pages. Wouldn't \vfil be better? Wait until the + % problem manifests itself, so it can be fixed for real --karl. + }% + }% + % + \parsearg\domultitable + } + \def\domultitable#1{% + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup &% + \global\advance\colcount by 1 + \multistrut + \vtop{% + % Use the current \colcount to find the correct column width: + \hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively + % marking characters. + \noindent\ignorespaces##\unskip\multistrut + }\cr + } + \def\Emultitable{% + \crcr + \egroup % end the \halign + \global\setpercentfalse + } + + \def\setmultitablespacing{% + \def\multistrut{\strut}% just use the standard line spacing + % + % Compute \multitablelinespace (if not defined by user) for use in + % \multitableparskip calculation. We used define \multistrut based on + % this, but (ironically) that caused the spacing to be off. + % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. + \ifdim\multitablelinespace=0pt + \setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip + \global\advance\multitablelinespace by-\ht0 + \fi + % Test to see if parskip is larger than space between lines of + % table. If not, do nothing. + % If so, set to same dimension as multitablelinespace. + \ifdim\multitableparskip>\multitablelinespace + \global\multitableparskip=\multitablelinespace + \global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. + \fi% + \ifdim\multitableparskip=0pt + \global\multitableparskip=\multitablelinespace + \global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. + \fi} + + + \message{conditionals,} + + % @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, + % @ifnotxml always succeed. They currently do nothing; we don't + % attempt to check whether the conditionals are properly nested. But we + % have to remember that they are conditionals, so that @end doesn't + % attempt to close an environment group. + % + \def\makecond#1{% + \expandafter\let\csname #1\endcsname = \relax + \expandafter\let\csname iscond.#1\endcsname = 1 + } + \makecond{iftex} + \makecond{ifnotdocbook} + \makecond{ifnothtml} + \makecond{ifnotinfo} + \makecond{ifnotplaintext} + \makecond{ifnotxml} + + % Ignore @ignore, @ifhtml, @ifinfo, and the like. + % + \def\direntry{\doignore{direntry}} + \def\documentdescription{\doignore{documentdescription}} + \def\docbook{\doignore{docbook}} + \def\html{\doignore{html}} + \def\ifdocbook{\doignore{ifdocbook}} + \def\ifhtml{\doignore{ifhtml}} + \def\ifinfo{\doignore{ifinfo}} + \def\ifnottex{\doignore{ifnottex}} + \def\ifplaintext{\doignore{ifplaintext}} + \def\ifxml{\doignore{ifxml}} + \def\ignore{\doignore{ignore}} + \def\menu{\doignore{menu}} + \def\xml{\doignore{xml}} + + % Ignore text until a line `@end #1', keeping track of nested conditionals. + % + % A count to remember the depth of nesting. + \newcount\doignorecount + + \def\doignore#1{\begingroup + % Scan in ``verbatim'' mode: + \obeylines + \catcode`\@ = \other + \catcode`\{ = \other + \catcode`\} = \other + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \spaceisspace + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \dodoignore{#1}% + } + + { \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1{% + % #1 contains the command name as a string, e.g., `ifinfo'. + % + % Define a command to find the next `@end #1'. + \long\def\doignoretext##1^^M@end #1{% + \doignoretextyyy##1^^M@#1\_STOP_}% + % + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% + % + % And now expand that command. + \doignoretext ^^M% + }% + } + + \def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \_STOP_ is present just after this macro. + } + + % We have to swallow the remaining "\_STOP_". + % + \def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next + } + + % Finish off ignored text. + { \obeylines% + % Ignore anything after the last `@end #1'; this matters in verbatim + % environments, where otherwise the newline after an ignored conditional + % would result in a blank line in the output. + \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% + } + + + % @set VAR sets the variable VAR to an empty value. + % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. + % + % Since we want to separate VAR from REST-OF-LINE (which might be + % empty), we can't just use \parsearg; we have to insert a space of our + % own to delimit the rest of the line, and then take it out again if we + % didn't need it. + % We rely on the fact that \parsearg sets \catcode`\ =10. + % + \parseargdef\set{\setyyy#1 \endsetyyy} + \def\setyyy#1 #2\endsetyyy{% + {% + \makevalueexpandable + \def\temp{#2}% + \edef\next{\gdef\makecsname{SET#1}}% + \ifx\temp\empty + \next{}% + \else + \setzzz#2\endsetzzz + \fi + }% + } + % Remove the trailing space \setxxx inserted. + \def\setzzz#1 \endsetzzz{\next{#1}} + + % @clear VAR clears (i.e., unsets) the variable VAR. + % + \parseargdef\clear{% + {% + \makevalueexpandable + \global\expandafter\let\csname SET#1\endcsname=\relax + }% + } + + % @value{foo} gets the text saved in variable foo. + \def\value{\begingroup\makevalueexpandable\valuexxx} + \def\valuexxx#1{\expandablevalue{#1}\endgroup} + { + \catcode`\-=\active \catcode`\_=\active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue + % We don't want these characters active, ... + \catcode`\-=\other \catcode`\_=\other + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. + \let-\normaldash \let_\normalunderscore + } + } + + % We have this subroutine so that we can handle at least some @value's + % properly in indexes (we call \makevalueexpandable in \indexdummies). + % The command has to be fully expandable (if the variable is set), since + % the result winds up in the index file. This means that if the + % variable's value contains other Texinfo commands, it's almost certain + % it will fail (although perhaps we could fix that with sufficient work + % to do a one-level expansion on the result, instead of complete). + % + % Unfortunately, this has the consequence that when _ is in the *value* + % of an @set, it does not print properly in the roman fonts (get the cmr + % dot accent at position 126 instead). No fix comes to mind, and it's + % been this way since 2003 or earlier, so just ignore it. + % + \def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi + } + + % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined + % with @set. + % + % To get the special treatment we need for `@end ifset,' we call + % \makecond and then redefine. + % + \makecond{ifset} + \def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} + \def\doifset#1#2{% + {% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname SET#2\endcsname\relax + #1% If not set, redefine \next. + \fi + \expandafter + }\next + } + \def\ifsetfail{\doignore{ifset}} + + % @ifclear VAR ... @end executes the `...' iff VAR has never been + % defined with @set, or has been undefined with @clear. + % + % The `\else' inside the `\doifset' parameter is a trick to reuse the + % above code: if the variable is not set, do nothing, if it is set, + % then redefine \next to \ifclearfail. + % + \makecond{ifclear} + \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} + \def\ifclearfail{\doignore{ifclear}} + + % @ifcommandisdefined CMD ... @end executes the `...' if CMD (written + % without the @) is in fact defined. We can only feasibly check at the + % TeX level, so something like `mathcode' is going to considered + % defined even though it is not a Texinfo command. + % + \makecond{ifcommanddefined} + \def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} + % + \def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next + } + \def\ifcmddefinedfail{\doignore{ifcommanddefined}} + + % @ifcommandnotdefined CMD ... handled similar to @ifclear above. + \makecond{ifcommandnotdefined} + \def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} + \def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + + % Set the `txicommandconditionals' variable, so documents have a way to + % test if the @ifcommand...defined conditionals are available. + \set txicommandconditionals + + % @dircategory CATEGORY -- specify a category of the dir file + % which this file should belong to. Ignore this in TeX. + \let\dircategory=\comment + + % @defininfoenclose. + \let\definfoenclose=\comment + + + \message{indexing,} + % Index generation facilities + + % Define \newwrite to be identical to plain tex's \newwrite + % except not \outer, so it can be used within macros and \if's. + \edef\newwrite{\makecsname{ptexnewwrite}} + + % \newindex {foo} defines an index named foo. + % It automatically defines \fooindex such that + % \fooindex ...rest of line... puts an entry in the index foo. + % It also defines \fooindfile to be the number of the output channel for + % the file that accumulates this index. The file's extension is foo. + % The name of an index should be no more than 2 characters long + % for the sake of vms. + % + \def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} + } + + % @defindex foo == \newindex{foo} + % + \def\defindex{\parsearg\newindex} + + % Define @defcodeindex, like @defindex except put all entries in @code. + % + \def\defcodeindex{\parsearg\newcodeindex} + % + \def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% + } + + + % @synindex foo bar makes index foo feed into index bar. + % Do this instead of @defindex foo if you don't want it as a separate index. + % + % @syncodeindex foo bar similar, but put all entries made for index foo + % inside @code. + % + \def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} + \def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + + % #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), + % #3 the target index (bar). + \def\dosynindex#1#2#3{% + % Only do \closeout if we haven't already done it, else we'll end up + % closing the target index. + \expandafter \ifx\csname donesynindex#2\endcsname \relax + % The \closeout helps reduce unnecessary open files; the limit on the + % Acorn RISC OS is a mere 16 files. + \expandafter\closeout\csname#2indfile\endcsname + \expandafter\let\csname donesynindex#2\endcsname = 1 + \fi + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% + } + + % Define \doindex, the driver for all \fooindex macros. + % Argument #1 is generated by the calling \fooindex macro, + % and it is "foo", the name of the index. + + % \doindex just uses \parsearg; it calls \doind for the actual work. + % This is because \doind is more useful to call from other macros. + + % There is also \dosubind {index}{topic}{subtopic} + % which makes an entry in a two-level index such as the operation index. + + \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} + \def\singleindexer #1{\doind{\indexname}{#1}} + + % like the previous two, but they put @code around the argument. + \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} + \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + + % Take care of Texinfo commands that can appear in an index entry. + % Since there are some commands we want to expand, and others we don't, + % we have to laboriously prevent expansion for those that we don't. + % + \def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \def\@{@}% change to @@ when we switch to @ as escape char in index files. + \def\ {\realbackslash\space }% + % + % Need these unexpandable (because we define \tt as a dummy) + % definitions when @{ or @} appear in index entry text. Also, more + % complicated, when \tex is in effect and \{ is a \delimiter again. + % We can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. Perhaps we + % should define @lbrace and @rbrace commands a la @comma. + \def\{{{\tt\char123}}% + \def\}{{\tt\char125}}% + % + % I don't entirely understand this, but when an index entry is + % generated from a macro call, the \endinput which \scanmacro inserts + % causes processing to be prematurely terminated. This is, + % apparently, because \indexsorttmp is fully expanded, and \endinput + % is an expandable command. The redefinition below makes \endinput + % disappear altogether for that purpose -- although logging shows that + % processing continues to some further point. On the other hand, it + % seems \endinput does not hurt in the printed index arg, since that + % is still getting written without apparent harm. + % + % Sample source (mac-idx3.tex, reported by Graham Percival to + % help-texinfo, 22may06): + % @macro funindex {WORD} + % @findex xyz + % @end macro + % ... + % @funindex commtest + % + % The above is not enough to reproduce the bug, but it gives the flavor. + % + % Sample whatsit resulting: + % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} + % + % So: + \let\endinput = \empty + % + % Do the redefinitions. + \commondummies + } + + % For the aux and toc files, @ is the escape character. So we want to + % redefine everything using @ as the escape character (instead of + % \realbackslash, still used for index files). When everything uses @, + % this will be simpler. + % + \def\atdummies{% + \def\@{@@}% + \def\ {@ }% + \let\{ = \lbraceatcmd + \let\} = \rbraceatcmd + % + % Do the redefinitions. + \commondummies + \otherbackslash + } + + % Called from \indexdummies and \atdummies. + % + \def\commondummies{% + % + % \definedummyword defines \#1 as \string\#1\space, thus effectively + % preventing its expansion. This is used only for control words, + % not control letters, because the \space would be incorrect for + % control characters, but is needed to separate the control word + % from whatever follows. + % + % For control letters, we have \definedummyletter, which omits the + % space. + % + % These can be used both for control words that take an argument and + % those that do not. If it is followed by {arg} in the input, then + % that will dutifully get written to the index (or wherever). + % + \def\definedummyword ##1{\def##1{\string##1\space}}% + \def\definedummyletter##1{\def##1{\string##1}}% + \let\definedummyaccent\definedummyletter + % + \commondummiesnofonts + % + \definedummyletter\_% + \definedummyletter\-% + % + % Non-English letters. + \definedummyword\AA + \definedummyword\AE + \definedummyword\DH + \definedummyword\L + \definedummyword\O + \definedummyword\OE + \definedummyword\TH + \definedummyword\aa + \definedummyword\ae + \definedummyword\dh + \definedummyword\exclamdown + \definedummyword\l + \definedummyword\o + \definedummyword\oe + \definedummyword\ordf + \definedummyword\ordm + \definedummyword\questiondown + \definedummyword\ss + \definedummyword\th + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword\bf + \definedummyword\gtr + \definedummyword\hat + \definedummyword\less + \definedummyword\sf + \definedummyword\sl + \definedummyword\tclose + \definedummyword\tt + % + \definedummyword\LaTeX + \definedummyword\TeX + % + % Assorted special characters. + \definedummyword\arrow + \definedummyword\bullet + \definedummyword\comma + \definedummyword\copyright + \definedummyword\registeredsymbol + \definedummyword\dots + \definedummyword\enddots + \definedummyword\entrybreak + \definedummyword\equiv + \definedummyword\error + \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq + \definedummyword\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\lbracechar + \definedummyword\leq + \definedummyword\minus + \definedummyword\ogonek + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \definedummyword\rbracechar + \definedummyword\result + \definedummyword\textdegree + % + % We want to disable all macros so that they are not expanded by \write. + \macrolist + % + \normalturnoffactive + % + % Handle some cases of @value -- where it does not contain any + % (non-fully-expandable) commands. + \makevalueexpandable + } + + % \commondummiesnofonts: common to \commondummies and \indexnofonts. + % + \def\commondummiesnofonts{% + % Control letters and accents. + \definedummyletter\!% + \definedummyaccent\"% + \definedummyaccent\'% + \definedummyletter\*% + \definedummyaccent\,% + \definedummyletter\.% + \definedummyletter\/% + \definedummyletter\:% + \definedummyaccent\=% + \definedummyletter\?% + \definedummyaccent\^% + \definedummyaccent\`% + \definedummyaccent\~% + \definedummyword\u + \definedummyword\v + \definedummyword\H + \definedummyword\dotaccent + \definedummyword\ogonek + \definedummyword\ringaccent + \definedummyword\tieaccent + \definedummyword\ubaraccent + \definedummyword\udotaccent + \definedummyword\dotless + % + % Texinfo font commands. + \definedummyword\b + \definedummyword\i + \definedummyword\r + \definedummyword\sansserif + \definedummyword\sc + \definedummyword\slanted + \definedummyword\t + % + % Commands that take arguments. + \definedummyword\abbr + \definedummyword\acronym + \definedummyword\anchor + \definedummyword\cite + \definedummyword\code + \definedummyword\command + \definedummyword\dfn + \definedummyword\dmn + \definedummyword\email + \definedummyword\emph + \definedummyword\env + \definedummyword\file + \definedummyword\image + \definedummyword\indicateurl + \definedummyword\inforef + \definedummyword\kbd + \definedummyword\key + \definedummyword\math + \definedummyword\option + \definedummyword\pxref + \definedummyword\ref + \definedummyword\samp + \definedummyword\strong + \definedummyword\tie + \definedummyword\uref + \definedummyword\url + \definedummyword\var + \definedummyword\verb + \definedummyword\w + \definedummyword\xref + } + + % \indexnofonts is used when outputting the strings to sort the index + % by, and when constructing control sequence names. It eliminates all + % control sequences and just writes whatever the best ASCII sort string + % would be for a given command (usually its argument). + % + \def\indexnofonts{% + % Accent commands should become @asis. + \def\definedummyaccent##1{\let##1\asis}% + % We can just ignore other control letters. + \def\definedummyletter##1{\let##1\empty}% + % All control words become @asis by default; overrides below. + \let\definedummyword\definedummyaccent + % + \commondummiesnofonts + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + \def\ { }% + \def\@{@}% + \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + % Unfortunately, texindex is not prepared to handle braces in the + % content at all. So for index sorting, we map @{ and @} to strings + % starting with |, since that ASCII character is between ASCII { and }. + \def\{{|a}% + \def\lbracechar{|a}% + % + \def\}{|b}% + \def\rbracechar{|b}% + % + % Non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\DH{DZZ}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\TH{ZZZ}% + \def\aa{aa}% + \def\ae{ae}% + \def\dh{dzz}% + \def\exclamdown{!}% + \def\l{l}% + \def\oe{oe}% + \def\ordf{a}% + \def\ordm{o}% + \def\o{o}% + \def\questiondown{?}% + \def\ss{ss}% + \def\th{zzz}% + % + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% + % + % Assorted special characters. + % (The following {} will end up in the sort string, but that's ok.) + \def\arrow{->}% + \def\bullet{bullet}% + \def\comma{,}% + \def\copyright{copyright}% + \def\dots{...}% + \def\enddots{...}% + \def\equiv{==}% + \def\error{error}% + \def\euro{euro}% + \def\expansion{==>}% + \def\geq{>=}% + \def\guillemetleft{<<}% + \def\guillemetright{>>}% + \def\guilsinglleft{<}% + \def\guilsinglright{>}% + \def\leq{<=}% + \def\minus{-}% + \def\point{.}% + \def\pounds{pounds}% + \def\print{-|}% + \def\quotedblbase{"}% + \def\quotedblleft{"}% + \def\quotedblright{"}% + \def\quoteleft{`}% + \def\quoteright{'}% + \def\quotesinglbase{,}% + \def\registeredsymbol{R}% + \def\result{=>}% + \def\textdegree{o}% + % + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax + \else \indexlquoteignore \fi + % + % We need to get rid of all macros, leaving only the arguments (if present). + % Of course this is not nearly correct, but it is the best we can do for now. + % makeinfo does not expand macros in the argument to @deffn, which ends up + % writing an index entry, and texindex isn't prepared for an index sort entry + % that starts with \. + % + % Since macro invocations are followed by braces, we can just redefine them + % to take a single TeX argument. The case of a macro invocation that + % goes to end-of-line is not handled. + % + \macrolist + } + + % Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us + % ignore left quotes in the sort term. + {\catcode`\`=\active + \gdef\indexlquoteignore{\let`=\empty}} + + \let\indexbackslash=0 %overridden during \printindex. + \let\SETmarginindex=\relax % put index entries in margin (undocumented)? + + % Most index entries go through here, but \dosubind is the general case. + % #1 is the index name, #2 is the entry text. + \def\doind#1#2{\dosubind{#1}{#2}{}} + + % Workhorse for all \fooindexes. + % #1 is name of index, #2 is stuff to put there, #3 is subentry -- + % empty if called from \doind, as we usually are (the main exception + % is with most defuns, which call us directly). + % + \def\dosubind#1#2#3{% + \iflinks + {% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with a space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \safewhatsit\dosubindwrite + }% + \fi + } + + % Write the entry in \toks0 to the index file: + % + \def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + % Process the index entry with all font commands turned off, to + % get the string to sort by. + {\indexnofonts + \edef\temp{\the\toks0}% need full expansion + \xdef\indexsorttmp{\temp}% + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% + }% + \temp + } + + % Take care of unwanted page breaks/skips around a whatsit: + % + % If a skip is the last thing on the list now, preserve it + % by backing up by \lastskip, doing the \write, then inserting + % the skip again. Otherwise, the whatsit generated by the + % \write or \pdfdest will make \lastskip zero. The result is that + % sequences like this: + % @end defun + % @tindex whatever + % @defun ... + % will have extra space inserted, because the \medbreak in the + % start of the @defun won't see the skip inserted by the @end of + % the previous defun. + % + % But don't do any of this if we're not in vertical mode. We + % don't want to do a \vskip and prematurely end a paragraph. + % + % Avoid page breaks due to these extra skips, too. + % + % But wait, there is a catch there: + % We'll have to check whether \lastskip is zero skip. \ifdim is not + % sufficient for this purpose, as it ignores stretch and shrink parts + % of the skip. The only way seems to be to check the textual + % representation of the skip. + % + % The following is almost like \def\zeroskipmacro{0.0pt} except that + % the ``p'' and ``t'' characters have catcode \other, not 11 (letter). + % + \edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} + % + \newskip\whatsitskip + \newcount\whatsitpenalty + % + % ..., ready, GO: + % + \def\safewhatsit#1{\ifhmode + #1% + \else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifx\lastskipmacro\zeroskipmacro + \else + \vskip-\whatsitskip + \fi + % + #1% + % + \ifx\lastskipmacro\zeroskipmacro + % If \lastskip was zero, perhaps the last item was a penalty, and + % perhaps it was >=10000, e.g., a \nobreak. In that case, we want + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi + \fi} + + % The index entry written in the file actually looks like + % \entry {sortstring}{page}{topic} + % or + % \entry {sortstring}{page}{topic}{subtopic} + % The texindex program reads in these files and writes files + % containing these kinds of lines: + % \initial {c} + % before the first topic whose initial is c + % \entry {topic}{pagelist} + % for a topic that is used without subtopics + % \primary {topic} + % for the beginning of a topic that is used with subtopics + % \secondary {subtopic}{pagelist} + % for each subtopic. + + % Define the user-accessible indexing commands + % @findex, @vindex, @kindex, @cindex. + + \def\findex {\fnindex} + \def\kindex {\kyindex} + \def\cindex {\cpindex} + \def\vindex {\vrindex} + \def\tindex {\tpindex} + \def\pindex {\pgindex} + + \def\cindexsub {\begingroup\obeylines\cindexsub} + {\obeylines % + \gdef\cindexsub "#1" #2^^M{\endgroup % + \dosubind{cp}{#2}{#1}}} + + % Define the macros used in formatting output of the sorted index material. + + % @printindex causes a particular index (the ??s file) to get printed. + % It does not print any chapter heading (usually an @unnumbered). + % + \parseargdef\printindex{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \plainfrenchspacing + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\backslashcurfont}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 + \endgroup} + + % These macros are used by the sorted index file itself. + % Change them to control the appearance of the index. + + \def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \nobreak + \vskip 0pt plus 3\baselineskip + \penalty 0 + \vskip 0pt plus -3\baselineskip + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + % Do our best not to break after the initial. + \nobreak + \vskip .33\baselineskip plus .1\baselineskip + }} + + % \entry typesets a paragraph consisting of the text (#1), dot leaders, and + % then page number (#2) flushed to the right margin. It is used for index + % and table of contents entries. The paragraph is indented by \leftskip. + % + % A straightforward implementation would start like this: + % \def\entry#1#2{... + % But this freezes the catcodes in the argument, and can cause problems to + % @code, which sets - active. This problem was fixed by a kludge--- + % ``-'' was active throughout whole index, but this isn't really right. + % The right solution is to prevent \entry from swallowing the whole text. + % --kasal, 21nov03 + \def\entry{% + \begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing + % columns. + \vskip 0pt plus1pt + % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% + % + % Swallow the left brace of the text (first parameter): + \afterassignment\doentry + \let\temp = + } + \def\entrybreak{\unskip\space\ignorespaces}% + \def\doentry{% + \bgroup % Instead of the swallowed brace. + \noindent + \aftergroup\finishentry + % And now comes the text of the entry. + } + \def\finishentry#1{% + % #1 is the page number. + % + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \setbox\boxA = \hbox{#1}% + \ifdim\wd\boxA = 0pt + \ % + \else + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#1.% + \ \the\toksA + \else + \ #1% + \fi + \fi + \par + \endgroup + } + + % Like plain.tex's \dotfill, except uses up at least 1 em. + \def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} + + \def\primary #1{\line{#1\hfil}} + + \newskip\secondaryindent \secondaryindent=0.5cm + \def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + #2 + \fi + \par + }} + + % Define two-column mode, which we use to typeset indexes. + % Adapted from the TeXbook, page 416, which is to say, + % the manmac.tex format used to print the TeXbook itself. + \catcode`\@=11 + + \newbox\partialpage + \newdimen\doublecolumnhsize + + \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \vsize = 2\vsize + } + + % The double-column output routine for all double-column pages except + % the last. + % + \def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + \advance\dimen@ by -\ht\partialpage + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty + } + % + % Re-output the contents of the output page -- any previous material, + % followed by the two boxes we just split, in box0 and box2. + \def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% + } + % + % All done with double columns. + \def\enddoublecolumns{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \pageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize + } + % + % Called at the end of the double column material. + \def\balancecolumns{% + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar + } + \catcode`\@ = \other + + + \message{sectioning,} + % Chapters, sections, etc. + + % Let's start with @part. + \outer\parseargdef\part{\partzzz{#1}} + \def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rmisbold #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + \chapoddpage + \endgroup + } + + % \unnumberedno is an oxymoron. But we count the unnumbered + % sections so that we can refer to them unambiguously in the pdf + % outlines by their "section number". We avoid collisions with chapter + % numbers by starting them at 10000. (If a document ever has 10000 + % chapters, we're in trouble anyway, I'm sure.) + \newcount\unnumberedno \unnumberedno = 10000 + \newcount\chapno + \newcount\secno \secno=0 + \newcount\subsecno \subsecno=0 + \newcount\subsubsecno \subsubsecno=0 + + % This counter is funny since it counts through charcodes of letters A, B, ... + \newcount\appendixno \appendixno = `\@ + % + % \def\appendixletter{\char\the\appendixno} + % We do the following ugly conditional instead of the above simple + % construct for the sake of pdftex, which needs the actual + % letter in the expansion, not just typeset. + % + \def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + + % Each @chapter defines these (using marks) as the number+name, number + % and name of the chapter. Page headings and footings can use + % these. @section does likewise. + \def\thischapter{} + \def\thischapternum{} + \def\thischaptername{} + \def\thissection{} + \def\thissectionnum{} + \def\thissectionname{} + + \newcount\absseclevel % used to calculate proper heading level + \newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count + + % @raisesections: treat @section as chapter, @subsection as section, etc. + \def\raisesections{\global\advance\secbase by -1} + \let\up=\raisesections % original BFox name + + % @lowersections: treat @chapter as section, @section as subsection, etc. + \def\lowersections{\global\advance\secbase by 1} + \let\down=\lowersections % original BFox name + + % we only have subsub. + \chardef\maxseclevel = 3 + % + % A numbered section within an unnumbered changes to unnumbered too. + % To achieve this, remember the "biggest" unnum. sec. we are currently in: + \chardef\unnlevel = \maxseclevel + % + % Trace whether the current chapter is an appendix or not: + % \chapheadtype is "N" or "A", unnumbered chapters are ignored. + \def\chapheadtype{N} + + % Choose a heading macro + % #1 is heading type + % #2 is heading level + % #3 is text for heading + \def\genhead#1#2#3{% + % Compute the abs. sec. level: + \absseclevel=#2 + \advance\absseclevel by \secbase + % Make sure \absseclevel doesn't fall outside the range: + \ifnum \absseclevel < 0 + \absseclevel = 0 + \else + \ifnum \absseclevel > 3 + \absseclevel = 3 + \fi + \fi + % The heading type: + \def\headtype{#1}% + \if \headtype U% + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel + \fi + \else + % Check for appendix sections: + \ifnum \absseclevel = 0 + \edef\chapheadtype{\headtype}% + \else + \if \headtype A\if \chapheadtype N% + \errmessage{@appendix... within a non-appendix chapter}% + \fi\fi + \fi + % Check for numbered within unnumbered: + \ifnum \absseclevel > \unnlevel + \def\headtype{U}% + \else + \chardef\unnlevel = 3 + \fi + \fi + % Now print the heading: + \if \headtype U% + \ifcase\absseclevel + \unnumberedzzz{#3}% + \or \unnumberedseczzz{#3}% + \or \unnumberedsubseczzz{#3}% + \or \unnumberedsubsubseczzz{#3}% + \fi + \else + \if \headtype A% + \ifcase\absseclevel + \appendixzzz{#3}% + \or \appendixsectionzzz{#3}% + \or \appendixsubseczzz{#3}% + \or \appendixsubsubseczzz{#3}% + \fi + \else + \ifcase\absseclevel + \chapterzzz{#3}% + \or \seczzz{#3}% + \or \numberedsubseczzz{#3}% + \or \numberedsubsubseczzz{#3}% + \fi + \fi + \fi + \suppressfirstparagraphindent + } + + % an interface: + \def\numhead{\genhead N} + \def\apphead{\genhead A} + \def\unnmhead{\genhead U} + + % @chapter, @appendix, @unnumbered. Increment top-level counter, reset + % all lower-level sectioning counters to zero. + % + % Also set \chaplevelprefix, which we prepend to @float sequence numbers + % (e.g., figures), q.v. By default (before any chapter), that is empty. + \let\chaplevelprefix = \empty + % + \outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz + \def\chapterzzz#1{% + % section resetting is \global in case the chapter is in a group, such + % as an @include file. + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\chapno by 1 + % + % Used for \float. + \gdef\chaplevelprefix{\the\chapno.}% + \resetallfloatnos + % + % \putwordChapter can contain complex things in translations. + \toks0=\expandafter{\putwordChapter}% + \message{\the\toks0 \space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec + } + + \outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz + % + \def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + % \putwordAppendix can contain complex things in translations. + \toks0=\expandafter{\putwordAppendix}% + \message{\the\toks0 \space \appendixletter}% + % + \chapmacro{#1}{Yappendix}{\appendixletter}% + % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec + } + + % normally unnmhead0 calls unnumberedzzz: + \outer\parseargdef\unnumbered{\unnmhead0{#1}} + \def\unnumberedzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\unnumberedno by 1 + % + % Since an unnumbered has no number, no prefix for figures. + \global\let\chaplevelprefix = \empty + \resetallfloatnos + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the to achieve this: TeX expands \the only once, + % simply yielding the contents of . (We also do this for + % the toc entries.) + \toks0 = {#1}% + \message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec + } + + % @centerchap is like @unnumbered, but the heading is centered. + \outer\parseargdef\centerchap{% + % Well, we could do the following in a group, but that would break + % an assumption that \chapmacro is called at the outermost level. + % Thus we are safer this way: --kasal, 24feb04 + \let\centerparametersmaybe = \centerparameters + \unnmhead0{#1}% + \let\centerparametersmaybe = \relax + } + + % @top is like @unnumbered. + \let\top\unnumbered + + % Sections. + % + \outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz + \def\seczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% + } + + % normally calls appendixsectionzzz: + \outer\parseargdef\appendixsection{\apphead1{#1}} + \def\appendixsectionzzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% + } + \let\appendixsec\appendixsection + + % normally calls unnumberedseczzz: + \outer\parseargdef\unnumberedsec{\unnmhead1{#1}} + \def\unnumberedseczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% + } + + % Subsections. + % + % normally calls numberedsubseczzz: + \outer\parseargdef\numberedsubsec{\numhead2{#1}} + \def\numberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% + } + + % normally calls appendixsubseczzz: + \outer\parseargdef\appendixsubsec{\apphead2{#1}} + \def\appendixsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% + } + + % normally calls unnumberedsubseczzz: + \outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} + \def\unnumberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% + } + + % Subsubsections. + % + % normally numberedsubsubseczzz: + \outer\parseargdef\numberedsubsubsec{\numhead3{#1}} + \def\numberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% + } + + % normally appendixsubsubseczzz: + \outer\parseargdef\appendixsubsubsec{\apphead3{#1}} + \def\appendixsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% + } + + % normally unnumberedsubsubseczzz: + \outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} + \def\unnumberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% + } + + % These macros control what the section commands do, according + % to what kind of chapter we are in (ordinary, appendix, or unnumbered). + % Define them by default for a numbered chapter. + \let\section = \numberedsec + \let\subsection = \numberedsubsec + \let\subsubsection = \numberedsubsubsec + + % Define @majorheading, @heading and @subheading + + \def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz + } + + \def\chapheading{\chapbreak \parsearg\chapheadingzzz} + \def\chapheadingzzz#1{% + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak + \suppressfirstparagraphindent + } + + % @heading, @subheading, @subsubheading. + \parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + \parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + \parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + + % These macros generate a chapter, section, etc. heading only + % (including whitespace, linebreaking, etc. around it), + % given all the information in convenient, parsed form. + + % Args are the skip and penalty (usually negative) + \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + + % Parameter controlling skip before chapter headings (if needed) + \newskip\chapheadingskip + + % Define plain chapter starts, and page on/off switching for it. + \def\chapbreak{\dobreak \chapheadingskip {-4000}} + \def\chappager{\par\vfill\supereject} + % Because \domark is called before \chapoddpage, the filler page will + % get the headings for the next chapter, which is wrong. But we don't + % care -- we just disable all headings on the filler page. + \def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \headingsoff + \null + \chappager + \endgroup + \fi + } + + \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + + \def\CHAPPAGoff{% + \global\let\contentsalignmacro = \chappager + \global\let\pchapsepmacro=\chapbreak + \global\let\pagealignmacro=\chappager} + + \def\CHAPPAGon{% + \global\let\contentsalignmacro = \chappager + \global\let\pchapsepmacro=\chappager + \global\let\pagealignmacro=\chappager + \global\def\HEADINGSon{\HEADINGSsingle}} + + \def\CHAPPAGodd{% + \global\let\contentsalignmacro = \chapoddpage + \global\let\pchapsepmacro=\chapoddpage + \global\let\pagealignmacro=\chapoddpage + \global\def\HEADINGSon{\HEADINGSdouble}} + + \CHAPPAGon + + % Chapter opening. + % + % #1 is the text, #2 is the section type (Ynumbered, Ynothing, + % Yappendix, Yomitfromtoc), #3 the chapter number. + % + % To test against our argument. + \def\Ynothingkeyword{Ynothing} + \def\Yomitfromtockeyword{Yomitfromtoc} + \def\Yappendixkeyword{Yappendix} + % + \def\chapmacro#1#2#3{% + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + % \noexpand\putwordAppendix avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + % \noexpand\putwordChapter avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordChapter{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rmisbold + % + % Have to define \lastsection before calling \donoderef, because the + % xref code eventually uses it. On the other hand, it has to be called + % after \pchapsepmacro, or the headline will change too soon. + \gdef\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak + } + + % @centerchap -- centered and unnumbered. + \let\centerparametersmaybe = \relax + \def\centerparameters{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt + } + + + % I don't think this chapter style is supported any more, so I'm not + % updating it with the new noderef stuff. We'll see. --karl, 11aug03. + % + \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + % + \def\unnchfopen #1{% + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip\nobreak + } + \def\chfopen #1#2{\chapoddpage {\chapfonts + \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% + \par\penalty 5000 % + } + \def\centerchfopen #1{% + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% + \nobreak\bigskip \nobreak + } + \def\CHAPFopen{% + \global\let\chapmacro=\chfopen + \global\let\centerchapmacro=\centerchfopen} + + + % Section titles. These macros combine the section number parts and + % call the generic \sectionheading to do the printing. + % + \newskip\secheadingskip + \def\secheadingbreak{\dobreak \secheadingskip{-1000}} + + % Subsection titles. + \newskip\subsecheadingskip + \def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + + % Subsubsection titles. + \def\subsubsecheadingskip{\subsecheadingskip} + \def\subsubsecheadingbreak{\subsecheadingbreak} + + + % Print any size, any type, section title. + % + % #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is + % the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the + % section number. + % + \def\seckeyword{sec} + % + \def\sectionheading#1#2#3#4{% + {% + \checkenv{}% should not be in an environment. + % + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rmisbold + % + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Go into vertical mode. Usually we'll already be there, but we + % don't want the following whatsit to end up in a preceding paragraph + % if the document didn't happen to have a blank line. + \par + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \global\let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chapmacro. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chapmacro. + \donoderef{#3}% + % + % Interline glue will be inserted when the vbox is completed. + % That glue will be a valid breakpoint for the page, since it'll be + % preceded by a whatsit (usually from the \donoderef, or from the + % \writetocentry if there was no node). We don't want to allow that + % break, since then the whatsits could end up on page n while the + % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. + \nobreak + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. + \vskip-\parskip + % + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. + \penalty 10001 + } + + + \message{toc,} + % Table of contents. + \newwrite\tocfile + + % Write an entry to the toc file, opening it if necessary. + % Called from @chapter, etc. + % + % Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} + % We append the current node name (if any) and page number as additional + % arguments for the \{chap,sec,...}entry macros which will eventually + % read this. The node name is used in the pdf outlines as the + % destination to jump to. + % + % We open the .toc file for writing here instead of at @setfilename (or + % any other fixed time) so that @contents can be anywhere in the document. + % But if #1 is `omit', then we don't do anything. This is used for the + % table of contents chapter openings themselves. + % + \newif\iftocfileopened + \def\omitkeyword{omit}% + % + \def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + {\atdummies + \edef\temp{% + \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% + \temp + }% + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf \global\pdfmakepagedesttrue \fi + } + + + % These characters do not print properly in the Computer Modern roman + % fonts, so we must take special care. This is more or less redundant + % with the Texinfo input format setup at the end of this file. + % + \def\activecatcodes{% + \catcode`\"=\active + \catcode`\$=\active + \catcode`\<=\active + \catcode`\>=\active + \catcode`\\=\active + \catcode`\^=\active + \catcode`\_=\active + \catcode`\|=\active + \catcode`\~=\active + } + + + % Read the toc file, which is essentially Texinfo input. + \def\readtocfile{% + \setupdatafile + \activecatcodes + \input \tocreadfilename + } + + \newskip\contentsrightmargin \contentsrightmargin=1in + \newcount\savepageno + \newcount\lastnegativepageno \lastnegativepageno = -1 + + % Prepare to read what we've written to \tocfile. + % + \def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi + } + + % redefined for the two-volume lispref. We always output on + % \jobname.toc even if this is redefined. + % + \def\tocreadfilename{\jobname.toc} + + % Normal (long) toc. + % + \def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \ifeof 1 \else + \pdfmakeoutlines + \fi + \closein 1 + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno + } + + % And just the chapters. + \def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\partentry = \shortpartentry + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \closein 1 + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno + } + \let\shortcontents = \summarycontents + + % Typeset the label for a chapter or appendix for the short contents. + % The arg is, e.g., `A' for an appendix, or `3' for a chapter. + % + \def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% + } + + % These macros generate individual entries in the table of contents. + % The first argument is the chapter or section name. + % The last argument is the page number. + % The arguments in between are the chapter number, section number, ... + + % Parts, in the main contents. Replace the part number, which doesn't + % exist, with an empty box. Let's hope all the numbers have the same width. + % Also ignore the page number, which is conventionally not printed. + \def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} + \def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} + % + % Parts, in the short toc. + \def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% + } + + % Chapters, in the main contents. + \def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} + % + % Chapters, in the short toc. + % See comments in \dochapentry re vbox and related settings. + \def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% + } + + % Appendices, in the main contents. + % Need the word Appendix, and a fixed-size box. + % + \def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} + % + \def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} + + % Unnumbered chapters. + \def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} + \def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + + % Sections. + \def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} + \let\appsecentry=\numsecentry + \def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + + % Subsections. + \def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} + \let\appsubsecentry=\numsubsecentry + \def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + + % And subsubsections. + \def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} + \let\appsubsubsecentry=\numsubsubsecentry + \def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + + % This parameter controls the indentation of the various levels. + % Same as \defaultparindent. + \newdimen\tocindent \tocindent = 15pt + + % Now for the actual typesetting. In all these, #1 is the text and #2 is the + % page number. + % + % If the toc has to be broken over pages, we want it to be at chapters + % if at all possible; hence the \penalty. + \def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip + } + + \def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup} + + \def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup} + + \def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup} + + % We use the same \entry macro as for the index entries. + \let\tocentry = \entry + + % Space between chapter (or whatever) number and the title. + \def\labelspace{\hskip1em \relax} + + \def\dopageno#1{{\rm #1}} + \def\doshortpageno#1{{\rm #1}} + + \def\chapentryfonts{\secfonts \rm} + \def\secentryfonts{\textfonts} + \def\subsecentryfonts{\textfonts} + \def\subsubsecentryfonts{\textfonts} + + + \message{environments,} + % @foo ... @end foo. + + % @tex ... @end tex escapes into raw TeX temporarily. + % One exception: @ is still an escape character, so that @end tex works. + % But \@ or @@ will get a plain @ character. + + \envdef\tex{% + \setupmarkupstyle{tex}% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \catcode `\`=\other + \catcode `\'=\other + \escapechar=`\\ + % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\*=\ptexstar + \let\t=\ptext + \expandafter \let\csname top\endcsname=\ptextop % we've made it outer + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% + } + % There is no need to define \Etex. + + % Define @lisp ... @end lisp. + % @lisp environment forms a group so it can rebind things, + % including the definition of @end lisp (which normally is erroneous). + + % Amount to narrow the margins by for @lisp. + \newskip\lispnarrowing \lispnarrowing=0.4in + + % This is the definition that ^^M gets inside @lisp, @example, and other + % such environments. \null is better than a space, since it doesn't + % have any width. + \def\lisppar{\null\endgraf} + + % This space is always present above and below environments. + \newskip\envskipamount \envskipamount = 0pt + + % Make spacing and below environment symmetrical. We use \parskip here + % to help in doing that, since in @example-like environments \parskip + % is reset to zero; thus the \afterenvbreak inserts no space -- but the + % start of the next paragraph will insert \parskip. + % + \def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty<10000 \penalty-50 \fi + \vskip\envskipamount + \fi + \fi + }} + + \let\afterenvbreak = \aboveenvbreak + + % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will + % also clear it, so that its embedded environments do the narrowing again. + \let\nonarrowing=\relax + + % @cartouche ... @end cartouche: draw rectangle w/rounded corners around + % environment contents. + \font\circle=lcircle10 + \newdimen\circthick + \newdimen\cartouter\newdimen\cartinner + \newskip\normbskip\newskip\normpskip\newskip\normlskip + \circthick=\fontdimen8\circle + % + \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth + \def\ctr{{\hskip 6pt\circle\char'010}} + \def\cbl{{\circle\char'012\hskip -6pt}} + \def\cbr{{\hskip 6pt\circle\char'011}} + \def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} + \def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} + % + \newskip\lskip\newskip\rskip + + \envdef\cartouche{% + \ifhmode\par\fi % can't be in the midst of a paragraph. + \startsavinginserts + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt % we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing = t% + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \kern3pt + \hsize=\cartinner + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip + \comment % For explanation, see the end of def\group. + } + \def\Ecartouche{% + \ifhmode\par\fi + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \checkinserts + } + + + % This macro is called at the beginning of all the @example variants, + % inside a group. + \newdimen\nonfillparindent + \def\nonfillstart{% + \aboveenvbreak + \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + % Turn off paragraph indentation but redefine \indent to emulate + % the normal \indent. + \nonfillparindent=\parindent + \parindent = 0pt + \let\indent\nonfillindent + % + \emergencystretch = 0pt % don't try to avoid overfull boxes + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \let\exdent=\nofillexdent + } + + \begingroup + \obeyspaces + % We want to swallow spaces (but not other tokens) after the fake + % @indent in our nonfill-environments, where spaces are normally + % active and set to @tie, resulting in them not being ignored after + % @indent. + \gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% + \gdef\nonfillindentcheck{% + \ifx\temp % + \expandafter\nonfillindentgobble% + \else% + \leavevmode\nonfillindentbox% + \fi% + }% + \endgroup + \def\nonfillindentgobble#1{\nonfillindent} + \def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} + + % If you want all examples etc. small: @set dispenvsize small. + % If you want even small examples the full size: @set dispenvsize nosmall. + % This affects the following displayed environments: + % @example, @display, @format, @lisp + % + \def\smallword{small} + \def\nosmallword{nosmall} + \let\SETdispenvsize\relax + \def\setnormaldispenv{% + \ifx\SETdispenvsize\smallword + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi + } + \def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi + } + + % We often define two environments, @foo and @smallfoo. + % Let's do it in one command. #1 is the env name, #2 the definition. + \def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% + \expandafter\let\csname E#1\endcsname \afterenvbreak + \expandafter\let\csname Esmall#1\endcsname \afterenvbreak + } + + % Define two environment synonyms (#1 and #2) for an environment. + \def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% + } + % + % @lisp: indented, narrowed, typewriter font; + % @example: same as @lisp. + % + % @smallexample and @smalllisp: use smaller fonts. + % Originally contributed by Pavel@xerox. + % + \maketwodispenvdef{lisp}{example}{% + \nonfillstart + \tt\setupmarkupstyle{example}% + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return + } + % @display/@smalldisplay: same as @lisp except keep current font. + % + \makedispenvdef{display}{% + \nonfillstart + \gobble + } + + % @format/@smallformat: same as @display except don't narrow margins. + % + \makedispenvdef{format}{% + \let\nonarrowing = t% + \nonfillstart + \gobble + } + + % @flushleft: same as @format, but doesn't obey \SETdispenvsize. + \envdef\flushleft{% + \let\nonarrowing = t% + \nonfillstart + \gobble + } + \let\Eflushleft = \afterenvbreak + + % @flushright. + % + \envdef\flushright{% + \let\nonarrowing = t% + \nonfillstart + \advance\leftskip by 0pt plus 1fill\relax + \gobble + } + \let\Eflushright = \afterenvbreak + + + % @raggedright does more-or-less normal line breaking but no right + % justification. From plain.tex. + \envdef\raggedright{% + \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax + } + \let\Eraggedright\par + + \envdef\raggedleft{% + \parindent=0pt \leftskip0pt plus2em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. + } + \let\Eraggedleft\par + + \envdef\raggedcenter{% + \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. + } + \let\Eraggedcenter\par + + + % @quotation does normal linebreaking (hence we can't use \nonfillstart) + % and narrows the margins. We keep \parskip nonzero in general, since + % we're doing normal filling. So, when using \aboveenvbreak and + % \afterenvbreak, temporarily make \parskip 0. + % + \makedispenvdef{quotation}{\quotationstart} + % + \def\quotationstart{% + \indentedblockstart % same as \indentedblock, but increase right margin too. + \ifx\nonarrowing\relax + \advance\rightskip by \lispnarrowing + \fi + \parsearg\quotationlabel + } + + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. + % + \def\Equotation{% + \par + \ifx\quotationauthor\thisisundefined\else + % indent a bit. + \leftline{\kern 2\leftskip \sl ---\quotationauthor}% + \fi + {\parskip=0pt \afterenvbreak}% + } + \def\Esmallquotation{\Equotation} + + % If we're given an argument, typeset it in bold with a colon after. + \def\quotationlabel#1{% + \def\temp{#1}% + \ifx\temp\empty \else + {\bf #1: }% + \fi + } + + % @indentedblock is like @quotation, but indents only on the left and + % has no optional argument. + % + \makedispenvdef{indentedblock}{\indentedblockstart} + % + \def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi + } + + % Keep a nonzero parskip for the environment, since we're doing normal filling. + % + \def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% + } + \def\Esmallindentedblock{\Eindentedblock} + + + % LaTeX-like @verbatim...@end verbatim and @verb{...} + % If we want to allow any as delimiter, + % we need the curly braces so that makeinfo sees the @verb command, eg: + % `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org + % + % [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. + % + % [Knuth] p.344; only we need to do the other characters Texinfo sets + % active too. Otherwise, they get lost as the first character on a + % verbatim line. + \def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% + % Don't do the quotes -- if we do, @set txicodequoteundirected and + % @set txicodequotebacktick will not have effect on @verb and + % @verbatim, and ?` and !` ligatures won't get disabled. + %\do\`\do\'% + } + % + % [Knuth] p. 380 + \def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} + % + % Setup for the @verb command. + % + % Eight spaces for a tab + \begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} + \endgroup + % + \def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \setupmarkupstyle{verb}% + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces + } + + % Setup for the @verbatim environment + % + % Real tab expansion. + \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount + % + % We typeset each line of the verbatim in an \hbox, so we can handle + % tabs. The \global is in case the verbatim line starts with an accent, + % or some other command that starts with a begin-group. Otherwise, the + % entire \verbbox would disappear at the corresponding end-group, before + % it is typeset. Meanwhile, we can't have nested verbatim commands + % (can we?), so the \global won't be overwriting itself. + \newbox\verbbox + \def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} + % + \begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox + }% + } + \endgroup + + % start the verbatim environment. + \def\setupverbatim{% + \let\nonarrowing = t% + \nonfillstart + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% + \tabexpand + \setupmarkupstyle{verbatim}% + % Respect line breaks, + % print special symbols as themselves, and + % make each space count. + % Must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% + } + + % Do the @verb magic: verbatim text is quoted by unique + % delimiter characters. Before first delimiter expect a + % right brace, after last delimiter expect closing brace: + % + % \def\doverb'{'#1'}'{#1} + % + % [Knuth] p. 382; only eat outer {} + \begingroup + \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] + \endgroup + % + \def\verb{\begingroup\setupverb\doverb} + % + % + % Do the @verbatim magic: define the macro \doverbatim so that + % the (first) argument ends when '@end verbatim' is reached, ie: + % + % \def\doverbatim#1@end verbatim{#1} + % + % For Texinfo it's a lot easier than for LaTeX, + % because texinfo's \verbatim doesn't stop at '\end{verbatim}': + % we need not redefine '\', '{' and '}'. + % + % Inspired by LaTeX's verbatim command set [latex.ltx] + % + \begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% + % We really want {...\end verbatim} in the body of the macro, but + % without the active space; thus we have to use \xdef and \gobble. + \endgroup + % + \envdef\verbatim{% + \setupverbatim\doverbatim + } + \let\Everbatim = \afterenvbreak + + + % @verbatiminclude FILE - insert text of file in verbatim environment. + % + \def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} + % + \def\doverbatiminclude#1{% + {% + \makevalueexpandable + \setupverbatim + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% + \input #1 + \afterenvbreak + }% + } + + % @copying ... @end copying. + % Save the text away for @insertcopying later. + % + % We save the uninterpreted tokens, rather than creating a box. + % Saving the text in a box would be much easier, but then all the + % typesetting commands (@smallbook, font changes, etc.) have to be done + % beforehand -- and a) we want @copying to be done first in the source + % file; b) letting users define the frontmatter in as flexible order as + % possible is very desirable. + % + \def\copying{\checkenv{}\begingroup\scanargctxt\docopying} + \def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} + % + \def\insertcopying{% + \begingroup + \parindent = 0pt % paragraph indentation looks wrong on title page + \scanexp\copyingtext + \endgroup + } + + + \message{defuns,} + % @defun etc. + + \newskip\defbodyindent \defbodyindent=.4in + \newskip\defargsindent \defargsindent=50pt + \newskip\deflastargmargin \deflastargmargin=18pt + \newcount\defunpenalty + + % Start the processing of @deffn: + \def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \else + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check specifically for penalty 10002, inserted + % by \printdefunline, instead of 10000, since the sectioning + % commands also insert a nobreak penalty, and we don't want to allow + % a break between a section heading and a defun. + % + % As a further refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent + } + + \def\dodefunx#1{% + % First, check whether we are in the right environment: + \checkenv#1% + % + % As above, allow line break if we have multiple x headers in a row. + % It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi + % + % And now, it's time to reuse the body of the original defun: + \expandafter\gobbledefun#1% + } + \def\gobbledefun#1\startdefun{} + + % \printdefunline \deffnheader{text} + % + \def\printdefunline#1#2{% + \begingroup + % call \deffnheader: + #1#2 \endheader + % common ending: + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil\relax + \endgraf + \nobreak\vskip -\parskip + \penalty\defunpenalty % signal to \startdefun and \dodefunx + % Some of the @defun-type tags do not enable magic parentheses, + % rendering the following check redundant. But we don't optimize. + \checkparencounts + \endgroup + } + + \def\Edefun{\endgraf\medbreak} + + % \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; + % the only thing remaining is to define \deffnheader. + % + \def\makedefun#1{% + \expandafter\let\csname E#1\endcsname = \Edefun + \edef\temp{\noexpand\domakedefun + \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% + \temp + } + + % \domakedefun \deffn \deffnx \deffnheader + % + % Define \deffn and \deffnx, without parameters. + % \deffnheader has to be defined explicitly. + % + \def\domakedefun#1#2#3{% + \envdef#1{% + \startdefun + \doingtypefnfalse % distinguish typed functions from all else + \parseargusing\activeparens{\printdefunline#3}% + }% + \def#2{\dodefunx#1}% + \def#3% + } + + \newif\ifdoingtypefn % doing typed function? + \newif\ifrettypeownline % typeset return type on its own line? + + % @deftypefnnewline on|off says whether the return type of typed functions + % are printed on their own line. This affects @deftypefn, @deftypefun, + % @deftypeop, and @deftypemethod. + % + \parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi + } + + % Untyped functions: + + % @deffn category name args + \makedefun{deffn}{\deffngeneral{}} + + % @deffn category class name args + \makedefun{defop}#1 {\defopon{#1\ \putwordon}} + + % \defopon {category on}class name args + \def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + + % \deffngeneral {subind}category name args + % + \def\deffngeneral#1#2 #3 #4\endheader{% + % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. + \dosubind{fn}{\code{#3}}{#1}% + \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% + } + + % Typed functions: + + % @deftypefn category type name args + \makedefun{deftypefn}{\deftypefngeneral{}} + + % @deftypeop category class type name args + \makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} + + % \deftypeopon {category on}class type name args + \def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + + % \deftypefngeneral {subind}category type name args + % + \def\deftypefngeneral#1#2 #3 #4 #5\endheader{% + \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% + } + + % Typed variables: + + % @deftypevr category type var args + \makedefun{deftypevr}{\deftypecvgeneral{}} + + % @deftypecv category class type var args + \makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} + + % \deftypecvof {category of}class type var args + \def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } + + % \deftypecvgeneral {subind}category type var args + % + \def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% + \dosubind{vr}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% + } + + % Untyped variables: + + % @defvr category var args + \makedefun{defvr}#1 {\deftypevrheader{#1} {} } + + % @defcv category class var args + \makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} + + % \defcvof {category of}class var args + \def\defcvof#1#2 {\deftypecvof{#1}#2 {} } + + % Types: + + % @deftp category name args + \makedefun{deftp}#1 #2 #3\endheader{% + \doind{tp}{\code{#2}}% + \defname{#1}{}{#2}\defunargs{#3\unskip}% + } + + % Remaining @defun-like shortcuts: + \makedefun{defun}{\deffnheader{\putwordDeffunc} } + \makedefun{defmac}{\deffnheader{\putwordDefmac} } + \makedefun{defspec}{\deffnheader{\putwordDefspec} } + \makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } + \makedefun{defvar}{\defvrheader{\putwordDefvar} } + \makedefun{defopt}{\defvrheader{\putwordDefopt} } + \makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } + \makedefun{defmethod}{\defopon\putwordMethodon} + \makedefun{deftypemethod}{\deftypeopon\putwordMethodon} + \makedefun{defivar}{\defcvof\putwordInstanceVariableof} + \makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} + + % \defname, which formats the name of the @def (not the args). + % #1 is the category, such as "Function". + % #2 is the return type, if any. + % #3 is the function name. + % + % We are followed by (but not passed) the arguments, if any. + % + \def\defname#1#2#3{% + \par + % Get the values of \leftskip and \rightskip as they were outside the @def... + \advance\leftskip by -\defbodyindent + % + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \def\temp{#1}% + \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} + % + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % + % The first line needs space for \box0; but if \rightskip is nonzero, + % we need only space for the part of \box0 which exceeds it: + \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % + % The continuations: + \dimen2=\hsize \advance\dimen2 by -\defargsindent + % + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. + \noindent + \hbox to 0pt{% + \hfil\box0 \kern-\hsize + % \hsize has to be shortened this way: + \kern\leftskip + % Intentionally do not respect \rightskip, since we need the space. + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \exdentamount=\defbodyindent + {% + % defun fonts. We use typewriter by default (used to be bold) because: + % . we're printing identifiers, they should be in tt in principle. + % . in languages with many accents, such as Czech or French, it's + % common to leave accents off identifiers. The result looks ok in + % tt, but exceedingly strange in rm. + % . we don't want -- and --- to be treated as ligatures. + % . this still does not fix the ?` and !` ligatures, but so far no + % one has made identifiers using them :). + \df \tt + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type + #3% output function name + }% + {\rm\enskip}% hskip 0.5 em of \tenrm + % + \boldbrax + % arguments will be output next, if any. + } + + % Print arguments in slanted roman (not ttsl), inconsistently with using + % tt for the name. This is because literal text is sometimes needed in + % the argument list (groff manual), and ttsl and tt are not very + % distinguishable. Prevent hyphenation at `-' chars. + % + \def\defunargs#1{% + % use sl by default (not ttsl), + % tt for the names. + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #1% + \sl\hyphenchar\font=45 + } + + % We want ()&[] to print specially on the defun line. + % + \def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\[=\active \catcode`\]=\active + \catcode`\&=\active + } + + % Make control sequences which act like normal parenthesis chars. + \let\lparen = ( \let\rparen = ) + + % Be sure that we always have a definition for `(', etc. For example, + % if the fn name has parens in it, \boldbrax will not be in effect yet, + % so TeX would otherwise complain about undefined control sequence. + { + \activeparens + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + \global\let& = \& + + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + \gdef\magicamp{\let&=\amprm} + } + + \newcount\parencount + + % If we encounter &foo, then turn on ()-hacking afterwards + \newif\ifampseen + \def\amprm#1 {\ampseentrue{\bf\ }} + + \def\parenfont{% + \ifampseen + % At the first level, print parens in roman, + % otherwise use the default font. + \ifnum \parencount=1 \rm \fi + \else + % The \sf parens (in \boldbrax) actually are a little bolder than + % the contained text. This is especially needed for [ and ] . + \sf + \fi + } + \def\infirstlevel#1{% + \ifampseen + \ifnum\parencount=1 + #1% + \fi + \fi + } + \def\bfafterword#1 {#1 \bf} + + \def\opnr{% + \global\advance\parencount by 1 + {\parenfont(}% + \infirstlevel \bfafterword + } + \def\clnr{% + {\parenfont)}% + \infirstlevel \sl + \global\advance\parencount by -1 + } + + \newcount\brackcount + \def\lbrb{% + \global\advance\brackcount by 1 + {\bf[}% + } + \def\rbrb{% + {\bf]}% + \global\advance\brackcount by -1 + } + + \def\checkparencounts{% + \ifnum\parencount=0 \else \badparencount \fi + \ifnum\brackcount=0 \else \badbrackcount \fi + } + % these should not use \errmessage; the glibc manual, at least, actually + % has such constructs (when documenting function pointers). + \def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 + } + \def\badbrackcount{% + \message{Warning: unbalanced square brackets in @def...}% + \global\brackcount=0 + } + + + \message{macros,} + % @macro. + + % To do this right we need a feature of e-TeX, \scantokens, + % which we arrange to emulate with a temporary file in ordinary TeX. + \ifx\eTeXversion\thisisundefined + \newwrite\macscribble + \def\scantokens#1{% + \toks0={#1}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \input \jobname.tmp + } + \fi + + \def\scanmacro#1{\begingroup + \newlinechar`\^^M + \let\xeatspaces\eatspaces + % + % Undo catcode changes of \startcontents and \doprintindex + % When called from @insertcopying or (short)caption, we need active + % backslash to get it printed correctly. Previously, we had + % \catcode`\\=\other instead. We'll see whether a problem appears + % with macro expansion. --kasal, 19aug04 + \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ + % + % ... and for \example: + \spaceisspace + % + % The \empty here causes a following catcode 5 newline to be eaten as + % part of reading whitespace after a control sequence. It does not + % eat a catcode 13 newline. There's no good way to handle the two + % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX + % would then have different behavior). See the Macro Details node in + % the manual for the workaround we recommend for macros and + % line-oriented commands. + % + \scantokens{#1\empty}% + \endgroup} + + \def\scanexp#1{% + \edef\temp{\noexpand\scanmacro{#1}}% + \temp + } + + \newcount\paramno % Count of parameters + \newtoks\macname % Macro name + \newif\ifrecursive % Is it recursive? + + % List of all defined macros in the form + % \definedummyword\macro1\definedummyword\macro2... + % Currently is also contains all @aliases; the list can be split + % if there is a need. + \def\macrolist{} + + % Add the macro to \macrolist + \def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} + \def\addtomacrolistxxx#1{% + \toks0 = \expandafter{\macrolist\definedummyword#1}% + \xdef\macrolist{\the\toks0}% + } + + % Utility routines. + % This does \let #1 = #2, with \csnames; that is, + % \let \csname#1\endcsname = \csname#2\endcsname + % (except of course we have to play expansion games). + % + \def\cslet#1#2{% + \expandafter\let + \csname#1\expandafter\endcsname + \csname#2\endcsname + } + + % Trim leading and trailing spaces off a string. + % Concepts from aro-bend problem 15 (see CTAN). + {\catcode`\@=11 + \gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} + \gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} + \gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} + \def\unbrace#1{#1} + \unbrace{\gdef\trim@@@ #1 } #2@{#1} + } + + % Trim a single trailing ^^M off a string. + {\catcode`\^^M=\other \catcode`\Q=3% + \gdef\eatcr #1{\eatcra #1Q^^MQ}% + \gdef\eatcra#1^^MQ{\eatcrb#1Q}% + \gdef\eatcrb#1Q#2Q{#1}% + } + + % Macro bodies are absorbed as an argument in a context where + % all characters are catcode 10, 11 or 12, except \ which is active + % (as in normal texinfo). It is necessary to change the definition of \ + % to recognize macro arguments; this is the job of \mbodybackslash. + % + % Non-ASCII encodings make 8-bit characters active, so un-activate + % them to avoid their expansion. Must do this non-globally, to + % confine the change to the current group. + % + % It's necessary to have hard CRs when the macro is executed. This is + % done by making ^^M (\endlinechar) catcode 12 when reading the macro + % body, and then making it the \newlinechar in \scanmacro. + % + \def\scanctxt{% used as subroutine + \catcode`\"=\other + \catcode`\+=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\@=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\~=\other + \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi + } + + \def\scanargctxt{% used for copying and captions, not macros. + \scanctxt + \catcode`\\=\other + \catcode`\^^M=\other + } + + \def\macrobodyctxt{% used for @macro definitions + \scanctxt + \catcode`\{=\other + \catcode`\}=\other + \catcode`\^^M=\other + \usembodybackslash + } + + \def\macroargctxt{% used when scanning invocations + \scanctxt + \catcode`\\=0 + } + % why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" + % for the single characters \ { }. Thus, we end up with the "commands" + % that would be written @\ @{ @} in a Texinfo document. + % + % We already have @{ and @}. For @\, we define it here, and only for + % this purpose, to produce a typewriter backslash (so, the @\ that we + % define for @math can't be used with @macro calls): + % + \def\\{\normalbackslash}% + % + % We would like to do this for \, too, since that is what makeinfo does. + % But it is not possible, because Texinfo already has a command @, for a + % cedilla accent. Documents must use @comma{} instead. + % + % \anythingelse will almost certainly be an error of some kind. + + + % \mbodybackslash is the definition of \ in @macro bodies. + % It maps \foo\ => \csname macarg.foo\endcsname => #N + % where N is the macro parameter number. + % We define \csname macarg.\endcsname to be \realbackslash, so + % \\ in macro replacement text gets you a backslash. + % + {\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} + } + \expandafter\def\csname macarg.\endcsname{\realbackslash} + + \def\margbackslash#1{\char`\#1 } + + \def\macro{\recursivefalse\parsearg\macroxxx} + \def\rmacro{\recursivetrue\parsearg\macroxxx} + + \def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0\relax + \else + \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + \addtomacrolist{\the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + + \parseargdef\unmacro{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\definedummyword\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi + } + + % Called by \do from \dounmacro on each macro. The idea is to omit any + % macro definitions that have been changed to \relax. + % + \def\unmacrodo#1{% + \ifx #1\relax + % remove this + \else + \noexpand\definedummyword \noexpand#1% + \fi + } + + % This makes use of the obscure feature that if the last token of a + % is #, then the preceding argument is delimited by + % an opening brace, and that opening brace is not consumed. + \def\getargs#1{\getargsxxx#1{}} + \def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} + \def\getmacname#1 #2\relax{\macname={#1}} + \def\getmacargs#1{\def\argl{#1}} + + % For macro processing make @ a letter so that we can make Texinfo private macro names. + \edef\texiatcatcode{\the\catcode`\@} + \catcode `@=11\relax + + % Parse the optional {params} list. Set up \paramno and \paramlist + % so \defmacro knows what to do. Define \macarg.BLAH for each BLAH + % in the params list to some hook where the argument si to be expanded. If + % there are less than 10 arguments that hook is to be replaced by ##N where N + % is the position in that list, that is to say the macro arguments are to be + % defined `a la TeX in the macro body. + % + % That gets used by \mbodybackslash (above). + % + % We need to get `macro parameter char #' into several definitions. + % The technique used is stolen from LaTeX: let \hash be something + % unexpandable, insert that wherever you need a #, and then redefine + % it to # just before using the token list produced. + % + % The same technique is used to protect \eatspaces till just before + % the macro is used. + % + % If there are 10 or more arguments, a different technique is used, where the + % hook remains in the body, and when macro is to be expanded the body is + % processed again to replace the arguments. + % + % In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the + % argument N value and then \edef the body (nothing else will expand because of + % the catcode regime underwhich the body was input). + % + % If you compile with TeX (not eTeX), and you have macros with 10 or more + % arguments, you need that no macro has more than 256 arguments, otherwise an + % error is produced. + \def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + % In case that there are 10 or more arguments we parse again the arguments + % list to set new definitions for the \macarg.BLAH macros corresponding to + % each BLAH argument. It was anyhow needed to parse already once this list + % in order to count the arguments, and as macros with at most 9 arguments + % are by far more frequent than macro with 10 or more arguments, defining + % twice the \macarg.BLAH macros does not cost too much processing power. + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi + } + \def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1 + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + + \def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + + % These two commands read recursive and nonrecursive macro bodies. + % (They're different since rec and nonrec macros end differently.) + % + + \catcode `\@\texiatcatcode + \long\def\parsemacbody#1@end macro% + {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + \long\def\parsermacbody#1@end rmacro% + {\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + \catcode `\@=11\relax + + \let\endargs@\relax + \let\nil@\relax + \def\nilm@{\nil@}% + \long\def\nillm@{\nil@}% + + % This macro is expanded during the Texinfo macro expansion, not during its + % definition. It gets all the arguments values and assigns them to macros + % macarg.ARGNAME + % + % #1 is the macro name + % #2 is the list of argument names + % #3 is the list of argument values + \def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi + } + + % + \def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next + } + + \def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% + } + + % Replace arguments by their values in the macro body, and place the result + % in macro \@tempa + \def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + + \def\macargexpandinbody@{% + %% Define the named-macro outside of this group and then close this group. + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd + } + + \def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next + } + + % Save the token stack pointer into macro #1 + \def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} + % Restore the token stack pointer from number in macro #1 + \def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} + % newtoks that can be used non \outer . + \def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} + + % Tailing missing arguments are set to empty + \def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next + } + + \def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% + } + + % #1 is the element target macro + % #2 is the list macro + % #3,#4\endargs@ is the list value + \def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% + } + \long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% + } + + % This defines a Texinfo @macro. There are eight cases: recursive and + % nonrecursive macros of zero, one, up to nine, and many arguments. + % Much magic with \expandafter here. + % \xdef is used so that macro definitions will survive the file + % they're defined in; @include reads the file inside a group. + % + \def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else + \ifnum\paramno<10\relax % at most 9 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \else % 10 or more + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % at most 9 + \ifnum\paramno<10\relax + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse + \fi + \fi + \fi} + + \catcode `\@\texiatcatcode\relax + + \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + + % \braceorline decides whether the next nonwhitespace character is a + % {. If so it reads up to the closing }, if not, it reads the whole + % line. Whatever was read is then fed to the next control sequence + % as an argument (by \parsebrace or \parsearg). + % + \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} + \def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \macnamexxx} + + + % @alias. + % We need some trickery to remove the optional spaces around the equal + % sign. Make them active and then expand them all to nothing. + % + \def\alias{\parseargusing\obeyspaces\aliasxxx} + \def\aliasxxx #1{\aliasyyy#1\relax} + \def\aliasyyy #1=#2\relax{% + {% + \expandafter\let\obeyedspace=\empty + \addtomacrolist{#1}% + \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% + }% + \next + } + + + \message{cross references,} + + \newwrite\auxfile + \newif\ifhavexrefs % True if xref values are known. + \newif\ifwarnedxrefs % True if we warned once that they aren't known. + + % @inforef is relatively simple. + \def\inforef #1{\inforefzzz #1,,,,**} + \def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + + % @node's only job in TeX is to define \lastnode, which is used in + % cross-references. The @node line might or might not have commas, and + % might or might not have spaces before the first comma, like: + % @node foo , bar , ... + % We don't want such trailing spaces in the node name. + % + \parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} + % + % also remove a trailing comma, in case of something like this: + % @node Help-Cross, , , Cross-refs + \def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} + \def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} + + \let\nwnode=\node + \let\lastnode=\empty + + % Write a cross-reference definition for the current node. #1 is the + % type (Ynumbered, Yappendix, Ynothing). + % + \def\donoderef#1{% + \ifx\lastnode\empty\else + \setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi + } + + % @anchor{NAME} -- define xref target at arbitrary point. + % + \newcount\savesfregister + % + \def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} + \def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} + \def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + + % \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an + % anchor), which consists of three parts: + % 1) NAME-title - the current sectioning name taken from \lastsection, + % or the anchor name. + % 2) NAME-snt - section number and type, passed as the SNT arg, or + % empty for anchors. + % 3) NAME-pg - the page number. + % + % This is called from \donoderef, \anchor, and \dofloat. In the case of + % floats, there is an additional part, which is not written here: + % 4) NAME-lof - the text as it should appear in a @listoffloats. + % + \def\setref#1#2{% + \pdfmkdest{#1}% + \iflinks + {% + \atdummies % preserve commands, but don't expand them + \edef\writexrdef##1##2{% + \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef + ##1}{##2}}% these are parameters of \writexrdef + }% + \toks0 = \expandafter{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout + }% + \fi + } + + % @xrefautosectiontitle on|off says whether @section(ing) names are used + % automatically in xrefs, if the third arg is not explicitly specified. + % This was provided as a "secret" @set xref-automatic-section-title + % variable, now it's official. + % + \parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi + } + + % + % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is + % the node name, #2 the name of the Info cross-reference, #3 the printed + % node name, #4 the name of the Info file, #5 the name of the printed + % manual. All but the node name can be omitted. + % + \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} + \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} + \def\ref#1{\xrefX[#1,,,,,,,]} + % + \newbox\toprefbox + \newbox\printedrefnamebox + \newbox\infofilenamebox + \newbox\printedmanualbox + % + \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + % + % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #3}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\infofilename{\ignorespaces #4}% + \setbox\infofilenamebox = \hbox{\infofilename\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We (should) know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % Make link in pdf output. + \ifpdf + {\indexnofonts + \turnoffactive + \makevalueexpandable + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \edef\pdfxrefdest{#1}% + \ifx\pdfxrefdest\empty + \def\pdfxrefdest{Top}% no empty targets + \else + \txiescapepdf\pdfxrefdest % escape PDF special chars + \fi + % + \leavevmode + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfxrefdest}% + \else + goto name{\pdfmkpgn{\pdfxrefdest}}% + \fi + }% + \setcolor{\linkcolor}% + \fi + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". We distinguish them by the + % LABEL-title being set to a magic string. + {% + % Have to otherify everything special to allow the \csname to + % include an _ in the xref name, etc. + \indexnofonts + \turnoffactive + \expandafter\global\expandafter\let\expandafter\Xthisreftitle + \csname XR#1-title\endcsname + }% + \iffloat\Xthisreftitle + % If the user specified the print name (third arg) to the ref, + % print it instead of our usual "Figure 1.2". + \ifdim\wd\printedrefnamebox = 0pt + \refx{#1-snt}{}% + \else + \printedrefname + \fi + % + % If the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd\printedmanualbox > 0pt + \space \putwordin{} \cite{\printedmanual}% + \fi + \else + % node/anchor (non-float) references. + % + % If we use \unhbox to print the node names, TeX does not insert + % empty discretionaries after hyphens, which means that it will not + % find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % + \ifdim \wd\printedmanualbox > 0pt + % Cross-manual reference with a printed manual name. + % + \crossmanualxref{\cite{\printedmanual\unskip}}% + % + \else\ifdim \wd\infofilenamebox > 0pt + % Cross-manual reference with only an info filename (arg 4), no + % printed manual name (arg 5). This is essentially the same as + % the case above; we output the filename, since we have nothing else. + % + \crossmanualxref{\code{\infofilename\unskip}}% + % + \else + % Reference within this manual. + % + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via the macro below so it can be overridden. + \xrefprintnodename\printedrefname + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi\fi + \fi + \endlink + \endgroup} + + % Output a cross-manual xref to #1. Used just above (twice). + % + % Only include the text "Section ``foo'' in" if the foo is neither + % missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply + % "see The Foo Manual", the idea being to refer to the whole manual. + % + % But, this being TeX, we can't easily compare our node name against the + % string "Top" while ignoring the possible spaces before and after in + % the input. By adding the arbitrary 7sp below, we make it much less + % likely that a real node name would have the same width as "Top" (e.g., + % in a monospaced font). Hopefully it will never happen in practice. + % + % For the same basic reason, we retypeset the "Top" at every + % reference, since the current font is indeterminate. + % + \def\crossmanualxref#1{% + \setbox\toprefbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp % nonempty? + \ifdim \wd2 = \wd\toprefbox \else % same as Top? + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + #1% + } + + % This macro is called from \xrefX for the `[nodename]' part of xref + % output. It's a separate macro only so it can be changed more easily, + % since square brackets don't work well in some documents. Particularly + % one that Bob is working on :). + % + \def\xrefprintnodename#1{[#1]} + + % Things referred to by \setref. + % + \def\Ynothing{} + \def\Yomitfromtoc{} + \def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi + } + \def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi + } + + % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. + % If its value is nonempty, SUFFIX is output afterward. + % + \def\refx#1#2{% + {% + \indexnofonts + \otherbackslash + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname XR#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. + } + + % This is the macro invoked by entries in the aux file. Usually it's + % just a \def (we prepend XR to the control sequence name to avoid + % collisions). But if this is a float type, we have more work to do. + % + \def\xrdef#1#2{% + {% The node name might contain 8-bit characters, which in our current + % implementation are changed to commands like @'e. Don't let these + % mess up the control sequence name. + \indexnofonts + \turnoffactive + \xdef\safexrefname{#1}% + }% + % + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\endcsname + % it was a float, and we have the (safe) float type in \iffloattype. + \expandafter\let\expandafter\floatlist + \csname floatlist\iffloattype\endcsname + % + % Is this the first time we've seen this float type? + \expandafter\ifx\floatlist\relax + \toks0 = {\do}% yes, so just \do + \else + % had it before, so preserve previous elements in list. + \toks0 = \expandafter{\floatlist\do}% + \fi + % + % Remember this xref in the control sequence \floatlistFLOATTYPE, + % for later use in \listoffloats. + \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 + {\safexrefname}}% + \fi + } + + % Read the last existing aux file, if any. No error if none exists. + % + \def\tryauxfile{% + \openin 1 \jobname.aux + \ifeof 1 \else + \readdatafile{aux}% + \global\havexrefstrue + \fi + \closein 1 + } + + \def\setupdatafile{% + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`\%=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other + % + % Make the characters 128-255 be printing characters. + {% + \count1=128 + \def\loop{% + \catcode\count1=\other + \advance\count1 by 1 + \ifnum \count1<256 \loop \fi + }% + }% + % + % @ is our escape character in .aux files, and we need braces. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 + } + + \def\readdatafile#1{% + \begingroup + \setupdatafile + \input\jobname.#1 + \endgroup} + + + \message{insertions,} + % including footnotes. + + \newcount \footnoteno + + % The trailing space in the following definition for supereject is + % vital for proper filling; pages come out unaligned when you do a + % pagealignmacro call if that space before the closing brace is + % removed. (Generally, numeric constants should always be followed by a + % space to prevent strange expansion errors.) + \def\supereject{\par\penalty -20000\footnoteno =0 } + + % @footnotestyle is meaningful for Info output only. + \let\footnotestyle=\comment + + {\catcode `\@=11 + % + % Auto-number footnotes. Otherwise like plain. + \gdef\footnote{% + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote + }% + + % Don't bother with the trickery in plain.tex to not require the + % footnote text as a parameter. Our footnotes don't need to be so general. + % + % Oh yes, they do; otherwise, @ifset (and anything else that uses + % \parseargline) fails inside footnotes because the tokens are fixed when + % the footnote is read. --karl, 16nov96. + % + \gdef\dofootnote{% + \insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \hsize=\pagewidth + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\hang}% + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + % + % Invoke rest of plain TeX footnote routine. + \futurelet\next\fo@t + } + }%end \catcode `\@=11 + + % In case a @footnote appears in a vbox, save the footnote text and create + % the real \insert just after the vbox finished. Otherwise, the insertion + % would be lost. + % Similarly, if a @footnote appears inside an alignment, save the footnote + % text to a box and make the \insert when a row of the table is finished. + % And the same can be done for other insert classes. --kasal, 16nov03. + + % Replace the \insert primitive by a cheating macro. + % Deeper inside, just make sure that the saved insertions are not spilled + % out prematurely. + % + \def\startsavinginserts{% + \ifx \insert\ptexinsert + \let\insert\saveinsert + \else + \let\checkinserts\relax + \fi + } + + % This \insert replacement works for both \insert\footins{foo} and + % \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. + % + \def\saveinsert#1{% + \edef\next{\noexpand\savetobox \makeSAVEname#1}% + \afterassignment\next + % swallow the left brace + \let\temp = + } + \def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} + \def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} + + \def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} + + \def\placesaveins#1{% + \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname + {\box#1}% + } + + % eat @SAVE -- beware, all of them have catcode \other: + { + \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) + \gdef\gobblesave @SAVE{} + } + + % initialization: + \def\newsaveins #1{% + \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% + \next + } + \def\newsaveinsX #1{% + \csname newbox\endcsname #1% + \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts + \checksaveins #1}% + } + + % initialize: + \let\checkinserts\empty + \newsaveins\footins + \newsaveins\margin + + + % @image. We use the macros from epsf.tex to support this. + % If epsf.tex is not installed and @image is used, we complain. + % + % Check for and read epsf.tex up front. If we read it only at @image + % time, we might be inside a group, and then its definitions would get + % undone and the next image would fail. + \openin 1 = epsf.tex + \ifeof 1 \else + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex + \fi + \closein 1 + % + % We will only complain once about lack of epsf.tex. + \newif\ifwarnednoepsf + \newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} + % + \def\image#1{% + \ifx\epsfbox\thisisundefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi + } + % + % Arguments to @image: + % #1 is (mandatory) image filename; we tack on .eps extension. + % #2 is (optional) width, #3 is (optional) height. + % #4 is (ignored optional) html alt text. + % #5 is (ignored optional) extension. + % #6 is just the usual extra ignored arg for parsing stuff. + \newif\ifimagevmode + \def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode + \nobreak\medskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \fi + % + % Leave vertical mode so that indentation from an enclosing + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi + % + % Output the image. + \ifpdf + \dopdfimage{#1}{#2}{#3}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \fi + % + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi + \endgroup} + + + % @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, + % etc. We don't actually implement floating yet, we always include the + % float "here". But it seemed the best name for the future. + % + \envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} + + % There may be a space before second and/or third parameter; delete it. + \def\eatcommaspace#1, {#1,} + + % #1 is the optional FLOATTYPE, the text label for this float, typically + % "Figure", "Table", "Example", etc. Can't contain commas. If omitted, + % this float will not be numbered and cannot be referred to. + % + % #2 is the optional xref label. Also must be present for the float to + % be referable. + % + % #3 is the optional positioning argument; for now, it is ignored. It + % will somehow specify the positions allowed to float to (here, top, bottom). + % + % We keep a separate counter for each FLOATTYPE, which we reset at each + % chapter-level command. + \let\resetallfloatnos=\empty + % + \def\dofloat#1,#2,#3,#4\finish{% + \let\thiscaption=\empty + \let\thisshortcaption=\empty + % + % don't lose footnotes inside @float. + % + % BEWARE: when the floats start float, we have to issue warning whenever an + % insert appears inside a float which could possibly float. --kasal, 26may04 + % + \startsavinginserts + % + % We can't be used inside a paragraph. + \par + % + \vtop\bgroup + \def\floattype{#1}% + \def\floatlabel{#2}% + \def\floatloc{#3}% we do nothing with this yet. + % + \ifx\floattype\empty + \let\safefloattype=\empty + \else + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + \fi + % + % If label is given but no type, we handle that as the empty type. + \ifx\floatlabel\empty \else + % We want each FLOATTYPE to be numbered separately (Figure 1, + % Table 1, Figure 2, ...). (And if no label, no number.) + % + \expandafter\getfloatno\csname\safefloattype floatno\endcsname + \global\advance\floatno by 1 + % + {% + % This magic value for \lastsection is output by \setref as the + % XREFLABEL-title value. \xrefX uses it to distinguish float + % labels (which have a completely different output format) from + % node and anchor labels. And \xrdef uses it to construct the + % lists of floats. + % + \edef\lastsection{\floatmagic=\safefloattype}% + \setref{\floatlabel}{Yfloat}% + }% + \fi + % + % start with \parskip glue, I guess. + \vskip\parskip + % + % Don't suppress indentation if a float happens to start a section. + \restorefirstparagraphindent + } + + % we have these possibilities: + % @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap + % @float Foo,lbl & no caption: Foo 1.1 + % @float Foo & @caption{Cap}: Foo: Cap + % @float Foo & no caption: Foo + % @float ,lbl & Caption{Cap}: 1.1: Cap + % @float ,lbl & no caption: 1.1 + % @float & @caption{Cap}: Cap + % @float & no caption: + % + \def\Efloat{% + \let\floatident = \empty + % + % In all cases, if we have a float type, it comes first. + \ifx\floattype\empty \else \def\floatident{\floattype}\fi + % + % If we have an xref label, the number comes next. + \ifx\floatlabel\empty \else + \ifx\floattype\empty \else % if also had float type, need tie first. + \appendtomacro\floatident{\tie}% + \fi + % the number. + \appendtomacro\floatident{\chaplevelprefix\the\floatno}% + \fi + % + % Start the printed caption with what we've constructed in + % \floatident, but keep it separate; we need \floatident again. + \let\captionline = \floatident + % + \ifx\thiscaption\empty \else + \ifx\floatident\empty \else + \appendtomacro\captionline{: }% had ident, so need a colon between + \fi + % + % caption text. + \appendtomacro\captionline{\scanexp\thiscaption}% + \fi + % + % If we have anything to print, print it, with space before. + % Eventually this needs to become an \insert. + \ifx\captionline\empty \else + \vskip.5\parskip + \captionline + % + % Space below caption. + \vskip\parskip + \fi + % + % If have an xref label, write the list of floats info. Do this + % after the caption, to avoid chance of it being a breakpoint. + \ifx\floatlabel\empty \else + % Write the text that goes in the lof to the aux file as + % \floatlabel-lof. Besides \floatident, we include the short + % caption if specified, else the full caption if specified, else nothing. + {% + \atdummies + % + % since we read the caption text in the macro world, where ^^M + % is turned into a normal character, we have to scan it back, so + % we don't write the literal three characters "^^M" into the aux file. + \scanexp{% + \xdef\noexpand\gtemp{% + \ifx\thisshortcaption\empty + \thiscaption + \else + \thisshortcaption + \fi + }% + }% + \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident + \ifx\gtemp\empty \else : \gtemp \fi}}% + }% + \fi + \egroup % end of \vtop + % + % place the captured inserts + % + % BEWARE: when the floats start floating, we have to issue warning + % whenever an insert appears inside a float which could possibly + % float. --kasal, 26may04 + % + \checkinserts + } + + % Append the tokens #2 to the definition of macro #1, not expanding either. + % + \def\appendtomacro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% + } + + % @caption, @shortcaption + % + \def\caption{\docaption\thiscaption} + \def\shortcaption{\docaption\thisshortcaption} + \def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} + \def\defcaption#1#2{\egroup \def#1{#2}} + + % The parameter is the control sequence identifying the counter we are + % going to use. Create it if it doesn't exist and assign it to \floatno. + \def\getfloatno#1{% + \ifx#1\relax + % Haven't seen this figure type before. + \csname newcount\endcsname #1% + % + % Remember to reset this floatno at the next chap. + \expandafter\gdef\expandafter\resetallfloatnos + \expandafter{\resetallfloatnos #1=0 }% + \fi + \let\floatno#1% + } + + % \setref calls this to get the XREFLABEL-snt value. We want an @xref + % to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we + % first read the @float command. + % + \def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% + + % Magic string used for the XREFLABEL-title value, so \xrefX can + % distinguish floats from other xref types. + \def\floatmagic{!!float!!} + + % #1 is the control sequence we are passed; we expand into a conditional + % which is true if #1 represents a float ref. That is, the magic + % \lastsection value which we \setref above. + % + \def\iffloat#1{\expandafter\doiffloat#1==\finish} + % + % #1 is (maybe) the \floatmagic string. If so, #2 will be the + % (safe) float type for this float. We set \iffloattype to #2. + % + \def\doiffloat#1=#2=#3\finish{% + \def\temp{#1}% + \def\iffloattype{#2}% + \ifx\temp\floatmagic + } + + % @listoffloats FLOATTYPE - print a list of floats like a table of contents. + % + \parseargdef\listoffloats{% + \def\floattype{#1}% floattype + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + % + % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. + \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax + \ifhavexrefs + % if the user said @listoffloats foo but never @float foo. + \message{\linenumber No `\safefloattype' floats to list.}% + \fi + \else + \begingroup + \leftskip=\tocindent % indent these entries like a toc + \let\do=\listoffloatsdo + \csname floatlist\safefloattype\endcsname + \endgroup + \fi + } + + % This is called on each entry in a list of floats. We're passed the + % xref label, in the form LABEL-title, which is how we save it in the + % aux file. We strip off the -title and look up \XRLABEL-lof, which + % has the text we're supposed to typeset here. + % + % Figures without xref labels will not be included in the list (since + % they won't appear in the aux file). + % + \def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} + \def\listoffloatsdoentry#1-title\finish{{% + % Can't fully expand XR#1-lof because it can contain anything. Just + % pass the control sequence. On the other hand, XR#1-pg is just the + % page number, and we want to fully expand that so we can get a link + % in pdf output. + \toksA = \expandafter{\csname XR#1-lof\endcsname}% + % + % use the same \entry macro we use to generate the TOC and index. + \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% + \writeentry + }} + + + \message{localization,} + + % For single-language documents, @documentlanguage is usually given very + % early, just after @documentencoding. Single argument is the language + % (de) or locale (de_DE) abbreviation. + % + { + \catcode`\_ = \active + \globaldefs=1 + \parseargdef\documentlanguage{\begingroup + \let_=\normalunderscore % normal _ character for filenames + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore{#1_\finish}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + \endgroup % end raw TeX + \endgroup} + % + % If they passed de_DE, and txi-de_DE.tex doesn't exist, + % try txi-de.tex. + % + \gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + } + }% end of special _ catcode + % + \newhelp\nolanghelp{The given language definition file cannot be found or + is empty. Maybe you need to install it? Putting it in the current + directory should work if nowhere else does.} + + % This macro is called from txi-??.tex files; the first argument is the + % \language name to set (without the "\lang@" prefix), the second and + % third args are \{left,right}hyphenmin. + % + % The language names to pass are determined when the format is built. + % See the etex.log file created at that time, e.g., + % /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. + % + % With TeX Live 2008, etex now includes hyphenation patterns for all + % available languages. This means we can support hyphenation in + % Texinfo, at least to some extent. (This still doesn't solve the + % accented characters problem.) + % + \catcode`@=11 + \def\txisetlanguage#1#2#3{% + % do not set the language if the name is undefined in the current TeX. + \expandafter\ifx\csname lang@#1\endcsname \relax + \message{no patterns for #1}% + \else + \global\language = \csname lang@#1\endcsname + \fi + % but there is no harm in adjusting the hyphenmin values regardless. + \global\lefthyphenmin = #2\relax + \global\righthyphenmin = #3\relax + } + + % Helpers for encodings. + % Set the catcode of characters 128 through 255 to the specified number. + % + \def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat + } + + \def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat + } + + % @documentencoding sets the definition of non-ASCII characters + % according to the specified encoding. + % + \parseargdef\documentencoding{% + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \setnonasciicharscatcode\active + \utfeightchardefs + % + \else + \message{Unknown document encoding #1, ignoring.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii + } + + % A message to be logged when using a character that isn't available + % the default font encoding (OT1). + % + \def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} + + % Take account of \c (plain) vs. \, (Texinfo) difference. + \def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + + % First, make active non-ASCII characters in order for them to be + % correctly categorized when TeX reads the replacement text of + % macros containing the character definitions. + \setnonasciicharscatcode\active + % + % Latin1 (ISO-8859-1) character definitions. + \def\latonechardefs{% + \gdef^^a0{\tie} + \gdef^^a1{\exclamdown} + \gdef^^a2{\missingcharmsg{CENT SIGN}} + \gdef^^a3{{\pounds}} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\missingcharmsg{YEN SIGN}} + \gdef^^a6{\missingcharmsg{BROKEN BAR}} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\copyright} + \gdef^^aa{\ordf} + \gdef^^ab{\guillemetleft} + \gdef^^ac{$\lnot$} + \gdef^^ad{\-} + \gdef^^ae{\registeredsymbol} + \gdef^^af{\={}} + % + \gdef^^b0{\textdegree} + \gdef^^b1{$\pm$} + \gdef^^b2{$^2$} + \gdef^^b3{$^3$} + \gdef^^b4{\'{}} + \gdef^^b5{$\mu$} + \gdef^^b6{\P} + % + \gdef^^b7{$^.$} + \gdef^^b8{\cedilla\ } + \gdef^^b9{$^1$} + \gdef^^ba{\ordm} + % + \gdef^^bb{\guillemetright} + \gdef^^bc{$1\over4$} + \gdef^^bd{$1\over2$} + \gdef^^be{$3\over4$} + \gdef^^bf{\questiondown} + % + \gdef^^c0{\`A} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\~A} + \gdef^^c4{\"A} + \gdef^^c5{\ringaccent A} + \gdef^^c6{\AE} + \gdef^^c7{\cedilla C} + \gdef^^c8{\`E} + \gdef^^c9{\'E} + \gdef^^ca{\^E} + \gdef^^cb{\"E} + \gdef^^cc{\`I} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\"I} + % + \gdef^^d0{\DH} + \gdef^^d1{\~N} + \gdef^^d2{\`O} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\~O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\O} + \gdef^^d9{\`U} + \gdef^^da{\'U} + \gdef^^db{\^U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\TH} + \gdef^^df{\ss} + % + \gdef^^e0{\`a} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\~a} + \gdef^^e4{\"a} + \gdef^^e5{\ringaccent a} + \gdef^^e6{\ae} + \gdef^^e7{\cedilla c} + \gdef^^e8{\`e} + \gdef^^e9{\'e} + \gdef^^ea{\^e} + \gdef^^eb{\"e} + \gdef^^ec{\`{\dotless i}} + \gdef^^ed{\'{\dotless i}} + \gdef^^ee{\^{\dotless i}} + \gdef^^ef{\"{\dotless i}} + % + \gdef^^f0{\dh} + \gdef^^f1{\~n} + \gdef^^f2{\`o} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\~o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\o} + \gdef^^f9{\`u} + \gdef^^fa{\'u} + \gdef^^fb{\^u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\th} + \gdef^^ff{\"y} + } + + % Latin9 (ISO-8859-15) encoding character definitions. + \def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdef^^a4{\euro} + \gdef^^a6{\v S} + \gdef^^a8{\v s} + \gdef^^b4{\v Z} + \gdef^^b8{\v z} + \gdef^^bc{\OE} + \gdef^^bd{\oe} + \gdef^^be{\"Y} + } + + % Latin2 (ISO-8859-2) character definitions. + \def\lattwochardefs{% + \gdef^^a0{\tie} + \gdef^^a1{\ogonek{A}} + \gdef^^a2{\u{}} + \gdef^^a3{\L} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\v L} + \gdef^^a6{\'S} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\v S} + \gdef^^aa{\cedilla S} + \gdef^^ab{\v T} + \gdef^^ac{\'Z} + \gdef^^ad{\-} + \gdef^^ae{\v Z} + \gdef^^af{\dotaccent Z} + % + \gdef^^b0{\textdegree} + \gdef^^b1{\ogonek{a}} + \gdef^^b2{\ogonek{ }} + \gdef^^b3{\l} + \gdef^^b4{\'{}} + \gdef^^b5{\v l} + \gdef^^b6{\'s} + \gdef^^b7{\v{}} + \gdef^^b8{\cedilla\ } + \gdef^^b9{\v s} + \gdef^^ba{\cedilla s} + \gdef^^bb{\v t} + \gdef^^bc{\'z} + \gdef^^bd{\H{}} + \gdef^^be{\v z} + \gdef^^bf{\dotaccent z} + % + \gdef^^c0{\'R} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\u A} + \gdef^^c4{\"A} + \gdef^^c5{\'L} + \gdef^^c6{\'C} + \gdef^^c7{\cedilla C} + \gdef^^c8{\v C} + \gdef^^c9{\'E} + \gdef^^ca{\ogonek{E}} + \gdef^^cb{\"E} + \gdef^^cc{\v E} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\v D} + % + \gdef^^d0{\DH} + \gdef^^d1{\'N} + \gdef^^d2{\v N} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\H O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\v R} + \gdef^^d9{\ringaccent U} + \gdef^^da{\'U} + \gdef^^db{\H U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\cedilla T} + \gdef^^df{\ss} + % + \gdef^^e0{\'r} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\u a} + \gdef^^e4{\"a} + \gdef^^e5{\'l} + \gdef^^e6{\'c} + \gdef^^e7{\cedilla c} + \gdef^^e8{\v c} + \gdef^^e9{\'e} + \gdef^^ea{\ogonek{e}} + \gdef^^eb{\"e} + \gdef^^ec{\v e} + \gdef^^ed{\'{\dotless{i}}} + \gdef^^ee{\^{\dotless{i}}} + \gdef^^ef{\v d} + % + \gdef^^f0{\dh} + \gdef^^f1{\'n} + \gdef^^f2{\v n} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\H o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\v r} + \gdef^^f9{\ringaccent u} + \gdef^^fa{\'u} + \gdef^^fb{\H u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\cedilla t} + \gdef^^ff{\dotaccent{}} + } + + % UTF-8 character definitions. + % + % This code to support UTF-8 is based on LaTeX's utf8.def, with some + % changes for Texinfo conventions. It is included here under the GPL by + % permission from Frank Mittelbach and the LaTeX team. + % + \newcount\countUTFx + \newcount\countUTFy + \newcount\countUTFz + + \gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} + % + \gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} + % + \gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + + \gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi + } + + \begingroup + \catcode`\~13 + \catcode`\"12 + + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiTwoOctets\string~}} + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiThreeOctets\string~}} + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiFourOctets\string~}} + \UTFviiiLoop + \endgroup + + \begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + + \gdef\DeclareUnicodeCharacter#1#2{% + \countUTFz = "#1\relax + %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% + \begingroup + \parseXMLCharref + \def\UTFviiiTwoOctets##1##2{% + \csname u8:##1\string ##2\endcsname}% + \def\UTFviiiThreeOctets##1##2##3{% + \csname u8:##1\string ##2\string ##3\endcsname}% + \def\UTFviiiFourOctets##1##2##3##4{% + \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter + \gdef\UTFviiiTmp{#2}% + \endgroup} + + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctets.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% + \fi\fi\fi + } + + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz + \multiply\countUTFz by 64 + \advance\countUTFx by -\countUTFz + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} + \endgroup + + \def\utfeightchardefs{% + \DeclareUnicodeCharacter{00A0}{\tie} + \DeclareUnicodeCharacter{00A1}{\exclamdown} + \DeclareUnicodeCharacter{00A3}{\pounds} + \DeclareUnicodeCharacter{00A8}{\"{ }} + \DeclareUnicodeCharacter{00A9}{\copyright} + \DeclareUnicodeCharacter{00AA}{\ordf} + \DeclareUnicodeCharacter{00AB}{\guillemetleft} + \DeclareUnicodeCharacter{00AD}{\-} + \DeclareUnicodeCharacter{00AE}{\registeredsymbol} + \DeclareUnicodeCharacter{00AF}{\={ }} + + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} + \DeclareUnicodeCharacter{00B4}{\'{ }} + \DeclareUnicodeCharacter{00B8}{\cedilla{ }} + \DeclareUnicodeCharacter{00BA}{\ordm} + \DeclareUnicodeCharacter{00BB}{\guillemetright} + \DeclareUnicodeCharacter{00BF}{\questiondown} + + \DeclareUnicodeCharacter{00C0}{\`A} + \DeclareUnicodeCharacter{00C1}{\'A} + \DeclareUnicodeCharacter{00C2}{\^A} + \DeclareUnicodeCharacter{00C3}{\~A} + \DeclareUnicodeCharacter{00C4}{\"A} + \DeclareUnicodeCharacter{00C5}{\AA} + \DeclareUnicodeCharacter{00C6}{\AE} + \DeclareUnicodeCharacter{00C7}{\cedilla{C}} + \DeclareUnicodeCharacter{00C8}{\`E} + \DeclareUnicodeCharacter{00C9}{\'E} + \DeclareUnicodeCharacter{00CA}{\^E} + \DeclareUnicodeCharacter{00CB}{\"E} + \DeclareUnicodeCharacter{00CC}{\`I} + \DeclareUnicodeCharacter{00CD}{\'I} + \DeclareUnicodeCharacter{00CE}{\^I} + \DeclareUnicodeCharacter{00CF}{\"I} + + \DeclareUnicodeCharacter{00D0}{\DH} + \DeclareUnicodeCharacter{00D1}{\~N} + \DeclareUnicodeCharacter{00D2}{\`O} + \DeclareUnicodeCharacter{00D3}{\'O} + \DeclareUnicodeCharacter{00D4}{\^O} + \DeclareUnicodeCharacter{00D5}{\~O} + \DeclareUnicodeCharacter{00D6}{\"O} + \DeclareUnicodeCharacter{00D8}{\O} + \DeclareUnicodeCharacter{00D9}{\`U} + \DeclareUnicodeCharacter{00DA}{\'U} + \DeclareUnicodeCharacter{00DB}{\^U} + \DeclareUnicodeCharacter{00DC}{\"U} + \DeclareUnicodeCharacter{00DD}{\'Y} + \DeclareUnicodeCharacter{00DE}{\TH} + \DeclareUnicodeCharacter{00DF}{\ss} + + \DeclareUnicodeCharacter{00E0}{\`a} + \DeclareUnicodeCharacter{00E1}{\'a} + \DeclareUnicodeCharacter{00E2}{\^a} + \DeclareUnicodeCharacter{00E3}{\~a} + \DeclareUnicodeCharacter{00E4}{\"a} + \DeclareUnicodeCharacter{00E5}{\aa} + \DeclareUnicodeCharacter{00E6}{\ae} + \DeclareUnicodeCharacter{00E7}{\cedilla{c}} + \DeclareUnicodeCharacter{00E8}{\`e} + \DeclareUnicodeCharacter{00E9}{\'e} + \DeclareUnicodeCharacter{00EA}{\^e} + \DeclareUnicodeCharacter{00EB}{\"e} + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} + + \DeclareUnicodeCharacter{00F0}{\dh} + \DeclareUnicodeCharacter{00F1}{\~n} + \DeclareUnicodeCharacter{00F2}{\`o} + \DeclareUnicodeCharacter{00F3}{\'o} + \DeclareUnicodeCharacter{00F4}{\^o} + \DeclareUnicodeCharacter{00F5}{\~o} + \DeclareUnicodeCharacter{00F6}{\"o} + \DeclareUnicodeCharacter{00F8}{\o} + \DeclareUnicodeCharacter{00F9}{\`u} + \DeclareUnicodeCharacter{00FA}{\'u} + \DeclareUnicodeCharacter{00FB}{\^u} + \DeclareUnicodeCharacter{00FC}{\"u} + \DeclareUnicodeCharacter{00FD}{\'y} + \DeclareUnicodeCharacter{00FE}{\th} + \DeclareUnicodeCharacter{00FF}{\"y} + + \DeclareUnicodeCharacter{0100}{\=A} + \DeclareUnicodeCharacter{0101}{\=a} + \DeclareUnicodeCharacter{0102}{\u{A}} + \DeclareUnicodeCharacter{0103}{\u{a}} + \DeclareUnicodeCharacter{0104}{\ogonek{A}} + \DeclareUnicodeCharacter{0105}{\ogonek{a}} + \DeclareUnicodeCharacter{0106}{\'C} + \DeclareUnicodeCharacter{0107}{\'c} + \DeclareUnicodeCharacter{0108}{\^C} + \DeclareUnicodeCharacter{0109}{\^c} + \DeclareUnicodeCharacter{0118}{\ogonek{E}} + \DeclareUnicodeCharacter{0119}{\ogonek{e}} + \DeclareUnicodeCharacter{010A}{\dotaccent{C}} + \DeclareUnicodeCharacter{010B}{\dotaccent{c}} + \DeclareUnicodeCharacter{010C}{\v{C}} + \DeclareUnicodeCharacter{010D}{\v{c}} + \DeclareUnicodeCharacter{010E}{\v{D}} + + \DeclareUnicodeCharacter{0112}{\=E} + \DeclareUnicodeCharacter{0113}{\=e} + \DeclareUnicodeCharacter{0114}{\u{E}} + \DeclareUnicodeCharacter{0115}{\u{e}} + \DeclareUnicodeCharacter{0116}{\dotaccent{E}} + \DeclareUnicodeCharacter{0117}{\dotaccent{e}} + \DeclareUnicodeCharacter{011A}{\v{E}} + \DeclareUnicodeCharacter{011B}{\v{e}} + \DeclareUnicodeCharacter{011C}{\^G} + \DeclareUnicodeCharacter{011D}{\^g} + \DeclareUnicodeCharacter{011E}{\u{G}} + \DeclareUnicodeCharacter{011F}{\u{g}} + + \DeclareUnicodeCharacter{0120}{\dotaccent{G}} + \DeclareUnicodeCharacter{0121}{\dotaccent{g}} + \DeclareUnicodeCharacter{0124}{\^H} + \DeclareUnicodeCharacter{0125}{\^h} + \DeclareUnicodeCharacter{0128}{\~I} + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} + \DeclareUnicodeCharacter{012A}{\=I} + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} + \DeclareUnicodeCharacter{012C}{\u{I}} + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} + + \DeclareUnicodeCharacter{0130}{\dotaccent{I}} + \DeclareUnicodeCharacter{0131}{\dotless{i}} + \DeclareUnicodeCharacter{0132}{IJ} + \DeclareUnicodeCharacter{0133}{ij} + \DeclareUnicodeCharacter{0134}{\^J} + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} + \DeclareUnicodeCharacter{0139}{\'L} + \DeclareUnicodeCharacter{013A}{\'l} + + \DeclareUnicodeCharacter{0141}{\L} + \DeclareUnicodeCharacter{0142}{\l} + \DeclareUnicodeCharacter{0143}{\'N} + \DeclareUnicodeCharacter{0144}{\'n} + \DeclareUnicodeCharacter{0147}{\v{N}} + \DeclareUnicodeCharacter{0148}{\v{n}} + \DeclareUnicodeCharacter{014C}{\=O} + \DeclareUnicodeCharacter{014D}{\=o} + \DeclareUnicodeCharacter{014E}{\u{O}} + \DeclareUnicodeCharacter{014F}{\u{o}} + + \DeclareUnicodeCharacter{0150}{\H{O}} + \DeclareUnicodeCharacter{0151}{\H{o}} + \DeclareUnicodeCharacter{0152}{\OE} + \DeclareUnicodeCharacter{0153}{\oe} + \DeclareUnicodeCharacter{0154}{\'R} + \DeclareUnicodeCharacter{0155}{\'r} + \DeclareUnicodeCharacter{0158}{\v{R}} + \DeclareUnicodeCharacter{0159}{\v{r}} + \DeclareUnicodeCharacter{015A}{\'S} + \DeclareUnicodeCharacter{015B}{\'s} + \DeclareUnicodeCharacter{015C}{\^S} + \DeclareUnicodeCharacter{015D}{\^s} + \DeclareUnicodeCharacter{015E}{\cedilla{S}} + \DeclareUnicodeCharacter{015F}{\cedilla{s}} + + \DeclareUnicodeCharacter{0160}{\v{S}} + \DeclareUnicodeCharacter{0161}{\v{s}} + \DeclareUnicodeCharacter{0162}{\cedilla{t}} + \DeclareUnicodeCharacter{0163}{\cedilla{T}} + \DeclareUnicodeCharacter{0164}{\v{T}} + + \DeclareUnicodeCharacter{0168}{\~U} + \DeclareUnicodeCharacter{0169}{\~u} + \DeclareUnicodeCharacter{016A}{\=U} + \DeclareUnicodeCharacter{016B}{\=u} + \DeclareUnicodeCharacter{016C}{\u{U}} + \DeclareUnicodeCharacter{016D}{\u{u}} + \DeclareUnicodeCharacter{016E}{\ringaccent{U}} + \DeclareUnicodeCharacter{016F}{\ringaccent{u}} + + \DeclareUnicodeCharacter{0170}{\H{U}} + \DeclareUnicodeCharacter{0171}{\H{u}} + \DeclareUnicodeCharacter{0174}{\^W} + \DeclareUnicodeCharacter{0175}{\^w} + \DeclareUnicodeCharacter{0176}{\^Y} + \DeclareUnicodeCharacter{0177}{\^y} + \DeclareUnicodeCharacter{0178}{\"Y} + \DeclareUnicodeCharacter{0179}{\'Z} + \DeclareUnicodeCharacter{017A}{\'z} + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} + \DeclareUnicodeCharacter{017C}{\dotaccent{z}} + \DeclareUnicodeCharacter{017D}{\v{Z}} + \DeclareUnicodeCharacter{017E}{\v{z}} + + \DeclareUnicodeCharacter{01C4}{D\v{Z}} + \DeclareUnicodeCharacter{01C5}{D\v{z}} + \DeclareUnicodeCharacter{01C6}{d\v{z}} + \DeclareUnicodeCharacter{01C7}{LJ} + \DeclareUnicodeCharacter{01C8}{Lj} + \DeclareUnicodeCharacter{01C9}{lj} + \DeclareUnicodeCharacter{01CA}{NJ} + \DeclareUnicodeCharacter{01CB}{Nj} + \DeclareUnicodeCharacter{01CC}{nj} + \DeclareUnicodeCharacter{01CD}{\v{A}} + \DeclareUnicodeCharacter{01CE}{\v{a}} + \DeclareUnicodeCharacter{01CF}{\v{I}} + + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} + \DeclareUnicodeCharacter{01D1}{\v{O}} + \DeclareUnicodeCharacter{01D2}{\v{o}} + \DeclareUnicodeCharacter{01D3}{\v{U}} + \DeclareUnicodeCharacter{01D4}{\v{u}} + + \DeclareUnicodeCharacter{01E2}{\={\AE}} + \DeclareUnicodeCharacter{01E3}{\={\ae}} + \DeclareUnicodeCharacter{01E6}{\v{G}} + \DeclareUnicodeCharacter{01E7}{\v{g}} + \DeclareUnicodeCharacter{01E8}{\v{K}} + \DeclareUnicodeCharacter{01E9}{\v{k}} + + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} + \DeclareUnicodeCharacter{01F1}{DZ} + \DeclareUnicodeCharacter{01F2}{Dz} + \DeclareUnicodeCharacter{01F3}{dz} + \DeclareUnicodeCharacter{01F4}{\'G} + \DeclareUnicodeCharacter{01F5}{\'g} + \DeclareUnicodeCharacter{01F8}{\`N} + \DeclareUnicodeCharacter{01F9}{\`n} + \DeclareUnicodeCharacter{01FC}{\'{\AE}} + \DeclareUnicodeCharacter{01FD}{\'{\ae}} + \DeclareUnicodeCharacter{01FE}{\'{\O}} + \DeclareUnicodeCharacter{01FF}{\'{\o}} + + \DeclareUnicodeCharacter{021E}{\v{H}} + \DeclareUnicodeCharacter{021F}{\v{h}} + + \DeclareUnicodeCharacter{0226}{\dotaccent{A}} + \DeclareUnicodeCharacter{0227}{\dotaccent{a}} + \DeclareUnicodeCharacter{0228}{\cedilla{E}} + \DeclareUnicodeCharacter{0229}{\cedilla{e}} + \DeclareUnicodeCharacter{022E}{\dotaccent{O}} + \DeclareUnicodeCharacter{022F}{\dotaccent{o}} + + \DeclareUnicodeCharacter{0232}{\=Y} + \DeclareUnicodeCharacter{0233}{\=y} + \DeclareUnicodeCharacter{0237}{\dotless{j}} + + \DeclareUnicodeCharacter{02DB}{\ogonek{ }} + + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} + + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} + + \DeclareUnicodeCharacter{1E20}{\=G} + \DeclareUnicodeCharacter{1E21}{\=g} + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} + \DeclareUnicodeCharacter{1E26}{\"H} + \DeclareUnicodeCharacter{1E27}{\"h} + + \DeclareUnicodeCharacter{1E30}{\'K} + \DeclareUnicodeCharacter{1E31}{\'k} + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} + \DeclareUnicodeCharacter{1E3E}{\'M} + \DeclareUnicodeCharacter{1E3F}{\'m} + + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} + + \DeclareUnicodeCharacter{1E54}{\'P} + \DeclareUnicodeCharacter{1E55}{\'p} + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} + + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} + + \DeclareUnicodeCharacter{1E7C}{\~V} + \DeclareUnicodeCharacter{1E7D}{\~v} + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} + + \DeclareUnicodeCharacter{1E80}{\`W} + \DeclareUnicodeCharacter{1E81}{\`w} + \DeclareUnicodeCharacter{1E82}{\'W} + \DeclareUnicodeCharacter{1E83}{\'w} + \DeclareUnicodeCharacter{1E84}{\"W} + \DeclareUnicodeCharacter{1E85}{\"w} + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} + \DeclareUnicodeCharacter{1E8C}{\"X} + \DeclareUnicodeCharacter{1E8D}{\"x} + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} + + \DeclareUnicodeCharacter{1E90}{\^Z} + \DeclareUnicodeCharacter{1E91}{\^z} + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} + \DeclareUnicodeCharacter{1E97}{\"t} + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} + + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} + + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} + \DeclareUnicodeCharacter{1EBC}{\~E} + \DeclareUnicodeCharacter{1EBD}{\~e} + + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} + + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} + + \DeclareUnicodeCharacter{1EF2}{\`Y} + \DeclareUnicodeCharacter{1EF3}{\`y} + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} + + \DeclareUnicodeCharacter{1EF8}{\~Y} + \DeclareUnicodeCharacter{1EF9}{\~y} + + \DeclareUnicodeCharacter{2013}{--} + \DeclareUnicodeCharacter{2014}{---} + \DeclareUnicodeCharacter{2018}{\quoteleft} + \DeclareUnicodeCharacter{2019}{\quoteright} + \DeclareUnicodeCharacter{201A}{\quotesinglbase} + \DeclareUnicodeCharacter{201C}{\quotedblleft} + \DeclareUnicodeCharacter{201D}{\quotedblright} + \DeclareUnicodeCharacter{201E}{\quotedblbase} + \DeclareUnicodeCharacter{2022}{\bullet} + \DeclareUnicodeCharacter{2026}{\dots} + \DeclareUnicodeCharacter{2039}{\guilsinglleft} + \DeclareUnicodeCharacter{203A}{\guilsinglright} + \DeclareUnicodeCharacter{20AC}{\euro} + + \DeclareUnicodeCharacter{2192}{\expansion} + \DeclareUnicodeCharacter{21D2}{\result} + + \DeclareUnicodeCharacter{2212}{\minus} + \DeclareUnicodeCharacter{2217}{\point} + \DeclareUnicodeCharacter{2261}{\equiv} + }% end of \utfeightchardefs + + + % US-ASCII character definitions. + \def\asciichardefs{% nothing need be done + \relax + } + + % Make non-ASCII characters printable again for compatibility with + % existing Texinfo documents that may use them, even without declaring a + % document encoding. + % + \setnonasciicharscatcode \other + + + \message{formatting,} + + \newdimen\defaultparindent \defaultparindent = 15pt + + \chapheadingskip = 15pt plus 4pt minus 2pt + \secheadingskip = 12pt plus 3pt minus 2pt + \subsecheadingskip = 9pt plus 2pt minus 2pt + + % Prevent underfull vbox error messages. + \vbadness = 10000 + + % Don't be very finicky about underfull hboxes, either. + \hbadness = 6666 + + % Following George Bush, get rid of widows and orphans. + \widowpenalty=10000 + \clubpenalty=10000 + + % Use TeX 3.0's \emergencystretch to help line breaking, but if we're + % using an old version of TeX, don't do anything. We want the amount of + % stretch added to depend on the line length, hence the dependence on + % \hsize. We call this whenever the paper size is set. + % + \def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi + } + + % Parameters in order: 1) textheight; 2) textwidth; + % 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; + % 7) physical page height; 8) physical page width. + % + % We also call \setleading{\textleading}, so the caller should define + % \textleading. The caller should also set \parskip. + % + \def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch + } + + % @letterpaper (the default). + \def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{607.2pt}{6in}% that's 46 lines + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% + }} + + % Use @smallbook to reset parameters for 7x9.25 trim size. + \def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {-.2in}{0in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .5cm + }} + + % Use @smallerbook to reset parameters for 6x9 trim size. + % (Just testing, parameters still in flux.) + \def\smallerbook{{\globaldefs = 1 + \parskip = 1.5pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.4in}{4.8in}% + {-.2in}{-.4in}% + {0pt}{14pt}% + {9in}{6in}% + % + \lispnarrowing = 0.25in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .4cm + }} + + % Use @afourpaper to print on European A4 paper. + \def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{673.2pt}{160mm}% that's 51 lines + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = 5mm + }} + + % Use @afivepaper to print on European A5 paper. + % From romildo@urano.iceb.ufop.br, 2 July 2000. + % He also recommends making @example and @lisp be small. + \def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \hfuzz = 1.2pt + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm + }} + + % A specific text layout, 24x15cm overall, intended for A4 paper. + \def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 + }} + + % Use @afourwide to print on A4 paper in landscape format. + \def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 + }} + + % @pagesizes TEXTHEIGHT[,TEXTWIDTH] + % Perhaps we should allow setting the margins, \topskip, \parskip, + % and/or leading, also. Or perhaps we should compute them somehow. + % + \parseargdef\pagesizes{\pagesizesyyy #1,,\finish} + \def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1\relax + \advance\dimen0 by \voffset + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% + }} + + % Set default to letter. + % + \letterpaper + + + \message{and turning on texinfo input format.} + + \def^^L{\par} % remove \outer, so ^L can appear in an @comment + + % DEL is a comment character, in case @c does not suffice. + \catcode`\^^? = 14 + + % Define macros to output various characters with catcode for normal text. + \catcode`\"=\other \def\normaldoublequote{"} + \catcode`\$=\other \def\normaldollar{$}%$ font-lock fix + \catcode`\+=\other \def\normalplus{+} + \catcode`\<=\other \def\normalless{<} + \catcode`\>=\other \def\normalgreater{>} + \catcode`\^=\other \def\normalcaret{^} + \catcode`\_=\other \def\normalunderscore{_} + \catcode`\|=\other \def\normalverticalbar{|} + \catcode`\~=\other \def\normaltilde{~} + + % This macro is used to make a character print one way in \tt + % (where it can probably be output as-is), and another way in other fonts, + % where something hairier probably needs to be done. + % + % #1 is what to print if we are indeed using \tt; #2 is what to print + % otherwise. Since all the Computer Modern typewriter fonts have zero + % interword stretch (and shrink), and it is reasonable to expect all + % typewriter fonts to have this, we can check that font parameter. + % + \def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + + % Same as above, but check for italic font. Actually this also catches + % non-italic slanted fonts since it is impossible to distinguish them from + % italic fonts. But since this is only used by $ and it uses \sl anyway + % this is not a problem. + \def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + + % Turn off all special characters except @ + % (and those which the user can use as if they were ordinary). + % Most of these we simply print from the \tt font, but for some, we can + % use math or other variants that look better in normal text. + + \catcode`\"=\active + \def\activedoublequote{{\tt\char34}} + \let"=\activedoublequote + \catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde + \chardef\hat=`\^ + \catcode`\^=\active \def\activehat{{\tt \hat}} \let^ = \activehat + + \catcode`\_=\active + \def_{\ifusingtt\normalunderscore\_} + \let\realunder=_ + % Subroutine for the previous macro. + \def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } + + \catcode`\|=\active + \def|{{\tt\char124}} + + \chardef \less=`\< + \catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless + \chardef \gtr=`\> + \catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr + \catcode`\+=\active \def+{{\tt \char 43}} + \catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix + + % used for headline/footline in the output routine, in case the page + % breaks in the middle of an @tex block. + \def\texinfochars{% + \let< = \activeless + \let> = \activegtr + \let~ = \activetilde + \let^ = \activehat + \markupsetuplqdefault \markupsetuprqdefault + \let\b = \strong + \let\i = \smartitalic + % in principle, all other definitions in \tex have to be undone too. + } + + % If a .fmt file is being used, characters that might appear in a file + % name cannot be active until we have parsed the command line. + % So turn them off again, and have \everyjob (or @setfilename) turn them on. + % \otherifyactive is called near the end of this file. + \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + + % Used sometimes to turn off (effectively) the active characters even after + % parsing them. + \def\turnoffactive{% + \normalturnoffactive + \otherbackslash + } + + \catcode`\@=0 + + % \backslashcurfont outputs one backslash character in current font, + % as in \char`\\. + \global\chardef\backslashcurfont=`\\ + \global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work + + % \realbackslash is an actual character `\' with catcode other, and + % \doublebackslash is two of them (for the pdf outlines). + {\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} + + % In texinfo, backslash is an active character; it prints the backslash + % in fixed width font. + \catcode`\\=\active % @ for escape char from now on. + + % The story here is that in math mode, the \char of \backslashcurfont + % ends up printing the roman \ from the math symbol font (because \char + % in math mode uses the \mathcode, and plain.tex sets + % \mathcode`\\="026E). It seems better for @backslashchar{} to always + % print a typewriter backslash, hence we use an explicit \mathchar, + % which is the decimal equivalent of "715c (class 7, e.g., use \fam; + % ignored family value; char position "5C). We can't use " for the + % usual hex value because it has already been made active. + @def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} + @let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. + + % On startup, @fixbackslash assigns: + % @let \ = @normalbackslash + % \rawbackslash defines an active \ to do \backslashcurfont. + % \otherbackslash defines an active \ to be a literal `\' character with + % catcode other. We switch back and forth between these. + @gdef@rawbackslash{@let\=@backslashcurfont} + @gdef@otherbackslash{@let\=@realbackslash} + + % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of + % the literal character `\'. Also revert - to its normal character, in + % case the active - from code has slipped in. + % + {@catcode`- = @active + @gdef@normalturnoffactive{% + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } + } + + % Make _ and + \other characters, temporarily. + % This is canceled by @fixbackslash. + @otherifyactive + + % If a .fmt file is being used, we don't want the `\input texinfo' to show up. + % That is what \eatinput is for; after that, the `\' should revert to printing + % a backslash. + % + @gdef@eatinput input texinfo{@fixbackslash} + @global@let\ = @eatinput + + % On the other hand, perhaps the file did not have a `\input texinfo'. Then + % the first `\' in the file would cause an error. This macro tries to fix + % that, assuming it is called before the first `\' could plausibly occur. + % Also turn back on active characters that might appear in the input + % file name, in case not using a pre-dumped format. + % + @gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active + } + + % Say @foo, not \foo, in error messages. + @escapechar = `@@ + + % These (along with & and #) are made active for url-breaking, so need + % active definitions as the normal characters. + @def@normaldot{.} + @def@normalquest{?} + @def@normalslash{/} + + % These look ok in all fonts, so just make them not special. + % @hashchar{} gets its own user-level command, because of #line. + @catcode`@& = @other @def@normalamp{&} + @catcode`@# = @other @def@normalhash{#} + @catcode`@% = @other @def@normalpercent{%} + + @let @hashchar = @normalhash + + @c Finally, make ` and ' active, so that txicodequoteundirected and + @c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we + @c don't make ` and ' active, @code will not get them as active chars. + @c Do this last of all since we use ` in the previous @catcode assignments. + @catcode`@'=@active + @catcode`@`=@active + @markupsetuplqdefault + @markupsetuprqdefault + + @c Local variables: + @c eval: (add-hook 'write-file-hooks 'time-stamp) + @c page-delimiter: "^\\\\message" + @c time-stamp-start: "def\\\\texinfoversion{" + @c time-stamp-format: "%:y-%02m-%02d.%02H" + @c time-stamp-end: "}" + @c End: + + @c vim:sw=2: + + @ignore + arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 + @end ignore diff -rc2P 3DLDF-2.0.2/examples/00README 3DLDF-2.0.3/examples/00README *** 3DLDF-2.0.2/examples/00README Thu Nov 7 15:57:55 2013 --- 3DLDF-2.0.3/examples/00README Fri Dec 13 16:35:23 2013 *************** *** 10,19 **** LDF 2013.11.07. ! This directory (`[...]/3DLDF-2.0/examples/') contains examples of how to use 3dldf together with MetaPost, TeX, dvips and ps2pdf to generate three-dimensional graphics. - The distribution includes the generated PostScript and PDF files, so neither 3dldf - nor any of the other packages have to be installed in order to generate them. - In order to prevent them from being generated, the `Makefile.am' does not contain rules for doing this. Instead, it contains the rule `rebuild', which calls `make' recursively --- 10,16 ---- LDF 2013.11.07. ! This directory (`3DLDF-2.0.3/examples/') contains examples of how to use 3dldf together with MetaPost, TeX, dvips and ps2pdf to generate three-dimensional graphics. In order to prevent them from being generated, the `Makefile.am' does not contain rules for doing this. Instead, it contains the rule `rebuild', which calls `make' recursively *************** *** 27,33 **** Please see the files `Makefile.am' and `Makefile_sub' for more information. ! #### ** (2) #### * (1) --- 24,37 ---- Please see the files `Makefile.am' and `Makefile_sub' for more information. + PLEASE NOTE: In order to reduce the size of the distribution of the GNU 3DLDF package itself, i.e., + the compressed archive file ("tarball") `3DLDF-2.0.3.tar.gz', the generated PostScript and PDF files + are not included in the distribution. However, in order to make them available without requiring + GNU 3DLDF to have been installed successfully previously, they are distributed separately in + the file `3DLDF-2.0.3-examples.tar.gz', along with the contents of this directory. ! `3DLDF-2.0.3-examples.tar.gz' should be available wherever the distribution is, in particular, ! on `ftp.gnu.org/gnu/3dldf' or any of its mirrors. + #### ** (2) #### * (1) diff -rc2P 3DLDF-2.0.2/examples/Makefile.am 3DLDF-2.0.3/examples/Makefile.am *** 3DLDF-2.0.2/examples/Makefile.am Thu Nov 7 16:06:07 2013 --- 3DLDF-2.0.3/examples/Makefile.am Fri Dec 13 16:38:02 2013 *************** *** 1,3 **** ! #### 3DLDF-2.0/examples/Makefile.am #### Created by Laurence D. Finston (LDF) Mon Nov 4 18:55:22 CET 2013 --- 1,3 ---- ! #### 3DLDF-2.0.3/examples/Makefile.am #### Created by Laurence D. Finston (LDF) Mon Nov 4 18:55:22 CET 2013 *************** *** 71,74 **** --- 71,88 ---- # stlltn05.mp + #### Errors now occur when these two files are passed to 3dldf as input. + #### The problems cannot be fixed easily. + #### LDF 2013.12.11. + #### elpsd_17.ldf + #### plyhd_05.ldf + #### + #### LDF 2013.12.11. + + #### Chess fonts may not be available. + #### chssbrds.ldf + #### chssbrds.txt + #### + #### LDF 2013.12.11. + # The generated mp files need to be modified, so the mp files are included in # the distribution. Check this! LDF 2013.11.05. *************** *** 76,86 **** LDF_FILES := arc_1.ldf arc_1.ldf bldelem1.ldf bldelem2.ldf bldelem3.ldf \ bldelem4.ldf bldelem5.ldf braik_01.ldf braik_02.ldf braik_03.ldf \ ! chssbrds.ldf clktwr_01.ldf cones01.ldf cubd_01.ldf cubd_02.ldf \ cubd_06.ldf cycld_1.ldf cycld_2.ldf dodec_01.ldf dodec_02.ldf \ dodec_03.ldf ellpln01.ldf elpdmd01.ldf elpsd_02.ldf elpsd_06.ldf \ ! elpsd_13.ldf elpsd_17.ldf fctcn01.ldf goboards.ldf grrhm_02.ldf \ grrhm_06.ldf hyprb_00.ldf hyprb_01.ldf hyprb_02.ldf hyprb_03.ldf \ hyprb_04.ldf hyprb_05.ldf intrfr_2.ldf intrfr_3.ldf intrfr_5.ldf \ ! intrfr_6.ldf intrfr_7.ldf kntpoly1.ldf plyhd_01.ldf plyhd_05.ldf \ polyrhyt.ldf pprcut01.ldf prbla_00.ldf prbla_01.ldf prbla_05.ldf \ prbla_06.ldf prbla_10.ldf prbla_11.ldf prbla_12.ldf rhmtrc_01.ldf \ --- 90,100 ---- LDF_FILES := arc_1.ldf arc_1.ldf bldelem1.ldf bldelem2.ldf bldelem3.ldf \ bldelem4.ldf bldelem5.ldf braik_01.ldf braik_02.ldf braik_03.ldf \ ! clktwr_01.ldf cones01.ldf cubd_01.ldf cubd_02.ldf \ cubd_06.ldf cycld_1.ldf cycld_2.ldf dodec_01.ldf dodec_02.ldf \ dodec_03.ldf ellpln01.ldf elpdmd01.ldf elpsd_02.ldf elpsd_06.ldf \ ! elpsd_13.ldf fctcn01.ldf goboards.ldf grrhm_02.ldf \ grrhm_06.ldf hyprb_00.ldf hyprb_01.ldf hyprb_02.ldf hyprb_03.ldf \ hyprb_04.ldf hyprb_05.ldf intrfr_2.ldf intrfr_3.ldf intrfr_5.ldf \ ! intrfr_6.ldf intrfr_7.ldf kntpoly1.ldf plyhd_01.ldf \ polyrhyt.ldf pprcut01.ldf prbla_00.ldf prbla_01.ldf prbla_05.ldf \ prbla_06.ldf prbla_10.ldf prbla_11.ldf prbla_12.ldf rhmtrc_01.ldf \ *************** *** 90,94 **** TEX_FILES := arc_1.txt bldelem1.txt bldelem2.txt bldelem3.txt bldelem4.txt \ ! bldelem5.txt braik_01.txt braik_02.txt braik_03.txt chssbrds.txt \ clktwr_01.txt cycld_1.txt cycld_2.txt dodec_01.txt dodec_02.txt \ dodec_03.txt ellpln01.txt elpdmd01.txt fctcn01.txt \ --- 104,108 ---- TEX_FILES := arc_1.txt bldelem1.txt bldelem2.txt bldelem3.txt bldelem4.txt \ ! bldelem5.txt braik_01.txt braik_02.txt braik_03.txt \ clktwr_01.txt cycld_1.txt cycld_2.txt dodec_01.txt dodec_02.txt \ dodec_03.txt ellpln01.txt elpdmd01.txt fctcn01.txt \ *************** *** 142,146 **** #### LDF 2013.11.05. ! EXTRA_DIST = 00README $(PS_FILES) $(PDF_FILES) $(LDF_FILES) $(TEX_FILES) \ $(NON_GEN_MP_FILES) $(LMC_FILES) Makefile.am Makefile.in Makefile_sub \ fmt8511.txt fmtdina4.txt wave_1.ldf wave_1.mp.bak wave_2.ldf wave_2.mp.bak --- 156,165 ---- #### LDF 2013.11.05. ! #### Removed the PostScript and PDF files from the distribution. ! #### I will distribute them separately. ! #### ! #### $(PS_FILES) $(PDF_FILES) ! ! EXTRA_DIST = 00README $(LDF_FILES) $(TEX_FILES) \ $(NON_GEN_MP_FILES) $(LMC_FILES) Makefile.am Makefile.in Makefile_sub \ fmt8511.txt fmtdina4.txt wave_1.ldf wave_1.mp.bak wave_2.ldf wave_2.mp.bak *************** *** 200,205 **** query: @echo "LDF_FILES == $(LDF_FILES)" ! $(MAKE) -f Makefile_sub query # @echo "TEX == $(TEX)" # @echo "CXXCOMPILE == $(CXXCOMPILE)" --- 219,225 ---- query: @echo "LDF_FILES == $(LDF_FILES)" ! @echo "PS_FILES == $(PS_FILES)" + # $(MAKE) -f Makefile_sub query # @echo "TEX == $(TEX)" # @echo "CXXCOMPILE == $(CXXCOMPILE)" diff -rc2P 3DLDF-2.0.2/examples/Makefile.in 3DLDF-2.0.3/examples/Makefile.in *** 3DLDF-2.0.2/examples/Makefile.in Sun Nov 10 18:30:13 2013 --- 3DLDF-2.0.3/examples/Makefile.in Fri Dec 13 16:56:54 2013 *************** *** 15,19 **** @SET_MAKE@ ! #### 3DLDF-2.0/examples/Makefile.am #### Created by Laurence D. Finston (LDF) Mon Nov 4 18:55:22 CET 2013 --- 15,19 ---- @SET_MAKE@ ! #### 3DLDF-2.0.3/examples/Makefile.am #### Created by Laurence D. Finston (LDF) Mon Nov 4 18:55:22 CET 2013 *************** *** 81,84 **** --- 81,98 ---- # stlltn05.mp + #### Errors now occur when these two files are passed to 3dldf as input. + #### The problems cannot be fixed easily. + #### LDF 2013.12.11. + #### elpsd_17.ldf + #### plyhd_05.ldf + #### + #### LDF 2013.12.11. + + #### Chess fonts may not be available. + #### chssbrds.ldf + #### chssbrds.txt + #### + #### LDF 2013.12.11. + # The generated mp files need to be modified, so the mp files are included in # the distribution. Check this! LDF 2013.11.05. *************** *** 313,323 **** LDF_FILES := arc_1.ldf arc_1.ldf bldelem1.ldf bldelem2.ldf bldelem3.ldf \ bldelem4.ldf bldelem5.ldf braik_01.ldf braik_02.ldf braik_03.ldf \ ! chssbrds.ldf clktwr_01.ldf cones01.ldf cubd_01.ldf cubd_02.ldf \ cubd_06.ldf cycld_1.ldf cycld_2.ldf dodec_01.ldf dodec_02.ldf \ dodec_03.ldf ellpln01.ldf elpdmd01.ldf elpsd_02.ldf elpsd_06.ldf \ ! elpsd_13.ldf elpsd_17.ldf fctcn01.ldf goboards.ldf grrhm_02.ldf \ grrhm_06.ldf hyprb_00.ldf hyprb_01.ldf hyprb_02.ldf hyprb_03.ldf \ hyprb_04.ldf hyprb_05.ldf intrfr_2.ldf intrfr_3.ldf intrfr_5.ldf \ ! intrfr_6.ldf intrfr_7.ldf kntpoly1.ldf plyhd_01.ldf plyhd_05.ldf \ polyrhyt.ldf pprcut01.ldf prbla_00.ldf prbla_01.ldf prbla_05.ldf \ prbla_06.ldf prbla_10.ldf prbla_11.ldf prbla_12.ldf rhmtrc_01.ldf \ --- 327,337 ---- LDF_FILES := arc_1.ldf arc_1.ldf bldelem1.ldf bldelem2.ldf bldelem3.ldf \ bldelem4.ldf bldelem5.ldf braik_01.ldf braik_02.ldf braik_03.ldf \ ! clktwr_01.ldf cones01.ldf cubd_01.ldf cubd_02.ldf \ cubd_06.ldf cycld_1.ldf cycld_2.ldf dodec_01.ldf dodec_02.ldf \ dodec_03.ldf ellpln01.ldf elpdmd01.ldf elpsd_02.ldf elpsd_06.ldf \ ! elpsd_13.ldf fctcn01.ldf goboards.ldf grrhm_02.ldf \ grrhm_06.ldf hyprb_00.ldf hyprb_01.ldf hyprb_02.ldf hyprb_03.ldf \ hyprb_04.ldf hyprb_05.ldf intrfr_2.ldf intrfr_3.ldf intrfr_5.ldf \ ! intrfr_6.ldf intrfr_7.ldf kntpoly1.ldf plyhd_01.ldf \ polyrhyt.ldf pprcut01.ldf prbla_00.ldf prbla_01.ldf prbla_05.ldf \ prbla_06.ldf prbla_10.ldf prbla_11.ldf prbla_12.ldf rhmtrc_01.ldf \ *************** *** 327,331 **** TEX_FILES := arc_1.txt bldelem1.txt bldelem2.txt bldelem3.txt bldelem4.txt \ ! bldelem5.txt braik_01.txt braik_02.txt braik_03.txt chssbrds.txt \ clktwr_01.txt cycld_1.txt cycld_2.txt dodec_01.txt dodec_02.txt \ dodec_03.txt ellpln01.txt elpdmd01.txt fctcn01.txt \ --- 341,345 ---- TEX_FILES := arc_1.txt bldelem1.txt bldelem2.txt bldelem3.txt bldelem4.txt \ ! bldelem5.txt braik_01.txt braik_02.txt braik_03.txt \ clktwr_01.txt cycld_1.txt cycld_2.txt dodec_01.txt dodec_02.txt \ dodec_03.txt ellpln01.txt elpdmd01.txt fctcn01.txt \ *************** *** 360,364 **** #### #### LDF 2013.11.05. ! EXTRA_DIST = 00README $(PS_FILES) $(PDF_FILES) $(LDF_FILES) $(TEX_FILES) \ $(NON_GEN_MP_FILES) $(LMC_FILES) Makefile.am Makefile.in Makefile_sub \ fmt8511.txt fmtdina4.txt wave_1.ldf wave_1.mp.bak wave_2.ldf wave_2.mp.bak --- 374,383 ---- #### #### LDF 2013.11.05. ! ! #### Removed the PostScript and PDF files from the distribution. ! #### I will distribute them separately. ! #### ! #### $(PS_FILES) $(PDF_FILES) ! EXTRA_DIST = 00README $(LDF_FILES) $(TEX_FILES) \ $(NON_GEN_MP_FILES) $(LMC_FILES) Makefile.am Makefile.in Makefile_sub \ fmt8511.txt fmtdina4.txt wave_1.ldf wave_1.mp.bak wave_2.ldf wave_2.mp.bak *************** *** 620,625 **** query: @echo "LDF_FILES == $(LDF_FILES)" ! $(MAKE) -f Makefile_sub query # @echo "TEX == $(TEX)" # @echo "CXXCOMPILE == $(CXXCOMPILE)" --- 639,645 ---- query: @echo "LDF_FILES == $(LDF_FILES)" ! @echo "PS_FILES == $(PS_FILES)" + # $(MAKE) -f Makefile_sub query # @echo "TEX == $(TEX)" # @echo "CXXCOMPILE == $(CXXCOMPILE)" diff -rc2P 3DLDF-2.0.2/examples/Makefile_sub 3DLDF-2.0.3/examples/Makefile_sub *** 3DLDF-2.0.2/examples/Makefile_sub Thu Nov 7 15:38:01 2013 --- 3DLDF-2.0.3/examples/Makefile_sub Fri Dec 13 16:38:03 2013 *************** *** 1,4 **** #### Makefile_sub ! #### [...]/3DLDF-2.0/examples/Makefile_sub #### Created by Laurence D. Finston (LDF) Thu Nov 7 16:31:41 CET 2013 --- 1,4 ---- #### Makefile_sub ! #### [...]/3DLDF-2.0.3/examples/Makefile_sub #### Created by Laurence D. Finston (LDF) Thu Nov 7 16:31:41 CET 2013 Only in 3DLDF-2.0.2/examples: arc_1.pdf Only in 3DLDF-2.0.2/examples: arc_1.ps Only in 3DLDF-2.0.2/examples: bldelem1.pdf Only in 3DLDF-2.0.2/examples: bldelem1.ps diff -rc2P 3DLDF-2.0.2/examples/bldelem1.txt 3DLDF-2.0.3/examples/bldelem1.txt *** 3DLDF-2.0.2/examples/bldelem1.txt Tue Nov 5 14:26:49 2013 --- 3DLDF-2.0.3/examples/bldelem1.txt Fri Nov 15 13:10:33 2013 *************** *** 152,160 **** %\hsize=420mm ! %% \advance\voffset by -1in ! %% \advance\voffset by 1.25cm ! %% \advance\hoffset by -1in ! %% \advance\hoffset by 1cm ! --- 152,159 ---- %\hsize=420mm ! \advance\voffset by -1in ! \advance\voffset by 1.25cm ! \advance\hoffset by -1in ! \advance\hoffset by 1cm Only in 3DLDF-2.0.2/examples: bldelem2.pdf Only in 3DLDF-2.0.2/examples: bldelem2.ps Only in 3DLDF-2.0.2/examples: bldelem3.pdf Only in 3DLDF-2.0.2/examples: bldelem3.ps Only in 3DLDF-2.0.2/examples: bldelem4.pdf Only in 3DLDF-2.0.2/examples: bldelem4.ps Only in 3DLDF-2.0.2/examples: bldelem5.pdf Only in 3DLDF-2.0.2/examples: bldelem5.ps Only in 3DLDF-2.0.2/examples: braik_01.pdf Only in 3DLDF-2.0.2/examples: braik_01.ps Only in 3DLDF-2.0.2/examples: braik_02.pdf Only in 3DLDF-2.0.2/examples: braik_02.ps Only in 3DLDF-2.0.2/examples: braik_03.pdf Only in 3DLDF-2.0.2/examples: braik_03.ps Only in 3DLDF-2.0.2/examples: chssbrds.ldf Only in 3DLDF-2.0.2/examples: chssbrds.pdf Only in 3DLDF-2.0.2/examples: chssbrds.ps Only in 3DLDF-2.0.2/examples: chssbrds.txt Only in 3DLDF-2.0.2/examples: clktwr_01.pdf Only in 3DLDF-2.0.2/examples: clktwr_01.ps diff -rc2P 3DLDF-2.0.2/examples/cubd_06.ldf 3DLDF-2.0.3/examples/cubd_06.ldf *** 3DLDF-2.0.2/examples/cubd_06.ldf Mon Nov 4 18:00:45 2013 --- 3DLDF-2.0.3/examples/cubd_06.ldf Wed Dec 11 18:56:53 2013 *************** *** 86,93 **** draw c; draw r with_color red; plane q; ! q := (plane) r; polygon poly; --- 86,95 ---- draw c; + draw r with_color red; plane q; ! ! q := get_plane r; polygon poly; *************** *** 102,106 **** endfor; - label.lrt("$i_0$", p0); label.lft("$i_1$", p1); --- 104,107 ---- *************** *** 117,121 **** label_pt := (0, -10); - beginfig(2); output save_picture with_projection parallel_x_z with_factor .75; --- 118,121 ---- *************** *** 123,127 **** endfig with_projection parallel_x_y; - beginfig(3); output save_picture with_projection parallel_x_y with_factor .75; --- 123,126 ---- Only in 3DLDF-2.0.2/examples: cycld_1.pdf Only in 3DLDF-2.0.2/examples: cycld_1.ps Only in 3DLDF-2.0.2/examples: cycld_2.pdf Only in 3DLDF-2.0.2/examples: cycld_2.ps Only in 3DLDF-2.0.2/examples: dodec_01.pdf Only in 3DLDF-2.0.2/examples: dodec_01.ps diff -rc2P 3DLDF-2.0.2/examples/dodec_02.ldf 3DLDF-2.0.3/examples/dodec_02.ldf *** 3DLDF-2.0.2/examples/dodec_02.ldf Tue Nov 5 14:29:23 2013 --- 3DLDF-2.0.3/examples/dodec_02.ldf Sun Nov 10 20:35:55 2013 *************** *** 70,75 **** --- 70,77 ---- %% ** (2) draw_dodecahedron_net + input "dodec_02.lmc"; + %% *** (3) Global declarations and initializations diff -rc2P 3DLDF-2.0.2/examples/dodec_02.lmc 3DLDF-2.0.3/examples/dodec_02.lmc *** 3DLDF-2.0.2/examples/dodec_02.lmc Tue Nov 5 14:29:24 2013 --- 3DLDF-2.0.3/examples/dodec_02.lmc Sun Nov 10 20:54:05 2013 *************** *** 97,100 **** --- 97,101 ---- rpv := get_net dodecahedron with_diameter diameter; + %% rpv needs to be rotated because the routines for "folding" %% the net to make polyhedra in 3DLDF fold upwards, whereas *************** *** 157,160 **** --- 158,162 ---- endfor; + %% **** (4) Draw stitch lines. Only in 3DLDF-2.0.2/examples: dodec_02.pdf Only in 3DLDF-2.0.2/examples: dodec_02.ps Only in 3DLDF-2.0.2/examples: dodec_03.pdf Only in 3DLDF-2.0.2/examples: dodec_03.ps Only in 3DLDF-2.0.2/examples: ellpln01.pdf Only in 3DLDF-2.0.2/examples: ellpln01.ps Only in 3DLDF-2.0.2/examples: elpdmd01.pdf Only in 3DLDF-2.0.2/examples: elpdmd01.ps diff -rc2P 3DLDF-2.0.2/examples/elpsd_06.ldf 3DLDF-2.0.3/examples/elpsd_06.ldf *** 3DLDF-2.0.2/examples/elpsd_06.ldf Mon Nov 4 18:00:45 2013 --- 3DLDF-2.0.3/examples/elpsd_06.ldf Wed Dec 11 19:00:29 2013 *************** *** 83,87 **** ellipse e; ! e := get_ellipse 3 E; p2 := get_point 60 e; %% On the surface. --- 83,88 ---- ellipse e; ! ! e := get_ellipse (3) E; p2 := get_point 60 e; %% On the surface. Only in 3DLDF-2.0.2/examples: elpsd_17.ldf Only in 3DLDF-2.0.2/examples: fctcn01.pdf Only in 3DLDF-2.0.2/examples: fctcn01.ps Only in 3DLDF-2.0.2/examples: goboards.pdf Only in 3DLDF-2.0.2/examples: goboards.ps diff -rc2P 3DLDF-2.0.2/examples/grrhm_02.ldf 3DLDF-2.0.3/examples/grrhm_02.ldf *** 3DLDF-2.0.2/examples/grrhm_02.ldf Mon Nov 4 18:00:45 2013 --- 3DLDF-2.0.3/examples/grrhm_02.ldf Wed Dec 11 19:00:29 2013 *************** *** 72,77 **** beginfig(1); polyhedron gr; ! gr := unit_great_rhombicosidododecahedron scaled 4; polygon poly[]; --- 72,79 ---- beginfig(1); + polyhedron gr; ! ! gr := unit_great_rhombicosidodecahedron scaled (4, 0); polygon poly[]; *************** *** 104,107 **** --- 106,110 ---- beginfig(2); + for i = 0 upto size gr - 1: poly[i] := get_reg_polygon (i) gr; *************** *** 128,131 **** --- 131,135 ---- beginfig(4); + for i = 0 upto size gr - 1: poly[i] := get_reg_polygon (i) gr; *************** *** 147,152 **** endfig with_projection parallel_z_y; - - verbatim_metapost "end"; end; --- 151,154 ---- Only in 3DLDF-2.0.2/examples: grrhm_06.pdf Only in 3DLDF-2.0.2/examples: grrhm_06.ps Only in 3DLDF-2.0.2/examples: hyprb_00.pdf Only in 3DLDF-2.0.2/examples: hyprb_00.ps Only in 3DLDF-2.0.2/examples: hyprb_01.pdf Only in 3DLDF-2.0.2/examples: hyprb_01.ps Only in 3DLDF-2.0.2/examples: hyprb_02.pdf Only in 3DLDF-2.0.2/examples: hyprb_02.ps diff -rc2P 3DLDF-2.0.2/examples/hyprb_05.ldf 3DLDF-2.0.3/examples/hyprb_05.ldf *** 3DLDF-2.0.2/examples/hyprb_05.ldf Mon Nov 4 18:00:45 2013 --- 3DLDF-2.0.3/examples/hyprb_05.ldf Wed Dec 11 19:00:29 2013 *************** *** 76,80 **** bool_point_vector bpv; ! bpv := (plane) r intersection_points h; draw r; --- 76,80 ---- bool_point_vector bpv; ! bpv := get_plane r intersection_points h; draw r; Only in 3DLDF-2.0.2/examples: intrfr_2.pdf Only in 3DLDF-2.0.2/examples: intrfr_2.ps Only in 3DLDF-2.0.2/examples: intrfr_3.pdf Only in 3DLDF-2.0.2/examples: intrfr_3.ps Only in 3DLDF-2.0.2/examples: intrfr_5.pdf Only in 3DLDF-2.0.2/examples: intrfr_5.ps Only in 3DLDF-2.0.2/examples: intrfr_6.pdf Only in 3DLDF-2.0.2/examples: intrfr_6.ps Only in 3DLDF-2.0.2/examples: intrfr_7.pdf Only in 3DLDF-2.0.2/examples: intrfr_7.ps Only in 3DLDF-2.0.2/examples: kntpoly1.pdf Only in 3DLDF-2.0.2/examples: kntpoly1.ps Only in 3DLDF-2.0.2/examples: plyhd_05.ldf Only in 3DLDF-2.0.2/examples: polyrhyt.pdf Only in 3DLDF-2.0.2/examples: polyrhyt.ps Only in 3DLDF-2.0.2/examples: pprcuts.pdf Only in 3DLDF-2.0.2/examples: pprcuts.ps Only in 3DLDF-2.0.2/examples: prbla_00.pdf Only in 3DLDF-2.0.2/examples: prbla_00.ps Only in 3DLDF-2.0.2/examples: prbla_01.pdf Only in 3DLDF-2.0.2/examples: prbla_01.ps Only in 3DLDF-2.0.2/examples: prbla_05.pdf Only in 3DLDF-2.0.2/examples: prbla_05.ps Only in 3DLDF-2.0.2/examples: prbla_06.pdf Only in 3DLDF-2.0.2/examples: prbla_06.ps Only in 3DLDF-2.0.2/examples: prbla_10.pdf Only in 3DLDF-2.0.2/examples: prbla_10.ps Only in 3DLDF-2.0.2/examples: prbla_11.pdf Only in 3DLDF-2.0.2/examples: prbla_11.ps Only in 3DLDF-2.0.2/examples: prbla_12.pdf Only in 3DLDF-2.0.2/examples: prbla_12.ps diff -rc2P 3DLDF-2.0.2/examples/rhmtrc_01.ldf 3DLDF-2.0.3/examples/rhmtrc_01.ldf *** 3DLDF-2.0.2/examples/rhmtrc_01.ldf Sun Nov 10 16:09:25 2013 --- 3DLDF-2.0.3/examples/rhmtrc_01.ldf Wed Dec 11 19:00:29 2013 *************** *** 562,570 **** endfor; - - - - - %% **** (4) End of figure 2 --- 562,565 ---- Only in 3DLDF-2.0.2/examples: rhmtrc_01.pdf Only in 3DLDF-2.0.2/examples: rhmtrc_01.ps Only in 3DLDF-2.0.2/examples: ripple_1.pdf Only in 3DLDF-2.0.2/examples: ripple_1.ps Only in 3DLDF-2.0.2/examples: ripple_2.pdf Only in 3DLDF-2.0.2/examples: ripple_2.ps Only in 3DLDF-2.0.2/examples: sphrmd01.pdf Only in 3DLDF-2.0.2/examples: sphrmd01.ps Only in 3DLDF-2.0.2/examples: sphrmd02.pdf Only in 3DLDF-2.0.2/examples: sphrmd02.ps Only in 3DLDF-2.0.2/examples: sphrmd03.pdf Only in 3DLDF-2.0.2/examples: sphrmd03.ps Only in 3DLDF-2.0.2/examples: stgrddc1.pdf Only in 3DLDF-2.0.2/examples: stgrddc1.ps Only in 3DLDF-2.0.2/examples: stlltn01.pdf Only in 3DLDF-2.0.2/examples: stlltn01.ps Only in 3DLDF-2.0.2/examples: stlltn02.pdf Only in 3DLDF-2.0.2/examples: stlltn02.ps Only in 3DLDF-2.0.2/examples: stlltn04.pdf Only in 3DLDF-2.0.2/examples: stlltn04.ps Only in 3DLDF-2.0.2/examples: stlltns.pdf Only in 3DLDF-2.0.2/examples: stlltns.ps Only in 3DLDF-2.0.2/examples: strspr01.pdf Only in 3DLDF-2.0.2/examples: strspr01.ps Only in 3DLDF-2.0.2/examples: sundl_01.pdf Only in 3DLDF-2.0.2/examples: sundl_01.ps Only in 3DLDF-2.0.2/examples: sundl_02.pdf Only in 3DLDF-2.0.2/examples: sundl_02.ps Only in 3DLDF-2.0.2/examples: sundl_03.pdf Only in 3DLDF-2.0.2/examples: sundl_03.ps Only in 3DLDF-2.0.2/examples: tngnts_1.pdf Only in 3DLDF-2.0.2/examples: tngnts_1.ps Only in 3DLDF-2.0.2/examples: trchd_1.pdf Only in 3DLDF-2.0.2/examples: trchd_1.ps Only in 3DLDF-2.0.2/examples: wave_1.pdf Only in 3DLDF-2.0.2/examples: wave_1.ps Only in 3DLDF-2.0.2/examples: wave_2.pdf Only in 3DLDF-2.0.2/examples: wave_2.ps diff -rc2P 3DLDF-2.0.2/reconfig.sh 3DLDF-2.0.3/reconfig.sh *** 3DLDF-2.0.2/reconfig.sh Sun Nov 10 18:28:10 2013 --- 3DLDF-2.0.3/reconfig.sh Fri Dec 13 16:20:17 2013 *************** *** 31,35 **** ##### --prefix=`pwd` $CONF_STATIC LIBS="-lgsl -lgslcblas -lm" ! configure --prefix=`pwd` $CONF_STATIC LIBS="-lgsl -lgslcblas -lm" if test $# -gt 1 --- 31,41 ---- ##### --prefix=`pwd` $CONF_STATIC LIBS="-lgsl -lgslcblas -lm" ! ! #### configure CPPFLAGS="-I/home/lfinsto/glibc-install/include" \ ! #### LDFLAGS="-L/home/lfinsto/glibc-install/lib64 -L/home/lfinsto/glibc-install/lib64 ! #### -L/home/lfinsto/gcc-4.8.2/lib64/../lib64" \ ! ##### --prefix=`pwd` $CONF_STATIC LIBS="-lgsl -lgslcblas -lm" ! ! ./configure --prefix=`pwd` $CONF_STATIC LIBS="-lgsl -lgslcblas -lm" if test $# -gt 1 diff -rc2P 3DLDF-2.0.2/src/Makefile.am 3DLDF-2.0.3/src/Makefile.am *** 3DLDF-2.0.2/src/Makefile.am Sun Nov 10 14:20:53 2013 --- 3DLDF-2.0.3/src/Makefile.am Fri Dec 13 12:34:39 2013 *************** *** 69,73 **** bin_PROGRAMS = dummy$(EXEEXT) prbsnflx$(EXEEXT) 3dldf$(EXEEXT) ! lib_LTLIBRARIES = lib3dldflb.la lib3dldfsp.la # colall.web intro.web --- 69,75 ---- bin_PROGRAMS = dummy$(EXEEXT) prbsnflx$(EXEEXT) 3dldf$(EXEEXT) ! # lib3dldfsp.la ! ! lib_LTLIBRARIES = lib3dldflb.la # colall.web intro.web *************** *** 97,110 **** ! 3dldfsp_CWEB_files = parser2.web scanner2.web - 3dldfsp_c_files = $(3dldfsp_CWEB_files:.web=.c) - 3dldfsp_cpp_files = $(3dldfsp_CWEB_files:.web=.c++) - 3dldfsp_h_files = $(3dldfsp_CWEB_files:.web=.h) - 3dldfsp_hpp_files = $(3dldfsp_CWEB_files:.web=.h++) parser_1.h++ - 3dldfsp_obj_files = $(3dldfsp_CWEB_files:.web=.o) - 3dldfsp_lo_files = $(3dldfsp_CWEB_files:.web=.lo) ! 3dldf_LDADD = lib3dldflb.la lib3dldfsp.la --- 99,113 ---- ! # 3dldfsp_CWEB_files = parser2.web scanner2.web ! ! # 3dldfsp_c_files = $(3dldfsp_CWEB_files:.web=.c) ! # 3dldfsp_cpp_files = $(3dldfsp_CWEB_files:.web=.c++) ! # 3dldfsp_h_files = $(3dldfsp_CWEB_files:.web=.h) ! # 3dldfsp_hpp_files = $(3dldfsp_CWEB_files:.web=.h++) parser_1.h++ ! # 3dldfsp_obj_files = $(3dldfsp_CWEB_files:.web=.o) ! # 3dldfsp_lo_files = $(3dldfsp_CWEB_files:.web=.lo) ! 3dldf_LDADD = lib3dldflb.la # lib3dldfsp.la *************** *** 158,161 **** --- 161,166 ---- dummy_SOURCES = dummy.cxx + # $(3dldfsp_CWEB_files) + EXTRA_DIST = check_scan_parse_output.sh \ cpyrtcpp.txt cpyrtasc.txt cpyrtcpp.txt cpyrtc.txt cpyrtel.txt \ *************** *** 164,169 **** sample.ldf sample0.ldf sample1.ldf sample2.ldf \ 3DLDFmp.mp 3DLDFtex.bas 3DLDFtex.tex \ ! $(3dldflb_CWEB_files) $(3dldfsp_CWEB_files) $(3dldf_SOURCES) \ ! $(3dldf_PARSER_FILES) CLEANFILES := $(3dldf_c_files) $(3dldf_cpp_files) $(3dldf_hpp_files) $(3dldf_h_files) \ --- 169,177 ---- sample.ldf sample0.ldf sample1.ldf sample2.ldf \ 3DLDFmp.mp 3DLDFtex.bas 3DLDFtex.tex \ ! $(3dldflb_CWEB_files) $(3dldf_SOURCES) \ ! $(3dldf_PARSER_FILES) scanner2.web parser2.web ! ! ! # scanner2.c++ scanner2.h++ scanner2.l++ parser2.y++ CLEANFILES := $(3dldf_c_files) $(3dldf_cpp_files) $(3dldf_hpp_files) $(3dldf_h_files) \ *************** *** 173,178 **** loader.c loader.c++ loader.h loader.h++ \ parser.c parser.c++ parser_1.h++ parser.h++ parser.output parser.y++ \ ! prbsnflx.c++ examples.h layers.h layers.h++ parser.h++ parser2.y++ parser.y++ \ ! scanner2.c++ scanner2.h++ ldf_1.log scanner2.l++ # AM_CXXFLAGS = --- 181,186 ---- loader.c loader.c++ loader.h loader.h++ \ parser.c parser.c++ parser_1.h++ parser.h++ parser.output parser.y++ \ ! prbsnflx.c++ examples.h layers.h layers.h++ parser.h++ parser.y++ \ ! ldf_1.log # AM_CXXFLAGS = *************** *** 185,190 **** .PHONY : touch touch: ! touch 3dldf$(EXEEXT) $(3dldf_obj_files) $(3dldflb_obj_files) $(3dldfsp_obj_files) \ $(3dldf_LDADD) --- 193,200 ---- .PHONY : touch + # $(3dldfsp_obj_files) + touch: ! touch 3dldf$(EXEEXT) $(3dldf_obj_files) $(3dldflb_obj_files) \ $(3dldf_LDADD) *************** *** 192,207 **** touch $@ ! lib3dldfsp.c: ! touch $@ dist-hook: ! rm ./lib3dldflb.c ./lib3dldfsp.c #### *** (3) Link 3dldf 3dldf$(EXEEXT): $(3dldf_obj_files) $(3dldf_LDADD) @echo "Linking 3dldf" $(CXXLINK) $(3dldf_obj_files) -pthread $(3dldf_LDADD) $(LIBS) ! @touch $(3dldf_obj_files) $(3dldflb_obj_files) $(3dldfsp_obj_files) \ $(3dldf_LDADD) 3dldf$(EXEEXT) --- 202,219 ---- touch $@ ! # lib3dldfsp.c: ! # touch $@ dist-hook: ! rm ./lib3dldflb.c # ./lib3dldfsp.c #### *** (3) Link 3dldf + # $(3dldfsp_obj_files) + 3dldf$(EXEEXT): $(3dldf_obj_files) $(3dldf_LDADD) @echo "Linking 3dldf" $(CXXLINK) $(3dldf_obj_files) -pthread $(3dldf_LDADD) $(LIBS) ! @touch $(3dldf_obj_files) $(3dldflb_obj_files) \ $(3dldf_LDADD) 3dldf$(EXEEXT) *************** *** 209,214 **** $(CXXLINK) -rpath $(libdir) $(3dldflb_lo_files) $(LIBS) ! lib3dldfsp.la: $(3dldfsp_hpp_files) $(3dldf_hpp_files) $(3dldfsp_lo_files) ! $(CXXLINK) -rpath $(libdir) $(3dldfsp_lo_files) $(LIBS) --- 221,226 ---- $(CXXLINK) -rpath $(libdir) $(3dldflb_lo_files) $(LIBS) ! # lib3dldfsp.la: $(3dldfsp_hpp_files) $(3dldf_hpp_files) $(3dldfsp_lo_files) ! # $(CXXLINK) -rpath $(libdir) $(3dldfsp_lo_files) $(LIBS) *************** *** 288,292 **** #### *** (3) parser ! parser.y++: parser.w prbsnflx$(EXEEXT) $(3dldf_PARSER_FILES) ctangle $< ./prbsnflx$(EXEEXT) parser.c parser.y --- 300,304 ---- #### *** (3) parser ! parser.y++ parser_1.h++: parser.w prbsnflx$(EXEEXT) $(3dldf_PARSER_FILES) ctangle $< ./prbsnflx$(EXEEXT) parser.c parser.y *************** *** 295,299 **** touch $@ ! parser.c++ parser.h++ parser_1.h++: parser.y++ $(YACC) --debug -d -o parser.cxx $< ./check_scan_parse_output.sh parser.cxx parser.c++ --- 307,312 ---- touch $@ ! ! parser.c++ parser.h++: parser.y++ $(YACC) --debug -d -o parser.cxx $< ./check_scan_parse_output.sh parser.cxx parser.c++ *************** *** 317,371 **** @echo "Compiling 'parser.c++'. This may take awhile ... " $(CXXCOMPILE) -c -o $@ $< - touch $@ - #### *** (3) parser2 ! parser2.y++ : parser2.web prbsnflx$(EXEEXT) $(3dldf_PARSER2_FILES) ! ctangle $< ! ./prbsnflx$(EXEEXT) parser2.c parser2.y ! rm parser2.c ! ./check_scan_parse_output.sh parser2.y parser2.y++ ! @touch $@ ! ! parser2.c++ parser2.h++ : parser2.y++ ! $(YACC) --debug -d -o parser2.cxx $< ! ./check_scan_parse_output.sh parser2.cxx parser2.c++ ! ./check_scan_parse_output.sh parser2.hxx parser2.h++ ! @touch $@ ! ! parser2.o: parser2.c++ parser2.h++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ \ ! complex.h++ cones.h++ conicsct.h++ crclslc.h++ \ ! creatnew.h++ cuboid.h++ curves.h++ cylinder.h++ \ ! dashptrn.h++ ddchdrn.h++ ellipses.h++ ellpsoid.h++ \ ! ellpsslc.h++ glyphs.h++ gsltmplt.h++ helices.h++ \ ! hyprbola.h++ io.h++ lines.h++ matrices.h++ nurbs.h++ \ ! origami.h++ parabola.h++ parabold.h++ paraellp.h++ \ ! parahypr.h++ paths.h++ pctfncs0.h++ pens.h++ pictures.h++ \ ! planes.h++ plyhdslc.h++ pntrvcf0.h++ pntrvctr.h++ \ ! points.h++ polygons.h++ polyhed.h++ predctes.h++ \ ! primes.h++ pspglb.h++ rectangs.h++ rhtchdrn.h++ \ ! scanprse.h++ shapes.h++ solfaced.h++ solids.h++ \ ! spheres.h++ sphrdevl.h++ transfor.h++ triangle.h++ \ ! utility.h++ ! $(CXXCOMPILE) -c -o $@ $< ! @touch $@ ! ! scanner2.o: scanner2.c++ scanner2.h++ io.h++ loader.h++ parser2.h++ pspglb.h++ ! $(CXXCOMPILE) -c -o $@ $< ! @touch $@ ! ! scanner2.c++ scanner2.h++ : scanner2.l++ ! $(LEX) -o scanner2.cxx $< ! ./check_scan_parse_output.sh scanner2.cxx scanner2.c++ ! ./check_scan_parse_output.sh scanner2.hxx scanner2.h++ ! @touch $@ ! ! scanner2.l++ : scanner2.web prbsnflx$(EXEEXT) ! ctangle scanner2.web ! ./prbsnflx$(EXEEXT) scanner2.c scanner2.l ! rm scanner2.c ! ./check_scan_parse_output.sh scanner2.l scanner2.l++ ! @touch $@ prbsnflx$(EXEEXT): prbsnflx.c++ --- 330,382 ---- @echo "Compiling 'parser.c++'. This may take awhile ... " $(CXXCOMPILE) -c -o $@ $< #### *** (3) parser2 ! # parser2.y++ : parser2.web prbsnflx$(EXEEXT) $(3dldf_PARSER2_FILES) ! # ctangle $< ! # ./prbsnflx$(EXEEXT) parser2.c parser2.y ! # rm parser2.c ! # ./check_scan_parse_output.sh parser2.y parser2.y++ ! # @touch $@ ! ! # parser2.c++ parser2.h++ : parser2.y++ ! # $(YACC) --debug -d -o parser2.cxx $< ! # ./check_scan_parse_output.sh parser2.cxx parser2.c++ ! # ./check_scan_parse_output.sh parser2.hxx parser2.h++ ! # @touch $@ ! ! # parser2.o: parser2.c++ parser2.h++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ \ ! # complex.h++ cones.h++ conicsct.h++ crclslc.h++ \ ! # creatnew.h++ cuboid.h++ curves.h++ cylinder.h++ \ ! # dashptrn.h++ ddchdrn.h++ ellipses.h++ ellpsoid.h++ \ ! # ellpsslc.h++ glyphs.h++ gsltmplt.h++ helices.h++ \ ! # hyprbola.h++ io.h++ lines.h++ matrices.h++ nurbs.h++ \ ! # origami.h++ parabola.h++ parabold.h++ paraellp.h++ \ ! # parahypr.h++ paths.h++ pctfncs0.h++ pens.h++ pictures.h++ \ ! # planes.h++ plyhdslc.h++ pntrvcf0.h++ pntrvctr.h++ \ ! # points.h++ polygons.h++ polyhed.h++ predctes.h++ \ ! # primes.h++ pspglb.h++ rectangs.h++ rhtchdrn.h++ \ ! # scanprse.h++ shapes.h++ solfaced.h++ solids.h++ \ ! # spheres.h++ sphrdevl.h++ transfor.h++ triangle.h++ \ ! # utility.h++ ! # $(CXXCOMPILE) -c -o $@ $< ! # @touch $@ ! ! # scanner2.o: scanner2.c++ scanner2.h++ io.h++ loader.h++ parser2.h++ pspglb.h++ ! # $(CXXCOMPILE) -c -o $@ $< ! # @touch $@ ! ! # scanner2.c++ scanner2.h++ : scanner2.l++ ! # $(LEX) -o scanner2.cxx $< ! # ./check_scan_parse_output.sh scanner2.cxx scanner2.c++ ! # ./check_scan_parse_output.sh scanner2.hxx scanner2.h++ ! # @touch $@ ! ! # scanner2.l++ : scanner2.web prbsnflx$(EXEEXT) ! # ctangle scanner2.web ! # ./prbsnflx$(EXEEXT) scanner2.c scanner2.l ! # rm scanner2.c ! # ./check_scan_parse_output.sh scanner2.l scanner2.l++ ! # @touch $@ prbsnflx$(EXEEXT): prbsnflx.c++ *************** *** 382,386 **** #### *** (3) ! main.o: main.c++ $(3dldf_hpp_files) parser.h++ parser2.h++ parser_1.h++ arc.o: arc.c++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ conicsct.h++ crclslc.h++ \ --- 393,399 ---- #### *** (3) ! # parser2.h++ ! ! main.o: main.c++ $(3dldf_hpp_files) parser.h++ parser_1.h++ arc.o: arc.c++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ conicsct.h++ crclslc.h++ \ *************** *** 913,920 **** .PHONY : run ! run: ! $(MAKE) 3dldf$(EXEEXT) && 3dldf$(EXEEXT) sample2.ldf \ ! && mpost 3DLDFmp.mp && tex 3DLDFtex.tex \ ! && dvips -o 3DLDFtex.ps 3DLDFtex.dvi 3DLDFtex.pdf.gz : 3DLDFtex.pdf --- 926,934 ---- .PHONY : run ! run: 3dldf$(EXEEXT) ! touch sample2.ldf ! -rm 3DLDFtex.dvi 3DLDFtex.ps ! $(MAKE) 3DLDFtex.ps ! 3DLDFtex.pdf.gz : 3DLDFtex.pdf diff -rc2P 3DLDF-2.0.2/src/Makefile.in 3DLDF-2.0.3/src/Makefile.in *** 3DLDF-2.0.2/src/Makefile.in Sun Nov 10 18:30:13 2013 --- 3DLDF-2.0.3/src/Makefile.in Fri Dec 13 12:34:58 2013 *************** *** 191,201 **** am__v_lt_0 = --silent am__v_lt_1 = - lib3dldfsp_la_LIBADD = - lib3dldfsp_la_SOURCES = lib3dldfsp.c - lib3dldfsp_la_OBJECTS = lib3dldfsp.lo PROGRAMS = $(bin_PROGRAMS) am_3dldf_OBJECTS = 3dldf_OBJECTS = $(am_3dldf_OBJECTS) ! 3dldf_DEPENDENCIES = lib3dldflb.la lib3dldfsp.la am_dummy_OBJECTS = dummy.$(OBJEXT) dummy_OBJECTS = $(am_dummy_OBJECTS) --- 191,198 ---- am__v_lt_0 = --silent am__v_lt_1 = PROGRAMS = $(bin_PROGRAMS) am_3dldf_OBJECTS = 3dldf_OBJECTS = $(am_3dldf_OBJECTS) ! 3dldf_DEPENDENCIES = lib3dldflb.la am_dummy_OBJECTS = dummy.$(OBJEXT) dummy_OBJECTS = $(am_dummy_OBJECTS) *************** *** 264,271 **** am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap ! SOURCES = lib3dldflb.c lib3dldfsp.c $(3dldf_SOURCES) $(dummy_SOURCES) \ $(prbsnflx_SOURCES) - DIST_SOURCES = lib3dldflb.c lib3dldfsp.c $(3dldf_SOURCES) \ - $(dummy_SOURCES) $(prbsnflx_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ --- 261,268 ---- am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap ! SOURCES = lib3dldflb.c $(3dldf_SOURCES) $(dummy_SOURCES) \ ! $(prbsnflx_SOURCES) ! DIST_SOURCES = lib3dldflb.c $(3dldf_SOURCES) $(dummy_SOURCES) \ $(prbsnflx_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ *************** *** 424,428 **** top_srcdir = @top_srcdir@ bin_PROGRAMS = dummy$(EXEEXT) prbsnflx$(EXEEXT) 3dldf$(EXEEXT) ! lib_LTLIBRARIES = lib3dldflb.la lib3dldfsp.la # colall.web intro.web --- 421,427 ---- top_srcdir = @top_srcdir@ bin_PROGRAMS = dummy$(EXEEXT) prbsnflx$(EXEEXT) 3dldf$(EXEEXT) ! ! # lib3dldfsp.la ! lib_LTLIBRARIES = lib3dldflb.la # colall.web intro.web *************** *** 448,459 **** 3dldflb_lo_files = $(3dldflb_CWEB_files:.web=.lo) 3dldflb_obj_files = $(3dldflb_CWEB_files:.web=.o) ! 3dldfsp_CWEB_files = parser2.web scanner2.web ! 3dldfsp_c_files = $(3dldfsp_CWEB_files:.web=.c) ! 3dldfsp_cpp_files = $(3dldfsp_CWEB_files:.web=.c++) ! 3dldfsp_h_files = $(3dldfsp_CWEB_files:.web=.h) ! 3dldfsp_hpp_files = $(3dldfsp_CWEB_files:.web=.h++) parser_1.h++ ! 3dldfsp_obj_files = $(3dldfsp_CWEB_files:.web=.o) ! 3dldfsp_lo_files = $(3dldfsp_CWEB_files:.web=.lo) ! 3dldf_LDADD = lib3dldflb.la lib3dldfsp.la 3dldf_SOURCES = main.web pspglb.web 3dldf_cpp_files = $(3dldf_SOURCES:.web=.c++) --- 447,460 ---- 3dldflb_lo_files = $(3dldflb_CWEB_files:.web=.lo) 3dldflb_obj_files = $(3dldflb_CWEB_files:.web=.o) ! ! # 3dldfsp_CWEB_files = parser2.web scanner2.web ! ! # 3dldfsp_c_files = $(3dldfsp_CWEB_files:.web=.c) ! # 3dldfsp_cpp_files = $(3dldfsp_CWEB_files:.web=.c++) ! # 3dldfsp_h_files = $(3dldfsp_CWEB_files:.web=.h) ! # 3dldfsp_hpp_files = $(3dldfsp_CWEB_files:.web=.h++) parser_1.h++ ! # 3dldfsp_obj_files = $(3dldfsp_CWEB_files:.web=.o) ! # 3dldfsp_lo_files = $(3dldfsp_CWEB_files:.web=.lo) ! 3dldf_LDADD = lib3dldflb.la # lib3dldfsp.la 3dldf_SOURCES = main.web pspglb.web 3dldf_cpp_files = $(3dldf_SOURCES:.web=.c++) *************** *** 499,502 **** --- 500,505 ---- prbsnflx_SOURCES = prbsnflx.l++ dummy_SOURCES = dummy.cxx + + # $(3dldfsp_CWEB_files) EXTRA_DIST = check_scan_parse_output.sh \ cpyrtcpp.txt cpyrtasc.txt cpyrtcpp.txt cpyrtc.txt cpyrtel.txt \ *************** *** 505,511 **** sample.ldf sample0.ldf sample1.ldf sample2.ldf \ 3DLDFmp.mp 3DLDFtex.bas 3DLDFtex.tex \ ! $(3dldflb_CWEB_files) $(3dldfsp_CWEB_files) $(3dldf_SOURCES) \ ! $(3dldf_PARSER_FILES) CLEANFILES := $(3dldf_c_files) $(3dldf_cpp_files) $(3dldf_hpp_files) $(3dldf_h_files) \ $(3dldf_OBJECTS) $(3dldf_rpo_files) \ --- 508,516 ---- sample.ldf sample0.ldf sample1.ldf sample2.ldf \ 3DLDFmp.mp 3DLDFtex.bas 3DLDFtex.tex \ ! $(3dldflb_CWEB_files) $(3dldf_SOURCES) \ ! $(3dldf_PARSER_FILES) scanner2.web parser2.web ! + # scanner2.c++ scanner2.h++ scanner2.l++ parser2.y++ CLEANFILES := $(3dldf_c_files) $(3dldf_cpp_files) $(3dldf_hpp_files) $(3dldf_h_files) \ $(3dldf_OBJECTS) $(3dldf_rpo_files) \ *************** *** 514,519 **** loader.c loader.c++ loader.h loader.h++ \ parser.c parser.c++ parser_1.h++ parser.h++ parser.output parser.y++ \ ! prbsnflx.c++ examples.h layers.h layers.h++ parser.h++ parser2.y++ parser.y++ \ ! scanner2.c++ scanner2.h++ ldf_1.log scanner2.l++ all: all-am --- 519,524 ---- loader.c loader.c++ loader.h loader.h++ \ parser.c parser.c++ parser_1.h++ parser.h++ parser.output parser.y++ \ ! prbsnflx.c++ examples.h layers.h layers.h++ parser.h++ parser.y++ \ ! ldf_1.log all: all-am *************** *** 648,652 **** @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib3dldflb.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib3dldfsp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prbsnflx.Po@am__quote@ --- 653,656 ---- *************** *** 947,952 **** .PHONY : touch touch: ! touch 3dldf$(EXEEXT) $(3dldf_obj_files) $(3dldflb_obj_files) $(3dldfsp_obj_files) \ $(3dldf_LDADD) --- 951,958 ---- .PHONY : touch + # $(3dldfsp_obj_files) + touch: ! touch 3dldf$(EXEEXT) $(3dldf_obj_files) $(3dldflb_obj_files) \ $(3dldf_LDADD) *************** *** 954,969 **** touch $@ ! lib3dldfsp.c: ! touch $@ dist-hook: ! rm ./lib3dldflb.c ./lib3dldfsp.c #### *** (3) Link 3dldf 3dldf$(EXEEXT): $(3dldf_obj_files) $(3dldf_LDADD) @echo "Linking 3dldf" $(CXXLINK) $(3dldf_obj_files) -pthread $(3dldf_LDADD) $(LIBS) ! @touch $(3dldf_obj_files) $(3dldflb_obj_files) $(3dldfsp_obj_files) \ $(3dldf_LDADD) 3dldf$(EXEEXT) --- 960,977 ---- touch $@ ! # lib3dldfsp.c: ! # touch $@ dist-hook: ! rm ./lib3dldflb.c # ./lib3dldfsp.c #### *** (3) Link 3dldf + # $(3dldfsp_obj_files) + 3dldf$(EXEEXT): $(3dldf_obj_files) $(3dldf_LDADD) @echo "Linking 3dldf" $(CXXLINK) $(3dldf_obj_files) -pthread $(3dldf_LDADD) $(LIBS) ! @touch $(3dldf_obj_files) $(3dldflb_obj_files) \ $(3dldf_LDADD) 3dldf$(EXEEXT) *************** *** 971,976 **** $(CXXLINK) -rpath $(libdir) $(3dldflb_lo_files) $(LIBS) ! lib3dldfsp.la: $(3dldfsp_hpp_files) $(3dldf_hpp_files) $(3dldfsp_lo_files) ! $(CXXLINK) -rpath $(libdir) $(3dldfsp_lo_files) $(LIBS) #### The following implicit (pattern) rule generates C++ source code and header files --- 979,984 ---- $(CXXLINK) -rpath $(libdir) $(3dldflb_lo_files) $(LIBS) ! # lib3dldfsp.la: $(3dldfsp_hpp_files) $(3dldf_hpp_files) $(3dldfsp_lo_files) ! # $(CXXLINK) -rpath $(libdir) $(3dldfsp_lo_files) $(LIBS) #### The following implicit (pattern) rule generates C++ source code and header files *************** *** 1044,1048 **** #### *** (3) parser ! parser.y++: parser.w prbsnflx$(EXEEXT) $(3dldf_PARSER_FILES) ctangle $< ./prbsnflx$(EXEEXT) parser.c parser.y --- 1052,1056 ---- #### *** (3) parser ! parser.y++ parser_1.h++: parser.w prbsnflx$(EXEEXT) $(3dldf_PARSER_FILES) ctangle $< ./prbsnflx$(EXEEXT) parser.c parser.y *************** *** 1051,1055 **** touch $@ ! parser.c++ parser.h++ parser_1.h++: parser.y++ $(YACC) --debug -d -o parser.cxx $< ./check_scan_parse_output.sh parser.cxx parser.c++ --- 1059,1063 ---- touch $@ ! parser.c++ parser.h++: parser.y++ $(YACC) --debug -d -o parser.cxx $< ./check_scan_parse_output.sh parser.cxx parser.c++ *************** *** 1073,1126 **** @echo "Compiling 'parser.c++'. This may take awhile ... " $(CXXCOMPILE) -c -o $@ $< - touch $@ #### *** (3) parser2 ! parser2.y++ : parser2.web prbsnflx$(EXEEXT) $(3dldf_PARSER2_FILES) ! ctangle $< ! ./prbsnflx$(EXEEXT) parser2.c parser2.y ! rm parser2.c ! ./check_scan_parse_output.sh parser2.y parser2.y++ ! @touch $@ ! ! parser2.c++ parser2.h++ : parser2.y++ ! $(YACC) --debug -d -o parser2.cxx $< ! ./check_scan_parse_output.sh parser2.cxx parser2.c++ ! ./check_scan_parse_output.sh parser2.hxx parser2.h++ ! @touch $@ ! ! parser2.o: parser2.c++ parser2.h++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ \ ! complex.h++ cones.h++ conicsct.h++ crclslc.h++ \ ! creatnew.h++ cuboid.h++ curves.h++ cylinder.h++ \ ! dashptrn.h++ ddchdrn.h++ ellipses.h++ ellpsoid.h++ \ ! ellpsslc.h++ glyphs.h++ gsltmplt.h++ helices.h++ \ ! hyprbola.h++ io.h++ lines.h++ matrices.h++ nurbs.h++ \ ! origami.h++ parabola.h++ parabold.h++ paraellp.h++ \ ! parahypr.h++ paths.h++ pctfncs0.h++ pens.h++ pictures.h++ \ ! planes.h++ plyhdslc.h++ pntrvcf0.h++ pntrvctr.h++ \ ! points.h++ polygons.h++ polyhed.h++ predctes.h++ \ ! primes.h++ pspglb.h++ rectangs.h++ rhtchdrn.h++ \ ! scanprse.h++ shapes.h++ solfaced.h++ solids.h++ \ ! spheres.h++ sphrdevl.h++ transfor.h++ triangle.h++ \ ! utility.h++ ! $(CXXCOMPILE) -c -o $@ $< ! @touch $@ ! ! scanner2.o: scanner2.c++ scanner2.h++ io.h++ loader.h++ parser2.h++ pspglb.h++ ! $(CXXCOMPILE) -c -o $@ $< ! @touch $@ ! ! scanner2.c++ scanner2.h++ : scanner2.l++ ! $(LEX) -o scanner2.cxx $< ! ./check_scan_parse_output.sh scanner2.cxx scanner2.c++ ! ./check_scan_parse_output.sh scanner2.hxx scanner2.h++ ! @touch $@ ! ! scanner2.l++ : scanner2.web prbsnflx$(EXEEXT) ! ctangle scanner2.web ! ./prbsnflx$(EXEEXT) scanner2.c scanner2.l ! rm scanner2.c ! ./check_scan_parse_output.sh scanner2.l scanner2.l++ ! @touch $@ prbsnflx$(EXEEXT): prbsnflx.c++ --- 1081,1133 ---- @echo "Compiling 'parser.c++'. This may take awhile ... " $(CXXCOMPILE) -c -o $@ $< #### *** (3) parser2 ! # parser2.y++ : parser2.web prbsnflx$(EXEEXT) $(3dldf_PARSER2_FILES) ! # ctangle $< ! # ./prbsnflx$(EXEEXT) parser2.c parser2.y ! # rm parser2.c ! # ./check_scan_parse_output.sh parser2.y parser2.y++ ! # @touch $@ ! ! # parser2.c++ parser2.h++ : parser2.y++ ! # $(YACC) --debug -d -o parser2.cxx $< ! # ./check_scan_parse_output.sh parser2.cxx parser2.c++ ! # ./check_scan_parse_output.sh parser2.hxx parser2.h++ ! # @touch $@ ! ! # parser2.o: parser2.c++ parser2.h++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ \ ! # complex.h++ cones.h++ conicsct.h++ crclslc.h++ \ ! # creatnew.h++ cuboid.h++ curves.h++ cylinder.h++ \ ! # dashptrn.h++ ddchdrn.h++ ellipses.h++ ellpsoid.h++ \ ! # ellpsslc.h++ glyphs.h++ gsltmplt.h++ helices.h++ \ ! # hyprbola.h++ io.h++ lines.h++ matrices.h++ nurbs.h++ \ ! # origami.h++ parabola.h++ parabold.h++ paraellp.h++ \ ! # parahypr.h++ paths.h++ pctfncs0.h++ pens.h++ pictures.h++ \ ! # planes.h++ plyhdslc.h++ pntrvcf0.h++ pntrvctr.h++ \ ! # points.h++ polygons.h++ polyhed.h++ predctes.h++ \ ! # primes.h++ pspglb.h++ rectangs.h++ rhtchdrn.h++ \ ! # scanprse.h++ shapes.h++ solfaced.h++ solids.h++ \ ! # spheres.h++ sphrdevl.h++ transfor.h++ triangle.h++ \ ! # utility.h++ ! # $(CXXCOMPILE) -c -o $@ $< ! # @touch $@ ! ! # scanner2.o: scanner2.c++ scanner2.h++ io.h++ loader.h++ parser2.h++ pspglb.h++ ! # $(CXXCOMPILE) -c -o $@ $< ! # @touch $@ ! ! # scanner2.c++ scanner2.h++ : scanner2.l++ ! # $(LEX) -o scanner2.cxx $< ! # ./check_scan_parse_output.sh scanner2.cxx scanner2.c++ ! # ./check_scan_parse_output.sh scanner2.hxx scanner2.h++ ! # @touch $@ ! ! # scanner2.l++ : scanner2.web prbsnflx$(EXEEXT) ! # ctangle scanner2.web ! # ./prbsnflx$(EXEEXT) scanner2.c scanner2.l ! # rm scanner2.c ! # ./check_scan_parse_output.sh scanner2.l scanner2.l++ ! # @touch $@ prbsnflx$(EXEEXT): prbsnflx.c++ *************** *** 1136,1140 **** #### *** (3) ! main.o: main.c++ $(3dldf_hpp_files) parser.h++ parser2.h++ parser_1.h++ arc.o: arc.c++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ conicsct.h++ crclslc.h++ \ --- 1143,1149 ---- #### *** (3) ! # parser2.h++ ! ! main.o: main.c++ $(3dldf_hpp_files) parser.h++ parser_1.h++ arc.o: arc.c++ arc.h++ circles.h++ cncsctlt.h++ colors.h++ conicsct.h++ crclslc.h++ \ *************** *** 1661,1668 **** .PHONY : run ! run: ! $(MAKE) 3dldf$(EXEEXT) && 3dldf$(EXEEXT) sample2.ldf \ ! && mpost 3DLDFmp.mp && tex 3DLDFtex.tex \ ! && dvips -o 3DLDFtex.ps 3DLDFtex.dvi 3DLDFtex.pdf.gz : 3DLDFtex.pdf --- 1670,1677 ---- .PHONY : run ! run: 3dldf$(EXEEXT) ! touch sample2.ldf ! -rm 3DLDFtex.dvi 3DLDFtex.ps ! $(MAKE) 3DLDFtex.ps 3DLDFtex.pdf.gz : 3DLDFtex.pdf diff -rc2P 3DLDF-2.0.2/src/arc.web 3DLDF-2.0.3/src/arc.web *** 3DLDF-2.0.2/src/arc.web Sun Aug 11 16:36:09 2013 --- 3DLDF-2.0.3/src/arc.web Thu Dec 12 13:20:41 2013 *************** *** 692,696 **** { ! if (center != 0) center->shift_times(x, y, z); --- 692,696 ---- { ! if (center != static_cast(0)) center->shift_times(x, y, z); *************** *** 839,853 **** cerr << text << endl; ! if (center == 0) cerr << "No `center'." << endl; else center->show("center:", coords, do_persp, do_apply, f, proj, factor); ! if (focus_0 == 0) cerr << "No `focus_0'." << endl; else focus_0->show("focus_0:", coords, do_persp, do_apply, f, proj, factor); ! if (focus_1 == 0) cerr << "No `focus_1'." << endl; else --- 839,853 ---- cerr << text << endl; ! if (center == static_cast(0)) cerr << "No `center'." << endl; else center->show("center:", coords, do_persp, do_apply, f, proj, factor); ! if (focus_0 == static_cast(0)) cerr << "No `focus_0'." << endl; else focus_0->show("focus_0:", coords, do_persp, do_apply, f, proj, factor); ! if (focus_1 == static_cast(0)) cerr << "No `focus_1'." << endl; else diff -rc2P 3DLDF-2.0.2/src/arcexpr.w 3DLDF-2.0.3/src/arcexpr.w *** 3DLDF-2.0.2/src/arcexpr.w Wed Nov 6 21:01:19 2013 --- 3DLDF-2.0.3/src/arcexpr.w Thu Dec 12 13:16:02 2013 *************** *** 85,94 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { @=$$@> = static_cast(0); ! } /* |if (entry == 0 || entry->object == 0)| */ else /* |entry != 0 && entry->object != 0| */ --- 85,95 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { @=$$@> = static_cast(0); ! } /* |if ( entry == static_cast(0) ! || entry->object == static_cast(0))| */ else /* |entry != 0 && entry->object != 0| */ *************** *** 145,149 **** = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == 0|.@> @ Error handling: |pv == 0|. --- 146,150 ---- = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == static_cast*>(0)|.@> @ Error handling: |pv == 0|. *************** *** 152,163 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; ! } /* |if (pv == 0)| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> --- 153,164 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); ! } /* |if (pv == static_cast*>(0))| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> *************** *** 172,176 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 173,177 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/arcvexpr.w 3DLDF-2.0.3/src/arcvexpr.w *** 3DLDF-2.0.2/src/arcvexpr.w Wed Nov 6 21:01:18 2013 --- 3DLDF-2.0.3/src/arcvexpr.w Thu Dec 12 13:19:13 2013 *************** *** 107,116 **** @q **** (4) Error handling: |entry == 0 || entry->object == 0|.@> ! @ Error handling: |entry == 0 || entry->object == 0|. \initials{LDF 2007.10.13.} @= ! if (entry == 0 || entry->object == 0) { --- 107,117 ---- @q **** (4) Error handling: |entry == 0 || entry->object == 0|.@> ! @ Error handling: ! |entry == static_cast(0) || entry->object == static_cast(0)|. \initials{LDF 2007.10.13.} @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 129,144 **** cerr_strm.str(""); ! @=$$@> = 0; ! } /* |if (entry == 0 || entry->object == 0)| */ ! @q **** (4) |!(entry == 0 || entry->object == 0)|.@> ! @ |!(entry == 0 || entry->object == 0)|. \initials{LDF 2007.10.13.} @= ! else /* |!(entry == 0 || entry->object == 0)| */ ! { --- 130,146 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); ! } /* |if ( entry == static_cast(0) ! || entry->object == static_cast(0))| */ ! @q **** (4) |!( entry == static_cast(0) ! || entry->object == static_cast(0))|.@> ! @ |!(entry == static_cast(0) || entry->object == static_cast(0))|. \initials{LDF 2007.10.13.} @= ! else { *************** *** 151,159 **** @=$$@> = static_cast(pv); ! } /* |else| (|!(entry == 0 || entry->object == 0)|) */ }; - @q ** (2) arc_vector_primary --> LEFT_PARENTHESIS @> @q ** (2) arc_vector_expression RIGHT_PARENTHESIS.@> --- 153,160 ---- @=$$@> = static_cast(pv); ! } /* |else| */ }; @q ** (2) arc_vector_primary --> LEFT_PARENTHESIS @> @q ** (2) arc_vector_expression RIGHT_PARENTHESIS.@> diff -rc2P 3DLDF-2.0.2/src/check_scan_parse_output.sh 3DLDF-2.0.3/src/check_scan_parse_output.sh *** 3DLDF-2.0.2/src/check_scan_parse_output.sh Sun Aug 11 16:32:25 2013 --- 3DLDF-2.0.3/src/check_scan_parse_output.sh Thu Dec 12 15:41:20 2013 *************** *** 2,6 **** #### check_scan_parse_output.sh ! #### [...]/Finston/gwrdifpk/src/check_scan_parse_output.sh #### Created by Laurence D. Finston (LDF) Sun May 19 16:48:34 CEST 2013 --- 2,6 ---- #### check_scan_parse_output.sh ! #### 3DLDF-2.0.3/src/check_scan_parse_output.sh #### Created by Laurence D. Finston (LDF) Sun May 19 16:48:34 CEST 2013 diff -rc2P 3DLDF-2.0.2/src/circles.web 3DLDF-2.0.3/src/circles.web *** 3DLDF-2.0.2/src/circles.web Wed Nov 6 20:53:55 2013 --- 3DLDF-2.0.3/src/circles.web Thu Dec 12 13:26:50 2013 *************** *** 685,692 **** Circle* circle_reflection = static_cast(v); ! @q *** (3) If |circle_reflection == 0|, try to allocate memory @> ! @q *** (3) on the free store for it. @> ! @ If |circle_reflection == 0|, try to allocate memory on the free store for it. \initials{LDF 2004.10.12.} --- 685,692 ---- Circle* circle_reflection = static_cast(v); ! @q *** (3) If |circle_reflection == static_cast(0)|, try to allocate memory @> ! @q *** (3) on the free store for it. @> ! @ If |circle_reflection == static_cast(0)|, try to allocate memory on the free store for it. \initials{LDF 2004.10.12.} *************** *** 694,698 **** @= ! if (circle_reflection == 0) { try --- 694,698 ---- @= ! if (circle_reflection == static_cast(0)) { try *************** *** 729,733 **** @q *** (3).@> ! } /* |if (circle_reflection == 0)| */ @q *** (3) Call |Ellipse::reflect_in|.@> --- 729,733 ---- @q *** (3).@> ! } /* |if (circle_reflection == static_cast(0))| */ @q *** (3) Call |Ellipse::reflect_in|.@> *************** *** 933,937 **** @q ***** (5) Preliminaries.@> ! bool DEBUG = true; /* |false| */ using namespace Scan_Parse; --- 933,937 ---- @q ***** (5) Preliminaries.@> ! volatile bool DEBUG = false; /* |true| */ using namespace Scan_Parse; *************** *** 1174,1178 **** if (DEBUG) { ! cerr << "Exiting Circle::is_circular(). Returning true.\n" << flush; } #endif /* |DEBUG_COMPILE| */ --- 1174,1178 ---- if (DEBUG) { ! cerr << "Exiting Circle::is_circular(). Returning true." << endl; } #endif /* |DEBUG_COMPILE| */ *************** *** 1662,1666 **** @= ! if (dist == 0) { #if DEBUG_COMPILE --- 1662,1666 ---- @= ! if (dist == ZERO_REAL) { #if DEBUG_COMPILE *************** *** 1777,1781 **** @q ****** (6).@> ! } /* |if (dist == 0)| */ @q ***** (5) |dist > (radius + c.radius)|.@> --- 1777,1781 ---- @q ****** (6).@> ! } /* |if (dist == ZERO_REAL)| */ @q ***** (5) |dist > (radius + c.radius)|.@> *************** *** 2233,2237 **** cerr << "ERROR! In Reg_Polygon::in_circle():\n" << "Reg_Polygon is non-planar.\n" ! << "Returning empty Circle.\n\n" << flush; return c; } --- 2233,2237 ---- cerr << "ERROR! In Reg_Polygon::in_circle():\n" << "Reg_Polygon is non-planar.\n" ! << "Returning empty Circle." << endl << endl; return c; } *************** *** 2241,2245 **** cerr << "ERROR! In `Reg_Polygon::in_circle()':\n" << "`Reg_Polygon' has fewer than 3 Points.\n" ! << "Returning empty `Circle'.\n\n" << flush; return c; } --- 2241,2245 ---- cerr << "ERROR! In `Reg_Polygon::in_circle()':\n" << "`Reg_Polygon' has fewer than 3 Points.\n" ! << "Returning empty `Circle'." << endl << endl; return c; } *************** *** 2345,2349 **** cerr << "ERROR! In Reg_Polygon::out_circle():\n" << "Reg_Polygon is non-planar.\n" ! << "Returning empty Circle.\n\n" << flush; return c; } --- 2345,2349 ---- cerr << "ERROR! In Reg_Polygon::out_circle():\n" << "Reg_Polygon is non-planar.\n" ! << "Returning empty Circle." << endl << endl; return c; } *************** *** 2352,2356 **** cerr << "ERROR! In Reg_Polygon::out_circle():\n" << "Reg_Polygon has less than 3 Points.\n" ! << "Returning empty Circle.\n\n" << flush; return c; } --- 2352,2356 ---- cerr << "ERROR! In Reg_Polygon::out_circle():\n" << "Reg_Polygon has less than 3 Points.\n" ! << "Returning empty Circle." << endl << endl; return c; } diff -rc2P 3DLDF-2.0.2/src/cmpxassn.w 3DLDF-2.0.3/src/cmpxassn.w *** 3DLDF-2.0.2/src/cmpxassn.w Wed Nov 6 21:02:09 2013 --- 3DLDF-2.0.3/src/cmpxassn.w Thu Dec 12 14:18:11 2013 *************** *** 135,139 **** delete pv; ! @=$$@> = 0; } --- 135,139 ---- delete pv; ! @=$$@> = static_cast(0); } diff -rc2P 3DLDF-2.0.2/src/cmpxexpr.w 3DLDF-2.0.3/src/cmpxexpr.w *** 3DLDF-2.0.2/src/cmpxexpr.w Wed Nov 6 21:02:09 2013 --- 3DLDF-2.0.3/src/cmpxexpr.w Thu Dec 12 14:21:21 2013 *************** *** 86,97 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { @=$$@> = static_cast(0); ! } /* |if (entry == 0 || entry->object == 0)| */ ! else /* |entry != 0 && entry->object != 0| */ @=$$@> = static_cast(create_new( --- 86,99 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { @=$$@> = static_cast(0); ! } /* |if ( entry == static_cast(0) ! || entry->object == static_cast(0))| */ ! else /* | entry != static_cast(0) ! && entry->object != static_cast(0)| */ @=$$@> = static_cast(create_new( *************** *** 146,164 **** = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == 0|.@> ! @ Error handling: |pv == 0|. \initials{LDF 2007.12.02.} @= ! if (pv == 0) { delete c; ! @=$$@> = 0; ! } /* |if (pv == 0)| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> --- 148,166 ---- = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == static_cast*>(0)|.@> ! @ Error handling: |pv == |pv == static_cast*>(0)|. \initials{LDF 2007.12.02.} @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); ! } /* |if (pv == static_cast*>(0))| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> *************** *** 173,183 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ ! @q ******* (7) |pv != 0 && pv->ctr > 0|.@> ! @ |pv != 0 && pv->ctr > 0|. Set |@=$$@>| to |*(pv->v[pv->ctr - 1])|. \initials{LDF 2007.12.02.} --- 175,186 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ ! @q ******* (7) |pv != static_cast*>(0) && pv->ctr > 0|.@> ! @ |pv != static_cast*>(0) && pv->ctr > 0|. ! Set |@=$$@>| to |*(pv->v[pv->ctr - 1])|. \initials{LDF 2007.12.02.} diff -rc2P 3DLDF-2.0.2/src/cmpxvxpr.w 3DLDF-2.0.3/src/cmpxvxpr.w *** 3DLDF-2.0.2/src/cmpxvxpr.w Wed Nov 6 21:02:09 2013 --- 3DLDF-2.0.3/src/cmpxvxpr.w Thu Dec 12 13:32:21 2013 *************** *** 105,116 **** entry = static_cast(@=$1@>); ! @q **** (4) Error handling: |entry == 0 || entry->object == 0|.@> ! @ Error handling: |entry == 0 || entry->object == 0|. \initials{LDF 2007.12.02.} @= ! if (entry == 0 || entry->object == 0) { --- 105,118 ---- entry = static_cast(@=$1@>); ! @q **** (4) Error handling: ! |entry == static_cast(0) || entry->object == static_cast(0)|.@> ! @ Error handling: ! |entry == static_cast(0) || entry->object == static_cast(0)|. \initials{LDF 2007.12.02.} @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 120,127 **** << "Rule `complex_vector_primary --> " << "complex_vector_variable':" ! << endl << "`entry' == 0 or `entry->object' == 0." << endl << "Setting `complex_vector_primary' " ! << "to 0 and will try to continue."; log_message(cerr_strm); --- 122,130 ---- << "Rule `complex_vector_primary --> " << "complex_vector_variable':" ! << endl << "`entry' == static_cast(0) or " ! << "`entry->object' == static_cast(0)." << endl << "Setting `complex_vector_primary' " ! << "to static_cast(0) and will try to continue."; log_message(cerr_strm); *************** *** 129,144 **** cerr_strm.str(""); ! @=$$@> = 0; ! } /* |if (entry == 0 || entry->object == 0)| */ ! @q **** (4) |!(entry == 0 || entry->object == 0)|.@> ! @ |!(entry == 0 || entry->object == 0)|. \initials{LDF 2007.12.02.} @= ! else /* |!(entry == 0 || entry->object == 0)| */ ! { --- 132,148 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); ! } /* |if ( entry == static_cast(0) ! || entry->object == static_cast(0))| */ ! @q **** (4) |!( entry == static_cast(0) @> ! @q **** (4) || entry->object == static_cast(0))|. @> ! @ |!(entry == static_cast(0) || entry->object == static_cast(0))|. \initials{LDF 2007.12.02.} @= ! else { *************** *** 151,155 **** @=$$@> = static_cast(pv); ! } /* |else| (|!(entry == 0 || entry->object == 0)|) */ }; --- 155,159 ---- @=$$@> = static_cast(pv); ! } /* |else| */ }; diff -rc2P 3DLDF-2.0.2/src/cncsctlt.web 3DLDF-2.0.3/src/cncsctlt.web *** 3DLDF-2.0.2/src/cncsctlt.web Wed Nov 6 20:53:54 2013 --- 3DLDF-2.0.3/src/cncsctlt.web Fri Dec 13 16:18:27 2013 *************** *** 1385,1389 **** @= ! if (pv == 0) { cerr_strm << thread_name << "ERROR! " --- 1385,1389 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 1401,1405 **** return 0; ! } /* |if (pv == 0)| */ @q ******* (7) Error handling: |*pv| contains too few |Points|.@> --- 1401,1405 ---- return 0; ! } /* |if (pv == static_cast*>(0))| */ @q ******* (7) Error handling: |*pv| contains too few |Points|.@> *************** *** 1429,1433 **** return 0; ! } /* |if (pv == 0)| */ --- 1429,1433 ---- return 0; ! } /* |if (pv->ctr < 3)| */ *************** *** 1747,1753 **** Path q; ! if ( lattice[0] == 0 || *lattice[0] == INVALID_POINT ! || lattice[1] == 0 || *lattice[1] == INVALID_POINT ! || lattice[2] == 0 || *lattice[2] == INVALID_POINT) return INVALID_PLANE; --- 1747,1756 ---- Path q; ! if ( lattice[0] == static_cast(0) ! || *lattice[0] == INVALID_POINT ! || lattice[1] == static_cast(0) ! || *lattice[1] == INVALID_POINT ! || lattice[2] == static_cast(0) ! || *lattice[2] == INVALID_POINT) return INVALID_PLANE; *************** *** 2031,2035 **** do_shift); ! if (p != 0) { Pointer_Vector* pv = new Pointer_Vector; --- 2034,2038 ---- do_shift); ! if (p != static_cast(0)) { Pointer_Vector* pv = new Pointer_Vector; *************** *** 2076,2080 **** Point p; ! Point* q = 0; bool b = true; --- 2079,2083 ---- Point p; ! Point* q = static_cast(0); bool b = true; *************** *** 2259,2263 **** */ ! if (q == 0 && quit_on_error) { cerr_strm << thread_name << "ERROR! " --- 2262,2266 ---- */ ! if (q == static_cast(0) && quit_on_error) { cerr_strm << thread_name << "ERROR! " *************** *** 2276,2280 **** } /* |if| */ ! else if (q == 0) { cerr_strm << thread_name << "WARNING! " --- 2279,2283 ---- } /* |if| */ ! else if (q == static_cast(0)) { cerr_strm << thread_name << "WARNING! " *************** *** 2291,2300 **** } /* |else if| */ ! else /* |q != 0| */ { *pv += q; } ! q = 0; start_temp += increment; start += increment; --- 2294,2303 ---- } /* |else if| */ ! else /* |q != static_cast(0)| */ { *pv += q; } ! q = static_cast(0); start_temp += increment; start += increment; *************** *** 2420,2426 **** @q ****** (6) Preliminaries.@> ! #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; ! #endif /* |DEBUG_COMPILE| */@; stringstream cerr_strm; --- 2423,2427 ---- @q ****** (6) Preliminaries.@> ! volatile bool DEBUG = false; /* |true| */ @; stringstream cerr_strm; diff -rc2P 3DLDF-2.0.2/src/colors.web 3DLDF-2.0.3/src/colors.web *** 3DLDF-2.0.2/src/colors.web Wed Nov 6 20:53:54 2013 --- 3DLDF-2.0.3/src/colors.web Sun Nov 10 19:07:50 2013 *************** *** 605,611 **** @= ! red_part = min(1.0, red_part + c.red_part); ! green_part = min(1.0, green_part + c.green_part); ! blue_part = min(1.0, blue_part + c.blue_part); @q **** (4).@> --- 605,611 ---- @= ! red_part = min(static_cast(1.0), red_part + c.red_part); ! green_part = min(static_cast(1.0), green_part + c.green_part); ! blue_part = min(static_cast(1.0), blue_part + c.blue_part); @q **** (4).@> *************** *** 613,619 **** if (type == RGB_COLOR && c.type == RGB_COLOR) { ! red_part = min(1.0, red_part + c.red_part); ! green_part = min(1.0, green_part + c.green_part); ! blue_part = min(1.0, blue_part + c.blue_part); } #endif --- 613,619 ---- if (type == RGB_COLOR && c.type == RGB_COLOR) { ! red_part = min(static_cast(1.0), red_part + c.red_part); ! green_part = min(static_cast(1.0), green_part + c.green_part); ! blue_part = min(static_cast(1.0), blue_part + c.blue_part); } #endif diff -rc2P 3DLDF-2.0.2/src/complex.web 3DLDF-2.0.3/src/complex.web *** 3DLDF-2.0.2/src/complex.web Wed Nov 6 21:02:08 2013 --- 3DLDF-2.0.3/src/complex.web Thu Dec 12 13:56:39 2013 *************** *** 92,96 **** { ! friend int yyparse(void*); --- 92,96 ---- { ! friend int yyparse(yyscan_t); *************** *** 394,398 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 394,398 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 501,507 **** @q ****** (6) Preliminaries.@> ! #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; ! #endif /* |DEBUG_COMPILE| */@; stringstream cerr_strm; --- 501,505 ---- @q ****** (6) Preliminaries.@> ! volatile bool DEBUG = false; /* |true| */ @; stringstream cerr_strm; *************** *** 517,521 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 515,519 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 626,630 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 624,628 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 724,728 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 722,726 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 822,826 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 820,824 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 919,923 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 917,921 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 1017,1021 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 1015,1019 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; diff -rc2P 3DLDF-2.0.2/src/cones.web 3DLDF-2.0.3/src/cones.web *** 3DLDF-2.0.2/src/cones.web Wed Nov 6 20:53:54 2013 --- 3DLDF-2.0.3/src/cones.web Thu Dec 12 13:59:54 2013 *************** *** 314,324 **** #endif /* |DEBUG_COMPILE| */@; ! @q **** (4) WARNING: |options == 0|.@> ! @ WARNING: |options == 0|. \initials{LDF 2006.11.08.} @= ! if (options == 0) { cerr_strm << "WARNING! In `Cone::set()':" --- 314,324 ---- #endif /* |DEBUG_COMPILE| */@; ! @q **** (4) WARNING: |options == static_cast(0)|.@> ! @ WARNING: |options == static_cast(0)|. \initials{LDF 2006.11.08.} @= ! if (options == static_cast(0)) { cerr_strm << "WARNING! In `Cone::set()':" *************** *** 333,337 **** return 1; ! } /* |if (options == 0)| */ --- 333,337 ---- return 1; ! } /* |if (options == static_cast(0))| */ *************** *** 342,350 **** @= ! if (options->center != 0) { center = *options->center; ! } /* |if (options->center == 0)| */ --- 342,350 ---- @= ! if (options->center != static_cast(0)) { center = *options->center; ! } /* |if (options->center == static_cast(0))| */ *************** *** 355,363 **** @= ! if (options->direction != 0) { direction = *options->direction; ! } /* |if (options->direction == 0)| */ --- 355,363 ---- @= ! if (options->direction != static_cast(0)) { direction = *options->direction; ! } /* |if (options->direction == static_cast(0))| */ *************** *** 559,563 **** center.set(0, axis_y, 0); ! if (options->center != 0) shift(*options->center - center); --- 559,563 ---- center.set(0, axis_y, 0); ! if (options->center != static_cast(0)) shift(*options->center - center); *************** *** 722,726 **** center.set(0, axis_y, 0); ! if (options->center != 0) shift(*options->center - center); --- 722,726 ---- center.set(0, axis_y, 0); ! if (options->center != static_cast(0)) shift(*options->center - center); *************** *** 1027,1035 **** @q **** (4)@> ! Point* p = 0; @q **** (4)@> ! if (type == CIRCULAR_CONE_TYPE && base != 0) { p = create_new(0); --- 1027,1035 ---- @q **** (4)@> ! Point* p = static_cast(0); @q **** (4)@> ! if (type == CIRCULAR_CONE_TYPE && base != static_cast(0)) { p = create_new(0); *************** *** 1043,1047 **** @q **** (4)@> ! else if (type == ELLIPTICAL_CONE_TYPE && base != 0) { p = create_new(0); --- 1043,1047 ---- @q **** (4)@> ! else if (type == ELLIPTICAL_CONE_TYPE && base != static_cast(0)) { p = create_new(0); *************** *** 1083,1087 **** Point* p; ! if (type == CIRCULAR_CONE_TYPE && cap != 0) { p = create_new(0); --- 1083,1087 ---- Point* p; ! if (type == CIRCULAR_CONE_TYPE && cap != static_cast(0)) { p = create_new(0); *************** *** 1094,1098 **** @q **** (4)@> ! else if (type == ELLIPTICAL_CONE_TYPE && cap != 0) { p = create_new(0); --- 1094,1098 ---- @q **** (4)@> ! else if (type == ELLIPTICAL_CONE_TYPE && cap != static_cast(0)) { p = create_new(0); *************** *** 1389,1393 **** { ! if (center != 0) center->shift_times(x, y, z); --- 1389,1393 ---- { ! if (center != static_cast(0)) center->shift_times(x, y, z); diff -rc2P 3DLDF-2.0.2/src/conicsct.web 3DLDF-2.0.3/src/conicsct.web *** 3DLDF-2.0.2/src/conicsct.web Wed Nov 6 20:53:54 2013 --- 3DLDF-2.0.3/src/conicsct.web Thu Dec 12 14:03:34 2013 *************** *** 621,625 **** X = bp.pt; ! if (isect_pv != 0) *isect_pv += create_new(X); --- 621,625 ---- X = bp.pt; ! if (isect_pv != static_cast*>(0)) *isect_pv += create_new(X); *************** *** 672,676 **** Y = bp.pt; ! if (isect_pv != 0) *isect_pv += create_new(Y); --- 672,676 ---- Y = bp.pt; ! if (isect_pv != static_cast*>(0)) *isect_pv += create_new(Y); *************** *** 723,727 **** Z = bp.pt; ! if (isect_pv != 0) *isect_pv += create_new(Z); --- 723,727 ---- Z = bp.pt; ! if (isect_pv != static_cast*>(0)) *isect_pv += create_new(Z); *************** *** 848,852 **** @= ! if (pv == 0) { cerr_strm << thread_name << "ERROR! " --- 848,852 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 860,864 **** ! } /* |if (pv == 0)| */ @q ***** (5)@> --- 860,864 ---- ! } /* |if (pv == static_cast*>(0))| */ @q ***** (5)@> *************** *** 1006,1010 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 1006,1010 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 1053,1063 **** \ENDLOG ! @q ***** (5) Error handling: |pv == 0|.@> ! @ Error handling: |pv == 0|. \initials{LDF 2007.07.15.} @= ! if (pv == 0) { cerr_strm << thread_name << "ERROR! In `Conic_Section::generate':" --- 1053,1063 ---- \ENDLOG ! @q ***** (5) Error handling: |pv == static_cast*>(0)|.@> ! @ Error handling: |pv == static_cast*>(0)|. \initials{LDF 2007.07.15.} @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name << "ERROR! In `Conic_Section::generate':" *************** *** 1072,1076 **** return 0; ! } /* |if (pv == 0)| */ @q ***** (5) Error handling: |*pv| doesn't contain enough |Points|.@> --- 1072,1076 ---- return 0; ! } /* |if (pv == static_cast*>(0))| */ @q ***** (5) Error handling: |*pv| doesn't contain enough |Points|.@> *************** *** 1268,1272 **** bool XYZ_set = false; ! if (isect_pv != 0 && isect_pv->v.size() >= 3) { X = *isect_pv->v[0]; --- 1268,1272 ---- bool XYZ_set = false; ! if (isect_pv != static_cast*>(0) && isect_pv->v.size() >= 3) { X = *isect_pv->v[0]; *************** *** 1712,1716 **** @q ***** (5) Preliminaries.@> ! bool DEBUG = true; /* |false| */ using namespace Scan_Parse; --- 1712,1716 ---- @q ***** (5) Preliminaries.@> ! bool DEBUG = false; /* |true| */ using namespace Scan_Parse; *************** *** 1902,1906 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 1902,1906 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; diff -rc2P 3DLDF-2.0.2/src/creatnew.web 3DLDF-2.0.3/src/creatnew.web *** 3DLDF-2.0.2/src/creatnew.web Wed Nov 6 20:56:26 2013 --- 3DLDF-2.0.3/src/creatnew.web Thu Dec 12 14:06:42 2013 *************** *** 193,197 **** #endif /* |DEBUG_COMPILE| */ ! if (arg != 0) *obj = *arg; --- 193,197 ---- #endif /* |DEBUG_COMPILE| */ ! if (arg != static_cast(0)) *obj = *arg; diff -rc2P 3DLDF-2.0.2/src/cslcmnd.w 3DLDF-2.0.3/src/cslcmnd.w *** 3DLDF-2.0.2/src/cslcmnd.w Wed Nov 6 21:02:07 2013 --- 3DLDF-2.0.3/src/cslcmnd.w Thu Dec 12 14:21:21 2013 *************** *** 85,89 **** } ! @=$$@> = 0; }; --- 85,89 ---- } ! @=$$@> = static_cast(0); }; *************** *** 133,137 **** } ! @=$$@> = 0; --- 133,137 ---- } ! @=$$@> = static_cast(0); *************** *** 169,173 **** delete t; ! @=$$@> = 0; }; --- 169,173 ---- delete t; ! @=$$@> = static_cast(0); }; *************** *** 199,203 **** } ! @=$$@> = 0; }; --- 199,203 ---- } ! @=$$@> = static_cast(0); }; *************** *** 229,233 **** } ! @=$$@> = 0; }; --- 229,233 ---- } ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/cslexpr.w 3DLDF-2.0.3/src/cslexpr.w *** 3DLDF-2.0.2/src/cslexpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/cslexpr.w Thu Dec 12 14:29:25 2013 *************** *** 91,102 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { @=$$@> = static_cast(0); ! } /* |if (entry == 0 || entry->object == 0)| */ ! else /* |entry != 0 && entry->object != 0| */ @=$$@> = static_cast(create_new( --- 91,104 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { @=$$@> = static_cast(0); ! } /* |if ( entry == static_cast(0) ! || entry->object == static_cast(0))| */ ! else /* | entry != static_cast(0) ! && entry->object != static_cast(0)| */ @=$$@> = static_cast(create_new( *************** *** 187,195 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->conic_section_lattice_options == 0) ! scanner_node->conic_section_lattice_options ! = new Conic_Section_Lattice_Options; ! @=$$@> = 0; }; --- 189,199 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node->conic_section_lattice_options ! == static_cast(0)) ! { ! scanner_node->conic_section_lattice_options = new Conic_Section_Lattice_Options; ! } ! @=$$@> = static_cast(0); }; *************** *** 214,218 **** { ! @=$$@> = 0; }; --- 218,222 ---- { ! @=$$@> = static_cast(0); }; *************** *** 251,255 **** = true; ! @=$$@> = 0; }; --- 255,259 ---- = true; ! @=$$@> = static_cast(0); }; *************** *** 274,278 **** = false; ! @=$$@> = 0; }; --- 278,282 ---- = false; ! @=$$@> = static_cast(0); }; *************** *** 297,301 **** = true; ! @=$$@> = 0; }; --- 301,305 ---- = true; ! @=$$@> = static_cast(0); }; *************** *** 320,324 **** = false; ! @=$$@> = 0; }; --- 324,328 ---- = false; ! @=$$@> = static_cast(0); }; *************** *** 344,348 **** = @=$2@>; ! @=$$@> = 0; }; --- 348,352 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 373,377 **** = true; ! @=$$@> = 0; }; --- 377,381 ---- = true; ! @=$$@> = static_cast(0); }; *************** *** 396,400 **** = false; ! @=$$@> = 0; }; --- 400,404 ---- = false; ! @=$$@> = static_cast(0); }; *************** *** 422,426 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 426,430 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 452,456 **** = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == 0|.@> @ Error handling: |pv == 0|. --- 456,460 ---- = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == static_cast*>(0)|.@> @ Error handling: |pv == 0|. *************** *** 459,470 **** @= ! if (pv == 0) { delete r; ! @=$$@> = 0; ! } /* |if (pv == 0)| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> --- 463,474 ---- @= ! if (pv == static_cast*>(0)) { delete r; ! @=$$@> = static_cast(0); ! } /* |if (pv == static_cast*>(0))| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> *************** *** 480,490 **** delete r; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ ! @q ******* (7) |pv != 0 && pv->ctr > 0|.@> ! @ |pv != 0 && pv->ctr > 0|. Set |@=$$@>| to |*(pv->v[pv->ctr - 1])|. \initials{LDF 2007.07.29.} --- 484,495 ---- delete r; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ ! @q ******* (7) |pv != static_cast*>(0) && pv->ctr > 0|.@> ! @ |pv != static_cast*>(0) && pv->ctr > 0|. ! Set |@=$$@>| to |*(pv->v[pv->ctr - 1])|. \initials{LDF 2007.07.29.} *************** *** 500,505 **** }; - - @q * (1) conic_section_lattice secondary.@> @* \§conic section lattice secondary>. --- 505,508 ---- *************** *** 561,565 **** { delete t; ! @=$$@> = 0; } }; --- 564,568 ---- { delete t; ! @=$$@> = static_cast(0); } }; diff -rc2P 3DLDF-2.0.2/src/cslvexpr.w 3DLDF-2.0.3/src/cslvexpr.w *** 3DLDF-2.0.2/src/cslvexpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/cslvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/cuboid.web 3DLDF-2.0.3/src/cuboid.web *** 3DLDF-2.0.2/src/cuboid.web Wed Nov 6 20:56:26 2013 --- 3DLDF-2.0.3/src/cuboid.web Thu Dec 12 14:11:47 2013 *************** *** 700,704 **** if (bpp.first.pt != INVALID_POINT) { ! if (bpv == 0) { bpv = new Pointer_Vector; --- 700,704 ---- if (bpp.first.pt != INVALID_POINT) { ! if (bpv == static_cast*>(0)) { bpv = new Pointer_Vector; *************** *** 721,725 **** if (bpp.second.pt != INVALID_POINT) { ! if (bpv == 0) { bpv = new Pointer_Vector; --- 721,725 ---- if (bpp.second.pt != INVALID_POINT) { ! if (bpv == static_cast*>(0)) { bpv = new Pointer_Vector; *************** *** 837,841 **** continue; ! else /* |bpv != 0 && bpv->ctr > 0| */ { --- 837,842 ---- continue; ! else /* | bpv != static_cast*>(0) ! && bpv->ctr > 0| */ { *************** *** 858,862 **** } /* End of first inner |for| */ ! } /* |else| (|bpv != 0|) */ delete bpv; --- 859,863 ---- } /* End of first inner |for| */ ! } /* |else| (|bpv != static_cast*>(0)|) */ delete bpv; *************** *** 976,983 **** Cuboid* cuboid_reflection = static_cast(v); ! @q *** (3) If |cuboid_reflection == 0|, try to allocate memory @> ! @q *** (3) on the free store for it. @> ! @ If |cuboid_reflection == 0|, try to allocate memory on the free store for it. \initials{LDF 2004.10.12.} --- 977,984 ---- Cuboid* cuboid_reflection = static_cast(v); ! @q *** (3) If |cuboid_reflection == static_cast(0)|, try to allocate memory @> ! @q *** (3) on the free store for it. @> ! @ If |cuboid_reflection == static_cast(0)|, try to allocate memory on the free store for it. \initials{LDF 2004.10.12.} *************** *** 985,989 **** @= ! if (cuboid_reflection == 0) { try --- 986,990 ---- @= ! if (cuboid_reflection == static_cast(0)) { try *************** *** 1020,1024 **** @q *** (3).@> ! } /* |if (cuboid_reflection == 0)| */ @q *** (3) Call |Solid_Faced::reflect_in()|.@> --- 1021,1025 ---- @q *** (3).@> ! } /* |if (cuboid_reflection == static_cast(0))| */ @q *** (3) Call |Solid_Faced::reflect_in()|.@> diff -rc2P 3DLDF-2.0.2/src/curves.web 3DLDF-2.0.3/src/curves.web *** 3DLDF-2.0.2/src/curves.web Wed Nov 6 20:56:26 2013 --- 3DLDF-2.0.3/src/curves.web Thu Dec 12 19:44:18 2013 *************** *** 205,218 **** Reg_Cl_Plane_Curve* reg_cl_plane_curve_reflection = static_cast(v); ! @q *** (3) If |reg_cl_plane_curve_reflection == 0|, try to allocate memory @> ! @q *** (3) on the free store for it. @> ! @ If |reg_cl_plane_curve_reflection == 0|, try to allocate memory ! on the free store for it. \initials{LDF 2004.10.12.} @= ! if (reg_cl_plane_curve_reflection == 0) { try --- 205,218 ---- Reg_Cl_Plane_Curve* reg_cl_plane_curve_reflection = static_cast(v); ! @q *** (3) If |reg_cl_plane_curve_reflection == static_cast(0)|, @> ! @q *** (3) try to allocate memory on the free store for it. @> ! @ If |reg_cl_plane_curve_reflection == static_cast(0)|, ! try to allocate memory on the free store for it. \initials{LDF 2004.10.12.} @= ! if (reg_cl_plane_curve_reflection == static_cast(0)) { try *************** *** 249,253 **** @q *** (3).@> ! } /* |if (reg_cl_plane_curve_reflection == 0)| */ @q *** (3) Call |Path::reflect_in()|.@> --- 249,253 ---- @q *** (3).@> ! } /* |if (reg_cl_plane_curve_reflection == static_cast(0))| */ @q *** (3) Call |Path::reflect_in()|.@> *************** *** 613,617 **** cerr << "ERROR! In Reg_Cl_Plane_Curve::location():" << "The Reg_Cl_Plane_Curve is non-planar.\n" ! << "Returning -6\n\n" << flush; return -6; } --- 613,617 ---- cerr << "ERROR! In Reg_Cl_Plane_Curve::location():" << "The Reg_Cl_Plane_Curve is non-planar.\n" ! << "Returning -6\n\n"; return -6; } *************** *** 627,631 **** cerr << "WARNING! In Reg_Cl_Plane_Curve::location().\n" << "Point is not in plane of regular closed plane curve.\n" ! << "Returning -2.\n\n" << flush; return -2; } --- 627,631 ---- cerr << "WARNING! In Reg_Cl_Plane_Curve::location().\n" << "Point is not in plane of regular closed plane curve.\n" ! << "Returning -2.\n\n"; return -2; } *************** *** 642,650 **** copy_normal.show("copy_normal"); ! if (copy_normal.magnitude() == 0) { cerr << "ERROR! In Reg_Cl_Plane_Curve::location().\n" ! << "Normal has no magnitude. Returning -4\n\n" ! << flush; return -4; } --- 642,650 ---- copy_normal.show("copy_normal"); ! if (copy_normal.magnitude() == ZERO_REAL) { cerr << "ERROR! In Reg_Cl_Plane_Curve::location().\n" ! << "Normal has no magnitude. Returning -4\n\n"; ! return -4; } *************** *** 693,697 **** if (DEBUG) { ! cerr << "orientation == " << orientation << endl << flush; #if 0 --- 693,697 ---- if (DEBUG) { ! cerr << "orientation == " << orientation << endl; #if 0 *************** *** 760,765 **** cerr << "ERROR! In Reg_Cl_Plane_Curve::location().\n" << "orientation has invalid value: " << orientation ! << "\nReturning -5\n\n" ! << flush; return -5; } --- 760,764 ---- cerr << "ERROR! In Reg_Cl_Plane_Curve::location().\n" << "orientation has invalid value: " << orientation ! << "\nReturning -5\n\n"; return -5; } *************** *** 816,820 **** { cerr << "ERROR! In Reg_Cl_Plane_Curve::location().\n" ! << "This can't happen! Returning -3.\n" << flush; if (DEBUG) --- 815,819 ---- { cerr << "ERROR! In Reg_Cl_Plane_Curve::location().\n" ! << "This can't happen! Returning -3.\n"; if (DEBUG) *************** *** 841,845 **** cerr << "ERROR! In Reg_Cl_Plane_Curve::angle_point().\n" << "This virtual function doesn't have a real definition for " ! << "ordinary Reg_Cl_Plane_Curves.\nReturning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 840,844 ---- cerr << "ERROR! In Reg_Cl_Plane_Curve::angle_point().\n" << "This virtual function doesn't have a real definition for " ! << "ordinary Reg_Cl_Plane_Curves.\nReturning INVALID_POINT.\n\n"; return INVALID_POINT; } *************** *** 973,977 **** if(DEBUG) cerr << " *** Entering Reg_Cl_Plane_Curve::" ! << "intersection_points()\n" << flush; Bool_Point_Pair bpp = INVALID_BOOL_POINT_PAIR; --- 972,976 ---- if(DEBUG) cerr << " *** Entering Reg_Cl_Plane_Curve::" ! << "intersection_points()\n"; Bool_Point_Pair bpp = INVALID_BOOL_POINT_PAIR; *************** *** 1017,1023 **** pt_vector.show("pt_vector:"); pl.normal.show("pl.normal"); ! cerr << "Returning INVALID_BOOL_POINT_PAIR.\n\n" << flush; if (DEBUG) ! cerr << "Exiting Polygon::intersection_points().\n\n" << flush; return INVALID_BOOL_POINT_PAIR; } --- 1016,1022 ---- pt_vector.show("pt_vector:"); pl.normal.show("pl.normal"); ! cerr << "Returning INVALID_BOOL_POINT_PAIR.\n\n"; if (DEBUG) ! cerr << "Exiting Polygon::intersection_points().\n\n"; return INVALID_BOOL_POINT_PAIR; } *************** *** 1042,1046 **** \ENDLOG @= ! if (distance == 0) { if (DEBUG) --- 1041,1046 ---- \ENDLOG @= ! ! if (distance == ZERO_REAL) { if (DEBUG) *************** *** 1094,1101 **** if (DEBUG) { ! cerr << "ang == " << ang << endl << flush; } ! if (ang != 0) { if (curve_0.get_z() > 0) --- 1094,1101 ---- if (DEBUG) { ! cerr << "ang == " << ang << endl; } ! if (ang != ZERO_REAL) { if (curve_0.get_z() > 0) *************** *** 1114,1118 **** ang = curve_0.angle(x_axis_pt); ! if (ang != 0) { if (curve_0.get_y() > 0) --- 1114,1118 ---- ang = curve_0.angle(x_axis_pt); ! if (ang != ZERO_REAL) { if (curve_0.get_y() > 0) *************** *** 1136,1144 **** { curve_4.show("curve_4"); ! cerr << "ang == " << ang << endl << flush; } ! if (ang != 0) { if (curve_4.get_y() > 0) --- 1136,1144 ---- { curve_4.show("curve_4"); ! cerr << "ang == " << ang << endl; } ! if (ang != ZERO_REAL) { if (curve_4.get_y() > 0) *************** *** 1190,1194 **** if (DEBUG) ! cerr << "Slope == " << Slope << endl << flush; Real_Pair rr; --- 1190,1194 ---- if (DEBUG) ! cerr << "Slope == " << Slope << endl; Real_Pair rr; *************** *** 1200,1208 **** ! if (Slope == 0) /* v is known, h is unknown. */ { if (DEBUG) { ! cerr << "Slope == 0" << endl << flush; } --- 1200,1208 ---- ! if (Slope == ZERO_REAL) /* v is known, h is unknown. */ { if (DEBUG) { ! cerr << "Slope == ZERO_REAL" << endl; } *************** *** 1228,1232 **** } ! } /* End |Slope == 0|. */ @q ****** (6) Slope is undefined (line is vertical).@> --- 1228,1232 ---- } ! } /* End |Slope == ZERO_REAL|. */ @q ****** (6) Slope is undefined (line is vertical).@> *************** *** 1268,1272 **** v_intercept = pt0_v - (Slope * pt0_h); if (DEBUG) ! cerr << "v_intercept == " << v_intercept << endl << flush; Real_Triple coeffs = get_coefficients(Slope, v_intercept); --- 1268,1272 ---- v_intercept = pt0_v - (Slope * pt0_h); if (DEBUG) ! cerr << "v_intercept == " << v_intercept << endl; Real_Triple coeffs = get_coefficients(Slope, v_intercept); *************** *** 1277,1281 **** if (DEBUG) { ! cerr << "Solving quadratic.\n" << flush; } --- 1277,1281 ---- if (DEBUG) { ! cerr << "Solving quadratic.\n"; } *************** *** 1286,1291 **** { cerr << "Not a quadratic. " ! << "Haven't programmed this case yet.\n" ! << flush; } --- 1286,1290 ---- { cerr << "Not a quadratic. " ! << "Haven't programmed this case yet.\n"; } *************** *** 1331,1337 **** { cerr << "on_segment.first == " ! << on_segment.first << endl << flush; cerr << "on_segment.second == " ! << on_segment.second << endl << flush; } --- 1330,1336 ---- { cerr << "on_segment.first == " ! << on_segment.first << endl; cerr << "on_segment.second == " ! << on_segment.second << endl; } *************** *** 1349,1353 **** { if (DEBUG) ! cerr << "Transforming bpp.first.pt\n" << flush; bpp.first.pt *= t_inverse; } --- 1348,1352 ---- { if (DEBUG) ! cerr << "Transforming bpp.first.pt\n"; bpp.first.pt *= t_inverse; } *************** *** 1355,1359 **** { if (DEBUG) ! cerr << "bpp.first.pt is invalid\n" << flush; } --- 1354,1358 ---- { if (DEBUG) ! cerr << "bpp.first.pt is invalid\n"; } *************** *** 1375,1381 **** { cerr << "on_segment.first == " ! << on_segment.first << endl << flush; cerr << "on_segment.second == " ! << on_segment.second << endl << flush; } --- 1374,1380 ---- { cerr << "on_segment.first == " ! << on_segment.first << endl; cerr << "on_segment.second == " ! << on_segment.second << endl; } *************** *** 1383,1387 **** { if (DEBUG) ! cerr << "Transforming bpp.second.pt\n" << flush; bpp.second.pt *= t_inverse; } --- 1382,1386 ---- { if (DEBUG) ! cerr << "Transforming bpp.second.pt\n"; bpp.second.pt *= t_inverse; } *************** *** 1390,1404 **** bpp.second.pt = INVALID_POINT; if (DEBUG) ! cerr << "bpp.second.pt is invalid\n" << flush; } if(DEBUG) { ! cerr << "rr.first == " << rr.first << endl << flush; ! cerr << "rr.second == " << rr.second << endl << flush; cerr << "bpp.first.b == " ! << bpp.first.b << endl << flush; cerr << "bpp.second.b == " ! << bpp.second.b << endl << flush; bpp.first.pt.show("bpp.first.pt"); bpp.second.pt.show("bpp.second.pt"); --- 1389,1403 ---- bpp.second.pt = INVALID_POINT; if (DEBUG) ! cerr << "bpp.second.pt is invalid\n"; } if(DEBUG) { ! cerr << "rr.first == " << rr.first << endl; ! cerr << "rr.second == " << rr.second << endl; cerr << "bpp.first.b == " ! << bpp.first.b << endl; cerr << "bpp.second.b == " ! << bpp.second.b << endl; bpp.first.pt.show("bpp.first.pt"); bpp.second.pt.show("bpp.second.pt"); *************** *** 1415,1419 **** << "Line and Reg_Cl_Plane_Curve are in parallel planes.\n" << "No intersections. Returning INVALID_BOOL_POINT_PAIR." ! << endl << endl << flush; return INVALID_BOOL_POINT_PAIR; } --- 1414,1418 ---- << "Line and Reg_Cl_Plane_Curve are in parallel planes.\n" << "No intersections. Returning INVALID_BOOL_POINT_PAIR." ! << endl << endl; return INVALID_BOOL_POINT_PAIR; } *************** *** 1430,1434 **** if (DEBUG) cerr << "The line is perpendicular to the " ! << "Reg_Cl_Plane_Curve.\n" << flush; } --- 1429,1433 ---- if (DEBUG) cerr << "The line is perpendicular to the " ! << "Reg_Cl_Plane_Curve.\n"; } *************** *** 1437,1441 **** if (DEBUG) cerr << "The line and the Reg_Cl_Plane_Curve " ! << "are non-coplanar.\n" << flush; } --- 1436,1440 ---- if (DEBUG) cerr << "The line and the Reg_Cl_Plane_Curve " ! << "are non-coplanar.\n"; } *************** *** 1450,1454 **** if (DEBUG) ! cerr << "location: s == " << s << endl << flush; if (s > -1) --- 1449,1453 ---- if (DEBUG) ! cerr << "location: s == " << s << endl; if (s > -1) *************** *** 1458,1462 **** if (DEBUG) ! cerr << "On segment: == " << bpp.first.b << endl << flush; return bpp; --- 1457,1461 ---- if (DEBUG) ! cerr << "On segment: == " << bpp.first.b << endl; return bpp; *************** *** 1495,1499 **** cerr << "ERROR! In Reg_Cl_Plane_Curve::intersection_points():\n" << "Path argument p is non-linear. " ! << "Returning INVALID_BOOL_POINT_PAIR.\n\n" << flush; return INVALID_BOOL_POINT_PAIR; } --- 1494,1498 ---- cerr << "ERROR! In Reg_Cl_Plane_Curve::intersection_points():\n" << "Path argument p is non-linear. " ! << "Returning INVALID_BOOL_POINT_PAIR.\n\n"; return INVALID_BOOL_POINT_PAIR; } *************** *** 1837,1841 **** angle = fmod(angle, 360); ! if (angle != 0) { Point normal = ptr->get_normal(); --- 1836,1840 ---- angle = fmod(angle, 360); ! if (angle != ZERO_REAL) { Point normal = ptr->get_normal(); *************** *** 1957,1966 **** @= ! if (angle != 0) { Point normal = get_normal(); p.rotate(center, normal, angle); ! } /* |if (angle != 0)| */ return p; --- 1956,1965 ---- @= ! if (angle != ZERO_REAL) { Point normal = get_normal(); p.rotate(center, normal, angle); ! } /* |if (angle != ZERO_REAL)| */ return p; *************** *** 2081,2090 **** @= ! if (angle != 0) { Point normal = get_normal(); p.rotate(center, normal, angle); ! } /* |if (angle != 0)| */ return p; --- 2080,2089 ---- @= ! if (angle != ZERO_REAL) { Point normal = get_normal(); p.rotate(center, normal, angle); ! } /* |if (angle != ZERO_REAL)| */ return p; diff -rc2P 3DLDF-2.0.2/src/cylinder.web 3DLDF-2.0.3/src/cylinder.web *** 3DLDF-2.0.2/src/cylinder.web Wed Nov 6 20:56:26 2013 --- 3DLDF-2.0.3/src/cylinder.web Thu Dec 12 20:18:05 2013 *************** *** 280,290 **** #endif /* |DEBUG_COMPILE| */@; ! @q **** (4) WARNING: |options == 0|.@> ! @ WARNING: |options == 0|. \initials{LDF 2006.11.06.} @= ! if (options == 0) { cerr_strm << "WARNING! In `Cylinder::set()':" --- 280,290 ---- #endif /* |DEBUG_COMPILE| */@; ! @q **** (4) WARNING: |options == static_cast(0)|.@> ! @ WARNING: |options == static_cast(0)|. \initials{LDF 2006.11.06.} @= ! if (options == static_cast(0)) { cerr_strm << "WARNING! In `Cylinder::set()':" *************** *** 299,303 **** return 1; ! } /* |if (options == 0)| */ --- 299,303 ---- return 1; ! } /* |if (options == static_cast(0))| */ *************** *** 308,316 **** @= ! if (options->center != 0) { center = *options->center; ! } /* |if (options->center == 0)| */ --- 308,316 ---- @= ! if (options->center != static_cast(0)) { center = *options->center; ! } /* |if (options->center == static_cast(0))| */ *************** *** 321,329 **** @= ! if (options->direction != 0) { direction = *options->direction; ! } /* |if (options->direction == 0)| */ --- 321,329 ---- @= ! if (options->direction != static_cast(0)) { direction = *options->direction; ! } /* |if (options->direction == static_cast(0))| */ *************** *** 413,417 **** ellipses.push_back(e); ! if (options->axis_y != 0) axis_y = *options->axis_y; else --- 413,417 ---- ellipses.push_back(e); ! if (options->axis_y != static_cast(0)) axis_y = *options->axis_y; else *************** *** 452,456 **** center.set(0, .5 * axis_y, 0); ! if (options->center != 0) shift(*options->center - center); --- 452,456 ---- center.set(0, .5 * axis_y, 0); ! if (options->center != static_cast(0)) shift(*options->center - center); *************** *** 470,474 **** ! if (options->radius != 0) radius = *options->radius; else if ( (options->axis_x && !options->axis_z) --- 470,474 ---- ! if (options->radius != static_cast(0)) radius = *options->radius; else if ( (options->axis_x && !options->axis_z) *************** *** 548,552 **** center.set(0, .5 * axis_y, 0); ! if (options->center != 0) shift(*options->center - center); --- 548,552 ---- center.set(0, .5 * axis_y, 0); ! if (options->center != static_cast(0)) shift(*options->center - center); *************** *** 850,854 **** @q **** (4)@> ! if (type == CIRCULAR_CYLINDER_TYPE && base != 0) { p = create_new(0); --- 850,854 ---- @q **** (4)@> ! if (type == CIRCULAR_CYLINDER_TYPE && base != static_cast(0)) { p = create_new(0); *************** *** 862,866 **** @q **** (4)@> ! else if (type == ELLIPTICAL_CYLINDER_TYPE && base != 0) { p = create_new(0); --- 862,866 ---- @q **** (4)@> ! else if (type == ELLIPTICAL_CYLINDER_TYPE && base != static_cast(0)) { p = create_new(0); *************** *** 905,909 **** Point* p; ! if (type == CIRCULAR_CYLINDER_TYPE && cap != 0) { p = create_new(0); --- 905,909 ---- Point* p; ! if (type == CIRCULAR_CYLINDER_TYPE && cap != static_cast(0)) { p = create_new(0); *************** *** 916,920 **** @q **** (4)@> ! else if (type == ELLIPTICAL_CYLINDER_TYPE && cap != 0) { p = create_new(0); --- 916,920 ---- @q **** (4)@> ! else if (type == ELLIPTICAL_CYLINDER_TYPE && cap != static_cast(0)) { p = create_new(0); diff -rc2P 3DLDF-2.0.2/src/dashptrn.web 3DLDF-2.0.3/src/dashptrn.web *** 3DLDF-2.0.2/src/dashptrn.web Wed Nov 6 20:56:26 2013 --- 3DLDF-2.0.3/src/dashptrn.web Wed Dec 11 18:38:32 2013 *************** *** 234,238 **** cerr << "ERROR! In Dash_Pattern::show():" << endl << "Invalid type: " << type << endl ! << "Will return `false'." << endl << flush; return_value = false; --- 234,238 ---- cerr << "ERROR! In Dash_Pattern::show():" << endl << "Invalid type: " << type << endl ! << "Will return `false'." << endl; return_value = false; diff -rc2P 3DLDF-2.0.2/src/ddchdrn.web 3DLDF-2.0.3/src/ddchdrn.web *** 3DLDF-2.0.2/src/ddchdrn.web Thu Nov 7 13:36:08 2013 --- 3DLDF-2.0.3/src/ddchdrn.web Thu Dec 12 19:36:23 2013 *************** *** 258,262 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Dodecahedron::Dodecahedron().\n" << flush; --- 258,262 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Dodecahedron::Dodecahedron().\n"; *************** *** 377,381 **** Transform t = center.shift(-center); ! if (angle_x != 0 || angle_y != 0 || angle_z != 0) t.rotate(angle_x, angle_y, angle_z); --- 377,381 ---- Transform t = center.shift(-center); ! if (angle_x != ZERO_REAL || angle_y != ZERO_REAL || angle_z != ZERO_REAL) t.rotate(angle_x, angle_y, angle_z); *************** *** 388,392 **** if (DEBUG) ! cerr << "Exiting Dodecahedron::Dodecahedron().\n" << flush; return; } --- 388,392 ---- if (DEBUG) ! cerr << "Exiting Dodecahedron::Dodecahedron().\n"; return; } *************** *** 579,587 **** { for (int j = 0; j < 5; j++) ! if (pents[i]->get_point(j).get_y() != 0) { cerr << "ERROR! In Dodecahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n" << flush; } } --- 579,587 ---- { for (int j = 0; j < 5; j++) ! if (pents[i]->get_point(j).get_y() != ZERO_REAL) { cerr << "ERROR! In Dodecahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n"; } } *************** *** 608,616 **** { for (int j = 0; j < 5; j++) ! if (pents[i]->get_point(j).get_y() != 0) { cerr << "ERROR! In Dodecahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n" << flush; } } --- 608,616 ---- { for (int j = 0; j < 5; j++) ! if (pents[i]->get_point(j).get_y() != ZERO_REAL) { cerr << "ERROR! In Dodecahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n"; } } *************** *** 769,775 **** @q ****** (6) Preliminaries.@> ! #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; ! #endif /* |DEBUG_COMPILE| */@; stringstream cerr_strm; --- 769,773 ---- @q ****** (6) Preliminaries.@> ! volatile bool DEBUG = false; /* |true| */ @; stringstream cerr_strm; *************** *** 786,789 **** --- 784,799 ---- &warning_stop_value); + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << "Entering `Dodecahedron::get_tabs'." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + using namespace Scan_Parse; *************** *** 849,852 **** --- 859,869 ---- @ First tab on |rpv[1]|. + \LOG + \initials{LDF 2013.11.10.} + @:BUG FIX@> BUG FIX: Now casting final argument of |Path::set| to |Point *|. + For some reason, this worked when |real| was a ``|typedef|'' for |double|, + but caused a run-time error when it was changed to |float|. + \ENDLOG + @= *************** *** 874,878 **** tab.set("--", true, &corner[0], &mid_pt[0], &corner[1], &mid_pt[1], ! &corner[2], &mid_pt[2], &corner[3], &mid_pt[3], 0); tab_vector.push_back(tab); --- 891,895 ---- tab.set("--", true, &corner[0], &mid_pt[0], &corner[1], &mid_pt[1], ! &corner[2], &mid_pt[2], &corner[3], &mid_pt[3], static_cast(0)); tab_vector.push_back(tab); *************** *** 1669,1682 **** Dodecahedron* dodecahedron_reflection = static_cast(v); ! @q *** (3) If |dodecahedron_reflection == 0|, try to allocate memory @> ! @q *** (3) on the free store for it. @> ! @ If |dodecahedron_reflection == 0|, try to allocate memory ! on the free store for it. \initials{LDF 2004.10.12.} @= ! if (dodecahedron_reflection == 0) { try --- 1686,1699 ---- Dodecahedron* dodecahedron_reflection = static_cast(v); ! @q *** (3) If |dodecahedron_reflection == static_cast(0)|, @> ! @q *** (3) try to allocate memory on the free store for it. @> ! @ If |dodecahedron_reflection == static_cast(0)|, ! try to allocate memory on the free store for it. \initials{LDF 2004.10.12.} @= ! if (dodecahedron_reflection == static_cast(0)) { try *************** *** 1713,1717 **** @q *** (3).@> ! } /* |if (dodecahedron_reflection == 0)| */ @q *** (3) Call |Polyhedron::reflect_in()|.@> --- 1730,1734 ---- @q *** (3).@> ! } /* |if (dodecahedron_reflection == static_cast(0))| */ @q *** (3) Call |Polyhedron::reflect_in()|.@> diff -rc2P 3DLDF-2.0.2/src/ellipses.web 3DLDF-2.0.3/src/ellipses.web *** 3DLDF-2.0.2/src/ellipses.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/ellipses.web Thu Dec 12 19:40:42 2013 *************** *** 310,314 **** << nnumber_of_points << "." << endl << "Using default instead: " << DEFAULT_NUMBER_OF_POINTS ! << endl << flush; number_of_points = DEFAULT_NUMBER_OF_POINTS; } --- 310,314 ---- << nnumber_of_points << "." << endl << "Using default instead: " << DEFAULT_NUMBER_OF_POINTS ! << endl; number_of_points = DEFAULT_NUMBER_OF_POINTS; } *************** *** 323,327 **** Transform t; ! if (angle_x != 0 || angle_y != 0 || angle_z != 0) t.rotate(angle_x, angle_y, angle_z); --- 323,327 ---- Transform t; ! if (angle_x != ZERO_REAL || angle_y != ZERO_REAL || angle_z != ZERO_REAL) t.rotate(angle_x, angle_y, angle_z); *************** *** 484,493 **** ! if (temp_pt.get_x() < 0 || temp_pt.get_z() != 0) temp_center *= normal *= temp_pt *= t.rotate(0, 2 * angle); @q **** (4)@> ! if (temp_pt.get_x() < 0 || temp_pt.get_z() != 0) { cerr_strm << thread_name << "ERROR! In `Ellipse' constructor:" --- 484,493 ---- ! if (temp_pt.get_x() < ZERO_REAL || temp_pt.get_z() != ZERO_REAL) temp_center *= normal *= temp_pt *= t.rotate(0, 2 * angle); @q **** (4)@> ! if (temp_pt.get_x() < ZERO_REAL || temp_pt.get_z() != ZERO_REAL) { cerr_strm << thread_name << "ERROR! In `Ellipse' constructor:" *************** *** 504,508 **** focus_0 = focus_1 = INVALID_POINT; ! } /* |if (temp_pt.get_x() < 0 || temp_pt.get_z() != 0)| */ else --- 504,508 ---- focus_0 = focus_1 = INVALID_POINT; ! } /* |if (temp_pt.get_x() < ZERO_REAL || temp_pt.get_z() != ZERO_REAL)| */ else *************** *** 661,664 **** --- 661,665 ---- Ellipse* p = create_new(0); *p = *this; + return static_cast(p); } *************** *** 736,749 **** Ellipse* ellipse_reflection = static_cast(v); ! @q *** (3) If |ellipse_reflection == 0|, try to allocate memory @> ! @q *** (3) on the free store for it. @> ! @ If |ellipse_reflection == 0|, try to allocate memory ! on the free store for it. \initials{LDF 2004.10.12.} @= ! if (ellipse_reflection == 0) { try --- 737,750 ---- Ellipse* ellipse_reflection = static_cast(v); ! @q *** (3) If |ellipse_reflection == static_cast(0)|, @> ! @q *** (3) try to allocate memory on the free store for it. @> ! @ If |ellipse_reflection == static_cast(0)|, ! try to allocate memory on the free store for it. \initials{LDF 2004.10.12.} @= ! if (ellipse_reflection == static_cast(0)) { try *************** *** 780,784 **** @q *** (3).@> ! } /* |if (ellipse_reflection == 0)| */ @q *** (3) Call |Reg_Cl_Plane_Curve::reflect_in()|.@> --- 781,785 ---- @q *** (3).@> ! } /* |if (ellipse_reflection == static_cast(0))| */ @q *** (3) Call |Reg_Cl_Plane_Curve::reflect_in()|.@> *************** *** 970,974 **** @q *** (3).@> ! if (v == 0) { cerr_strm << thread_name << "ERROR! In `Ellipse::reflect_off()':" --- 971,975 ---- @q *** (3).@> ! if (v == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Ellipse::reflect_off()':" *************** *** 982,986 **** return 1; ! } /* |if (v == 0)| */ --- 983,987 ---- return 1; ! } /* |if (v == static_cast(0))| */ *************** *** 1313,1317 **** @q ***** (5) Preliminaries.@> ! bool DEBUG = true; /* |false| */ using namespace Scan_Parse; --- 1314,1318 ---- @q ***** (5) Preliminaries.@> ! bool DEBUG = false; /* |true| */ using namespace Scan_Parse; *************** *** 1499,1503 **** << "get_normal() returned INVALID_POINT." << endl << "*this is non-planar. Returning false." ! << endl << endl << flush; return false; } --- 1500,1504 ---- << "get_normal() returned INVALID_POINT." << endl << "*this is non-planar. Returning false." ! << endl << endl; return false; } *************** *** 1536,1540 **** if (DEBUG) cerr << "ERROR! In is_elliptical():\n" ! << "Rotation failed.\nReturning false\n\n" << flush; return false; } --- 1537,1541 ---- if (DEBUG) cerr << "ERROR! In is_elliptical():\n" ! << "Rotation failed.\nReturning false\n\n"; return false; } *************** *** 1551,1556 **** if (DEBUG) { ! cerr << "a == " << a << endl << flush; ! cerr << "b == " << b << endl << flush; } --- 1552,1557 ---- if (DEBUG) { ! cerr << "a == " << a << endl; ! cerr << "b == " << b << endl; } *************** *** 1566,1573 **** if (DEBUG) { ! cerr << "Point " << i << ": " << endl << flush; (**iter).show("iter:"); ! cerr << "x == " << x << endl << flush; ! cerr << "z == " << z << endl << flush; } --- 1567,1574 ---- if (DEBUG) { ! cerr << "Point " << i << ": " << endl; (**iter).show("iter:"); ! cerr << "x == " << x << endl; ! cerr << "z == " << z << endl; } *************** *** 1575,1579 **** if (DEBUG) ! cerr << "r == " << r << endl << flush; if (fabs(r - 1) > Point::epsilon()) --- 1576,1580 ---- if (DEBUG) ! cerr << "r == " << r << endl; if (fabs(r - 1) > Point::epsilon()) *************** *** 1581,1585 **** if (DEBUG) cerr << "Point " << i << " doesn't satisfy ellipse equation.\n" ! << "Returning false.\n\n" << flush; return false; } --- 1582,1586 ---- if (DEBUG) cerr << "Point " << i << " doesn't satisfy ellipse equation.\n" ! << "Returning false.\n\n"; return false; } *************** *** 1589,1593 **** if (DEBUG) cerr << "Exiting Ellipse::is_elliptical(). Returning true." ! << endl << endl << flush; return true; --- 1590,1594 ---- if (DEBUG) cerr << "Exiting Ellipse::is_elliptical(). Returning true." ! << endl << endl; return true; *************** *** 1614,1618 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; if (DEBUG) { --- 1615,1619 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; if (DEBUG) { *************** *** 1728,1733 **** cerr << "ERROR! In Ellipse::solve().\n" << "Invalid character for axis_unknown: " ! << axis_unknown << "\nReturning INVALID_REAL_PAIR.\n\n" ! << flush; return INVALID_REAL_PAIR; } --- 1729,1733 ---- cerr << "ERROR! In Ellipse::solve().\n" << "Invalid character for axis_unknown: " ! << axis_unknown << "\nReturning INVALID_REAL_PAIR.\n\n"; return INVALID_REAL_PAIR; } *************** *** 2388,2393 **** cerr << "ERROR! In `Ellipse::location':" << endl ! << "Ellipse is non-elliptical. Returning -3.\n\n" ! << flush; return -3; } --- 2388,2393 ---- cerr << "ERROR! In `Ellipse::location':" << endl ! << "Ellipse is non-elliptical. Returning -3.\n\n"; ! return -3; } *************** *** 2397,2401 **** cerr << "WARNING! In Ellipse::location():\n" << "Point doesn't lie in plane of Ellipse.\n" ! << "Returning -2.\n\n" << flush; return -2; } --- 2397,2402 ---- cerr << "WARNING! In Ellipse::location():\n" << "Point doesn't lie in plane of Ellipse.\n" ! << "Returning -2.\n\n"; ! return -2; } *************** *** 2783,2787 **** if (DEBUG) { ! cerr << "Ellipses are coplanar.\n" << flush; } --- 2784,2788 ---- if (DEBUG) { ! cerr << "Ellipses are coplanar.\n"; } *************** *** 2863,2867 **** { if (DEBUG) ! cerr << "Centers and axis orientation are the same.\n" << flush; /* \initials{LDF 2002.04.14.} --- 2864,2868 ---- { if (DEBUG) ! cerr << "Centers and axis orientation are the same.\n"; /* \initials{LDF 2002.04.14.} *************** *** 2923,2927 **** { if (DEBUG) ! cerr << "i == " << i << endl << flush; if (i != 0) --- 2924,2928 ---- { if (DEBUG) ! cerr << "i == " << i << endl; if (i != 0) *************** *** 2955,2960 **** cerr << "In Ellipse::intersection_points(Ellipse).\n" << "This can't happen (this)!\n" ! << "Will try to continue.\n\n" ! << flush; pt2 = INVALID_POINT; } --- 2956,2961 ---- cerr << "In Ellipse::intersection_points(Ellipse).\n" << "This can't happen (this)!\n" ! << "Will try to continue.\n\n"; ! pt2 = INVALID_POINT; } *************** *** 2979,2984 **** { cerr << "In Ellipse::intersection_points(Ellipse).\n" ! << "This can't happen (e)!\nWill try to continue.\n\n" ! << flush; pt3 = INVALID_POINT; } --- 2980,2985 ---- { cerr << "In Ellipse::intersection_points(Ellipse).\n" ! << "This can't happen (e)!\nWill try to continue.\n\n"; ! pt3 = INVALID_POINT; } *************** *** 3011,3015 **** if (DEBUG) { ! cerr << "congruent_flag == " << congruent_flag << endl << flush; } --- 3012,3016 ---- if (DEBUG) { ! cerr << "congruent_flag == " << congruent_flag << endl; } *************** *** 3024,3029 **** else if (DEBUG) { ! cerr << "All five points are not on both ellipses.\n" ! << flush; } --- 3025,3030 ---- else if (DEBUG) { ! cerr << "All five points are not on both ellipses.\n"; ! } *************** *** 3053,3057 **** if (DEBUG) { ! cerr << "Shifting copy to origin_pt.\n" << flush; } --- 3054,3058 ---- if (DEBUG) { ! cerr << "Shifting copy to origin_pt.\n"; } *************** *** 3064,3068 **** else if (DEBUG) { ! cerr << "copy is already at origin_pt.\n" << flush; } --- 3065,3069 ---- else if (DEBUG) { ! cerr << "copy is already at origin_pt.\n"; } *************** *** 3096,3130 **** const unsigned short OTHER = 3; #endif ! if (normal_x == 0 && normal_y == 0 && normal_z == 0) { cerr << "ERROR! In Ellipse::intersection_points():\n" << "Normal == 0. " ! << "Returning INVALID_BOOL_POINT_QUADRUPLE\n\n" ! << flush; return INVALID_BOOL_POINT_QUADRUPLE; } ! else if (normal_x == 0 && normal_y == 0) /* Ellipse lies in a plane parallel to x-y plane. */ { if (DEBUG) ! cerr << "Ellipse lies in a plane parallel to x-y plane\n" ! << flush; orientation = X_Y; } ! else if (normal_x == 0 && normal_z == 0) /* Ellipse lies in a plane parallel to x-z plane. */ { if (DEBUG) ! cerr << "Ellipse lies in a plane parallel to x-z plane\n" << flush; orientation = X_Z; } ! else if (normal_z == 0 && normal_y == 0) /* Ellipse lies in a plane parallel to z-y plane. */ { if (DEBUG) ! cerr << "Ellipse lies in a plane parallel to z-y plane\n" << flush; orientation = Z_Y; } --- 3097,3131 ---- const unsigned short OTHER = 3; #endif ! if (normal_x == ZERO_REAL && normal_y == ZERO_REAL && normal_z == ZERO_REAL) { cerr << "ERROR! In Ellipse::intersection_points():\n" << "Normal == 0. " ! << "Returning INVALID_BOOL_POINT_QUADRUPLE\n\n"; ! return INVALID_BOOL_POINT_QUADRUPLE; } ! else if (normal_x == ZERO_REAL && normal_y == ZERO_REAL) /* Ellipse lies in a plane parallel to x-y plane. */ { if (DEBUG) ! cerr << "Ellipse lies in a plane parallel to x-y plane\n"; ! orientation = X_Y; } ! else if (normal_x == ZERO_REAL && normal_z == ZERO_REAL) /* Ellipse lies in a plane parallel to x-z plane. */ { if (DEBUG) ! cerr << "Ellipse lies in a plane parallel to x-z plane\n"; orientation = X_Z; } ! else if (normal_z == ZERO_REAL && normal_y == ZERO_REAL) /* Ellipse lies in a plane parallel to z-y plane. */ { if (DEBUG) ! cerr << "Ellipse lies in a plane parallel to z-y plane\n"; orientation = Z_Y; } *************** *** 3133,3139 **** { if (DEBUG) ! cerr << "Ellipse doesn't lie in a plane parallel to a major plane.\n" ! << flush; ! /* Put it in x-z plane. */ --- 3134,3139 ---- { if (DEBUG) ! cerr << "Ellipse doesn't lie in a plane parallel to a major plane.\n"; ! /* Put it in x-z plane. */ *************** *** 3231,3238 **** if (DEBUG) { ! cerr << "a == " << a << endl << flush; ! cerr << "b == " << b << endl << flush; ! cerr << "c == " << c << endl << flush; ! cerr << "d == " << d << endl << flush; } --- 3231,3238 ---- if (DEBUG) { ! cerr << "a == " << a << endl; ! cerr << "b == " << b << endl; ! cerr << "c == " << c << endl; ! cerr << "d == " << d << endl; } *************** *** 3244,3251 **** if (DEBUG) { ! cerr << "aa == " << aa << endl << flush; ! cerr << "bb == " << bb << endl << flush; ! cerr << "cc == " << cc << endl << flush; ! cerr << "dd == " << dd << endl << flush; } --- 3244,3251 ---- if (DEBUG) { ! cerr << "aa == " << aa << endl; ! cerr << "bb == " << bb << endl; ! cerr << "cc == " << cc << endl; ! cerr << "dd == " << dd << endl; } *************** *** 3262,3270 **** if (DEBUG) { ! cerr << "numerator == " << numerator << endl << flush; ! cerr << "denominator == " << denominator << endl << flush; } ! if (denominator == 0) { if (DEBUG) --- 3262,3270 ---- if (DEBUG) { ! cerr << "numerator == " << numerator << endl; ! cerr << "denominator == " << denominator << endl; } ! if (denominator == ZERO_REAL) { if (DEBUG) *************** *** 3289,3293 **** if (DEBUG) { ! cerr << "x == " << x << endl << flush; cerr << "y coordinate:\n"; } --- 3289,3293 ---- if (DEBUG) { ! cerr << "x == " << x << endl; cerr << "y coordinate:\n"; } *************** *** 3298,3306 **** if (DEBUG) { ! cerr << "numerator == " << numerator << endl << flush; ! cerr << "denominator == " << denominator << endl << flush; } ! if (denominator == 0) { if (DEBUG) --- 3298,3306 ---- if (DEBUG) { ! cerr << "numerator == " << numerator << endl; ! cerr << "denominator == " << denominator << endl; } ! if (denominator == ZERO_REAL) { if (DEBUG) *************** *** 3325,3329 **** if (DEBUG) { ! cerr << "y == " << y << endl << flush; } --- 3325,3329 ---- if (DEBUG) { ! cerr << "y == " << y << endl; } *************** *** 3349,3355 **** { pt20.set( x, y, 0); ! pt21.set(-x, -y, 0) ; ! if (y != 0 && x != 0) { pt22.set( x, -y, 0); --- 3349,3355 ---- { pt20.set( x, y, 0); ! pt21.set(-x, -y, 0); ! if (y != ZERO_REAL && x != ZERO_REAL) { pt22.set( x, -y, 0); *************** *** 3367,3371 **** pt21.set(-x, 0, -y); ! if (y != 0 && x != 0) { pt22.set( x, 0, -y); --- 3367,3371 ---- pt21.set(-x, 0, -y); ! if (y != ZERO_REAL && x != ZERO_REAL) { pt22.set( x, 0, -y); *************** *** 3383,3387 **** pt21.set(0, -y, -x); ! if (x != 0 && y != 0) { pt22.set(0, y, -x); --- 3383,3387 ---- pt21.set(0, -y, -x); ! if (x != ZERO_REAL && y != ZERO_REAL) { pt22.set(0, y, -x); *************** *** 3399,3404 **** << "This can't happen! orientation has invalid value: " << orientation << endl ! << "Will to try to continue.\n\n" ! << flush; } --- 3399,3404 ---- << "This can't happen! orientation has invalid value: " << orientation << endl ! << "Will to try to continue.\n\n"; ! } *************** *** 3426,3435 **** if (DEBUG) ! cerr << "ss_copy == " << ss_copy << endl << flush; ss_e = e.location(pt20); if (DEBUG) ! cerr << "ss_e == " << ss_e << endl << flush; } --- 3426,3435 ---- if (DEBUG) ! cerr << "ss_copy == " << ss_copy << endl; ss_e = e.location(pt20); if (DEBUG) ! cerr << "ss_e == " << ss_e << endl; } *************** *** 3521,3530 **** cerr << "In Ellipse::intersection_points():\n" << "Searching for Ellipse intersections. " ! << "This can take some time...\n\n" << flush; for (real i = 0; i < 360; i += .5) { if (DEBUG) ! cerr << "i == " << i << endl << flush; curr_point = copy.angle_point(i); --- 3521,3530 ---- cerr << "In Ellipse::intersection_points():\n" << "Searching for Ellipse intersections. " ! << "This can take some time...\n\n"; for (real i = 0; i < 360; i += .5) { if (DEBUG) ! cerr << "i == " << i << endl; curr_point = copy.angle_point(i); *************** *** 3535,3539 **** if (DEBUG) ! cerr << "curr_location == " << curr_location << endl << flush; if (curr_location == 0) --- 3535,3539 ---- if (DEBUG) ! cerr << "curr_location == " << curr_location << endl; if (curr_location == 0) *************** *** 3555,3559 **** } /* |if|. End of ``Found an intersection point''. */ ! else if (i == 0) { location_switch = curr_location; --- 3555,3559 ---- } /* |if|. End of ``Found an intersection point''. */ ! else if (i == ZERO_REAL) { location_switch = curr_location; *************** *** 3577,3582 **** << "This can't happen! curr_location has bad value: " << curr_location << " " ! << "Returning INVALID_BOOL_POINT_QUADRUPLE\n\n" ! << flush; return INVALID_BOOL_POINT_QUADRUPLE; } --- 3577,3582 ---- << "This can't happen! curr_location has bad value: " << curr_location << " " ! << "Returning INVALID_BOOL_POINT_QUADRUPLE\n\n"; ! return INVALID_BOOL_POINT_QUADRUPLE; } *************** *** 3587,3595 **** { cerr << "Found a transition!\n"; ! cerr << "i == " << i << endl << flush; ! cerr << "save_angle == " << save_angle << endl << flush; ! cerr << "curr_location == " << curr_location << endl << flush; cerr << "location_switch == " ! << location_switch << endl << flush; } if (location_switch == 1) --- 3587,3595 ---- { cerr << "Found a transition!\n"; ! cerr << "i == " << i << endl; ! cerr << "save_angle == " << save_angle << endl; ! cerr << "curr_location == " << curr_location << endl; cerr << "location_switch == " ! << location_switch << endl; } if (location_switch == 1) *************** *** 3644,3649 **** << "This can't happen! Invalid value for curr_location: " << curr_location ! << "\nReturning INVALID_BOOL_POINT_QUADRUPLE.\n\n" ! << flush; return INVALID_BOOL_POINT_QUADRUPLE; } --- 3644,3649 ---- << "This can't happen! Invalid value for curr_location: " << curr_location ! << "\nReturning INVALID_BOOL_POINT_QUADRUPLE.\n\n"; ! return INVALID_BOOL_POINT_QUADRUPLE; } *************** *** 3655,3659 **** cerr << "Finished searching for Ellipse intersections." ! << endl << endl << flush; } /* End of ``Ellipses have different centers --- 3655,3659 ---- cerr << "Finished searching for Ellipse intersections." ! << endl << endl; } /* End of ``Ellipses have different centers *************** *** 3674,3678 **** { cerr << "intersection_ctr == " ! << intersection_ctr << endl << flush; } --- 3674,3678 ---- { cerr << "intersection_ctr == " ! << intersection_ctr << endl; } *************** *** 3745,3749 **** { if (DEBUG) ! cerr << "Ellipses are in perpendicular or skew planes.\n" << flush; --- 3745,3749 ---- { if (DEBUG) ! cerr << "Ellipses are in perpendicular or skew planes.\n"; *************** *** 3762,3768 **** if (DEBUG) { ! cerr << "bpp.first.b == " << bpp.first.b << endl << flush; bpp.first.pt.show("bpp first point:"); ! cerr << "bpp.second.b == " << bpp.second.b << endl << flush; bpp.second.pt.show("bpp second point:"); } --- 3762,3768 ---- if (DEBUG) { ! cerr << "bpp.first.b == " << bpp.first.b << endl; bpp.first.pt.show("bpp first point:"); ! cerr << "bpp.second.b == " << bpp.second.b << endl; bpp.second.pt.show("bpp second point:"); } *************** *** 3834,3838 **** if (DEBUG || verbose) ! cerr << "Exiting Ellipse::intersection_points(Ellipse)\n" << flush; return bpq; } --- 3834,3838 ---- if (DEBUG || verbose) ! cerr << "Exiting Ellipse::intersection_points(Ellipse)\n"; return bpq; } *************** *** 3966,3970 **** if (DEBUG) cerr << "Recalculating linear_eccentricity, " ! << "numerical_eccentricity and foci.\n" << flush; if (axis_h >= axis_v) --- 3966,3970 ---- if (DEBUG) cerr << "Recalculating linear_eccentricity, " ! << "numerical_eccentricity and foci.\n"; if (axis_h >= axis_v) *************** *** 3995,3999 **** else if (DEBUG) cerr << "axis_h and axis_v are unchanged.\n" ! << "Not recalculating foci.\n" << flush; } /* |if (is_elliptical())| */ --- 3995,3999 ---- else if (DEBUG) cerr << "axis_h and axis_v are unchanged.\n" ! << "Not recalculating foci.\n"; } /* |if (is_elliptical())| */ *************** *** 4456,4460 **** { cerr << "Intersection didn't work.\n" ! << "Returning empty rectangle.\n\n" << flush; Rectangle r2; return r2; --- 4456,4460 ---- { cerr << "Intersection didn't work.\n" ! << "Returning empty rectangle.\n\n"; Rectangle r2; return r2; *************** *** 4691,4695 **** I don't have a way to do this yet. \initials{LDF 2003.07.18.} */ ! cerr << endl << flush; } --- 4691,4695 ---- I don't have a way to do this yet. \initials{LDF 2003.07.18.} */ ! cerr << endl; } *************** *** 4712,4716 **** cerr << "ERROR! In |Rectangle::out_ellipse()|:\n" << "Couldn't find intersection point.\n" ! << "Returning empty Ellipse.\n\n" << flush; Ellipse r; return r; --- 4712,4716 ---- cerr << "ERROR! In |Rectangle::out_ellipse()|:\n" << "Couldn't find intersection point.\n" ! << "Returning empty Ellipse.\n\n"; Ellipse r; return r; diff -rc2P 3DLDF-2.0.2/src/ellpsoid.web 3DLDF-2.0.3/src/ellpsoid.web *** 3DLDF-2.0.2/src/ellpsoid.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/ellpsoid.web Fri Dec 13 12:43:41 2013 *************** *** 1566,1570 **** Pointer_Vector* bpv = c->intersection_points(*p, scanner_node); ! if (bpv == 0 || bpv->ctr < 2) { delete c; --- 1566,1570 ---- Pointer_Vector* bpv = c->intersection_points(*p, scanner_node); ! if (bpv == static_cast*>(0) || bpv->ctr < 2) { delete c; *************** *** 2680,2684 **** normal = normal_save; ! isect_path[4].set("--", true, &isect_pt[0], &isect_pt[3], &isect_pt[2],&isect_pt[1], 0); #if TESTING --- 2680,2690 ---- normal = normal_save; ! isect_path[4].set("--", ! true, ! &isect_pt[0], ! &isect_pt[3], ! &isect_pt[2], ! &isect_pt[1], ! static_cast(0)); #if TESTING diff -rc2P 3DLDF-2.0.2/src/fcscmnd.w 3DLDF-2.0.3/src/fcscmnd.w *** 3DLDF-2.0.2/src/fcscmnd.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/fcscmnd.w Thu Dec 12 14:46:08 2013 *************** *** 84,88 **** } ! @=$$@> = 0; }; --- 84,88 ---- } ! @=$$@> = static_cast(0); }; *************** *** 297,301 **** parameter); ! @=$$@> = 0; }; --- 297,301 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 325,329 **** parameter); ! @=$$@> = 0; }; --- 325,329 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 356,360 **** parameter); ! @=$$@> = 0; }; --- 356,360 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 380,384 **** parameter); ! @=$$@> = 0; }; --- 380,384 ---- parameter); ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/figures.web 3DLDF-2.0.3/src/figures.web *** 3DLDF-2.0.2/src/figures.web Wed Nov 6 20:54:38 2013 --- 3DLDF-2.0.3/src/figures.web Thu Dec 12 19:41:15 2013 *************** *** 192,196 **** beginfig(Scanner_Node s, unsigned short i, bool silent) { ! bool DEBUG = true; /* |false| */@; if (SILENT_GLOBAL) --- 192,196 ---- beginfig(Scanner_Node s, unsigned short i, bool silent) { ! bool DEBUG = false; /* |true| */@; if (SILENT_GLOBAL) *************** *** 198,206 **** if (DEBUG) ! cerr << "Entering beginfig(" << i << ")" << endl << flush; if (!silent) cerr << "Beginning figure " << i << "." ! << endl << flush; --- 198,206 ---- if (DEBUG) ! cerr << "Entering beginfig(" << i << ")" << endl; if (!silent) cerr << "Beginning figure " << i << "." ! << endl; *************** *** 212,220 **** @= ! if (current_picture != 0) { if (DEBUG) cerr << "current_picture != 0. Clearing and freeing the memory." ! << endl << flush; current_picture->clear(); delete current_picture; --- 212,220 ---- @= ! if (current_picture != static_cast(0)) { if (DEBUG) cerr << "current_picture != 0. Clearing and freeing the memory." ! << endl; current_picture->clear(); delete current_picture; *************** *** 223,227 **** { if (DEBUG) ! cerr << "current_picture == 0." << endl << flush; } --- 223,227 ---- { if (DEBUG) ! cerr << "current_picture == 0." << endl; } *************** *** 233,237 **** if (DEBUG) ! cerr << "Exiting beginfig(" << i << ")" << endl << flush; return; --- 233,237 ---- if (DEBUG) ! cerr << "Exiting beginfig(" << i << ")" << endl; return; *************** *** 293,300 **** const real min_z_proj, const real max_z_proj) { ! bool DEBUG = true; /* |false| */ @; if (DEBUG) ! cerr << "Entering endfig().\n" << flush; --- 293,300 ---- const real min_z_proj, const real max_z_proj) { ! bool DEBUG = false; /* |true| */ @; if (DEBUG) ! cerr << "Entering endfig().\n"; *************** *** 307,311 **** if (DEBUG) cerr << "projection != Projections::suppress. " ! << "Calling current_picture->output()." << "\n" << flush; current_picture->output(s, f, projection, factor, sort_value, do_warnings, --- 307,311 ---- if (DEBUG) cerr << "projection != Projections::suppress. " ! << "Calling current_picture->output()." << "\n"; current_picture->output(s, f, projection, factor, sort_value, do_warnings, *************** *** 318,322 **** if (DEBUG) cerr << "projection == Projections::suppress. " ! << "Not calling current_picture->output()." << "\n" << flush; } --- 318,322 ---- if (DEBUG) cerr << "projection == Projections::suppress. " ! << "Not calling current_picture->output()." << "\n"; } *************** *** 331,335 **** if (DEBUG) ! cerr << "Exiting endfig().\n" << flush; return; --- 331,335 ---- if (DEBUG) ! cerr << "Exiting endfig().\n"; return; diff -rc2P 3DLDF-2.0.2/src/gsltmplt.web 3DLDF-2.0.3/src/gsltmplt.web *** 3DLDF-2.0.2/src/gsltmplt.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/gsltmplt.web Wed Dec 11 18:38:32 2013 *************** *** 145,156 **** if (verbose) { ! cout << "USHORT_SIZE == " << USHORT_SIZE << endl << flush; ! cout << "UINT_SIZE == " << UINT_SIZE << endl << flush; ! cout << "ULONG_SIZE == " << ULONG_SIZE << endl << flush; ! cout << "ULONG_LONG_SIZE == " << ULONG_LONG_SIZE << endl << flush; ! cout << "FLT_SIZE == " << FLT_SIZE << endl << flush; ! cout << "DBL_SIZE == " << DBL_SIZE << endl << flush; ! cout << "LONG_DBL_SIZE == " << LONG_DBL_SIZE << endl << flush; ! cout << "Real_SIZE == " << Real_SIZE << endl << flush; } --- 145,156 ---- if (verbose) { ! cout << "USHORT_SIZE == " << USHORT_SIZE << endl; ! cout << "UINT_SIZE == " << UINT_SIZE << endl; ! cout << "ULONG_SIZE == " << ULONG_SIZE << endl; ! cout << "ULONG_LONG_SIZE == " << ULONG_LONG_SIZE << endl; ! cout << "FLT_SIZE == " << FLT_SIZE << endl; ! cout << "DBL_SIZE == " << DBL_SIZE << endl; ! cout << "LONG_DBL_SIZE == " << LONG_DBL_SIZE << endl; ! cout << "Real_SIZE == " << Real_SIZE << endl; } *************** *** 195,199 **** << "as any unsigned integral type.\n" << "There must be some mistake.\n" ! << "Exiting with return value -1.\n\n" << flush; return -1; } --- 195,199 ---- << "as any unsigned integral type.\n" << "There must be some mistake.\n" ! << "Exiting with return value -1.\n\n"; return -1; } *************** *** 212,216 **** << (MAX_VAL > *rp) << endl << "MAX_VAL < *rp == " ! << (MAX_VAL < *rp) << endl << flush; } --- 212,216 ---- << (MAX_VAL > *rp) << endl << "MAX_VAL < *rp == " ! << (MAX_VAL < *rp) << endl; } *************** *** 220,224 **** cerr << "ERROR! In System::get_second_largest():\n" << "MAX_VAL == *rp. Exiting with return value 1" ! << endl << endl << flush; exit(1); } --- 220,224 ---- cerr << "ERROR! In System::get_second_largest():\n" << "MAX_VAL == *rp. Exiting with return value 1" ! << endl << endl; exit(1); } *************** *** 228,232 **** cerr << "ERROR! In System::get_second_largest():\n" << "MAX_VAL < *rp. Exiting with return value 1" ! << endl << endl << flush; exit(1); } --- 228,232 ---- cerr << "ERROR! In System::get_second_largest():\n" << "MAX_VAL < *rp. Exiting with return value 1" ! << endl << endl; exit(1); } *************** *** 242,246 **** if (verbose) ! cout << "*ip == " << *ip << endl << flush; i_type bit_pattern_i_type; --- 242,246 ---- if (verbose) ! cout << "*ip == " << *ip << endl; i_type bit_pattern_i_type; *************** *** 255,279 **** if (verbose) ! cout << "b (MAX_VAL) == " << b << endl << flush; b = bit_pattern_i_type; if (verbose) ! cout << "b (bit_pattern_i_type) == " << b << endl << flush; result = bit_pattern_i_type ^ *ip; if (verbose) ! cout << "result == " << result << endl << flush; b = result; if (verbose) ! cout << "b (result) == " << b << endl << flush; rp = reinterpret_cast(&result); if (verbose) ! cout << "*rp == " << *rp << endl << flush; } --- 255,279 ---- if (verbose) ! cout << "b (MAX_VAL) == " << b << endl; b = bit_pattern_i_type; if (verbose) ! cout << "b (bit_pattern_i_type) == " << b << endl; result = bit_pattern_i_type ^ *ip; if (verbose) ! cout << "result == " << result << endl; b = result; if (verbose) ! cout << "b (result) == " << b << endl; rp = reinterpret_cast(&result); if (verbose) ! cout << "*rp == " << *rp << endl; } *************** *** 288,292 **** { if (verbose) ! cout << "i == " << i << endl << flush; --- 288,292 ---- { if (verbose) ! cout << "i == " << i << endl; *************** *** 310,314 **** { if (verbose) ! cout << "i == " << i << ". This produces NAN. Continuing.\n\n" << flush; continue; } --- 310,314 ---- { if (verbose) ! cout << "i == " << i << ". This produces NAN. Continuing.\n\n"; continue; } *************** *** 319,328 **** if (verbose) cout << "bit_pattern_i_type (1 << " << i << ") == " ! << bit_pattern_i_type << endl << flush; b = bit_pattern_i_type; if (verbose) ! cout << "b (bit_pattern_i_type) == " << b << endl << flush; result = bit_pattern_i_type ^ *ip; --- 319,328 ---- if (verbose) cout << "bit_pattern_i_type (1 << " << i << ") == " ! << bit_pattern_i_type << endl; b = bit_pattern_i_type; if (verbose) ! cout << "b (bit_pattern_i_type) == " << b << endl; result = bit_pattern_i_type ^ *ip; *************** *** 330,344 **** if (verbose) ! cout << "result == " << result << endl << flush; b = result; if (verbose) ! cout << "b (result) == " << b << endl << flush; rp = reinterpret_cast(&result); if (verbose) ! cout << "*rp == " << *rp << endl << flush; --- 330,344 ---- if (verbose) ! cout << "result == " << result << endl; b = result; if (verbose) ! cout << "b (result) == " << b << endl; rp = reinterpret_cast(&result); if (verbose) ! cout << "*rp == " << *rp << endl; *************** *** 346,350 **** { if (verbose) ! cout << "*rp <= 0.\nContinuing.\n\n" << flush; continue; } --- 346,350 ---- { if (verbose) ! cout << "*rp <= 0.\nContinuing.\n\n"; continue; } *************** *** 354,358 **** if (verbose) cout << "*rp >= MAX_VAL\nContinuing." ! << endl << flush; continue; } --- 354,358 ---- if (verbose) cout << "*rp >= MAX_VAL\nContinuing." ! << endl; continue; } *************** *** 362,366 **** if (verbose) cout << "second_largest_real >= *rp\nContinuing." ! << "\n" << flush; continue; } --- 362,366 ---- if (verbose) cout << "second_largest_real >= *rp\nContinuing." ! << "\n"; continue; } *************** *** 371,375 **** << "*rp < MAX_VAL" << endl << "Setting second_largest_real to *rp" ! << " and counter to i (" << i << ").\n" << flush; second_largest_real = *rp; --- 371,375 ---- << "*rp < MAX_VAL" << endl << "Setting second_largest_real to *rp" ! << " and counter to i (" << i << ").\n"; second_largest_real = *rp; diff -rc2P 3DLDF-2.0.2/src/helices.web 3DLDF-2.0.3/src/helices.web *** 3DLDF-2.0.2/src/helices.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/helices.web Thu Dec 12 20:18:51 2013 *************** *** 324,328 **** @q **** (4) @> ! if (option_struct == 0) { cerr_strm << thread_name << "ERROR! In 'Helix::set()':" --- 324,328 ---- @q **** (4) @> ! if (option_struct == static_cast(0)) { cerr_strm << thread_name << "ERROR! In 'Helix::set()':" *************** *** 338,342 **** return 1; ! } /* |if (option_struct == 0)| */ @q **** (4) @> --- 338,342 ---- return 1; ! } /* |if (option_struct == static_cast(0))| */ @q **** (4) @> *************** *** 344,348 **** if (option_struct->center) { ! if (center == 0) center = option_struct->center; --- 344,348 ---- if (option_struct->center) { ! if (center == static_cast(0)) center = option_struct->center; *************** *** 365,369 **** if (option_struct->direction) { ! if (direction == 0) direction = option_struct->direction; --- 365,369 ---- if (option_struct->direction) { ! if (direction == static_cast(0)) direction = option_struct->direction; *************** *** 387,391 **** if (option_struct->direction_vector) { ! if (direction_vector == 0) direction_vector = option_struct->direction_vector; --- 387,391 ---- if (option_struct->direction_vector) { ! if (direction_vector == static_cast*>(0)) direction_vector = option_struct->direction_vector; *************** *** 396,400 **** } ! option_struct->direction_vector = 0; } --- 396,400 ---- } ! option_struct->direction_vector = static_cast*>(0); } *************** *** 532,538 **** return *this; ! if (h.center != 0) { ! if (center == 0) center = create_new(0); --- 532,538 ---- return *this; ! if (h.center != static_cast(0)) { ! if (center == static_cast(0)) center = create_new(0); *************** *** 540,546 **** } ! if (h.direction != 0) { ! if (direction == 0) direction = create_new(0); --- 540,546 ---- } ! if (h.direction != static_cast(0)) { ! if (direction == static_cast(0)) direction = create_new(0); *************** *** 548,554 **** } ! if (h.direction_vector != 0) { ! if (direction_vector == 0) direction_vector = new Pointer_Vector; --- 548,554 ---- } ! if (h.direction_vector != static_cast*>(0)) { ! if (direction_vector == static_cast*>(0)) direction_vector = new Pointer_Vector; *************** *** 631,635 **** @q ***** (5) Preliminaries.@> ! bool DEBUG = true; /* |false| */ using namespace Scan_Parse; --- 631,635 ---- @q ***** (5) Preliminaries.@> ! bool DEBUG = false; /* |true| */ using namespace Scan_Parse; *************** *** 686,690 **** Helix::operator*=(const Transform& t) { ! if (center != 0) *center *= t; --- 686,690 ---- Helix::operator*=(const Transform& t) { ! if (center != static_cast(0)) *center *= t; *************** *** 862,866 **** { ! if (center != 0) center->shift_times(x, y, z); --- 862,866 ---- { ! if (center != static_cast(0)) center->shift_times(x, y, z); *************** *** 1015,1019 **** f, proj, factor); ! if (center == 0) cerr << "center == 0" << endl; else --- 1015,1019 ---- f, proj, factor); ! if (center == static_cast(0)) cerr << "center == 0" << endl; else *************** *** 1021,1030 **** ! if (direction == 0) cerr << "direction == 0" << endl; else direction->show("direction:"); ! if (direction_vector == 0) cerr << "direction_vector == 0" << endl; else --- 1021,1030 ---- ! if (direction == static_cast(0)) cerr << "direction == 0" << endl; else direction->show("direction:"); ! if (direction_vector == static_cast*>(0)) cerr << "direction_vector == 0" << endl; else diff -rc2P 3DLDF-2.0.2/src/hyprbola.web 3DLDF-2.0.3/src/hyprbola.web *** 3DLDF-2.0.2/src/hyprbola.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/hyprbola.web Thu Dec 12 19:54:47 2013 *************** *** 234,251 **** using namespace Scan_Parse; ! @q **** (4) |options == 0|. Use defaults.@> ! @ |options == 0|. Use defaults. \initials{LDF 2005.11.15.} @= ! if (!options) ! { ! ! } /* |if (!options)| */ ! @q **** (4) |options != 0|.@> ! @ |options != 0|. \initials{LDF 2005.11.15.} --- 234,251 ---- using namespace Scan_Parse; ! @q **** (4) |options == static_cast(0)|. Use defaults.@> ! @ |options == static_cast(0)|. Use defaults. \initials{LDF 2005.11.15.} @= ! if (options == static_cast(0)) ! { ! /* Do nothing */ + } /* |if (options == static_cast(0))| */ ! @q **** (4) |options != static_cast(0)|. @> ! @ |options != static_cast(0)|. \initials{LDF 2005.11.15.} *************** *** 264,268 **** @= ! else /* |options != 0| */ { --- 264,268 ---- @= ! else /* |options != static_cast(0)| */ { *************** *** 357,361 **** connectors.push_back(".."); ! } /* |else| (|options != 0|) */ --- 357,361 ---- connectors.push_back(".."); ! } /* |else| (|options != static_cast(0)|) */ *************** *** 590,594 **** @= ! if (u == 0) { cerr_strm << thread_name << "ERROR! In `Hyperbola::get_discriminant()':" --- 590,594 ---- @= ! if (u == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Hyperbola::get_discriminant()':" *************** *** 611,615 **** ! } /* |if (u == 0)| */ @q **** (4)@> --- 611,615 ---- ! } /* |if (u == static_cast(0))| */ @q **** (4)@> *************** *** 796,800 **** @= ! if (t == 0) { cerr_strm << thread_name --- 796,800 ---- @= ! if (t == static_cast(0)) { cerr_strm << thread_name *************** *** 812,816 **** return -5; ! } /* |if (t == 0)| */ @q **** (4)@> --- 812,816 ---- return -5; ! } /* |if (t == static_cast(0))| */ @q **** (4)@> *************** *** 993,997 **** cerr << "ERROR! In Hyperbola::get_point():\n" << "Argument is >= size of Hyperbola.\n" ! << "Returning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 993,997 ---- cerr << "ERROR! In Hyperbola::get_point():\n" << "Argument is >= size of Hyperbola.\n" ! << "Returning INVALID_POINT.\n\n" ; return INVALID_POINT; } *************** *** 1046,1050 **** cerr << "ERROR! In Hyperbola::get_point():\n" << "Argument is >= size of Hyperbola.\n" ! << "Returning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 1046,1050 ---- cerr << "ERROR! In Hyperbola::get_point():\n" << "Argument is >= size of Hyperbola.\n" ! << "Returning INVALID_POINT.\n\n" ; return INVALID_POINT; } *************** *** 1983,1987 **** @q ***** (5)@> ! if (discriminant == 0) { x = (-a_2 * m * n) / ((a_2 * m_2) - b_2); --- 1983,1987 ---- @q ***** (5)@> ! if (discriminant == ZERO_REAL) { x = (-a_2 * m * n) / ((a_2 * m_2) - b_2); *************** *** 2002,2010 **** return bpv; ! } /* |if (discriminant == 0)| */ @q ***** (5)@> ! if (discriminant > 0) { --- 2002,2010 ---- return bpv; ! } /* |if (discriminant == ZERO_REAL)| */ @q ***** (5)@> ! if (discriminant > ZERO_REAL) { *************** *** 2051,2055 **** ! } /* |if (discriminant > 0)| */ @q ***** (5)@> --- 2051,2055 ---- ! } /* |if (discriminant > ZERO_REAL)| */ @q ***** (5)@> diff -rc2P 3DLDF-2.0.2/src/imetfncs.web 3DLDF-2.0.3/src/imetfncs.web *** 3DLDF-2.0.2/src/imetfncs.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/imetfncs.web Thu Dec 12 20:17:11 2013 *************** *** 232,243 **** ! @q ******* (7) Error handling: |curr_entry == 0|.@> ! @ Error handling: |curr_entry == 0|. \initials{LDF 2004.09.17.} @= ! if (curr_entry == 0) { --- 232,243 ---- ! @q ******* (7) Error handling: |curr_entry == static_cast(0)|.@> ! @ Error handling: |curr_entry == static_cast(0)|. \initials{LDF 2004.09.17.} @= ! if (curr_entry == static_cast(0)) { *************** *** 254,258 **** throw bad_assignment; ! } /* |if (curr_entry == 0)| */ --- 254,258 ---- throw bad_assignment; ! } /* |if (curr_entry == static_cast(0))| */ *************** *** 266,270 **** @= ! else if (curr_entry->subordinate_array != 0) ; /* Do nothing. */@; --- 266,270 ---- @= ! else if (curr_entry->subordinate_array != static_cast(0)) ; /* Do nothing. */@; *************** *** 334,338 **** @= ! if (curr_entry->superordinate_vector != 0) { --- 334,338 ---- @= ! if (curr_entry->superordinate_vector != static_cast(0)) { *************** *** 377,381 **** @q ********* (9).@> ! } /* |else if (curr_entry->superordinate_vector != 0)| */ --- 377,381 ---- @q ********* (9).@> ! } /* |else if (curr_entry->superordinate_vector != static_cast(0))| */ *************** *** 600,609 **** { Shape* s = static_cast(object); ! if (s != 0) { s->clear(); delete s; ! s = 0; } --- 600,609 ---- { Shape* s = static_cast(object); ! if (s != static_cast(0)) { s->clear(); delete s; ! s = static_cast(0); } *************** *** 636,643 **** { Nurb* n = static_cast(object); ! if (n != 0) { delete n; ! n = 0; } --- 636,643 ---- { Nurb* n = static_cast(object); ! if (n != static_cast(0)) { delete n; ! n = static_cast(0); } *************** *** 695,699 **** else if (type == UNDECLARED) { ! if (object != 0) { --- 695,699 ---- else if (type == UNDECLARED) { ! if (object != static_cast(0)) { *************** *** 711,717 **** return; ! } /* |if (object != 0)| */ ! else if (left != 0 || right != 0) { --- 711,718 ---- return; ! } /* |if (object != static_cast(0))| */ ! else if ( left != static_cast(0) ! || right != static_cast(0)) { *************** *** 729,733 **** return; ! } /* |else if (left != 0 || right != 0)| */ else --- 730,735 ---- return; ! } /* |else if ( left != static_cast(0) ! || right != static_cast(0))| */ else *************** *** 825,829 **** @= ! if (object != 0) { --- 827,831 ---- @= ! if (object != static_cast(0)) { *************** *** 1330,1334 **** object = 0; ! } /* |if (object != 0)| */ --- 1332,1336 ---- object = 0; ! } /* |if (object != static_cast(0))| */ *************** *** 1356,1360 **** #if DEBUG_COMPILE ! else if (DEBUG) /* |object == 0| */ { --- 1358,1362 ---- #if DEBUG_COMPILE ! else if (DEBUG) /* |object == static_cast(0)| */ { *************** *** 1367,1371 **** cerr_strm.str(""); ! } /* |else if (DEBUG)| (|object == 0|) */ #endif /* |DEBUG_COMPILE| */@; --- 1369,1373 ---- cerr_strm.str(""); ! } /* |else if (DEBUG)| (|object == static_cast(0)|) */ #endif /* |DEBUG_COMPILE| */@; *************** *** 1437,1444 **** Predicate* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } --- 1439,1446 ---- Predicate* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } *************** *** 1452,1459 **** int* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } /* |else if (type == BOOLEAN)| */ --- 1454,1461 ---- int* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } /* |else if (type == BOOLEAN)| */ *************** *** 1464,1471 **** { Complex* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } --- 1466,1473 ---- { Complex* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } *************** *** 1476,1483 **** { Matrix* m = static_cast(object); ! if (m != 0) { delete m; ! m = 0; } --- 1478,1485 ---- { Matrix* m = static_cast(object); ! if (m != static_cast(0)) { delete m; ! m = static_cast(0); } *************** *** 1493,1500 **** Bool_Point* bp = static_cast(object); ! if (bp != 0) { delete bp; ! bp = 0; } } /* |else if (type == BOOL_POINT)| */ --- 1495,1502 ---- Bool_Point* bp = static_cast(object); ! if (bp != static_cast(0)) { delete bp; ! bp = static_cast(0); } } /* |else if (type == BOOL_POINT)| */ *************** *** 1508,1515 **** string* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1510,1517 ---- string* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1521,1528 **** real* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1523,1530 ---- real* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1533,1540 **** unsigned long long* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1535,1542 ---- unsigned long long* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1545,1552 **** Pen* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1547,1554 ---- Pen* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1557,1564 **** Dash_Pattern* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1559,1566 ---- Dash_Pattern* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1569,1576 **** Color* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } --- 1571,1578 ---- Color* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } *************** *** 1583,1590 **** Picture* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1585,1592 ---- Picture* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1595,1602 **** Transform* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1597,1604 ---- Transform* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1607,1614 **** Plane* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1609,1616 ---- Plane* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1621,1628 **** Focus* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1623,1630 ---- Focus* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1634,1641 **** Definition_Info_Node c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1636,1643 ---- Definition_Info_Node c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1646,1653 **** Origami_Figure* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1648,1655 ---- Origami_Figure* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1658,1665 **** Glyph* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1660,1667 ---- Glyph* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1678,1685 **** real* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1680,1687 ---- real* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1699,1706 **** real* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1701,1708 ---- real* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1721,1728 **** string* c = static_cast(object); ! if (c != 0) { delete c; ! c = 0; } } --- 1723,1730 ---- string* c = static_cast(object); ! if (c != static_cast(0)) { delete c; ! c = static_cast(0); } } *************** *** 1749,1753 **** @= ! else if (object != 0) { cerr_strm << thread_name --- 1751,1755 ---- @= ! else if (object != static_cast(0)) { cerr_strm << thread_name *************** *** 1988,1992 **** ! if (curr_entry->up == 0) { --- 1990,1994 ---- ! if (curr_entry->up == static_cast(0)) { *************** *** 2008,2012 **** return 0; ! } /* |if (curr_entry->up == 0)| */ temp_entry = curr_entry; --- 2010,2014 ---- return 0; ! } /* |if (curr_entry->up == static_cast(0))| */ temp_entry = curr_entry; *************** *** 2160,2164 **** cerr << "ERROR! In `Id_Map_Entry_Type::set_entry()':" << endl << "`pthread_mutex_init()' failed."; ! cerr << "Type to continue.\n" << flush; getchar(); /* Don't delete this! */ --- 2162,2166 ---- cerr << "ERROR! In `Id_Map_Entry_Type::set_entry()':" << endl << "`pthread_mutex_init()' failed."; ! cerr << "Type to continue.\n"; getchar(); /* Don't delete this! */ *************** *** 2171,2175 **** cerr << "In `Id_Map_Entry_Type::set_entry()':" << endl << "`pthread_mutex_init()' succeeded!" ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 2173,2177 ---- cerr << "In `Id_Map_Entry_Type::set_entry()':" << endl << "`pthread_mutex_init()' succeeded!" ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 2188,2192 **** cerr << "In set_entry(): type == " << type << " == " ! << name_map[type] << endl << flush; if (category == SPARK) --- 2190,2194 ---- cerr << "In set_entry(): type == " << type << " == " ! << name_map[type] << endl; if (category == SPARK) *************** *** 2214,2238 **** ! if (object == 0) cerr << "object == 0" << "\n"; else cerr << "object != 0" << "\n"; ! if (up == 0) cerr << "up == 0" << "\n"; else cerr << "up != 0" << "\n"; ! if (left == 0) cerr << "left == 0" << "\n"; else cerr << "left != 0" << "\n"; ! if (right == 0) cerr << "right == 0" << "\n"; else cerr << "right != 0" << "\n"; ! cerr << "Exiting Id_Map_Entry_Type::set()." << "\n" << flush; } --- 2216,2240 ---- ! if (object == static_cast(0)) cerr << "object == 0" << "\n"; else cerr << "object != 0" << "\n"; ! if (up == static_cast(0)) cerr << "up == 0" << "\n"; else cerr << "up != 0" << "\n"; ! if (left == static_cast(0)) cerr << "left == 0" << "\n"; else cerr << "left != 0" << "\n"; ! if (right == static_cast(0)) cerr << "right == 0" << "\n"; else cerr << "right != 0" << "\n"; ! cerr << "Exiting Id_Map_Entry_Type::set()." << "\n"; } *************** *** 2276,2301 **** Scanner_Node scanner_node; ! if (id_map_node != 0 && id_map_node->scanner_node != 0) { scanner_node = id_map_node->scanner_node; ! } /* |if (id_map_node->scanner_node != 0)| */ ! else if (i.id_map_node->scanner_node != 0) { scanner_node = i.id_map_node->scanner_node; ! } /* |if (i.id_map_node->scanner_node != 0)| */ ! else /* | id_map_node->scanner_node == 0 ! && i.id_map_node->scanner_node == 0| */ { ! scanner_node = 0; ! } /* |else| (|i.id_map_node->scanner_node == 0|) */ --- 2278,2304 ---- Scanner_Node scanner_node; ! if ( id_map_node != static_cast(0) ! && id_map_node->scanner_node != static_cast(0)) { scanner_node = id_map_node->scanner_node; ! } /* |if (id_map_node->scanner_node != static_cast(0))| */ ! else if (i.id_map_node->scanner_node != static_cast(0)) { scanner_node = i.id_map_node->scanner_node; ! } /* |if (i.id_map_node->scanner_node != static_cast(0))| */ ! else /* | id_map_node->scanner_node == static_cast(0) ! && i.id_map_node->scanner_node == static_cast(0)| */ { ! scanner_node = static_cast(0); ! } /* |else| (|i.id_map_node->scanner_node == static_cast(0)|) */ *************** *** 2382,2386 **** @= ! if (type == SYNONYM && i.object != 0) { string* o = new string; --- 2385,2389 ---- @= ! if (type == SYNONYM && i.object != static_cast(0)) { string* o = new string; *************** *** 2391,2395 **** ! else if (type == PREDICATE && i.object != 0) { Predicate* o = new Predicate; --- 2394,2398 ---- ! else if (type == PREDICATE && i.object != static_cast(0)) { Predicate* o = new Predicate; *************** *** 2399,2403 **** } ! else if (type == BOOLEAN && i.object != 0) { int* o = new int; --- 2402,2406 ---- } ! else if (type == BOOLEAN && i.object != static_cast(0)) { int* o = new int; *************** *** 2407,2411 **** } ! else if (type == NUMERIC && i.object != 0) { real* o = new real; --- 2410,2414 ---- } ! else if (type == NUMERIC && i.object != static_cast(0)) { real* o = new real; *************** *** 2414,2418 **** } ! else if (type == ULONG_LONG && i.object != 0) { ulong_long* o = new ulong_long; --- 2417,2421 ---- } ! else if (type == ULONG_LONG && i.object != static_cast(0)) { ulong_long* o = new ulong_long; *************** *** 2422,2426 **** ! else if (type == STRING && i.object != 0) { string* o = new string; --- 2425,2429 ---- ! else if (type == STRING && i.object != static_cast(0)) { string* o = new string; *************** *** 2429,2433 **** } ! else if (type == PEN && i.object != 0) { Pen* o = new Pen; --- 2432,2436 ---- } ! else if (type == PEN && i.object != static_cast(0)) { Pen* o = new Pen; *************** *** 2436,2440 **** } ! else if (type == DASH_PATTERN && i.object != 0) { Dash_Pattern* o = new Dash_Pattern; --- 2439,2443 ---- } ! else if (type == DASH_PATTERN && i.object != static_cast(0)) { Dash_Pattern* o = new Dash_Pattern; *************** *** 2443,2447 **** } ! else if (type == COLOR && i.object != 0) { Color* o = new Color; --- 2446,2450 ---- } ! else if (type == COLOR && i.object != static_cast(0)) { Color* o = new Color; *************** *** 2450,2454 **** } ! else if (type == PICTURE && i.object != 0) { Picture* o = new Picture; --- 2453,2457 ---- } ! else if (type == PICTURE && i.object != static_cast(0)) { Picture* o = new Picture; *************** *** 2459,2463 **** ! else if (type == TRANSFORM && i.object != 0) { Transform* o = new Transform; --- 2462,2466 ---- ! else if (type == TRANSFORM && i.object != static_cast(0)) { Transform* o = new Transform; *************** *** 2467,2471 **** ! else if (type == FOCUS && i.object != 0) { Focus* o = new Focus; --- 2470,2474 ---- ! else if (type == FOCUS && i.object != static_cast(0)) { Focus* o = new Focus; *************** *** 2475,2479 **** ! else if (type == MACRO && i.object != 0) { Definition_Info_Node o = new Definition_Info_Type; --- 2478,2482 ---- ! else if (type == MACRO && i.object != static_cast(0)) { Definition_Info_Node o = new Definition_Info_Type; *************** *** 2499,2503 **** ! else if (type == BOOL_POINT && i.object != 0) { int* o = new int; --- 2502,2506 ---- ! else if (type == BOOL_POINT && i.object != static_cast(0)) { int* o = new int; *************** *** 2507,2511 **** } ! else if (type == POINT && i.object != 0) { Point* o = new Point; --- 2510,2514 ---- } ! else if (type == POINT && i.object != static_cast(0)) { Point* o = new Point; *************** *** 2514,2518 **** } ! else if (type == PATH && i.object != 0) { Path* o = new Path; --- 2517,2521 ---- } ! else if (type == PATH && i.object != static_cast(0)) { Path* o = new Path; *************** *** 2521,2525 **** } ! else if (type == TRIANGLE && i.object != 0) { Triangle* o = new Triangle; --- 2524,2528 ---- } ! else if (type == TRIANGLE && i.object != static_cast(0)) { Triangle* o = new Triangle; *************** *** 2529,2533 **** ! else if (type == POLYGON && i.object != 0) { Polygon* o = new Polygon; --- 2532,2536 ---- ! else if (type == POLYGON && i.object != static_cast(0)) { Polygon* o = new Polygon; *************** *** 2536,2540 **** } ! else if (type == REG_POLYGON && i.object != 0) { Reg_Polygon* o = new Reg_Polygon; --- 2539,2543 ---- } ! else if (type == REG_POLYGON && i.object != static_cast(0)) { Reg_Polygon* o = new Reg_Polygon; *************** *** 2543,2547 **** } ! else if (type == RECTANGLE && i.object != 0) { Rectangle* o = new Rectangle; --- 2546,2550 ---- } ! else if (type == RECTANGLE && i.object != static_cast(0)) { Rectangle* o = new Rectangle; *************** *** 2552,2556 **** #if 0 /* |Square| not defined yet. \initials{LDF 2004.09.14.} */@; ! else if (type == SQUARE && i.object != 0) { Square* o = new Square; --- 2555,2559 ---- #if 0 /* |Square| not defined yet. \initials{LDF 2004.09.14.} */@; ! else if (type == SQUARE && i.object != static_cast(0)) { Square* o = new Square; *************** *** 2560,2564 **** #endif ! else if (type == ELLIPSE && i.object != 0) { Ellipse* o = new Ellipse; --- 2563,2567 ---- #endif ! else if (type == ELLIPSE && i.object != static_cast(0)) { Ellipse* o = new Ellipse; *************** *** 2567,2571 **** } ! else if (type == CIRCLE && i.object != 0) { Circle* o = new Circle; --- 2570,2574 ---- } ! else if (type == CIRCLE && i.object != static_cast(0)) { Circle* o = new Circle; *************** *** 2575,2579 **** ! else if (type == CUBOID && i.object != 0) { Cuboid* o = new Cuboid; --- 2578,2582 ---- ! else if (type == CUBOID && i.object != static_cast(0)) { Cuboid* o = new Cuboid; *************** *** 2582,2586 **** } ! else if (type == POLYHEDRON && i.object != 0) { Polyhedron* o = new Polyhedron; --- 2585,2589 ---- } ! else if (type == POLYHEDRON && i.object != static_cast(0)) { Polyhedron* o = new Polyhedron; *************** *** 2828,2838 **** { ! @q ****** (6) Error handling: |object != 0|.@> ! @ Error handling: |object != 0|. \initials{LDF 2004.09.14.} @= ! if (i.object != 0) { cerr_strm << thread_name --- 2831,2841 ---- { ! @q ****** (6) Error handling: |object != static_cast(0)|.@> ! @ Error handling: |object != static_cast(0)|. \initials{LDF 2004.09.14.} @= ! if (i.object != static_cast(0)) { cerr_strm << thread_name *************** *** 2845,2852 **** cerr_strm.str(""); ! } /* |if (i.object != 0)| */ ! @q ****** (6) |object == 0|.@> ! @ |object == 0|. \initials{LDF 2004.09.14.} --- 2848,2855 ---- cerr_strm.str(""); ! } /* |if (i.object != static_cast(0))| */ ! @q ****** (6) |object == static_cast(0)|.@> ! @ |object == static_cast(0)|. \initials{LDF 2004.09.14.} *************** *** 2854,2858 **** #if DEBUG_COMPILE ! else if (DEBUG) /* |i.object == 0| */ { --- 2857,2861 ---- #if DEBUG_COMPILE ! else if (DEBUG) /* |i.object == static_cast(0)| */ { *************** *** 2865,2869 **** cerr_strm.str(""); ! } /* |else if (DEBUG)| (|i.object == 0|) */ #endif /* |DEBUG_COMPILE| */@; --- 2868,2872 ---- cerr_strm.str(""); ! } /* |else if (DEBUG)| (|i.object == static_cast(0)|) */ #endif /* |DEBUG_COMPILE| */@; *************** *** 2898,2903 **** ! @q ****** (6) |i.left != 0|.@> ! @ |i.left != 0|. \initials{LDF 2004.09.14.} --- 2901,2906 ---- ! @q ****** (6) |i.left != static_cast(0)|.@> ! @ |i.left != static_cast(0)|. \initials{LDF 2004.09.14.} *************** *** 2905,2909 **** ! if (i.left != 0) { --- 2908,2912 ---- ! if (i.left != static_cast(0)) { *************** *** 2932,2940 **** left->up = this; ! } /* |if (i.left != 0)| */ ! @q ****** (6) |i.right != 0|.@> ! @ |i.right != 0|. \initials{LDF 2004.09.14.} --- 2935,2943 ---- left->up = this; ! } /* |if (i.left != static_cast(0))| */ ! @q ****** (6) |i.right != static_cast(0)|.@> ! @ |i.right != static_cast(0)|. \initials{LDF 2004.09.14.} *************** *** 2942,2946 **** ! if (i.right != 0) { --- 2945,2949 ---- ! if (i.right != static_cast(0)) { *************** *** 2967,2971 **** right->up = this; ! } /* |if (i.right != 0)| */ --- 2970,2974 ---- right->up = this; ! } /* |if (i.right != static_cast(0))| */ *************** *** 3042,3046 **** Scanner_Node scanner_node = 0; ! if (id_map_node != 0 && id_map_node->scanner_node != 0) scanner_node = id_map_node->scanner_node; --- 3045,3050 ---- Scanner_Node scanner_node = 0; ! if ( id_map_node != static_cast(0) ! && id_map_node->scanner_node != static_cast(0)) scanner_node = id_map_node->scanner_node; *************** *** 3049,3053 **** bool error_stop_value; ! if (scanner_node != 0) error_stop_value = (scanner_node->get_run_state()->error_stop_mode == Run_State::STOPPING) ? true : false; --- 3053,3057 ---- bool error_stop_value; ! if (scanner_node != static_cast(0)) error_stop_value = (scanner_node->get_run_state()->error_stop_mode == Run_State::STOPPING) ? true : false; *************** *** 3070,3077 **** Do this in the assignment operators, too. */ ! if (scanner_node != 0 && ! ( scanner_node->get_run_state()->multithread_input ! || scanner_node->get_run_state()->multithread_output ! || scanner_node->get_run_state()->multithread_include)) /* Using multithreading. */ --- 3074,3082 ---- Do this in the assignment operators, too. */ ! if ( scanner_node != static_cast(0) ! && ! ( scanner_node->get_run_state()->multithread_input ! || scanner_node->get_run_state()->multithread_output ! || scanner_node->get_run_state()->multithread_include)) /* Using multithreading. */ *************** *** 3084,3100 **** ! @q ***** (5) |scanner_node == 0| or not using multithreading.@> ! @ |scanner_node == 0| or not using multithreading. \initials{LDF 2004.09.17.} @= ! else /* |scanner_node == 0| or not using multithreading. */ { ! thread_info = 0; thread_name = ""; ! } /* |else| (|scanner_node == 0| or not using multithreading.) */ --- 3089,3106 ---- ! @q ***** (5) |scanner_node == static_cast(0)| or not using multithreading.@> ! @ |scanner_node == static_cast(0)| or not using multithreading. \initials{LDF 2004.09.17.} @= ! else { ! thread_info = static_cast(0); thread_name = ""; ! } /* |else| (|scanner_node == static_cast(0)| ! or not using multithreading.) */ *************** *** 3221,3229 **** { ! if (s->subordinate_array == 0) s->subordinate_array = this; ! if (type == COLOR && object != 0) { --- 3227,3235 ---- { ! if (s->subordinate_array == static_cast(0)) s->subordinate_array = this; ! if (type == COLOR && object != static_cast(0)) { *************** *** 3231,3235 **** ! if (s->object == 0) s->object = static_cast(new Pv); --- 3237,3241 ---- ! if (s->object == static_cast(0)) s->object = static_cast(new Pv); *************** *** 3243,3252 **** ! else if (type == POINT && object != 0) { typedef Pointer_Vector Pv; ! if (s->object == 0) s->object = static_cast(new Pv); --- 3249,3258 ---- ! else if (type == POINT && object != static_cast(0)) { typedef Pointer_Vector Pv; ! if (s->object == static_cast(0)) s->object = static_cast(new Pv); *************** *** 3260,3269 **** ! else if (type == BOOL_POINT && object != 0) { typedef Pointer_Vector Pv; ! if (s->object == 0) s->object = static_cast(new Pv); --- 3266,3275 ---- ! else if (type == BOOL_POINT && object != static_cast(0)) { typedef Pointer_Vector Pv; ! if (s->object == static_cast(0)) s->object = static_cast(new Pv); *************** *** 3277,3281 **** ! else if (object != 0) /* Invalid |type|. */ { --- 3283,3287 ---- ! else if (object != static_cast(0)) /* Invalid |type|. */ { *************** *** 3292,3296 **** return 1; ! } /* |else if (object != 0)| (Invalid |type|.) */ --- 3298,3302 ---- return 1; ! } /* |else if (object != static_cast(0))| (Invalid |type|.) */ *************** *** 3439,3450 **** ! @q **** (4) If |left != 0|, call this function recursively on |left|.@> ! @ If |left != 0|, call this function recursively on |left|. \initials{LDF 2004.09.17.} @= ! if (left != 0) { status = left->set_id_map_node(i); --- 3445,3458 ---- ! @q **** (4) If |left != static_cast(0)|, @> ! @q **** (4) call this function recursively on |left|. @> ! @ If |left != static_cast(0)|, ! call this function recursively on |left|. \initials{LDF 2004.09.17.} @= ! if (left != static_cast(0)) { status = left->set_id_map_node(i); *************** *** 3473,3477 **** } /* |if (status != 0)| */ ! } /* |if (left != 0)| */ --- 3481,3485 ---- } /* |if (status != 0)| */ ! } /* |if (left != static_cast(0))| */ *************** *** 3485,3496 **** id_map_node = i; ! @q **** (4) If |right != 0|, call this function recursively on |right|.@> ! @ If |right != 0|, call this function recursively on |right|. \initials{LDF 2004.09.17.} @= ! if (right != 0) { status = right->set_id_map_node(i); --- 3493,3506 ---- id_map_node = i; ! @q **** (4) If |right != static_cast(0)|, @> ! @q **** (4) call this function recursively on |right|. @> ! @ If |right != static_cast(0)|, ! call this function recursively on |right|. \initials{LDF 2004.09.17.} @= ! if (right != static_cast(0)) { status = right->set_id_map_node(i); *************** *** 3519,3523 **** } /* |if (status != 0)| */ ! } /* |if (right != 0)| */ --- 3529,3533 ---- } /* |if (status != 0)| */ ! } /* |if (right != static_cast(0))| */ *************** *** 3611,3615 **** Scanner_Node scanner_node = 0; ! if (id_map_node != 0 && id_map_node->scanner_node != 0) scanner_node = id_map_node->scanner_node; --- 3621,3626 ---- Scanner_Node scanner_node = 0; ! if ( id_map_node != static_cast(0) ! && id_map_node->scanner_node != static_cast(0)) scanner_node = id_map_node->scanner_node; *************** *** 3618,3622 **** bool error_stop_value; ! if (scanner_node != 0) error_stop_value = (scanner_node->get_run_state()->error_stop_mode == Run_State::STOPPING) ? true : false; --- 3629,3633 ---- bool error_stop_value; ! if (scanner_node != static_cast(0)) error_stop_value = (scanner_node->get_run_state()->error_stop_mode == Run_State::STOPPING) ? true : false; *************** *** 3636,3640 **** @= ! if (scanner_node != 0 && ( scanner_node->get_run_state()->multithread_input || scanner_node->get_run_state()->multithread_output --- 3647,3651 ---- @= ! if (scanner_node != static_cast(0) && ( scanner_node->get_run_state()->multithread_input || scanner_node->get_run_state()->multithread_output *************** *** 3650,3666 **** ! @q ***** (5) |scanner_node == 0| or not using multithreading.@> ! @ |scanner_node == 0| or not using multithreading. \initials{LDF 2004.09.17.} @= ! else /* |scanner_node == 0| or not using multithreading. */ { ! thread_info = 0; thread_name = ""; ! } /* |else| (|scanner_node == 0| or not using multithreading.) */ --- 3661,3678 ---- ! @q ***** (5) |scanner_node == static_cast(0)| or not using multithreading.@> ! @ |scanner_node == static_cast(0)| or not using multithreading. \initials{LDF 2004.09.17.} @= ! else /* |scanner_node == static_cast(0)| or not using multithreading. */ { ! thread_info = static_cast(0); thread_name = ""; ! } /* |else| (|scanner_node == static_cast(0)| ! or not using multithreading.) */ *************** *** 3693,3702 **** ! if (s->left != 0) set_subordinate_array(s->left, true, type); ! if (s->object != 0) { #if DEBUG_COMPILE --- 3705,3714 ---- ! if (s->left != static_cast(0)) set_subordinate_array(s->left, true, type); ! if (s->object != static_cast(0)) { #if DEBUG_COMPILE *************** *** 3764,3771 **** ! } /* |if (s->object != 0)| */ ! if (s->right != 0) set_subordinate_array(s->right, true, type); --- 3776,3783 ---- ! } /* |if (s->object != static_cast(0))| */ ! if (s->right != static_cast(0)) set_subordinate_array(s->right, true, type); *************** *** 3878,3889 **** #endif /* |DEBUG_COMPILE| */@; ! @q ***** (5) Error handling: |object == 0|.@> ! @ Error handling: |object == 0|. \initials{LDF 2004.09.29.} @= ! if (object == 0) { cerr_strm << thread_name --- 3890,3901 ---- #endif /* |DEBUG_COMPILE| */@; ! @q ***** (5) Error handling: |object == static_cast(0)|.@> ! @ Error handling: |object == static_cast(0)|. \initials{LDF 2004.09.29.} @= ! if (object == static_cast(0)) { cerr_strm << thread_name *************** *** 3895,3899 **** return INVALID_TRANSFORM; ! } /* |if (object == 0)| */ @q ***** (5).@> --- 3907,3911 ---- return INVALID_TRANSFORM; ! } /* |if (object == static_cast(0))| */ @q ***** (5).@> *************** *** 4374,4381 **** Scanner_Node scanner_node; ! if (id_map_node != 0) scanner_node = id_map_node->scanner_node; else ! scanner_node = 0; --- 4386,4393 ---- Scanner_Node scanner_node; ! if (id_map_node != static_cast(0)) scanner_node = id_map_node->scanner_node; else ! scanner_node = static_cast(0); *************** *** 4395,4406 **** ! @q ***** (5) |scanner_node != 0|.@> ! @ |scanner_node != 0|. \initials{LDF 2004.08.23.} @= ! if (scanner_node) /* |scanner_node != 0| */ { --- 4407,4418 ---- ! @q ***** (5) |scanner_node != static_cast(0)|.@> ! @ |scanner_node != static_cast(0)|. \initials{LDF 2004.08.23.} @= ! if (scanner_node != static_cast(0)) { *************** *** 4425,4452 **** ! @q ****** (6) |scanner_node != 0|, but not using multithreading.@> ! @ |scanner_node != 0|, but not using multithreading. \initials{LDF 2004.08.23.} @= ! else /* |scanner_node != 0|, but not using multithreading. */ { ! thread_info = 0; thread_name = ""; ! } /* |else| (|scanner_node != 0|, but not using multithreading.) */ } /* |if (scanner_node)| */ ! @q ***** (5) |scanner_node == 0|. Assume we're using multithreading.@> ! ! @ |scanner_node == 0|. Assume we're using multithreading. @= ! else /* (|scanner_node == 0|) */ { --- 4437,4464 ---- ! @q ****** (6) |scanner_node != static_cast(0)|, but not using multithreading.@> ! @ |scanner_node != static_cast(0)|, but not using multithreading. \initials{LDF 2004.08.23.} @= ! else /* |scanner_node != static_cast(0)|, but not using multithreading. */ { ! thread_info = static_cast(0); thread_name = ""; ! } /* |else| (|scanner_node != static_cast(0)|, ! but not using multithreading.) */ } /* |if (scanner_node)| */ ! @q ***** (5) |scanner_node == static_cast(0)|. Assume we're using multithreading.@> ! @ |scanner_node == static_cast(0)|. Assume we're using multithreading. @= ! else /* (|scanner_node == static_cast(0)|) */ { *************** *** 4455,4459 **** ! } /* |else| (|scanner_node == 0|) */ #else /* |HAVE_PTHREAD_H| is undefined. */@; --- 4467,4471 ---- ! } /* |else| (|scanner_node == static_cast(0)|) */ #else /* |HAVE_PTHREAD_H| is undefined. */@; *************** *** 4473,4477 **** bool error_stop_value; ! if (scanner_node != 0) error_stop_value = ( scanner_node->get_run_state()->error_stop_mode --- 4485,4489 ---- bool error_stop_value; ! if (scanner_node != static_cast(0)) error_stop_value = ( scanner_node->get_run_state()->error_stop_mode *************** *** 4657,4661 **** ! if (object != 0) { --- 4669,4673 ---- ! if (object != static_cast(0)) { *************** *** 5037,5042 **** else if (type == COLOR_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5049,5054 ---- else if (type == COLOR_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5044,5048 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5056,5060 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5058,5062 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == COLOR_VECTOR)| */ --- 5070,5074 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == COLOR_VECTOR)| */ *************** *** 5077,5082 **** else if (type == POINT_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5089,5094 ---- else if (type == POINT_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5085,5089 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5097,5101 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5100,5104 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == POINT_VECTOR)| */ --- 5112,5116 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == POINT_VECTOR)| */ *************** *** 5119,5124 **** else if (type == BOOL_POINT_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5131,5136 ---- else if (type == BOOL_POINT_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5126,5130 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5138,5142 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5141,5145 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == BOOL_POINT_VECTOR)| */ --- 5153,5157 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == BOOL_POINT_VECTOR)| */ *************** *** 5161,5166 **** else if (type == PATH_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5173,5178 ---- else if (type == PATH_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5168,5172 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5180,5184 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5183,5187 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == PATH_VECTOR)| */ --- 5195,5199 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == PATH_VECTOR)| */ *************** *** 5201,5206 **** else if (type == ELLIPSE_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5213,5218 ---- else if (type == ELLIPSE_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5208,5212 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5220,5224 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5223,5227 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == ELLIPSE_VECTOR)| */ --- 5235,5239 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == ELLIPSE_VECTOR)| */ *************** *** 5242,5247 **** else if (type == CIRCLE_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5254,5259 ---- else if (type == CIRCLE_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5249,5253 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5261,5265 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5264,5268 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == CIRCLE_VECTOR)| */ --- 5276,5280 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == CIRCLE_VECTOR)| */ *************** *** 5282,5287 **** else if (type == PARABOLA_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5294,5299 ---- else if (type == PARABOLA_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5289,5293 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5301,5305 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5304,5308 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == PARABOLA_VECTOR)| */ --- 5316,5320 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == PARABOLA_VECTOR)| */ *************** *** 5322,5327 **** else if (type == HYPERBOLA_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5334,5339 ---- else if (type == HYPERBOLA_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5329,5333 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5341,5345 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5344,5348 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == HYPERBOLA_VECTOR)| */ --- 5356,5360 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == HYPERBOLA_VECTOR)| */ *************** *** 5362,5367 **** else if (type == ARC_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5374,5379 ---- else if (type == ARC_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5369,5373 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5381,5385 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5384,5388 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == ARC_VECTOR)| */ --- 5396,5400 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == ARC_VECTOR)| */ *************** *** 5404,5409 **** else if (type == CONIC_SECTION_LATTICE_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5416,5421 ---- else if (type == CONIC_SECTION_LATTICE_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5411,5415 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5423,5427 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5426,5430 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == CONIC_SECTION_LATTICE_VECTOR)| */ --- 5438,5442 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == CONIC_SECTION_LATTICE_VECTOR)| */ *************** *** 5445,5450 **** else if (type == HELIX_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5457,5462 ---- else if (type == HELIX_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5452,5456 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5464,5468 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5467,5471 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == HELIX_VECTOR)| */ --- 5479,5483 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == HELIX_VECTOR)| */ *************** *** 5485,5490 **** else if (type == POLYGON_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5497,5502 ---- else if (type == POLYGON_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5492,5496 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5504,5508 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5507,5511 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == POLYGON_VECTOR)| */ --- 5519,5523 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == POLYGON_VECTOR)| */ *************** *** 5525,5530 **** else if (type == RECTANGLE_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5537,5542 ---- else if (type == RECTANGLE_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5532,5536 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5544,5548 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5547,5551 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == RECTANGLE_VECTOR)| */ --- 5559,5563 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == RECTANGLE_VECTOR)| */ *************** *** 5565,5570 **** else if (type == REG_POLYGON_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5577,5582 ---- else if (type == REG_POLYGON_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5572,5576 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5584,5588 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5587,5591 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == REG_POLYGON_VECTOR)| */ --- 5599,5603 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == REG_POLYGON_VECTOR)| */ *************** *** 5606,5611 **** else if (type == CONE_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5618,5623 ---- else if (type == CONE_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5613,5617 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5625,5629 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5628,5632 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == CONE_VECTOR)| */ --- 5640,5644 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == CONE_VECTOR)| */ *************** *** 5647,5652 **** else if (type == CYLINDER_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5659,5664 ---- else if (type == CYLINDER_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5654,5658 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5666,5670 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5669,5673 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == CYLINDER_VECTOR)| */ --- 5681,5685 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == CYLINDER_VECTOR)| */ *************** *** 5690,5695 **** else if (type == CUBOID_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5702,5707 ---- else if (type == CUBOID_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5697,5701 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5709,5713 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5712,5716 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == CUBOID_VECTOR)| */ --- 5724,5728 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == CUBOID_VECTOR)| */ *************** *** 5731,5736 **** else if (type == ELLIPSOID_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5743,5748 ---- else if (type == ELLIPSOID_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5738,5742 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5750,5754 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5753,5757 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == ELLIPSOID_VECTOR)| */ --- 5765,5769 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == ELLIPSOID_VECTOR)| */ *************** *** 5772,5777 **** else if (type == SPHERE_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5784,5789 ---- else if (type == SPHERE_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5779,5783 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5791,5795 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5794,5798 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == SPHERE_VECTOR)| */ --- 5806,5810 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == SPHERE_VECTOR)| */ *************** *** 5812,5817 **** else if (type == PARABOLOID_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5824,5829 ---- else if (type == PARABOLOID_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5819,5823 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5831,5835 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5834,5838 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == PARABOLOID_VECTOR)| */ --- 5846,5850 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == PARABOLOID_VECTOR)| */ *************** *** 5853,5858 **** else if (type == HYPERBOLOID_VECTOR) { ! if (verbose && object == 0) ! cerr_strm << "object == 0."; else --- 5865,5870 ---- else if (type == HYPERBOLOID_VECTOR) { ! if (verbose && object == static_cast(0)) ! cerr_strm << "object == static_cast(0)."; else *************** *** 5860,5864 **** if (verbose) { ! cerr_strm << "object != 0."; log_message(cerr_strm); --- 5872,5876 ---- if (verbose) { ! cerr_strm << "object != static_cast(0)."; log_message(cerr_strm); *************** *** 5875,5879 **** ! } /* |else| (|object != 0|) */ } /* |else if (type == HYPERBOLOID_VECTOR)| */ --- 5887,5891 ---- ! } /* |else| (|object != static_cast(0)|) */ } /* |else if (type == HYPERBOLOID_VECTOR)| */ *************** *** 5895,5904 **** } ! } /* |if (object != 0)| */ ! @q **** (4) |object == 0|. Can't show it.@> ! @ |object == 0|. Can't show it. \initials{LDF 2004.10.26.} --- 5907,5916 ---- } ! } /* |if (object != static_cast(0))| */ ! @q **** (4) |object == static_cast(0)|. Can't show it.@> ! @ |object == static_cast(0)|. Can't show it. \initials{LDF 2004.10.26.} *************** *** 5906,5912 **** ! else if (verbose) /* (|object == 0|) */ { ! cerr_strm << "object == 0. Can't show it."; log_message(cerr_strm); --- 5918,5924 ---- ! else if (verbose) /* (|object == static_cast(0)|) */ { ! cerr_strm << "object == static_cast(0). Can't show it."; log_message(cerr_strm); *************** *** 5914,5918 **** cerr_strm.str(""); ! } /* |else if (verbose)| (|object == 0|) */ @q **** (4)@> --- 5926,5930 ---- cerr_strm.str(""); ! } /* |else if (verbose)| (|object == static_cast(0)|) */ @q **** (4)@> *************** *** 5924,5928 **** { ! if (up == 0) cerr_strm << "up == 0"; else --- 5936,5940 ---- { ! if (up == static_cast(0)) cerr_strm << "up == 0"; else *************** *** 5933,5937 **** cerr_strm.str(""); ! if (left == 0) cerr_strm << "left == 0"; else --- 5945,5949 ---- cerr_strm.str(""); ! if (left == static_cast(0)) cerr_strm << "left == 0"; else *************** *** 5949,5953 **** ! if (right == 0) cerr_strm << "right == 0"; else --- 5961,5965 ---- ! if (right == static_cast(0)) cerr_strm << "right == 0"; else *************** *** 5965,5969 **** ! if (superordinate_vector == 0) cerr_strm << "superordinate_vector == 0"; --- 5977,5981 ---- ! if (superordinate_vector == static_cast(0)) cerr_strm << "superordinate_vector == 0"; *************** *** 5974,5978 **** ! if (subordinate_array == 0) cerr_strm << "subordinate_array == 0"; --- 5986,5990 ---- ! if (subordinate_array == static_cast(0)) cerr_strm << "subordinate_array == 0"; *************** *** 5990,5999 **** @= ! if (traverse && left != 0) { left->show(left->name, true); } ! if (traverse && right != 0) { right->show(right->name, true); --- 6002,6011 ---- @= ! if (traverse && left != static_cast(0)) { left->show(left->name, true); } ! if (traverse && right != static_cast(0)) { right->show(right->name, true); diff -rc2P 3DLDF-2.0.2/src/io.web 3DLDF-2.0.3/src/io.web *** 3DLDF-2.0.2/src/io.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/io.web Fri Dec 13 15:42:52 2013 *************** *** 272,276 **** if (DEBUG) cerr << "Entering `Io_Struct::~Io_Struct()'." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 272,276 ---- if (DEBUG) cerr << "Entering `Io_Struct::~Io_Struct()'." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 279,283 **** if (DEBUG) cerr << "Exiting `Io_Struct::~Io_Struct()'." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 279,283 ---- if (DEBUG) cerr << "Exiting `Io_Struct::~Io_Struct()'." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 342,347 **** Input_Struct::Input_Struct(void) { ! stream_ptr = 0; ! up = 0; } --- 342,347 ---- Input_Struct::Input_Struct(void) { ! stream_ptr = static_cast(0); ! up = static_cast(0); } *************** *** 400,404 **** if (DEBUG) cerr << "Entering `Input_Struct' destructor." ! << "\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 400,404 ---- if (DEBUG) cerr << "Entering `Input_Struct' destructor." ! << "\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 411,415 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "Closing " << filename << ".\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 411,415 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "Closing " << filename << ".\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 420,435 **** ! if (type == FILE_TYPE && stream_ptr != 0) { #if DEBUG_COMPILE if (DEBUG) cerr << "Deleting stream_ptr and pointing it at 0" ! << ".\n" << flush; #endif /* |DEBUG_COMPILE| */@; delete (stream_ptr); ! stream_ptr = 0; ! } /* |if (type == FILE_TYPE && stream_ptr != 0)| */ --- 420,435 ---- ! if (type == FILE_TYPE && stream_ptr != static_cast(0)) { #if DEBUG_COMPILE if (DEBUG) cerr << "Deleting stream_ptr and pointing it at 0" ! << ".\n"; #endif /* |DEBUG_COMPILE| */@; delete (stream_ptr); ! stream_ptr = static_cast(0); ! } /* |if (type == FILE_TYPE && stream_ptr != static_cast(0))| */ *************** *** 461,465 **** #if 0 ! while (up != 0) { --- 461,465 ---- #if 0 ! while (up != static_cast(0)) { *************** *** 468,472 **** { cerr << "`up' " << j++ << " is non-null. Deleting" ! << "\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 468,472 ---- { cerr << "`up' " << j++ << " is non-null. Deleting" ! << "\n"; } #endif /* |DEBUG_COMPILE| */@; *************** *** 475,479 **** up = i->up; delete i; ! i = 0; } #endif --- 475,479 ---- up = i->up; delete i; ! i = static_cast(0); } #endif *************** *** 491,506 **** @= ! if (type == SCANTOKENS_STRING_TYPE && stream_ptr != 0) { #if DEBUG_COMPILE if (DEBUG) cerr << "Deleting stream_ptr and pointing it at 0" ! << ".\n" << flush; #endif /* |DEBUG_COMPILE| */@; delete (stream_ptr); ! stream_ptr = 0; ! } /* |if (type == SCANTOKENS_STRING_TYPE && stream_ptr != 0)| */ --- 491,506 ---- @= ! if (type == SCANTOKENS_STRING_TYPE && stream_ptr != static_cast(0)) { #if DEBUG_COMPILE if (DEBUG) cerr << "Deleting stream_ptr and pointing it at 0" ! << ".\n"; #endif /* |DEBUG_COMPILE| */@; delete (stream_ptr); ! stream_ptr = static_cast(0); ! } /* |if (type == SCANTOKENS_STRING_TYPE && stream_ptr != static_cast(0))| */ *************** *** 517,527 **** @= ! if (type == MACRO_STRING_TYPE && stream_ptr != 0) { delete stream_ptr; ! stream_ptr = 0; ! } /* |if (type == MACRO_STRING_TYPE && stream_ptr != 0)| */ --- 517,527 ---- @= ! if (type == MACRO_STRING_TYPE && stream_ptr != static_cast(0)) { delete stream_ptr; ! stream_ptr = static_cast(0); ! } /* |if (type == MACRO_STRING_TYPE && stream_ptr != static_cast(0))| */ *************** *** 540,544 **** { cerr << "Exiting `Input_Struct' destructor." ! << "\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 540,544 ---- { cerr << "Exiting `Input_Struct' destructor." ! << "\n"; } #endif /* |DEBUG_COMPILE| */@; *************** *** 604,608 **** Output_Struct::Output_Struct(void) { ! stream_ptr = 0; } --- 604,608 ---- Output_Struct::Output_Struct(void) { ! stream_ptr = static_cast(0); } *************** *** 636,640 **** if (DEBUG) cerr << "Entering `Output_Struct' destructor." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 636,640 ---- if (DEBUG) cerr << "Entering `Output_Struct' destructor." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 646,650 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "Closing " << filename << ".\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 646,650 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "Closing " << filename << ".\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 653,657 **** } /* |if (type == FILE_TYPE)| */@; ! if (stream_ptr != 0) { --- 653,657 ---- } /* |if (type == FILE_TYPE)| */@; ! if (stream_ptr != static_cast(0)) { *************** *** 659,663 **** if (DEBUG) cerr << "Deleting `stream_ptr' and pointing it at 0." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 659,663 ---- if (DEBUG) cerr << "Deleting `stream_ptr' and pointing it at 0." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 1012,1016 **** friend class Id_Map_Type; friend class Scanner_Type; ! friend int yyparse(void*); @<|friend| declarations for functions in |namespace Scan_Parse|@>@; --- 1012,1016 ---- friend class Id_Map_Type; friend class Scanner_Type; ! friend int yyparse(yyscan_t); @<|friend| declarations for functions in |namespace Scan_Parse|@>@; *************** *** 1714,1718 **** friend class Scanner_Type; friend class Id_Map_Entry_Type; ! friend int yyparse(void*); --- 1714,1718 ---- friend class Scanner_Type; friend class Id_Map_Entry_Type; ! friend int yyparse(yyscan_t); *************** *** 1798,1802 **** n = iter->second; ! if (n != 0) { --- 1798,1802 ---- n = iter->second; ! if (n != static_cast(0)) { *************** *** 1835,1839 **** n = 0; ! } /* |if (n != 0)| */ } /* |for| */ --- 1835,1839 ---- n = 0; ! } /* |if (n != static_cast(0))| */ } /* |for| */ *************** *** 1850,1854 **** ! if (up != 0) { #if DEBUG_COMPILE --- 1850,1854 ---- ! if (up != static_cast(0)) { #if DEBUG_COMPILE *************** *** 1868,1876 **** up = 0; ! } /* |if (up != 0)| */ #if DEBUG_COMPILE ! else if (DEBUG) /* (|up == 0|) */ { cerr_strm << thread_name << "In `Id_Map_Type' destructor:" --- 1868,1876 ---- up = 0; ! } /* |if (up != static_cast(0))| */ #if DEBUG_COMPILE ! else if (DEBUG) /* (|up == static_cast(0)|) */ { cerr_strm << thread_name << "In `Id_Map_Type' destructor:" *************** *** 1882,1886 **** cerr_strm.str(""); ! } /* |else| (|up == 0|) */ #endif /* |DEBUG_COMPILE| */@; --- 1882,1886 ---- cerr_strm.str(""); ! } /* |else| (|up == static_cast(0)|) */ #endif /* |DEBUG_COMPILE| */@; *************** *** 1940,1944 **** s = "Id_Map_Type:"; ! cerr << s << endl << "id_map:" << endl << flush; for (Id_Map_Const_Iterator iter = id_map.begin(); --- 1940,1944 ---- s = "Id_Map_Type:"; ! cerr << s << endl << "id_map:" << endl; for (Id_Map_Const_Iterator iter = id_map.begin(); *************** *** 1956,1964 **** } /* |for| */@; ! if (up == 0) cerr << "up == 0\n"; else { ! cerr << "up != 0. Showing up." << endl << flush; up->show(); } --- 1956,1964 ---- } /* |for| */@; ! if (up == static_cast(0)) cerr << "up == 0\n"; else { ! cerr << "up != 0. Showing up." << endl; up->show(); } *************** *** 2159,2163 **** limit_value = 0; ! if (loop_strm_ptr != 0) delete loop_strm_ptr; --- 2159,2163 ---- limit_value = 0; ! if (loop_strm_ptr != static_cast(0)) delete loop_strm_ptr; *************** *** 2560,2564 **** friend class Rhombic_Triacontahedron; ! friend int yyparse(void*); friend int main(int, char**); --- 2560,2564 ---- friend class Rhombic_Triacontahedron; ! friend int yyparse(yyscan_t); friend int main(int, char**); *************** *** 3102,3106 **** if (DEBUG) cerr << "Entering Scanner_Type::open_default_out_file()" << endl ! << "format == " << format << endl << flush; --- 3102,3106 ---- if (DEBUG) cerr << "Entering Scanner_Type::open_default_out_file()" << endl ! << "format == " << format << endl; *************** *** 3137,3141 **** cerr << "ERROR! In Scanner_Type::open_default_out_file():\n" << "Invalid `format\' argument: " << format << endl ! << "Returning `false\'." << endl << endl << flush; return false; } --- 3137,3141 ---- cerr << "ERROR! In Scanner_Type::open_default_out_file():\n" << "Invalid `format\' argument: " << format << endl ! << "Returning `false\'." << endl << endl; return false; } *************** *** 3152,3157 **** cerr << "ERROR! In Scanner_Type::open_default_out_file():" << "Opening " << filename ! << " failed! Returning false.\n\n" ! << flush; return false; } --- 3152,3157 ---- cerr << "ERROR! In Scanner_Type::open_default_out_file():" << "Opening " << filename ! << " failed! Returning false.\n\n"; ! return false; } *************** *** 3166,3170 **** << " succeeded! returning `true\'" << endl << "Exiting Scanner_Type::open_default_out_file()" << endl ! << endl << flush; return true; } /* |else| */@; --- 3166,3170 ---- << " succeeded! returning `true\'" << endl << "Exiting Scanner_Type::open_default_out_file()" << endl ! << endl; return true; } /* |else| */@; *************** *** 3173,3178 **** { cerr << conditional_string << " == false. Returning `false\'.\n" ! << "Exiting Scanner_Type::open_default_out_file()" << endl ! << flush; return false; } --- 3173,3178 ---- { cerr << conditional_string << " == false. Returning `false\'.\n" ! << "Exiting Scanner_Type::open_default_out_file()" << endl; ! return false; } *************** *** 3392,3401 **** { bool DEBUG = false; /* |true| */ @; ! if (in == 0) { if (!silent || DEBUG) cerr << "WARNING! In Scanner_Type::get_in_filename():\n" << "Scanner_Type.in is a null pointer. Returning " ! << "empty string.\n" << flush; return ""; } --- 3392,3401 ---- { bool DEBUG = false; /* |true| */ @; ! if (in == static_cast(0)) { if (!silent || DEBUG) cerr << "WARNING! In Scanner_Type::get_in_filename():\n" << "Scanner_Type.in is a null pointer. Returning " ! << "empty string.\n"; return ""; } *************** *** 3404,3408 **** if (DEBUG) cerr << "In Scanner_Type::get_in_filename():\n" ! << "returning " << in->filename << ".\n" << flush; return in->filename; } --- 3404,3408 ---- if (DEBUG) cerr << "In Scanner_Type::get_in_filename():\n" ! << "returning " << in->filename << ".\n"; return in->filename; } *************** *** 3465,3469 **** { ! if (in->up == 0) { cerr_mutex.lock(); --- 3465,3469 ---- { ! if (in->up == static_cast(0)) { cerr_mutex.lock(); *************** *** 3476,3486 **** return 1; ! } /* |if (in->up == 0)| */ Input_Struct* i = in; in = in->up; ! i->up = 0; delete i; ! i = 0; return 0; --- 3476,3486 ---- return 1; ! } /* |if (in->up == static_cast(0))| */ Input_Struct* i = in; in = in->up; ! i->up = static_cast(0); delete i; ! i = static_cast(0); return 0; *************** *** 3857,3861 **** #endif /* |DEBUG_COMPILE| */@; ! if (root == 0) { --- 3857,3861 ---- #endif /* |DEBUG_COMPILE| */@; ! if (root == static_cast(0)) { *************** *** 3872,3881 **** return static_cast(0); ! } /* |if (root == 0)| */ int curr_type = root->type; ! @q ****** (6) |root->left == 0|.@> ! @ |root->left == 0|. \initials{LDF Undated.} --- 3872,3881 ---- return static_cast(0); ! } /* |if (root == static_cast(0))| */ int curr_type = root->type; ! @q ****** (6) |root->left == static_cast(0)|.@> ! @ |root->left == static_cast(0)|. \initials{LDF Undated.} *************** *** 3888,3892 **** @= ! if (root->left == 0 && create_if_none) { --- 3888,3892 ---- @= ! if (root->left == static_cast(0) && create_if_none) { *************** *** 3938,3945 **** return root->left; ! } /* |if (root->left == 0)| */ ! @q ****** (6) |root->left == 0 && !create_if_none|.@> ! @ |root->left == 0 && !create_if_none|. \initials{LDF 2005.01.08.} --- 3938,3945 ---- return root->left; ! } /* |if (root->left == static_cast(0))| */ ! @q ****** (6) |root->left == static_cast(0) && !create_if_none|.@> ! @ |root->left == static_cast(0) && !create_if_none|. \initials{LDF 2005.01.08.} *************** *** 3951,3955 **** @= ! else if (root->left == 0 && !create_if_none) { #if DEBUG_COMPILE --- 3951,3955 ---- @= ! else if (root->left == static_cast(0) && !create_if_none) { #if DEBUG_COMPILE *************** *** 3970,3981 **** return 0; ! } /* |else if (root->left == 0 && !create_if_none)| */ ! @q ****** (6) |root->left != 0|.@> ! @ |root->left != 0|. @= ! else /* (|root->left != 0|) */ { --- 3970,3982 ---- return 0; ! } /* |else if ( root->left == static_cast(0) ! && !create_if_none)| */ ! @q ****** (6) |root->left != static_cast(0)|.@> ! @ |root->left != static_cast(0)|. @= ! else /* (|root->left != static_cast(0)|) */ { *************** *** 4053,4063 **** ! @q ****** (6) |(root->left == 0)|.@> ! @ |(root->left == 0)|. \initials{LDF 2004.08.23.} @= ! if (root->left == 0) { --- 4054,4064 ---- ! @q ****** (6) |(root->left == static_cast(0)|.@> ! @ |(root->left == static_cast(0))|. \initials{LDF 2004.08.23.} @= ! if (root->left == static_cast(0)) { *************** *** 4111,4124 **** ! } /* |if (root->left == 0)| */@; ! @q ****** (6) |(root->left != 0)|.@> ! @ |(root->left != 0)|. \initials{LDF 2004.08.23.} @= ! else /* |if (root->left != 0)| */@; { --- 4112,4125 ---- ! } /* |if (root->left == static_cast(0))| */@; ! @q ****** (6) |(root->left != static_cast(0))|.@> ! @ |(root->left != static_cast(0))|. \initials{LDF 2004.08.23.} @= ! else /* |if (root->left != static_cast(0))| */@; { *************** *** 4140,4144 **** continue; ! } /* |else| (|root->left != 0|) */@; } /* |if (s < root->name)| */@; --- 4141,4145 ---- continue; ! } /* |else| (|root->left != static_cast(0)|) */@; } /* |if (s < root->name)| */@; *************** *** 4157,4168 **** ! @q ****** (6) |root->right == 0|.@> ! @ |root->right == 0|. \initials{LDF 2004.08.23.} @= ! if (root->right == 0) { --- 4158,4169 ---- ! @q ****** (6) |root->right == static_cast(0)|.@> ! @ |root->right == static_cast(0)|. \initials{LDF 2004.08.23.} @= ! if (root->right == static_cast(0)) { *************** *** 4212,4221 **** return root->right; ! } /* |if (root->right == 0)| */@; ! @q ****** (6) |root->right != 0|.@> ! @ |root->right != 0|. \initials{LDF 2004.08.23.} --- 4213,4222 ---- return root->right; ! } /* |if (root->right == static_cast(0))| */@; ! @q ****** (6) |root->right != static_cast(0)|.@> ! @ |root->right != static_cast(0)|. \initials{LDF 2004.08.23.} *************** *** 4223,4227 **** ! else /* |root->right != 0| */ { #if DEBUG_COMPILE --- 4224,4228 ---- ! else /* |root->right != static_cast(0)| */ { #if DEBUG_COMPILE *************** *** 4242,4246 **** root = root->right; continue; ! } /* |else| (|root->right != 0|) */ } /* |else if (s > root->name)| */ --- 4243,4247 ---- root = root->right; continue; ! } /* |else| (|root->right != static_cast(0)|) */ } /* |else if (s > root->name)| */ *************** *** 4248,4252 **** } /* |for| */ ! } /* |else| (|root->left != 0|) */ } /* End of |Scanner_Type::get_array_entry| definition. */ --- 4249,4253 ---- } /* |for| */ ! } /* |else| (|root->left != static_cast(0)|) */ } /* End of |Scanner_Type::get_array_entry| definition. */ *************** *** 4345,4349 **** cerr << s << ":" << endl; ! if (in == 0) cerr << "in == 0" << endl; else --- 4346,4350 ---- cerr << s << ":" << endl; ! if (in == static_cast(0)) cerr << "in == 0" << endl; else *************** *** 4352,4360 **** for (int i = Run_State::METAPOST; i <= Run_State::LIBPLOT; ++i) { ! if (out[i] == 0) cerr << "out[" << i << "] == 0" << endl; else cerr << "out[" << i << "]->filename == " << out[i]->filename ! << endl << flush; } --- 4353,4361 ---- for (int i = Run_State::METAPOST; i <= Run_State::LIBPLOT; ++i) { ! if (out[i] == static_cast(0)) cerr << "out[" << i << "] == 0" << endl; else cerr << "out[" << i << "]->filename == " << out[i]->filename ! << endl; } *************** *** 6184,6188 **** #ifndef LDF_IO_H_KNOWN #define LDF_IO_H_KNOWN ! int yyparse(void*); @@; @@; --- 6185,6189 ---- #ifndef LDF_IO_H_KNOWN #define LDF_IO_H_KNOWN ! int yyparse(yyscan_t); @@; @@; Only in 3DLDF-2.0.2/src: lib3dldfsp.c diff -rc2P 3DLDF-2.0.2/src/lines.web 3DLDF-2.0.3/src/lines.web *** 3DLDF-2.0.2/src/lines.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/lines.web Thu Dec 12 20:37:05 2013 *************** *** 700,704 **** @q ***** (5).@> ! if (u_z != 0) { --- 700,704 ---- @q ***** (5).@> ! if (u_z != ZERO_REAL) { *************** *** 719,728 **** / u_z; ! } /* |if (u_z != 0)| */ @q ***** (5).@> ! else if (u_x != 0) { --- 719,728 ---- / u_z; ! } /* |if (u_z != ZERO_REAL)| */ @q ***** (5).@> ! else if (u_x != ZERO_REAL) { *************** *** 742,751 **** / u_x; ! } /* |else if (u_x != 0)| */ @q ***** (5).@> ! else if (u_y != 0) { --- 742,751 ---- / u_x; ! } /* |else if (u_x != ZERO_REAL)| */ @q ***** (5).@> ! else if (u_y != ZERO_REAL) { *************** *** 767,771 **** / u_y; ! } /* |else if (u_y != 0)| */ @q ***** (5).@> --- 767,771 ---- / u_y; ! } /* |else if (u_y != ZERO_REAL)| */ @q ***** (5).@> *************** *** 971,981 **** if (DEBUG) { ! cerr << "brp.b == " << brp.b << endl << flush; ! cerr << "brp.r == " << brp.r << endl << flush; brp.pt.show("brp.pt"); } ! if (brp.r != 0 || brp.b == false || brp.pt == INVALID_POINT) return INVALID_BOOL_POINT; --- 971,981 ---- if (DEBUG) { ! cerr << "brp.b == " << brp.b << endl; ! cerr << "brp.r == " << brp.r << endl; brp.pt.show("brp.pt"); } ! if (brp.r != ZERO_REAL || brp.b == false || brp.pt == INVALID_POINT) return INVALID_BOOL_POINT; *************** *** 989,996 **** if (DEBUG) { ! cerr << "br_p.first == " << br_p.first << endl << flush; ! cerr << "br_p.second == " << br_p.second << endl << flush; ! cerr << "br_q.first == " << br_q.first << endl << flush; ! cerr << "br_q.second == " << br_q.second << endl << flush; } --- 989,996 ---- if (DEBUG) { ! cerr << "br_p.first == " << br_p.first << endl; ! cerr << "br_p.second == " << br_p.second << endl; ! cerr << "br_q.first == " << br_q.first << endl; ! cerr << "br_q.second == " << br_q.second << endl; } diff -rc2P 3DLDF-2.0.2/src/main.web 3DLDF-2.0.3/src/main.web *** 3DLDF-2.0.2/src/main.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/main.web Thu Dec 12 20:38:07 2013 *************** *** 185,190 **** --- 185,192 ---- #include "prrfnc0.h++" + #if 0 #include "parser2.h++" #include "scanner2.h++" + #endif @q * (1) Scanning and parsing input.@> *************** *** 203,210 **** @= int ! yyparse (void*); int ! zzparse (void*); @q ** yywrap. @> --- 205,214 ---- @= int ! yyparse(yyscan_t); + #if 0 int ! zzparse (yyscan_t); ! #endif @q ** yywrap. @> *************** *** 323,327 **** @= { ! bool DEBUG = true; /* |false| */ int option_ctr; int digit_optind = 0; --- 327,331 ---- @= { ! bool DEBUG = false; /* |true| */ int option_ctr; int digit_optind = 0; *************** *** 393,397 **** if (optarg) cerr << "optarg == " << optarg << endl; - cerr << flush; } #endif --- 397,400 ---- *************** *** 1062,1066 **** curr_scanner_node = Scanner_Type::create(s, run_state_initial, true); ! if (curr_scanner_node == 0) { cerr << "ERROR! In main(): " --- 1065,1069 ---- curr_scanner_node = Scanner_Type::create(s, run_state_initial, true); ! if (curr_scanner_node == static_cast(0)) { cerr << "ERROR! In main(): " *************** *** 1319,1323 **** } /* |if ( vector_size == 0)| */ @; ! @q *** At least one filename argument. @> @ At least one filename argument. --- 1322,1326 ---- } /* |if ( vector_size == 0)| */ @; ! @q *** (3) At least one filename argument. @> @ At least one filename argument. diff -rc2P 3DLDF-2.0.2/src/matrices.web 3DLDF-2.0.3/src/matrices.web *** 3DLDF-2.0.2/src/matrices.web Thu Nov 7 13:36:08 2013 --- 3DLDF-2.0.3/src/matrices.web Thu Dec 12 20:38:43 2013 *************** *** 863,867 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 863,867 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 1063,1067 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 1063,1067 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 3160,3164 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 3160,3164 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 3175,3179 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 3175,3179 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; diff -rc2P 3DLDF-2.0.2/src/mtrxassn.w 3DLDF-2.0.3/src/mtrxassn.w *** 3DLDF-2.0.2/src/mtrxassn.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/mtrxassn.w Thu Dec 12 14:29:25 2013 *************** *** 123,127 **** } ! @=$$@> = 0; }; --- 123,127 ---- } ! @=$$@> = static_cast(0); }; *************** *** 167,171 **** #endif ! @=$$@> = 0; }; --- 167,171 ---- #endif ! @=$$@> = static_cast(0); }; *************** *** 202,206 **** } ! @=$$@> = 0; }; --- 202,206 ---- } ! @=$$@> = static_cast(0); }; *************** *** 236,240 **** } ! @=$$@> = 0; }; --- 236,240 ---- } ! @=$$@> = static_cast(0); }; *************** *** 270,274 **** } ! @=$$@> = 0; }; --- 270,274 ---- } ! @=$$@> = static_cast(0); }; *************** *** 305,309 **** } ! @=$$@> = 0; }; --- 305,309 ---- } ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/mtrxexpr.w 3DLDF-2.0.3/src/mtrxexpr.w *** 3DLDF-2.0.2/src/mtrxexpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/mtrxexpr.w Thu Dec 12 20:40:32 2013 *************** *** 88,103 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { @=$$@> = static_cast(0); ! } /* |if (entry == 0 || entry->object == 0)| */ ! else /* |entry != 0 && entry->object != 0| */ ! ! @=$$@> = static_cast(create_new( static_cast( entry->object))); }; --- 88,106 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { @=$$@> = static_cast(0); ! } /* |if ( entry == static_cast(0) ! || entry->object == static_cast(0))| */ ! else ! { ! @=$$@> = static_cast(create_new( static_cast( entry->object))); + } + }; *************** *** 147,165 **** = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == 0|.@> ! @ Error handling: |pv == 0|. \initials{LDF 2007.11.28.} @= ! if (pv == 0) { delete c; ! @=$$@> = 0; ! } /* |if (pv == 0)| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> --- 150,168 ---- = static_cast*>(@=$2@>); ! @q ******* (7) Error handling: |pv == static_cast*>(0)|.@> ! @ Error handling: |pv == static_cast*>(0)|. \initials{LDF 2007.11.28.} @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); ! } /* |if (pv == static_cast*>(0))| */ @q ******* (7) Error handling: |pv->ctr == 0|.@> *************** *** 174,184 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ ! @q ******* (7) |pv != 0 && pv->ctr > 0|.@> ! @ |pv != 0 && pv->ctr > 0|. Set |@=$$@>| to |*(pv->v[pv->ctr - 1])|. \initials{LDF 2007.11.28.} --- 177,188 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ ! @q ******* (7) |pv != static_cast*>(0) && pv->ctr > 0|.@> ! @ |pv != static_cast*>(0) && pv->ctr > 0|. ! Set |@=$$@>| to |*(pv->v[pv->ctr - 1])|. \initials{LDF 2007.11.28.} diff -rc2P 3DLDF-2.0.2/src/mtrxvxpr.w 3DLDF-2.0.3/src/mtrxvxpr.w *** 3DLDF-2.0.2/src/mtrxvxpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/mtrxvxpr.w Fri Dec 13 12:04:41 2013 *************** *** 114,118 **** @= ! if (entry == 0 || entry->object == 0) { --- 114,118 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 131,135 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 131,135 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/nurbs.web 3DLDF-2.0.3/src/nurbs.web *** 3DLDF-2.0.2/src/nurbs.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/nurbs.web Thu Dec 12 20:42:21 2013 *************** *** 1643,1647 **** Nurb::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; --- 1643,1647 ---- Nurb::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; *************** *** 1689,1693 **** Nurb::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 1689,1693 ---- Nurb::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 1735,1742 **** Nurb::push_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 1735,1742 ---- Nurb::push_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 1785,1789 **** Nurb::push_pen(Pen*& p, bool copy) { ! if (pen_vector == 0) pen_vector = new Pointer_Vector; --- 1785,1789 ---- Nurb::push_pen(Pen*& p, bool copy) { ! if (pen_vector == static_cast*>(0)) pen_vector = new Pointer_Vector; *************** *** 1829,1833 **** Nurb::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == 0) dash_pattern_vector = new Pointer_Vector; --- 1829,1833 ---- Nurb::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == static_cast*>(0)) dash_pattern_vector = new Pointer_Vector; *************** *** 1915,1919 **** #endif /* |DEBUG_COMPILE| */@; ! @q **** (4) |p == 0|.@> #if DEBUG_COMPILE --- 1915,1919 ---- #endif /* |DEBUG_COMPILE| */@; ! @q **** (4) |p == 0U|.@> #if DEBUG_COMPILE *************** *** 1924,1928 **** #endif /* |DEBUG_COMPILE| */@; ! if (p == 0) { --- 1924,1928 ---- #endif /* |DEBUG_COMPILE| */@; ! if (p == 0U) { *************** *** 1965,1973 **** ! } /* |if (p == 0)| */ ! @q **** (4) |p != 0|.@> ! else /* |p != 0| */ { real coefficient_1; --- 1965,1973 ---- ! } /* |if (p == 0U)| */ ! @q **** (4) |p != 0U|.@> ! else /* |p != 0U| */ { real coefficient_1; *************** *** 1988,1992 **** ! if (coefficient_1 != 0) { coefficient_1 = (u - *(knots[i])) / coefficient_1; --- 1988,1992 ---- ! if (coefficient_1 != ZERO_REAL) { coefficient_1 = (u - *(knots[i])) / coefficient_1; *************** *** 2015,2019 **** ! if (coefficient_2 != 0) { coefficient_2 = (*(knots[i + p + 1]) - u) / coefficient_2; --- 2015,2019 ---- ! if (coefficient_2 != ZERO_REAL) { coefficient_2 = (*(knots[i + p + 1]) - u) / coefficient_2; *************** *** 2037,2041 **** return value_1 + value_2; ! } /* |else| (|p != 0|) */ --- 2037,2041 ---- return value_1 + value_2; ! } /* |else| (|p != 0U|) */ diff -rc2P 3DLDF-2.0.2/src/parabola.web 3DLDF-2.0.3/src/parabola.web *** 3DLDF-2.0.2/src/parabola.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/parabola.web Thu Dec 12 20:52:16 2013 *************** *** 243,248 **** ! @q **** (4) |options == 0|. Use defaults.@> ! @ |options == 0|. Use defaults. \initials{LDF 2005.11.07.} --- 243,248 ---- ! @q **** (4) |options == static_cast(0)|. Use defaults.@> ! @ |options == static_cast(0)|. Use defaults. \initials{LDF 2005.11.07.} *************** *** 250,257 **** ! if (!options) /* Use defaults. Not programmed yet. ! LDF 2005.11.07. */ { vertex_0.set(0, 0, 0); focus_0 = INVALID_POINT; --- 250,259 ---- ! if (options == static_cast(0)) { + /* Use defaults. Not programmed yet. + LDF 2005.11.07. */ + vertex_0.set(0, 0, 0); focus_0 = INVALID_POINT; *************** *** 262,272 **** ! @q **** (4) |options != 0|.@> ! @ |options != 0|. \initials{LDF 2005.11.07.} @= ! else /* |options != 0| */ { --- 264,274 ---- ! @q **** (4) |options != static_cast(0)|.@> ! @ |options != static_cast(0)|. \initials{LDF 2005.11.07.} @= ! else /* |options != static_cast(0)| */ { *************** *** 338,342 **** ! } /* |else| (|options != 0|) */ @q **** (4) Check |focus_0| and |vertex_0| for consistency.@> --- 340,344 ---- ! } /* |else| (|options != static_cast(0)|) */ @q **** (4) Check |focus_0| and |vertex_0| for consistency.@> *************** *** 723,727 **** { ! if (t != 0) t->reset(); } --- 725,729 ---- { ! if (t != static_cast(0)) t->reset(); } *************** *** 743,747 **** @= ! if (u == 0) { cerr_strm << thread_name --- 745,749 ---- @= ! if (u == static_cast(0)) { cerr_strm << thread_name *************** *** 764,768 **** return INVALID_REAL_TRIPLE; ! } /* |if (u == 0)| */ @q ***** (5)@> --- 766,770 ---- return INVALID_REAL_TRIPLE; ! } /* |if (u == static_cast(0))| */ @q ***** (5)@> *************** *** 770,779 **** pth *= *u; ! if (t != 0) *t = u->inverse(); delete u; ! u = 0; } /* |else| (|normal != y_axis_pt|) */ --- 772,781 ---- pth *= *u; ! if (t != static_cast(0)) *t = u->inverse(); delete u; ! u = static_cast(0); } /* |else| (|normal != y_axis_pt|) */ *************** *** 915,919 **** @= ! if (t == 0) { cerr_strm << thread_name --- 917,921 ---- @= ! if (t == static_cast(0)) { cerr_strm << thread_name *************** *** 931,935 **** return -5; ! } /* |if (t == 0)| */ @q **** (4)@> --- 933,937 ---- return -5; ! } /* |if (t == static_cast(0))| */ @q **** (4)@> *************** *** 1586,1590 **** @q **** (4).@> ! if (p == 0) { cerr_strm << thread_name --- 1588,1592 ---- @q **** (4).@> ! if (p == static_cast(0)) { cerr_strm << thread_name *************** *** 1598,1602 **** return 0; ! } /* |if (p == 0)| */ @q **** (4)@> --- 1600,1604 ---- return 0; ! } /* |if (p == static_cast(0))| */ @q **** (4)@> *************** *** 1725,1729 **** @= ! if (slope == 0) { Point temp_pt = p->get_point(0); --- 1727,1731 ---- @= ! if (slope == ZERO_REAL) { Point temp_pt = p->get_point(0); *************** *** 1741,1745 **** *bpv += curr_bool_pt; ! } /* |if (slope == 0)| */ @q ****** (6)@> --- 1743,1747 ---- *bpv += curr_bool_pt; ! } /* |if (slope == ZERO_REAL)| */ @q ****** (6)@> *************** *** 1751,1755 **** @= ! else /* |slope != 0| */ { --- 1753,1757 ---- @= ! else /* |slope != ZERO_REAL| */ { *************** *** 1798,1802 **** @q ******* (7)@> ! } /* |else| (|slope != 0|) */ @q ****** (6)@> --- 1800,1804 ---- @q ******* (7)@> ! } /* |else| (|slope != ZERO_REAL|) */ @q ****** (6)@> *************** *** 1805,1809 **** delete t; ! t = 0; return bpv; --- 1807,1811 ---- delete t; ! t = static_cast(0); return bpv; diff -rc2P 3DLDF-2.0.2/src/parabold.web 3DLDF-2.0.3/src/parabold.web *** 3DLDF-2.0.2/src/parabold.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/parabold.web Wed Dec 11 18:42:22 2013 *************** *** 584,588 **** @q ***** (5) Preliminaries.@> ! bool DEBUG = true; /* |false| */ using namespace Scan_Parse; --- 584,588 ---- @q ***** (5) Preliminaries.@> ! bool DEBUG = false; /* |true| */ using namespace Scan_Parse; diff -rc2P 3DLDF-2.0.2/src/paraellp.web 3DLDF-2.0.3/src/paraellp.web *** 3DLDF-2.0.2/src/paraellp.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/paraellp.web Wed Dec 11 18:42:22 2013 *************** *** 477,481 **** @q ***** (5) Preliminaries.@> ! bool DEBUG = true; /* |false| */ using namespace Scan_Parse; --- 477,481 ---- @q ***** (5) Preliminaries.@> ! bool DEBUG = false; /* |true| */ using namespace Scan_Parse; diff -rc2P 3DLDF-2.0.2/src/parahypr.web 3DLDF-2.0.3/src/parahypr.web *** 3DLDF-2.0.2/src/parahypr.web Wed Nov 6 20:56:25 2013 --- 3DLDF-2.0.3/src/parahypr.web Wed Dec 11 18:42:22 2013 *************** *** 477,481 **** @q ***** (5) Preliminaries.@> ! bool DEBUG = true; /* |false| */ using namespace Scan_Parse; --- 477,481 ---- @q ***** (5) Preliminaries.@> ! bool DEBUG = false; /* |true| */ using namespace Scan_Parse; diff -rc2P 3DLDF-2.0.2/src/passign.w 3DLDF-2.0.3/src/passign.w *** 3DLDF-2.0.2/src/passign.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/passign.w Thu Dec 12 21:00:24 2013 *************** *** 706,721 **** @= ! if (entry == 0) { delete pv; ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ***** (5) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.08.30.} --- 706,721 ---- @= ! if (entry == static_cast(0)) { delete pv; ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ***** (5) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.08.30.} *************** *** 723,727 **** @= ! else /* |entry != 0| */ { --- 723,727 ---- @= ! else /* |entry != static_cast(0)| */ { *************** *** 745,749 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 745,749 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 760,769 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ ! } /* |else| (|entry != 0|) */ --- 760,769 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 832,843 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! else /* |entry != 0| */ { --- 832,843 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! else /* |entry != static_cast(0)| */ { *************** *** 851,855 **** delete pv; ! @=$$@> = 0; } /* |else| */ --- 851,855 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| */ *************** *** 1905,1909 **** Pointer_Vector* pv = static_cast*>(@=$3@>); ! if (pv == 0 || pv->ctr <= 0) { r = INVALID_REAL; --- 1905,1909 ---- Pointer_Vector* pv = static_cast*>(@=$3@>); ! if (pv == static_cast*>(0) || pv->ctr <= 0) { r = INVALID_REAL; *************** *** 2261,2286 **** ! @q ****** (6) Error handling: |entry == 0|.@> ! @ Error handling: |entry == 0|. \initials{LDF 2004.12.30.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.12.30.} @= ! else /* |entry != 0| */ { --- 2261,2286 ---- ! @q ****** (6) Error handling: |entry == static_cast(0)|.@> ! @ Error handling: |entry == static_cast(0)|. \initials{LDF 2004.12.30.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.12.30.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 2288,2292 **** ! @q ******* (7) Error handling: |entry_0 == 0 || entry_0->object == 0|.@> @ Error handling: |entry_0 == 0 || entry_0->object == 0|. \initials{LDF 2004.12.30.} --- 2288,2293 ---- ! @q ******* (7) Error handling: @> ! @q ******* (7) |entry_0 == static_cast(0) || entry_0->object == 0|. @> @ Error handling: |entry_0 == 0 || entry_0->object == 0|. \initials{LDF 2004.12.30.} *************** *** 2294,2303 **** @= ! if (entry_0 == 0 || entry_0->object == 0) { ! @=$$@> = 0; ! } /* |if (entry_0 == 0 || entry_0->object == 0)| */ --- 2295,2305 ---- @= ! if ( entry_0 == static_cast(0) ! || entry_0->object == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if| */ *************** *** 2321,2325 **** @= ! if (entry->object == 0) { --- 2323,2327 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 2329,2347 **** entry->object = static_cast(d); ! } /* |if (entry->object == 0)| */ ! @q ******** (8) |entry->object != 0|.@> ! @ |entry->object == 0|. \initials{LDF 2004.12.30.} @= ! else /* |entry->object != 0| */ { d = static_cast(entry->object); ! } /* |else| (|entry->object != 0|) */ @q ******** (8) @> --- 2331,2349 ---- entry->object = static_cast(d); ! } /* |if (entry->object == static_cast(0))| */ ! @q ******** (8) |entry->object != static_cast(0)|.@> ! @ |entry->object == static_cast(0)|. \initials{LDF 2004.12.30.} @= ! else /* |entry->object != static_cast(0)| */ { d = static_cast(entry->object); ! } /* |else| (|entry->object != static_cast(0)|) */ @q ******** (8) @> *************** *** 2580,2594 **** @= ! if (entry == 0) { @=$$@> = static_cast(0); ! } /* |if (entry == 0)| */ ! @q ******* (7) |entry != 0|.@> @ |entry != 0|. --- 2582,2596 ---- @= ! if (entry == static_cast(0)) { @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ******* (7) |entry != static_cast(0)|.@> @ |entry != 0|. *************** *** 2612,2616 **** @= ! if (bp == 0) { --- 2614,2618 ---- @= ! if (bp == static_cast(0)) { *************** *** 2620,2633 **** ! } /* |if (bp == 0)| */ ! @q ******** (8) |bp != 0|.@> ! @ |bp != 0|. \initials{LDF 2004.11.03.} @= ! else /* |bp != 0| */ { bp->b = bpe->b, --- 2622,2635 ---- ! } /* |if (bp == static_cast(0))| */ ! @q ******** (8) |bp != static_cast(0)|.@> ! @ |bp != static_cast(0)|. \initials{LDF 2004.11.03.} @= ! else /* |bp != static_cast(0)| */ { bp->b = bpe->b, *************** *** 2638,2644 **** @=$$@> = entry->object; ! } /* |else| (|bp != 0|) */ ! } /* |else| (|entry != 0|) */ }; --- 2640,2646 ---- @=$$@> = entry->object; ! } /* |else| (|bp != static_cast(0)|) */ ! } /* |else| (|entry != static_cast(0)|) */ }; *************** *** 2676,2685 **** @= ! if (entry == 0) { delete b; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 2678,2687 ---- @= ! if (entry == static_cast(0)) { delete b; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 2708,2712 **** @= ! if (bp == 0) { --- 2710,2714 ---- @= ! if (bp == static_cast(0)) { *************** *** 2766,2770 **** @= ! if (entry == 0) { --- 2768,2772 ---- @= ! if (entry == static_cast(0)) { *************** *** 2772,2776 **** delete p; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 2774,2778 ---- delete p; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 2798,2802 **** @= ! if (bp == 0) { --- 2800,2804 ---- @= ! if (bp == static_cast(0)) { *************** *** 3998,4005 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 4000,4007 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 4045,4049 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4047,4051 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4107,4114 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 4109,4116 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 4154,4158 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4156,4160 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4216,4223 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 4218,4225 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 4263,4267 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4265,4269 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4334,4341 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 4336,4343 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 4380,4384 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4382,4386 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4452,4470 **** @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.13.} @= ! else /* |entry != 0| */ { --- 4454,4472 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.13.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 4498,4502 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4500,4504 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4518,4522 **** ! } /* |else| (|entry != 0|) */ --- 4520,4524 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 4562,4587 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.01.13.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.13.} @= ! else /* |entry != 0| */ { --- 4564,4589 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.01.13.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.13.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 4617,4621 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4619,4623 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4637,4641 **** ! } /* |else| (|entry != 0|) */ --- 4639,4643 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 4685,4710 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.01.07.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.07.} @= ! else /* |entry != 0| */ { --- 4687,4712 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.01.07.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.07.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 4738,4742 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4740,4744 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4758,4762 **** ! } /* |else| (|entry != 0|) */ --- 4760,4764 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 4802,4827 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.01.13.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.13.} @= ! else /* |entry != 0| */ { --- 4804,4829 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.01.13.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.13.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 4855,4859 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4857,4861 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4875,4879 **** ! } /* |else| (|entry != 0|) */ --- 4877,4881 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 4919,4944 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.01.18.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.18.} @= ! else /* |entry != 0| */ { --- 4921,4946 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.01.18.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.18.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 4972,4976 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4974,4978 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4992,4996 **** ! } /* |else| (|entry != 0|) */ --- 4994,4998 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5056,5081 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.11.06.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.09.01.} @= ! else /* |entry != 0| */ { --- 5058,5083 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.11.06.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.09.01.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 5109,5113 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5111,5115 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5129,5133 **** ! } /* |else| (|entry != 0|) */ --- 5131,5135 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5164,5184 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.11.10.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.11.10.} --- 5166,5186 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.11.10.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.11.10.} *************** *** 5186,5190 **** @= ! else /* |entry != 0| */ { --- 5188,5192 ---- @= ! else /* |entry != static_cast(0)| */ { *************** *** 5219,5223 **** delete bpv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5221,5225 ---- delete bpv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5239,5243 **** ! } /* |else| (|entry != 0|) */ --- 5241,5245 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5296,5316 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.11.06.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.09.01.} --- 5298,5318 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.11.06.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.09.01.} *************** *** 5333,5337 **** @= ! else /* |entry != 0| */ { --- 5335,5339 ---- @= ! else /* |entry != static_cast(0)| */ { *************** *** 5366,5370 **** bpv = 0; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5368,5372 ---- bpv = 0; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5386,5390 **** } /* |else| (|status == 0|) */ ! } /* |else| (|entry != 0|) */ --- 5388,5392 ---- } /* |else| (|status == 0|) */ ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5422,5442 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.11.10.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.11.10.} --- 5424,5444 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.11.10.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.11.10.} *************** *** 5444,5448 **** @= ! else /* |entry != 0| */ { --- 5446,5450 ---- @= ! else /* |entry != static_cast(0)| */ { *************** *** 5476,5480 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5478,5482 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5496,5500 **** ! } /* |else| (|entry != 0|) */ --- 5498,5502 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5539,5564 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.12.10.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.12.10.} @= ! else /* |entry != 0| */ { --- 5541,5566 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.12.10.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.12.10.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 5591,5595 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5593,5597 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5611,5615 **** ! } /* |else| (|entry != 0|) */ --- 5613,5617 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5653,5678 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.12.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.12.14.} @= ! else /* |entry != 0| */ { --- 5655,5680 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.12.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.12.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 5705,5709 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5707,5711 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5725,5729 **** ! } /* |else| (|entry != 0|) */ --- 5727,5731 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5767,5792 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.12.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.12.14.} @= ! else /* |entry != 0| */ { --- 5769,5794 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.12.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.12.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 5819,5823 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5821,5825 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5839,5843 **** ! } /* |else| (|entry != 0|) */ --- 5841,5845 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 5885,5910 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.11.07.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.11.07.} @= ! else /* |entry != 0| */ { --- 5887,5912 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.11.07.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.11.07.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 5939,5943 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5941,5945 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5959,5963 **** ! } /* |else| (|entry != 0|) */ --- 5961,5965 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6004,6029 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.11.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.11.14.} @= ! else /* |entry != 0| */ { --- 6006,6031 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.11.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.11.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6058,6062 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6060,6064 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6078,6082 **** ! } /* |else| (|entry != 0|) */ --- 6080,6084 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6123,6148 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2007.10.13.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2007.10.13.} @= ! else /* |entry != 0| */ { --- 6125,6150 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2007.10.13.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2007.10.13.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6177,6181 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6179,6183 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6197,6201 **** ! } /* |else| (|entry != 0|) */ --- 6199,6203 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6242,6267 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.11.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.11.14.} @= ! else /* |entry != 0| */ { --- 6244,6269 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.11.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.11.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6297,6301 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6299,6303 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6317,6321 **** ! } /* |else| (|entry != 0|) */ --- 6319,6323 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6363,6388 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.05.20.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.05.20.} @= ! else /* |entry != 0| */ { --- 6365,6390 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.05.20.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.05.20.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6415,6419 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6417,6421 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6435,6439 **** ! } /* |else| (|entry != 0|) */ --- 6437,6441 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6479,6504 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.01.25.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.25.} @= ! else /* |entry != 0| */ { --- 6481,6506 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.01.25.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.25.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6531,6535 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6533,6537 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6551,6555 **** ! } /* |else| (|entry != 0|) */ --- 6553,6557 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6595,6620 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.01.26.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.26.} @= ! else /* |entry != 0| */ { --- 6597,6622 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.01.26.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.26.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6646,6650 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6648,6652 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6666,6670 **** ! } /* |else| (|entry != 0|) */ --- 6668,6672 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6763,6767 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6765,6769 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6823,6848 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.12.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.12.14.} @= ! else /* |entry != 0| */ { --- 6825,6850 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.12.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.12.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6874,6878 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6876,6880 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6894,6898 **** ! } /* |else| (|entry != 0|) */ --- 6896,6900 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 6939,6964 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.12.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.12.14.} @= ! else /* |entry != 0| */ { --- 6941,6966 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.12.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.12.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 6992,6996 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6994,6998 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7012,7016 **** ! } /* |else| (|entry != 0|) */ --- 7014,7018 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 7054,7079 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2004.12.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2004.12.14.} @= ! else /* |entry != 0| */ { --- 7056,7081 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2004.12.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2004.12.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 7107,7111 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 7109,7113 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7127,7131 **** ! } /* |else| (|entry != 0|) */ --- 7129,7133 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 7169,7194 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.01.14.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.01.14.} @= ! else /* |entry != 0| */ { --- 7171,7196 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.01.14.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.01.14.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 7222,7226 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 7224,7228 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7242,7246 **** ! } /* |else| (|entry != 0|) */ --- 7244,7248 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 7284,7309 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.10.30.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.10.30.} @= ! else /* |entry != 0| */ { --- 7286,7311 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.10.30.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.10.30.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 7336,7340 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 7338,7342 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7356,7360 **** ! } /* |else| (|entry != 0|) */ --- 7358,7362 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 7398,7423 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.10.30.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.10.30.} @= ! else /* |entry != 0| */ { --- 7400,7425 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.10.30.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.10.30.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 7450,7454 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 7452,7456 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7470,7474 **** ! } /* |else| (|entry != 0|) */ --- 7472,7476 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 7512,7537 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.10.30.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.10.30.} @= ! else /* |entry != 0| */ { --- 7514,7539 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.10.30.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.10.30.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 7565,7569 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 7567,7571 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7585,7589 **** ! } /* |else| (|entry != 0|) */ --- 7587,7591 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 7628,7653 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == 0|.@> ! @ Error handling for the case that |entry == 0 |. \initials{LDF 2005.02.03.} @= ! if (entry == 0) { ! @=$$@> = 0; ! } /* |if (entry == 0)| */ ! @q ****** (6) |entry != 0|.@> ! @ |entry != 0|. \initials{LDF 2005.02.03.} @= ! else /* |entry != 0| */ { --- 7630,7655 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! @q ****** (6) Error handling for the case that |entry == static_cast(0)|.@> ! @ Error handling for the case that |entry == static_cast(0) |. \initials{LDF 2005.02.03.} @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); ! } /* |if (entry == static_cast(0))| */ ! @q ****** (6) |entry != static_cast(0)|.@> ! @ |entry != static_cast(0)|. \initials{LDF 2005.02.03.} @= ! else /* |entry != static_cast(0)| */ { *************** *** 7681,7685 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 7683,7687 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7701,7705 **** ! } /* |else| (|entry != 0|) */ --- 7703,7707 ---- ! } /* |else| (|entry != static_cast(0)|) */ *************** *** 7763,7767 **** delete static_cast(@=$1@>); ! @=$$@> = 0; }; --- 7765,7769 ---- delete static_cast(@=$1@>); ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/paths.web 3DLDF-2.0.3/src/paths.web *** 3DLDF-2.0.2/src/paths.web Sun Nov 10 16:53:36 2013 --- 3DLDF-2.0.3/src/paths.web Fri Dec 13 11:34:13 2013 *************** *** 357,361 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 357,361 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 410,417 **** @q **** (4) @> ! if (draw_color_vector == 0 && p.draw_color_vector == 0) ; /* Do nothing. */@; ! else if (draw_color_vector == 0 && p.draw_color_vector != 0) { --- 410,419 ---- @q **** (4) @> ! if ( draw_color_vector == static_cast*>(0) ! && p.draw_color_vector == static_cast*>(0)) ; /* Do nothing. */@; ! else if ( draw_color_vector == static_cast*>(0) ! && p.draw_color_vector != static_cast*>(0)) { *************** *** 423,427 **** } ! else if (draw_color_vector != 0 && p.draw_color_vector == 0) { draw_color_vector->clear(); --- 425,430 ---- } ! else if ( draw_color_vector != static_cast*>(0) ! && p.draw_color_vector == static_cast*>(0)) { draw_color_vector->clear(); *************** *** 431,443 **** } ! else if (draw_color_vector != 0 && p.draw_color_vector != 0) *draw_color_vector = *(p.draw_color_vector); @q **** (4) @> ! if (fill_color_vector == 0 && p.fill_color_vector == 0) ; /* Do nothing. */@; ! else if (fill_color_vector == 0 && p.fill_color_vector != 0) { --- 434,449 ---- } ! else if ( draw_color_vector != static_cast*>(0) ! && p.draw_color_vector != static_cast*>(0)) *draw_color_vector = *(p.draw_color_vector); @q **** (4) @> ! if ( fill_color_vector == static_cast*>(0) ! && p.fill_color_vector == static_cast*>(0)) ; /* Do nothing. */@; ! else if ( fill_color_vector == static_cast*>(0) ! && p.fill_color_vector != static_cast*>(0)) { *************** *** 449,461 **** } ! else if (fill_color_vector != 0 && p.fill_color_vector == 0) { fill_color_vector->clear(); delete fill_color_vector; ! fill_color_vector = 0; } ! else if (fill_color_vector != 0 && p.fill_color_vector != 0) *fill_color_vector = *(p.fill_color_vector); --- 455,469 ---- } ! else if ( fill_color_vector != static_cast*>(0) ! && p.fill_color_vector == static_cast*>(0)) { fill_color_vector->clear(); delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } ! else if ( fill_color_vector != static_cast*>(0) ! && p.fill_color_vector != static_cast*>(0)) *fill_color_vector = *(p.fill_color_vector); *************** *** 495,502 **** ! if (dash_pattern_vector == 0 && p.dash_pattern_vector == 0) ; /* Do nothing. */@; ! else if (dash_pattern_vector == 0 && p.dash_pattern_vector != 0) { --- 503,512 ---- ! if ( dash_pattern_vector == static_cast*>(0) ! && p.dash_pattern_vector == static_cast*>(0)) ; /* Do nothing. */@; ! else if ( dash_pattern_vector == static_cast*>(0) ! && p.dash_pattern_vector != static_cast*>(0)) { *************** *** 508,520 **** } ! else if (dash_pattern_vector != 0 && p.dash_pattern_vector == 0) { dash_pattern_vector->clear(); delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! else if (dash_pattern_vector != 0 && p.dash_pattern_vector != 0) *dash_pattern_vector = *(p.dash_pattern_vector); --- 518,532 ---- } ! else if ( dash_pattern_vector != static_cast*>(0) ! && p.dash_pattern_vector == static_cast*>(0)) { dash_pattern_vector->clear(); delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! else if ( dash_pattern_vector != static_cast*>(0) ! && p.dash_pattern_vector != static_cast*>(0)) *dash_pattern_vector = *(p.dash_pattern_vector); *************** *** 532,539 **** ! if (pen_vector == 0 && p.pen_vector == 0) ; /* Do nothing. */@; ! else if (pen_vector == 0 && p.pen_vector != 0) { --- 544,553 ---- ! if ( pen_vector == static_cast*>(0) ! && p.pen_vector == static_cast*>(0)) ; /* Do nothing. */@; ! else if ( pen_vector == static_cast*>(0) ! && p.pen_vector != static_cast*>(0)) { *************** *** 545,557 **** } ! else if (pen_vector != 0 && p.pen_vector == 0) { pen_vector->clear(); delete pen_vector; ! pen_vector = 0; } ! else if (pen_vector != 0 && p.pen_vector != 0) *pen_vector = *(p.pen_vector); --- 559,573 ---- } ! else if ( pen_vector != static_cast*>(0) ! && p.pen_vector == static_cast*>(0)) { pen_vector->clear(); delete pen_vector; ! pen_vector = static_cast*>(0); } ! else if ( pen_vector != static_cast*>(0) ! && p.pen_vector != static_cast*>(0)) *pen_vector = *(p.pen_vector); *************** *** 582,586 **** if (world_extremes.size() == 0) ! world_extremes.resize(6,0); pre_projective_extremes = p.pre_projective_extremes; --- 598,602 ---- if (world_extremes.size() == 0) ! world_extremes.resize(6, 0); pre_projective_extremes = p.pre_projective_extremes; *************** *** 588,597 **** if (pre_projective_extremes.size() == 0) ! pre_projective_extremes.resize(6,0); projective_extremes = p.projective_extremes; if (projective_extremes.size() == 0) ! projective_extremes.resize(6,0); --- 604,613 ---- if (pre_projective_extremes.size() == 0) ! pre_projective_extremes.resize(6, 0); projective_extremes = p.projective_extremes; if (projective_extremes.size() == 0) ! projective_extremes.resize(6, 0); *************** *** 718,722 **** if (DEBUG) ! cerr << "Entering Path() (default version).\n" << flush; line_switch = false; --- 734,738 ---- if (DEBUG) ! cerr << "Entering Path() (default version).\n"; line_switch = false; *************** *** 815,819 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path() (line version).\n" << flush; line_switch = true; --- 831,835 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path() (line version).\n"; line_switch = true; *************** *** 848,852 **** connectors.push_back("--"); if (DEBUG) ! cerr << "Exiting Path() (line version).\n" << flush; return; --- 864,868 ---- connectors.push_back("--"); if (DEBUG) ! cerr << "Exiting Path() (line version).\n"; return; *************** *** 914,942 **** fill_draw_value = 0; ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (fill_color_vector != 0) { delete fill_color_vector; ! fill_color_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } --- 930,958 ---- fill_draw_value = 0; ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } *************** *** 1039,1043 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path() (connector, cycle, ...).\n" << flush; shape_type = PATH_TYPE; --- 1055,1059 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path() (connector, cycle, ...).\n"; shape_type = PATH_TYPE; *************** *** 1078,1082 **** va_end(ap); if (DEBUG) ! cerr << "Exiting Path() (connector, cycle, ...).\n" << flush; return; } --- 1094,1098 ---- va_end(ap); if (DEBUG) ! cerr << "Exiting Path() (connector, cycle, ...).\n"; return; } *************** *** 1140,1143 **** --- 1156,1170 ---- volatile bool DEBUG = false; /* |true| */ + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << "Entering `Path::set'." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + line_switch = false; cycle_switch = cycle; *************** *** 1150,1176 **** ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (fill_color_vector != 0) { delete fill_color_vector; ! fill_color_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } --- 1177,1203 ---- ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } *************** *** 1193,1197 **** points.push_back(create_new(arg_ptr)); } ! va_end(ap); --- 1220,1224 ---- points.push_back(create_new(arg_ptr)); } ! va_end(ap); *************** *** 1235,1239 **** @^\cfunc{Path}{Path}@> - \LOG \initials{LDF 2004.06.07.} --- 1262,1265 ---- *************** *** 1272,1276 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path() (Point* ...).\n" << flush; shape_type = PATH_TYPE; --- 1298,1302 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path() (Point* ...).\n"; shape_type = PATH_TYPE; *************** *** 1324,1328 **** va_end(ap); if (DEBUG) ! cerr << "Exiting Path() (Point* ...).\n" << flush; } --- 1350,1354 ---- va_end(ap); if (DEBUG) ! cerr << "Exiting Path() (Point* ...).\n"; } *************** *** 1398,1424 **** fill_draw_value = 0; ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (fill_color_vector != 0) { delete fill_color_vector; ! fill_color_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } --- 1424,1450 ---- fill_draw_value = 0; ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } *************** *** 1521,1525 **** if (DEBUG) ! cerr << "Exiting Path() (copy constructor).\n" << flush; return; } --- 1547,1551 ---- if (DEBUG) ! cerr << "Exiting Path() (copy constructor).\n"; return; } *************** *** 1632,1636 **** if (DEBUG) { ! cerr << "Entering ~Path().\n" << flush; show("Path:"); } --- 1658,1662 ---- if (DEBUG) { ! cerr << "Entering ~Path().\n"; show("Path:"); } *************** *** 1666,1673 **** @= ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } /* |if (draw_color_vector != 0)| */ --- 1692,1699 ---- @= ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } /* |if (draw_color_vector != 0)| */ *************** *** 1677,1693 **** { delete fill_color_vector; ! fill_color_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } --- 1703,1719 ---- { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } *************** *** 1696,1700 **** if (DEBUG) { ! cerr << "Exiting ~Path().\n" << flush; } } --- 1722,1726 ---- if (DEBUG) { ! cerr << "Exiting ~Path().\n"; } } *************** *** 1766,1770 **** @@; ! if (draw_color_vector != 0) { delete draw_color_vector; --- 1792,1796 ---- @@; ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; *************** *** 1772,1776 **** } ! if (fill_color_vector != 0) { delete fill_color_vector; --- 1798,1802 ---- } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; *************** *** 1779,1783 **** ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; --- 1805,1809 ---- ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; *************** *** 1785,1789 **** } ! if (pen_vector != 0) { delete pen_vector; --- 1811,1815 ---- } ! if (pen_vector != static_cast*>(0)) { delete pen_vector; *************** *** 2032,2036 **** Path::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; --- 2058,2062 ---- Path::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; *************** *** 2082,2086 **** Path::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 2108,2112 ---- Path::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 2132,2139 **** Path::push_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 2158,2165 ---- Path::push_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 2182,2186 **** Path::push_pen(Pen*& p, bool copy) { ! if (pen_vector == 0) pen_vector = new Pointer_Vector; --- 2208,2212 ---- Path::push_pen(Pen*& p, bool copy) { ! if (pen_vector == static_cast*>(0)) pen_vector = new Pointer_Vector; *************** *** 2226,2230 **** Path::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == 0) dash_pattern_vector = new Pointer_Vector; --- 2252,2256 ---- Path::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == static_cast*>(0)) dash_pattern_vector = new Pointer_Vector; *************** *** 3395,3399 **** cerr << "ERROR! In Path::project():\n" << "Point::project() returned false.\n" ! << "Returning false.\n\n" << flush; return false; } --- 3421,3425 ---- cerr << "ERROR! In Path::project():\n" << "Point::project() returned false.\n" ! << "Returning false.\n\n"; return false; } *************** *** 3481,3485 **** ! if (path_reflection == 0) { cerr_strm << thread_name --- 3507,3511 ---- ! if (path_reflection == static_cast(0)) { cerr_strm << thread_name *************** *** 3780,3784 **** @= ! if (path_ptr_vector == 0) { --- 3806,3810 ---- @= ! if (path_ptr_vector == static_cast*>(0)) { *************** *** 4149,4153 **** << "Don't call this function with the \"assign\" " << "argument == false.\nIt won't cause any harm, though.\n" ! << "Continuing.\n\n" << flush; return t; } --- 4175,4179 ---- << "Don't call this function with the \"assign\" " << "argument == false.\nIt won't cause any harm, though.\n" ! << "Continuing.\n\n"; return t; } *************** *** 4341,4345 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 4367,4371 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 4359,4363 **** @= ! if (c == 0) { cerr_strm << thread_name << "WARNING! In `Path::operator+=(Color*)':" --- 4385,4389 ---- @= ! if (c == static_cast(0)) { cerr_strm << thread_name << "WARNING! In `Path::operator+=(Color*)':" *************** *** 4379,4383 **** @q *** (3).@> ! if (draw_color_vector == 0) { --- 4405,4409 ---- @q *** (3).@> ! if (draw_color_vector == static_cast*>(0)) { *************** *** 4406,4410 **** ! } /* |if (draw_color_vector == 0)| */ @q *** (3).@> --- 4432,4436 ---- ! } /* |if (draw_color_vector == static_cast*>(0))| */ @q *** (3).@> *************** *** 4493,4498 **** cerr << "ERROR! In Path::operator&(Path&)." << "Paths don't touch.\n" ! << "Using \"..\" to join them instead of \"&\".\n" ! << flush; connectors.push_back(".."); } --- 4519,4524 ---- cerr << "ERROR! In Path::operator&(Path&)." << "Paths don't touch.\n" ! << "Using \"..\" to join them instead of \"&\".\n"; ! connectors.push_back(".."); } *************** *** 4966,4970 **** ! if (ppen_vector != 0) { p->pen_vector = new Pointer_Vector; --- 4992,4996 ---- ! if (ppen_vector != static_cast*>(0)) { p->pen_vector = new Pointer_Vector; *************** *** 4976,4980 **** ! if (ddash_pattern_vector != 0) { p->dash_pattern_vector = new Pointer_Vector; --- 5002,5006 ---- ! if (ddash_pattern_vector != static_cast*>(0)) { p->dash_pattern_vector = new Pointer_Vector; *************** *** 5247,5251 **** Pointer_Vector* ppen_vector = 0; ! if (ppen != 0) { ppen_vector = new Pointer_Vector; --- 5273,5277 ---- Pointer_Vector* ppen_vector = 0; ! if (ppen != static_cast(0)) { ppen_vector = new Pointer_Vector; *************** *** 5255,5259 **** Pointer_Vector* ddash_pattern_vector = 0; ! if (ddash_pattern != 0) { ddash_pattern_vector = new Pointer_Vector; --- 5281,5285 ---- Pointer_Vector* ddash_pattern_vector = 0; ! if (ddash_pattern != static_cast(0)) { ddash_pattern_vector = new Pointer_Vector; *************** *** 5526,5530 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::fill().\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 5552,5556 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::fill().\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 5534,5538 **** << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n" << flush; return 1; } --- 5560,5564 ---- << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n"; return 1; } *************** *** 5565,5569 **** << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 5591,5595 ---- << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 5573,5577 **** cerr << "`Picture::lock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 5599,5603 ---- cerr << "`Picture::lock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 5604,5608 **** << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 5630,5634 ---- << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 5612,5616 **** cerr << "`Picture::unlock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 5638,5642 ---- cerr << "`Picture::unlock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 5627,5631 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "Exiting Path::fill().\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 5653,5657 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "Exiting Path::fill().\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 5754,5758 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::filldraw().\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 5780,5784 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::filldraw().\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 5762,5766 **** << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n" << flush; return 1; } --- 5788,5792 ---- << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n"; return 1; } *************** *** 5780,5784 **** p->push_fill_color(ffill_color, false); ! if (ppen_vector != 0) { p->pen_vector = new Pointer_Vector; --- 5806,5810 ---- p->push_fill_color(ffill_color, false); ! if (ppen_vector != static_cast*>(0)) { p->pen_vector = new Pointer_Vector; *************** *** 5789,5793 **** ! if (ddash_pattern_vector != 0) { p->dash_pattern_vector = new Pointer_Vector; --- 5815,5819 ---- ! if (ddash_pattern_vector != static_cast*>(0)) { p->dash_pattern_vector = new Pointer_Vector; *************** *** 5814,5818 **** << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 5840,5844 ---- << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 5822,5826 **** cerr << "`Picture::lock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 5848,5852 ---- cerr << "`Picture::lock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 5855,5859 **** << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 5881,5885 ---- << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 5863,5867 **** cerr << "`Picture::unlock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 5889,5893 ---- cerr << "`Picture::unlock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 5878,5882 **** if (DEBUG) ! cerr << "Exiting Path::filldraw().\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 5904,5908 ---- if (DEBUG) ! cerr << "Exiting Path::filldraw().\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 5957,5961 **** << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n" << flush; return 1; } --- 5983,5987 ---- << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n"; return 1; } *************** *** 5968,5972 **** p->fill_color_vector = 0; ! if (ppen_vector != 0) { p->pen_vector = new Pointer_Vector; --- 5994,5998 ---- p->fill_color_vector = 0; ! if (ppen_vector != static_cast*>(0)) { p->pen_vector = new Pointer_Vector; *************** *** 5976,5980 **** p->pen_vector = 0; ! if (ddash_pattern_vector != 0) { p->dash_pattern_vector = new Pointer_Vector; --- 6002,6006 ---- p->pen_vector = 0; ! if (ddash_pattern_vector != static_cast*>(0)) { p->dash_pattern_vector = new Pointer_Vector; *************** *** 6002,6006 **** << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6028,6032 ---- << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6010,6014 **** cerr << "`Picture::lock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6036,6040 ---- cerr << "`Picture::lock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6042,6046 **** << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6068,6072 ---- << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6050,6054 **** cerr << "`Picture::unlock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6076,6080 ---- cerr << "`Picture::unlock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6121,6125 **** Pointer_Vector* ppen_vector = 0; ! if (ppen != 0) { ppen_vector = new Pointer_Vector; --- 6147,6151 ---- Pointer_Vector* ppen_vector = 0; ! if (ppen != static_cast(0)) { ppen_vector = new Pointer_Vector; *************** *** 6130,6134 **** Pointer_Vector* ddash_pattern_vector = 0; ! if (ddash_pattern != 0) { ddash_pattern_vector = new Pointer_Vector; --- 6156,6160 ---- Pointer_Vector* ddash_pattern_vector = 0; ! if (ddash_pattern != static_cast(0)) { ddash_pattern_vector = new Pointer_Vector; *************** *** 6196,6200 **** << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n" << flush; return 1; } --- 6222,6226 ---- << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n"; return 1; } *************** *** 6226,6230 **** << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6252,6256 ---- << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6234,6238 **** cerr << "`Picture::lock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6260,6264 ---- cerr << "`Picture::lock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6265,6269 **** << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6291,6295 ---- << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6273,6277 **** cerr << "`Picture::unlock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6299,6303 ---- cerr << "`Picture::unlock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6381,6385 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::unfilldraw().\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 6407,6411 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::unfilldraw().\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 6389,6393 **** << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n" << flush; return 1; } --- 6415,6419 ---- << "Path doesn't contain any Points.\n" << "Not adding `Path' to `Picture', returning 1, " ! << "and will try to continue.\n\n"; return 1; } *************** *** 6405,6409 **** p->fill_color_vector = 0; ! if (ppen_vector != 0) { p->pen_vector = new Pointer_Vector; --- 6431,6435 ---- p->fill_color_vector = 0; ! if (ppen_vector != static_cast*>(0)) { p->pen_vector = new Pointer_Vector; *************** *** 6414,6418 **** ! if (ddash_pattern_vector != 0) { p->dash_pattern_vector = new Pointer_Vector; --- 6440,6444 ---- ! if (ddash_pattern_vector != static_cast*>(0)) { p->dash_pattern_vector = new Pointer_Vector; *************** *** 6441,6445 **** << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6467,6471 ---- << "`Picture::lock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6449,6453 **** cerr << "`Picture::lock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6475,6479 ---- cerr << "`Picture::lock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6480,6484 **** << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6506,6510 ---- << "`Picture::unlock' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6488,6492 **** cerr << "`Picture::unlock' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6514,6518 ---- cerr << "`Picture::unlock' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6503,6507 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "Exiting Path::unfilldraw().\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 6529,6533 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "Exiting Path::unfilldraw().\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 7746,7756 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_minimum_x()" << endl << flush; if (DEBUG) ! cerr << "minimum_x == " << projective_extremes[0] << endl << flush; if (DEBUG) ! cerr << "Exiting Path::get_minimum_x()" << endl << flush; return projective_extremes[0]; --- 7772,7782 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_minimum_x()" << endl; if (DEBUG) ! cerr << "minimum_x == " << projective_extremes[0] << endl; if (DEBUG) ! cerr << "Exiting Path::get_minimum_x()" << endl; return projective_extremes[0]; *************** *** 7789,7799 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_maximum_x()" << endl << flush; if (DEBUG) ! cerr << "maximum_x == " << projective_extremes[1] << endl << flush; if (DEBUG) ! cerr << "Exiting Path::get_maximum_x()" << endl << flush; return projective_extremes[1]; --- 7815,7825 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_maximum_x()" << endl; if (DEBUG) ! cerr << "maximum_x == " << projective_extremes[1] << endl; if (DEBUG) ! cerr << "Exiting Path::get_maximum_x()" << endl; return projective_extremes[1]; *************** *** 7863,7873 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_minimum_y()" << endl << flush; if (DEBUG) ! cerr << "minimum_y == " << projective_extremes[2] << endl << flush; if (DEBUG) ! cerr << "Exiting Path::get_minimum_y()" << endl << flush; return projective_extremes[2]; --- 7889,7899 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_minimum_y()" << endl; if (DEBUG) ! cerr << "minimum_y == " << projective_extremes[2] << endl; if (DEBUG) ! cerr << "Exiting Path::get_minimum_y()" << endl; return projective_extremes[2]; *************** *** 7906,7916 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_maximum_y()" << endl << flush; if (DEBUG) ! cerr << "maximum_y == " << projective_extremes[3] << endl << flush; if (DEBUG) ! cerr << "Exiting Path::get_maximum_y()" << endl << flush; return projective_extremes[3]; --- 7932,7942 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Path::get_maximum_y()" << endl; if (DEBUG) ! cerr << "maximum_y == " << projective_extremes[3] << endl; if (DEBUG) ! cerr << "Exiting Path::get_maximum_y()" << endl; return projective_extremes[3]; *************** *** 8005,8009 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 8031,8035 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 8120,8124 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 8146,8150 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 8237,8241 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 8263,8267 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 8588,8592 **** @@; ! if (fill_color_vector != 0 && fill_color_vector->ctr > 0) *out_stream << " withcolor " << *(fill_color_vector->v[0]); --- 8614,8619 ---- @@; ! if ( fill_color_vector != static_cast*>(0) ! && fill_color_vector->ctr > 0) *out_stream << " withcolor " << *(fill_color_vector->v[0]); *************** *** 8644,8660 **** Color* temp_color; ! if (fill_color_vector != 0 && fill_color_vector->ctr > 0) temp_color = fill_color_vector->v[0]; ! else temp_color = 0; ! if (temp_color == 0) { entry = scanner_node->lookup("background_color"); ! if (entry != 0) v = entry->get_object(); ! if (entry != 0 && v != 0) temp_color = static_cast(v); else temp_color = const_cast(&Colors::white); --- 8671,8694 ---- Color* temp_color; ! if ( fill_color_vector != static_cast*>(0) ! && fill_color_vector->ctr > 0) ! { temp_color = fill_color_vector->v[0]; ! } ! else ! temp_color = 0; ! if (temp_color == static_cast(0)) { entry = scanner_node->lookup("background_color"); ! if (entry != static_cast(0)) v = entry->get_object(); ! if ( entry != static_cast(0) ! && v != static_cast(0)) ! { temp_color = static_cast(v); + } else temp_color = const_cast(&Colors::white); *************** *** 8801,8805 **** @q ***** (5).@> ! if ( draw_color_vector == 0 || draw_color_vector->v.size() == 0) { --- 8835,8839 ---- @q ***** (5).@> ! if ( draw_color_vector == static_cast*>(0) || draw_color_vector->v.size() == 0) { *************** *** 9018,9024 **** || shape_type == RECTANGLE_TYPE || shape_type == REG_POLYGON_TYPE) ! && ( draw_color_vector != 0 && draw_color_vector->ctr > 1 ! || pen_vector != 0 && pen_vector->ctr > 1 ! || dash_pattern_vector != 0 && dash_pattern_vector->ctr > 1) ) --- 9052,9061 ---- || shape_type == RECTANGLE_TYPE || shape_type == REG_POLYGON_TYPE) ! && ( ( draw_color_vector != static_cast*>(0) ! && draw_color_vector->ctr > 1) ! || ( pen_vector != static_cast*>(0) ! && pen_vector->ctr > 1) ! || ( dash_pattern_vector != static_cast*>(0) ! && dash_pattern_vector->ctr > 1)) ) *************** *** 9075,9079 **** ! if (dash_pattern_vector != 0 && dash_pattern_vector->ctr > 0) { dash_pattern_iter = dash_pattern_vector->v.begin(); --- 9112,9117 ---- ! if ( dash_pattern_vector != static_cast*>(0) ! && dash_pattern_vector->ctr > 0) { dash_pattern_iter = dash_pattern_vector->v.begin(); *************** *** 9094,9098 **** << endl; ! if (do_pens && pen_vector != 0) cerr << "`pen_vector->v.size' == " << pen_vector->v.size() --- 9132,9136 ---- << endl; ! if (do_pens && pen_vector != static_cast*>(0)) cerr << "`pen_vector->v.size' == " << pen_vector->v.size() *************** *** 9102,9106 **** << endl; ! if (do_dash_patterns && dash_pattern_vector != 0) cerr << "`dash_pattern_vector->v.size' == " << dash_pattern_vector->v.size() --- 9140,9145 ---- << endl; ! if (do_dash_patterns && dash_pattern_vector ! != static_cast*>(0)) cerr << "`dash_pattern_vector->v.size' == " << dash_pattern_vector->v.size() *************** *** 9334,9345 **** @q ****** (6).@> ! } /* |if ( ( shape_type == POLYGON_TYPE ! || shape_type == TRIANGLE_TYPE ! || shape_type == RECTANGLE_TYPE ! || shape_type == REG_POLYGON_TYPE) ! && ( draw_color_vector != 0 && draw_color_vector->ctr > 1 ! || pen_vector != 0 && pen_vector->ctr > 1 ! || dash_pattern_vector != 0 && dash_pattern_vector->ctr > 1) ! )| */ @q ***** (5).@> --- 9373,9377 ---- @q ****** (6).@> ! } /* |if| */ @q ***** (5).@> *************** *** 9357,9361 **** @= ! else if ( pen_vector == 0 || pen_vector->ctr == 0 || pen_vector->v[0]->get_type() != Pen::NULL_PEN) --- 9389,9394 ---- @= ! else if ( pen_vector == static_cast*>(0) ! || pen_vector->ctr == 0 || pen_vector->v[0]->get_type() != Pen::NULL_PEN) *************** *** 9366,9370 **** if (DEBUG) { ! if (pen_vector == 0) cerr << "`pen_vector' == 0." << endl; --- 9399,9403 ---- if (DEBUG) { ! if (pen_vector == static_cast*>(0)) cerr << "`pen_vector' == 0." << endl; *************** *** 9409,9424 **** @@; ! if (draw_color_vector != 0 && draw_color_vector->ctr > 0) *out_stream << endl << "withcolor " << *(draw_color_vector->v[0]) << " "; ! if (pen_vector != 0 && pen_vector->ctr > 0) *out_stream << endl << "withpen " << *(pen_vector->v[0]) << " "; ! if (dash_pattern_vector != 0 && dash_pattern_vector->ctr > 0) *out_stream << endl << *(dash_pattern_vector->v[0]); *out_stream << ";\n" << flush; ! } /* |else if ( pen_vector == 0 || pen_vector->ctr == 0 || pen_vector->v[0]->get_type() != Pen::NULL_PEN)| (Not dividing |Path|.) */ --- 9442,9460 ---- @@; ! if ( draw_color_vector != static_cast*>(0) ! && draw_color_vector->ctr > 0) *out_stream << endl << "withcolor " << *(draw_color_vector->v[0]) << " "; ! if (pen_vector != static_cast*>(0) && pen_vector->ctr > 0) *out_stream << endl << "withpen " << *(pen_vector->v[0]) << " "; ! if ( dash_pattern_vector != static_cast*>(0) ! && dash_pattern_vector->ctr > 0) *out_stream << endl << *(dash_pattern_vector->v[0]); *out_stream << ";\n" << flush; ! } /* |else if ( pen_vector == static_cast*>(0) ! || pen_vector->ctr == 0 || pen_vector->v[0]->get_type() != Pen::NULL_PEN)| (Not dividing |Path|.) */ *************** *** 9540,9544 **** @= ! if (pen_vector != 0 && pen_vector->ctr > 0) { --- 9576,9580 ---- @= ! if (pen_vector != static_cast*>(0) && pen_vector->ctr > 0) { *************** *** 9563,9567 **** @= ! if (dash_pattern_vector != 0 && dash_pattern_vector->ctr > 0) { --- 9599,9604 ---- @= ! if ( dash_pattern_vector != static_cast*>(0) ! && dash_pattern_vector->ctr > 0) { *************** *** 9650,9660 **** else if (coords == 'p') ! cerr << "Projective coordinates.\n" << flush; else if (coords == 'u') ! cerr << "User coordinates.\n" << flush; else if (coords == 'v') ! cerr << "View coordinates.\n" << flush; else --- 9687,9697 ---- else if (coords == 'p') ! cerr << "Projective coordinates.\n"; else if (coords == 'u') ! cerr << "User coordinates.\n"; else if (coords == 'v') ! cerr << "View coordinates.\n"; else *************** *** 9682,9690 **** cerr << "connectors.size() == " ! << connectors.size() << endl << flush; if (connectors.size() == 0) { ! cerr << "Using \"--\" as connector.\n" << flush; connector_string = "--"; } --- 9719,9727 ---- cerr << "connectors.size() == " ! << connectors.size() << endl; if (connectors.size() == 0) { ! cerr << "Using \"--\" as connector.\n"; connector_string = "--"; } *************** *** 9755,9764 **** cerr << endl; ! if (fill_color_vector == 0) cerr << "`fill_color_vector' == 0" << endl; else fill_color_vector->show("fill_color_vector:"); ! if (draw_color_vector == 0) cerr << "`draw_color_vector' == 0" << endl; else --- 9792,9801 ---- cerr << endl; ! if (fill_color_vector == static_cast*>(0)) cerr << "`fill_color_vector' == 0" << endl; else fill_color_vector->show("fill_color_vector:"); ! if (draw_color_vector == static_cast*>(0)) cerr << "`draw_color_vector' == 0" << endl; else *************** *** 9766,9775 **** ! if (pen_vector == 0) cerr << "`pen_vector' == 0" << endl; else pen_vector->show("pen_vector:"); ! if (dash_pattern_vector == 0) cerr << "`dash_pattern_vector' == 0" << endl; else --- 9803,9812 ---- ! if (pen_vector == static_cast*>(0)) cerr << "`pen_vector' == 0" << endl; else pen_vector->show("pen_vector:"); ! if (dash_pattern_vector == static_cast*>(0)) cerr << "`dash_pattern_vector' == 0" << endl; else *************** *** 9786,9790 **** cerr << "`arrow' == `Path::NO_ARROW'."; ! cerr << endl << flush; return; --- 9823,9827 ---- cerr << "`arrow' == `Path::NO_ARROW'."; ! cerr << endl; return; *************** *** 9806,9818 **** Path::show_colors(bool stop) { ! if (draw_color_vector != 0) draw_color_vector->show("draw_color_vector:"); else ! cerr << "draw_color_vector == 0.\n"; ! if (fill_color_vector != 0) fill_color_vector->show("fill_color_vector:"); else ! cerr << "fill_color_vector == 0.\n"; if (stop) --- 9843,9855 ---- Path::show_colors(bool stop) { ! if (draw_color_vector != static_cast*>(0)) draw_color_vector->show("draw_color_vector:"); else ! cerr << "draw_color_vector == static_cast*>(0).\n"; ! if (fill_color_vector != static_cast*>(0)) fill_color_vector->show("fill_color_vector:"); else ! cerr << "fill_color_vector == static_cast*>(0).\n"; if (stop) *************** *** 9955,9959 **** #if 0 cerr << "WARNING! In Path::is_planar():\n" ! << "Path is linear. Returning true.\n\n" << flush; #endif if (verbose) --- 9992,9996 ---- #if 0 cerr << "WARNING! In Path::is_planar():\n" ! << "Path is linear. Returning true.\n\n"; #endif if (verbose) *************** *** 11105,11109 **** { cerr << "ERROR! In Path::slope(). Path is not linear!\n" ! << "Returning INVALID_REAL\n" << flush; return INVALID_REAL; } --- 11142,11146 ---- { cerr << "ERROR! In Path::slope(). Path is not linear!\n" ! << "Returning INVALID_REAL\n"; return INVALID_REAL; } *************** *** 11166,11170 **** cerr << "ERROR! In Path::subpath():\n" << "The \"start\" argument is < the \"end\" argument.\n" ! << "Returning empty Path.\n\n" << flush; return p; } --- 11203,11207 ---- cerr << "ERROR! In Path::subpath():\n" << "The \"start\" argument is < the \"end\" argument.\n" ! << "Returning empty Path.\n\n"; return p; } *************** *** 11177,11182 **** cerr << "ERROR! In Path::subpath():\n" << "\"start\" argument is > points.size() - 1.\n" ! << "Will try to recover by setting start = 0.\n\n" ! << flush; start = 0; } --- 11214,11219 ---- cerr << "ERROR! In Path::subpath():\n" << "\"start\" argument is > points.size() - 1.\n" ! << "Will try to recover by setting start = 0.\n\n"; ! start = 0; } *************** *** 11186,11191 **** cerr << "ERROR! In Path::subpath():\n" << "\"end\" argument is > points.size().\n" ! << "Will try to recover by setting end = points.size().\n\n" ! << flush; end = points.size(); } --- 11223,11228 ---- cerr << "ERROR! In Path::subpath():\n" << "\"end\" argument is > points.size().\n" ! << "Will try to recover by setting end = points.size().\n\n"; ! end = points.size(); } *************** *** 11204,11208 **** cerr << "ERROR! In Path::subpath():\n" << "end argument > points.size().\n" ! << "Breaking out of loop.\n\n" << flush; break; } --- 11241,11245 ---- cerr << "ERROR! In Path::subpath():\n" << "end argument > points.size().\n" ! << "Breaking out of loop.\n\n"; break; } *************** *** 11241,11245 **** } if (DEBUG) ! cerr << "p.connectors.size() == " << p.connectors.size() << endl << flush; Path q; --- 11278,11282 ---- } if (DEBUG) ! cerr << "p.connectors.size() == " << p.connectors.size() << endl; Path q; *************** *** 11309,11313 **** cerr << "ERROR! In Path::get_point():\n" << "Argument is >= size of Path.\n" ! << "Returning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 11346,11350 ---- cerr << "ERROR! In Path::get_point():\n" << "Argument is >= size of Path.\n" ! << "Returning INVALID_POINT.\n\n" ; return INVALID_POINT; } *************** *** 11349,11353 **** cerr << "ERROR! In Path::get_point():\n" << "Argument is >= size of Path.\n" ! << "Returning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 11386,11390 ---- cerr << "ERROR! In Path::get_point():\n" << "Argument is >= size of Path.\n" ! << "Returning INVALID_POINT.\n\n" ; return INVALID_POINT; } *************** *** 11390,11394 **** cerr << "ERROR! In Path::get_last_point():\n" << "Path is empty.\n" ! << "Returning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 11427,11431 ---- cerr << "ERROR! In Path::get_last_point():\n" << "Path is empty.\n" ! << "Returning INVALID_POINT.\n\n" ; return INVALID_POINT; } *************** *** 11531,11537 **** Path::get_normal(void) const { ! bool DEBUG = false; /* |true| */@; if (DEBUG) ! cerr << "Entering Path::get_normal().\n" << flush; Point origin_pt(0, 0, 0); --- 11568,11579 ---- Path::get_normal(void) const { ! volatile bool DEBUG = false; /* |true| */@; ! if (DEBUG) ! { ! cerr_mutex.lock(); ! cerr << "Entering Path::get_normal().\n"; ! cerr_mutex.unlock(); ! } Point origin_pt(0, 0, 0); *************** *** 11542,11546 **** cerr << "WARNING! In Path::get_normal():\n" << "Path is empty or contains only one Point. " ! << "Returning INVALID_POINT.\n\n" << flush; cerr_mutex.unlock(); --- 11584,11588 ---- cerr << "WARNING! In Path::get_normal():\n" << "Path is empty or contains only one Point. " ! << "Returning INVALID_POINT.\n\n"; cerr_mutex.unlock(); *************** *** 11562,11566 **** cerr << "WARNING! In Path::get_normal():\n" << "Connector may make Path non-linear or non-planar: " ! << *iter << endl << "Returning INVALID_POINT.\n\n" << flush; cerr_mutex.unlock(); --- 11604,11608 ---- cerr << "WARNING! In Path::get_normal():\n" << "Connector may make Path non-linear or non-planar: " ! << *iter << endl << "Returning INVALID_POINT.\n\n"; cerr_mutex.unlock(); *************** *** 11581,11585 **** #if 0 cerr << "WARNING! In Path::get_normal():\n" ! << "Path has 2 Points. Returning origin_pt.\n\n" << flush; #endif return origin_pt; --- 11623,11627 ---- #if 0 cerr << "WARNING! In Path::get_normal():\n" ! << "Path has 2 Points. Returning origin_pt.\n\n"; #endif return origin_pt; *************** *** 11605,11618 **** if (iter == points.end() && b0 == origin_pt) ! { ! if (DEBUG) ! cerr_mutex.lock(); ! cerr << "Exiting Path::get_normal(). " ! << "Points are all colinear.\n" ! << "Returning origin_pt.\n\n"; ! cerr_mutex.unlock(); ! return origin_pt; ! } if (DEBUG) --- 11647,11670 ---- if (iter == points.end() && b0 == origin_pt) ! { ! if (DEBUG) ! cerr_mutex.lock(); ! cerr << "Exiting Path::get_normal(). " ! << "Points are all colinear.\n" ! << "Returning origin_pt.\n\n"; ! cerr_mutex.unlock(); ! return origin_pt; ! } ! #if DEBUG_COMPILE ! else if (DEBUG) ! { ! cerr_mutex.lock(); ! cerr << "Exiting Path::get_normal(). " ! << "Points are not all colinear.\n"; ! cerr_mutex.unlock(); ! ! } /* |else if (DEBUG)| */ ! #endif /* |DEBUG_COMPILE| */ if (DEBUG) *************** *** 11632,11637 **** cerr << "Exiting Path::get_normal(). " << "Points are all colinear except for one.\n" ! << "Returning normal.\n\n" ! << flush; } return -b0; --- 11684,11689 ---- cerr << "Exiting Path::get_normal(). " << "Points are all colinear except for one.\n" ! << "Returning normal.\n\n"; ! } return -b0; *************** *** 11673,11677 **** cerr_mutex.lock(); cerr << "Exiting Path::get_normal(). " ! << "Returning INVALID_POINT.\n\n" << flush; cerr_mutex.unlock(); } --- 11725,11729 ---- cerr_mutex.lock(); cerr << "Exiting Path::get_normal(). " ! << "Returning INVALID_POINT.\n\n"; cerr_mutex.unlock(); } *************** *** 11720,11724 **** cerr << "ERROR! In Point::get_normal():\n" << "The Points do not determine a plane.\n" ! << "Returning INVALID_POINT.\n\n" << flush; cerr_mutex.unlock(); return INVALID_POINT; --- 11772,11776 ---- cerr << "ERROR! In Point::get_normal():\n" << "The Points do not determine a plane.\n" ! << "Returning INVALID_POINT.\n\n"; cerr_mutex.unlock(); return INVALID_POINT; *************** *** 11829,11833 **** cerr << "WARNING! In Point::is_in_triangle():\n" << "The Point arguments do not determine a plane.\n" ! << "Returning false.\n\n" << flush; } return false; --- 11881,11885 ---- cerr << "WARNING! In Point::is_in_triangle():\n" << "The Point arguments do not determine a plane.\n" ! << "Returning false.\n\n"; } return false; *************** *** 11840,11844 **** << "*this doesn't lie in the plane determined " << "by the arguments.\n" ! << "Returning false.\n\n" << flush; } return false; --- 11892,11896 ---- << "*this doesn't lie in the plane determined " << "by the arguments.\n" ! << "Returning false.\n\n"; } return false; *************** *** 11885,11893 **** bool exchange_y_z = false; bool exchange_x_z = false; ! if (lambda_denominator == 0 || mu_denominator == 0) { if (DEBUG) cerr << "lambda_denominator or mu_denominator == 0. " ! << "Exchanging y and z-coordinates.\n" << flush; real temp; --- 11937,11945 ---- bool exchange_y_z = false; bool exchange_x_z = false; ! if (lambda_denominator == ZERO_REAL || mu_denominator == ZERO_REAL) { if (DEBUG) cerr << "lambda_denominator or mu_denominator == 0. " ! << "Exchanging y and z-coordinates.\n"; real temp; *************** *** 11912,11921 **** ! if (!(lambda_denominator == 0 || mu_denominator == 0)) { if (DEBUG) cerr << "Exchanging y and z-coordinates worked.\n" ! << "lambda_denominator and mu_denominator are no longer 0.\n" ! << flush; exchange_y_z = true; } --- 11964,11973 ---- ! if (!(lambda_denominator == ZERO_REAL || mu_denominator == ZERO_REAL)) { if (DEBUG) cerr << "Exchanging y and z-coordinates worked.\n" ! << "lambda_denominator and mu_denominator are no longer 0.\n"; ! exchange_y_z = true; } *************** *** 11924,11929 **** if (DEBUG) cerr << "Exchanging y and z-coordinates didn't work.\n" ! << "Exchanging x and z-coordinates.\n" ! << flush; @ First, put things back the way they were. --- 11976,11980 ---- if (DEBUG) cerr << "Exchanging y and z-coordinates didn't work.\n" ! << "Exchanging x and z-coordinates.\n"; @ First, put things back the way they were. *************** *** 11970,11979 **** mu_denominator = ((e_x - c_x) * (d_y - c_y)) - ((e_y - c_y) * (d_x - c_x)); ! if (!(lambda_denominator == 0 || mu_denominator == 0)) { if (DEBUG) cerr << "Exchanging x and z-coordinates worked.\n" ! << "lambda_denominator and mu_denominator are no longer 0.\n" ! << flush; exchange_x_z = true; } --- 12021,12030 ---- mu_denominator = ((e_x - c_x) * (d_y - c_y)) - ((e_y - c_y) * (d_x - c_x)); ! if (!(lambda_denominator == ZERO_REAL || mu_denominator == ZERO_REAL)) { if (DEBUG) cerr << "Exchanging x and z-coordinates worked.\n" ! << "lambda_denominator and mu_denominator are no longer 0.\n"; ! exchange_x_z = true; } *************** *** 11984,11988 **** cerr << "WARNING! In Point::is_in_triangle():\n" << "lambda_denominator or mu_denominator is 0.\n" ! << "Returning false.\n\n" << flush; } return false; --- 12035,12039 ---- cerr << "WARNING! In Point::is_in_triangle():\n" << "lambda_denominator or mu_denominator is 0.\n" ! << "Returning false.\n\n"; } return false; *************** *** 11999,12008 **** if (DEBUG) { ! cerr << "lambda == " << lambda << endl << flush; ! cerr << "mu == " << mu << endl << flush; ! cerr << "lambda + mu == " << lambda + mu << endl << flush; cerr << "(lambda >= 0 && mu >= 0 && ((lambda + mu) <= 1)) == " ! << (lambda >= 0 && mu >= 0 && ((lambda + mu) <= 1)) << endl << flush; } --- 12050,12059 ---- if (DEBUG) { ! cerr << "lambda == " << lambda << endl; ! cerr << "mu == " << mu << endl; ! cerr << "lambda + mu == " << lambda + mu << endl; cerr << "(lambda >= 0 && mu >= 0 && ((lambda + mu) <= 1)) == " ! << (lambda >= 0 && mu >= 0 && ((lambda + mu) <= 1)) << endl; } *************** *** 12018,12022 **** cerr << "The Point doesn't lie within the triangle. " << "Returning false."; ! cerr << endl << endl << flush; } return b; --- 12069,12073 ---- cerr << "The Point doesn't lie within the triangle. " << "Returning false."; ! cerr << endl << endl; } return b; *************** *** 12181,12185 **** Path::adjust_draw_color_vector(void) { ! if (draw_color_vector == 0 || draw_color_vector->ctr <= 0) return 1; --- 12232,12237 ---- Path::adjust_draw_color_vector(void) { ! if ( draw_color_vector == static_cast*>(0) ! || draw_color_vector->ctr <= 0) return 1; *************** *** 12227,12231 **** Path::adjust_pen_vector(void) { ! if (pen_vector == 0 || pen_vector->ctr <= 0) return 1; --- 12279,12283 ---- Path::adjust_pen_vector(void) { ! if (pen_vector == static_cast*>(0) || pen_vector->ctr <= 0) return 1; *************** *** 12273,12277 **** Path::adjust_dash_pattern_vector(void) { ! if (dash_pattern_vector == 0 || dash_pattern_vector->ctr <= 0) return 1; --- 12325,12330 ---- Path::adjust_dash_pattern_vector(void) { ! if ( dash_pattern_vector == static_cast*>(0) ! || dash_pattern_vector->ctr <= 0) return 1; *************** *** 12594,12598 **** { cerr << "Haven't coded this case yet. " ! << "Returning INVALID_BOOL_POINT.\n" << flush; return INVALID_BOOL_POINT; } --- 12647,12651 ---- { cerr << "Haven't coded this case yet. " ! << "Returning INVALID_BOOL_POINT.\n"; return INVALID_BOOL_POINT; } *************** *** 12652,12656 **** cerr << "ERROR! In Plane::intersection_point(const Path&):" << endl << "Path is not linear! Returning INVALID_BOOL_POINT." ! << endl << endl << flush; return INVALID_BOOL_POINT; } --- 12705,12709 ---- cerr << "ERROR! In Plane::intersection_point(const Path&):" << endl << "Path is not linear! Returning INVALID_BOOL_POINT." ! << endl << endl; return INVALID_BOOL_POINT; } *************** *** 12800,12806 **** ! x_pt = (shift_x != 0) ? *shift_x : origin_pt; ! y_pt = (shift_y != 0) ? *shift_y : origin_pt; ! z_pt = (shift_z != 0) ? *shift_z : origin_pt; @ --- 12853,12859 ---- ! x_pt = (shift_x != static_cast(0)) ? *shift_x : origin_pt; ! y_pt = (shift_y != static_cast(0)) ? *shift_y : origin_pt; ! z_pt = (shift_z != static_cast(0)) ? *shift_z : origin_pt; @ *************** *** 12813,12817 **** cerr << "WARNING! In draw_axes():" << endl << "All axes are suppressed. Returning." ! << endl << endl << flush; return; } --- 12866,12870 ---- cerr << "WARNING! In draw_axes():" << endl << "All axes are suppressed. Returning." ! << endl << endl; return; } *************** *** 12938,12942 **** { cerr << "ERROR! In Path::get_line():\n" ! << "Path is not linear. Returning INVALID_LINE.\n\n" << flush; return INVALID_LINE; } --- 12991,12995 ---- { cerr << "ERROR! In Path::get_line():\n" ! << "Path is not linear. Returning INVALID_LINE.\n\n"; return INVALID_LINE; } *************** *** 13121,13127 **** @q ***** (5) Preliminaries.@> ! #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; ! #endif /* |DEBUG_COMPILE| */@; stringstream cerr_strm; --- 13174,13178 ---- @q ***** (5) Preliminaries.@> ! volatile bool DEBUG = false; /* |true| */ @; stringstream cerr_strm; *************** *** 13161,13165 **** @= ! if (p == 0 || pv == 0) { cerr_strm << "ERROR! In `Path::decompose':" --- 13212,13216 ---- @= ! if (p == static_cast(0) || pv == static_cast*>(0)) { cerr_strm << "ERROR! In `Path::decompose':" *************** *** 13230,13234 **** @= ! if (br.second == 0 || br.second == 1) { #if DEBUG_COMPILE --- 13281,13285 ---- @= ! if (br.second == ZERO_REAL || br.second == 1) { #if DEBUG_COMPILE *************** *** 13734,13738 **** ! if (blend_value_denominator != 0) *C_of_u /= blend_value_denominator; --- 13785,13789 ---- ! if (blend_value_denominator != ZERO_REAL) *C_of_u /= blend_value_denominator; *************** *** 13876,13882 **** @q ***** (5) Preliminaries.@> ! #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; ! #endif /* |DEBUG_COMPILE| */@; stringstream cerr_strm; --- 13927,13931 ---- @q ***** (5) Preliminaries.@> ! volatile bool DEBUG = false; /* |true| */ @; stringstream cerr_strm; *************** *** 13941,13944 **** --- 13990,14005 ---- } + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + position.show("position:"); + direction.show("direction:"); + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + @q ***** (5)@> *************** *** 13992,13998 **** normal.shift(position); real temp_angle = (up - position).angle(direction - position); ! up.rotate(normal, position, 90 - temp_angle); if (up.get_y() < 0) --- 14053,14091 ---- normal.shift(position); + + Point temp_pt[2]; + + temp_pt[0] = (up - position); + temp_pt[1] = (direction - position); + real temp_angle = (up - position).angle(direction - position); ! #if DEBUG_COMPILE ! if (DEBUG) ! { ! cerr_mutex.lock(); ! temp_pt[0].show("temp_pt[0]:"); ! temp_pt[1].show("temp_pt[1]:"); ! ! cerr << "temp_angle == " << temp_angle << endl; ! up.show("up before rotation:"); ! cerr_mutex.unlock(); ! ! } /* |if (DEBUG)| */ ! #endif /* |DEBUG_COMPILE| */ ! ! up.rotate(normal, position, 90 - temp_angle); ! ! #if DEBUG_COMPILE ! if (DEBUG) ! { ! cerr_mutex.lock(); ! up.show("up after rotation:"); ! cerr << "up.get_y == " << up.get_y() << endl ! << "(up.get_y() < 0.0F) " << (up.get_y() < 0.0F) << endl; ! cerr_mutex.unlock(); ! ! } /* |if (DEBUG)| */ ! #endif /* |DEBUG_COMPILE| */ if (up.get_y() < 0) *************** *** 14183,14187 **** @q ****** (6)@> ! } /* |if (angle != 0)| */ @q ***** (5)@> --- 14276,14280 ---- @q ****** (6)@> ! } /* |if (fabs(angle) > tolerance)| */ @q ***** (5)@> diff -rc2P 3DLDF-2.0.2/src/patterns.web 3DLDF-2.0.3/src/patterns.web *** 3DLDF-2.0.2/src/patterns.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/patterns.web Fri Dec 13 11:40:23 2013 *************** *** 269,305 **** } - @ - - \LOG - \initials{LDF 2002.09.22.} - This is necessary, because |Path::fill()| interprets ``|""|'' - as |"black"|. In |hex_pattern_1()|, it may be necessary to have a - placeholder for a |fill_color|, and it's better to be able to use - ``|""|'' than to have to type ``|background|''. - - \initials{LDF 2002.09.24.} Changed this, because I'm now using - |class Color| instead of |strings|. Now it looks like I'm going to have - to use ``|*Colors::background_color|'' as a placeholder. - I'm going to have to check to see what the consequences - of this change are here. - - \initials{LDF 2004.06.07.} Now setting - |fill_color_outer = 0| instead of - |fill_color_outer = Colors::background_color|, because I've gotten rid of - |Colors::background_color|. - \ENDLOG - - @= - if (fill_color_outer == 0) - - - fill_color_outer = 0; - - if (fill_color_middle == 0) - fill_color_middle = 0; - - if (fill_color_inner == 0) - fill_color_inner = 0; - @ Having |do_middle| and |do_inner| is a convenience, so I don't have to check whether |diameter_middle| and |diameter_inner| are $\equiv 0$ below, which --- 269,272 ---- *************** *** 312,317 **** bool do_inner; ! do_middle = (diameter_middle == 0) ? false : true; ! do_inner = (diameter_inner == 0) ? false : true; @ --- 279,284 ---- bool do_inner; ! do_middle = (diameter_middle == ZERO_REAL) ? false : true; ! do_inner = (diameter_inner == ZERO_REAL) ? false : true; @ *************** *** 490,494 **** for (i = i_min; i < i_max; ++i) { ! if (fill_color_outer == 0) p_outer_copy.draw(picture, draw_color_outer, 0, &pen_outer); --- 457,461 ---- for (i = i_min; i < i_max; ++i) { ! if (fill_color_outer == static_cast(0)) p_outer_copy.draw(picture, draw_color_outer, 0, &pen_outer); diff -rc2P 3DLDF-2.0.2/src/pblexpr.w 3DLDF-2.0.3/src/pblexpr.w *** 3DLDF-2.0.2/src/pblexpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/pblexpr.w Fri Dec 13 12:06:55 2013 *************** *** 119,126 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 119,126 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 362,366 **** @q **** (4).@> ! if (entry == 0) { --- 362,366 ---- @q **** (4).@> ! if (entry == static_cast(0)) { *************** *** 424,428 **** @q **** (4).@> ! if (entry == 0) { --- 424,428 ---- @q **** (4).@> ! if (entry == static_cast(0)) { *************** *** 513,519 **** Point* p = static_cast(@=$2@>); ! *b = (p == 0 || *p == INVALID_POINT) ? false : true; ! delete p; @=$$@> = static_cast(b); --- 513,524 ---- Point* p = static_cast(@=$2@>); ! *b = ( p == static_cast(0) ! || *p == INVALID_POINT) ? false : true; ! if (p) ! { ! delete p; ! p = static_cast(0); ! } @=$$@> = static_cast(b); *************** *** 537,543 **** Point* p = static_cast(@=$2@>); ! *b = (p == 0 || *p == INVALID_POINT) ? true : false; ! delete p; @=$$@> = static_cast(b); --- 542,552 ---- Point* p = static_cast(@=$2@>); ! *b = (p == static_cast(0) || *p == INVALID_POINT) ? true : false; ! if (p) ! { ! delete p; ! p = 0; ! } @=$$@> = static_cast(b); *************** *** 566,570 **** = static_cast*>(@=$2@>); ! *b = (bpv == 0 || bpv->v.size() <= 0) ? false : true; delete bpv; --- 575,580 ---- = static_cast*>(@=$2@>); ! *b = ( bpv == static_cast*>(0) ! || bpv->v.size() <= 0) ? false : true; delete bpv; *************** *** 595,599 **** Pointer_Vector* bpv = static_cast*>(@=$2@>); ! *b = (bpv == 0 || bpv->v.size() <= 0) ? true : false; delete bpv; --- 605,610 ---- Pointer_Vector* bpv = static_cast*>(@=$2@>); ! *b = ( bpv == static_cast*>(0) ! || bpv->v.size() <= 0) ? true : false; delete bpv; *************** *** 681,685 **** @= ! if (entry == 0) { --- 692,696 ---- @= ! if (entry == static_cast(0)) { *************** *** 2070,2074 **** Path* q = static_cast(@=$3@>); ! *i = (p && q != 0 && p->is_coplanar(*q)) ? 1 : 0; delete p; --- 2081,2085 ---- Path* q = static_cast(@=$3@>); ! *i = (p && q && p->is_coplanar(*q)) ? 1 : 0; delete p; *************** *** 2646,2650 **** delete p; delete e; ! @=$$@> = 0; } --- 2657,2661 ---- delete p; delete e; ! @=$$@> = static_cast(0); } *************** *** 2684,2689 **** { - - Bool_Point* bp = static_cast(@=$1@>); --- 2695,2698 ---- *************** *** 2694,2698 **** delete bp; delete e; ! @=$$@> = 0; } --- 2703,2707 ---- delete bp; delete e; ! @=$$@> = static_cast(0); } *************** *** 2858,2862 **** bool* b = new bool; ! *b = (pv == 0) ? false : pv->are_distinct(@=$3@>, 10, parameter); delete pv; --- 2867,2872 ---- bool* b = new bool; ! *b = (pv == static_cast*>(0)) ? ! false : pv->are_distinct(@=$3@>, 10, parameter); delete pv; *************** *** 2889,2893 **** bool* b = new bool; ! *b = (pv == 0) ? false : pv->are_distinct(@=$3@>, 10, parameter); delete pv; --- 2899,2904 ---- bool* b = new bool; ! *b = (pv == static_cast*>(0)) ? ! false : pv->are_distinct(@=$3@>, 10, parameter); delete pv; *************** *** 2923,2927 **** @=predicate_clause: /* Empty */@>@/ { ! @=$$@> = 0; } --- 2934,2938 ---- @=predicate_clause: /* Empty */@>@/ { ! @=$$@> = static_cast(0); } *************** *** 2946,2950 **** *(scanner_node->tolerance) = @=$2@>; ! @=$$@> = 0; } --- 2957,2961 ---- *(scanner_node->tolerance) = @=$2@>; ! @=$$@> = static_cast(0); } *************** *** 3093,3097 **** @= ! if (pv == 0) { --- 3104,3108 ---- @= ! if (pv == static_cast*>(0)) { *************** *** 3378,3382 **** @= ! if (p == 0 || q == 0) { --- 3389,3393 ---- @= ! if (p == static_cast(0) || q == static_cast(0)) { diff -rc2P 3DLDF-2.0.2/src/pblvexpr.w 3DLDF-2.0.3/src/pblvexpr.w *** 3DLDF-2.0.2/src/pblvexpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/pblvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 99,106 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 99,106 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pbpexpr.w 3DLDF-2.0.3/src/pbpexpr.w *** 3DLDF-2.0.2/src/pbpexpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/pbpexpr.w Fri Dec 13 12:14:30 2013 *************** *** 104,108 **** @= ! if (entry == 0 || entry->object == 0) { --- 104,108 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 261,269 **** @= ! if (bpv == 0) { delete bp; ! @=$$@> = 0; } /* |if (bpv == 0)| */ --- 261,269 ---- @= ! if (bpv == static_cast*>(0)) { delete bp; ! @=$$@> = static_cast(0); } /* |if (bpv == 0)| */ *************** *** 281,285 **** delete bp; ! @=$$@> = 0; } /* |else if (bpv->ctr == 0)| */ --- 281,285 ---- delete bp; ! @=$$@> = static_cast(0); } /* |else if (bpv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pbpvexpr.w 3DLDF-2.0.3/src/pbpvexpr.w *** 3DLDF-2.0.2/src/pbpvexpr.w Thu Nov 7 13:36:07 2013 --- 3DLDF-2.0.3/src/pbpvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 1314,1318 **** if (!(e && p)) ! @=$$@> = 0; else --- 1314,1318 ---- if (!(e && p)) ! @=$$@> = static_cast(0); else *************** *** 1354,1358 **** if (!(e && p)) ! @=$$@> = 0; else --- 1354,1358 ---- if (!(e && p)) ! @=$$@> = static_cast(0); else *************** *** 1439,1443 **** if (!(c && p)) ! @=$$@> = 0; else --- 1439,1443 ---- if (!(c && p)) ! @=$$@> = static_cast(0); else *************** *** 1473,1477 **** if (!(c && p)) ! @=$$@> = 0; else --- 1473,1477 ---- if (!(c && p)) ! @=$$@> = static_cast(0); else diff -rc2P 3DLDF-2.0.2/src/pbsndecl.w 3DLDF-2.0.3/src/pbsndecl.w *** 3DLDF-2.0.2/src/pbsndecl.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pbsndecl.w Mon Nov 11 18:43:06 2013 *************** *** 203,211 **** @= #define YYPARSE_PARAM parameter #define YYLEX_PARAM parameter #define YYLTYPE LDF_LOCATION_TYPE #define YYLOC_DEFAULT(Current, Rhs, N) /* Do nothing. */ ! @q #if DEBUG_COMPILE @> --- 203,212 ---- @= + #if 0 #define YYPARSE_PARAM parameter #define YYLEX_PARAM parameter #define YYLTYPE LDF_LOCATION_TYPE #define YYLOC_DEFAULT(Current, Rhs, N) /* Do nothing. */ ! #endif @q #if DEBUG_COMPILE @> *************** *** 223,228 **** @= #define YYERROR_VERBOSE ! --- 224,230 ---- @= + #if 0 #define YYERROR_VERBOSE ! #endif *************** *** 256,262 **** @=%debug@>@/ @q =%expect 1@>@/ ! @=%locations@>@/ @q =%glr-parser@>@/ @=%pure_parser@>@/ @=/* %token_table */@>@/ @=%verbose@> --- 258,266 ---- @=%debug@>@/ @q =%expect 1@>@/ ! @q =%locations@>@/ @q =%glr-parser@>@/ @=%pure_parser@>@/ + @=%parse-param {yyscan_t parameter}@>@;@/ + @=%lex-param {yyscan_t parameter}@>@;@/ @=/* %token_table */@>@/ @=%verbose@> diff -rc2P 3DLDF-2.0.2/src/pcbvexpr.w 3DLDF-2.0.3/src/pcbvexpr.w *** 3DLDF-2.0.2/src/pcbvexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcbvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pcirexpr.w 3DLDF-2.0.3/src/pcirexpr.w *** 3DLDF-2.0.2/src/pcirexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcirexpr.w Fri Dec 13 12:16:07 2013 *************** *** 93,97 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 93,97 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 164,173 **** @= ! if (t == 0) { delete s; ! @=$$@> = 0; } /* |if (t == 0)| */ --- 164,173 ---- @= ! if (t == static_cast(0)) { delete s; ! @=$$@> = static_cast(0); } /* |if (t == 0)| */ *************** *** 250,254 **** @=$$@> = (c) ? c->get_circle(static_cast(parameter)) ! : @=$$@> = 0; }; --- 250,254 ---- @=$$@> = (c) ? c->get_circle(static_cast(parameter)) ! : @=$$@> = static_cast(0); }; *************** *** 343,352 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 343,352 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 364,368 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 364,368 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pclrcmnd.w 3DLDF-2.0.3/src/pclrcmnd.w *** 3DLDF-2.0.2/src/pclrcmnd.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pclrcmnd.w Fri Dec 13 12:04:41 2013 *************** *** 80,84 **** static_cast(@=$2@>)); ! @=$$@> = 0; }; --- 80,84 ---- static_cast(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 111,117 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 111,117 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 129,133 **** p->clear_connectors(); ! @=$$@> = 0; }; --- 129,133 ---- p->clear_connectors(); ! @=$$@> = static_cast(0); }; *************** *** 156,162 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 156,162 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 174,178 **** entry->object = 0; ! @=$$@> = 0; }; --- 174,178 ---- entry->object = 0; ! @=$$@> = static_cast(0); }; *************** *** 200,206 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 200,206 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 222,226 **** static_cast(entry->object)->clear(); ! @=$$@> = 0; }; --- 222,226 ---- static_cast(entry->object)->clear(); ! @=$$@> = static_cast(0); }; *************** *** 243,247 **** delete static_cast(entry->object); entry->object = 0; ! @=$$@> = 0; }; --- 243,247 ---- delete static_cast(entry->object); entry->object = 0; ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pclvexpr.w 3DLDF-2.0.3/src/pclvexpr.w *** 3DLDF-2.0.2/src/pclvexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pclvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pcnvexpr.w 3DLDF-2.0.3/src/pcnvexpr.w *** 3DLDF-2.0.2/src/pcnvexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcnvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pcolexpr.w 3DLDF-2.0.3/src/pcolexpr.w *** 3DLDF-2.0.2/src/pcolexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcolexpr.w Fri Dec 13 12:18:45 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 157,166 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 157,166 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 177,181 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 177,181 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 235,241 **** @= ! if (c == 0) { ! @=$$@> = 0; } /* |if (c == 0)| */ --- 235,241 ---- @= ! if (c == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (c == 0)| */ *************** *** 268,272 **** @= ! if (r == 0) { --- 268,272 ---- @= ! if (r == ZERO_REAL) { *************** *** 291,295 **** c = 0; ! @=$$@> = 0; --- 291,295 ---- c = 0; ! @=$$@> = static_cast(0); *************** *** 378,385 **** @= ! if (c == 0) { ! @=$$@> = 0; } /* |if (c == 0)| */ --- 378,385 ---- @= ! if (c == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (c == 0)| */ *************** *** 431,437 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 431,437 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 510,514 **** @q **** (4) @> ! if (c == 0 || d == 0) { --- 510,514 ---- @q **** (4) @> ! if (c == static_cast(0) || d == static_cast(0)) { *************** *** 516,523 **** delete d; ! c = 0; ! d = 0; ! @=$$@> = 0; } /* |if (c == 0 || d == 0)| */ --- 516,523 ---- delete d; ! c = static_cast(0); ! d = static_cast(0); ! @=$$@> = static_cast(0); } /* |if (c == 0 || d == 0)| */ *************** *** 568,580 **** @q **** (4) @> ! if (c == 0 || d == 0) { delete c; delete d; ! c = 0; ! d = 0; ! @=$$@> = 0; } /* |if (c == 0 || d == 0)| */ --- 568,580 ---- @q **** (4) @> ! if (c == static_cast(0) || d == static_cast(0)) { delete c; delete d; ! c = static_cast(0); ! d = static_cast(0); ! @=$$@> = static_cast(0); } /* |if (c == 0 || d == 0)| */ *************** *** 598,602 **** delete d; ! d = 0; }; --- 598,602 ---- delete d; ! d = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pcommand.w 3DLDF-2.0.3/src/pcommand.w *** 3DLDF-2.0.2/src/pcommand.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcommand.w Fri Dec 13 12:19:25 2013 *************** *** 127,131 **** clip_to_func(@=$2@>, parameter); ! @=$$@> = 0; }; --- 127,131 ---- clip_to_func(@=$2@>, parameter); ! @=$$@> = static_cast(0); }; *************** *** 226,230 **** Scan_Parse::message_command_func(@=$1@>, @=$2@>, parameter); ! @=$$@> = 0; }; --- 226,230 ---- Scan_Parse::message_command_func(@=$1@>, @=$2@>, parameter); ! @=$$@> = static_cast(0); }; *************** *** 252,256 **** cerr_mutex.unlock(); ! @=$$@> = 0; }; --- 252,256 ---- cerr_mutex.unlock(); ! @=$$@> = static_cast(0); }; *************** *** 271,278 **** string* str_ptr = static_cast(@=$2@>); ! if (str_ptr == 0) { ! @=$$@> = 0; } /* |if (str_ptr == 0)| */ --- 271,278 ---- string* str_ptr = static_cast(@=$2@>); ! if (str_ptr == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (str_ptr == 0)| */ *************** *** 300,304 **** static_cast(parameter)->in = curr_input_struct; ! @=$$@> = 0; } /* |else| (|str_ptr != 0|) */ --- 300,304 ---- static_cast(parameter)->in = curr_input_struct; ! @=$$@> = static_cast(0); } /* |else| (|str_ptr != 0|) */ *************** *** 330,336 **** @= ! if (s == 0) { ! @=$$@> = 0; } /* |s == 0| */ --- 330,336 ---- @= ! if (s == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |s == 0| */ *************** *** 377,381 **** delete s; ! @=$$@> = 0; @q ***** (5).@> --- 377,381 ---- delete s; ! @=$$@> = static_cast(0); @q ***** (5).@> diff -rc2P 3DLDF-2.0.2/src/pcondit.w 3DLDF-2.0.3/src/pcondit.w *** 3DLDF-2.0.2/src/pcondit.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcondit.w Mon Nov 11 18:43:06 2013 *************** *** 368,381 **** @@; ! if (scanner_node->in->type == Io_Struct::FILE_TYPE) ! { ! location_strm << scanner_node->in->filename << ": " ! << @=@@1@>@=.first_line@> << ":" << @=@@1@>@=.first_column@> ! << "--" ! << @=@@1@>@=.last_line@> << ":" << @=@@1@>@=.last_column@>; ! } ! else location_strm.str(""); @q ****** (6).@> --- 368,382 ---- @@; ! #if 0 ! @q if (scanner_node->in->type == Io_Struct::FILE_TYPE) @> ! @q { @> ! @q location_strm << scanner_node->in->filename << ": " @> ! @q << @@=@@1@@>@@=.first_line@@> << ":" << @@=@@1@@>@@=.first_column@@> @> ! @q << "--" @> ! @q << @@=@@1@@>@@=.last_line@@> << ":" << @@=@@1@@>@@=.last_column@@>; @> ! @q } @> else location_strm.str(""); + #endif @q ****** (6).@> diff -rc2P 3DLDF-2.0.2/src/pconexpr.w 3DLDF-2.0.3/src/pconexpr.w *** 3DLDF-2.0.2/src/pconexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pconexpr.w Fri Dec 13 12:22:56 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 155,164 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 155,164 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 176,180 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 176,180 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pcrclslc.w 3DLDF-2.0.3/src/pcrclslc.w *** 3DLDF-2.0.2/src/pcrclslc.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcrclslc.w Fri Dec 13 12:04:41 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { diff -rc2P 3DLDF-2.0.2/src/pcrvexpr.w 3DLDF-2.0.3/src/pcrvexpr.w *** 3DLDF-2.0.2/src/pcrvexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcrvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 243,247 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 243,247 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/pctfncs0.web 3DLDF-2.0.3/src/pctfncs0.web *** 3DLDF-2.0.2/src/pctfncs0.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/pctfncs0.web Fri Dec 13 12:25:12 2013 *************** *** 774,778 **** @q ********* (9) @> ! if (ivp.v == 0) { --- 774,778 ---- @q ********* (9) @> ! if (ivp.v == static_cast(0)) { *************** *** 800,804 **** @q ********** (10) @> ! if (pv == 0 || pv->ctr <= 0) { #if DEBUG_COMPILE --- 800,805 ---- @q ********** (10) @> ! if ( pv == static_cast*>(0) ! || pv->ctr <= 0) { #if DEBUG_COMPILE *************** *** 1083,1088 **** else if (status == 0) ! { ! } /* |if (status == 0)| */ --- 1084,1088 ---- else if (status == 0) ! ; /* Do nothing */ diff -rc2P 3DLDF-2.0.2/src/pcubexpr.w 3DLDF-2.0.3/src/pcubexpr.w *** 3DLDF-2.0.2/src/pcubexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcubexpr.w Fri Dec 13 12:25:58 2013 *************** *** 93,97 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 93,97 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 194,202 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 194,202 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 214,218 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 214,218 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pcylexpr.w 3DLDF-2.0.3/src/pcylexpr.w *** 3DLDF-2.0.2/src/pcylexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcylexpr.w Fri Dec 13 12:40:36 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 159,167 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 159,167 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 178,182 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 178,182 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pcyvexpr.w 3DLDF-2.0.3/src/pcyvexpr.w *** 3DLDF-2.0.2/src/pcyvexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pcyvexpr.w Fri Dec 13 12:04:41 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pdpvexpr.w 3DLDF-2.0.3/src/pdpvexpr.w *** 3DLDF-2.0.2/src/pdpvexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pdpvexpr.w Fri Dec 13 12:04:40 2013 *************** *** 96,108 **** @q **** (4) Error handling: |entry == 0 || entry->object == 0|.@> ! @ Error handling: |entry == 0 || entry->object == 0|. \initials{LDF 2005.01.13.} @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 96,108 ---- @q **** (4) Error handling: |entry == 0 || entry->object == 0|.@> ! @ Error handling: |entry == static_cast(0) || entry->object == 0|. \initials{LDF 2005.01.13.} @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pdrwcmnd.w 3DLDF-2.0.3/src/pdrwcmnd.w *** 3DLDF-2.0.2/src/pdrwcmnd.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pdrwcmnd.w Fri Dec 13 12:58:20 2013 *************** *** 399,403 **** static_cast*>(@=$2@>)); ! @=$$@> = 0; }; --- 399,403 ---- static_cast*>(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 427,431 **** static_cast*>(@=$2@>)); ! @=$$@> = 0; }; --- 427,431 ---- static_cast*>(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 455,459 **** static_cast*>(@=$2@>)); ! @=$$@> = 0; }; --- 455,459 ---- static_cast*>(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 483,487 **** static_cast*>(@=$2@>)); ! @=$$@> = 0; }; --- 483,487 ---- static_cast*>(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 511,515 **** static_cast*>(@=$2@>)); ! @=$$@> = 0; }; --- 511,515 ---- static_cast*>(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 539,543 **** static_cast*>(@=$2@>)); ! @=$$@> = 0; }; --- 539,543 ---- static_cast*>(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 567,571 **** static_cast*>(@=$2@>)); ! @=$$@> = 0; }; --- 567,571 ---- static_cast*>(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 606,610 **** ! @=$$@> = 0; }; --- 606,610 ---- ! @=$$@> = static_cast(0); }; *************** *** 634,638 **** ! @=$$@> = 0; }; --- 634,638 ---- ! @=$$@> = static_cast(0); }; *************** *** 662,666 **** ! @=$$@> = 0; }; --- 662,666 ---- ! @=$$@> = static_cast(0); }; *************** *** 690,694 **** ! @=$$@> = 0; }; --- 690,694 ---- ! @=$$@> = static_cast(0); }; *************** *** 718,722 **** static_cast(@=$2@>)); ! @=$$@> = 0; }; --- 718,722 ---- static_cast(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 747,751 **** ! @=$$@> = 0; }; --- 747,751 ---- ! @=$$@> = static_cast(0); }; *************** *** 776,780 **** ! @=$$@> = 0; }; --- 776,780 ---- ! @=$$@> = static_cast(0); }; *************** *** 813,817 **** { ! if (@=$2@> != 0) { Conic_Section_Lattice* c = static_cast(@=$2@>); --- 813,817 ---- { ! if (@=$2@> != static_cast(0)) { Conic_Section_Lattice* c = static_cast(@=$2@>); *************** *** 820,824 **** } ! @=$$@> = 0; }; --- 820,824 ---- } ! @=$$@> = static_cast(0); }; *************** *** 1017,1021 **** static_cast(@=$2@>)); ! @=$$@> = 0; }; --- 1017,1021 ---- static_cast(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 1053,1062 **** @= ! if (bp == 0 || bp->pt == INVALID_POINT) ! { ! ! ! } /* |if (bp == 0 || bp->pt == INVALID_POINT)| */ ! @q ***** (5) |bp != 0 && bp->pt != INVALID_POINT|.@> --- 1053,1058 ---- @= ! if (bp == static_cast(0) || bp->pt == INVALID_POINT) ! ; /* Do nothing */ @q ***** (5) |bp != 0 && bp->pt != INVALID_POINT|.@> *************** *** 1086,1090 **** delete bp; ! @=$$@> = 0; }; --- 1082,1086 ---- delete bp; ! @=$$@> = static_cast(0); }; *************** *** 1193,1197 **** delete bp; ! @=$$@> = 0; }; --- 1189,1193 ---- delete bp; ! @=$$@> = static_cast(0); }; *************** *** 1226,1230 **** { cerr << "\n*** Parser: drawdot_or_undrawdot --> DRAWDOT." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 1222,1226 ---- { cerr << "\n*** Parser: drawdot_or_undrawdot --> DRAWDOT." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 1252,1256 **** { cerr << "\n*** Parser: drawdot_or_undrawdot --> UNDRAWDOT." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 1248,1252 ---- { cerr << "\n*** Parser: drawdot_or_undrawdot --> UNDRAWDOT." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 1365,1369 **** #endif /* |DEBUG_COMPILE| */@; ! @=$$@> = 0; } --- 1361,1365 ---- #endif /* |DEBUG_COMPILE| */@; ! @=$$@> = static_cast(0); } *************** *** 1381,1385 **** { ! @=$$@> = 0; }; --- 1377,1381 ---- { ! @=$$@> = static_cast(0); }; *************** *** 1418,1422 **** static_cast(parameter)->color_vector_ptr = entry->object; ! @=$$@> = 0; }; --- 1414,1418 ---- static_cast(parameter)->color_vector_ptr = entry->object; ! @=$$@> = static_cast(0); }; *************** *** 1448,1452 **** static_cast(parameter)->draw_color_vector_ptr = entry->object; ! @=$$@> = 0; }; --- 1444,1448 ---- static_cast(parameter)->draw_color_vector_ptr = entry->object; ! @=$$@> = static_cast(0); }; *************** *** 1481,1485 **** static_cast(parameter)->fill_color_vector_ptr = entry->object; ! @=$$@> = 0; }; --- 1477,1481 ---- static_cast(parameter)->fill_color_vector_ptr = entry->object; ! @=$$@> = static_cast(0); }; *************** *** 1692,1696 **** @= ! if (p == 0) { #if 0 --- 1688,1692 ---- @= ! if (p == static_cast(0)) { #if 0 *************** *** 1729,1733 **** @= ! if (q == 0) { --- 1725,1729 ---- @= ! if (q == static_cast(0)) { *************** *** 1748,1752 **** ! @=$$@> = 0; }; --- 1744,1748 ---- ! @=$$@> = static_cast(0); }; *************** *** 1795,1799 **** } /* |if (status != 0)| */ ! @=$$@> = 0; }; --- 1791,1795 ---- } /* |if (status != 0)| */ ! @=$$@> = static_cast(0); }; *************** *** 1841,1845 **** } /* |if (status != 0)| */ ! @=$$@> = 0; }; --- 1837,1841 ---- } /* |if (status != 0)| */ ! @=$$@> = static_cast(0); }; *************** *** 1883,1887 **** } /* |if (status != 0)| */ ! @=$$@> = 0; }; --- 1879,1883 ---- } /* |if (status != 0)| */ ! @=$$@> = static_cast(0); }; *************** *** 1933,1937 **** } /* |if (status != 0)| */ ! @=$$@> = 0; }; --- 1929,1933 ---- } /* |if (status != 0)| */ ! @=$$@> = static_cast(0); }; *************** *** 1964,1968 **** "scanner_node->current_pen"); ! @=$$@> = 0; --- 1960,1964 ---- "scanner_node->current_pen"); ! @=$$@> = static_cast(0); *************** *** 1995,1999 **** "scanner_node->current_color"); ! @=$$@> = 0; }; --- 1991,1995 ---- "scanner_node->current_color"); ! @=$$@> = static_cast(0); }; *************** *** 2025,2029 **** "scanner_node->current_draw_color"); ! @=$$@> = 0; }; --- 2021,2025 ---- "scanner_node->current_draw_color"); ! @=$$@> = static_cast(0); }; *************** *** 2056,2060 **** ! @=$$@> = 0; }; --- 2052,2056 ---- ! @=$$@> = static_cast(0); }; *************** *** 2088,2092 **** ! @=$$@> = 0; }; --- 2084,2088 ---- ! @=$$@> = static_cast(0); }; *************** *** 2133,2137 **** ! @=$$@> = 0; }; --- 2129,2133 ---- ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pdshexpr.w 3DLDF-2.0.3/src/pdshexpr.w *** 3DLDF-2.0.2/src/pdshexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pdshexpr.w Fri Dec 13 12:43:59 2013 *************** *** 83,87 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 83,87 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 161,170 **** @= ! if (pv == 0) { delete p; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 161,170 ---- @= ! if (pv == static_cast*>(0)) { delete p; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 182,186 **** delete p; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 182,186 ---- delete p; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pedvexpr.w 3DLDF-2.0.3/src/pedvexpr.w *** 3DLDF-2.0.2/src/pedvexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pedvexpr.w Fri Dec 13 12:04:39 2013 *************** *** 99,106 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 99,106 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/peldexpr.w 3DLDF-2.0.3/src/peldexpr.w *** 3DLDF-2.0.2/src/peldexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/peldexpr.w Fri Dec 13 12:45:54 2013 *************** *** 89,98 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) ! { @=$$@> = static_cast(0); ! } /* |if (entry == 0 || entry->object == 0)| */ else /* |entry != 0 && entry->object != 0| */ --- 89,98 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) ! { @=$$@> = static_cast(0); ! } /* |if (entry == 0 || entry->object == 0)| */ else /* |entry != 0 && entry->object != 0| */ *************** *** 155,164 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 155,164 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 176,180 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 176,180 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pellexpr.w 3DLDF-2.0.3/src/pellexpr.w *** 3DLDF-2.0.2/src/pellexpr.w Thu Nov 7 13:36:06 2013 --- 3DLDF-2.0.3/src/pellexpr.w Fri Dec 13 12:59:30 2013 *************** *** 92,96 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 92,96 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 190,198 **** ! if (t == 0) { delete s; ! @=$$@> = 0; } /* |if (t == 0)| */ --- 190,198 ---- ! if (t == static_cast(0)) { delete s; ! @=$$@> = static_cast(0); } /* |if (t == 0)| */ *************** *** 277,281 **** @=$$@> = (c) ? c->get_ellipse(static_cast(parameter)) ! : @=$$@> = 0; }; --- 277,281 ---- @=$$@> = (c) ? c->get_ellipse(static_cast(parameter)) ! : @=$$@> = static_cast(0); }; *************** *** 379,388 **** @= ! if (pv == 0) { delete p; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 379,388 ---- @= ! if (pv == static_cast*>(0)) { delete p; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 400,404 **** delete p; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 400,404 ---- delete p; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pellpslc.w 3DLDF-2.0.3/src/pellpslc.w *** 3DLDF-2.0.2/src/pellpslc.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pellpslc.w Fri Dec 13 11:59:36 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { diff -rc2P 3DLDF-2.0.2/src/pelvexpr.w 3DLDF-2.0.3/src/pelvexpr.w *** 3DLDF-2.0.2/src/pelvexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pelvexpr.w Fri Dec 13 11:59:36 2013 *************** *** 116,120 **** @= ! if (entry == 0 || entry->object == 0) { --- 116,120 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 133,137 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 133,137 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 308,312 **** if (status != 0) { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 308,312 ---- if (status != 0) { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/pens.web 3DLDF-2.0.3/src/pens.web *** 3DLDF-2.0.2/src/pens.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/pens.web Wed Dec 11 18:42:22 2013 *************** *** 349,354 **** { cerr << "ERROR! In Pen::show():\n" ! << "Invalid `type': " << type << endl ! << flush; return_value = false; --- 349,353 ---- { cerr << "ERROR! In Pen::show():\n" ! << "Invalid `type': " << type << endl; return_value = false; diff -rc2P 3DLDF-2.0.2/src/pfcvexpr.w 3DLDF-2.0.3/src/pfcvexpr.w *** 3DLDF-2.0.2/src/pfcvexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pfcvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 116,120 **** @= ! if (entry == 0 || entry->object == 0) { --- 116,120 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 133,137 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 133,137 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 292,296 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 292,296 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/pfgopcmd.w 3DLDF-2.0.3/src/pfgopcmd.w *** 3DLDF-2.0.2/src/pfgopcmd.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pfgopcmd.w Fri Dec 13 13:03:30 2013 *************** *** 91,95 **** Scan_Parse::beginfig_func(scanner_node, i); ! @=$$@> = 0; }; --- 91,95 ---- Scan_Parse::beginfig_func(scanner_node, i); ! @=$$@> = static_cast(0); }; *************** *** 171,175 **** Scan_Parse::output_command_func(scanner_node); ! @=$$@> = 0; }; --- 171,175 ---- Scan_Parse::output_command_func(scanner_node); ! @=$$@> = static_cast(0); }; *************** *** 197,201 **** delete s; ! @=$$@> = 0; }; --- 197,201 ---- delete s; ! @=$$@> = static_cast(0); }; *************** *** 228,232 **** { ! @=$$@> = 0; }; --- 228,232 ---- { ! @=$$@> = static_cast(0); }; *************** *** 264,268 **** { ! @=$$@> = 0; }; --- 264,268 ---- { ! @=$$@> = static_cast(0); }; *************** *** 314,318 **** Scan_Parse::output_command_func(scanner_node); ! @=$$@> = 0; }; --- 314,318 ---- Scan_Parse::output_command_func(scanner_node); ! @=$$@> = static_cast(0); }; *************** *** 343,347 **** { ! @=$$@> = 0; }; --- 343,347 ---- { ! @=$$@> = static_cast(0); }; *************** *** 362,366 **** { ! @=$$@> = 0; }; --- 362,366 ---- { ! @=$$@> = static_cast(0); }; *************** *** 395,399 **** bool* b; ! if (scanner_node->clear_ptr == 0) b = new bool; --- 395,399 ---- bool* b; ! if (scanner_node->clear_ptr == static_cast(0)) b = new bool; *************** *** 420,424 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->focus_ptr != 0) delete static_cast(scanner_node->focus_ptr); --- 420,424 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->focus_ptr != static_cast(0)) delete static_cast(scanner_node->focus_ptr); *************** *** 448,452 **** *i = @=$2@>; ! if (scanner_node->projection_ptr != 0) delete static_cast(scanner_node->projection_ptr); --- 448,452 ---- *i = @=$2@>; ! if (scanner_node->projection_ptr != static_cast(0)) delete static_cast(scanner_node->projection_ptr); *************** *** 477,481 **** real* r; ! if (scanner_node->factor_ptr != 0) r = static_cast(scanner_node->factor_ptr); else --- 477,481 ---- real* r; ! if (scanner_node->factor_ptr != static_cast(0)) r = static_cast(scanner_node->factor_ptr); else *************** *** 536,540 **** *i = Sorting::MAX_Z; ! if (scanner_node->sort_value_ptr != 0) delete static_cast(scanner_node->sort_value_ptr); --- 536,540 ---- *i = Sorting::MAX_Z; ! if (scanner_node->sort_value_ptr != static_cast(0)) delete static_cast(scanner_node->sort_value_ptr); *************** *** 561,565 **** *i = Sorting::MIN_Z; ! if (scanner_node->sort_value_ptr != 0) delete static_cast(scanner_node->sort_value_ptr); --- 561,565 ---- *i = Sorting::MIN_Z; ! if (scanner_node->sort_value_ptr != static_cast(0)) delete static_cast(scanner_node->sort_value_ptr); *************** *** 586,590 **** *i = Sorting::MEAN_Z; ! if (scanner_node->sort_value_ptr != 0) delete static_cast(scanner_node->sort_value_ptr); --- 586,590 ---- *i = Sorting::MEAN_Z; ! if (scanner_node->sort_value_ptr != static_cast(0)) delete static_cast(scanner_node->sort_value_ptr); *************** *** 611,615 **** *i = Sorting::SUPPRESS_SORT; ! if (scanner_node->sort_value_ptr != 0) delete static_cast(scanner_node->sort_value_ptr); --- 611,615 ---- *i = Sorting::SUPPRESS_SORT; ! if (scanner_node->sort_value_ptr != static_cast(0)) delete static_cast(scanner_node->sort_value_ptr); *************** *** 670,674 **** real* r; ! if (scanner_node->factor_ptr != 0) r = static_cast(scanner_node->min_x_proj_ptr); else --- 670,674 ---- real* r; ! if (scanner_node->factor_ptr != static_cast(0)) r = static_cast(scanner_node->min_x_proj_ptr); else *************** *** 707,711 **** real* r; ! if (scanner_node->factor_ptr != 0) r = static_cast(scanner_node->max_x_proj_ptr); else --- 707,711 ---- real* r; ! if (scanner_node->factor_ptr != static_cast(0)) r = static_cast(scanner_node->max_x_proj_ptr); else *************** *** 740,744 **** real* r; ! if (scanner_node->factor_ptr != 0) r = static_cast(scanner_node->min_y_proj_ptr); else --- 740,744 ---- real* r; ! if (scanner_node->factor_ptr != static_cast(0)) r = static_cast(scanner_node->min_y_proj_ptr); else *************** *** 775,779 **** real* r; ! if (scanner_node->factor_ptr != 0) r = static_cast(scanner_node->max_y_proj_ptr); else --- 775,779 ---- real* r; ! if (scanner_node->factor_ptr != static_cast(0)) r = static_cast(scanner_node->max_y_proj_ptr); else *************** *** 808,812 **** real* r; ! if (scanner_node->factor_ptr != 0) r = static_cast(scanner_node->min_z_proj_ptr); else --- 808,812 ---- real* r; ! if (scanner_node->factor_ptr != static_cast(0)) r = static_cast(scanner_node->min_z_proj_ptr); else *************** *** 841,845 **** real* r; ! if (scanner_node->factor_ptr != 0) r = static_cast(scanner_node->max_z_proj_ptr); else --- 841,845 ---- real* r; ! if (scanner_node->factor_ptr != static_cast(0)) r = static_cast(scanner_node->max_z_proj_ptr); else *************** *** 1026,1035 **** real* r; ! if (scanner_node->surface_hiding_value_ptr != 0) { r = static_cast(scanner_node->surface_hiding_value_ptr); } ! else /* |scanner_node->surface_hiding_value_ptr == 0| */ { --- 1026,1035 ---- real* r; ! if (scanner_node->surface_hiding_value_ptr != static_cast(0)) { r = static_cast(scanner_node->surface_hiding_value_ptr); } ! else /* |scanner_node->surface_hiding_value_ptr == static_cast(0)| */ { *************** *** 1060,1064 **** real* r; ! if (scanner_node->surface_hiding_value_ptr != 0) { r = static_cast(scanner_node->surface_hiding_value_ptr); --- 1060,1064 ---- real* r; ! if (scanner_node->surface_hiding_value_ptr != static_cast(0)) { r = static_cast(scanner_node->surface_hiding_value_ptr); diff -rc2P 3DLDF-2.0.2/src/pfocexpr.w 3DLDF-2.0.3/src/pfocexpr.w *** 3DLDF-2.0.2/src/pfocexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pfocexpr.w Fri Dec 13 12:51:32 2013 *************** *** 84,88 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 84,88 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 145,154 **** @= ! if (pv == 0) { delete p; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 145,154 ---- @= ! if (pv == static_cast*>(0)) { delete p; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 166,170 **** delete p; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 166,170 ---- delete p; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pfuncfin.w 3DLDF-2.0.3/src/pfuncfin.w *** 3DLDF-2.0.2/src/pfuncfin.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pfuncfin.w Wed Dec 11 18:42:22 2013 *************** *** 75,81 **** int yylex(YYSTYPE* value, ! YYLTYPE* location, ! void* parameter); @q ** yyerror() @> --- 75,83 ---- int yylex(YYSTYPE* value, ! yyscan_t parameter); + #if 0 + YYLTYPE* location, + #endif @q ** yyerror() @> *************** *** 83,94 **** @= int ! yyerror(char const* message);@/ @ @= int ! yyerror(char const* message) { ! cerr << "ERROR! In yyparse(): " << message << endl << flush; return 0; } --- 85,96 ---- @= int ! yyerror(void *v, char const* message);@/ @ @= int ! yyerror(void *v, char const* message) { ! cerr << "ERROR! In yyparse(): " << message << endl; return 0; } *************** *** 183,187 **** @@; @@; ! @@; @@; @@; --- 185,190 ---- @@; @@; ! typedef void* yyscan_t; ! @q Declare location type @> @@; @@; *************** *** 202,206 **** @=%%@> /* Introduces ``Additional C++ code'' section. \initials{LDF 2004.04.07}. */ ! @@; @@; --- 205,209 ---- @=%%@> /* Introduces ``Additional C++ code'' section. \initials{LDF 2004.04.07}. */ ! @q @@; *************** *** 230,234 **** #undef YYLTYPE ! @@; @@; @<|extern| declarations in |namespace Scan_Parse|@>@; --- 233,238 ---- #undef YYLTYPE ! typedef void* yyscan_t; ! @q @@; @<|extern| declarations in |namespace Scan_Parse|@>@; diff -rc2P 3DLDF-2.0.2/src/pglvexpr.w 3DLDF-2.0.3/src/pglvexpr.w *** 3DLDF-2.0.2/src/pglvexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pglvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 99,106 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 99,106 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pglyexpr.w 3DLDF-2.0.3/src/pglyexpr.w *** 3DLDF-2.0.2/src/pglyexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pglyexpr.w Fri Dec 13 12:51:32 2013 *************** *** 89,93 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 89,93 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 157,165 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 157,165 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 177,181 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 177,181 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pgrpcmnd.w 3DLDF-2.0.3/src/pgrpcmnd.w *** 3DLDF-2.0.2/src/pgrpcmnd.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pgrpcmnd.w Thu Dec 12 14:49:08 2013 *************** *** 249,253 **** { ! @=$$@> = 0; }; --- 249,253 ---- { ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/phlxexpr.w 3DLDF-2.0.3/src/phlxexpr.w *** 3DLDF-2.0.2/src/phlxexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/phlxexpr.w Fri Dec 13 12:51:32 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 155,164 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 155,164 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 176,180 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 176,180 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/phpvexpr.w 3DLDF-2.0.3/src/phpvexpr.w *** 3DLDF-2.0.2/src/phpvexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/phpvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 115,119 **** @= ! if (entry == 0 || entry->object == 0) { --- 115,119 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 132,136 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 132,136 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/phxvexpr.w 3DLDF-2.0.3/src/phxvexpr.w *** 3DLDF-2.0.2/src/phxvexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/phxvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/phypexpr.w 3DLDF-2.0.3/src/phypexpr.w *** 3DLDF-2.0.2/src/phypexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/phypexpr.w Fri Dec 13 12:51:31 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 155,164 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 155,164 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 175,179 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 175,179 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 241,245 **** @=$$@> = (c) ? c->get_hyperbola(static_cast(parameter)) ! : @=$$@> = 0; }; --- 241,245 ---- @=$$@> = (c) ? c->get_hyperbola(static_cast(parameter)) ! : @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pictures.web 3DLDF-2.0.3/src/pictures.web *** 3DLDF-2.0.2/src/pictures.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/pictures.web Wed Dec 11 18:42:22 2013 *************** *** 476,480 **** if (DEBUG) cerr << "Entering `Picture::~Picture()'." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 476,480 ---- if (DEBUG) cerr << "Entering `Picture::~Picture()'." ! << endl; #endif /* |DEBUG_COMPILE| */@; diff -rc2P 3DLDF-2.0.2/src/pinptcmd.w 3DLDF-2.0.3/src/pinptcmd.w *** 3DLDF-2.0.2/src/pinptcmd.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pinptcmd.w Fri Dec 13 13:04:26 2013 *************** *** 103,107 **** @= ! if (s == 0 || s->size() == 0) { --- 103,107 ---- @= ! if (s == static_cast(0) || s->size() == 0) { *************** *** 219,223 **** @= ! if (s != 0) delete s; --- 219,223 ---- @= ! if (s != static_cast(0)) delete s; diff -rc2P 3DLDF-2.0.2/src/planes.web 3DLDF-2.0.3/src/planes.web *** 3DLDF-2.0.2/src/planes.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/planes.web Fri Dec 13 13:05:47 2013 *************** *** 243,247 **** { cerr << "WARNING! In Plane():\nnormal == origin_pt. " ! << "Plane is INVALID_PLANE.\n\n" << flush; point = INVALID_POINT; distance = INVALID_REAL; --- 243,247 ---- { cerr << "WARNING! In Plane():\nnormal == origin_pt. " ! << "Plane is INVALID_PLANE.\n\n"; point = INVALID_POINT; distance = INVALID_REAL; *************** *** 730,734 **** ! if (reflection == 0) { cerr_strm << thread_name --- 730,734 ---- ! if (reflection == static_cast(0)) { cerr_strm << thread_name *************** *** 955,959 **** @= ! if (pv == 0) { --- 955,959 ---- @= ! if (pv == static_cast*>(0)) { *************** *** 1032,1036 **** @= ! if (reflection == 0) { --- 1032,1036 ---- @= ! if (reflection == static_cast(0)) { *************** *** 1153,1157 **** ! if (rs.first == 0) { cerr_strm << thread_name << "ERROR! In `Point::reflect_off()':" --- 1153,1157 ---- ! if (rs.first == ZERO_REAL) { cerr_strm << thread_name << "ERROR! In `Point::reflect_off()':" *************** *** 1364,1368 **** @= ! if (denominator == 0) { if (!suppress_warnings) --- 1364,1368 ---- @= ! if (denominator == ZERO_REAL) { if (!suppress_warnings) *************** *** 1556,1560 **** real vz = direction_vector.get_z(); ! if (direction_vector.get_x() != 0) { x = 0; --- 1556,1560 ---- real vz = direction_vector.get_z(); ! if (direction_vector.get_x() != ZERO_REAL) { x = 0; *************** *** 1562,1566 **** z = (d*my - e*ny) / vx; } ! else if (direction_vector.get_y() != 0) { x = (d * mz - e * nz) / vy; --- 1562,1566 ---- z = (d*my - e*ny) / vx; } ! else if (direction_vector.get_y() != ZERO_REAL) { x = (d * mz - e * nz) / vy; *************** *** 1605,1609 **** if (*this == INVALID_PLANE) { ! cerr << "INVALID_PLANE. Can't show." << endl << endl << flush; return; } --- 1605,1609 ---- if (*this == INVALID_PLANE) { ! cerr << "INVALID_PLANE. Can't show." << endl << endl; return; } *************** *** 1611,1615 **** normal.show("normal:"); point.show("point:"); ! cerr << "distance == " << distance << endl << endl << flush; } --- 1611,1615 ---- normal.show("normal:"); point.show("point:"); ! cerr << "distance == " << distance << endl << endl; } diff -rc2P 3DLDF-2.0.2/src/plblcmnd.w 3DLDF-2.0.3/src/plblcmnd.w *** 3DLDF-2.0.2/src/plblcmnd.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/plblcmnd.w Fri Dec 13 13:06:26 2013 *************** *** 908,912 **** p->suppress_labels(); ! @=$$@> = 0; }; --- 908,912 ---- p->suppress_labels(); ! @=$$@> = static_cast(0); }; *************** *** 942,946 **** p->unsuppress_labels(); ! @=$$@> = 0; }; --- 942,946 ---- p->unsuppress_labels(); ! @=$$@> = static_cast(0); }; *************** *** 971,975 **** p->kill_labels(); ! @=$$@> = 0; }; --- 971,975 ---- p->kill_labels(); ! @=$$@> = static_cast(0); }; *************** *** 1407,1411 **** { ! @=$$@> = 0; }; --- 1407,1411 ---- { ! @=$$@> = static_cast(0); }; *************** *** 1461,1465 **** { ! @=$$@> = 0; }; --- 1461,1465 ---- { ! @=$$@> = static_cast(0); }; *************** *** 1517,1521 **** { ! @=$$@> = 0; }; --- 1517,1521 ---- { ! @=$$@> = static_cast(0); }; *************** *** 1570,1574 **** Conic_Section_Lattice* c = static_cast(@=$3@>); ! if (c != 0) { c->label_lattice(parameter, --- 1570,1574 ---- Conic_Section_Lattice* c = static_cast(@=$3@>); ! if (c != static_cast(0)) { c->label_lattice(parameter, *************** *** 1621,1625 **** Conic_Section_Lattice* c = static_cast(@=$3@>); ! if (c != 0) { c->label_lattice(parameter, --- 1621,1625 ---- Conic_Section_Lattice* c = static_cast(@=$3@>); ! if (c != static_cast(0)) { c->label_lattice(parameter, *************** *** 1673,1677 **** Conic_Section_Lattice* c = static_cast(@=$4@>); ! if (c != 0) { c->label_lattice(parameter, --- 1673,1677 ---- Conic_Section_Lattice* c = static_cast(@=$4@>); ! if (c != static_cast(0)) { c->label_lattice(parameter, diff -rc2P 3DLDF-2.0.2/src/pldfdcl.w 3DLDF-2.0.3/src/pldfdcl.w *** 3DLDF-2.0.2/src/pldfdcl.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pldfdcl.w Fri Dec 13 13:11:44 2013 *************** *** 2122,2126 **** #ifdef HAVE_PTHREAD_H ! if ( scanner_node != 0 && scanner_node->thread_info != 0 && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) --- 2122,2127 ---- #ifdef HAVE_PTHREAD_H ! if ( scanner_node != static_cast(0) ! && scanner_node->thread_info != static_cast(0) && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) *************** *** 2205,2209 **** #ifdef HAVE_PTHREAD_H ! if ( scanner_node != 0 && scanner_node->thread_info != 0 && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) --- 2206,2211 ---- #ifdef HAVE_PTHREAD_H ! if ( scanner_node != static_cast(0) ! && scanner_node->thread_info != static_cast(0) && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) *************** *** 2288,2292 **** #ifdef HAVE_PTHREAD_H ! if ( scanner_node != 0 && scanner_node->thread_info != 0 && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) --- 2290,2295 ---- #ifdef HAVE_PTHREAD_H ! if ( scanner_node != static_cast(0) ! && scanner_node->thread_info != static_cast(0) && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) diff -rc2P 3DLDF-2.0.2/src/ploops.w 3DLDF-2.0.3/src/ploops.w *** 3DLDF-2.0.2/src/ploops.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/ploops.w Fri Dec 13 13:13:06 2013 *************** *** 584,588 **** scanner_node->loop_info_node = scanner_node->loop_info_node->up; ! if (temp_loop_info_node != 0) delete temp_loop_info_node; --- 584,588 ---- scanner_node->loop_info_node = scanner_node->loop_info_node->up; ! if (temp_loop_info_node != static_cast(0)) delete temp_loop_info_node; *************** *** 746,750 **** scanner_node->loop_info_node = scanner_node->loop_info_node->up; ! if (temp_loop_info_node != 0) delete temp_loop_info_node; --- 746,750 ---- scanner_node->loop_info_node = scanner_node->loop_info_node->up; ! if (temp_loop_info_node != static_cast(0)) delete temp_loop_info_node; *************** *** 830,834 **** scanner_node->loop_info_node = scanner_node->loop_info_node->up; ! if (temp_loop_info_node != 0) delete temp_loop_info_node; --- 830,834 ---- scanner_node->loop_info_node = scanner_node->loop_info_node->up; ! if (temp_loop_info_node != static_cast(0)) delete temp_loop_info_node; diff -rc2P 3DLDF-2.0.2/src/pmacros.w 3DLDF-2.0.3/src/pmacros.w *** 3DLDF-2.0.2/src/pmacros.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pmacros.w Fri Dec 13 13:19:38 2013 *************** *** 160,164 **** @q ****** (6).@> ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 160,164 ---- @q ****** (6).@> ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 182,186 **** scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 182,186 ---- scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 269,273 **** ! @=$$@> = 0; } /* |if (status != 0)| */ --- 269,273 ---- ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 278,282 **** scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 278,282 ---- scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 332,336 **** entry = static_cast(@=$2@>); ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 332,336 ---- entry = static_cast(@=$2@>); ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 354,358 **** scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 354,358 ---- scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 366,370 **** @q ******* (7) @> ! if (entry->object == 0) { Definition_Info_Node d; --- 366,370 ---- @q ******* (7) @> ! if (entry->object == static_cast(0)) { Definition_Info_Node d; *************** *** 483,487 **** ! @=$$@> = 0; } /* |if (status != 0)| */ --- 483,487 ---- ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 492,496 **** scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 492,496 ---- scanner_node->macro_typed_parameter_vector.clear(); ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 527,531 **** static_cast(@=$2@>)); ! @=$$@> = 0; }; --- 527,531 ---- static_cast(@=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 558,562 **** { ! @=$$@> = 0; }; --- 558,562 ---- { ! @=$$@> = static_cast(0); }; *************** *** 608,612 **** make_pair(@=$1@>, @=$2@>)); ! @=$$@> = 0; }; --- 608,612 ---- make_pair(@=$1@>, @=$2@>)); ! @=$$@> = static_cast(0); }; *************** *** 632,636 **** make_pair(@=$3@>, @=$4@>)); ! @=$$@> = 0; }; --- 632,636 ---- make_pair(@=$3@>, @=$4@>)); ! @=$$@> = static_cast(0); }; *************** *** 662,666 **** @=untyped_parameter_list: /* Empty */@>@/ { ! @=$$@> = 0; }; --- 662,666 ---- @=untyped_parameter_list: /* Empty */@>@/ { ! @=$$@> = static_cast(0); }; *************** *** 681,685 **** @=untyped_parameter_list: LEFT_PARENTHESIS untyped_parameter_sublist RIGHT_PARENTHESIS@>@/ { ! @=$$@> = 0; }; --- 681,685 ---- @=untyped_parameter_list: LEFT_PARENTHESIS untyped_parameter_sublist RIGHT_PARENTHESIS@>@/ { ! @=$$@> = static_cast(0); }; *************** *** 715,719 **** @=$1@>); ! @=$$@> = 0; }; --- 715,719 ---- @=$1@>); ! @=$$@> = static_cast(0); }; *************** *** 740,744 **** @=$3@>); ! @=$$@> = 0; }; --- 740,744 ---- @=$3@>); ! @=$$@> = static_cast(0); }; *************** *** 781,785 **** macro_call_func(static_cast(parameter), static_cast(@=$1@>)); ! @=$$@> = 0; }; --- 781,785 ---- macro_call_func(static_cast(parameter), static_cast(@=$1@>)); ! @=$$@> = static_cast(0); }; *************** *** 806,810 **** static_cast(@=$1@>)); ! @=$$@> = 0; }; --- 806,810 ---- static_cast(@=$1@>)); ! @=$$@> = static_cast(0); }; *************** *** 830,834 **** static_cast(@=$1@>), true); ! @=$$@> = 0; }; --- 830,834 ---- static_cast(@=$1@>), true); ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pnbvexpr.w 3DLDF-2.0.3/src/pnbvexpr.w *** 3DLDF-2.0.2/src/pnbvexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pnbvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 102,109 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 102,109 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pnmvexpr.w 3DLDF-2.0.3/src/pnmvexpr.w *** 3DLDF-2.0.2/src/pnmvexpr.w Thu Nov 7 13:36:05 2013 --- 3DLDF-2.0.3/src/pnmvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 99,106 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 99,106 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 182,186 **** { ! @=$$@> = 0; } /* |else| (|status != 0|) */ --- 182,186 ---- { ! @=$$@> = static_cast(0); } /* |else| (|status != 0|) */ diff -rc2P 3DLDF-2.0.2/src/pnrbexpr.w 3DLDF-2.0.3/src/pnrbexpr.w *** 3DLDF-2.0.2/src/pnrbexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pnrbexpr.w Fri Dec 13 11:59:35 2013 *************** *** 89,93 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 89,93 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { diff -rc2P 3DLDF-2.0.2/src/pntrvcf0.web 3DLDF-2.0.3/src/pntrvcf0.web *** 3DLDF-2.0.2/src/pntrvcf0.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/pntrvcf0.web Fri Dec 13 13:36:07 2013 *************** *** 467,471 **** ! if (do_transform && transform != 0) *transform = t; --- 467,471 ---- ! if (do_transform && transform != static_cast(0)) *transform = t; *************** *** 749,753 **** #endif ! if (do_transform && t == 0 ) t = create_new(0); --- 749,753 ---- #endif ! if (do_transform && t == static_cast(0)) t = create_new(0); diff -rc2P 3DLDF-2.0.2/src/pntrvctr.web 3DLDF-2.0.3/src/pntrvctr.web *** 3DLDF-2.0.2/src/pntrvctr.web Sun Nov 10 16:53:35 2013 --- 3DLDF-2.0.3/src/pntrvctr.web Fri Dec 13 13:33:24 2013 *************** *** 420,424 **** Pointer_Vector* pvc; ! if (c == 0) pvc = new Pointer_Vector; else --- 420,424 ---- Pointer_Vector* pvc; ! if (c == static_cast*>(0)) pvc = new Pointer_Vector; else *************** *** 868,872 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 868,872 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 947,951 **** static Pointer_Vector* ! convert(Pointer_Vector*& d); @q ***** (5) Definition.@> --- 947,951 ---- static Pointer_Vector* ! convert(Pointer_Vector* d); @q ***** (5) Definition.@> *************** *** 955,961 **** template Pointer_Vector* ! Pointer_Vector::convert(Pointer_Vector*& d) { ! if (d == 0 || d->ctr == 0) return 0; --- 955,962 ---- template Pointer_Vector* ! Pointer_Vector::convert(Pointer_Vector* d) { ! if ( d == static_cast*>(0) ! || d->ctr == 0) return 0; *************** *** 1135,1139 **** ++j; ! if (*i == 0) { ++i_ctr; --- 1136,1140 ---- ++j; ! if (*i == static_cast(0)) { ++i_ctr; *************** *** 1153,1157 **** for (;j != temp_vector.end(); ++j) { ! if (*j == 0) ; else if ((**i).is_equal(**j, tolerance)) --- 1154,1158 ---- for (;j != temp_vector.end(); ++j) { ! if (*j == static_cast(0)) ; else if ((**i).is_equal(**j, tolerance)) *************** *** 1174,1178 **** @q ******* (7)@> ! if (temp_vector.back() != 0) { v.push_back(temp_vector.back()); --- 1175,1179 ---- @q ******* (7)@> ! if (temp_vector.back() != static_cast(0)) { v.push_back(temp_vector.back()); *************** *** 1317,1321 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 1318,1322 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 1356,1360 **** ctr_strm << i++ << ":"; ! if (*iter != 0) (*iter)->show(ctr_strm.str()); else --- 1357,1361 ---- ctr_strm << i++ << ":"; ! if (*iter != static_cast(0)) (*iter)->show(ctr_strm.str()); else diff -rc2P 3DLDF-2.0.2/src/pnumexpr.w 3DLDF-2.0.3/src/pnumexpr.w *** 3DLDF-2.0.2/src/pnumexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pnumexpr.w Fri Dec 13 13:36:06 2013 *************** *** 110,117 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 110,117 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = ZERO_REAL; } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 224,240 **** #endif /* |DEBUG_COMPILE| */ ! if (@=$3@> == 0) { ! unsigned int first_line = @=@@1@>.first_line; ! unsigned int first_column = @=@@1@>.first_column; ! unsigned int last_line = @=@@3@>.last_line; ! unsigned int last_column = @=@@3@>.last_column; cerr_strm << "ERROR! "; if (scanner_node->in->type == Io_Struct::FILE_TYPE) cerr_strm << "In input file `" << scanner_node->in->filename << "' " << first_line << "." << first_column << "--" << last_line << "." << last_column << "." << endl; cerr_strm << "Division by 0. Setting to 0." --- 224,244 ---- #endif /* |DEBUG_COMPILE| */ ! if (@=$3@> == ZERO_REAL) { ! #if 0 ! @q unsigned int first_line = @@=@@1@@>.first_line; @> ! @q unsigned int first_column = @@=@@1@@>.first_column; @> ! @q unsigned int last_line = @@=@@3@@>.last_line; @> ! @q unsigned int last_column = @@=@@3@@>.last_column; @> ! #endif cerr_strm << "ERROR! "; + #if 0 if (scanner_node->in->type == Io_Struct::FILE_TYPE) cerr_strm << "In input file `" << scanner_node->in->filename << "' " << first_line << "." << first_column << "--" << last_line << "." << last_column << "." << endl; + #endif cerr_strm << "Division by 0. Setting to 0." *************** *** 246,250 **** cerr_strm.str(""); ! @=$$@> = 0; --- 250,254 ---- cerr_strm.str(""); ! @=$$@> = ZERO_REAL; *************** *** 382,389 **** Point* p = static_cast(@=$2@>); ! if (p == 0) { ! @=$$@> = 0; } /* |if (p == 0)| */ --- 386,393 ---- Point* p = static_cast(@=$2@>); ! if (p == static_cast(0)) { ! @=$$@> = ZERO_REAL; } /* |if (p == 0)| */ *************** *** 422,428 **** Point* p = static_cast(@=$2@>); ! if (p == 0) { ! @=$$@> = 0; } /* |if (p == 0)| */ --- 426,433 ---- Point* p = static_cast(@=$2@>); ! ! if (p == static_cast(0)) { ! @=$$@> = ZERO_REAL; } /* |if (p == 0)| */ *************** *** 448,452 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 453,457 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 466,470 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 471,475 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 484,488 **** @=$$@> = e->size(); else ! @=$$@> = 0; delete e; --- 489,493 ---- @=$$@> = e->size(); else ! @=$$@> = ZERO_REAL; delete e; *************** *** 502,506 **** @=$$@> = e->size(); else ! @=$$@> = 0; delete e; --- 507,511 ---- @=$$@> = e->size(); else ! @=$$@> = ZERO_REAL; delete e; *************** *** 526,530 **** @=$$@> = c->size(); else ! @=$$@> = 0; delete c; --- 531,535 ---- @=$$@> = c->size(); else ! @=$$@> = ZERO_REAL; delete c; *************** *** 550,554 **** @=$$@> = c->size(); else ! @=$$@> = 0; delete c; --- 555,559 ---- @=$$@> = c->size(); else ! @=$$@> = ZERO_REAL; delete c; *************** *** 579,583 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 584,588 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 604,608 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 609,613 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 629,633 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 634,638 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 654,658 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 659,663 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 679,683 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 684,688 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 703,707 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 708,712 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 727,731 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 732,736 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 745,749 **** @=$$@> = e->size(); else ! @=$$@> = 0; delete e; --- 750,754 ---- @=$$@> = e->size(); else ! @=$$@> = ZERO_REAL; delete e; *************** *** 792,796 **** delete p; ! @=$$@> = 0; }; --- 797,801 ---- delete p; ! @=$$@> = ZERO_REAL; }; *************** *** 816,820 **** @=$$@> = p->size(); else ! @=$$@> = 0; delete p; --- 821,825 ---- @=$$@> = p->size(); else ! @=$$@> = ZERO_REAL; delete p; *************** *** 1523,1527 **** @= ! if (entry == 0) { --- 1528,1532 ---- @= ! if (entry == static_cast(0)) { *************** *** 1539,1544 **** else /* |entry != 0| */ { ! if (entry->object == 0) ! @=$$@> = 0; else /* |entry->object != 0| */ --- 1544,1549 ---- else /* |entry != 0| */ { ! if (entry->object == static_cast(0)) ! @=$$@> = ZERO_REAL; else /* |entry->object != 0| */ *************** *** 1583,1587 **** @= ! if (entry == 0) { @=$$@> = INVALID_REAL; --- 1588,1592 ---- @= ! if (entry == static_cast(0)) { @=$$@> = INVALID_REAL; *************** *** 1598,1603 **** else /* |entry != 0| */ { ! if (entry->object == 0) ! @=$$@> = 0; else /* |entry->object != 0| */ --- 1603,1608 ---- else /* |entry != 0| */ { ! if (entry->object == static_cast(0)) ! @=$$@> = ZERO_REAL; else /* |entry->object != 0| */ *************** *** 1830,1849 **** else if (part == CYAN_PART) ! @=$$@> = 0; else if (part == MAGENTA_PART) ! @=$$@> = 0; else if (part == BLACK_PART) ! @=$$@> = 0; else if (part == WHITE_PART) ! @=$$@> = 0; else if (part == RED_ORANGE_PART) ! @=$$@> = 0; else if (part == BLUE_VIOLET_PART) ! @=$$@> = 0; else --- 1835,1854 ---- else if (part == CYAN_PART) ! @=$$@> = ZERO_REAL; else if (part == MAGENTA_PART) ! @=$$@> = ZERO_REAL; else if (part == BLACK_PART) ! @=$$@> = ZERO_REAL; else if (part == WHITE_PART) ! @=$$@> = ZERO_REAL; else if (part == RED_ORANGE_PART) ! @=$$@> = ZERO_REAL; else if (part == BLUE_VIOLET_PART) ! @=$$@> = ZERO_REAL; else *************** *** 2446,2450 **** @= ! if (pv == 0) { @=$$@> = INVALID_REAL; --- 2451,2455 ---- @= ! if (pv == static_cast*>(0)) { @=$$@> = INVALID_REAL; *************** *** 2895,2899 **** @= ! if (entry == 0 || entry->object == 0) { --- 2900,2904 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 2952,2956 **** @= ! if (entry == 0 || entry->object == 0) { --- 2957,2961 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 3005,3009 **** @= ! if (entry == 0 || entry->object == 0) { @=$$@> = INVALID_REAL; --- 3010,3014 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { @=$$@> = INVALID_REAL; *************** *** 3032,3036 **** @= ! if (*r == 0) { @=$$@> = INVALID_REAL; --- 3037,3041 ---- @= ! if (*r == ZERO_REAL) { @=$$@> = INVALID_REAL; *************** *** 3070,3094 **** else if (@=$2@> == OVER) { ! if (@=$3@> == 0) { ! unsigned int first_line = @=@@1.first_line;@>@; ! unsigned int first_column = @=@@1.first_column;@>@; ! unsigned int last_line = @=@@3.last_line;@>@; ! unsigned int last_column = @=@@3.last_column;@>@; cerr_strm << "ERROR! "; ! if (scanner_node->in->type == Io_Struct::FILE_TYPE) cerr_strm << "In input file `" << scanner_node->in->filename << "' " << first_line << "." << first_column << "--" << last_line << "." << last_column << ".\n"; cerr_strm << "Division by 0. Setting to 0.\n" ! << "Will try to continue.\n" << flush; ! @=$$@> = 0; log_message(cerr_strm); --- 3075,3102 ---- else if (@=$2@> == OVER) { ! if (@=$3@> == ZERO_REAL) { ! #if 0 ! @q unsigned int first_line = @@=@@1.first_line;@@>@@; @> ! @q unsigned int first_column = @@=@@1.first_column;@@>@@; @> ! @q unsigned int last_line = @@=@@3.last_line;@@>@@; @> ! @q unsigned int last_column = @@=@@3.last_column;@@>@@; @> ! #endif cerr_strm << "ERROR! "; ! #if 0 if (scanner_node->in->type == Io_Struct::FILE_TYPE) cerr_strm << "In input file `" << scanner_node->in->filename << "' " << first_line << "." << first_column << "--" << last_line << "." << last_column << ".\n"; + #endif cerr_strm << "Division by 0. Setting to 0.\n" ! << "Will try to continue.\n"; ! @=$$@> = ZERO_REAL; log_message(cerr_strm); *************** *** 3216,3220 **** @= ! if (p == 0 || q == 0) { --- 3224,3228 ---- @= ! if (p == static_cast(0) || q == static_cast(0)) { *************** *** 3737,3741 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl << flush; #endif /* |DEBUG_COMPILE| */ --- 3745,3749 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl; #endif /* |DEBUG_COMPILE| */ *************** *** 3818,3824 **** << "Can't square it." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n" << flush; ! @=$$@> = 0; goto end_numeric_tertiary_2; } --- 3826,3832 ---- << "Can't square it." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n"; ! @=$$@> = ZERO_REAL; goto end_numeric_tertiary_2; } *************** *** 3833,3839 **** << "Can't square it." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n" << flush; ! @=$$@> = 0; goto end_numeric_tertiary_2; } --- 3841,3847 ---- << "Can't square it." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n"; ! @=$$@> = ZERO_REAL; goto end_numeric_tertiary_2; } *************** *** 3857,3867 **** << "Can't perform Pythagorean addition." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n" << flush; ! @=$$@> = 0; if (scanner_node->run_state.error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n" ! << flush; getchar(); /* Don't delete this! */@; } --- 3865,3876 ---- << "Can't perform Pythagorean addition." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n"; ! ! @=$$@> = ZERO_REAL; if (scanner_node->run_state.error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n"; ! getchar(); /* Don't delete this! */@; } *************** *** 3892,3902 **** << "Can't perform Pythagorean subtraction." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n" << flush; ! @=$$@> = 0; if (scanner_node->run_state.error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n" ! << flush; getchar(); /* Don't delete this! */@; } --- 3901,3911 ---- << "Can't perform Pythagorean subtraction." << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n"; ! ! @=$$@> = ZERO_REAL; if (scanner_node->run_state.error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n"; getchar(); /* Don't delete this! */@; } *************** *** 3921,3926 **** << "$2 has invalid value: " << @=$2@> << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n" << flush; ! @=$$@> = 0; goto end_numeric_tertiary_2; } --- 3930,3937 ---- << "$2 has invalid value: " << @=$2@> << endl << "Setting `numeric_tertiary' to 0 " ! << "and will try to continue.\n"; ! ! @=$$@> = ZERO_REAL; ! goto end_numeric_tertiary_2; } *************** *** 3932,3936 **** if (DEBUG) { ! cerr << "$$ == " << @=$$@> << endl << flush; } #endif /* |DEBUG_COMPILE| */ --- 3943,3947 ---- if (DEBUG) { ! cerr << "$$ == " << @=$$@> << endl; } #endif /* |DEBUG_COMPILE| */ *************** *** 3996,4000 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl << flush; #endif /* |DEBUG_COMPILE| */ --- 4007,4011 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl; #endif /* |DEBUG_COMPILE| */ *************** *** 4026,4030 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl << flush; #endif /* |DEBUG_COMPILE| */ } --- 4037,4041 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl; #endif /* |DEBUG_COMPILE| */ } *************** *** 4047,4051 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl << flush; #endif /* |DEBUG_COMPILE| */ --- 4058,4062 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl; #endif /* |DEBUG_COMPILE| */ *************** *** 4080,4084 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl << flush; #endif /* |DEBUG_COMPILE| */ --- 4091,4095 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "$$ == " << @=$$@> << endl; #endif /* |DEBUG_COMPILE| */ diff -rc2P 3DLDF-2.0.2/src/points.web 3DLDF-2.0.3/src/points.web *** 3DLDF-2.0.2/src/points.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/points.web Fri Dec 13 13:41:28 2013 *************** *** 775,787 **** @= - #ifdef __DECCXX - world_coordinates = null_coordinates; - user_coordinates = null_coordinates; - view_coordinates = null_coordinates; - pre_projective_coordinates = null_coordinates;@/ - projective_coordinates = null_coordinates;@/ - #endif - - #ifdef __GNUC__ world_coordinates.resize(4, 0); user_coordinates.resize(4, 0); --- 775,778 ---- *************** *** 790,794 **** projective_coordinates.resize(4, 0); transform.reset(); - #endif world_coordinates[3] = 1; --- 781,784 ---- *************** *** 838,846 **** do_output = true; ! pen_vector = 0; ! dash_pattern_vector = 0; ! draw_color_vector = 0; ! fill_color_vector = 0; shape_type = POINT_TYPE; --- 828,836 ---- do_output = true; ! pen_vector = static_cast*>(0); ! dash_pattern_vector = static_cast*>(0); ! draw_color_vector = static_cast*>(0); ! fill_color_vector = static_cast*>(0); shape_type = POINT_TYPE; *************** *** 903,911 **** do_output = true; ! pen_vector = 0; ! dash_pattern_vector = 0; ! draw_color_vector = 0; ! fill_color_vector = 0; shape_type = POINT_TYPE; --- 893,901 ---- do_output = true; ! pen_vector = static_cast*>(0); ! dash_pattern_vector = static_cast*>(0); ! draw_color_vector = static_cast*>(0); ! fill_color_vector = static_cast*>(0); shape_type = POINT_TYPE; *************** *** 972,998 **** Point p(x, y, z); ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (fill_color_vector != 0) { delete fill_color_vector; ! fill_color_vector = 0; } --- 962,987 ---- Point p(x, y, z); ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } *************** *** 1037,1045 **** @@; ! draw_color_vector = 0; ! fill_color_vector = 0; ! pen_vector = 0; ! dash_pattern_vector = 0; *this = p; --- 1026,1034 ---- @@; ! draw_color_vector = static_cast*>(0); ! fill_color_vector = static_cast*>(0); ! pen_vector = static_cast*>(0); ! dash_pattern_vector = static_cast*>(0); *this = p; *************** *** 1049,1052 **** --- 1038,1044 ---- decomposition_level = 0; do_output = true; + + return; + } *************** *** 1086,1111 **** { ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (fill_color_vector != 0) { delete fill_color_vector; ! fill_color_vector = 0; } ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } --- 1078,1103 ---- { ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } *************** *** 1219,1246 **** Point::~Point(void) { ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (fill_color_vector != 0) { delete fill_color_vector; ! fill_color_vector = 0; } --- 1211,1251 ---- Point::~Point(void) { + volatile bool DEBUG = false; /* |true| */ + + + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << "Entering `Point' destructor." << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } *************** *** 1339,1352 **** #endif /* |DEBUG_COMPILE| */@; - transform = p.transform; - drawdot_value = p.drawdot_value; ! if (p.draw_color_vector == 0 && draw_color_vector == 0) ; /* Do nothing. */@; ! else if (p.draw_color_vector != 0 && draw_color_vector == 0) { draw_color_vector = new Pointer_Vector; --- 1344,1357 ---- #endif /* |DEBUG_COMPILE| */@; transform = p.transform; drawdot_value = p.drawdot_value; ! if ( p.draw_color_vector == static_cast*>(0) ! && draw_color_vector == static_cast*>(0)) ; /* Do nothing. */@; ! else if ( p.draw_color_vector != static_cast*>(0) ! && draw_color_vector == static_cast*>(0)) { draw_color_vector = new Pointer_Vector; *************** *** 1354,1372 **** } ! else if (p.draw_color_vector != 0 && draw_color_vector != 0) *draw_color_vector = *(p.draw_color_vector); ! else if (p.draw_color_vector == 0 && draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (p.pen_vector == 0 && pen_vector == 0) ; /* Do nothing. */@; ! else if (p.pen_vector != 0 && pen_vector == 0) { pen_vector = new Pointer_Vector; --- 1359,1381 ---- } ! else if ( p.draw_color_vector != static_cast*>(0) ! && draw_color_vector != static_cast*>(0)) *draw_color_vector = *(p.draw_color_vector); ! else if ( p.draw_color_vector == static_cast*>(0) ! && draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if ( p.pen_vector == static_cast*>(0) ! && pen_vector == static_cast*>(0)) ; /* Do nothing. */@; ! else if ( p.pen_vector != static_cast*>(0) ! && pen_vector == static_cast*>(0)) { pen_vector = new Pointer_Vector; *************** *** 1374,1384 **** } ! else if (p.pen_vector != 0 && pen_vector != 0) *pen_vector = *(p.pen_vector); ! else if (p.pen_vector == 0 && pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } --- 1383,1395 ---- } ! else if ( p.pen_vector != static_cast*>(0) ! && pen_vector != static_cast*>(0)) *pen_vector = *(p.pen_vector); ! else if ( p.pen_vector == static_cast*>(0) ! && pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } *************** *** 1480,1505 **** { ! if (pen_vector != 0) { delete pen_vector; ! pen_vector = 0; } ! if (dash_pattern_vector != 0) { delete dash_pattern_vector; ! dash_pattern_vector = 0; } ! if (draw_color_vector != 0) { delete draw_color_vector; ! draw_color_vector = 0; } ! if (fill_color_vector != 0) { delete fill_color_vector; ! fill_color_vector = 0; } --- 1491,1516 ---- { ! if (pen_vector != static_cast*>(0)) { delete pen_vector; ! pen_vector = static_cast*>(0); } ! if (dash_pattern_vector != static_cast*>(0)) { delete dash_pattern_vector; ! dash_pattern_vector = static_cast*>(0); } ! if (draw_color_vector != static_cast*>(0)) { delete draw_color_vector; ! draw_color_vector = static_cast*>(0); } ! if (fill_color_vector != static_cast*>(0)) { delete fill_color_vector; ! fill_color_vector = static_cast*>(0); } *************** *** 1924,1928 **** @= ! if (f == 0) { --- 1935,1939 ---- @= ! if (f == static_cast(0)) { *************** *** 1931,1936 **** << "'Focus* f' may not be 0.\n" << "Returning 'projective_coordinates' as-is " ! << "and will try to continue." << endl ! ; return projective_coordinates; } --- 1942,1947 ---- << "'Focus* f' may not be 0.\n" << "Returning 'projective_coordinates' as-is " ! << "and will try to continue." << endl; ! return projective_coordinates; } *************** *** 2050,2054 **** @ @= ! if(do_persp && f == 0) { cerr << "ERROR! In 'Point::get_all_coords':" --- 2061,2065 ---- @ @= ! if(do_persp && f == static_cast(0)) { cerr << "ERROR! In 'Point::get_all_coords':" *************** *** 2056,2061 **** << "'Focus* f' may not be 0.\n" << "Returning 'projective_coordinates' as-is " ! << "and will try to continue." << endl ! ; return INVALID_REAL; } --- 2067,2072 ---- << "'Focus* f' may not be 0.\n" << "Returning 'projective_coordinates' as-is " ! << "and will try to continue." << endl; ! return INVALID_REAL; } *************** *** 2668,2673 **** { cerr << "ERROR! In Point::is_on_segment()\n" ! << "Can't calculate t. Returning false and INVALID_REAL.\n\n" ! ; return pair (false, INVALID_REAL); } --- 2679,2684 ---- { cerr << "ERROR! In Point::is_on_segment()\n" ! << "Can't calculate t. Returning false and INVALID_REAL.\n\n"; ! return pair (false, INVALID_REAL); } *************** *** 2954,2958 **** Point::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; --- 2965,2969 ---- Point::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; *************** *** 3005,3009 **** Point::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 3016,3020 ---- Point::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 3056,3063 **** Point::push_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 3067,3074 ---- Point::push_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 3119,3123 **** Point::push_pen(Pen*& p, bool copy) { ! if (pen_vector == 0) pen_vector = new Pointer_Vector; --- 3130,3134 ---- Point::push_pen(Pen*& p, bool copy) { ! if (pen_vector == static_cast*>(0)) pen_vector = new Pointer_Vector; *************** *** 3163,3167 **** Point::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == 0) dash_pattern_vector = new Pointer_Vector; --- 3174,3178 ---- Point::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == static_cast*>(0)) dash_pattern_vector = new Pointer_Vector; *************** *** 3972,3976 **** { Transform t; ! if (x != 0 || y != 0 || z != 0) transform *= t.shift(x, y, z); return t; --- 3983,3987 ---- { Transform t; ! if (x != ZERO_REAL || y != ZERO_REAL || z != ZERO_REAL) transform *= t.shift(x, y, z); return t; *************** *** 4207,4211 **** cerr << "angle of projection: " << angle << endl; ! if(angle != 0 && angle != INVALID_REAL) t *= p1.rotate(0, -angle); --- 4218,4222 ---- cerr << "angle of projection: " << angle << endl; ! if(angle != ZERO_REAL && angle != INVALID_REAL) t *= p1.rotate(0, -angle); *************** *** 4218,4222 **** cerr << "angle to x-axis: " << angle << endl; ! if(angle != 0 && angle != INVALID_REAL) t *= p1.rotate(0, 0, -angle); --- 4229,4233 ---- cerr << "angle to x-axis: " << angle << endl; ! if(angle != ZERO_REAL && angle != INVALID_REAL) t *= p1.rotate(0, 0, -angle); *************** *** 4259,4265 **** \ENDLOG @= ! if ( proj_on_x_z_plane.world_coordinates[0] == 0 ! && proj_on_x_z_plane.world_coordinates[1] == 0) ! angle = 0; else angle = proj_on_x_z_plane.angle(pt_on_z_axis); --- 4270,4276 ---- \ENDLOG @= ! if ( proj_on_x_z_plane.world_coordinates[0] == ZERO_REAL ! && proj_on_x_z_plane.world_coordinates[1] == ZERO_REAL) ! angle = ZERO_REAL; else angle = proj_on_x_z_plane.angle(pt_on_z_axis); *************** *** 4272,4276 **** cerr << "angle of projection: " << angle << endl; ! if(angle != 0 && angle != INVALID_REAL) t *= p1.rotate(0, angle); --- 4283,4287 ---- cerr << "angle of projection: " << angle << endl; ! if(angle != ZERO_REAL && angle != INVALID_REAL) t *= p1.rotate(0, angle); *************** *** 4294,4299 **** \ENDLOG @= ! if (p1.world_coordinates[1] == 0) ! angle = 0; else angle = p1.angle(pt_on_z_axis); --- 4305,4310 ---- \ENDLOG @= ! if (p1.world_coordinates[1] == ZERO_REAL) ! angle = ZERO_REAL; else angle = p1.angle(pt_on_z_axis); *************** *** 4306,4310 **** ! if(angle != 0 && angle != INVALID_REAL) t *= p1.rotate(-angle); --- 4317,4321 ---- ! if(angle != ZERO_REAL && angle != INVALID_REAL) t *= p1.rotate(-angle); *************** *** 4703,4707 **** { using namespace Projections; ! if (factor == 0) { cerr << "ERROR! In Point::project():\n" --- 4714,4718 ---- { using namespace Projections; ! if (factor == ZERO_REAL) { cerr << "ERROR! In Point::project():\n" *************** *** 4753,4758 **** << projective_coordinates[1] << ", " << projective_coordinates[2] << ", " ! << projective_coordinates[3] << ")" << endl << endl ! ; } --- 4764,4769 ---- << projective_coordinates[1] << ", " << projective_coordinates[2] << ", " ! << projective_coordinates[3] << ")" << endl << endl; ! } *************** *** 4780,4784 **** @= ! if (temp_coordinates[2] + f.get_distance() == 0) { cerr << "ERROR! In Point::project():\n" --- 4791,4795 ---- @= ! if (temp_coordinates[2] + f.get_distance() == ZERO_REAL) { cerr << "ERROR! In Point::project():\n" *************** *** 4830,4834 **** real eps = epsilon(); ! if (projective_coordinates[3] == 0) { cerr << "ERROR! In Point::project(): " --- 4841,4845 ---- real eps = epsilon(); ! if (projective_coordinates[3] == ZERO_REAL) { cerr << "ERROR! In Point::project(): " *************** *** 4946,4950 **** += world_coordinates[j] * transform.transform_matrix[j][i]; ! if (new_coordinates[i] != 0) { if (DEBUG) --- 4957,4961 ---- += world_coordinates[j] * transform.transform_matrix[j][i]; ! if (new_coordinates[i] != ZERO_REAL) { if (DEBUG) *************** *** 5103,5110 **** pt->drawdot_value = DRAWDOT_VALUE; ! if (ddrawdot_color != 0) pt->push_draw_color(ddrawdot_color, true); ! if (ppen != 0) { pt->push_pen(ppen); --- 5114,5121 ---- pt->drawdot_value = DRAWDOT_VALUE; ! if (ddrawdot_color != static_cast(0)) pt->push_draw_color(ddrawdot_color, true); ! if (ppen != static_cast(0)) { pt->push_pen(ppen); *************** *** 5274,5278 **** ! if (ppen != 0) { pt->push_pen(ppen); --- 5285,5289 ---- ! if (ppen != static_cast(0)) { pt->push_pen(ppen); *************** *** 5667,5672 **** if (*this == INVALID_POINT) { ! cerr << "INVALID_POINT: (INVALID_REAL, INVALID_REAL, INVALID_REAL)\n" ! ; return; } --- 5678,5683 ---- if (*this == INVALID_POINT) { ! cerr << "INVALID_POINT: (INVALID_REAL, INVALID_REAL, INVALID_REAL)\n"; ! return; } *************** *** 6232,6236 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 6243,6247 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 6347,6351 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 6358,6362 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 6460,6464 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 6471,6475 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 7504,7509 **** { if (DEBUG) ! cerr << "In Point::output(): do_output == false. Returning.\n" ! ; return; } --- 7515,7520 ---- { if (DEBUG) ! cerr << "In Point::output(): do_output == false. Returning.\n"; ! return; } *************** *** 7537,7542 **** if (scanner_node->get_run_state()->error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n" ! ; getchar(); /* Don't delete this! */@; } --- 7548,7553 ---- if (scanner_node->get_run_state()->error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n"; ! getchar(); /* Don't delete this! */@; } *************** *** 7566,7570 **** @= ! if (draw_color_vector != 0 && draw_color_vector->ctr > 0) *out_stream << endl << " withcolor " << *(draw_color_vector->v[0]); --- 7577,7581 ---- @= ! if (draw_color_vector != static_cast*>(0) && draw_color_vector->ctr > 0) *out_stream << endl << " withcolor " << *(draw_color_vector->v[0]); *************** *** 7580,7584 **** @= ! if (pen_vector != 0 && pen_vector->ctr > 0) { --- 7591,7595 ---- @= ! if (pen_vector != static_cast*>(0) && pen_vector->ctr > 0) { *************** *** 7617,7622 **** == Run_State::STOPPING) { ! cerr << "Type to continue.\n" ! ; getchar(); /* Don't delete this! */@; } --- 7628,7633 ---- == Run_State::STOPPING) { ! cerr << "Type to continue.\n"; ! getchar(); /* Don't delete this! */@; } *************** *** 7672,7676 **** } /* |if (!pen->get_transform().is_identity())| */@; ! } /* |if (pen_vector != 0 && pen_vector->ctr > 0)| */ --- 7683,7687 ---- } /* |if (!pen->get_transform().is_identity())| */@; ! } /* |if (pen_vector != static_cast*>(0) && pen_vector->ctr > 0)| */ *************** *** 8280,8284 **** and I don't know how to turn it off. \initials{LDF 2006.11.09.} */ - cerr << "Error after here 6" << endl; #endif --- 8291,8294 ---- *************** *** 8516,8519 **** --- 8526,8530 ---- \initials{LDF 2002.10.27.} Note that the vector operations don't affect the w coordinate. + \LOG \initials{LDF 2002.10.27.} *************** *** 9009,9013 **** return INVALID_REAL; } ! else if (mag == 0) { if (DEBUG) --- 9020,9024 ---- return INVALID_REAL; } ! else if (mag == ZERO_REAL) { if (DEBUG) *************** *** 9023,9027 **** return INVALID_REAL; } ! else if (p_mag == 0) { if (DEBUG) --- 9034,9038 ---- return INVALID_REAL; } ! else if (p_mag == ZERO_REAL) { if (DEBUG) *************** *** 9097,9102 **** << "Don't call this function with false as its argument.\n" << "Use unit_vector() without an argument instead.\n" ! << "Calling unit_vector() without an argument.\n\n" ! ; } return unit_vector(); --- 9108,9113 ---- << "Don't call this function with false as its argument.\n" << "Use unit_vector() without an argument instead.\n" ! << "Calling unit_vector() without an argument.\n\n"; ! } return unit_vector(); *************** *** 9108,9112 **** ! if (m == 0) /* LDF 2002.04.10. Added this error handling code for the case where *this has no magnitude. */ { --- 9119,9123 ---- ! if (m == ZERO_REAL) /* LDF 2002.04.10. Added this error handling code for the case where *this has no magnitude. */ { *************** *** 9428,9434 **** @= ! if (t_x == 0 && p_x == 0 ! && t_y == 0 && p_y == 0 ! && t_z == 0 && p_z == 0) { --- 9439,9445 ---- @= ! if (t_x == ZERO_REAL && p_x == ZERO_REAL ! && t_y == ZERO_REAL && p_y == ZERO_REAL ! && t_z == ZERO_REAL && p_z == ZERO_REAL) { *************** *** 9469,9510 **** signed short p_z_sign; ! if(t_x == 0) t_x_sign = 0; ! else if (t_x < 0) t_x_sign = -1; else t_x_sign = 1; ! if(t_y == 0) t_y_sign = 0; ! else if (t_y < 0) t_y_sign = -1; else t_y_sign = 1; ! if(t_z == 0) t_z_sign = 0; ! else if (t_z < 0) t_z_sign = -1; else t_z_sign = 1; ! if(p_x == 0) p_x_sign = 0; ! else if (p_x < 0) p_x_sign = -1; else p_x_sign = 1; ! if(p_y == 0) p_y_sign = 0; ! else if (p_y < 0) p_y_sign = -1; else p_y_sign = 1; ! if(p_z == 0) p_z_sign = 0; ! else if (p_z < 0) p_z_sign = -1; else --- 9480,9521 ---- signed short p_z_sign; ! if (t_x == ZERO_REAL) t_x_sign = 0; ! else if (t_x < ZERO_REAL) t_x_sign = -1; else t_x_sign = 1; ! if (t_y == ZERO_REAL) t_y_sign = 0; ! else if (t_y < ZERO_REAL) t_y_sign = -1; else t_y_sign = 1; ! if (t_z == ZERO_REAL) t_z_sign = 0; ! else if (t_z < ZERO_REAL) t_z_sign = -1; else t_z_sign = 1; ! if (p_x == ZERO_REAL) p_x_sign = 0; ! else if (p_x < ZERO_REAL) p_x_sign = -1; else p_x_sign = 1; ! if (p_y == ZERO_REAL) p_y_sign = 0; ! else if (p_y < ZERO_REAL) p_y_sign = -1; else p_y_sign = 1; ! if (p_z == ZERO_REAL) p_z_sign = 0; ! else if (p_z < ZERO_REAL) p_z_sign = -1; else *************** *** 9935,9957 **** real slope_p_x_y ! = (delta_x_p != 0) ? delta_y_p/delta_x_p : INVALID_REAL; real slope_p_x_z ! = (delta_x_p != 0) ? delta_z_p/delta_x_p : INVALID_REAL; real slope_p_z_y ! = (delta_z_p != 0) ? delta_y_p/delta_z_p : INVALID_REAL; @ Slopes for line $\overrightarrow{q_0q_1}$. @= real slope_q_x_y ! = (delta_x_q != 0) ? delta_y_q/delta_x_q : INVALID_REAL; real slope_q_x_z ! = (delta_x_q != 0) ? delta_z_q/delta_x_q : INVALID_REAL; real slope_q_z_y ! = (delta_z_q != 0) ? delta_y_q/delta_z_q : INVALID_REAL; @ The traces on the x-y plane. |x_i|, |y_i|, |z_i|, |y_int_p|, and --- 9946,9968 ---- real slope_p_x_y ! = (delta_x_p != ZERO_REAL) ? delta_y_p/delta_x_p : INVALID_REAL; real slope_p_x_z ! = (delta_x_p != ZERO_REAL) ? delta_z_p/delta_x_p : INVALID_REAL; real slope_p_z_y ! = (delta_z_p != ZERO_REAL) ? delta_y_p/delta_z_p : INVALID_REAL; @ Slopes for line $\overrightarrow{q_0q_1}$. @= real slope_q_x_y ! = (delta_x_q != ZERO_REAL) ? delta_y_q/delta_x_q : INVALID_REAL; real slope_q_x_z ! = (delta_x_q != ZERO_REAL) ? delta_z_q/delta_x_q : INVALID_REAL; real slope_q_z_y ! = (delta_z_q != ZERO_REAL) ? delta_y_q/delta_z_q : INVALID_REAL; @ The traces on the x-y plane. |x_i|, |y_i|, |z_i|, |y_int_p|, and diff -rc2P 3DLDF-2.0.2/src/polygons.web 3DLDF-2.0.3/src/polygons.web *** 3DLDF-2.0.2/src/polygons.web Sun Nov 10 14:44:51 2013 --- 3DLDF-2.0.3/src/polygons.web Fri Dec 13 13:45:26 2013 *************** *** 310,314 **** << "Polygon doesn't contain any Points, " << "so it presumably doesn't have a center.\n" ! << "Returning INVALID_POINT.\n\n" << flush; return const_cast(INVALID_POINT); } --- 310,314 ---- << "Polygon doesn't contain any Points, " << "so it presumably doesn't have a center.\n" ! << "Returning INVALID_POINT.\n\n"; return const_cast(INVALID_POINT); } *************** *** 344,348 **** << "Polygon doesn't contain any Points, " << "so it presumably doesn't have a center.\n" ! << "Returning INVALID_POINT.\n\n" << flush; return const_cast(INVALID_POINT); } --- 344,348 ---- << "Polygon doesn't contain any Points, " << "so it presumably doesn't have a center.\n" ! << "Returning INVALID_POINT.\n\n"; return const_cast(INVALID_POINT); } *************** *** 804,808 **** else if (surface_vector == pt_vector || surface_vector == -pt_vector || cross == pl.normal || cross == -pl.normal ! || cross.magnitude() == 0) { --- 804,808 ---- else if (surface_vector == pt_vector || surface_vector == -pt_vector || cross == pl.normal || cross == -pl.normal ! || cross.magnitude() == ZERO_REAL) { *************** *** 825,829 **** ! if (distance == 0) { --- 825,829 ---- ! if (distance == ZERO_REAL) { *************** *** 1100,1104 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "The line and the Polygon are non-coplanar.\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 1100,1104 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "The line and the Polygon are non-coplanar.\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 1122,1126 **** if (DEBUG) { ! cerr << "bp.pt == center." << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 1122,1126 ---- if (DEBUG) { ! cerr << "bp.pt == center." << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 1139,1143 **** show("this:"); center.show("center"); ! cerr << "points.size() == " << points.size() << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 1139,1143 ---- show("this:"); center.show("center"); ! cerr << "points.size() == " << points.size() << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 1174,1180 **** { if (bp.pt == r0) ! cerr << "bp.pt == r0." << endl << flush; else if (bp.pt == r1) ! cerr << "bp.pt == r1." << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 1174,1180 ---- { if (bp.pt == r0) ! cerr << "bp.pt == r0." << endl; else if (bp.pt == r1) ! cerr << "bp.pt == r1." << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 1247,1251 **** if (DEBUG) { ! cerr << "Exiting Polygon::intersection_points.\n\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 1247,1251 ---- if (DEBUG) { ! cerr << "Exiting Polygon::intersection_points.\n\n"; } #endif /* |DEBUG_COMPILE| */@; *************** *** 1373,1378 **** pl.normal.show("pl.normal"); r_pl.normal.show("r_pl.normal"); ! cerr << "pl.distance == " << pl.distance << endl << flush; ! cerr << "r_pl.distance == " << r_pl.distance << endl << flush; } --- 1373,1378 ---- pl.normal.show("pl.normal"); r_pl.normal.show("r_pl.normal"); ! cerr << "pl.distance == " << pl.distance << endl; ! cerr << "r_pl.distance == " << r_pl.distance << endl; } *************** *** 1383,1387 **** if (DEBUG) ! cerr << "distance == " << distance << endl << flush; if (pl.normal == r_pl.normal) --- 1383,1387 ---- if (DEBUG) ! cerr << "distance == " << distance << endl; if (pl.normal == r_pl.normal) *************** *** 1391,1395 **** @ Coplanar case. @= ! if (distance == 0) { if (DEBUG) --- 1391,1395 ---- @ Coplanar case. @= ! if (distance == ZERO_REAL) { if (DEBUG) *************** *** 1433,1437 **** cerr << "WARNING! In Polygon::intersection_points():\n" << "The Polygons lie in parallel planes. " ! << "Returning empty vector.\n\n" << flush; return v; } --- 1433,1437 ---- cerr << "WARNING! In Polygon::intersection_points():\n" << "The Polygons lie in parallel planes. " ! << "Returning empty vector.\n\n"; return v; } *************** *** 1500,1504 **** if (DEBUG) cerr << "No intersection points found. " ! << "Returning empty vector\n\n" << flush; v.clear(); return v; --- 1500,1504 ---- if (DEBUG) cerr << "No intersection points found. " ! << "Returning empty vector\n\n"; v.clear(); return v; *************** *** 1885,1889 **** @= ! if (polygon_reflection == 0) { try --- 1885,1889 ---- @= ! if (polygon_reflection == static_cast(0)) { try *************** *** 2104,2108 **** @q *** (3).@> ! if (v == 0) { cerr_strm << thread_name << "ERROR! In `Polygon::reflect_off():" --- 2104,2108 ---- @q *** (3).@> ! if (v == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Polygon::reflect_off():" *************** *** 2295,2303 **** &warning_stop_value); using namespace Scan_Parse; @q **** (4).@> ! if (v == 0) { cerr_strm << thread_name << "ERROR! In `Polygon::disentangle():" --- 2295,2318 ---- &warning_stop_value); + using namespace Scan_Parse; + @q **** (4) @> + + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "Entering `Polygon::disentangle'." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + @q **** (4).@> ! if (v == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Polygon::disentangle():" *************** *** 2408,2411 **** --- 2423,2441 ---- vector quad[4]; + + + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "In `Polygon::disentangle':" + << endl + << "`pv.size()' == " << pv.size() + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + for (pv_iter = pv.begin(); pv_iter != pv.end(); ++pv_iter) *************** *** 2431,2434 **** --- 2461,2478 ---- Compare_Angles cmp_ang_neg(&ORIGIN, &neg_x_axis_point); + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "In `Polygon::disentangle':" + << endl + << "Before `for' loop." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + for (int i = 0; i < 4; ++i) { *************** *** 2449,2452 **** --- 2493,2511 ---- + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "In `Polygon::disentangle':" + << endl + << "After `for' loop." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + + pv.clear(); *************** *** 2491,2494 **** --- 2550,2568 ---- Bool_Point bp; + + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "In `Polygon::disentangle':" + << endl + << "Before `do' loop." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + do { *************** *** 2497,2506 **** --- 2571,2596 ---- for (i = 0; i < pv_size - 2; ++i) { + j = (i + 1); for (k = (i + 1); k < pv_size; ++k) { + m = (k + 1) % pv_size; + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << "`i' == " << i << endl + << "`j' == " << j << endl + << "`i' == " << k << endl + << "`m' == " << m << endl + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + bp = Point::intersection_point(pv[i], pv[j], pv[k], pv[m % pv_size]); *************** *** 2523,2526 **** --- 2613,2629 ---- } while (repeat); + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "In `Polygon::disentangle':" + << endl + << "After `do' loop." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + *************** *** 2537,2540 **** --- 2640,2660 ---- } + + @q **** (4) @> + + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "Exiting `Polygon::disentangle' successfully " + << "with return value `poly'." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + + poly->set_cycle(); *************** *** 2663,2667 **** @= ! if (p0 == 0 || p1 == 0 || pv == 0) { cerr_strm << thread_name << "ERROR! " --- 2783,2789 ---- @= ! if ( p0 == static_cast(0) ! || p1 == static_cast(0) ! || pv == static_cast*>(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 2911,2915 **** @= ! if (fill_color_vector != 0 && fill_color_vector->ctr > 0) { for (vector::iterator iter = fill_color_vector->v.begin(); --- 3033,3038 ---- @= ! if ( fill_color_vector != static_cast*>(0) ! && fill_color_vector->ctr > 0) { for (vector::iterator iter = fill_color_vector->v.begin(); *************** *** 3737,3741 **** @q ***** (5).@> ! if (pvp != 0) { --- 3860,3864 ---- @q ***** (5).@> ! if (pvp != static_cast*>(0)) { *************** *** 4107,4111 **** if (DEBUG) cerr << "Entering Reg_Polygon::Reg_Polygon() " ! << "(center, sides, diameter, angles).\n" << flush; shape_type = REG_POLYGON_TYPE; --- 4230,4234 ---- if (DEBUG) cerr << "Entering Reg_Polygon::Reg_Polygon() " ! << "(center, sides, diameter, angles).\n"; shape_type = REG_POLYGON_TYPE; *************** *** 4142,4153 **** ! if (angle_x != 0 || angle_y != 0 ! || angle_z != 0) /* Rotation around the x-axis, y-axis, and z-axis, if ! applicable. */ vertex->rotate(angle_x, angle_y, angle_z); - - vertex->shift(center); /* Put in position around |center|. */ points.push_back(vertex); --- 4265,4273 ---- + /* Rotation around the x-axis, y-axis, and z-axis, if applicable. */ ! if (angle_x != ZERO_REAL || angle_y != ZERO_REAL || angle_z != ZERO_REAL) vertex->rotate(angle_x, angle_y, angle_z); vertex->shift(center); /* Put in position around |center|. */ points.push_back(vertex); *************** *** 4155,4159 **** if (DEBUG) cerr << "Exiting Reg_Polygon::Reg_Polygon() " ! << "(center, sides, diameter, angles).\n" << flush; return; } --- 4275,4279 ---- if (DEBUG) cerr << "Exiting Reg_Polygon::Reg_Polygon() " ! << "(center, sides, diameter, angles).\n"; return; } *************** *** 4183,4187 **** if (DEBUG) cerr << "Entering Reg_Polygon::set() " ! << "(center, sides, diameter, angles).\n" << flush; @ @:??@> ?? \initials{LDF 2002.10.07.} At exactly this place, |Path::Path| (the --- 4303,4307 ---- if (DEBUG) cerr << "Entering Reg_Polygon::set() " ! << "(center, sides, diameter, angles).\n"; @ @:??@> ?? \initials{LDF 2002.10.07.} At exactly this place, |Path::Path| (the *************** *** 4198,4202 **** if (DEBUG) cerr << "Exiting Reg_Polygon::set() " ! << "(center, sides, diameter, angles).\n" << flush; return; --- 4318,4322 ---- if (DEBUG) cerr << "Exiting Reg_Polygon::set() " ! << "(center, sides, diameter, angles).\n"; return; *************** *** 4374,4379 **** if (DEBUG) { ! cerr << "internal_angle == " << internal_angle << endl << flush; ! cerr << "sides == " << sides << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 4494,4499 ---- if (DEBUG) { ! cerr << "internal_angle == " << internal_angle << endl; ! cerr << "sides == " << sides << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 4441,4446 **** int Reg_Polygon::reflect_in(const Plane& p, ! void* v, ! const Scanner_Node scanner_node) const --- 4561,4566 ---- int Reg_Polygon::reflect_in(const Plane& p, ! void* v, ! const Scanner_Node scanner_node) const *************** *** 4478,4482 **** @= ! if (reg_polygon_reflection == 0) { try --- 4598,4602 ---- @= ! if (reg_polygon_reflection == static_cast(0)) { try diff -rc2P 3DLDF-2.0.2/src/polyhed.web 3DLDF-2.0.3/src/polyhed.web *** 3DLDF-2.0.2/src/polyhed.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/polyhed.web Fri Dec 13 14:07:19 2013 *************** *** 288,292 **** @= ! if (polyhedron_reflection == 0) { try --- 288,292 ---- @= ! if (polyhedron_reflection == static_cast(0)) { try *************** *** 658,661 **** --- 658,673 ---- &warning_stop_value); + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "Entering `Polyhedron::intersection'." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + @q **** (4)@> @ *************** *** 754,762 **** suppress_warnings)); return poly; @q **** (4)@> ! } /* End of |Polyhedron::intersection_points(const Plane& p, [etc.])| definition. */ --- 766,788 ---- suppress_warnings)); + + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + cerr << thread_name << "Exiting `Polyhedron::intersection' " + << "with return value `poly'." + << endl; + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + return poly; @q **** (4)@> ! } /* End of |Polyhedron::intersection(const Plane& p, [etc.])| definition. */ *************** *** 811,815 **** { v = (**iter0).intersection_points(**iter1); ! cerr << "v.size() == " << v.size() << endl << flush; for (vector::iterator pt_iter = v.begin(); pt_iter != v.end(); --- 837,841 ---- { v = (**iter0).intersection_points(**iter1); ! cerr << "v.size() == " << v.size() << endl; for (vector::iterator pt_iter = v.begin(); pt_iter != v.end(); *************** *** 1063,1072 **** Point P2 = P0 - pts[1]; P1.show("P1"); ! cerr << " P1.magnitude() == " << P1.magnitude() << endl << flush; P2.show("P2"); ! cerr << "P2.magnitude() == " << P2.magnitude() << endl << flush; distance = (P2.magnitude() / P1.magnitude()); cerr.precision(25); ! cerr << "distance == " << distance << endl << flush; cerr.precision(6); #endif --- 1089,1098 ---- Point P2 = P0 - pts[1]; P1.show("P1"); ! cerr << " P1.magnitude() == " << P1.magnitude() << endl; P2.show("P2"); ! cerr << "P2.magnitude() == " << P2.magnitude() << endl; distance = (P2.magnitude() / P1.magnitude()); cerr.precision(25); ! cerr << "distance == " << distance << endl; cerr.precision(6); #endif *************** *** 1082,1086 **** center.shift(-center); ! if (angle_x != 0 || angle_y != 0 || angle_z != 0) { for(i = 0; i < 4; ++i) --- 1108,1112 ---- center.shift(-center); ! if (angle_x != ZERO_REAL || angle_y != ZERO_REAL || angle_z != ZERO_REAL) { for(i = 0; i < 4; ++i) *************** *** 1372,1376 **** Path p[6]; ! p[0].set("--", true, &pts[6], &pts[10], &pts[11], &pts[7], 0); p[0].draw(picture); --- 1398,1402 ---- Path p[6]; ! p[0].set("--", true, &pts[6], &pts[10], &pts[11], &pts[7], static_cast(0)); p[0].draw(picture); *************** *** 1607,1611 **** @= ! if (tetrahedron_reflection == 0) { try --- 1633,1637 ---- @= ! if (tetrahedron_reflection == static_cast(0)) { try *************** *** 2418,2422 **** @= ! if (octahedron_reflection == 0) { try --- 2444,2448 ---- @= ! if (octahedron_reflection == static_cast(0)) { try *************** *** 2703,2707 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Icosahedron::Icosahedron().\n" << flush; shape_type = ICOSAHEDRON_TYPE; --- 2729,2733 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Icosahedron::Icosahedron().\n"; shape_type = ICOSAHEDRON_TYPE; *************** *** 2822,2826 **** center = origin_pt; ! if (angle_x != 0 || angle_y != 0 || angle_z != 0) for(vector::iterator iter = reg_polygons.begin(); iter != reg_polygons.end(); ++iter) --- 2848,2852 ---- center = origin_pt; ! if (angle_x != ZERO_REAL || angle_y != ZERO_REAL || angle_z != ZERO_REAL) for(vector::iterator iter = reg_polygons.begin(); iter != reg_polygons.end(); ++iter) *************** *** 2839,2843 **** if (DEBUG) { ! cerr << "Exiting Icosahedron::Icosahedron().\n" << flush; } return; --- 2865,2869 ---- if (DEBUG) { ! cerr << "Exiting Icosahedron::Icosahedron().\n"; } return; *************** *** 3018,3026 **** { for (int j = 0; j < 3; j++) ! if (triangles[i]->get_point(j).get_y() != 0) { cerr << "ERROR! In Icosahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n" << flush; } } --- 3044,3052 ---- { for (int j = 0; j < 3; j++) ! if (triangles[i]->get_point(j).get_y() != ZERO_REAL) { cerr << "ERROR! In Icosahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n"; } } *************** *** 3057,3065 **** { for (int j = 0; j < 3; j++) ! if (triangles[i]->get_point(j).get_y() != 0) { cerr << "ERROR! In Icosahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n" << flush; } } --- 3083,3091 ---- { for (int j = 0; j < 3; j++) ! if (triangles[i]->get_point(j).get_y() != ZERO_REAL) { cerr << "ERROR! In Icosahedron::get_net():\n" << "y-coordinate != 0!\n" ! << "You'd better fix this!\n\n"; } } *************** *** 3185,3189 **** #endif ! p[0].set("--", true, &pts[3], &pts[9], &pts[10], &pts[4], 0); p[1] = p[2] = p[3] = p[4] = p[5] = p[0]; --- 3211,3215 ---- #endif ! p[0].set("--", true, &pts[3], &pts[9], &pts[10], &pts[4], static_cast(0)); p[1] = p[2] = p[3] = p[4] = p[5] = p[0]; *************** *** 3301,3305 **** @= ! if (icosahedron_reflection == 0) { try --- 3327,3331 ---- @= ! if (icosahedron_reflection == static_cast(0)) { try diff -rc2P 3DLDF-2.0.2/src/popassgn.w 3DLDF-2.0.3/src/popassgn.w *** 3DLDF-2.0.2/src/popassgn.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/popassgn.w Fri Dec 13 14:15:26 2013 *************** *** 130,134 **** @= ! if (entry == 0) { --- 130,134 ---- @= ! if (entry == static_cast(0)) { *************** *** 153,157 **** @= ! if (entry->object == 0) { --- 153,157 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 184,188 **** @= ! @=$$@> = 0; }; --- 184,188 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 215,219 **** @= ! if (entry == 0) { --- 215,219 ---- @= ! if (entry == static_cast(0)) { *************** *** 238,242 **** @= ! if (entry->object == 0) { --- 238,242 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 270,274 **** @= ! @=$$@> = 0; }; --- 270,274 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 301,305 **** @= ! if (entry == 0) { --- 301,305 ---- @= ! if (entry == static_cast(0)) { *************** *** 324,328 **** @= ! if (entry->object == 0) { --- 324,328 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 356,360 **** @= ! @=$$@> = 0; }; --- 356,360 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 386,394 **** @= ! if (@=$3@> == 0) ! { ! ! ! } /* |if (@=$3@> == 0)| */ @q ****** (6) Error handling: |entry == 0|.@> --- 386,391 ---- @= ! if (@=$3@> == ZERO_REAL) ! ; /* Do nothing */ @q ****** (6) Error handling: |entry == 0|.@> *************** *** 399,407 **** @= ! else if (entry == 0) ! { ! ! } /* |else if (entry == 0)| */ ! @q ***** (5) |$3 != 0 && entry != 0|.@> --- 396,401 ---- @= ! else if (entry == static_cast(0)) ! ; /* Do nothing */ @q ***** (5) |$3 != 0 && entry != 0|.@> *************** *** 422,426 **** @= ! if (entry->object == 0) { --- 416,420 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 453,457 **** @= ! @=$$@> = 0; }; --- 447,451 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 497,505 **** ! if (c == 0) ! { ! ! ! } /* |if (c == 0)| */ @q ****** (6) Error handling: |entry == 0|.@> --- 491,496 ---- ! if (c == static_cast(0)) ! ; @q ****** (6) Error handling: |entry == 0|.@> *************** *** 510,517 **** @= ! else if (entry == 0) ! { ! ! } /* |else if (entry == 0)| */ --- 501,506 ---- @= ! else if (entry == static_cast(0)) ! ; *************** *** 533,537 **** @= ! if (entry->object == 0) { --- 522,526 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 568,572 **** @= ! @=$$@> = 0; }; --- 557,561 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 604,611 **** ! if (c == 0) ! { ! ! } /* |if (c == 0)| */ @q ****** (6) Error handling: |entry == 0|.@> --- 593,598 ---- ! if (c == static_cast(0)) ! ; /* Do nothing */ @q ****** (6) Error handling: |entry == 0|.@> *************** *** 616,623 **** @= ! else if (entry == 0) ! { ! ! } /* |else if (entry == 0)| */ --- 603,608 ---- @= ! else if (entry == static_cast(0)) ! ; /* Do nothing */ *************** *** 639,643 **** @= ! if (entry->object == 0) { --- 624,628 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 675,679 **** @= ! @=$$@> = 0; }; --- 660,664 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 709,713 **** @= ! if (entry == 0) { --- 694,698 ---- @= ! if (entry == static_cast(0)) { *************** *** 732,740 **** @= ! if (entry->object == 0) ! { ! ! ! } /* |if (entry->object == 0)| */ @q ****** (6). |entry->object != 0|.@> --- 717,722 ---- @= ! if (entry->object == static_cast(0)) ! ; /* Do nothing */ @q ****** (6). |entry->object != 0|.@> *************** *** 765,769 **** @= ! @=$$@> = 0; }; --- 747,751 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 816,820 **** ! if (r == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 798,802 ---- ! if (r == ZERO_REAL) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 842,846 **** @= ! else if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 824,828 ---- @= ! else if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 876,880 **** @= ! if (entry->object == 0) { --- 858,862 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 921,925 **** @= ! @=$$@> = 0; }; --- 903,907 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 979,983 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 961,965 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1013,1017 **** @= ! if (s == 0) { --- 995,999 ---- @= ! if (s == static_cast(0)) { *************** *** 1061,1065 **** @= ! @=$$@> = 0; }; --- 1043,1047 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 1121,1125 **** ! if (p == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 1103,1107 ---- ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1144,1148 **** @= ! else if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 1126,1130 ---- @= ! else if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1178,1182 **** @= ! if (entry->object == 0) { --- 1160,1164 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 1227,1231 **** @= ! @=$$@> = 0; }; --- 1209,1213 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 1299,1303 **** @= ! else if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 1281,1285 ---- @= ! else if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1333,1337 **** @= ! if (entry->object == 0) { --- 1315,1319 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 1382,1390 **** @= ! @=$$@> = 0; }; - @q **** (4) operation_assignment --> point_variable @> @q **** (4) TIMES_ASSIGN numeric_expression. @> --- 1364,1371 ---- @= ! @=$$@> = static_cast(0); }; @q **** (4) operation_assignment --> point_variable @> @q **** (4) TIMES_ASSIGN numeric_expression. @> *************** *** 1431,1435 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 1412,1416 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1465,1469 **** @= ! if (entry->object == 0) { --- 1446,1450 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 1510,1514 **** @= ! @=$$@> = 0; }; --- 1491,1495 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 1560,1564 **** ! if (r == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 1541,1545 ---- ! if (r == ZERO_REAL) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1586,1590 **** @= ! else if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 1567,1571 ---- @= ! else if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1620,1624 **** @= ! if (entry->object == 0) { --- 1601,1605 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 1665,1669 **** @= ! @=$$@> = 0; }; --- 1646,1650 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 1736,1740 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 1717,1721 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 1819,1823 **** @= ! if (q == 0) { --- 1800,1804 ---- @= ! if (q == static_cast(0)) { *************** *** 1891,1895 **** @= ! @=$$@> = 0; }; --- 1872,1876 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 1940,1944 **** @= ! if (entry == 0 || entry->object == 0) { --- 1921,1925 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 1978,1982 **** @= ! @=$$@> = 0; }; --- 1959,1963 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 2020,2024 **** @= ! if (entry == 0) { --- 2001,2005 ---- @= ! if (entry == static_cast(0)) { *************** *** 2047,2051 **** @= ! if (p == 0) { --- 2028,2032 ---- @= ! if (p == static_cast(0)) { *************** *** 2083,2087 **** @q ****** (6).@> ! if (p != 0) p->set_cycle(true); --- 2064,2068 ---- @q ****** (6).@> ! if (p != static_cast(0)) p->set_cycle(true); *************** *** 2101,2105 **** @= ! @=$$@> = 0; }; --- 2082,2086 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 2140,2144 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0) { /* Do nothing. */ --- 2121,2125 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0)) { /* Do nothing. */ *************** *** 2161,2165 **** Path* p = static_cast(entry->object); ! if (p != 0) { p->set_cycle(false); --- 2142,2146 ---- Path* p = static_cast(entry->object); ! if (p != static_cast(0)) { p->set_cycle(false); *************** *** 2184,2188 **** @= ! @=$$@> = 0; }; --- 2165,2169 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 2241,2245 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 2222,2226 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 2276,2280 **** @= ! if (q == 0) { --- 2257,2261 ---- @= ! if (q == static_cast(0)) { *************** *** 2326,2330 **** @= ! @=$$@> = 0; }; --- 2307,2311 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 2375,2379 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 2356,2360 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 2408,2412 **** @= ! if (q == 0) { --- 2389,2393 ---- @= ! if (q == static_cast(0)) { *************** *** 2456,2460 **** @= ! @=$$@> = 0; }; --- 2437,2441 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 2603,2607 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 2584,2588 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 2670,2674 **** @= ! if (q == 0) { --- 2651,2655 ---- @= ! if (q == static_cast(0)) { *************** *** 2718,2722 **** @= ! @=$$@> = 0; }; --- 2699,2703 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 2759,2763 **** @= ! if (entry == 0) { --- 2740,2744 ---- @= ! if (entry == static_cast(0)) { *************** *** 2773,2777 **** Parabola* p = static_cast(entry->object); ! if (p == 0) { --- 2754,2758 ---- Parabola* p = static_cast(entry->object); ! if (p == static_cast(0)) { *************** *** 2784,2788 **** ! if (p != 0) p->set_cycle(true); --- 2765,2769 ---- ! if (p != static_cast(0)) p->set_cycle(true); *************** *** 2796,2800 **** @= ! @=$$@> = 0; }; --- 2777,2781 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 2825,2829 **** @= ! if (entry == 0) { --- 2806,2810 ---- @= ! if (entry == static_cast(0)) { *************** *** 2839,2843 **** Parabola* p = static_cast(entry->object); ! if (p == 0) { --- 2820,2824 ---- Parabola* p = static_cast(entry->object); ! if (p == static_cast(0)) { *************** *** 2850,2854 **** ! if (p != 0) p->set_cycle(false); --- 2831,2835 ---- ! if (p != static_cast(0)) p->set_cycle(false); *************** *** 2862,2872 **** @= ! @=$$@> = 0; }; - - @q *** (3) |rectangles|.@> --- 2843,2851 ---- @= ! @=$$@> = static_cast(0); }; @q *** (3) |rectangles|.@> *************** *** 2923,2927 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 2902,2906 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 2958,2962 **** @= ! if (q == 0) { --- 2937,2941 ---- @= ! if (q == static_cast(0)) { *************** *** 3016,3020 **** @= ! @=$$@> = 0; }; --- 2995,2999 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 3054,3058 **** static_cast(parameter)); ! @=$$@> = 0; }; --- 3033,3037 ---- static_cast(parameter)); ! @=$$@> = static_cast(0); }; *************** *** 3186,3190 **** @= ! @=$$@> = 0; }; --- 3165,3169 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 3343,3347 **** @= ! @=$$@> = 0; }; --- 3322,3326 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 3471,3475 **** @= ! @=$$@> = 0; }; --- 3450,3454 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 3593,3597 **** @= ! @=$$@> = 0; }; --- 3572,3576 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 3719,3728 **** @= ! @=$$@> = 0; }; - - @q *** (3) |color_vectors|.@> --- 3698,3705 ---- @= ! @=$$@> = static_cast(0); }; @q *** (3) |color_vectors|.@> *************** *** 3864,3868 **** @= ! @=$$@> = 0; }; --- 3841,3845 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 3990,3994 **** @= ! @=$$@> = 0; }; --- 3967,3971 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 4056,4060 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 4033,4037 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 4078,4082 **** delete direction; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 4055,4059 ---- delete direction; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 4209,4213 **** delete direction; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4186,4190 ---- delete direction; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4220,4224 **** delete direction; ! @=$$@> = 0; } /* |else| (|status != 0|) */ --- 4197,4201 ---- delete direction; ! @=$$@> = static_cast(0); } /* |else| (|status != 0|) */ *************** *** 4370,4374 **** @= ! @=$$@> = 0; }; --- 4347,4351 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 4436,4440 **** @= ! if (entry == 0) { --- 4413,4417 ---- @= ! if (entry == static_cast(0)) { *************** *** 4458,4462 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 4435,4439 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 4525,4529 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4502,4506 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4540,4544 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 4517,4521 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 4701,4705 **** @= ! @=$$@> = 0; }; --- 4678,4682 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 4826,4830 **** @= ! @=$$@> = 0; }; --- 4803,4807 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 4883,4887 **** @= ! if (entry == 0) { --- 4860,4864 ---- @= ! if (entry == static_cast(0)) { *************** *** 4905,4909 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 4882,4886 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 4971,4975 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 4948,4952 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 4986,4990 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 4963,4967 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 5041,5045 **** ! @=$$@> = 0; }; --- 5018,5022 ---- ! @=$$@> = static_cast(0); }; *************** *** 5079,5088 **** @= ! if (entry == 0) { delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 5056,5065 ---- @= ! if (entry == static_cast(0)) { delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 5103,5107 **** delete pv; ! @=$$@> = 0; } --- 5080,5084 ---- delete pv; ! @=$$@> = static_cast(0); } *************** *** 5228,5232 **** @= ! @=$$@> = 0; }; --- 5205,5209 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 5285,5289 **** @= ! if (entry == 0) { --- 5262,5266 ---- @= ! if (entry == static_cast(0)) { *************** *** 5307,5311 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 5284,5288 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 5373,5377 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5350,5354 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5388,5392 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 5365,5369 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 5442,5446 **** ! @=$$@> = 0; }; --- 5419,5423 ---- ! @=$$@> = static_cast(0); }; *************** *** 5480,5489 **** @= ! if (entry == 0) { delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 5457,5466 ---- @= ! if (entry == static_cast(0)) { delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 5504,5508 **** delete pv; ! @=$$@> = 0; } --- 5481,5485 ---- delete pv; ! @=$$@> = static_cast(0); } *************** *** 5551,5555 **** ! @=$$@> = 0; }; --- 5528,5532 ---- ! @=$$@> = static_cast(0); }; *************** *** 5589,5598 **** @= ! if (entry == 0) { delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 5566,5575 ---- @= ! if (entry == static_cast(0)) { delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 5613,5617 **** delete pv; ! @=$$@> = 0; } --- 5590,5594 ---- delete pv; ! @=$$@> = static_cast(0); } *************** *** 5661,5665 **** ! @=$$@> = 0; }; --- 5638,5642 ---- ! @=$$@> = static_cast(0); }; *************** *** 5698,5707 **** @= ! if (entry == 0) { delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 5675,5684 ---- @= ! if (entry == static_cast(0)) { delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 5723,5727 **** delete pv; ! @=$$@> = 0; } --- 5700,5704 ---- delete pv; ! @=$$@> = static_cast(0); } *************** *** 5774,5778 **** ! @=$$@> = 0; }; --- 5751,5755 ---- ! @=$$@> = static_cast(0); }; *************** *** 5832,5836 **** @= ! if (entry == 0) { --- 5809,5813 ---- @= ! if (entry == static_cast(0)) { *************** *** 5854,5858 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 5831,5835 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 5920,5924 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 5897,5901 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 5935,5939 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 5912,5916 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 6068,6072 **** @= ! @=$$@> = 0; }; --- 6045,6049 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 6125,6129 **** @= ! if (entry == 0) { --- 6102,6106 ---- @= ! if (entry == static_cast(0)) { *************** *** 6147,6151 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 6124,6128 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 6213,6217 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6190,6194 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6228,6232 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 6205,6209 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 6360,6364 **** @= ! @=$$@> = 0; }; --- 6337,6341 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 6417,6421 **** @= ! if (entry == 0) { --- 6394,6398 ---- @= ! if (entry == static_cast(0)) { *************** *** 6439,6443 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 6416,6420 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 6505,6509 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6482,6486 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6520,6524 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 6497,6501 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 6652,6656 **** @= ! @=$$@> = 0; }; --- 6629,6633 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 6709,6713 **** @= ! if (entry == 0) { --- 6686,6690 ---- @= ! if (entry == static_cast(0)) { *************** *** 6731,6735 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 6708,6712 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 6797,6801 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 6774,6778 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 6812,6816 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 6789,6793 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 6866,6870 **** ! @=$$@> = 0; }; --- 6843,6847 ---- ! @=$$@> = static_cast(0); }; *************** *** 6904,6913 **** @= ! if (entry == 0) { delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 6881,6890 ---- @= ! if (entry == static_cast(0)) { delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 6928,6932 **** delete pv; ! @=$$@> = 0; } --- 6905,6909 ---- delete pv; ! @=$$@> = static_cast(0); } *************** *** 6975,6979 **** ! @=$$@> = 0; }; --- 6952,6956 ---- ! @=$$@> = static_cast(0); }; *************** *** 7013,7022 **** @= ! if (entry == 0) { delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 6990,6999 ---- @= ! if (entry == static_cast(0)) { delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 7037,7041 **** delete pv; ! @=$$@> = 0; } --- 7014,7018 ---- delete pv; ! @=$$@> = static_cast(0); } *************** *** 7165,7169 **** @= ! @=$$@> = 0; }; --- 7142,7146 ---- @= ! @=$$@> = static_cast(0); }; *************** *** 7222,7226 **** @= ! if (entry == 0) { --- 7199,7203 ---- @= ! if (entry == static_cast(0)) { *************** *** 7244,7248 **** delete pv; ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 7221,7225 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 7310,7314 **** delete pv; ! @=$$@> = 0; } /* |if (status != 0)| */ --- 7287,7291 ---- delete pv; ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 7325,7329 **** delete pv; ! @=$$@> = 0; } /* |else| (|status == 0|) */ --- 7302,7306 ---- delete pv; ! @=$$@> = static_cast(0); } /* |else| (|status == 0|) */ *************** *** 7460,7464 **** @= ! @=$$@> = 0; }; --- 7437,7441 ---- @= ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/porgexpr.w 3DLDF-2.0.3/src/porgexpr.w *** 3DLDF-2.0.2/src/porgexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/porgexpr.w Fri Dec 13 12:51:31 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 156,165 **** @= ! if (pv == 0) { delete r; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 156,165 ---- @= ! if (pv == static_cast*>(0)) { delete r; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 177,181 **** delete r; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 177,181 ---- delete r; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/porvexpr.w 3DLDF-2.0.3/src/porvexpr.w *** 3DLDF-2.0.2/src/porvexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/porvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 99,106 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 99,106 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/ppbvexpr.w 3DLDF-2.0.3/src/ppbvexpr.w *** 3DLDF-2.0.2/src/ppbvexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/ppbvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 115,119 **** @= ! if (entry == 0 || entry->object == 0) { --- 115,119 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 132,136 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 132,136 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/ppdvexpr.w 3DLDF-2.0.3/src/ppdvexpr.w *** 3DLDF-2.0.2/src/ppdvexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/ppdvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 99,106 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 99,106 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/ppenexpr.w 3DLDF-2.0.3/src/ppenexpr.w *** 3DLDF-2.0.2/src/ppenexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/ppenexpr.w Fri Dec 13 12:51:31 2013 *************** *** 90,94 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 90,94 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 225,233 **** @= ! if (pv == 0) { delete p; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 225,233 ---- @= ! if (pv == static_cast*>(0)) { delete p; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 245,249 **** delete p; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 245,249 ---- delete p; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/ppgvexpr.w 3DLDF-2.0.3/src/ppgvexpr.w *** 3DLDF-2.0.2/src/ppgvexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/ppgvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 115,119 **** @= ! if (entry == 0 || entry->object == 0) { --- 115,119 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 132,136 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 132,136 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 446,450 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 446,450 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 592,596 **** if (status != 0) { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 592,596 ---- if (status != 0) { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 657,661 **** if (status != 0) { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 657,661 ---- if (status != 0) { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/pphdexpr.w 3DLDF-2.0.3/src/pphdexpr.w *** 3DLDF-2.0.2/src/pphdexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pphdexpr.w Fri Dec 13 12:51:31 2013 *************** *** 104,108 **** entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 104,108 ---- entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 224,228 **** @= ! if (pv == 0) { cerr_strm << thread_name --- 224,228 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 241,245 **** delete t; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 241,245 ---- delete t; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 269,273 **** delete t; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 269,273 ---- delete t; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pphvexpr.w 3DLDF-2.0.3/src/pphvexpr.w *** 3DLDF-2.0.2/src/pphvexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pphvexpr.w Fri Dec 13 11:59:35 2013 *************** *** 116,120 **** @= ! if (entry == 0 || entry->object == 0) { --- 116,120 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 133,137 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 133,137 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 358,362 **** if (status != 0) { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 358,362 ---- if (status != 0) { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 476,480 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 476,480 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/ppicexpr.w 3DLDF-2.0.3/src/ppicexpr.w *** 3DLDF-2.0.2/src/ppicexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/ppicexpr.w Fri Dec 13 13:26:05 2013 *************** *** 100,104 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0) { --- 100,104 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0)) { *************** *** 118,122 **** @= ! else if (entry->object == 0) { entry->known_state = Id_Map_Entry_Type::KNOWN; --- 118,122 ---- @= ! else if (entry->object == static_cast(0)) { entry->known_state = Id_Map_Entry_Type::KNOWN; diff -rc2P 3DLDF-2.0.2/src/pplhdslc.w 3DLDF-2.0.3/src/pplhdslc.w *** 3DLDF-2.0.2/src/pplhdslc.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pplhdslc.w Fri Dec 13 11:59:35 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { diff -rc2P 3DLDF-2.0.2/src/pplnexpr.w 3DLDF-2.0.3/src/pplnexpr.w *** 3DLDF-2.0.2/src/pplnexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pplnexpr.w Fri Dec 13 12:51:31 2013 *************** *** 89,93 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 89,93 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 138,142 **** if (v == INVALID_PLANE) ! @=$$@> = 0; else { --- 138,142 ---- if (v == INVALID_PLANE) ! @=$$@> = static_cast(0); else { *************** *** 148,152 **** else { ! @=$$@> = 0; } --- 148,152 ---- else { ! @=$$@> = static_cast(0); } *************** *** 372,376 **** @= ! if (pv == 0) { #if 0 --- 372,376 ---- @= ! if (pv == static_cast*>(0)) { #if 0 *************** *** 391,395 **** c = 0; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 391,395 ---- c = 0; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 421,425 **** c = 0; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 421,425 ---- c = 0; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pplnvxpr.w 3DLDF-2.0.3/src/pplnvxpr.w *** 3DLDF-2.0.2/src/pplnvxpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pplnvxpr.w Fri Dec 13 11:59:34 2013 *************** *** 115,119 **** @= ! if (entry == 0 || entry->object == 0) { --- 115,119 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 132,136 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 132,136 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pplvexpr.w 3DLDF-2.0.3/src/pplvexpr.w *** 3DLDF-2.0.2/src/pplvexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pplvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 116,120 **** @= ! if (entry == 0 || entry->object == 0) { --- 116,120 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 133,137 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 133,137 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 307,311 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 307,311 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/ppntexpr.w 3DLDF-2.0.3/src/ppntexpr.w *** 3DLDF-2.0.2/src/ppntexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/ppntexpr.w Fri Dec 13 14:46:32 2013 *************** *** 133,140 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 133,140 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 503,508 **** Plane* q = static_cast(@=$4@>); ! if (p == 0 || q == 0) ! @=$$@> = 0; else { --- 503,508 ---- Plane* q = static_cast(@=$4@>); ! if (p == static_cast(0) || q == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 542,547 **** Reg_Polygon* r = static_cast(@=$4@>); ! if (p == 0 || r == 0) ! @=$$@> = 0; else { --- 542,547 ---- Reg_Polygon* r = static_cast(@=$4@>); ! if (p == static_cast(0) || r == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 588,592 **** } else ! @=$$@> = 0; }; --- 588,592 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 616,620 **** else ! @=$$@> = 0; }; --- 616,620 ---- else ! @=$$@> = static_cast(0); }; *************** *** 643,647 **** } else ! @=$$@> = 0; }; --- 643,647 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 829,833 **** Point p = f->get_normal(); if (p == INVALID_POINT) ! @=$$@> = 0; else @=$$@> = static_cast(create_new(p)); --- 829,833 ---- Point p = f->get_normal(); if (p == INVALID_POINT) ! @=$$@> = static_cast(0); else @=$$@> = static_cast(create_new(p)); *************** *** 836,840 **** } else ! @=$$@> = 0; }; --- 836,840 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 1033,1038 **** Conic_Section_Lattice* c = static_cast(@=$2@>); ! if (c == 0) ! @=$$@> = 0; else { --- 1033,1038 ---- Conic_Section_Lattice* c = static_cast(@=$2@>); ! if (c == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 1061,1066 **** Conic_Section_Lattice* c = static_cast(@=$2@>); ! if (c == 0) ! @=$$@> = 0; else { --- 1061,1066 ---- Conic_Section_Lattice* c = static_cast(@=$2@>); ! if (c == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 1089,1094 **** Conic_Section_Lattice* c = static_cast(@=$2@>); ! if (c == 0) ! @=$$@> = 0; else { --- 1089,1094 ---- Conic_Section_Lattice* c = static_cast(@=$2@>); ! if (c == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 1148,1152 **** delete scanner_node->conic_section_lattice_options; scanner_node->conic_section_lattice_options = 0; ! @=$$@> = 0; } --- 1148,1152 ---- delete scanner_node->conic_section_lattice_options; scanner_node->conic_section_lattice_options = 0; ! @=$$@> = static_cast(0); } *************** *** 1211,1215 **** } ! @=$$@> = 0; } /* |else| */ --- 1211,1215 ---- } ! @=$$@> = static_cast(0); } /* |else| */ *************** *** 1257,1261 **** } else ! @=$$@> = 0; }; --- 1257,1261 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 1318,1322 **** { ! @=$$@> = 0; }; --- 1318,1322 ---- { ! @=$$@> = static_cast(0); }; *************** *** 1339,1346 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) scanner_node->conic_section_lattice_options->do_cull = true; ! @=$$@> = 0; }; --- 1339,1348 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) scanner_node->conic_section_lattice_options->do_cull = true; ! @=$$@> = static_cast(0); }; *************** *** 1362,1369 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) ! scanner_node->conic_section_lattice_options->do_cull = false; ! @=$$@> = 0; }; --- 1364,1373 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) ! scanner_node->conic_section_lattice_options->do_cull = false; ! @=$$@> = static_cast(0); }; *************** *** 1387,1394 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) ! scanner_node->conic_section_lattice_options->tolerance = @=$2@>; ! @=$$@> = 0; }; --- 1391,1400 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) ! scanner_node->conic_section_lattice_options->tolerance = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1428,1432 **** } ! @=$$@> = 0; }; --- 1434,1438 ---- } ! @=$$@> = static_cast(0); }; *************** *** 1460,1464 **** } ! @=$$@> = 0; }; --- 1466,1470 ---- } ! @=$$@> = static_cast(0); }; *************** *** 1503,1507 **** delete pv; ! @=$$@> = 0; }; --- 1509,1513 ---- delete pv; ! @=$$@> = static_cast(0); }; *************** *** 1544,1548 **** delete pv; ! @=$$@> = 0; }; --- 1550,1554 ---- delete pv; ! @=$$@> = static_cast(0); }; *************** *** 1564,1571 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) scanner_node->conic_section_lattice_options->do_rectify = true; ! @=$$@> = 0; }; --- 1570,1579 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) scanner_node->conic_section_lattice_options->do_rectify = true; ! @=$$@> = static_cast(0); }; *************** *** 1587,1594 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) scanner_node->conic_section_lattice_options->do_rectify = false; ! @=$$@> = 0; }; --- 1595,1604 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) scanner_node->conic_section_lattice_options->do_rectify = false; ! @=$$@> = static_cast(0); }; *************** *** 1613,1617 **** scanner_node->conic_section_lattice_options->do_shift = true; ! @=$$@> = 0; }; --- 1623,1627 ---- scanner_node->conic_section_lattice_options->do_shift = true; ! @=$$@> = static_cast(0); }; *************** *** 1636,1640 **** scanner_node->conic_section_lattice_options->do_shift = false; ! @=$$@> = 0; }; --- 1646,1650 ---- scanner_node->conic_section_lattice_options->do_shift = false; ! @=$$@> = static_cast(0); }; *************** *** 1656,1663 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) scanner_node->conic_section_lattice_options->do_test = true; ! @=$$@> = 0; }; --- 1666,1675 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) scanner_node->conic_section_lattice_options->do_test = true; ! @=$$@> = static_cast(0); }; *************** *** 1679,1686 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) scanner_node->conic_section_lattice_options->do_test = false; ! @=$$@> = 0; }; --- 1691,1700 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) scanner_node->conic_section_lattice_options->do_test = false; ! @=$$@> = static_cast(0); }; *************** *** 1703,1710 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) scanner_node->conic_section_lattice_options->do_transform = true; ! @=$$@> = 0; }; --- 1717,1726 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) scanner_node->conic_section_lattice_options->do_transform = true; ! @=$$@> = static_cast(0); }; *************** *** 1728,1732 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) { scanner_node->conic_section_lattice_options->do_transform = true; --- 1744,1750 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) { scanner_node->conic_section_lattice_options->do_transform = true; *************** *** 1735,1739 **** } ! @=$$@> = 0; }; --- 1753,1757 ---- } ! @=$$@> = static_cast(0); }; *************** *** 1756,1765 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node != 0 && scanner_node->conic_section_lattice_options != 0) { scanner_node->conic_section_lattice_options->do_transform = false; } ! @=$$@> = 0; }; --- 1774,1785 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node != static_cast(0) ! && scanner_node->conic_section_lattice_options ! != static_cast(0)) { scanner_node->conic_section_lattice_options->do_transform = false; } ! @=$$@> = static_cast(0); }; *************** *** 2614,2618 **** @= ! if (pv == 0) { cerr_strm << thread_name --- 2634,2638 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 2631,2635 **** delete p; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 2651,2655 ---- delete p; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 2659,2663 **** delete p; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 2679,2683 ---- delete p; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 2706,2710 **** Ellipse* e = static_cast(@=$3@>); ! if (e == 0) @=$$@> = static_cast(0); else --- 2726,2730 ---- Ellipse* e = static_cast(@=$3@>); ! if (e == static_cast(0)) @=$$@> = static_cast(0); else *************** *** 2810,2814 **** @= ! if (p == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', " --- 2830,2834 ---- @= ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', " *************** *** 2864,2868 **** @= ! if (@=$3@> == 0) { cerr_strm << thread_name --- 2884,2888 ---- @= ! if (@=$3@> == ZERO_REAL) { cerr_strm << thread_name *************** *** 3032,3036 **** Point* p = static_cast(@=$3@>); ! if (p == 0) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " --- 3052,3056 ---- Point* p = static_cast(@=$3@>); ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " *************** *** 3096,3100 **** Point* p = static_cast(@=$2@>); ! if (p == 0) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " --- 3116,3120 ---- Point* p = static_cast(@=$2@>); ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " *************** *** 3199,3203 **** @= ! if (p == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()'," --- 3219,3223 ---- @= ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()'," *************** *** 3216,3220 **** delete t; ! @=$$@> = 0; } /* |if (p == 0)| */@; --- 3236,3240 ---- delete t; ! @=$$@> = static_cast(0); } /* |if (p == 0)| */@; *************** *** 3246,3250 **** delete t; ! @=$$@> = 0; } /* |if (p == 0 || *p == INVALID_POINT)| */@; --- 3266,3270 ---- delete t; ! @=$$@> = static_cast(0); } /* |if (p == 0 || *p == INVALID_POINT)| */@; *************** *** 3268,3272 **** @= ! if (t == 0) { --- 3288,3292 ---- @= ! if (t == static_cast(0)) { *************** *** 3528,3532 **** @= ! if (p == 0) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " --- 3548,3552 ---- @= ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " *************** *** 3546,3550 **** @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (q != 0) delete q; --- 3566,3570 ---- @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (q != static_cast(0)) delete q; *************** *** 3556,3560 **** @= ! else if (q == 0) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " --- 3576,3580 ---- @= ! else if (q == static_cast(0)) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " *************** *** 3573,3577 **** @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (p != 0) delete p; --- 3593,3597 ---- @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (p != static_cast(0)) delete p; *************** *** 3634,3638 **** @= ! if (p == 0) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " --- 3654,3658 ---- @= ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " *************** *** 3652,3656 **** @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (q != 0) delete q; --- 3672,3676 ---- @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (q != static_cast(0)) delete q; *************** *** 3662,3666 **** @= ! else if (q == 0) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " --- 3682,3686 ---- @= ! else if (q == static_cast(0)) { cerr_strm << thread_name << "ERROR! In yyparse(), rule " *************** *** 3679,3683 **** @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (p != 0) delete p; --- 3699,3703 ---- @=$$@> = static_cast(create_new(&INVALID_POINT)); ! if (p != static_cast(0)) delete p; diff -rc2P 3DLDF-2.0.2/src/ppnvexpr.w 3DLDF-2.0.3/src/ppnvexpr.w *** 3DLDF-2.0.2/src/ppnvexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/ppnvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 101,108 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 101,108 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pprbexpr.w 3DLDF-2.0.3/src/pprbexpr.w *** 3DLDF-2.0.2/src/pprbexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pprbexpr.w Fri Dec 13 12:51:31 2013 *************** *** 103,107 **** entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 103,107 ---- entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 223,227 **** @= ! if (pv == 0) { cerr_strm << thread_name --- 223,227 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 240,244 **** delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 240,244 ---- delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 268,272 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 268,272 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 334,338 **** @=$$@> = (c) ? c->get_parabola(static_cast(parameter)) ! : @=$$@> = 0; }; --- 334,338 ---- @=$$@> = (c) ? c->get_parabola(static_cast(parameter)) ! : @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pprdexpr.w 3DLDF-2.0.3/src/pprdexpr.w *** 3DLDF-2.0.2/src/pprdexpr.w Thu Nov 7 13:36:04 2013 --- 3DLDF-2.0.3/src/pprdexpr.w Fri Dec 13 12:51:31 2013 *************** *** 89,93 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 89,93 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 155,164 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 155,164 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 176,180 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 176,180 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pprgstmt.w 3DLDF-2.0.3/src/pprgstmt.w *** 3DLDF-2.0.2/src/pprgstmt.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/pprgstmt.w Fri Dec 13 14:23:05 2013 *************** *** 164,168 **** \LOG @:BUG FIX@> BUG FIX: Now checking ! that |scanner_node != 0 && scanner_node->thread_info != 0| before setting |thread_name = scanner_node->thread_info->name|. \ENDLOG --- 164,168 ---- \LOG @:BUG FIX@> BUG FIX: Now checking ! that |scanner_node != 0 && scanner_node->thread_info != static_cast(0)| before setting |thread_name = scanner_node->thread_info->name|. \ENDLOG *************** *** 173,177 **** #ifdef HAVE_PTHREAD_H ! if ( scanner_node != 0 && scanner_node->thread_info != 0 && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) --- 173,178 ---- #ifdef HAVE_PTHREAD_H ! if ( scanner_node != static_cast(0) ! && scanner_node->thread_info != static_cast(0) && ( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_output)) *************** *** 261,265 **** ! if ( scanner_node->in->up != 0 && !( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_include)) --- 262,266 ---- ! if ( scanner_node->in->up != static_cast(0) && !( scanner_node->run_state.multithread_input || scanner_node->run_state.multithread_include)) *************** *** 268,272 **** Input_Struct* up = scanner_node->in->up; ! while (up != 0) { delete scanner_node->in; --- 269,273 ---- Input_Struct* up = scanner_node->in->up; ! while (up != static_cast(0)) { delete scanner_node->in; diff -rc2P 3DLDF-2.0.2/src/ppthexpr.w 3DLDF-2.0.3/src/ppthexpr.w *** 3DLDF-2.0.2/src/ppthexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ppthexpr.w Fri Dec 13 14:32:35 2013 *************** *** 116,120 **** @= ! if (entry == 0) { --- 116,120 ---- @= ! if (entry == static_cast(0)) { *************** *** 162,166 **** @= ! if (p == 0) { --- 162,166 ---- @= ! if (p == static_cast(0)) { *************** *** 348,358 **** << "`path_primary' on the right-hand side " << endl << "and proceeding with fingers crossed." ! << endl << flush; if (scanner_node->run_state.error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n" ! << flush; getchar(); /* Don't delete this! */@; } --- 348,358 ---- << "`path_primary' on the right-hand side " << endl << "and proceeding with fingers crossed." ! << endl; if (scanner_node->run_state.error_stop_mode == Run_State::STOPPING) { ! cerr << "Type to continue.\n"; ! getchar(); /* Don't delete this! */@; } *************** *** 693,697 **** ! @=$$@> = 0; }; --- 693,697 ---- ! @=$$@> = ZERO_REAL; }; *************** *** 890,894 **** @= ! if (t == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 890,894 ---- @= ! if (t == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 907,911 **** delete s; ! @=$$@> = 0; } /* |if (t == 0)| */ --- 907,911 ---- delete s; ! @=$$@> = static_cast(0); } /* |if (t == 0)| */ *************** *** 1114,1118 **** @= ! if (pv == 0) { cerr_strm << thread_name --- 1114,1118 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 1131,1135 **** delete p; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 1131,1135 ---- delete p; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 1159,1163 **** delete p; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 1159,1163 ---- delete p; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 1226,1230 **** @q ****** (6).@> ! if (n == 0) { cerr_strm << thread_name --- 1226,1230 ---- @q ****** (6).@> ! if (n == static_cast(0)) { cerr_strm << thread_name *************** *** 1241,1245 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (n == 0)| */ --- 1241,1245 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (n == 0)| */ *************** *** 1314,1318 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (status != 0)| */ --- 1314,1318 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ *************** *** 1392,1397 **** @=conic_section_lattice_expression with_conic_section_lattice_option_list@>@/ { ! if (@=$4@> == 0) ! @=$$@> = 0; else { --- 1392,1397 ---- @=conic_section_lattice_expression with_conic_section_lattice_option_list@>@/ { ! if (@=$4@> == static_cast(0)) ! @=$$@> = static_cast(0); else { diff -rc2P 3DLDF-2.0.2/src/pptvexpr.w 3DLDF-2.0.3/src/pptvexpr.w *** 3DLDF-2.0.2/src/pptvexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/pptvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 226,230 **** } else ! @=$$@> = 0; }; --- 226,230 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 540,544 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 540,544 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/ppygexpr.w 3DLDF-2.0.3/src/ppygexpr.w *** 3DLDF-2.0.2/src/ppygexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ppygexpr.w Fri Dec 13 14:26:20 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 136,141 **** { ! if (@=$2@> == 0) ! @=$$@> = 0; else { --- 136,141 ---- { ! if (@=$2@> == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 162,167 **** { ! if (@=$2@> == 0) ! @=$$@> = 0; else { --- 162,167 ---- { ! if (@=$2@> == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 188,193 **** { ! if (@=$2@> == 0) ! @=$$@> = 0; else { --- 188,193 ---- { ! if (@=$2@> == static_cast(0)) ! @=$$@> = static_cast(0); else { *************** *** 256,265 **** @= ! if (pv == 0) { delete r; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 256,265 ---- @= ! if (pv == static_cast*>(0)) { delete r; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 276,280 **** delete r; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 276,280 ---- delete r; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 470,474 **** if (!(c && p)) ! @=$$@> = 0; else @=$$@> = static_cast(c->intersection(*p, --- 470,474 ---- if (!(c && p)) ! @=$$@> = static_cast(0); else @=$$@> = static_cast(c->intersection(*p, *************** *** 503,507 **** if (!(c && p)) ! @=$$@> = 0; else @=$$@> = static_cast(c->intersection(*p, --- 503,507 ---- if (!(c && p)) ! @=$$@> = static_cast(0); else @=$$@> = static_cast(c->intersection(*p, *************** *** 536,540 **** if (!(p && q)) ! @=$$@> = 0; else @=$$@> = static_cast(p->intersection(*q, --- 536,540 ---- if (!(p && q)) ! @=$$@> = static_cast(0); else @=$$@> = static_cast(p->intersection(*q, *************** *** 569,573 **** if (!(p && q)) ! @=$$@> = 0; else @=$$@> = static_cast(p->intersection(*q, --- 569,573 ---- if (!(p && q)) ! @=$$@> = static_cast(0); else @=$$@> = static_cast(p->intersection(*q, diff -rc2P 3DLDF-2.0.2/src/prcvexpr.w 3DLDF-2.0.3/src/prcvexpr.w *** 3DLDF-2.0.2/src/prcvexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/prcvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 116,120 **** @= ! if (entry == 0 || entry->object == 0) { --- 116,120 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 133,137 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 133,137 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 298,302 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 298,302 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/precexpr.w 3DLDF-2.0.3/src/precexpr.w *** 3DLDF-2.0.2/src/precexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/precexpr.w Fri Dec 13 14:26:49 2013 *************** *** 94,98 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 94,98 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 188,192 **** @= ! if (t == 0) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " --- 188,192 ---- @= ! if (t == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `yyparse()', rule " *************** *** 205,209 **** delete s; ! @=$$@> = 0; } /* |if (t == 0)| */ --- 205,209 ---- delete s; ! @=$$@> = static_cast(0); } /* |if (t == 0)| */ *************** *** 309,313 **** } else ! @=$$@> = 0; }; --- 309,313 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 345,349 **** } else ! @=$$@> = 0; }; --- 345,349 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 447,451 **** @= ! if (pv == 0) { cerr_strm << thread_name --- 447,451 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 464,468 **** delete r; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 464,468 ---- delete r; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 492,496 **** delete r; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 492,496 ---- delete r; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 545,549 **** if (r.size() != 4) ! @=$$@> = 0; else @=$$@> = static_cast(create_new(r)); --- 545,549 ---- if (r.size() != 4) ! @=$$@> = static_cast(0); else @=$$@> = static_cast(create_new(r)); *************** *** 553,557 **** else { ! @=$$@> = 0; } --- 553,557 ---- else { ! @=$$@> = static_cast(0); } diff -rc2P 3DLDF-2.0.2/src/predctes.web 3DLDF-2.0.3/src/predctes.web *** 3DLDF-2.0.2/src/predctes.web Thu Nov 7 13:36:08 2013 --- 3DLDF-2.0.3/src/predctes.web Wed Dec 11 18:52:33 2013 *************** *** 268,272 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 268,272 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 376,380 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 376,380 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; diff -rc2P 3DLDF-2.0.2/src/prelims.web 3DLDF-2.0.3/src/prelims.web *** 3DLDF-2.0.2/src/prelims.web Thu Nov 7 13:36:42 2013 --- 3DLDF-2.0.3/src/prelims.web Fri Dec 13 14:27:04 2013 *************** *** 73,77 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 73,77 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; diff -rc2P 3DLDF-2.0.2/src/primes.web 3DLDF-2.0.3/src/primes.web *** 3DLDF-2.0.2/src/primes.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/primes.web Fri Dec 13 14:50:03 2013 *************** *** 175,179 **** ! if (primes_table != 0) { B: --- 175,179 ---- ! if (primes_table != static_cast*>(0)) { B: *************** *** 537,541 **** @q **** (4)@> ! if (primes_table == 0 || primes_table->size() < v) { get_prime(v, scanner_node); --- 537,541 ---- @q **** (4)@> ! if (primes_table == static_cast*>(0) || primes_table->size() < v) { get_prime(v, scanner_node); *************** *** 633,637 **** r = n % (*primes_table)[k]; ! if (r == 0) { break; --- 633,637 ---- r = n % (*primes_table)[k]; ! if (r == 0ULL) { break; *************** *** 686,690 **** @q **** (4)@> ! if (primes_table == 0) { cerr_mutex.lock(); --- 686,690 ---- @q **** (4)@> ! if (primes_table == static_cast*>(0)) { cerr_mutex.lock(); diff -rc2P 3DLDF-2.0.2/src/prplexpr.w 3DLDF-2.0.3/src/prplexpr.w *** 3DLDF-2.0.2/src/prplexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/prplexpr.w Fri Dec 13 14:28:46 2013 *************** *** 94,98 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 94,98 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 180,189 **** ! if (t == 0) { delete s; ! @=$$@> = 0; } /* |if (t == 0)| */ --- 180,189 ---- ! if (t == static_cast(0)) { delete s; ! @=$$@> = static_cast(0); } /* |if (t == 0)| */ *************** *** 240,249 **** const Reg_Polygon* t = p->get_reg_polygon_ptr(u); ! if (t == 0) { delete p; ! @=$$@> = 0; } /* |if (t == 0)| */ --- 240,249 ---- const Reg_Polygon* t = p->get_reg_polygon_ptr(u); ! if (t == static_cast(0)) { delete p; ! @=$$@> = static_cast(0); } /* |if (t == 0)| */ *************** *** 299,308 **** @= ! if (pv == 0) { delete r; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 299,308 ---- @= ! if (pv == static_cast*>(0)) { delete r; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 319,323 **** delete r; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 319,323 ---- delete r; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/prpvexpr.w 3DLDF-2.0.3/src/prpvexpr.w *** 3DLDF-2.0.2/src/prpvexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/prpvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 360,364 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 360,364 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/prrfnc0.web 3DLDF-2.0.3/src/prrfnc0.web *** 3DLDF-2.0.2/src/prrfnc0.web Wed Nov 6 20:56:24 2013 --- 3DLDF-2.0.3/src/prrfnc0.web Fri Dec 13 14:31:51 2013 *************** *** 3215,3219 **** @q **** (4)@> ! if (bp == 0) { --- 3215,3219 ---- @q **** (4)@> ! if (bp == static_cast(0)) { *************** *** 3257,3261 **** @q **** (4)@> ! if (s == 0) { stringstream label_strm; --- 3257,3261 ---- @q **** (4)@> ! if (s == static_cast(0)) { stringstream label_strm; *************** *** 3503,3506 **** --- 3503,3510 ---- \initials{LDF 2006.02.23.} Now setting |*result| to 0, if the value returned by |sin() < .00001|. + + \initials{LDF 2013.12.11.} + Added conditionally compiled code for the cases that |real| is a |typedef| for |float| + or |double|. This eliminates a warning from GCC. \ENDLOG *************** *** 3510,3516 **** { ! operand = fmod(operand, 360.0); ! real r = sin((PI/180.0) * operand); *result = (fabs(r) < .00001) ? 0 : r; return 0; --- 3514,3530 ---- { ! real r; ! #if LDF_REAL_FLOAT ! operand = fmodf(operand, 360.0F); ! r = sin((PI/180.0F) * operand); ! #elif LDF_REAL_DOUBLE ! operand = fmod(operand, 360.0D); ! r = sin((PI/180.0D) * operand); ! #else /* Default. */ ! operand = fmodf(operand, 360.0F); ! r = sin((PI/180.0F) * operand); ! #endif ! *result = (fabs(r) < .00001) ? 0 : r; return 0; *************** *** 3524,3527 **** --- 3538,3545 ---- \initials{LDF 2006.02.23.} Now setting |*result| to 0, if the value returned by |cos() < .00001|. + + \initials{LDF 2013.12.11.} + Added conditionally compiled code for the cases that |real| is a |typedef| for |float| + or |double|. This eliminates a warning from GCC. \ENDLOG *************** *** 3530,3535 **** else if (operator_value == COSD) { ! operand = fmod(operand, 360.0); ! real r = cos((PI/180.0) * operand); *result = (fabs(r) < .00001) ? 0 : r; return 0; --- 3548,3566 ---- else if (operator_value == COSD) { ! ! real r; ! ! #if LDF_REAL_FLOAT ! operand = fmodf(operand, 360.0F); ! r = cos((PI/180.0F) * operand); ! #elif LDF_REAL_DOUBLE ! operand = fmod(operand, 360.0D); ! r = cos((PI/180.0D) * operand); ! #else /* Default. */ ! operand = fmodf(operand, 360.0F); ! r = cos((PI/180.0F) * operand); ! ! #endif ! *result = (fabs(r) < .00001) ? 0 : r; return 0; *************** *** 3542,3545 **** --- 3573,3580 ---- \initials{LDF 2007.02.06.} Added this section. + + \initials{LDF 2013.12.11.} + Added conditionally compiled code for the cases that |real| is a |typedef| for |float| + or |double|. This eliminates a warning from GCC. \ENDLOG *************** *** 3549,3553 **** { ! operand = fmod(operand, 360.0); @q ****** (6)@> --- 3584,3594 ---- { ! #if LDF_REAL_FLOAT ! operand = fmodf(operand, 360.0F); ! #elif LDF_REAL_DOUBLE ! operand = fmod(operand, 360.0D); ! #else /* Default. */ ! operand = fmodf(operand, 360.0F); ! #endif @q ****** (6)@> *************** *** 3969,3973 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 4010,4014 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 4118,4122 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 4159,4163 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 4527,4531 **** @q **** (4).@> ! if (ffocus == 0) return 0; --- 4568,4572 ---- @q **** (4).@> ! if (ffocus == static_cast(0)) return 0; *************** *** 4613,4617 **** @q **** (4)@> ! if (transform == 0) { --- 4654,4658 ---- @q **** (4)@> ! if (transform == static_cast(0)) { *************** *** 4836,4840 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 4877,4881 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 5140,5144 **** = static_cast(to_picture_entry); ! if (p_entry == 0) { cerr_strm << "ERROR! " --- 5181,5185 ---- = static_cast(to_picture_entry); ! if (p_entry == static_cast(0)) { cerr_strm << "ERROR! " *************** *** 5162,5166 **** Picture* p; ! if (p_entry->object == 0) { p = new Picture; --- 5203,5207 ---- Picture* p; ! if (p_entry->object == static_cast(0)) { p = new Picture; *************** *** 5181,5185 **** ! if (q_entry == 0) { cerr_strm << "ERROR! " --- 5222,5226 ---- ! if (q_entry == static_cast(0)) { cerr_strm << "ERROR! " *************** *** 5202,5206 **** Picture* q; ! if (q_entry->object == 0) { q = new Picture; --- 5243,5247 ---- Picture* q; ! if (q_entry->object == static_cast(0)) { q = new Picture; *************** *** 5266,5270 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 5307,5311 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 5321,5325 **** @q ***** (5)@> ! if (curr_var == 0 || parameter == 0) return 1; --- 5362,5366 ---- @q ***** (5)@> ! if (curr_var == static_cast(0) || parameter == static_cast(0)) return 1; *************** *** 5328,5332 **** Matrix* curr_matrix = static_cast(entry->object); ! if (curr_matrix == 0) { curr_matrix = create_new(0); --- 5369,5373 ---- Matrix* curr_matrix = static_cast(entry->object); ! if (curr_matrix == static_cast(0)) { curr_matrix = create_new(0); *************** *** 5399,5403 **** ! if (curr_var == 0 || parameter == 0) return 1; --- 5440,5444 ---- ! if (curr_var == static_cast(0) || parameter == static_cast(0)) return 1; *************** *** 5411,5415 **** Parabola* curr_parabola = static_cast(entry->object); ! if (curr_parabola == 0) { curr_parabola = create_new(0); --- 5452,5456 ---- Parabola* curr_parabola = static_cast(entry->object); ! if (curr_parabola == static_cast(0)) { curr_parabola = create_new(0); *************** *** 5449,5453 **** ! if (curr_var == 0 || parameter == 0) return 1; --- 5490,5494 ---- ! if (curr_var == static_cast(0) || parameter == static_cast(0)) return 1; *************** *** 5460,5464 **** Hyperbola* curr_hyperbola = static_cast(entry->object); ! if (curr_hyperbola == 0) { curr_hyperbola = create_new(0); --- 5501,5505 ---- Hyperbola* curr_hyperbola = static_cast(entry->object); ! if (curr_hyperbola == static_cast(0)) { curr_hyperbola = create_new(0); *************** *** 5498,5502 **** ! if (curr_var == 0 || parameter == 0) return 1; --- 5539,5543 ---- ! if (curr_var == static_cast(0) || parameter == static_cast(0)) return 1; *************** *** 5511,5515 **** Arc* curr_arc = static_cast(entry->object); ! if (curr_arc == 0) { curr_arc = create_new(0); --- 5552,5556 ---- Arc* curr_arc = static_cast(entry->object); ! if (curr_arc == static_cast(0)) { curr_arc = create_new(0); *************** *** 5587,5591 **** @q ***** (5)@> ! if (entry == 0) { cerr_strm << thread_name --- 5628,5632 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 5613,5617 **** Helix* curr_helix; ! if (entry->object == 0) { curr_helix = create_new(0); --- 5654,5658 ---- Helix* curr_helix; ! if (entry->object == static_cast(0)) { curr_helix = create_new(0); *************** *** 5683,5687 **** @q ***** (5)@> ! if (entry == 0) { cerr_strm << thread_name --- 5724,5728 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 5709,5713 **** Cone* curr_cone; ! if (entry->object == 0) { curr_cone = create_new(0); --- 5750,5754 ---- Cone* curr_cone; ! if (entry->object == static_cast(0)) { curr_cone = create_new(0); *************** *** 5776,5780 **** @q ***** (5)@> ! if (entry == 0) { cerr_strm << thread_name --- 5817,5821 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 5802,5806 **** Cylinder* curr_cylinder; ! if (entry->object == 0) { curr_cylinder = create_new(0); --- 5843,5847 ---- Cylinder* curr_cylinder; ! if (entry->object == static_cast(0)) { curr_cylinder = create_new(0); *************** *** 5875,5879 **** @q ***** (5)@> ! if (entry == 0) { cerr_strm << thread_name --- 5916,5920 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 5901,5905 **** Ellipsoid* curr_ellipsoid; ! if (entry->object == 0) { curr_ellipsoid = create_new(0); --- 5942,5946 ---- Ellipsoid* curr_ellipsoid; ! if (entry->object == static_cast(0)) { curr_ellipsoid = create_new(0); *************** *** 5971,5975 **** @q ***** (5)@> ! if (entry == 0) { cerr_strm << thread_name --- 6012,6016 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 5997,6001 **** Sphere* curr_sphere; ! if (entry->object == 0) { curr_sphere = create_new(0); --- 6038,6042 ---- Sphere* curr_sphere; ! if (entry->object == static_cast(0)) { curr_sphere = create_new(0); *************** *** 6053,6057 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 6094,6098 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 6079,6083 **** @q ***** (5)@> ! if (entry == 0) { cerr_strm << thread_name --- 6120,6124 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 6105,6109 **** Sphere_Development* curr_sphere_development; ! if (entry->object == 0) { curr_sphere_development = create_new(0); --- 6146,6150 ---- Sphere_Development* curr_sphere_development; ! if (entry->object == static_cast(0)) { curr_sphere_development = create_new(0); *************** *** 6182,6186 **** @q ***** (5)@> ! if (entry == 0) { cerr_strm << thread_name --- 6223,6227 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 6237,6241 **** @q ***** (5)@> ! if (entry->object == 0 && options->type == Paraboloid::ELLIPTICAL_TYPE) { Elliptical_Paraboloid* curr_paraboloid --- 6278,6282 ---- @q ***** (5)@> ! if (entry->object == static_cast(0) && options->type == Paraboloid::ELLIPTICAL_TYPE) { Elliptical_Paraboloid* curr_paraboloid *************** *** 6253,6257 **** ! else if (entry->object == 0 && options->type == Paraboloid::HYPERBOLIC_TYPE) { Hyperbolic_Paraboloid* curr_paraboloid --- 6294,6299 ---- ! else if ( entry->object == static_cast(0) ! && options->type == Paraboloid::HYPERBOLIC_TYPE) { Hyperbolic_Paraboloid* curr_paraboloid *************** *** 6266,6270 **** @q ***** (5)@> ! else if (entry->object != 0) { Paraboloid* curr_paraboloid = static_cast(entry->object); --- 6308,6312 ---- @q ***** (5)@> ! else if (entry->object != static_cast(0)) { Paraboloid* curr_paraboloid = static_cast(entry->object); diff -rc2P 3DLDF-2.0.2/src/psetcmnd.w 3DLDF-2.0.3/src/psetcmnd.w *** 3DLDF-2.0.2/src/psetcmnd.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/psetcmnd.w Fri Dec 13 14:52:37 2013 *************** *** 166,170 **** @= ! if (entry == 0) { --- 166,170 ---- @= ! if (entry == static_cast(0)) { *************** *** 196,200 **** @= ! if (entry->object == 0) { --- 196,200 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 248,252 **** @q ***** (5) @> ! @=$$@> = 0; }; --- 248,252 ---- @q ***** (5) @> ! @=$$@> = static_cast(0); }; *************** *** 554,561 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 554,561 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 578,585 **** @= ! if (e == 0) { - e = create_new(0); --- 578,584 ---- @= ! if (e == static_cast(0)) { e = create_new(0); *************** *** 706,712 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 705,711 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 729,733 **** @= ! if (c == 0) { --- 728,732 ---- @= ! if (c == static_cast(0)) { *************** *** 844,848 **** static_cast(parameter)->parabola_set_option_struct = 0; ! @=$$@> = 0; }; --- 843,847 ---- static_cast(parameter)->parabola_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 877,881 **** ! if (scanner_node->parabola_set_option_struct != 0) scanner_node->parabola_set_option_struct->clear(); --- 876,881 ---- ! if ( scanner_node->parabola_set_option_struct ! != static_cast(0)) scanner_node->parabola_set_option_struct->clear(); *************** *** 883,887 **** scanner_node->parabola_set_option_struct = new Parabola_Set_Option_Struct; ! @=$$@> = 0; }; --- 883,887 ---- scanner_node->parabola_set_option_struct = new Parabola_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 903,907 **** { ! @=$$@> = 0; }; --- 903,907 ---- { ! @=$$@> = static_cast(0); }; *************** *** 937,941 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 937,941 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 958,962 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 958,962 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 979,983 **** = @=$2@>; ! @=$$@> = 0; }; --- 979,983 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1001,1005 **** = @=$2@> / 2; ! @=$$@> = 0; }; --- 1001,1005 ---- = @=$2@> / 2; ! @=$$@> = static_cast(0); }; *************** *** 1024,1028 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1024,1028 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1045,1049 **** = @=$2@>; ! @=$$@> = 0; }; --- 1045,1049 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1066,1070 **** = @=$2@>; ! @=$$@> = 0; }; --- 1066,1070 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1102,1106 **** static_cast(parameter)->hyperbola_set_option_struct = 0; ! @=$$@> = 0; }; --- 1102,1106 ---- static_cast(parameter)->hyperbola_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 1135,1139 **** ! if (scanner_node->hyperbola_set_option_struct != 0) scanner_node->hyperbola_set_option_struct->clear(); --- 1135,1139 ---- ! if (scanner_node->hyperbola_set_option_struct != static_cast(0)) scanner_node->hyperbola_set_option_struct->clear(); *************** *** 1141,1145 **** scanner_node->hyperbola_set_option_struct = new Hyperbola_Set_Option_Struct; ! @=$$@> = 0; }; --- 1141,1145 ---- scanner_node->hyperbola_set_option_struct = new Hyperbola_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 1161,1165 **** { ! @=$$@> = 0; }; --- 1161,1165 ---- { ! @=$$@> = static_cast(0); }; *************** *** 1195,1199 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1195,1199 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1219,1223 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1219,1223 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1240,1244 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1240,1244 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1261,1265 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1261,1265 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1282,1286 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1282,1286 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1303,1307 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1303,1307 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1324,1328 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1324,1328 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1345,1349 **** = @=$2@>; ! @=$$@> = 0; }; --- 1345,1349 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1367,1371 **** = @=$2@> / 2; ! @=$$@> = 0; }; --- 1367,1371 ---- = @=$2@> / 2; ! @=$$@> = static_cast(0); }; *************** *** 1389,1393 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1389,1393 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1410,1414 **** = @=$2@>; ! @=$$@> = 0; }; --- 1410,1414 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1431,1435 **** = @=$2@>; ! @=$$@> = 0; }; --- 1431,1435 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1454,1458 **** = @=$2@>; ! @=$$@> = 0; }; --- 1454,1458 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1477,1481 **** = @=$2@> / 2; ! @=$$@> = 0; }; --- 1477,1481 ---- = @=$2@> / 2; ! @=$$@> = static_cast(0); }; *************** *** 1500,1504 **** = @=$2@>; ! @=$$@> = 0; }; --- 1500,1504 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1523,1527 **** = @=$2@> / 2; ! @=$$@> = 0; }; --- 1523,1527 ---- = @=$2@> / 2; ! @=$$@> = static_cast(0); }; *************** *** 1575,1579 **** static_cast(parameter)->helix_set_option_struct = 0; ! @=$$@> = 0; }; --- 1575,1579 ---- static_cast(parameter)->helix_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 1608,1612 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->helix_set_option_struct != 0) scanner_node->helix_set_option_struct->clear(); --- 1608,1612 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->helix_set_option_struct != static_cast(0)) scanner_node->helix_set_option_struct->clear(); *************** *** 1614,1618 **** scanner_node->helix_set_option_struct = new Helix_Set_Option_Struct; ! @=$$@> = 0; }; --- 1614,1618 ---- scanner_node->helix_set_option_struct = new Helix_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 1634,1638 **** { ! @=$$@> = 0; }; --- 1634,1638 ---- { ! @=$$@> = static_cast(0); }; *************** *** 1668,1672 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1668,1672 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1689,1693 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 1689,1693 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1710,1714 **** = static_cast*>(@=$2@>); ! @=$$@> = 0; }; --- 1710,1714 ---- = static_cast*>(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1731,1735 **** = @=$2@>; ! @=$$@> = 0; }; --- 1731,1735 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1756,1760 **** ! @=$$@> = 0; }; --- 1756,1760 ---- ! @=$$@> = static_cast(0); }; *************** *** 1776,1780 **** static_cast(parameter)->helix_set_option_struct->cycles = fabs(@=$2@>); ! @=$$@> = 0; }; --- 1776,1780 ---- static_cast(parameter)->helix_set_option_struct->cycles = fabs(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 1797,1801 **** = fmod(fabs(@=$2@>), 360); ! @=$$@> = 0; }; --- 1797,1801 ---- = fmod(fabs(@=$2@>), 360); ! @=$$@> = static_cast(0); }; *************** *** 1818,1822 **** static_cast(parameter)->helix_set_option_struct->type = @=$2@>; ! @=$$@> = 0; }; --- 1818,1822 ---- static_cast(parameter)->helix_set_option_struct->type = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 1972,1979 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 1972,1979 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 1996,2000 **** @= ! if (t == 0) { --- 1996,2000 ---- @= ! if (t == static_cast(0)) { *************** *** 2067,2073 **** @= ! if (entry == 0) { ! @=$$@> = 0; } /* |if (entry == 0)| */ --- 2067,2073 ---- @= ! if (entry == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0)| */ *************** *** 2090,2094 **** @= ! if (r == 0) { --- 2090,2094 ---- @= ! if (r == static_cast(0)) { *************** *** 2476,2480 **** @= ! if (r == 0) { --- 2476,2480 ---- @= ! if (r == ZERO_REAL) { *************** *** 2633,2637 **** static_cast(parameter)->cone_set_option_struct = 0; ! @=$$@> = 0; }; --- 2633,2637 ---- static_cast(parameter)->cone_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 2666,2670 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct != 0) scanner_node->cone_set_option_struct->clear(); --- 2666,2670 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct != static_cast(0)) scanner_node->cone_set_option_struct->clear(); *************** *** 2672,2676 **** scanner_node->cone_set_option_struct = new Cone_Set_Option_Struct; ! @=$$@> = 0; }; --- 2672,2676 ---- scanner_node->cone_set_option_struct = new Cone_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 2692,2696 **** { ! @=$$@> = 0; }; --- 2692,2696 ---- { ! @=$$@> = static_cast(0); }; *************** *** 2726,2730 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 2726,2730 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 2747,2757 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; ! @q ** (2) set_cone_option_list --> WITH_RADIUS numeric_expression.@> ! @* \§set cone option list> $\longrightarrow$ \.{WITH\_RADIUS} ! \§numeric expresssion>. \initials{LDF 2006.11.08.} --- 2747,2756 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; ! @q ** (2) set_cone_option --> WITH_RADIUS numeric_expression.@> ! @* \§set cone option> $\longrightarrow$ \.{WITH\_RADIUS} \§numeric expresssion>. \initials{LDF 2006.11.08.} *************** *** 2767,2771 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->radius == 0) scanner_node->cone_set_option_struct->radius = new real(@=$2@>); else --- 2766,2770 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->radius == static_cast(0)) scanner_node->cone_set_option_struct->radius = new real(@=$2@>); else *************** *** 2773,2777 **** ! @=$$@> = 0; }; --- 2772,2776 ---- ! @=$$@> = static_cast(0); }; *************** *** 2793,2802 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->axis_x == 0) scanner_node->cone_set_option_struct->axis_x = new real(@=$2@>); else *scanner_node->cone_set_option_struct->axis_x = @=$2@>; ! @=$$@> = 0; }; --- 2792,2801 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->axis_x == static_cast(0)) scanner_node->cone_set_option_struct->axis_x = new real(@=$2@>); else *scanner_node->cone_set_option_struct->axis_x = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 2818,2827 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->axis_y == 0) scanner_node->cone_set_option_struct->axis_y = new real(@=$2@>); else *scanner_node->cone_set_option_struct->axis_y = @=$2@>; ! @=$$@> = 0; }; --- 2817,2826 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->axis_y == static_cast(0)) scanner_node->cone_set_option_struct->axis_y = new real(@=$2@>); else *scanner_node->cone_set_option_struct->axis_y = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 2843,2852 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->axis_z == 0) scanner_node->cone_set_option_struct->axis_z = new real(@=$2@>); else *scanner_node->cone_set_option_struct->axis_z = @=$2@>; ! @=$$@> = 0; }; --- 2842,2851 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cone_set_option_struct->axis_z == static_cast(0)) scanner_node->cone_set_option_struct->axis_z = new real(@=$2@>); else *scanner_node->cone_set_option_struct->axis_z = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 2869,2873 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 2868,2872 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 2890,2894 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 2889,2893 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 2912,2916 **** = @=$2@>; ! @=$$@> = 0; }; --- 2911,2915 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3018,3022 **** = @=$2@>; ! @=$$@> = 0; }; --- 3017,3021 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3106,3110 **** static_cast(parameter)->cylinder_set_option_struct = 0; ! @=$$@> = 0; }; --- 3105,3109 ---- static_cast(parameter)->cylinder_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 3139,3143 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct != 0) scanner_node->cylinder_set_option_struct->clear(); --- 3138,3142 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct != static_cast(0)) scanner_node->cylinder_set_option_struct->clear(); *************** *** 3146,3150 **** ! @=$$@> = 0; }; --- 3145,3149 ---- ! @=$$@> = static_cast(0); }; *************** *** 3166,3170 **** { ! @=$$@> = 0; }; --- 3165,3169 ---- { ! @=$$@> = static_cast(0); }; *************** *** 3200,3204 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 3199,3203 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 3222,3226 **** = static_cast(@=$2@>); ! @=$$@> = 0; --- 3221,3225 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); *************** *** 3243,3247 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->radius == 0) scanner_node->cylinder_set_option_struct->radius = new real(@=$2@>); else --- 3242,3246 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->radius == static_cast(0)) scanner_node->cylinder_set_option_struct->radius = new real(@=$2@>); else *************** *** 3249,3253 **** ! @=$$@> = 0; }; --- 3248,3252 ---- ! @=$$@> = static_cast(0); }; *************** *** 3270,3279 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->axis_x == 0) scanner_node->cylinder_set_option_struct->axis_x = new real(@=$2@>); else *scanner_node->cylinder_set_option_struct->axis_x = @=$2@>; ! @=$$@> = 0; }; --- 3269,3278 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->axis_x == static_cast(0)) scanner_node->cylinder_set_option_struct->axis_x = new real(@=$2@>); else *scanner_node->cylinder_set_option_struct->axis_x = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3295,3304 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->axis_y == 0) scanner_node->cylinder_set_option_struct->axis_y = new real(@=$2@>); else *scanner_node->cylinder_set_option_struct->axis_y = @=$2@>; ! @=$$@> = 0; }; --- 3294,3303 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->axis_y == static_cast(0)) scanner_node->cylinder_set_option_struct->axis_y = new real(@=$2@>); else *scanner_node->cylinder_set_option_struct->axis_y = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3320,3329 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->axis_z == 0) scanner_node->cylinder_set_option_struct->axis_z = new real(@=$2@>); else *scanner_node->cylinder_set_option_struct->axis_z = @=$2@>; ! @=$$@> = 0; }; --- 3319,3328 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->cylinder_set_option_struct->axis_z == static_cast(0)) scanner_node->cylinder_set_option_struct->axis_z = new real(@=$2@>); else *scanner_node->cylinder_set_option_struct->axis_z = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3346,3350 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3345,3349 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3367,3371 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3366,3370 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3389,3393 **** = @=$2@>; ! @=$$@> = 0; }; --- 3388,3392 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3512,3516 **** static_cast(parameter)->ellipsoid_set_option_struct = 0; ! @=$$@> = 0; }; --- 3511,3515 ---- static_cast(parameter)->ellipsoid_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 3548,3552 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->ellipsoid_set_option_struct != 0) scanner_node->ellipsoid_set_option_struct->clear(); --- 3547,3551 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->ellipsoid_set_option_struct != static_cast(0)) scanner_node->ellipsoid_set_option_struct->clear(); *************** *** 3554,3558 **** scanner_node->ellipsoid_set_option_struct = new Ellipsoid_Set_Option_Struct; ! @=$$@> = 0; }; --- 3553,3557 ---- scanner_node->ellipsoid_set_option_struct = new Ellipsoid_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 3573,3577 **** @=set_ellipsoid_option_list: set_ellipsoid_option_list set_ellipsoid_option@>@/ { ! @=$$@> = 0; }; --- 3572,3576 ---- @=set_ellipsoid_option_list: set_ellipsoid_option_list set_ellipsoid_option@>@/ { ! @=$$@> = static_cast(0); }; *************** *** 3607,3611 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 3606,3610 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 3637,3641 **** = @=$2@>; ! @=$$@> = 0; }; --- 3636,3640 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3659,3663 **** = @=$2@>; ! @=$$@> = 0; }; --- 3658,3662 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3680,3684 **** = @=$2@>; ! @=$$@> = 0; }; --- 3679,3683 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 3711,3715 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3710,3714 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3732,3736 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3731,3735 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3753,3757 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3752,3756 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3774,3778 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3773,3777 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3810,3814 **** static_cast(parameter)->sphere_set_option_struct = 0; ! @=$$@> = 0; }; --- 3809,3813 ---- static_cast(parameter)->sphere_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 3846,3850 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->sphere_set_option_struct != 0) scanner_node->sphere_set_option_struct->clear(); --- 3845,3849 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->sphere_set_option_struct != static_cast(0)) scanner_node->sphere_set_option_struct->clear(); *************** *** 3852,3856 **** scanner_node->sphere_set_option_struct = new Sphere_Set_Option_Struct; ! @=$$@> = 0; }; --- 3851,3855 ---- scanner_node->sphere_set_option_struct = new Sphere_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 3872,3876 **** { ! @=$$@> = 0; }; --- 3871,3875 ---- { ! @=$$@> = static_cast(0); }; *************** *** 3910,3914 **** = static_cast(@=$2@>); ! @=$$@> = 0; }; --- 3909,3913 ---- = static_cast(@=$2@>); ! @=$$@> = static_cast(0); }; *************** *** 3945,3949 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3944,3948 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3970,3974 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3969,3973 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 3995,3999 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 3994,3998 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 4015,4019 **** static_cast(parameter)->sphere_set_option_struct->radius = @=$2@>; ! @=$$@> = 0; }; --- 4014,4018 ---- static_cast(parameter)->sphere_set_option_struct->radius = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 4040,4044 **** static_cast(parameter)->sphere_set_option_struct->radius = .5 * @=$2@>; ! @=$$@> = 0; }; --- 4039,4043 ---- static_cast(parameter)->sphere_set_option_struct->radius = .5 * @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 4063,4067 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 4062,4066 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 4083,4087 **** = @=$2@>; ! @=$$@> = 0; }; --- 4082,4086 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 4167,4171 **** static_cast(parameter)->sphere_development_set_option_struct = 0; ! @=$$@> = 0; }; --- 4166,4170 ---- static_cast(parameter)->sphere_development_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 4199,4203 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->sphere_development_set_option_struct != 0) scanner_node->sphere_development_set_option_struct->clear(); --- 4198,4203 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node->sphere_development_set_option_struct ! != static_cast(0)) scanner_node->sphere_development_set_option_struct->clear(); *************** *** 4206,4210 **** = new Sphere_Development_Set_Option_Struct; ! @=$$@> = 0; }; --- 4206,4210 ---- = new Sphere_Development_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 4227,4231 **** { ! @=$$@> = 0; }; --- 4227,4231 ---- { ! @=$$@> = static_cast(0); }; *************** *** 4263,4267 **** = @=$2@>; ! @=$$@> = 0; }; --- 4263,4267 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 4284,4288 **** = .5 * @=$2@>; ! @=$$@> = 0; }; --- 4284,4288 ---- = .5 * @=$2@>; ! @=$$@> = static_cast(0); }; *************** *** 4306,4314 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; ! @q *** (3) set_sphere_development_option_list --> WITH_DIVISIONS_LONGITUDE numeric_expression.@> @*2 \§set sphere_development option list> $\longrightarrow$ \.{WITH\_DIVISIONS\_LONGITUDE} \§numeric expresssion>. --- 4306,4314 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; ! @q *** (3) set_sphere_development_option_list --> WITH_DIVISIONS_LONGITUDE numeric_expression.@> @*2 \§set sphere_development option list> $\longrightarrow$ \.{WITH\_DIVISIONS\_LONGITUDE} \§numeric expresssion>. *************** *** 4328,4332 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 4328,4332 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 4350,4354 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 4350,4354 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 4371,4375 **** = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = 0; }; --- 4371,4375 ---- = static_cast(floor(fabs(@=$2@>) + .5)); ! @=$$@> = static_cast(0); }; *************** *** 4392,4396 **** Transform* t = static_cast(@=$2@>); ! if (t != 0) { static_cast( --- 4392,4396 ---- Transform* t = static_cast(@=$2@>); ! if (t != static_cast(0)) { static_cast( *************** *** 4402,4406 **** } ! @=$$@> = 0; }; --- 4402,4406 ---- } ! @=$$@> = static_cast(0); }; *************** *** 4439,4443 **** static_cast(parameter)->paraboloid_set_option_struct = 0; ! @=$$@> = 0; }; --- 4439,4443 ---- static_cast(parameter)->paraboloid_set_option_struct = 0; ! @=$$@> = static_cast(0); }; *************** *** 4471,4475 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->paraboloid_set_option_struct != 0) scanner_node->paraboloid_set_option_struct->clear(); --- 4471,4476 ---- Scanner_Node scanner_node = static_cast(parameter); ! if ( scanner_node->paraboloid_set_option_struct ! != static_cast(0)) scanner_node->paraboloid_set_option_struct->clear(); *************** *** 4477,4481 **** scanner_node->paraboloid_set_option_struct = new Paraboloid_Set_Option_Struct; ! @=$$@> = 0; }; --- 4478,4482 ---- scanner_node->paraboloid_set_option_struct = new Paraboloid_Set_Option_Struct; ! @=$$@> = static_cast(0); }; *************** *** 4497,4501 **** { ! @=$$@> = 0; }; --- 4498,4502 ---- { ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pshowcmd.w 3DLDF-2.0.3/src/pshowcmd.w *** 3DLDF-2.0.2/src/pshowcmd.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/pshowcmd.w Fri Dec 13 11:59:34 2013 *************** *** 110,114 **** cerr_strm.str(""); ! @=$$@> = 0; }; --- 110,114 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); }; *************** *** 166,170 **** cerr_strm.str(""); ! @=$$@> = 0; }; --- 166,170 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); }; *************** *** 193,197 **** parameter); ! @=$$@> = 0; }; --- 193,197 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 221,225 **** parameter); ! @=$$@> = 0; }; --- 221,225 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 252,256 **** @=fixed_optional: /* Empty */@>@/ { ! @=$$@> = 0; }; --- 252,256 ---- @=fixed_optional: /* Empty */@>@/ { ! @=$$@> = 0; /* integer */ }; *************** *** 302,306 **** cerr_strm.str(""); ! @=$$@> = 0; }; --- 302,306 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); }; *************** *** 365,369 **** cerr_strm.str(""); ! @=$$@> = 0; }; --- 365,369 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); }; *************** *** 398,402 **** parameter); ! @=$$@> = 0; }; --- 398,402 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 429,433 **** parameter); ! @=$$@> = 0; --- 429,433 ---- parameter); ! @=$$@> = static_cast(0); *************** *** 462,466 **** parameter); ! @=$$@> = 0; --- 462,466 ---- parameter); ! @=$$@> = static_cast(0); *************** *** 494,498 **** parameter); ! @=$$@> = 0; }; --- 494,498 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 543,547 **** ! @=$$@> = 0; }; --- 543,547 ---- ! @=$$@> = static_cast(0); }; *************** *** 571,575 **** parameter); ! @=$$@> = 0; }; --- 571,575 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 600,604 **** parameter); ! @=$$@> = 0; }; --- 600,604 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 630,634 **** parameter); ! @=$$@> = 0; }; --- 630,634 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 663,667 **** parameter); ! @=$$@> = 0; }; --- 663,667 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 693,697 **** parameter); ! @=$$@> = 0; }; --- 693,697 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 724,728 **** parameter); ! @=$$@> = 0; }; --- 724,728 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 769,773 **** cerr_strm << ">> "; ! if (entry == 0 || entry->object == 0) { cerr_strm << "(unknown macro)"; --- 769,773 ---- cerr_strm << ">> "; ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << "(unknown macro)"; *************** *** 793,797 **** } /* |else| (|entry != 0 && entry->object != 0|) */ ! @=$$@> = 0; }; --- 793,797 ---- } /* |else| (|entry != 0 && entry->object != 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 826,830 **** parameter); ! @=$$@> = 0; }; --- 826,830 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 857,861 **** parameter); ! @=$$@> = 0; }; --- 857,861 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 881,885 **** parameter); ! @=$$@> = 0; }; --- 881,885 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 905,909 **** parameter); ! @=$$@> = 0; }; --- 905,909 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 944,948 **** parameter); ! @=$$@> = 0; }; --- 944,948 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 969,973 **** parameter); ! @=$$@> = 0; }; --- 969,973 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 993,997 **** parameter); ! @=$$@> = 0; }; --- 993,997 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1020,1024 **** parameter); ! @=$$@> = 0; }; --- 1020,1024 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1051,1055 **** parameter); ! @=$$@> = 0; }; --- 1051,1055 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1078,1082 **** parameter); ! @=$$@> = 0; }; --- 1078,1082 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1105,1109 **** parameter); ! @=$$@> = 0; }; --- 1105,1109 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1133,1137 **** parameter); ! @=$$@> = 0; }; --- 1133,1137 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1164,1168 **** parameter); ! @=$$@> = 0;}; @q **** (4) command --> SHOW cone_expression@> --- 1164,1168 ---- parameter); ! @=$$@> = static_cast(0);}; @q **** (4) command --> SHOW cone_expression@> *************** *** 1190,1194 **** parameter); ! @=$$@> = 0; }; --- 1190,1194 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1218,1222 **** parameter); ! @=$$@> = 0; }; --- 1218,1222 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1250,1254 **** parameter); ! @=$$@> = 0; }; --- 1250,1254 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1280,1284 **** parameter); ! @=$$@> = 0; }; --- 1280,1284 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1307,1311 **** parameter); ! @=$$@> = 0; }; --- 1307,1311 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1334,1338 **** parameter); ! @=$$@> = 0; }; --- 1334,1338 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1358,1362 **** parameter); ! @=$$@> = 0; }; --- 1358,1362 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1383,1387 **** parameter); ! @=$$@> = 0; }; --- 1383,1387 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1413,1417 **** parameter); ! @=$$@> = 0; }; --- 1413,1417 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1440,1444 **** parameter); ! @=$$@> = 0; }; --- 1440,1444 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1467,1471 **** parameter); ! @=$$@> = 0; }; --- 1467,1471 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1570,1574 **** } /* |else| (|!nv|) */ ! @=$$@> = 0; }; --- 1570,1574 ---- } /* |else| (|!nv|) */ ! @=$$@> = static_cast(0); }; *************** *** 1649,1653 **** } /* |else| (|!nv|) */ ! @=$$@> = 0; }; --- 1649,1653 ---- } /* |else| (|!nv|) */ ! @=$$@> = static_cast(0); }; *************** *** 1711,1715 **** } /* |else| (|!nv|) */ ! @=$$@> = 0; }; --- 1711,1715 ---- } /* |else| (|!nv|) */ ! @=$$@> = static_cast(0); }; *************** *** 1739,1743 **** parameter); ! @=$$@> = 0; }; --- 1739,1743 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1767,1771 **** parameter); ! @=$$@> = 0; }; --- 1767,1771 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 1857,1861 **** } /* |else| (|!sv || sv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 1857,1861 ---- } /* |else| (|!sv || sv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 1925,1929 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 1925,1929 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 1994,1998 **** } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 1994,1998 ---- } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 2067,2071 **** } /* |else| (|!cv|) */ ! @=$$@> = 0; }; --- 2067,2071 ---- } /* |else| (|!cv|) */ ! @=$$@> = static_cast(0); }; *************** *** 2136,2140 **** } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 2136,2140 ---- } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 2204,2208 **** } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 2204,2208 ---- } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 2247,2251 **** cerr_strm << ">> "; ! if (entry == 0 || entry->object == 0) { cerr_strm << "(unknown picture_vector)"; --- 2247,2251 ---- cerr_strm << ">> "; ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << "(unknown picture_vector)"; *************** *** 2272,2276 **** ! @=$$@> = 0; }; --- 2272,2276 ---- ! @=$$@> = static_cast(0); }; *************** *** 2316,2320 **** cerr_strm << ">> "; ! if (entry == 0 || entry->object == 0) { cerr_strm << "(unknown macro_vector)"; --- 2316,2320 ---- cerr_strm << ">> "; ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << "(unknown macro_vector)"; *************** *** 2341,2345 **** ! @=$$@> = 0; }; --- 2341,2345 ---- ! @=$$@> = static_cast(0); }; *************** *** 2408,2412 **** } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 2408,2412 ---- } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 2476,2480 **** } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 2476,2480 ---- } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 2544,2548 **** } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 2544,2548 ---- } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; *************** *** 2628,2632 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 2628,2632 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 2699,2703 **** } /* |else| (|!bpv|) */ ! @=$$@> = 0; }; --- 2699,2703 ---- } /* |else| (|!bpv|) */ ! @=$$@> = static_cast(0); }; *************** *** 2766,2770 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 2766,2770 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 2798,2802 **** parameter); ! @=$$@> = 0; }; --- 2798,2802 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 2827,2831 **** parameter); ! @=$$@> = 0; --- 2827,2831 ---- parameter); ! @=$$@> = static_cast(0); *************** *** 2856,2860 **** parameter); ! @=$$@> = 0; }; --- 2856,2860 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 2885,2889 **** parameter); ! @=$$@> = 0; }; --- 2885,2889 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 2912,2916 **** parameter); ! @=$$@> = 0; }; --- 2912,2916 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 2940,2944 **** parameter); ! @=$$@> = 0; }; --- 2940,2944 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 3009,3013 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 3009,3013 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 3077,3081 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 3077,3081 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 3142,3146 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 3142,3146 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 3211,3215 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 3211,3215 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 3281,3285 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 3281,3285 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 3348,3352 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 3348,3352 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 3415,3419 **** } /* |else| (|!pv|) */ ! @=$$@> = 0; }; --- 3415,3419 ---- } /* |else| (|!pv|) */ ! @=$$@> = static_cast(0); }; *************** *** 3441,3445 **** parameter); ! @=$$@> = 0; }; --- 3441,3445 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 3469,3473 **** parameter); ! @=$$@> = 0; }; --- 3469,3473 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 3496,3500 **** parameter); ! @=$$@> = 0; }; --- 3496,3500 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 3524,3528 **** parameter); ! @=$$@> = 0; }; --- 3524,3528 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 3551,3555 **** parameter); ! @=$$@> = 0; }; --- 3551,3555 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 3618,3622 **** } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = 0; }; --- 3618,3622 ---- } /* |else| (|!pv || pv->ctr <= 0|) */ ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/pspglb.web 3DLDF-2.0.3/src/pspglb.web *** 3DLDF-2.0.2/src/pspglb.web Thu Nov 7 13:38:22 2013 --- 3DLDF-2.0.3/src/pspglb.web Fri Dec 13 15:06:19 2013 *************** *** 5,9 **** @q This file is part of 3DLDF, a package for three-dimensional drawing. @> @q Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @> ! @q 2011, 2012, 2013 The Free Software Foundation @> @q GNU 3DLDF is free software; you can redistribute it and/or modify @> --- 5,9 ---- @q This file is part of 3DLDF, a package for three-dimensional drawing. @> @q Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @> ! @q 2011, 2012, 2013 The Free Software Foundation @> @q GNU 3DLDF is free software; you can redistribute it and/or modify @> *************** *** 173,178 **** @= ! #define LDF_REAL_FLOAT 0 ! #define LDF_REAL_DOUBLE 1 #if LDF_REAL_FLOAT --- 173,178 ---- @= ! #define LDF_REAL_FLOAT 1 ! #define LDF_REAL_DOUBLE 0 #if LDF_REAL_FLOAT *************** *** 436,440 **** #endif /* |HAVE_PTHREAD_H| */@; ! @q *** |Mutex_Type| functions. @> @ {\bf Mutex\_Type} functions. --- 436,440 ---- #endif /* |HAVE_PTHREAD_H| */@; ! @q *** (3) |Mutex_Type| functions. @> @ {\bf Mutex\_Type} functions. *************** *** 466,470 **** { cerr << "Entering `Mutex_Type' default constructor." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 466,470 ---- { cerr << "Entering `Mutex_Type' default constructor." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 487,491 **** cerr << "In `Io_Struct::Io_Struct(void)':" << endl << "`pthread_mutex_init' succeeded!" ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 487,491 ---- cerr << "In `Io_Struct::Io_Struct(void)':" << endl << "`pthread_mutex_init' succeeded!" ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 496,500 **** { cerr << "Exiting `Mutex_Type' default constructor." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 496,500 ---- { cerr << "Exiting `Mutex_Type' default constructor." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 1630,1634 **** if (DEBUG) cerr << "Entering `Thread_Info_Type' destructor." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 1630,1634 ---- if (DEBUG) cerr << "Entering `Thread_Info_Type' destructor." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 1641,1645 **** if (DEBUG) cerr << "Exiting `Thread_Info_Type' destructor." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 1641,1645 ---- if (DEBUG) cerr << "Exiting `Thread_Info_Type' destructor." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 1671,1680 **** if (DEBUG) cerr << "Entering `Thread_Info_Type::destroy_key_value'." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; Thread_Info_Type* t = static_cast(arg); ! if (t != 0) delete t; t = 0; --- 1671,1680 ---- if (DEBUG) cerr << "Entering `Thread_Info_Type::destroy_key_value'." ! << endl; #endif /* |DEBUG_COMPILE| */@; Thread_Info_Type* t = static_cast(arg); ! if (t != static_cast(0)) delete t; t = 0; *************** *** 1683,1687 **** if (DEBUG) cerr << "Exiting `Thread_Info_Type::destroy_key_value'." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 1683,1687 ---- if (DEBUG) cerr << "Exiting `Thread_Info_Type::destroy_key_value'." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 1754,1758 **** @= ! if (v == 0 && !create_if_none) { --- 1754,1758 ---- @= ! if (v == static_cast(0) && !create_if_none) { *************** *** 1780,1784 **** ! if (v != 0) { #if DEBUG_COMPILE --- 1780,1784 ---- ! if (v != static_cast(0)) { #if DEBUG_COMPILE *************** *** 2001,2005 **** #endif /* |DEBUG_COMPILE| */@; ! if (thread_info == 0) { string s = ""; --- 2001,2005 ---- #endif /* |DEBUG_COMPILE| */@; ! if (thread_info == static_cast(0)) { string s = ""; *************** *** 2046,2050 **** #endif /* |DEBUG_COMPILE| */@; ! if (thread_info == 0) { return 0; --- 2046,2050 ---- #endif /* |DEBUG_COMPILE| */@; ! if (thread_info == static_cast(0)) { return 0; *************** *** 2206,2209 **** --- 2206,2213 ---- \initials{LDF 2007.07.03.} Removed years previous to ``2007'' from the |string| |COPYRIGHT_3DLDF|. + + \initials{LDF 2013.12.12.} + Added |extern const float ZERO_REAL| it is initialized to |0.0F| or |0.0D|, depending + on the values of |LDF_REAL_FLOAT| and |LDF_REAL_DOUBLE|. \ENDLOG *************** *** 2213,2225 **** extern const bool ldf_real_float = 1; extern const bool ldf_real_double = 0; #elif LDF_REAL_DOUBLE extern const bool ldf_real_float = 0; extern const bool ldf_real_double = 1; #else /* Defaults. LDF 2003.12.17. */ extern const bool ldf_real_float = 1; extern const bool ldf_real_double = 0; #endif ! extern const string VERSION_3DLDF = "2.0"; extern const string COPYRIGHT_3DLDF = "Copyright (C) 2013 The Free Software Foundation"; --- 2217,2232 ---- extern const bool ldf_real_float = 1; extern const bool ldf_real_double = 0; + extern const float ZERO_REAL = 0.0F; #elif LDF_REAL_DOUBLE extern const bool ldf_real_float = 0; extern const bool ldf_real_double = 1; + extern const double ZERO_REAL = 0.0D; #else /* Defaults. LDF 2003.12.17. */ extern const bool ldf_real_float = 1; extern const bool ldf_real_double = 0; + extern const float ZERO_REAL = 0.0F; #endif ! extern const string VERSION_3DLDF = "2.0.3"; extern const string COPYRIGHT_3DLDF = "Copyright (C) 2013 The Free Software Foundation"; *************** *** 2227,2233 **** = "GNU 3DLDF comes with ABSOLUTELY NO WARRANTY;\n\ for details see the file COPYING,\n\ ! which you should have received\n\ ! in the distribution of GNU 3DLDF 2.0.\n\ ! This is Free Software, and you are welcome\n\ to redistribute it under certain conditions;\n\ for details, again, see the file COPYING.\n\n\ --- 2234,2240 ---- = "GNU 3DLDF comes with ABSOLUTELY NO WARRANTY;\n\ for details see the file COPYING,\n\ ! which you should have received \ ! in the distribution of GNU 3DLDF 2.0.3\n\ ! This is Free Software, and you are welcome \ to redistribute it under certain conditions;\n\ for details, again, see the file COPYING.\n\n\ *************** *** 2247,2250 **** --- 2254,2258 ---- extern const bool ldf_real_float; extern const bool ldf_real_double; + extern const float ZERO_REAL; @ @:!! TO DO@> TO DO: Find out why the library *************** *** 2412,2416 **** << "`cerr_mutex.lock' failed." << endl << "Exiting with return value " << status ! << "." << endl << flush; return status; } --- 2420,2424 ---- << "`cerr_mutex.lock' failed." << endl << "Exiting with return value " << status ! << "." << endl; return status; } *************** *** 2425,2429 **** if(get_char) { ! cerr << "Type to continue.\n" << flush; getchar(); /* Don't delete this! */ } --- 2433,2437 ---- if(get_char) { ! cerr << "Type to continue.\n"; getchar(); /* Don't delete this! */ } *************** *** 2437,2441 **** << "`cerr_mutex.unlock' failed." << endl << "Exiting with return value " ! << status << "." << endl << flush; return status; } --- 2445,2449 ---- << "`cerr_mutex.unlock' failed." << endl << "Exiting with return value " ! << status << "." << endl; return status; } *************** *** 2508,2513 **** return Real_Pair(INVALID_REAL, INVALID_REAL); ! p.first = (a == 0) ? INVALID_REAL : q/a; ! p.second = (q == 0) ? INVALID_REAL : c/q; return p; --- 2516,2521 ---- return Real_Pair(INVALID_REAL, INVALID_REAL); ! p.first = (a == ZERO_REAL) ? INVALID_REAL : q/a; ! p.second = (q == ZERO_REAL) ? INVALID_REAL : c/q; return p; *************** *** 2786,2792 **** Run_State::show(void) { ! cout << "multithread_input == " << multithread_input << endl << flush; ! cout << "multithread_output == " << multithread_output << endl << flush; ! cout << "multithread_include == " << multithread_include << endl << flush; return; } --- 2794,2800 ---- Run_State::show(void) { ! cout << "multithread_input == " << multithread_input << endl; ! cout << "multithread_output == " << multithread_output << endl; ! cout << "multithread_include == " << multithread_include << endl; return; } *************** *** 2954,2959 **** { if (verbose) ! cout << "Processor is little-endian." << endl << endl ! << flush; return 0; } --- 2962,2967 ---- { if (verbose) ! cout << "Processor is little-endian." << endl << endl; ! return 0; } *************** *** 2961,2966 **** { if (verbose) ! cout << "Processor is big-endian." << endl << endl ! << flush; return 1; } --- 2969,2974 ---- { if (verbose) ! cout << "Processor is big-endian." << endl << endl; ! return 1; } *************** *** 2969,2973 **** cerr << "ERROR! In System::get_endianness:\n" << "Can't determine endianness. Returning -1" ! << endl << endl << flush; return -1; } --- 2977,2981 ---- cerr << "ERROR! In System::get_endianness:\n" << "Can't determine endianness. Returning -1" ! << endl << endl; return -1; } *************** *** 5202,5205 **** --- 5210,5214 ---- #define LDF_PSPGLB_H_KNOWN @@; + typedef void* yyscan_t; @@; @@; diff -rc2P 3DLDF-2.0.2/src/psphexpr.w 3DLDF-2.0.3/src/psphexpr.w *** 3DLDF-2.0.2/src/psphexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/psphexpr.w Fri Dec 13 12:51:31 2013 *************** *** 90,94 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 90,94 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 157,166 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 157,166 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 177,181 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 177,181 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pspvexpr.w 3DLDF-2.0.3/src/pspvexpr.w *** 3DLDF-2.0.2/src/pspvexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/pspvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pstrexpr.w 3DLDF-2.0.3/src/pstrexpr.w *** 3DLDF-2.0.2/src/pstrexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/pstrexpr.w Fri Dec 13 15:06:19 2013 *************** *** 110,114 **** entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 110,114 ---- entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 146,150 **** @=$$@> = Scan_Parse::string_primary_rule_func(@=$1@>, parameter); else ! @=$$@> = 0; }; --- 146,150 ---- @=$$@> = Scan_Parse::string_primary_rule_func(@=$1@>, parameter); else ! @=$$@> = static_cast(0); }; *************** *** 249,253 **** @= ! if (pv == 0) { cerr_strm << thread_name --- 249,253 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 266,270 **** delete s; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 266,270 ---- delete s; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 294,298 **** delete s; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 294,298 ---- delete s; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 797,801 **** @= ! if (s == 0 || t == 0) { --- 797,801 ---- @= ! if (s == static_cast(0) || t == static_cast(0)) { diff -rc2P 3DLDF-2.0.2/src/pstvexpr.w 3DLDF-2.0.3/src/pstvexpr.w *** 3DLDF-2.0.2/src/pstvexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/pstvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/ptfvexpr.w 3DLDF-2.0.3/src/ptfvexpr.w *** 3DLDF-2.0.2/src/ptfvexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ptfvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 101,108 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 101,108 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/ptglexpr.w 3DLDF-2.0.3/src/ptglexpr.w *** 3DLDF-2.0.2/src/ptglexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ptglexpr.w Fri Dec 13 12:51:31 2013 *************** *** 88,92 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 88,92 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 155,164 **** @= ! if (pv == 0) { delete r; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 155,164 ---- @= ! if (pv == static_cast*>(0)) { delete r; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 175,179 **** delete r; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 175,179 ---- delete r; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/ptgvexpr.w 3DLDF-2.0.3/src/ptgvexpr.w *** 3DLDF-2.0.2/src/ptgvexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ptgvexpr.w Fri Dec 13 11:59:34 2013 *************** *** 116,120 **** @= ! if (entry == 0 || entry->object == 0) { --- 116,120 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 133,137 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 133,137 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 307,311 **** { ! @=$$@> = 0; } /* |if (status != 0)| */ --- 307,311 ---- { ! @=$$@> = static_cast(0); } /* |if (status != 0)| */ diff -rc2P 3DLDF-2.0.2/src/ptokdecl.w 3DLDF-2.0.3/src/ptokdecl.w *** 3DLDF-2.0.2/src/ptokdecl.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ptokdecl.w Wed Dec 11 18:52:33 2013 *************** *** 645,650 **** if (DEBUG) { ! cerr << "$2 == " << @=$2@> << endl << flush; ! cerr << "$$ == " << @=$$@> << endl << flush; } #endif /* |DEBUG_COMPILE| */ --- 645,650 ---- if (DEBUG) { ! cerr << "$2 == " << @=$2@> << endl; ! cerr << "$$ == " << @=$$@> << endl; } #endif /* |DEBUG_COMPILE| */ *************** *** 688,694 **** if (DEBUG) { ! cerr << "$2 == " << @=$2@> << endl << flush; ! cerr << "$3 == " << @=$3@> << endl << flush; ! cerr << "$$ == " << @=$$@> << endl << flush; } #endif /* |DEBUG_COMPILE| */ --- 688,694 ---- if (DEBUG) { ! cerr << "$2 == " << @=$2@> << endl; ! cerr << "$3 == " << @=$3@> << endl; ! cerr << "$$ == " << @=$$@> << endl; } #endif /* |DEBUG_COMPILE| */ diff -rc2P 3DLDF-2.0.2/src/ptrfcmnd.w 3DLDF-2.0.3/src/ptrfcmnd.w *** 3DLDF-2.0.2/src/ptrfcmnd.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ptrfcmnd.w Fri Dec 13 15:06:19 2013 *************** *** 81,85 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; --- 81,85 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); *************** *** 106,110 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; --- 106,110 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); *************** *** 134,138 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 134,138 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 158,162 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 158,162 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 184,188 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 184,188 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 208,212 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 208,212 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 232,236 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 232,236 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 256,260 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 256,260 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 280,284 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 280,284 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 306,310 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 306,310 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 330,334 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 330,334 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 354,358 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 354,358 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 381,385 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 381,385 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 405,409 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 405,409 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 431,435 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 431,435 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 457,461 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 457,461 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 481,485 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 481,485 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 505,509 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 505,509 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 538,542 **** pv); ! @=$$@> = 0; }; --- 538,542 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 571,575 **** pv); ! @=$$@> = 0; }; --- 571,575 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 604,608 **** pv); ! @=$$@> = 0; }; --- 604,608 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 637,641 **** pv); ! @=$$@> = 0; }; --- 637,641 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 670,674 **** pv); ! @=$$@> = 0; }; --- 670,674 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 703,707 **** pv); ! @=$$@> = 0; }; --- 703,707 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 736,740 **** pv); ! @=$$@> = 0; }; --- 736,740 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 769,773 **** pv); ! @=$$@> = 0; }; --- 769,773 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 802,806 **** pv); ! @=$$@> = 0; }; --- 802,806 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 835,839 **** pv); ! @=$$@> = 0; }; --- 835,839 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 868,872 **** pv); ! @=$$@> = 0; }; --- 868,872 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 901,905 **** pv); ! @=$$@> = 0; }; --- 901,905 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 934,938 **** pv); ! @=$$@> = 0; }; --- 934,938 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 967,971 **** pv); ! @=$$@> = 0; }; --- 967,971 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 1000,1004 **** pv); ! @=$$@> = 0; }; --- 1000,1004 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 1055,1059 **** pv); ! @=$$@> = 0; }; --- 1055,1059 ---- pv); ! @=$$@> = static_cast(0); }; *************** *** 1080,1086 **** Point* p = static_cast(@=$4@>); ! if (p == 0 || *p == INVALID_POINT) { ! @=$$@> = 0; } else --- 1080,1086 ---- Point* p = static_cast(@=$4@>); ! if (p == static_cast(0) || *p == INVALID_POINT) { ! @=$$@> = static_cast(0); } else *************** *** 1100,1104 **** delete p; ! @=$$@> = 0; }; --- 1100,1104 ---- delete p; ! @=$$@> = static_cast(0); }; *************** *** 1137,1141 **** static_cast*>(@=$3@>)); ! @=$$@> = 0; }; --- 1137,1141 ---- static_cast*>(@=$3@>)); ! @=$$@> = static_cast(0); }; *************** *** 1285,1289 **** @= ! if (entry == 0 || entry->object == 0) { --- 1285,1289 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 1306,1310 **** cerr_strm.str(""); ! @=$$@> = 0; --- 1306,1310 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); *************** *** 1337,1341 **** @= ! if (t == 0) { --- 1337,1341 ---- @= ! if (t == static_cast(0)) { *************** *** 1358,1362 **** cerr_strm.str(""); ! @=$$@> = 0; } /* |if (t == 0)| */ --- 1358,1362 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); } /* |if (t == 0)| */ *************** *** 1398,1402 **** delete t; ! @=$$@> = 0; } /* |else| (|t != 0|) */ --- 1398,1402 ---- delete t; ! @=$$@> = static_cast(0); } /* |else| (|t != 0|) */ *************** *** 1431,1435 **** } ! @=$$@> = 0; }; --- 1431,1435 ---- } ! @=$$@> = static_cast(0); }; *************** *** 1457,1461 **** } ! @=$$@> = 0; }; --- 1457,1461 ---- } ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/ptrnexpr.w 3DLDF-2.0.3/src/ptrnexpr.w *** 3DLDF-2.0.2/src/ptrnexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/ptrnexpr.w Fri Dec 13 15:06:19 2013 *************** *** 94,98 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 94,98 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 163,171 **** @= ! if (pv == 0) { delete p; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 163,171 ---- @= ! if (pv == static_cast*>(0)) { delete p; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 183,187 **** delete p; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 183,187 ---- delete p; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ *************** *** 250,254 **** } else ! @=$$@> = 0; }; --- 250,254 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 284,288 **** } else ! @=$$@> = 0; }; --- 284,288 ---- } else ! @=$$@> = static_cast(0); }; *************** *** 719,723 **** @= ! if (entry == 0 || entry->object == 0) { --- 719,723 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 828,832 **** @= ! if (q == 0 || *q == INVALID_POINT) { --- 828,832 ---- @= ! if (q == static_cast(0) || *q == INVALID_POINT) { *************** *** 1110,1114 **** @= ! if (t == 0) { --- 1110,1114 ---- @= ! if (t == static_cast(0)) { *************** *** 1183,1187 **** @= ! if (t == 0) { --- 1183,1187 ---- @= ! if (t == static_cast(0)) { diff -rc2P 3DLDF-2.0.2/src/pullexpr.w 3DLDF-2.0.3/src/pullexpr.w *** 3DLDF-2.0.2/src/pullexpr.w Thu Nov 7 13:36:03 2013 --- 3DLDF-2.0.3/src/pullexpr.w Fri Dec 13 11:59:34 2013 *************** *** 88,95 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 88,95 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = 0ULL; } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pullvxpr.w 3DLDF-2.0.3/src/pullvxpr.w *** 3DLDF-2.0.2/src/pullvxpr.w Thu Nov 7 13:36:02 2013 --- 3DLDF-2.0.3/src/pullvxpr.w Fri Dec 13 11:59:33 2013 *************** *** 90,97 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 90,97 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/pvariabl.w 3DLDF-2.0.3/src/pvariabl.w *** 3DLDF-2.0.2/src/pvariabl.w Thu Nov 7 13:36:02 2013 --- 3DLDF-2.0.3/src/pvariabl.w Fri Dec 13 15:06:19 2013 *************** *** 3117,3121 **** @= ! if (entry == 0 || entry->object == 0) { cerr_strm << thread_name --- 3117,3121 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 3133,3137 **** ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 3133,3137 ---- ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 3162,3166 **** cerr_strm.str(""); ! @=$$@> = 0; --- 3162,3166 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); *************** *** 3184,3188 **** @q ******** (8) @> ! if (array_entry == 0) { cerr_strm << thread_name --- 3184,3188 ---- @q ******** (8) @> ! if (array_entry == static_cast(0)) { cerr_strm << thread_name *************** *** 3201,3205 **** cerr_strm.str(""); ! @=$$@> = 0; --- 3201,3205 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); *************** *** 3360,3364 **** @= ! if (entry == 0 || entry->object == 0) { cerr_strm << thread_name --- 3360,3364 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 3376,3380 **** ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 3376,3380 ---- ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ *************** *** 3405,3409 **** cerr_strm.str(""); ! @=$$@> = 0; --- 3405,3409 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); *************** *** 3427,3431 **** @q ******** (8) @> ! if (array_entry == 0) { cerr_strm << thread_name --- 3427,3431 ---- @q ******** (8) @> ! if (array_entry == static_cast(0)) { cerr_strm << thread_name *************** *** 3444,3448 **** cerr_strm.str(""); ! @=$$@> = 0; --- 3444,3448 ---- cerr_strm.str(""); ! @=$$@> = static_cast(0); diff -rc2P 3DLDF-2.0.2/src/pvcmncmd.w 3DLDF-2.0.3/src/pvcmncmd.w *** 3DLDF-2.0.2/src/pvcmncmd.w Thu Nov 7 13:36:02 2013 --- 3DLDF-2.0.3/src/pvcmncmd.w Fri Dec 13 15:06:19 2013 *************** *** 108,112 **** } /* |if (status != 0)| */ ! @=$$@> = 0; }; --- 108,112 ---- } /* |if (status != 0)| */ ! @=$$@> = static_cast(0); }; *************** *** 150,154 **** @=$3@>); ! @=$$@> = 0; }; --- 150,154 ---- @=$3@>); ! @=$$@> = static_cast(0); }; *************** *** 195,199 **** static_cast(0)); ! @=$$@> = 0; }; --- 195,199 ---- static_cast(0)); ! @=$$@> = static_cast(0); }; *************** *** 234,238 **** @q ***** (5)@> ! if (entry == 0) { #if 0 --- 234,238 ---- @q ***** (5)@> ! if (entry == static_cast(0)) { #if 0 *************** *** 258,262 **** @q ****** (6)@> ! if (entry->object == 0) { --- 258,262 ---- @q ****** (6)@> ! if (entry->object == static_cast(0)) { *************** *** 283,287 **** @q ******* (7)@> ! if (root == 0) { #if 0 --- 283,287 ---- @q ******* (7)@> ! if (root == static_cast(0)) { #if 0 *************** *** 313,317 **** @q ******** (8)@> ! if (temp_entry == 0) { #if 0 --- 313,317 ---- @q ******** (8)@> ! if (temp_entry == static_cast(0)) { #if 0 *************** *** 341,345 **** @q ********* (9).@> ! if (temp_entry->object == 0) { Picture* p; --- 341,345 ---- @q ********* (9).@> ! if (temp_entry->object == static_cast(0)) { Picture* p; *************** *** 382,386 **** @q ***** (5)@> ! @=$$@> = 0; }; --- 382,386 ---- @q ***** (5)@> ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/rectangs.web 3DLDF-2.0.3/src/rectangs.web *** 3DLDF-2.0.2/src/rectangs.web Thu Nov 7 13:38:22 2013 --- 3DLDF-2.0.3/src/rectangs.web Fri Dec 13 15:06:19 2013 *************** *** 237,243 **** ! if (angle_x != 0 || angle_y != 0 ! || angle_z != 0) /* Rotation around the x-axis, ! y-axis, and z-axis. */ { bot_lft.rotate(angle_x, angle_y, angle_z); --- 237,243 ---- ! if (angle_x != ZERO_REAL || angle_y != ZERO_REAL ! || angle_z != ZERO_REAL) /* Rotation around the x-axis, ! y-axis, and z-axis. */ { bot_lft.rotate(angle_x, angle_y, angle_z); *************** *** 589,593 **** @= ! if (rectangle_reflection == 0) { try --- 589,593 ---- @= ! if (rectangle_reflection == static_cast(0)) { try *************** *** 831,835 **** { cerr << "ERROR: Rectangles have 4 corners, " ! << "numbered 0 through 3.\nReturning INVALID_POINT.\n" << flush; return INVALID_POINT; --- 831,835 ---- { cerr << "ERROR: Rectangles have 4 corners, " ! << "numbered 0 through 3.\nReturning INVALID_POINT.\n"; return INVALID_POINT; *************** *** 871,876 **** { cerr << "ERROR: Rectangles have 4 mid_points, " ! << "numbered 0 through 3.\nReturning INVALID_POINT.\n" ! << flush; return INVALID_POINT; } --- 871,876 ---- { cerr << "ERROR: Rectangles have 4 mid_points, " ! << "numbered 0 through 3.\nReturning INVALID_POINT.\n"; ! return INVALID_POINT; } diff -rc2P 3DLDF-2.0.2/src/rhtchdrn.web 3DLDF-2.0.3/src/rhtchdrn.web *** 3DLDF-2.0.2/src/rhtchdrn.web Sun Nov 10 16:08:24 2013 --- 3DLDF-2.0.3/src/rhtchdrn.web Mon Nov 11 18:43:05 2013 *************** *** 404,408 **** p[2].rotate(p[1], p[3]); ! rhombus->set("--", true, &p[0], &p[1], &p[2], &p[3], 0); return rhombus; --- 404,408 ---- p[2].rotate(p[1], p[3]); ! rhombus->set("--", true, &p[0], &p[1], &p[2], &p[3], static_cast(0)); return rhombus; *************** *** 592,596 **** p[2].rotate(p[1], p[3]); ! rhombus[0].set("--", true, &p[0], &p[1], &p[2], &p[3], 0); *pv += create_new(rhombus[0]); --- 592,596 ---- p[2].rotate(p[1], p[3]); ! rhombus[0].set("--", true, &p[0], &p[1], &p[2], &p[3], static_cast(0)); *pv += create_new(rhombus[0]); *************** *** 850,854 **** p[9].rotate(p[8], p[5], -angle); ! tab.set("--", true, &p[4], &p[7], &p[9], &p[5], 0); *tv += create_new(tab); --- 850,854 ---- p[9].rotate(p[8], p[5], -angle); ! tab.set("--", true, &p[4], &p[7], &p[9], &p[5], static_cast(0)); *tv += create_new(tab); diff -rc2P 3DLDF-2.0.2/src/scan.web 3DLDF-2.0.3/src/scan.web *** 3DLDF-2.0.2/src/scan.web Sun Aug 11 17:38:23 2013 --- 3DLDF-2.0.3/src/scan.web Fri Dec 13 15:40:52 2013 *************** *** 166,171 **** \initials{LDF 2004.04.08.} - \functexi{int yylex(YYSTYPE* value, YYLTYPE* location, void* parameter)} - \LOG \initials{LDF 2004.04.08.} --- 166,169 ---- *************** *** 218,222 **** int yylex(YYSTYPE* value, - YYLTYPE* location, void* parameter) { --- 216,219 ---- *************** *** 268,272 **** @= ! if (scanner_node == 0) { --- 265,269 ---- @= ! if (scanner_node == static_cast(0)) { *************** *** 387,391 **** << endl; ! if (rescan_value == 0) cerr_strm << "`rescan_value' == 0" << endl; else --- 384,388 ---- << endl; ! if (rescan_value == static_cast(0)) cerr_strm << "`rescan_value' == 0" << endl; else *************** *** 412,416 **** @= ! if (rescan_value != 0 || !rescan_retest) { --- 409,413 ---- @= ! if (rescan_value != static_cast(0) || !rescan_retest) { *************** *** 526,530 **** curr_catcode = sub_yylex(value, - location, scanner_node); --- 523,526 ---- *************** *** 548,552 **** prev_catcode = curr_catcode; curr_catcode = sub_yylex(value, - location, scanner_node); --- 544,547 ---- *************** *** 564,568 **** prev_catcode = curr_catcode; curr_catcode = sub_yylex(value, - location, scanner_node); --- 559,562 ---- *************** *** 593,597 **** prev_catcode = curr_catcode; curr_catcode = sub_yylex(value, - location, scanner_node); --- 587,590 ---- *************** *** 890,894 **** @= ! if (entry == 0) { #if DEBUG_COMPILE --- 883,887 ---- @= ! if (entry == static_cast(0)) { #if DEBUG_COMPILE *************** *** 933,937 **** cerr << value->string_value << " is a spark. Will return " << name_map[entry->get_type()] ! << endl << flush; } --- 926,930 ---- cerr << value->string_value << " is a spark. Will return " << name_map[entry->get_type()] ! << endl; } *************** *** 1085,1089 **** int sub_yylex(YYSTYPE *value, - YYLTYPE *location, Scanner_Node scanner_node); --- 1078,1081 ---- *************** *** 1095,1099 **** int sub_yylex(YYSTYPE *value, - YYLTYPE *location, Scanner_Node scanner_node) { --- 1087,1090 ---- *************** *** 1144,1148 **** @= ! if (scanner_node == 0) { --- 1135,1139 ---- @= ! if (scanner_node == static_cast(0)) { *************** *** 1240,1243 **** --- 1231,1235 ---- loop_start: + #if 0 curr_position = location->position; start_line = location->last_line; *************** *** 1245,1249 **** start_column = location->last_column; curr_column = start_column; ! for (bool first_time = true;;) --- 1237,1247 ---- start_column = location->last_column; curr_column = start_column; ! #else ! curr_position = 0; ! start_line = 0; ! curr_line = start_line; ! start_column = 0; ! curr_column = start_column; ! #endif for (bool first_time = true;;) *************** *** 1420,1423 **** --- 1418,1422 ---- ++curr_column; + #if 0 location->first_line = start_line; location->first_column = start_column; *************** *** 1425,1428 **** --- 1424,1428 ---- location->last_column = curr_column; location->position = curr_position; + #endif *************** *** 2015,2018 **** --- 2015,2019 ---- #endif /* |DEBUG_COMPILE| */@; + #if 0 location->first_line = start_line; location->first_column = start_column; *************** *** 2020,2023 **** --- 2021,2025 ---- location->last_column = curr_column; location->position = curr_position; + #endif goto loop_start; *************** *** 2222,2225 **** --- 2224,2228 ---- cerr_strm.str(); + #if 0 location->first_line = start_line; location->first_column = start_column; *************** *** 2227,2230 **** --- 2230,2234 ---- location->last_column = curr_column; location->position = curr_position; + #endif scanner_node->set_token_string(curr_token_string); *************** *** 2256,2259 **** --- 2260,2264 ---- #endif /* |DEBUG_COMPILE| */@; + #if 0 location->first_line = start_line; location->first_column = start_column; *************** *** 2261,2264 **** --- 2266,2270 ---- location->last_column = curr_column; location->position = curr_position; + #endif if (scanner_node->get_in_type() == Io_Struct::STDIN_TYPE) *************** *** 2524,2527 **** --- 2530,2534 ---- #endif /* |DEBUG_COMPILE| */@; + #if 0 location->first_line = start_line; location->first_column = start_column; *************** *** 2529,2532 **** --- 2536,2540 ---- location->last_column = curr_column; location->position = curr_position; + #endif goto loop_start; *************** *** 2897,2900 **** --- 2905,2909 ---- @= + #if 0 location->first_line = start_line; location->first_column = start_column; *************** *** 2902,2905 **** --- 2911,2915 ---- location->last_column = curr_column; location->position = curr_position; + #endif #if DEBUG_COMPILE diff -rc2P 3DLDF-2.0.2/src/scanprse.web 3DLDF-2.0.3/src/scanprse.web *** 3DLDF-2.0.2/src/scanprse.web Thu Nov 7 13:38:22 2013 --- 3DLDF-2.0.3/src/scanprse.web Fri Dec 13 15:06:33 2013 *************** *** 351,355 **** Scan_Parse::Picture_Output_Arg_Type::~Picture_Output_Arg_Type(void) { ! if (picture != 0) { picture->clear(); --- 351,355 ---- Scan_Parse::Picture_Output_Arg_Type::~Picture_Output_Arg_Type(void) { ! if (picture != static_cast(0)) { picture->clear(); *************** *** 358,362 **** } ! if (focus != 0) { delete focus; --- 358,362 ---- } ! if (focus != static_cast(0)) { delete focus; *************** *** 1222,1226 **** @= ! if (*(scanner_node->default_pen) != 0) { *out_stream << "pickup " << **(scanner_node->default_pen); --- 1222,1226 ---- @= ! if (*(scanner_node->default_pen) != static_cast(0)) { *out_stream << "pickup " << **(scanner_node->default_pen); *************** *** 1463,1467 **** = static_cast(arg); ! if (picture_ptr_arg == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::output_func()':" --- 1463,1467 ---- = static_cast(arg); ! if (picture_ptr_arg == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::output_func()':" *************** *** 1585,1589 **** Output_Struct* out_stream = picture_ptr_arg->scanner_node->out[Run_State::METAPOST]; ! if (out_stream == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::output_func()':" --- 1585,1589 ---- Output_Struct* out_stream = picture_ptr_arg->scanner_node->out[Run_State::METAPOST]; ! if (out_stream == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::output_func()':" *************** *** 2296,2300 **** @= ! if (scanner_node->endfig_ptr != 0) { --- 2296,2300 ---- @= ! if (scanner_node->endfig_ptr != static_cast(0)) { *************** *** 2331,2335 **** ! if (entry == 0 || entry->object == 0) { --- 2331,2335 ---- ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 2473,2477 **** @= ! if (p == 0) { cerr_strm << "ERROR! " << thread_name --- 2473,2477 ---- @= ! if (p == static_cast(0)) { cerr_strm << "ERROR! " << thread_name *************** *** 2979,2983 **** Thread_Info_Type* thread_info; ! if (scanner_node == 0 /* Assume we're using threads. */ || (scanner_node->get_run_state()->multithread_input --- 2979,2983 ---- Thread_Info_Type* thread_info; ! if (scanner_node == static_cast(0) /* Assume we're using threads. */ || (scanner_node->get_run_state()->multithread_input *************** *** 3444,3448 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! In " --- 3444,3448 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! In " *************** *** 3503,3507 **** @= ! if (expr == 0) { cerr_strm << thread_name << "ERROR! In " --- 3503,3507 ---- @= ! if (expr == static_cast(0)) { cerr_strm << thread_name << "ERROR! In " *************** *** 3554,3558 **** if (use_or_delete_expr) { ! if (c == 0) c = expr; --- 3554,3558 ---- if (use_or_delete_expr) { ! if (c == static_cast(0)) c = expr; *************** *** 3586,3590 **** { ! if (c == 0) { --- 3586,3590 ---- { ! if (c == static_cast(0)) { *************** *** 3919,3923 **** @= ! if (entry == 0) { cerr_strm << thread_name << "ERROR! " --- 3919,3923 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 3946,3950 **** ! if (expr == 0) { cerr_strm << thread_name << "ERROR! " --- 3946,3950 ---- ! if (expr == static_cast(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 3981,3985 **** << " `entry->name' == " << entry->name << ". "; ! if (entry->object == 0) cerr_strm << "`entry->object' == 0. Allocating new object."; else --- 3981,3985 ---- << " `entry->name' == " << entry->name << ". "; ! if (entry->object == static_cast(0)) cerr_strm << "`entry->object' == 0. Allocating new object."; else *************** *** 4015,4019 **** @= ! if (entry->object == 0) { try --- 4015,4019 ---- @= ! if (entry->object == static_cast(0)) { try *************** *** 4212,4216 **** @= ! if (entry == 0) { cerr_strm << thread_name --- 4212,4216 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 4239,4243 **** @= ! if (entry_0 == 0) { cerr_strm << thread_name --- 4239,4243 ---- @= ! if (entry_0 == static_cast(0)) { cerr_strm << thread_name *************** *** 4332,4336 **** << endl << "entry->name == " << entry->name << "." << endl; ! if (entry->object == 0) cerr_strm << "entry->object == 0. Allocating new `picture'."; else --- 4332,4336 ---- << endl << "entry->name == " << entry->name << "." << endl; ! if (entry->object == static_cast(0)) cerr_strm << "entry->object == 0. Allocating new `picture'."; else *************** *** 4344,4348 **** ! if (entry->object == 0) entry->object = static_cast(new(Picture)); --- 4344,4348 ---- ! if (entry->object == static_cast(0)) entry->object = static_cast(new(Picture)); *************** *** 4777,4781 **** ! if (entry == 0) { cerr_strm << thread_name --- 4777,4781 ---- ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 4810,4814 **** << "entry->name == " << entry->name << endl; ! if (entry->object == 0) cerr_strm << "entry->object == 0. Creating new `Picture'."; else --- 4810,4814 ---- << "entry->name == " << entry->name << endl; ! if (entry->object == static_cast(0)) cerr_strm << "entry->object == 0. Creating new `Picture'."; else *************** *** 4824,4828 **** ! if (entry->object == 0) entry->object = static_cast(new(Picture)); --- 4824,4828 ---- ! if (entry->object == static_cast(0)) entry->object = static_cast(new(Picture)); *************** *** 4836,4840 **** @= ! if (t == 0) { --- 4836,4840 ---- @= ! if (t == static_cast(0)) { *************** *** 5326,5330 **** @= ! if (entry == 0) { --- 5326,5330 ---- @= ! if (entry == static_cast(0)) { *************** *** 5363,5367 **** << endl; ! if (entry->object == 0) cerr_strm << "entry->object == 0. Allocating new `Point'."; else --- 5363,5367 ---- << endl; ! if (entry->object == static_cast(0)) cerr_strm << "entry->object == 0. Allocating new `Point'."; else *************** *** 5375,5379 **** ! if (entry->object == 0) entry->object = static_cast(create_new(0)); --- 5375,5379 ---- ! if (entry->object == static_cast(0)) entry->object = static_cast(create_new(0)); *************** *** 5392,5396 **** Id_Map_Entry_Node z_entry = scanner_node->lookup("curr_z"); ! if (y_entry == 0) { cerr_strm << thread_name << "WARNING! In `assign_point_numeric()':" --- 5392,5396 ---- Id_Map_Entry_Node z_entry = scanner_node->lookup("curr_z"); ! if (y_entry == static_cast(0)) { cerr_strm << thread_name << "WARNING! In `assign_point_numeric()':" *************** *** 5416,5420 **** @= ! if (z_entry == 0) { --- 5416,5420 ---- @= ! if (z_entry == static_cast(0)) { *************** *** 5488,5492 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) { thread_info->log_stream << s.str(); --- 5488,5492 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) { thread_info->log_stream << s.str(); *************** *** 5575,5579 **** ! if (entry == 0) { cerr_strm << thread_name --- 5575,5579 ---- ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 5662,5666 **** Color* c; ! if (entry->object == 0) { c = create_new(0); --- 5662,5666 ---- Color* c; ! if (entry->object == static_cast(0)) { c = create_new(0); *************** *** 5833,5837 **** @= ! if (entry == 0) { cerr_strm << thread_name --- 5833,5837 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 5929,5933 **** << "entry->name == " << entry->name << endl; ! if (entry->object == 0) cerr_strm << "entry->object == 0. Allocating new `focus'."; else --- 5929,5933 ---- << "entry->name == " << entry->name << endl; ! if (entry->object == static_cast(0)) cerr_strm << "entry->object == 0. Allocating new `focus'."; else *************** *** 5942,5946 **** #endif /* |DEBUG_COMPILE| */@; ! if (entry->object == 0) entry->object = static_cast(create_new(0)); --- 5942,5946 ---- #endif /* |DEBUG_COMPILE| */@; ! if (entry->object == static_cast(0)) entry->object = static_cast(create_new(0)); *************** *** 6143,6147 **** @= ! if (entry == 0 || entry->object == 0) { --- 6143,6147 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 6659,6663 **** @= ! if (vector_entry != 0) { --- 6659,6663 ---- @= ! if (vector_entry != static_cast(0)) { *************** *** 6723,6727 **** @= ! if (array_entry != 0) { --- 6723,6727 ---- @= ! if (array_entry != static_cast(0)) { *************** *** 6856,6860 **** @= ! if (array_entry == 0) { cerr_strm << thread_name --- 6856,6860 ---- @= ! if (array_entry == static_cast(0)) { cerr_strm << thread_name *************** *** 6948,6952 **** @= ! if (vector_entry == 0) { --- 6948,6952 ---- @= ! if (vector_entry == static_cast(0)) { *************** *** 7405,7409 **** ! if (pv == 0) { try --- 7405,7409 ---- ! if (pv == static_cast(0)) { try *************** *** 7500,7504 **** @= ! if (array_entry == 0) { --- 7500,7504 ---- @= ! if (array_entry == static_cast(0)) { *************** *** 7558,7562 **** @= ! if (c_entry == 0) { cerr_strm << thread_name --- 7558,7562 ---- @= ! if (c_entry == static_cast(0)) { cerr_strm << thread_name *************** *** 7791,7795 **** @= ! if (entry == 0) { cerr_strm << thread_name --- 7791,7795 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 7818,7822 **** @= ! if (object_vector == 0) { cerr_strm << thread_name --- 7818,7822 ---- @= ! if (object_vector == static_cast*>(0)) { cerr_strm << thread_name *************** *** 7856,7860 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { delete pv; --- 7856,7860 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { delete pv; *************** *** 7870,7874 **** ! if (pv == 0) { try --- 7870,7874 ---- ! if (pv == static_cast(0)) { try *************** *** 7967,7971 **** @= ! if (array_entry == 0) { --- 7967,7971 ---- @= ! if (array_entry == static_cast(0)) { *************** *** 8025,8029 **** @= ! if (c_entry == 0) { cerr_strm << thread_name --- 8025,8029 ---- @= ! if (c_entry == static_cast(0)) { cerr_strm << thread_name *************** *** 8173,8177 **** @q ***** (5)@> ! if (v == 0) { cerr_strm << thread_name --- 8173,8177 ---- @q ***** (5)@> ! if (v == static_cast(0)) { cerr_strm << thread_name *************** *** 8197,8201 **** Id_Map_Entry_Node entry = static_cast(v); ! if (entry->object == 0) { cerr_strm << thread_name --- 8197,8201 ---- Id_Map_Entry_Node entry = static_cast(v); ! if (entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 8367,8371 **** @= ! if (v == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::rectify_func':" --- 8367,8371 ---- @= ! if (v == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::rectify_func':" *************** *** 8397,8401 **** @= ! if (entry->object == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::rectify_func':" --- 8397,8401 ---- @= ! if (entry->object == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::rectify_func':" *************** *** 8625,8629 **** Id_Map_Entry_Node entry = static_cast(v); ! if (entry == 0 || entry->object == 0) return 1; --- 8625,8629 ---- Id_Map_Entry_Node entry = static_cast(v); ! if (entry == static_cast(0) || entry->object == static_cast(0)) return 1; *************** *** 8887,8891 **** @= ! if (object == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::reflect_in_func()': " --- 8887,8891 ---- @= ! if (object == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::reflect_in_func()': " *************** *** 8938,8942 **** @= ! if (plane_path == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::reflect_in_func()': " --- 8938,8942 ---- @= ! if (plane_path == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::reflect_in_func()': " *************** *** 9120,9124 **** @= ! if (reflection == 0) { --- 9120,9124 ---- @= ! if (reflection == static_cast(0)) { *************** *** 9346,9350 **** @= ! if (object == 0) { cerr_strm << thread_name --- 9346,9350 ---- @= ! if (object == static_cast(0)) { cerr_strm << thread_name *************** *** 9402,9406 **** @= ! if (pv == 0) { cerr_strm << thread_name --- 9402,9406 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 9441,9445 **** @= ! if (plane_path == 0) { cerr_strm << thread_name --- 9441,9445 ---- @= ! if (plane_path == static_cast(0)) { cerr_strm << thread_name *************** *** 9480,9484 **** @= ! if (direction == 0) { cerr_strm << thread_name --- 9480,9484 ---- @= ! if (direction == static_cast(0)) { cerr_strm << thread_name *************** *** 9636,9640 **** ! if (pv == 0) cerr_strm << "`pv' == 0." << endl; else --- 9636,9640 ---- ! if (pv == static_cast*>(0)) cerr_strm << "`pv' == 0." << endl; else *************** *** 9645,9649 **** cerr_strm.str(""); ! if (pv != 0) pv->show("pv in `Scan_Parse::reflect_off_func()':"); --- 9645,9649 ---- cerr_strm.str(""); ! if (pv != static_cast*>(0)) pv->show("pv in `Scan_Parse::reflect_off_func()':"); *************** *** 9757,9761 **** @= ! if (expression == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::pickup_command()':" --- 9757,9761 ---- @= ! if (expression == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::pickup_command()':" *************** *** 9793,9797 **** @= ! if (q == 0) { try --- 9793,9797 ---- @= ! if (q == static_cast(0)) { try *************** *** 9911,9915 **** @= ! if (*pointer == 0) { --- 9911,9915 ---- @= ! if (*pointer == static_cast(0)) { *************** *** 10441,10445 **** @= ! if (c == 0) { --- 10441,10445 ---- @= ! if (c == static_cast(0)) { *************** *** 10682,10686 **** @= ! if (c == 0) { --- 10682,10686 ---- @= ! if (c == static_cast(0)) { *************** *** 11017,11021 **** Scan_Parse::standardize_func(C* c, void* v) { ! if (c == 0) return 0; --- 11017,11021 ---- Scan_Parse::standardize_func(C* c, void* v) { ! if (c == static_cast(0)) return 0; *************** *** 11481,11485 **** @= ! if (conic_section_lattice == 0 || c == 0) { delete conic_section_lattice; --- 11481,11486 ---- @= ! if ( conic_section_lattice == static_cast(0) ! || c == static_cast(0)) { delete conic_section_lattice; *************** *** 11675,11679 **** Scan_Parse::plane_cast_func(C* c, void* parameter) { ! if (c == 0) return 0; else if (!c->is_planar()) --- 11676,11680 ---- Scan_Parse::plane_cast_func(C* c, void* parameter) { ! if (c == static_cast(0)) return 0; else if (!c->is_planar()) *************** *** 11744,11748 **** Scan_Parse::plane_assignment_func(void* entry, C* c, void* parameter) { ! if (c == 0) return 0; --- 11745,11749 ---- Scan_Parse::plane_assignment_func(void* entry, C* c, void* parameter) { ! if (c == static_cast(0)) return 0; *************** *** 12322,12326 **** { ! if (c == 0) return 0; --- 12323,12327 ---- { ! if (c == static_cast(0)) return 0; *************** *** 12372,12376 **** Scan_Parse::out_cuboid_func(C* c, void* parameter) { ! if (c == 0) return 0; --- 12373,12377 ---- Scan_Parse::out_cuboid_func(C* c, void* parameter) { ! if (c == static_cast(0)) return 0; diff -rc2P 3DLDF-2.0.2/src/scanprsf.web 3DLDF-2.0.3/src/scanprsf.web *** 3DLDF-2.0.2/src/scanprsf.web Thu Nov 7 13:40:08 2013 --- 3DLDF-2.0.3/src/scanprsf.web Fri Dec 13 15:38:06 2013 *************** *** 193,197 **** Thread_Info_Type* thread_info; ! if (scanner_node == 0 /* Assume we're using threads. */ || (scanner_node->get_run_state()->multithread_input --- 193,197 ---- Thread_Info_Type* thread_info; ! if (scanner_node == static_cast(0) /* Assume we're using threads. */ || (scanner_node->get_run_state()->multithread_input *************** *** 250,254 **** if (DEBUG) { ! if (entry == 0) { cerr_strm << thread_name << "In `Scan_Parse::variable_func()':" --- 250,254 ---- if (DEBUG) { ! if (entry == static_cast(0)) { cerr_strm << thread_name << "In `Scan_Parse::variable_func()':" *************** *** 268,272 **** cerr_strm.str(""); ! if (entry->object == 0) { --- 268,272 ---- cerr_strm.str(""); ! if (entry->object == static_cast(0)) { *************** *** 326,334 **** int curr_type; ! if (entry == 0) { curr_type = UNDECLARED; } ! else if (entry->object == 0) { curr_type = entry->type; --- 326,334 ---- int curr_type; ! if (entry == static_cast(0)) { curr_type = UNDECLARED; } ! else if (entry->object == static_cast(0)) { curr_type = entry->type; *************** *** 471,475 **** @= ! if (position == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::label_point_command()':" --- 471,475 ---- @= ! if (position == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::label_point_command()':" *************** *** 566,570 **** @= ! if (entry == 0 || entry->object == 0) { cerr_strm << thread_name --- 566,570 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 1051,1055 **** @= ! if (ppath == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::label_point_command()':" --- 1051,1055 ---- @= ! if (ppath == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::label_point_command()':" *************** *** 1118,1122 **** @= ! if (entry == 0 || entry->object == 0) { cerr_strm << thread_name --- 1118,1122 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 1566,1570 **** @= ! if (ppath == 0) { --- 1566,1570 ---- @= ! if (ppath == static_cast(0)) { *************** *** 1645,1649 **** @= ! if (scanner_node->picture_entry_ptr == 0) { --- 1645,1649 ---- @= ! if (scanner_node->picture_entry_ptr == static_cast(0)) { *************** *** 1672,1676 **** @= ! if (entry == 0 || entry->object == 0) { --- 1672,1676 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 1781,1786 **** @= ! if (ddraw_color_vector != 0) ! scanner_node->draw_color_vector_ptr = 0; else /* |ddraw_color_vector == 0| */ --- 1781,1786 ---- @= ! if (ddraw_color_vector != static_cast*>(0)) ! scanner_node->draw_color_vector_ptr = static_cast(0); else /* |ddraw_color_vector == 0| */ *************** *** 1788,1792 **** ddraw_color_vector = new Pointer_Vector; ! if (ddraw_color != 0) { --- 1788,1792 ---- ddraw_color_vector = new Pointer_Vector; ! if (ddraw_color != static_cast(0)) { *************** *** 1795,1799 **** ! else if (ccolor != 0) { ddraw_color_vector->append_copy(ccolor); --- 1795,1799 ---- ! else if (ccolor != static_cast(0)) { ddraw_color_vector->append_copy(ccolor); *************** *** 1801,1805 **** ! else if (ccolor_vector != 0 && ccolor_vector->ctr > 0) { ddraw_color_vector->append_copy(*ccolor_vector); --- 1801,1806 ---- ! else if ( ccolor_vector != static_cast*>(0) ! && ccolor_vector->ctr > 0) { ddraw_color_vector->append_copy(*ccolor_vector); *************** *** 1812,1816 **** entry = scanner_node->lookup("default_color"); ! if (entry != 0 && entry->object != 0) ddraw_color_vector->append_copy( static_cast(entry->object)); --- 1813,1818 ---- entry = scanner_node->lookup("default_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) ddraw_color_vector->append_copy( static_cast(entry->object)); *************** *** 1829,1833 **** @= ! if (ffill_color != 0) scanner_node->fill_color_ptr = 0; --- 1831,1835 ---- @= ! if (ffill_color != static_cast(0)) scanner_node->fill_color_ptr = 0; *************** *** 1840,1844 **** @q ******* (7) @> ! if (ffill_color_vector != 0 && ffill_color_vector->ctr > 0) { --- 1842,1847 ---- @q ******* (7) @> ! if ( ffill_color_vector != static_cast*>(0) ! && ffill_color_vector->ctr > 0) { *************** *** 1850,1854 **** @q ******* (7) @> ! else if (ccolor != 0) { *ffill_color = *ccolor; --- 1853,1857 ---- @q ******* (7) @> ! else if (ccolor != static_cast(0)) { *ffill_color = *ccolor; *************** *** 1858,1862 **** ! else if (ccolor_vector != 0 && ccolor_vector->ctr > 0) { --- 1861,1866 ---- ! else if ( ccolor_vector != static_cast*>(0) ! && ccolor_vector->ctr > 0) { *************** *** 1872,1876 **** entry = scanner_node->lookup("default_color"); ! if (entry != 0 && entry->object != 0) *ffill_color = *(static_cast(entry->object)); else --- 1876,1881 ---- entry = scanner_node->lookup("default_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) *ffill_color = *(static_cast(entry->object)); else *************** *** 1886,1890 **** entry = scanner_node->lookup("background_color"); ! if (entry != 0 && entry->object != 0) *ffill_color = *(static_cast(entry->object)); else --- 1891,1896 ---- entry = scanner_node->lookup("background_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) *ffill_color = *(static_cast(entry->object)); else *************** *** 1913,1917 **** @q ****** (6).@> ! if (scanner_node->pen_vector_ptr != 0) ppen_vector = static_cast*>(scanner_node->pen_vector_ptr); --- 1919,1923 ---- @q ****** (6).@> ! if (scanner_node->pen_vector_ptr != static_cast(0)) ppen_vector = static_cast*>(scanner_node->pen_vector_ptr); *************** *** 1933,1942 **** @= ! if (scanner_node->pen_ptr == 0) { @q ******** (8) @> ! if (*(scanner_node->current_pen) != 0) { ppen = *(scanner_node->current_pen); --- 1939,1948 ---- @= ! if (scanner_node->pen_ptr == static_cast(0)) { @q ******** (8) @> ! if (*(scanner_node->current_pen) != static_cast(0)) { ppen = *(scanner_node->current_pen); *************** *** 1960,1964 **** @q ******* (7) @> ! if (ppen != 0) { ppen_vector = new Pointer_Vector; --- 1966,1970 ---- @q ******* (7) @> ! if (ppen != static_cast(0)) { ppen_vector = new Pointer_Vector; *************** *** 1985,1989 **** @q ****** (6).@> ! if (scanner_node->dash_pattern_vector_ptr != 0) ddash_pattern_vector = static_cast*>( --- 1991,1995 ---- @q ****** (6).@> ! if (scanner_node->dash_pattern_vector_ptr != static_cast(0)) ddash_pattern_vector = static_cast*>( *************** *** 1997,2001 **** @q ******* (7) @> ! if (scanner_node->dash_pattern_ptr == 0) { --- 2003,2007 ---- @q ******* (7) @> ! if (scanner_node->dash_pattern_ptr == static_cast(0)) { *************** *** 2003,2007 **** ! if (*(scanner_node->current_dash_pattern) != 0) { ddash_pattern = *(scanner_node->current_dash_pattern); --- 2009,2013 ---- ! if (*(scanner_node->current_dash_pattern) != static_cast(0)) { ddash_pattern = *(scanner_node->current_dash_pattern); *************** *** 2026,2030 **** @q ******* (7) @> ! if (ddash_pattern != 0) { ddash_pattern_vector = new Pointer_Vector; --- 2032,2036 ---- @q ******* (7) @> ! if (ddash_pattern != static_cast(0)) { ddash_pattern_vector = new Pointer_Vector; *************** *** 2423,2427 **** @= ! if (ssolid == 0) { cerr_strm << thread_name --- 2429,2433 ---- @= ! if (ssolid == static_cast(0)) { cerr_strm << thread_name *************** *** 2476,2480 **** @= ! if (scanner_node->picture_entry_ptr == 0) { --- 2482,2486 ---- @= ! if (scanner_node->picture_entry_ptr == static_cast(0)) { *************** *** 2503,2507 **** @= ! if (entry == 0 || entry->object == 0) { --- 2509,2513 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 2583,2587 **** @= ! if (scanner_node->color_vector_ptr == 0) { --- 2589,2593 ---- @= ! if (scanner_node->color_vector_ptr == static_cast(0)) { *************** *** 2614,2618 **** @= ! if (scanner_node->color_ptr != 0) { --- 2620,2624 ---- @= ! if (scanner_node->color_ptr != static_cast(0)) { *************** *** 2728,2732 **** @= ! if (scanner_node->draw_color_vector_ptr == 0) { --- 2734,2738 ---- @= ! if (scanner_node->draw_color_vector_ptr == static_cast(0)) { *************** *** 2760,2764 **** @= ! if (scanner_node->draw_color_ptr != 0) { --- 2766,2770 ---- @= ! if (scanner_node->draw_color_ptr != static_cast(0)) { *************** *** 2893,2897 **** @= ! if (scanner_node->fill_color_vector_ptr == 0) { --- 2899,2903 ---- @= ! if (scanner_node->fill_color_vector_ptr == static_cast(0)) { *************** *** 2926,2930 **** @= ! if (scanner_node->fill_color_ptr != 0) { --- 2932,2936 ---- @= ! if (scanner_node->fill_color_ptr != static_cast(0)) { *************** *** 3028,3032 **** @= ! if (ddraw_color_vector_ptr == 0 && ccolor_vector_ptr != 0) { --- 3034,3039 ---- @= ! if ( ddraw_color_vector_ptr == static_cast(0) ! && ccolor_vector_ptr != static_cast(0)) { *************** *** 3071,3075 **** } /* |if (ddraw_color_vector_ptr == 0 && ccolor_vector_ptr != 0)| */ ! if (ffill_color_vector_ptr == 0 && ccolor_vector_ptr != 0) { ffill_color_vector_ptr = ccolor_vector_ptr; --- 3078,3083 ---- } /* |if (ddraw_color_vector_ptr == 0 && ccolor_vector_ptr != 0)| */ ! if ( ffill_color_vector_ptr == static_cast(0) ! && ccolor_vector_ptr != static_cast(0)) { ffill_color_vector_ptr = ccolor_vector_ptr; *************** *** 3099,3103 **** @= ! if ( ddraw_color_vector_ptr == 0 && ( basic_drawing_command == DRAW || basic_drawing_command == FILLDRAW --- 3107,3111 ---- @= ! if ( ddraw_color_vector_ptr == static_cast(0) && ( basic_drawing_command == DRAW || basic_drawing_command == FILLDRAW *************** *** 3134,3138 **** ! if (entry == 0) { --- 3142,3146 ---- ! if (entry == static_cast(0)) { *************** *** 3242,3246 **** @= ! if ( ffill_color_vector_ptr == 0 && basic_drawing_command == FILL) --- 3250,3254 ---- @= ! if ( ffill_color_vector_ptr == static_cast(0) && basic_drawing_command == FILL) *************** *** 3275,3279 **** ! if (entry == 0) { --- 3283,3287 ---- ! if (entry == static_cast(0)) { *************** *** 3352,3356 **** @= ! if ( ffill_color_vector_ptr == 0 && basic_drawing_command == FILLDRAW) --- 3360,3364 ---- @= ! if ( ffill_color_vector_ptr == static_cast(0) && basic_drawing_command == FILLDRAW) *************** *** 3385,3389 **** ! if (entry == 0) { --- 3393,3397 ---- ! if (entry == static_cast(0)) { *************** *** 3466,3470 **** @= ! if (scanner_node->pen_ptr == 0) { #if DEBUG_COMPILE --- 3474,3478 ---- @= ! if (scanner_node->pen_ptr == static_cast(0)) { #if DEBUG_COMPILE *************** *** 3483,3487 **** ! if (*(scanner_node->current_pen) != 0) { ppen = *(scanner_node->current_pen); --- 3491,3495 ---- ! if (*(scanner_node->current_pen) != static_cast(0)) { ppen = *(scanner_node->current_pen); *************** *** 3529,3538 **** \initials{LDF 2004.11.13.} Now setting |ddash_pattern = *(scanner_node->current_dash_pattern)|, if ! | scanner_node->dash_pattern_ptr == 0 ! && *(scanner_node->current_dash_pattern) != 0|. \ENDLOG @= ! if (scanner_node->dash_pattern_ptr == 0) { #if DEBUG_COMPILE --- 3537,3545 ---- \initials{LDF 2004.11.13.} Now setting |ddash_pattern = *(scanner_node->current_dash_pattern)|, if ! |scanner_node->dash_pattern_ptr == 0 && *(scanner_node->current_dash_pattern) != 0|. \ENDLOG @= ! if (scanner_node->dash_pattern_ptr == static_cast(0)) { #if DEBUG_COMPILE *************** *** 3550,3554 **** #endif /* |DEBUG_COMPILE| */@; ! if (*(scanner_node->current_dash_pattern) != 0) { ddash_pattern = *(scanner_node->current_dash_pattern); --- 3557,3561 ---- #endif /* |DEBUG_COMPILE| */@; ! if (*(scanner_node->current_dash_pattern) != static_cast(0)) { ddash_pattern = *(scanner_node->current_dash_pattern); *************** *** 3883,3887 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 3890,3894 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 3918,3922 **** @= ! if (sd == 0) { --- 3925,3929 ---- @= ! if (sd == static_cast(0)) { *************** *** 3980,3984 **** @= ! if (scanner_node->picture_entry_ptr == 0) { --- 3987,3991 ---- @= ! if (scanner_node->picture_entry_ptr == static_cast(0)) { *************** *** 4007,4011 **** @= ! if (entry == 0 || entry->object == 0) { --- 4014,4018 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 4099,4104 **** @= ! if (ddraw_color_vector != 0) ! scanner_node->draw_color_vector_ptr = 0; else /* |ddraw_color_vector == 0| */ --- 4106,4111 ---- @= ! if (ddraw_color_vector != static_cast*>(0)) ! scanner_node->draw_color_vector_ptr = static_cast(0); else /* |ddraw_color_vector == 0| */ *************** *** 4106,4110 **** ddraw_color_vector = new Pointer_Vector; ! if (ddraw_color != 0) { --- 4113,4117 ---- ddraw_color_vector = new Pointer_Vector; ! if (ddraw_color != static_cast(0)) { *************** *** 4113,4117 **** ! else if (ccolor != 0) { ddraw_color_vector->append_copy(ccolor); --- 4120,4124 ---- ! else if (ccolor != static_cast(0)) { ddraw_color_vector->append_copy(ccolor); *************** *** 4119,4123 **** ! else if (ccolor_vector != 0 && ccolor_vector->ctr > 0) { ddraw_color_vector->append_copy(*ccolor_vector); --- 4126,4131 ---- ! else if ( ccolor_vector != static_cast*>(0) ! && ccolor_vector->ctr > 0) { ddraw_color_vector->append_copy(*ccolor_vector); *************** *** 4130,4134 **** entry = scanner_node->lookup("default_color"); ! if (entry != 0 && entry->object != 0) ddraw_color_vector->append_copy( static_cast(entry->object)); --- 4138,4143 ---- entry = scanner_node->lookup("default_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) ddraw_color_vector->append_copy( static_cast(entry->object)); *************** *** 4147,4151 **** @= ! if (ffill_color != 0) scanner_node->fill_color_ptr = 0; --- 4156,4160 ---- @= ! if (ffill_color != static_cast(0)) scanner_node->fill_color_ptr = 0; *************** *** 4158,4162 **** @q ******* (7) @> ! if (ffill_color_vector != 0 && ffill_color_vector->ctr > 0) { --- 4167,4172 ---- @q ******* (7) @> ! if ( ffill_color_vector != static_cast*>(0) ! && ffill_color_vector->ctr > 0) { *************** *** 4168,4172 **** @q ******* (7) @> ! else if (ccolor != 0) { *ffill_color = *ccolor; --- 4178,4182 ---- @q ******* (7) @> ! else if (ccolor != static_cast(0)) { *ffill_color = *ccolor; *************** *** 4176,4180 **** ! else if (ccolor_vector != 0 && ccolor_vector->ctr > 0) { --- 4186,4191 ---- ! else if ( ccolor_vector != static_cast*>(0) ! && ccolor_vector->ctr > 0) { *************** *** 4190,4194 **** entry = scanner_node->lookup("default_color"); ! if (entry != 0 && entry->object != 0) *ffill_color = *(static_cast(entry->object)); else --- 4201,4206 ---- entry = scanner_node->lookup("default_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) *ffill_color = *(static_cast(entry->object)); else *************** *** 4204,4208 **** entry = scanner_node->lookup("background_color"); ! if (entry != 0 && entry->object != 0) *ffill_color = *(static_cast(entry->object)); else --- 4216,4221 ---- entry = scanner_node->lookup("background_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) *ffill_color = *(static_cast(entry->object)); else *************** *** 4223,4227 **** @q ****** (6).@> ! if (scanner_node->pen_vector_ptr != 0) ppen_vector = static_cast*>(scanner_node->pen_vector_ptr); --- 4236,4240 ---- @q ****** (6).@> ! if (scanner_node->pen_vector_ptr != static_cast(0)) ppen_vector = static_cast*>(scanner_node->pen_vector_ptr); *************** *** 4237,4246 **** @= ! if (scanner_node->pen_ptr == 0) { @q ******** (8) @> ! if (*(scanner_node->current_pen) != 0) { ppen = *(scanner_node->current_pen); --- 4250,4259 ---- @= ! if (scanner_node->pen_ptr == static_cast(0)) { @q ******** (8) @> ! if (*(scanner_node->current_pen) != static_cast(0)) { ppen = *(scanner_node->current_pen); *************** *** 4264,4268 **** @q ******* (7) @> ! if (ppen != 0) { ppen_vector = new Pointer_Vector; --- 4277,4281 ---- @q ******* (7) @> ! if (ppen != static_cast(0)) { ppen_vector = new Pointer_Vector; *************** *** 4284,4288 **** @q ****** (6).@> ! if (scanner_node->dash_pattern_vector_ptr != 0) ddash_pattern_vector = static_cast*>( --- 4297,4301 ---- @q ****** (6).@> ! if (scanner_node->dash_pattern_vector_ptr != static_cast(0)) ddash_pattern_vector = static_cast*>( *************** *** 4296,4300 **** @q ******* (7) @> ! if (scanner_node->dash_pattern_ptr == 0) { --- 4309,4313 ---- @q ******* (7) @> ! if (scanner_node->dash_pattern_ptr == static_cast(0)) { *************** *** 4302,4306 **** ! if (*(scanner_node->current_dash_pattern) != 0) { ddash_pattern = *(scanner_node->current_dash_pattern); --- 4315,4319 ---- ! if (*(scanner_node->current_dash_pattern) != static_cast(0)) { ddash_pattern = *(scanner_node->current_dash_pattern); *************** *** 4325,4329 **** @q ******* (7) @> ! if (ddash_pattern != 0) { ddash_pattern_vector = new Pointer_Vector; --- 4338,4342 ---- @q ******* (7) @> ! if (ddash_pattern != static_cast(0)) { ddash_pattern_vector = new Pointer_Vector; *************** *** 4739,4743 **** @= ! if (scanner_node->picture_entry_ptr == 0) { --- 4752,4756 ---- @= ! if (scanner_node->picture_entry_ptr == static_cast(0)) { *************** *** 4766,4770 **** @= ! if (entry == 0 || entry->object == 0) { --- 4779,4783 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 4847,4851 **** @= ! if (scanner_node->color_vector_ptr != 0) { ccolor_vector --- 4860,4864 ---- @= ! if (scanner_node->color_vector_ptr != static_cast(0)) { ccolor_vector *************** *** 4866,4870 **** @q ******* (7) @> ! if (scanner_node->color_ptr != 0 || *(scanner_node->current_color) != 0) { --- 4879,4884 ---- @q ******* (7) @> ! if ( scanner_node->color_ptr != static_cast(0) ! || *(scanner_node->current_color) != static_cast(0)) { *************** *** 4911,4915 **** ! if (scanner_node->color_ptr != 0) { --- 4925,4929 ---- ! if (scanner_node->color_ptr != static_cast(0)) { *************** *** 4921,4925 **** @q ******* (7) @> ! else if (*(scanner_node->current_color) != 0) { ccolor_vector->append_copy(*scanner_node->current_color); --- 4935,4939 ---- @q ******* (7) @> ! else if (*(scanner_node->current_color) != static_cast(0)) { ccolor_vector->append_copy(*scanner_node->current_color); *************** *** 4942,4946 **** @= ! if (scanner_node->draw_color_vector_ptr != 0) { ddraw_color_vector --- 4956,4960 ---- @= ! if (scanner_node->draw_color_vector_ptr != static_cast(0)) { ddraw_color_vector *************** *** 4995,4999 **** @q ******* (7) @> ! if (scanner_node->draw_color_ptr != 0) { --- 5009,5013 ---- @q ******* (7) @> ! if (scanner_node->draw_color_ptr != static_cast(0)) { *************** *** 5027,5031 **** @= ! if (scanner_node->fill_color_vector_ptr != 0) { ffill_color_vector --- 5041,5045 ---- @= ! if (scanner_node->fill_color_vector_ptr != static_cast(0)) { ffill_color_vector *************** *** 5080,5084 **** @q ******* (7) @> ! if (scanner_node->fill_color_ptr != 0) { --- 5094,5098 ---- @q ******* (7) @> ! if (scanner_node->fill_color_ptr != static_cast(0)) { *************** *** 5106,5110 **** @= ! if (scanner_node->color_ptr != 0) ccolor = static_cast(scanner_node->color_ptr); --- 5120,5124 ---- @= ! if (scanner_node->color_ptr != static_cast(0)) ccolor = static_cast(scanner_node->color_ptr); *************** *** 5114,5123 **** if (ddraw_color_vector->ctr == 0) { ! if (ccolor_vector != 0 && ccolor_vector->ctr > 0) { delete ddraw_color_vector; ddraw_color_vector = ccolor_vector; } ! else if (ccolor != 0) { ddraw_color_vector->append_copy(ccolor); --- 5128,5138 ---- if (ddraw_color_vector->ctr == 0) { ! if ( ccolor_vector != static_cast*>(0) ! && ccolor_vector->ctr > 0) { delete ddraw_color_vector; ddraw_color_vector = ccolor_vector; } ! else if (ccolor != static_cast(0)) { ddraw_color_vector->append_copy(ccolor); *************** *** 5128,5132 **** entry = scanner_node->lookup("default_color"); ! if (entry != 0 && entry->object != 0) ddraw_color_vector->append_copy(static_cast(entry->object)); --- 5143,5148 ---- entry = scanner_node->lookup("default_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) ddraw_color_vector->append_copy(static_cast(entry->object)); *************** *** 5142,5150 **** if (ffill_color_vector->ctr == 0) { ! if (ccolor_vector != 0 && ccolor_vector->ctr > 0) { *ffill_color_vector = *ccolor_vector; } ! else if (ccolor != 0) { ffill_color_vector->append_copy(ccolor); --- 5158,5167 ---- if (ffill_color_vector->ctr == 0) { ! if ( ccolor_vector != static_cast*>(0) ! && ccolor_vector->ctr > 0) { *ffill_color_vector = *ccolor_vector; } ! else if (ccolor != static_cast(0)) { ffill_color_vector->append_copy(ccolor); *************** *** 5155,5159 **** entry = scanner_node->lookup("background_color"); ! if (entry != 0 && entry->object != 0) ffill_color_vector->append_copy(static_cast(entry->object)); --- 5172,5177 ---- entry = scanner_node->lookup("background_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) ffill_color_vector->append_copy(static_cast(entry->object)); *************** *** 5167,5171 **** entry = scanner_node->lookup("default_color"); ! if (entry != 0 && entry->object != 0) ffill_color_vector->append_copy(static_cast(entry->object)); --- 5185,5190 ---- entry = scanner_node->lookup("default_color"); ! if ( entry != static_cast(0) ! && entry->object != static_cast(0)) ffill_color_vector->append_copy(static_cast(entry->object)); *************** *** 5194,5198 **** @q ****** (6).@> ! if (scanner_node->pen_vector_ptr != 0) ppen_vector = static_cast*>(scanner_node->pen_vector_ptr); --- 5213,5217 ---- @q ****** (6).@> ! if (scanner_node->pen_vector_ptr != static_cast(0)) ppen_vector = static_cast*>(scanner_node->pen_vector_ptr); *************** *** 5214,5223 **** @= ! if (scanner_node->pen_ptr == 0) { @q ******** (8) @> ! if (*(scanner_node->current_pen) != 0) { ppen = *(scanner_node->current_pen); --- 5233,5242 ---- @= ! if (scanner_node->pen_ptr == static_cast(0)) { @q ******** (8) @> ! if (*(scanner_node->current_pen) != static_cast(0)) { ppen = *(scanner_node->current_pen); *************** *** 5241,5245 **** @q ******* (7) @> ! if (ppen != 0) { ppen_vector = new Pointer_Vector; --- 5260,5264 ---- @q ******* (7) @> ! if (ppen != static_cast(0)) { ppen_vector = new Pointer_Vector; *************** *** 5266,5270 **** @q ****** (6).@> ! if (scanner_node->dash_pattern_vector_ptr != 0) ddash_pattern_vector = static_cast*>( --- 5285,5289 ---- @q ****** (6).@> ! if (scanner_node->dash_pattern_vector_ptr != static_cast(0)) ddash_pattern_vector = static_cast*>( *************** *** 5278,5282 **** @q ******* (7) @> ! if (scanner_node->dash_pattern_ptr == 0) { --- 5297,5301 ---- @q ******* (7) @> ! if (scanner_node->dash_pattern_ptr == static_cast(0)) { *************** *** 5284,5288 **** ! if (*(scanner_node->current_dash_pattern) != 0) { ddash_pattern = *(scanner_node->current_dash_pattern); --- 5303,5307 ---- ! if (*(scanner_node->current_dash_pattern) != static_cast(0)) { ddash_pattern = *(scanner_node->current_dash_pattern); *************** *** 5307,5311 **** @q ******* (7) @> ! if (ddash_pattern != 0) { ddash_pattern_vector = new Pointer_Vector; --- 5326,5330 ---- @q ******* (7) @> ! if (ddash_pattern != static_cast(0)) { ddash_pattern_vector = new Pointer_Vector; *************** *** 5742,5746 **** --- 5761,5767 ---- YYSTYPE value; + #if 0 YYLTYPE location; + #endif int curr_catcode; *************** *** 5756,5760 **** --- 5777,5785 ---- { + #if 0 curr_catcode = yylex(&value, &location, scanner_node); + #else + curr_catcode = yylex(&value, scanner_node); + #endif #if DEBUG_COMPILE *************** *** 5954,5958 **** --- 5979,5988 ---- #endif /* |DEBUG_COMPILE| */@; + #if 0 curr_catcode = yylex(&value, &location, scanner_node); + #else + curr_catcode = yylex(&value, scanner_node); + #endif + @q ******** (8) Error handling: |curr_catcode != COLON|.@> *************** *** 6229,6233 **** @= ! if (filename == 0 || filename->size() == 0) { --- 6259,6263 ---- @= ! if (filename == static_cast(0) || filename->size() == 0) { *************** *** 6289,6293 **** @= ! if (new_scanner_node == 0) { cerr_strm << thread_name --- 6319,6323 ---- @= ! if (new_scanner_node == static_cast(0)) { cerr_strm << thread_name *************** *** 6400,6404 **** Id_Map_Entry_Node entry = new_scanner_node->lookup("current_picture"); ! if (entry != 0 && entry->object != 0) static_cast(entry->object)->clear(); --- 6430,6434 ---- Id_Map_Entry_Node entry = new_scanner_node->lookup("current_picture"); ! if (entry != static_cast(0) && entry->object != static_cast(0)) static_cast(entry->object)->clear(); *************** *** 6792,6796 **** @= ! if (ppoint == 0) { cerr_strm << thread_name --- 6822,6826 ---- @= ! if (ppoint == static_cast(0)) { cerr_strm << thread_name *************** *** 6827,6831 **** @= ! if (scanner_node->picture_entry_ptr == 0) { --- 6857,6861 ---- @= ! if (scanner_node->picture_entry_ptr == static_cast(0)) { *************** *** 6853,6857 **** @= ! if (entry == 0 || entry->object == 0) { cerr_strm << thread_name --- 6883,6887 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 6939,6943 **** @= ! if (scanner_node->color_ptr == 0) { --- 6969,6973 ---- @= ! if (scanner_node->color_ptr == static_cast(0)) { *************** *** 6956,6960 **** #endif /* |DEBUG_COMPILE| */@; ! if (*(scanner_node->current_color) != 0) ccolor = *(scanner_node->current_color); --- 6986,6990 ---- #endif /* |DEBUG_COMPILE| */@; ! if (*(scanner_node->current_color) != static_cast(0)) ccolor = *(scanner_node->current_color); *************** *** 6997,7001 **** @= ! if (scanner_node->draw_color_ptr == 0) { #if DEBUG_COMPILE --- 7027,7031 ---- @= ! if (scanner_node->draw_color_ptr == static_cast(0)) { #if DEBUG_COMPILE *************** *** 7045,7049 **** @= ! if (ddraw_color == 0 && ccolor != 0) ddraw_color = ccolor; --- 7075,7079 ---- @= ! if (ddraw_color == static_cast(0) && ccolor != static_cast(0)) ddraw_color = ccolor; *************** *** 7065,7069 **** @= ! if (scanner_node->pen_ptr == 0) { #if DEBUG_COMPILE --- 7095,7099 ---- @= ! if (scanner_node->pen_ptr == static_cast(0)) { #if DEBUG_COMPILE *************** *** 7082,7086 **** @q ******* (7).@> ! if (*(scanner_node->current_pen) != 0) ppen = *(scanner_node->current_pen); --- 7112,7116 ---- @q ******* (7).@> ! if (*(scanner_node->current_pen) != static_cast(0)) ppen = *(scanner_node->current_pen); *************** *** 7219,7223 **** scanner_node->picture_entry_ptr = 0; ! if (scanner_node->color_ptr != 0) { Color* c = static_cast(scanner_node->color_ptr); --- 7249,7253 ---- scanner_node->picture_entry_ptr = 0; ! if (scanner_node->color_ptr != static_cast(0)) { Color* c = static_cast(scanner_node->color_ptr); *************** *** 7226,7230 **** } ! if (scanner_node->draw_color_ptr != 0) { delete static_cast(scanner_node->draw_color_ptr); --- 7256,7260 ---- } ! if (scanner_node->draw_color_ptr != static_cast(0)) { delete static_cast(scanner_node->draw_color_ptr); *************** *** 7233,7237 **** ! if (scanner_node->fill_color_ptr != 0) { delete static_cast(scanner_node->fill_color_ptr); --- 7263,7267 ---- ! if (scanner_node->fill_color_ptr != static_cast(0)) { delete static_cast(scanner_node->fill_color_ptr); *************** *** 7239,7243 **** } ! if (scanner_node->pen_ptr != 0) { delete static_cast(scanner_node->pen_ptr); --- 7269,7273 ---- } ! if (scanner_node->pen_ptr != static_cast(0)) { delete static_cast(scanner_node->pen_ptr); *************** *** 7245,7249 **** } ! if (scanner_node->dash_pattern_ptr != 0) { delete static_cast(scanner_node->dash_pattern_ptr); --- 7275,7279 ---- } ! if (scanner_node->dash_pattern_ptr != static_cast(0)) { delete static_cast(scanner_node->dash_pattern_ptr); *************** *** 7263,7267 **** @= ! if (scanner_node->color_vector_ptr != 0) { --- 7293,7297 ---- @= ! if (scanner_node->color_vector_ptr != static_cast(0)) { *************** *** 7281,7285 **** @= ! if (scanner_node->draw_color_vector_ptr != 0) { --- 7311,7315 ---- @= ! if (scanner_node->draw_color_vector_ptr != static_cast(0)) { *************** *** 7299,7303 **** @= ! if (scanner_node->fill_color_vector_ptr != 0) { --- 7329,7333 ---- @= ! if (scanner_node->fill_color_vector_ptr != static_cast(0)) { *************** *** 7387,7391 **** ! if (entry != 0 && entry->array_flag) { --- 7417,7421 ---- ! if (entry != static_cast(0) && entry->array_flag) { *************** *** 7426,7430 **** } /* |if (entry != 0 && entry->array_flag)| */ ! else if (entry == 0) entry = scanner_node->lookup(curr_name); --- 7456,7460 ---- } /* |if (entry != 0 && entry->array_flag)| */ ! else if (entry == static_cast(0)) entry = scanner_node->lookup(curr_name); *************** *** 7432,7436 **** if (DEBUG) { ! if (entry == 0) { cerr_strm << thread_name --- 7462,7466 ---- if (DEBUG) { ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 7468,7472 **** @= ! if (entry == 0) { --- 7498,7502 ---- @= ! if (entry == static_cast(0)) { *************** *** 7497,7501 **** @= ! if (entry != 0 && entry->type != curr_type) { --- 7527,7531 ---- @= ! if (entry != static_cast(0) && entry->type != curr_type) { *************** *** 7596,7600 **** @= ! if (entry == 0) { cerr_strm << thread_name --- 7626,7630 ---- @= ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 7617,7621 **** @= ! if (entry->object == 0) { cerr_strm << thread_name --- 7647,7651 ---- @= ! if (entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 7858,7867 **** definition. */ - - - - - - @q ** (2) |rotate_around_func|.@> @*1 {\bf rotate\_around\_func}. --- 7888,7891 ---- *************** *** 7961,7966 **** @= ! if ( p == 0 || q == 0 || *p == INVALID_POINT || *q == INVALID_POINT ! || r == INVALID_REAL) { --- 7985,7993 ---- @= ! if ( p == static_cast(0) ! || q == static_cast(0) ! || *p == INVALID_POINT ! || *q == INVALID_POINT ! || r == INVALID_REAL) { *************** *** 8094,8098 **** @= ! if (entry == 0 || entry->object == 0) { cerr_strm << thread_name --- 8121,8125 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << thread_name *************** *** 8148,8152 **** @= ! if (t == 0) { --- 8175,8179 ---- @= ! if (t == static_cast(0)) { *************** *** 8721,8725 **** --- 8748,8754 ---- YYSTYPE value; + #if 0 YYLTYPE location; + #endif scanner_node->group_ctr++; *************** *** 8890,8894 **** --- 8919,8927 ---- prev_token = curr_token; + #if 0 curr_token = yylex(&value, &location, scanner_node); + #else + curr_token = yylex(&value, scanner_node); + #endif *************** *** 9316,9320 **** --- 9349,9355 ---- YYSTYPE value; + #if 0 YYLTYPE location; + #endif int curr_catcode = NULL_VALUE; *************** *** 9332,9347 **** @q ***** (5).@> curr_catcode = yylex(&value, &location, scanner_node); #if DEBUG_COMPILE ! if (DEBUG) ! { ! cerr << "After `yylex()': " ! << "`scanner_node->token_string' == " ! << scanner_node->token_string << endl; ! } ! #endif /* |DEBUG_COMPILE| */@; ! ! if (curr_catcode == COLON) { --- 9367,9385 ---- @q ***** (5).@> + #if 0 curr_catcode = yylex(&value, &location, scanner_node); + #else + curr_catcode = yylex(&value, scanner_node); + #endif #if DEBUG_COMPILE ! if (DEBUG) ! { ! cerr << "After `yylex()': " ! << "`scanner_node->token_string' == " ! << scanner_node->token_string << endl; ! } ! #endif /* |DEBUG_COMPILE| */ ! if (curr_catcode == COLON) { *************** *** 9437,9441 **** --- 9475,9483 ---- @q ***** (5).@> + #if 0 curr_catcode = yylex(&value, &location, scanner_node); + #else + curr_catcode = yylex(&value, scanner_node); + #endif if (curr_catcode == END_FOR && nest_ctr == 0) *************** *** 10387,10391 **** ! if (entry == 0) { cerr_strm << thread_name << "ERROR! " --- 10429,10433 ---- ! if (entry == static_cast(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 10416,10420 **** Definition_Info_Node din; ! if (entry->object == 0) { try --- 10458,10462 ---- Definition_Info_Node din; ! if (entry->object == static_cast(0)) { try *************** *** 10574,10578 **** --- 10616,10622 ---- YYSTYPE value; + #if 0 YYLTYPE location; + #endif int prev_token; *************** *** 10597,10601 **** --- 10641,10650 ---- prev_token = curr_token; + #if 0 curr_token = yylex(&value, &location, scanner_node); + #else + curr_token = yylex(&value, scanner_node); + #endif + #if DEBUG_COMPILE *************** *** 11016,11020 **** ! if (entry == 0) { cerr_strm << thread_name --- 11065,11069 ---- ! if (entry == static_cast(0)) { cerr_strm << thread_name *************** *** 11320,11324 **** @= ! if (entry == 0 || entry->object == 0) { cerr_strm << "ERROR! In Scan_Parse::macro_call_func()':" --- 11369,11373 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { cerr_strm << "ERROR! In Scan_Parse::macro_call_func()':" *************** *** 11550,11554 **** --- 11599,11605 ---- YYSTYPE value; + #if 0 YYLTYPE location; + #endif int prev_token; *************** *** 11562,11567 **** curr_token = LEFT_BRACE; else ! curr_token = yylex(&value, &location, scanner_node); if (curr_token == LEFT_BRACE) --- 11613,11624 ---- curr_token = LEFT_BRACE; else ! { + #if 0 + curr_token = yylex(&value, &location, scanner_node); + #else + curr_token = yylex(&value, scanner_node); + #endif + } /* |else| */ if (curr_token == LEFT_BRACE) *************** *** 11597,11601 **** --- 11654,11663 ---- prev_token = curr_token; + #if 0 curr_token = yylex(&value, &location, scanner_node); + #else + curr_token = yylex(&value, scanner_node); + #endif + if (curr_token == RIGHT_BRACE && brace_nest_ctr == 0) *************** *** 12047,12051 **** @= ! if (entry == 0) { --- 12109,12113 ---- @= ! if (entry == static_cast(0)) { *************** *** 12067,12071 **** @= ! if (entry->subordinate_array == 0) { --- 12129,12133 ---- @= ! if (entry->subordinate_array == static_cast(0)) { *************** *** 12164,12168 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12226,12230 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12191,12195 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12253,12257 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12218,12222 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12280,12284 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12244,12248 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12306,12310 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12272,12276 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12334,12338 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12298,12302 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12360,12364 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12323,12327 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12385,12389 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12350,12354 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12412,12416 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12377,12381 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12439,12443 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12405,12409 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12467,12471 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12432,12436 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12494,12498 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12459,12463 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12521,12525 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12495,12499 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12557,12561 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12522,12526 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12584,12588 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12549,12553 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12611,12615 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12577,12581 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12639,12643 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12604,12608 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12666,12670 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12632,12636 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12694,12698 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12658,12662 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12720,12724 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12687,12691 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12749,12753 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12713,12717 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12775,12779 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12741,12745 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12803,12807 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12767,12771 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12829,12833 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12795,12799 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12857,12861 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12821,12825 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12883,12887 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12850,12854 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12912,12916 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12877,12881 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { pv->v.clear(); --- 12939,12943 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { pv->v.clear(); *************** *** 12981,12985 **** @= ! if (entry == 0) { --- 13043,13047 ---- @= ! if (entry == static_cast(0)) { *************** *** 13001,13005 **** @= ! if (entry->subordinate_array == 0) { --- 13063,13067 ---- @= ! if (entry->subordinate_array == static_cast(0)) { *************** *** 13227,13231 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13289,13293 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13248,13252 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13310,13314 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13268,13272 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13330,13334 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13289,13293 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13351,13355 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13315,13319 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13377,13381 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13340,13344 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13402,13406 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13366,13370 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13428,13432 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13392,13396 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13454,13458 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13418,13422 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13480,13484 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13444,13448 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13506,13510 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13473,13477 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13535,13539 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13501,13505 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13563,13567 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13527,13531 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13589,13593 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13553,13557 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13615,13619 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13578,13582 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13640,13644 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13604,13608 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13666,13670 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13631,13635 **** PV* pv = static_cast(entry->object); ! if (pv != 0) { @@; --- 13693,13697 ---- PV* pv = static_cast(entry->object); ! if (pv != static_cast(0)) { @@; *************** *** 13692,13696 **** @= ! if (pv != 0) { --- 13754,13758 ---- @= ! if (pv != static_cast(0)) { *************** *** 13702,13706 **** root = scanner_node->lookup(root_strm.str()); ! if (root == 0) { cerr_strm << thread_name --- 13764,13768 ---- root = scanner_node->lookup(root_strm.str()); ! if (root == static_cast(0)) { cerr_strm << thread_name *************** *** 13726,13730 **** false); ! if (temp_entry == 0) { cerr_strm << thread_name --- 13788,13792 ---- false); ! if (temp_entry == static_cast(0)) { cerr_strm << thread_name *************** *** 13743,13747 **** return 1; ! } /* |if (temp_entry == 0)| */ --- 13805,13809 ---- return 1; ! } /* |if (temp_entry == static_cast(0))| */ *************** *** 13752,13756 **** --pv->ctr; ! } /* |if (pv != 0)| */ @q ** (2) |let_func|.@> --- 13814,13818 ---- --pv->ctr; ! } /* |if (pv != static_cast(0))| */ @q ** (2) |let_func|.@> *************** *** 13820,13824 **** --- 13882,13888 ---- YYSTYPE value; + #if 0 YYLTYPE location; + #endif int curr_catcode; *************** *** 13829,13833 **** --- 13893,13901 ---- { + #if 0 curr_catcode = yylex(&value, &location, scanner_node); + #else + curr_catcode = yylex(&value, scanner_node); + #endif if (curr_catcode == SEMI_COLON) *************** *** 13866,13870 **** @= ! if (entry_1 == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::let_func()':" --- 13934,13938 ---- @= ! if (entry_1 == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::let_func()':" *************** *** 13897,13901 **** @= ! if (entry_0 != 0) { #if DEBUG_COMPILE --- 13965,13969 ---- @= ! if (entry_0 != static_cast(0)) { #if DEBUG_COMPILE *************** *** 14081,14085 **** @= ! if (p == 0 || q == 0) { --- 14149,14153 ---- @= ! if (p == static_cast(0) || q == static_cast(0)) { *************** *** 14191,14195 **** @= ! if (r == 0 || p0 == 0 || p1 == 0) { cerr_strm << thread_name --- 14259,14265 ---- @= ! if ( r == static_cast(0) ! || p0 == static_cast(0) ! || p1 == static_cast(0)) { cerr_strm << thread_name *************** *** 14278,14282 **** @q ****** (6).@> ! if (pv == 0) { cerr_strm << thread_name --- 14348,14352 ---- @q ****** (6).@> ! if (pv == static_cast*>(0)) { cerr_strm << thread_name *************** *** 14306,14310 **** @q ****** (6).@> ! else /* |pv != 0| */ { --- 14376,14380 ---- @q ****** (6).@> ! else /* |pv != static_cast(0)| */ { *************** *** 14315,14319 **** return 0; ! } /* |else | (|pv != 0|) */ @q ****** (6).@> --- 14385,14389 ---- return 0; ! } /* |else | (|pv != static_cast(0)|) */ @q ****** (6).@> *************** *** 14370,14374 **** @= ! if (r == 0 || p == 0) { cerr_strm << thread_name --- 14440,14444 ---- @= ! if (r == static_cast(0) || p == static_cast(0)) { cerr_strm << thread_name *************** *** 14602,14606 **** @= ! if (p == 0) { cerr_strm << thread_name --- 14672,14676 ---- @= ! if (p == static_cast(0)) { cerr_strm << thread_name *************** *** 15175,15179 **** ! if (entry == 0) { --- 15245,15249 ---- ! if (entry == static_cast(0)) { *************** *** 15522,15526 **** @q **** (4) @> ! if (str == 0) { cerr_strm << thread_name << "WARNING! " --- 15592,15596 ---- @q **** (4) @> ! if (str == static_cast(0)) { cerr_strm << thread_name << "WARNING! " *************** *** 15614,15623 **** @= ! if (p == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::is_cycle_func()':" << endl ! << "`path* p' is null." << endl << "Returning `bool* b' (cast to `void*') with `*b == 0'."; --- 15684,15693 ---- @= ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::is_cycle_func()':" << endl ! << "`Path* p' is null." << endl << "Returning `bool* b' (cast to `void*') with `*b == 0'."; *************** *** 15899,15903 **** @= ! if (!p || !q) { cerr_strm << "ERROR! In `Scan_Parse::plane_intersection_func:'" --- 15969,15973 ---- @= ! if (p == static_cast(0) || q == static_cast(0)) { cerr_strm << "ERROR! In `Scan_Parse::plane_intersection_func:'" *************** *** 16165,16169 **** @= ! if (v == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::get_hyperbola_branch_func':" --- 16235,16239 ---- @= ! if (v == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::get_hyperbola_branch_func':" *************** *** 16220,16224 **** @= ! if (p == 0) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::get_hyperbola_branch_func':" --- 16290,16294 ---- @= ! if (p == static_cast(0)) { cerr_strm << thread_name << "ERROR! In `Scan_Parse::get_hyperbola_branch_func':" *************** *** 16414,16418 **** @= ! if (c == 0) { cerr_strm << thread_name << "ERROR! " --- 16484,16488 ---- @= ! if (c == static_cast(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 16459,16463 **** @= ! if (pv == 0) { cerr_strm << thread_name << "ERROR! " --- 16529,16533 ---- @= ! if (pv == static_cast*>(0)) { cerr_strm << thread_name << "ERROR! " *************** *** 17254,17258 **** Point* p = 0; ! if (increment != 0) { p = get_point(scanner_node, --- 17324,17328 ---- Point* p = 0; ! if (increment != ZERO_REAL) { p = get_point(scanner_node, *************** *** 17275,17279 **** @= ! if (p != 0) { q = create_new(0); --- 17345,17349 ---- @= ! if (p != static_cast(0)) { q = create_new(0); *************** *** 17291,17295 **** @= ! if (p != 0) { --- 17361,17365 ---- @= ! if (p != static_cast(0)) { *************** *** 17662,17666 **** @= ! if (increment != 0) { --- 17732,17736 ---- @= ! if (increment != ZERO_REAL) { *************** *** 17860,17864 **** @= ! if (pv == 0) { --- 17930,17934 ---- @= ! if (pv == static_cast*>(0)) { *************** *** 17965,17969 **** @= ! if (increment != 0) { p = create_new(pv->v[2]); --- 18035,18039 ---- @= ! if (increment != ZERO_REAL) { p = create_new(pv->v[2]); diff -rc2P 3DLDF-2.0.2/src/sctpcrt.web 3DLDF-2.0.3/src/sctpcrt.web *** 3DLDF-2.0.2/src/sctpcrt.web Thu Nov 7 13:40:08 2013 --- 3DLDF-2.0.3/src/sctpcrt.web Fri Dec 13 15:40:52 2013 *************** *** 288,292 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "in_filename == " << in_filename << endl << flush; #endif --- 288,292 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "in_filename == " << in_filename << endl; #endif *************** *** 296,300 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "No period." << "\n" << flush;@/@,@; #endif --- 296,300 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "No period." << "\n";@/@,@; #endif *************** *** 308,312 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "Trying " << in_filename<< ".\n" << flush; #endif --- 308,312 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "Trying " << in_filename<< ".\n"; #endif *************** *** 316,320 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << in_filename << " exists!" << endl << flush; #endif } --- 316,320 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << in_filename << " exists!" << endl; #endif } *************** *** 328,332 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << in_filename << " doesn't exist!" << endl << flush; #endif in_filename = str; --- 328,332 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << in_filename << " doesn't exist!" << endl; #endif in_filename = str; *************** *** 336,341 **** cerr << "ERROR! In Scanner_Type::create():\n" << in_filename << " doesn't exist! " ! << "Returning 0. Will try to continue.\n\n" ! << flush; delete in_file; --- 336,340 ---- cerr << "ERROR! In Scanner_Type::create():\n" << in_filename << " doesn't exist! " ! << "Returning 0. Will try to continue.\n\n"; delete in_file; *************** *** 353,358 **** { #if DEBUG_COMPILE ! if (DEBUG) ! cerr << "s == " << s << endl << flush; #endif --- 352,361 ---- { #if DEBUG_COMPILE ! if (DEBUG) ! { ! cerr_mutex.lock(); ! cerr << "s == " << s << endl; ! cerr_mutex.unlock(); ! } #endif *************** *** 362,366 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << in_filename << " exists!" << endl << flush; #endif } --- 365,369 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << in_filename << " exists!" << endl; #endif } *************** *** 369,373 **** cerr << "ERROR! In Scanner_Type::create():\n" << in_filename << " doesn't exist! " ! << "Returning 0. Will try to continue.\n\n" << flush; delete in_file; return 0; --- 372,376 ---- cerr << "ERROR! In Scanner_Type::create():\n" << in_filename << " doesn't exist! " ! << "Returning 0. Will try to continue.\n\n"; delete in_file; return 0; *************** *** 400,404 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "out_filename_base == " << out_filename_base << endl << flush; #endif --- 403,407 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "out_filename_base == " << out_filename_base << endl; #endif *************** *** 412,416 **** if (DEBUG) cerr << "out_filename_base after erase == " ! << out_filename_base << endl << flush; #endif --- 415,419 ---- if (DEBUG) cerr << "out_filename_base after erase == " ! << out_filename_base << endl; #endif *************** *** 580,584 **** scanner_node->in->filename = in_filename; ! if (in_file != 0) { scanner_node->in->stream_ptr = static_cast(in_file); --- 583,587 ---- scanner_node->in->filename = in_filename; ! if (in_file != static_cast(0)) { scanner_node->in->stream_ptr = static_cast(in_file); *************** *** 589,593 **** ! else if (in_stream != 0) { scanner_node->in->stream_ptr = in_stream; --- 592,596 ---- ! else if (in_stream != static_cast(0)) { scanner_node->in->stream_ptr = in_stream; *************** *** 983,987 **** if (DEBUG) cerr << "top_level == true. Initializing scanner_node->id_map_node." ! << endl << flush; #endif --- 986,990 ---- if (DEBUG) cerr << "top_level == true. Initializing scanner_node->id_map_node." ! << endl; #endif *************** *** 5588,5591 **** --- 5591,5606 ---- Focus a(0, 0, -10, 0, 0, 10, 20); + + #if DEBUG_COMPILE + if (DEBUG) + { + cerr_mutex.lock(); + a.show("a:"); + cerr_mutex.unlock(); + + } /* |if (DEBUG)| */ + #endif /* |DEBUG_COMPILE| */ + + Focus* f = create_new(a); *************** *** 6092,6096 **** if (DEBUG) cerr << "Entry " << i++ << ": " << iter->first ! << endl << flush; } } --- 6107,6111 ---- if (DEBUG) cerr << "Entry " << i++ << ": " << iter->first ! << endl; } } *************** *** 6106,6110 **** if (DEBUG) cerr << "top_level == false. Not initializing scanner_node->id_map_node." ! << endl << flush; #endif --- 6121,6125 ---- if (DEBUG) cerr << "top_level == false. Not initializing scanner_node->id_map_node." ! << endl; #endif *************** *** 6117,6121 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "Exiting Scanner_Node::create()\n" << flush; #endif return scanner_node; --- 6132,6136 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "Exiting Scanner_Node::create()\n"; #endif return scanner_node; *************** *** 6144,6148 **** cerr << "In `Check in_filename' section:" << endl << "in_filename == " << in_filename << endl ! << "in_filename == " << in_filename << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 6159,6163 ---- cerr << "In `Check in_filename' section:" << endl << "in_filename == " << in_filename << endl ! << "in_filename == " << in_filename << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 6178,6182 **** << "Won't input `" << in_filename << "' twice." << endl ! << "Returning 0. Will try to continue.\n\n" << flush; delete in_file; --- 6193,6197 ---- << "Won't input `" << in_filename << "' twice." << endl ! << "Returning 0. Will try to continue.\n\n"; delete in_file; *************** *** 6194,6198 **** cerr << in_filename << " not found on `in_filename_vector'." << endl << "Adding it." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 6209,6213 ---- cerr << in_filename << " not found on `in_filename_vector'." << endl << "Adding it." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 6219,6223 **** cerr << "In `Check out_filename' section:" << endl << "in_filename == " << in_filename << endl ! << "out_filename == " << out_filename << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 6234,6238 ---- cerr << "In `Check out_filename' section:" << endl << "in_filename == " << in_filename << endl ! << "out_filename == " << out_filename << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 6253,6257 **** << "Won't input `" << in_filename << "' twice." << endl ! << "Returning 0. Will try to continue.\n\n" << flush; delete in_file; --- 6268,6272 ---- << "Won't input `" << in_filename << "' twice." << endl ! << "Returning 0. Will try to continue.\n\n"; delete in_file; *************** *** 6269,6273 **** cerr << out_filename << " not found on `out_filename_vector'." << endl << "Adding it." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 6284,6288 ---- cerr << out_filename << " not found on `out_filename_vector'." << endl << "Adding it." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 6288,6292 **** cerr << "ERROR! In `Scanner_Node::create()':\n" << out_filename << " doesn't exist! " ! << "Returning 0. Will try to continue.\n\n" << flush; delete in_file; delete out_file; --- 6303,6307 ---- cerr << "ERROR! In `Scanner_Node::create()':\n" << out_filename << " doesn't exist! " ! << "Returning 0. Will try to continue.\n\n"; delete in_file; delete out_file; *************** *** 6297,6302 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "Succeeded in opening " << out_filename << ".\n" ! << flush; #endif } --- 6312,6317 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "Succeeded in opening " << out_filename << ".\n"; ! #endif } diff -rc2P 3DLDF-2.0.2/src/sctpfncs.web 3DLDF-2.0.3/src/sctpfncs.web *** 3DLDF-2.0.2/src/sctpfncs.web Thu Nov 7 13:40:08 2013 --- 3DLDF-2.0.3/src/sctpfncs.web Fri Dec 13 13:19:38 2013 *************** *** 174,178 **** if (DEBUG) cerr << "Entering `Scanner_Type' destructor." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 174,178 ---- if (DEBUG) cerr << "Entering `Scanner_Type' destructor." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 299,303 **** if (DEBUG) cerr << "Calling `delete id_map_node'." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 299,303 ---- if (DEBUG) cerr << "Calling `delete id_map_node'." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 312,316 **** { cerr << "After call to `delete id_map_node'." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 312,316 ---- { cerr << "After call to `delete id_map_node'." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 324,328 **** cerr << "In `Scanner_Type' destructor: Calling `delete' on `up'." << endl << "This will cause this function to be called recursively." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 324,328 ---- cerr << "In `Scanner_Type' destructor: Calling `delete' on `up'." << endl << "This will cause this function to be called recursively." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 710,714 **** if (DEBUG) cerr << "Exiting `Scanner_Type' destructor." ! << endl << flush; #endif /* |DEBUG_COMPILE| */@; --- 710,714 ---- if (DEBUG) cerr << "Exiting `Scanner_Type' destructor." ! << endl; #endif /* |DEBUG_COMPILE| */@; *************** *** 1438,1442 **** if (DEBUG) ! cerr << "Entering Scanner_Type::add_synonym()." << "\n" << flush; #endif --- 1438,1442 ---- if (DEBUG) ! cerr << "Entering Scanner_Type::add_synonym()." << "\n"; #endif *************** *** 1452,1458 **** << "Entry already exists for " << synonym << ".Returning 0.\n" ! << "Type to continue.\n" ! << flush; ! getchar(); /* Don't delete this! */@; --- 1452,1457 ---- << "Entry already exists for " << synonym << ".Returning 0.\n" ! << "Type to continue.\n"; ! getchar(); /* Don't delete this! */@; *************** *** 1469,1475 **** << "can't add a synonym." << endl << "Returning 0.\n" ! << "Type to continue.\n" ! << flush; ! getchar(); /* Don't delete this! */@; --- 1468,1473 ---- << "can't add a synonym." << endl << "Returning 0.\n" ! << "Type to continue.\n"; ! getchar(); /* Don't delete this! */@; *************** *** 1505,1509 **** { cerr << "Exiting Scanner_Type::add_synonym() and returning `entry'." ! << "\n" << flush; } #endif --- 1503,1507 ---- { cerr << "Exiting Scanner_Type::add_synonym() and returning `entry'." ! << "\n"; } #endif *************** *** 1542,1546 **** if (DEBUG) cerr << "Entering Scanner_Type::lookup(). level == " << level ! << ".\n" << flush; #endif --- 1540,1544 ---- if (DEBUG) cerr << "Entering Scanner_Type::lookup(). level == " << level ! << ".\n"; #endif *************** *** 1563,1567 **** << ". It's a synonym for " << *base_name << "." << endl << "Calling `lookup(" << *base_name ! << ", ...)'." << endl << flush; } #endif --- 1561,1565 ---- << ". It's a synonym for " << *base_name << "." << endl << "Calling `lookup(" << *base_name ! << ", ...)'." << endl; } #endif *************** *** 1578,1582 **** cerr << "In lookup(): Found " << s << ". Returning Id_Map_Entry_Node with `type' == " ! << name_map[iter->second->type] << ".\n" << flush; #endif --- 1576,1580 ---- cerr << "In lookup(): Found " << s << ". Returning Id_Map_Entry_Node with `type' == " ! << name_map[iter->second->type] << ".\n"; #endif *************** *** 1608,1612 **** #if DEBUG_COMPILE if (DEBUG) ! cerr << "traverse == false. Returning 0." << endl << flush; #endif --- 1606,1610 ---- #if DEBUG_COMPILE if (DEBUG) ! cerr << "traverse == false. Returning 0." << endl; #endif *************** *** 1625,1629 **** if (DEBUG) cerr << "traverse == true, but local_id_map_node->up == 0. " ! << "Returning 0." << endl << flush; #endif --- 1623,1627 ---- if (DEBUG) cerr << "traverse == true, but local_id_map_node->up == 0. " ! << "Returning 0." << endl; #endif *************** *** 1643,1647 **** << "Calling this function recursively:" << endl << "`lookup(" << s << ", true, " << level ! << ", local_id_map_node->up)'" << endl << flush; #endif return lookup(s, true, level, local_id_map_node->up); --- 1641,1645 ---- << "Calling this function recursively:" << endl << "`lookup(" << s << ", true, " << level ! << ", local_id_map_node->up)'" << endl; #endif return lookup(s, true, level, local_id_map_node->up); *************** *** 2236,2240 **** } /* End of |Scanner_Type::handle_numeric_list()| definition. */ ! ; @q * (0) Extract |Picture| output arguments.@> --- 2234,2238 ---- } /* End of |Scanner_Type::handle_numeric_list()| definition. */ ! @q * (0) Extract |Picture| output arguments.@> *************** *** 2343,2347 **** if (DEBUG) { ! if (entry != 0) { cerr_mutex.lock(); --- 2341,2345 ---- if (DEBUG) { ! if (entry != static_cast(0)) { cerr_mutex.lock(); *************** *** 2449,2453 **** @= ! if (entry->object == 0) { --- 2447,2451 ---- @= ! if (entry->object == static_cast(0)) { *************** *** 3131,3135 **** ! if (focus_entry == 0 || focus_entry->object == 0) { --- 3129,3133 ---- ! if (focus_entry == static_cast(0) || focus_entry->object == 0) { diff -rc2P 3DLDF-2.0.2/src/setarc.w 3DLDF-2.0.3/src/setarc.w *** 3DLDF-2.0.2/src/setarc.w Thu Nov 7 13:36:02 2013 --- 3DLDF-2.0.3/src/setarc.w Fri Dec 13 15:42:52 2013 *************** *** 72,76 **** parameter); ! @=$$@> = 0; }; --- 72,76 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 104,108 **** ! if (scanner_node->arc_options != 0) scanner_node->arc_options->clear(); --- 104,108 ---- ! if (scanner_node->arc_options != static_cast(0)) scanner_node->arc_options->clear(); *************** *** 110,114 **** scanner_node->arc_options = new Arc_Options; ! @=$$@> = 0; }; --- 110,114 ---- scanner_node->arc_options = new Arc_Options; ! @=$$@> = static_cast(0); }; *************** *** 130,134 **** { ! @=$$@> = 0; }; --- 130,134 ---- { ! @=$$@> = static_cast(0); }; *************** *** 167,171 **** delete options->focus_0; ! if (@=$3@> == 0) options->focus_0 = static_cast(@=$5@>); else if (@=$3@> == 1) --- 167,171 ---- delete options->focus_0; ! if (@=$3@> == ZERO_REAL) options->focus_0 = static_cast(@=$5@>); else if (@=$3@> == 1) *************** *** 181,185 **** LDF 2007.11.25. */ ! @=$$@> = 0; }; --- 181,185 ---- LDF 2007.11.25. */ ! @=$$@> = static_cast(0); }; *************** *** 202,206 **** = @=$2@>; ! @=$$@> = 0; }; --- 202,206 ---- = @=$2@>; ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/setmatrx.w 3DLDF-2.0.3/src/setmatrx.w *** 3DLDF-2.0.2/src/setmatrx.w Thu Nov 7 13:36:02 2013 --- 3DLDF-2.0.3/src/setmatrx.w Fri Dec 13 15:42:52 2013 *************** *** 75,79 **** parameter); ! @=$$@> = 0; }; --- 75,79 ---- parameter); ! @=$$@> = static_cast(0); }; *************** *** 106,115 **** Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->matrix_options != 0) scanner_node->matrix_options->clear(); else scanner_node->matrix_options = new Matrix_Options; ! @=$$@> = 0; }; --- 106,115 ---- Scanner_Node scanner_node = static_cast(parameter); ! if (scanner_node->matrix_options != static_cast(0)) scanner_node->matrix_options->clear(); else scanner_node->matrix_options = new Matrix_Options; ! @=$$@> = static_cast(0); }; *************** *** 131,135 **** { ! @=$$@> = 0; }; --- 131,135 ---- { ! @=$$@> = static_cast(0); }; *************** *** 166,170 **** options->type = Matrix::MATRIX_DOUBLE_TYPE; ! @=$$@> = 0; }; --- 166,170 ---- options->type = Matrix::MATRIX_DOUBLE_TYPE; ! @=$$@> = static_cast(0); }; *************** *** 187,191 **** options->type = Matrix::MATRIX_FLOAT_TYPE; ! @=$$@> = 0; }; --- 187,191 ---- options->type = Matrix::MATRIX_FLOAT_TYPE; ! @=$$@> = static_cast(0); }; *************** *** 209,213 **** options->type = Matrix::MATRIX_COMPLEX_TYPE; ! @=$$@> = 0; }; --- 209,213 ---- options->type = Matrix::MATRIX_COMPLEX_TYPE; ! @=$$@> = static_cast(0); }; diff -rc2P 3DLDF-2.0.2/src/solfaced.web 3DLDF-2.0.3/src/solfaced.web *** 3DLDF-2.0.2/src/solfaced.web Thu Nov 7 13:40:07 2013 --- 3DLDF-2.0.3/src/solfaced.web Fri Dec 13 15:42:52 2013 *************** *** 235,239 **** ! if (solid_faced_reflection == 0) { try --- 235,239 ---- ! if (solid_faced_reflection == static_cast(0)) { try diff -rc2P 3DLDF-2.0.2/src/solids.web 3DLDF-2.0.3/src/solids.web *** 3DLDF-2.0.2/src/solids.web Thu Nov 7 13:40:07 2013 --- 3DLDF-2.0.3/src/solids.web Fri Dec 13 15:45:47 2013 *************** *** 665,678 **** if (DEBUG) { ! cerr << "paths.size() == " << paths.size() << endl << flush; ! cerr << "ellipses.size() == " << ellipses.size() << endl << flush; ! cerr << "circles.size() == " << circles.size() << endl << flush; ! cerr << "parabolae.size() == " << parabolae.size() << endl << flush; ! cerr << "hyperbolae.size() == " << hyperbolae.size() << endl << flush; cerr << "reg_polygons.size() == " << reg_polygons.size() ! << endl << flush; ! cerr << "rectangles.size() == " << rectangles.size() << endl << flush; } --- 665,678 ---- if (DEBUG) { ! cerr << "paths.size() == " << paths.size() << endl; ! cerr << "ellipses.size() == " << ellipses.size() << endl; ! cerr << "circles.size() == " << circles.size() << endl; ! cerr << "parabolae.size() == " << parabolae.size() << endl; ! cerr << "hyperbolae.size() == " << hyperbolae.size() << endl; cerr << "reg_polygons.size() == " << reg_polygons.size() ! << endl; ! cerr << "rectangles.size() == " << rectangles.size() << endl; } *************** *** 909,913 **** if (DEBUG) { ! cerr << "Entering Solid::get_shape_ptr().\n" << flush; } --- 909,913 ---- if (DEBUG) { ! cerr << "Entering Solid::get_shape_ptr().\n"; } *************** *** 925,929 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > paths.size() (" << paths.size() ! << ")\nReturning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 925,929 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > paths.size() (" << paths.size() ! << ")\nReturning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 943,947 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > ellipses.size() (" << ellipses.size() ! << ")\nReturning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 943,947 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > ellipses.size() (" << ellipses.size() ! << ")\nReturning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 960,964 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > circles.size() (" << circles.size() ! << ")\nReturning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 960,964 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > circles.size() (" << circles.size() ! << ")\nReturning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 979,983 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > parabolae.size() (" << parabolae.size() ! << ")\nReturning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 979,983 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > parabolae.size() (" << parabolae.size() ! << ")\nReturning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 997,1001 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > hyperbolae.size() (" << hyperbolae.size() ! << ")\nReturning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 997,1001 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > hyperbolae.size() (" << hyperbolae.size() ! << ")\nReturning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 1018,1022 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > rectangles.size() (" << rectangles.size() ! << ")\nReturning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 1018,1022 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > rectangles.size() (" << rectangles.size() ! << ")\nReturning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 1035,1039 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > reg_polygons.size() (" << reg_polygons.size() ! << ")\nReturning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 1035,1039 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "s (" << s << ") > reg_polygons.size() (" << reg_polygons.size() ! << ")\nReturning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 1045,1049 **** cerr << "ERROR! In Solid::get_shape_ptr():\n" << "Invalid value for curr_shape_type: " << curr_shape_type << endl ! << "Returning a null pointer (0).\n\n" << flush; return static_cast(0); } --- 1045,1049 ---- cerr << "ERROR! In Solid::get_shape_ptr():\n" << "Invalid value for curr_shape_type: " << curr_shape_type << endl ! << "Returning a null pointer (0).\n\n"; return static_cast(0); } *************** *** 1369,1373 **** cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > circles.size() (" << circles.size() ! << ")\nReturning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 1369,1373 ---- cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > circles.size() (" << circles.size() ! << ")\nReturning INVALID_POINT.\n\n"; return INVALID_POINT; } *************** *** 1383,1387 **** cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > ellipses.size() (" << ellipses.size() ! << ")\nReturning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 1383,1387 ---- cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > ellipses.size() (" << ellipses.size() ! << ")\nReturning INVALID_POINT.\n\n"; return INVALID_POINT; } *************** *** 1397,1401 **** cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > rectangles.size() (" << rectangles.size() ! << ")\nReturning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 1397,1401 ---- cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > rectangles.size() (" << rectangles.size() ! << ")\nReturning INVALID_POINT.\n\n"; return INVALID_POINT; } *************** *** 1411,1415 **** cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > reg_polygons.size() (" << reg_polygons.size() ! << ")\nReturning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 1411,1415 ---- cerr << "ERROR! In Solid::get_shape_center():\n" << "s (" << s << ") > reg_polygons.size() (" << reg_polygons.size() ! << ")\nReturning INVALID_POINT.\n\n"; return INVALID_POINT; } *************** *** 1422,1426 **** cerr << "ERROR! In Solid::get_shape_center():\n" << "Invalid argument for curr_shape_type: " << curr_shape_type ! << endl << "Returning INVALID_POINT.\n\n" << flush; return INVALID_POINT; } --- 1422,1426 ---- cerr << "ERROR! In Solid::get_shape_center():\n" << "Invalid argument for curr_shape_type: " << curr_shape_type ! << endl << "Returning INVALID_POINT.\n\n"; return INVALID_POINT; } *************** *** 2511,2515 **** Solid::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; --- 2511,2515 ---- Solid::push_draw_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; *************** *** 2557,2561 **** Solid::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 2557,2561 ---- Solid::push_fill_color(Color*& c, bool copy) { ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 2603,2610 **** Solid::push_color(Color*& c, bool copy) { ! if (draw_color_vector == 0) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == 0) fill_color_vector = new Pointer_Vector; --- 2603,2610 ---- Solid::push_color(Color*& c, bool copy) { ! if (draw_color_vector == static_cast*>(0)) draw_color_vector = new Pointer_Vector; ! if (fill_color_vector == static_cast*>(0)) fill_color_vector = new Pointer_Vector; *************** *** 2652,2656 **** Solid::push_pen(Pen*& p, bool copy) { ! if (pen_vector == 0) pen_vector = new Pointer_Vector; --- 2652,2656 ---- Solid::push_pen(Pen*& p, bool copy) { ! if (pen_vector == static_cast*>(0)) pen_vector = new Pointer_Vector; *************** *** 2696,2700 **** Solid::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == 0) dash_pattern_vector = new Pointer_Vector; --- 2696,2700 ---- Solid::push_dash_pattern(Dash_Pattern*& d, bool copy) { ! if (dash_pattern_vector == static_cast*>(0)) dash_pattern_vector = new Pointer_Vector; *************** *** 2863,2867 **** else cerr << "rectangles is empty.\n"; ! cerr << endl << flush; return; --- 2863,2867 ---- else cerr << "rectangles is empty.\n"; ! cerr << endl; return; *************** *** 2924,2928 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 2924,2928 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 3372,3376 **** ! if (solid_reflection == 0) { cerr_strm << thread_name --- 3372,3376 ---- ! if (solid_reflection == static_cast(0)) { cerr_strm << thread_name *************** *** 4415,4419 **** @= ! if (solid_ptr_vector == 0) { --- 4415,4419 ---- @= ! if (solid_ptr_vector == static_cast*>(0)) { *************** *** 4688,4692 **** cerr << "WARNING! In Solid::extract():\n" << "Path cannot be projected. " ! << "Returning empty vector .\n" << flush; return v; break; --- 4688,4692 ---- cerr << "WARNING! In Solid::extract():\n" << "Path cannot be projected. " ! << "Returning empty vector .\n"; return v; break; *************** *** 4702,4706 **** cerr << "WARNING! In Solid::extract():\n" << "Ellipse cannot be projected. " ! << "Returning empty vector .\n" << flush; return v; break; --- 4702,4706 ---- cerr << "WARNING! In Solid::extract():\n" << "Ellipse cannot be projected. " ! << "Returning empty vector .\n"; return v; break; *************** *** 4716,4720 **** cerr << "WARNING! In Solid::extract():\n" << "Circle cannot be projected. " ! << "Returning empty vector .\n" << flush; return v; break; --- 4716,4720 ---- cerr << "WARNING! In Solid::extract():\n" << "Circle cannot be projected. " ! << "Returning empty vector .\n"; return v; break; *************** *** 4730,4734 **** cerr << "WARNING! In Solid::extract():\n" << "Parabola cannot be projected. " ! << "Returning empty vector .\n" << flush; return v; break; --- 4730,4734 ---- cerr << "WARNING! In Solid::extract():\n" << "Parabola cannot be projected. " ! << "Returning empty vector .\n"; return v; break; *************** *** 4744,4748 **** cerr << "WARNING! In Solid::extract():\n" << "Hyperbola cannot be projected. " ! << "Returning empty vector .\n" << flush; return v; break; --- 4744,4748 ---- cerr << "WARNING! In Solid::extract():\n" << "Hyperbola cannot be projected. " ! << "Returning empty vector .\n"; return v; break; *************** *** 4761,4765 **** cerr << "WARNING! In Solid::extract():\n" << "Polygon cannot be projected. " ! << "Returning empty vector .\n" << flush; return v; break; --- 4761,4765 ---- cerr << "WARNING! In Solid::extract():\n" << "Polygon cannot be projected. " ! << "Returning empty vector .\n"; return v; break; *************** *** 4775,4779 **** cerr << "WARNING! In Solid::extract():\n" << "Rectangle cannot be projected. " ! << "Returning empty vector .\n" << flush; return v; break; --- 4775,4779 ---- cerr << "WARNING! In Solid::extract():\n" << "Rectangle cannot be projected. " ! << "Returning empty vector .\n"; return v; break; *************** *** 4844,4848 **** bool DEBUG = false; /* |true| */@; if (DEBUG) ! cerr << "Entering Solid::set_pre_projective_extremes()" << "\n" << flush; valarray v; v.resize(6, 0); /* LDF 2002.12.13. Added. Needed for compiling --- 4844,4848 ---- bool DEBUG = false; /* |true| */@; if (DEBUG) ! cerr << "Entering Solid::set_pre_projective_extremes()" << "\n"; valarray v; v.resize(6, 0); /* LDF 2002.12.13. Added. Needed for compiling *************** *** 4859,4863 **** cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 4859,4863 ---- cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 4882,4886 **** cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 4882,4886 ---- cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 4905,4909 **** cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 4905,4909 ---- cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 4928,4932 **** cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 4928,4932 ---- cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 4951,4955 **** cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 4951,4955 ---- cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 4977,4981 **** cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 4977,4981 ---- cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5000,5004 **** cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5000,5004 ---- cerr << "ERROR! In Solid::set_pre_projective_extremes():\n" << "Path::set_pre_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5017,5021 **** if (DEBUG) ! cerr << "Exiting Solid::set_pre_projective_extremes()" << "\n" << flush; return true; --- 5017,5021 ---- if (DEBUG) ! cerr << "Exiting Solid::set_pre_projective_extremes()" << "\n"; return true; *************** *** 5057,5061 **** bool DEBUG = false; /* |true| */@; if (DEBUG) ! cerr << "Entering Solid::set_projective_extremes()" << "\n" << flush; valarray v; v.resize(6, 0); /* LDF 2002.12.13. Added. Needed for compiling --- 5057,5061 ---- bool DEBUG = false; /* |true| */@; if (DEBUG) ! cerr << "Entering Solid::set_projective_extremes()" << "\n"; valarray v; v.resize(6, 0); /* LDF 2002.12.13. Added. Needed for compiling *************** *** 5072,5076 **** cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5072,5076 ---- cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5095,5099 **** cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5095,5099 ---- cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5118,5122 **** cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5118,5122 ---- cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5141,5145 **** cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5141,5145 ---- cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5165,5169 **** cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5165,5169 ---- cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5190,5194 **** cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5190,5194 ---- cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5213,5217 **** cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n" << flush; return false; } --- 5213,5217 ---- cerr << "ERROR! In Solid::set_projective_extremes():\n" << "Path::set_projective_extremes() returned false. " ! << "Returning false.\n\n"; return false; } *************** *** 5230,5234 **** if (DEBUG) ! cerr << "Exiting Solid::set_projective_extremes()" << "\n" << flush; return true; --- 5230,5234 ---- if (DEBUG) ! cerr << "Exiting Solid::set_projective_extremes()" << "\n"; return true; *************** *** 5430,5440 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_minimum_x()" << endl << flush; if (DEBUG) ! cerr << "minimum_x == " << projective_extremes[0] << endl << flush; if (DEBUG) ! cerr << "Exiting Solid::get_minimum_x()" << endl << flush; return projective_extremes[0]; --- 5430,5440 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_minimum_x()" << endl; if (DEBUG) ! cerr << "minimum_x == " << projective_extremes[0] << endl; if (DEBUG) ! cerr << "Exiting Solid::get_minimum_x()" << endl; return projective_extremes[0]; *************** *** 5473,5483 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_maximum_x()" << endl << flush; if (DEBUG) ! cerr << "maximum_x == " << projective_extremes[1] << endl << flush; if (DEBUG) ! cerr << "Exiting Solid::get_maximum_x()" << endl << flush; return projective_extremes[1]; --- 5473,5483 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_maximum_x()" << endl; if (DEBUG) ! cerr << "maximum_x == " << projective_extremes[1] << endl; if (DEBUG) ! cerr << "Exiting Solid::get_maximum_x()" << endl; return projective_extremes[1]; *************** *** 5547,5557 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_minimum_y()" << endl << flush; if (DEBUG) ! cerr << "minimum_y == " << projective_extremes[2] << endl << flush; if (DEBUG) ! cerr << "Exiting Solid::get_minimum_y()" << endl << flush; return projective_extremes[2]; --- 5547,5557 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_minimum_y()" << endl; if (DEBUG) ! cerr << "minimum_y == " << projective_extremes[2] << endl; if (DEBUG) ! cerr << "Exiting Solid::get_minimum_y()" << endl; return projective_extremes[2]; *************** *** 5590,5600 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_maximum_y()" << endl << flush; if (DEBUG) ! cerr << "maximum_y == " << projective_extremes[3] << endl << flush; if (DEBUG) ! cerr << "Exiting Solid::get_maximum_y()" << endl << flush; return projective_extremes[3]; --- 5590,5600 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::get_maximum_y()" << endl; if (DEBUG) ! cerr << "maximum_y == " << projective_extremes[3] << endl; if (DEBUG) ! cerr << "Exiting Solid::get_maximum_y()" << endl; return projective_extremes[3]; *************** *** 5689,5693 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 5689,5693 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 5803,5807 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 5803,5807 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 5917,5921 **** Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != 0) scanner_node = thread_info->scanner_node; --- 5917,5921 ---- Thread_Info_Type* thread_info = Thread_Info_Type::get_thread_info(); ! if (thread_info != static_cast(0)) scanner_node = thread_info->scanner_node; *************** *** 6171,6175 **** Color* c = create_new(0); ! if (color_ptr != 0) *c = *color_ptr; else --- 6171,6175 ---- Color* c = create_new(0); ! if (color_ptr != static_cast(0)) *c = *color_ptr; else *************** *** 6582,6586 **** Color* c = create_new(0); ! if (color_ptr != 0) *c = *color_ptr; else --- 6582,6586 ---- Color* c = create_new(0); ! if (color_ptr != static_cast(0)) *c = *color_ptr; else *************** *** 6651,6655 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::fill():" << "\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 6651,6655 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::fill():" << "\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 6741,6745 **** << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6741,6745 ---- << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6749,6753 **** cerr << "`Picture::lock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6749,6753 ---- cerr << "`Picture::lock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6780,6784 **** << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 6780,6784 ---- << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 6788,6792 **** cerr << "`Picture::unlock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6788,6792 ---- cerr << "`Picture::unlock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6803,6807 **** if (DEBUG) { ! cerr << "Exiting Solid::fill():" << "\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 6803,6807 ---- if (DEBUG) { ! cerr << "Exiting Solid::fill():" << "\n"; } #endif /* |DEBUG_COMPILE| */@; *************** *** 6876,6880 **** Color* c = create_new(0); ! if (draw_color_ptr != 0) *c = *draw_color_ptr; else --- 6876,6880 ---- Color* c = create_new(0); ! if (draw_color_ptr != static_cast(0)) *c = *draw_color_ptr; else *************** *** 6893,6897 **** c = create_new(0); ! if (fill_color_ptr != 0) *c = *fill_color_ptr; else --- 6893,6897 ---- c = create_new(0); ! if (fill_color_ptr != static_cast(0)) *c = *fill_color_ptr; else *************** *** 6974,6978 **** if (DEBUG) cerr << "Entering Solid::filldraw():" ! << "\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 6974,6978 ---- if (DEBUG) cerr << "Entering Solid::filldraw():" ! << "\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 7072,7076 **** << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7072,7076 ---- << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7080,7084 **** cerr << "`Picture::lock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7080,7084 ---- cerr << "`Picture::lock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7111,7115 **** << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7111,7115 ---- << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7119,7123 **** cerr << "`Picture::unlock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7119,7123 ---- cerr << "`Picture::unlock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7135,7139 **** if (DEBUG) { ! cerr << "Exiting Solid::filldraw():" << "\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7135,7139 ---- if (DEBUG) { ! cerr << "Exiting Solid::filldraw():" << "\n"; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7221,7225 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::undraw():" << "\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 7221,7225 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::undraw():" << "\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 7295,7299 **** << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7295,7299 ---- << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7303,7307 **** cerr << "`Picture::lock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7303,7307 ---- cerr << "`Picture::lock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7334,7338 **** << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7334,7338 ---- << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7342,7346 **** cerr << "`Picture::unlock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7342,7346 ---- cerr << "`Picture::unlock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7357,7361 **** if (DEBUG) { ! cerr << "Exiting Solid::undraw():" << "\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7357,7361 ---- if (DEBUG) { ! cerr << "Exiting Solid::undraw():" << "\n"; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7430,7434 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::unfill():" << "\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 7430,7434 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::unfill():" << "\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 7503,7507 **** << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7503,7507 ---- << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7511,7515 **** cerr << "`Picture::lock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7511,7515 ---- cerr << "`Picture::lock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7542,7546 **** << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7542,7546 ---- << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7550,7554 **** cerr << "`Picture::unlock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7550,7554 ---- cerr << "`Picture::unlock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7565,7569 **** if (DEBUG) { ! cerr << "Exiting Solid::unfill():" << "\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7565,7569 ---- if (DEBUG) { ! cerr << "Exiting Solid::unfill():" << "\n"; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7673,7677 **** bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::unfilldraw():" << "\n" << flush; #endif /* |DEBUG_COMPILE| */@; --- 7673,7677 ---- bool DEBUG = false; /* |true| */ if (DEBUG) ! cerr << "Entering Solid::unfilldraw():" << "\n"; #endif /* |DEBUG_COMPILE| */@; *************** *** 7744,7748 **** << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7744,7748 ---- << "`Picture::lock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7752,7756 **** cerr << "`Picture::lock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7752,7756 ---- cerr << "`Picture::lock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7784,7788 **** << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl << flush; return 1; } --- 7784,7788 ---- << "`Picture::unlock()' failed. " << "Returning 1 and will try to continue." ! << endl; return 1; } *************** *** 7792,7796 **** cerr << "`Picture::unlock()' succeeded." ! << endl << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7792,7796 ---- cerr << "`Picture::unlock()' succeeded." ! << endl; } #endif /* |DEBUG_COMPILE| */@; *************** *** 7806,7810 **** if (DEBUG) { ! cerr << "Exiting Solid::unfilldraw():" << "\n" << flush; } #endif /* |DEBUG_COMPILE| */@; --- 7806,7810 ---- if (DEBUG) { ! cerr << "Exiting Solid::unfilldraw():" << "\n"; } #endif /* |DEBUG_COMPILE| */@; diff -rc2P 3DLDF-2.0.2/src/spdvexpr.w 3DLDF-2.0.3/src/spdvexpr.w *** 3DLDF-2.0.2/src/spdvexpr.w Thu Nov 7 13:36:02 2013 --- 3DLDF-2.0.3/src/spdvexpr.w Fri Dec 13 12:51:30 2013 *************** *** 89,93 **** Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == 0 || entry->object == 0) { --- 89,93 ---- Id_Map_Entry_Node entry = static_cast(@=$1@>); ! if (entry == static_cast(0) || entry->object == static_cast(0)) { *************** *** 156,165 **** @= ! if (pv == 0) { delete c; ! @=$$@> = 0; } /* |if (pv == 0)| */ --- 156,165 ---- @= ! if (pv == static_cast*>(0)) { delete c; ! @=$$@> = static_cast(0); } /* |if (pv == 0)| */ *************** *** 176,180 **** delete c; ! @=$$@> = 0; } /* |else if (pv->ctr == 0)| */ --- 176,180 ---- delete c; ! @=$$@> = static_cast(0); } /* |else if (pv->ctr == 0)| */ diff -rc2P 3DLDF-2.0.2/src/spdvvexp.w 3DLDF-2.0.3/src/spdvvexp.w *** 3DLDF-2.0.2/src/spdvvexp.w Thu Nov 7 13:36:02 2013 --- 3DLDF-2.0.3/src/spdvvexp.w Fri Dec 13 11:59:33 2013 *************** *** 100,107 **** @= ! if (entry == 0 || entry->object == 0) { ! @=$$@> = 0; } /* |if (entry == 0 || entry->object == 0)| */ --- 100,107 ---- @= ! if (entry == static_cast(0) || entry->object == static_cast(0)) { ! @=$$@> = static_cast(0); } /* |if (entry == 0 || entry->object == 0)| */ diff -rc2P 3DLDF-2.0.2/src/spheres.web 3DLDF-2.0.3/src/spheres.web *** 3DLDF-2.0.2/src/spheres.web Wed Nov 6 20:57:22 2013 --- 3DLDF-2.0.3/src/spheres.web Fri Dec 13 15:47:46 2013 *************** *** 361,365 **** @q ******* (7).@> ! if (options == 0) { cerr_strm << thread_name << "In `Sphere::set':" --- 361,365 ---- @q ******* (7).@> ! if (options == static_cast(0)) { cerr_strm << thread_name << "In `Sphere::set':" *************** *** 428,432 **** @= ! if (options == 0) { cerr << "options == 0" << endl; --- 428,432 ---- @= ! if (options == static_cast(0)) { cerr << "options == 0" << endl; *************** *** 465,469 **** @= ! if (options == 0) { #if DEBUG_COMPILE --- 465,469 ---- @= ! if (options == static_cast(0)) { #if DEBUG_COMPILE *************** *** 518,522 **** @= ! if (options == 0) { #if DEBUG_COMPILE --- 518,522 ---- @= ! if (options == static_cast(0)) { #if DEBUG_COMPILE *************** *** 540,544 **** ! else if (options->radius == 0) { #if DEBUG_COMPILE --- 540,544 ---- ! else if (options->radius == ZERO_REAL) { #if DEBUG_COMPILE *************** *** 614,618 **** @= ! if (options == 0) { #if DEBUG_COMPILE --- 614,618 ---- @= ! if (options == static_cast(0)) { #if DEBUG_COMPILE *************** *** 1508,1512 **** { ! if (center != 0) center->shift_times(x, y, z); --- 1508,1512 ---- { ! if (center != static_cast(0)) center->shift_times(x, y, z); *************** *** 1801,1805 **** point_pair.first = a + (lambda1 * v); ! if (root_value == 0) { point_pair.second = INVALID_POINT; --- 1801,1805 ---- point_pair.first = a + (lambda1 * v); ! if (root_value == ZERO_REAL) { point_pair.second = INVALID_POINT; *************** *** 2029,2033 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 2029,2033 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 2385,2389 **** @q ***** (5).@> ! if (center == 0) cerr << "center == 0" << endl; else --- 2385,2389 ---- @q ***** (5).@> ! if (center == static_cast(0)) cerr << "center == 0" << endl; else diff -rc2P 3DLDF-2.0.2/src/sphrdevl.web 3DLDF-2.0.3/src/sphrdevl.web *** 3DLDF-2.0.2/src/sphrdevl.web Wed Nov 6 20:57:22 2013 --- 3DLDF-2.0.3/src/sphrdevl.web Fri Dec 13 15:52:51 2013 *************** *** 252,256 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 252,256 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 291,295 **** @q ****** (6).@> ! if (options == 0) { --- 291,295 ---- @q ****** (6).@> ! if (options == static_cast(0)) { *************** *** 577,581 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 577,581 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; *************** *** 707,711 **** #if DEBUG_COMPILE ! bool DEBUG = true; /* |false| */ @; #endif /* |DEBUG_COMPILE| */@; --- 707,711 ---- #if DEBUG_COMPILE ! bool DEBUG = false; /* |true| */ @; #endif /* |DEBUG_COMPILE| */@; diff -rc2P 3DLDF-2.0.2/src/transfor.web 3DLDF-2.0.3/src/transfor.web *** 3DLDF-2.0.2/src/transfor.web Thu Nov 7 13:40:07 2013 --- 3DLDF-2.0.3/src/transfor.web Fri Dec 13 15:54:34 2013 *************** *** 523,527 **** for (int j = 0; j < 4; j++) if ((i == j && transform_matrix[i][j] != 1) ! || ((i != j) && transform_matrix[i][j] != 0)) return false; return true; --- 523,527 ---- for (int j = 0; j < 4; j++) if ((i == j && transform_matrix[i][j] != 1) ! || ((i != j) && transform_matrix[i][j] != ZERO_REAL)) return false; return true; *************** *** 546,550 **** for (int j = 0; j < 4; j++) if ((i == j && transform_matrix[i][j] != 1) ! || ((i != j) && transform_matrix[i][j] != 0)) return false; return true; --- 546,550 ---- for (int j = 0; j < 4; j++) if ((i == j && transform_matrix[i][j] != 1) ! || ((i != j) && transform_matrix[i][j] != ZERO_REAL)) return false; return true; *************** *** 720,724 **** ! if (xy == 0 && xz == 0 && yx == 0 && yz == 0 && zx == 0 && zy == 0) { cerr << "WARNING! In Transform::shear():\n" --- 720,729 ---- ! if ( xy == ZERO_REAL ! && xz == ZERO_REAL ! && yx == ZERO_REAL ! && yz == ZERO_REAL ! && zx == ZERO_REAL ! && zy == ZERO_REAL) { cerr << "WARNING! In Transform::shear():\n" *************** *** 760,764 **** Transform t; ! if (x == 0 && y == 0 && z == 0) return t; --- 765,769 ---- Transform t; ! if (x == ZERO_REAL && y == ZERO_REAL && z == ZERO_REAL) return t; *************** *** 840,849 **** real eps = epsilon(); ! if (x == 0 && y == 0 && z == 0) { if (DEBUG) cerr << "In rotate(real, real, real)\n" ! << "0 rotation about all axes. Returning identity matrix.\n" ! ; return t_all; } --- 845,854 ---- real eps = epsilon(); ! if (x == ZERO_REAL && y == ZERO_REAL && z == ZERO_REAL) { if (DEBUG) cerr << "In rotate(real, real, real)\n" ! << "0 rotation about all axes. Returning identity matrix.\n"; ! return t_all; } *************** *** 860,864 **** @ Rotation around the x-axis. @= ! if (x != 0) { --- 865,870 ---- @ Rotation around the x-axis. @= ! ! if (x != ZERO_REAL) { *************** *** 887,891 **** @ Rotation around the y-axis. @= ! if (y != 0) { --- 893,898 ---- @ Rotation around the y-axis. @= ! ! if (y != ZERO_REAL) { *************** *** 912,916 **** @ Rotation around the z-axis. @= ! if (z != 0) { --- 919,924 ---- @ Rotation around the z-axis. @= ! ! if (z != ZERO_REAL) { *************** *** 1290,1298 **** cout << "row == " << row << endl; } ! if (max == 0) { cerr << "ERROR! In Transform::inverse():\n" ! << "Transform_Matrix is singular. Returning INVALID_TRANSFORM.\n" ! ; return INVALID_TRANSFORM; } --- 1298,1307 ---- cout << "row == " << row << endl; } ! ! if (max == ZERO_REAL) { cerr << "ERROR! In Transform::inverse():\n" ! << "Transform_Matrix is singular. Returning INVALID_TRANSFORM.\n"; ! return INVALID_TRANSFORM; } diff -rc2P 3DLDF-2.0.2/src/utility.web 3DLDF-2.0.3/src/utility.web *** 3DLDF-2.0.2/src/utility.web Thu Nov 7 13:40:07 2013 --- 3DLDF-2.0.3/src/utility.web Fri Dec 13 15:55:05 2013 *************** *** 216,226 **** ! if (horizon_rt == 0) horizon_rt = horizon_lft; ! if (gl_lft == 0) gl_lft = horizon_lft; ! if (gl_rt == 0) gl_rt = horizon_rt; --- 216,226 ---- ! if (horizon_rt == ZERO_REAL) horizon_rt = horizon_lft; ! if (gl_lft == ZERO_REAL) gl_lft = horizon_lft; ! if (gl_rt == ZERO_REAL) gl_rt = horizon_rt; *************** *** 290,294 **** cerr << "points[" << points.size() << "]. Angle = " << *iter <<". x = " ! << q.get_x() << endl << flush; #endif points.push_back(create_new(q)); --- 290,294 ---- cerr << "points[" << points.size() << "]. Angle = " << *iter <<". x = " ! << q.get_x() << endl; #endif points.push_back(create_new(q)); *************** *** 426,431 **** { cerr << "ERROR! In persp_0():\n" ! << "front_corner_z < 0.\nReturning.\n\n" ! << flush; return; } --- 426,431 ---- { cerr << "ERROR! In persp_0():\n" ! << "front_corner_z < 0.\nReturning.\n\n"; ! return; } *************** *** 442,452 **** ! if (horizon_rt == 0) horizon_rt = horizon_lft; ! if (gl_lft == 0) gl_lft = horizon_lft; ! if (gl_rt == 0) gl_rt = horizon_rt; --- 442,452 ---- ! if (horizon_rt == ZERO_REAL) horizon_rt = horizon_lft; ! if (gl_lft == ZERO_REAL) gl_lft = horizon_lft; ! if (gl_rt == ZERO_REAL) gl_rt = horizon_rt; *************** *** 632,637 **** Point back_corner = Point::intersection_point(right_corner, vpl, left_corner, vpr).pt; back_corner.dotlabel(picture, "$r_2$"); ! Path pa("--", true, &front_corner, &right_corner, &back_corner, &left_corner, 0); ! Point center = Point::intersection_point(front_corner, back_corner, --- 632,642 ---- Point back_corner = Point::intersection_point(right_corner, vpl, left_corner, vpr).pt; back_corner.dotlabel(picture, "$r_2$"); ! Path pa("--", ! true, ! &front_corner, ! &right_corner, ! &back_corner, ! &left_corner, ! static_cast(0)); Point center = Point::intersection_point(front_corner, back_corner,