3DLDF: The Program Version 1.1.5.1 by Laurence D. Finston

January 2004

Section Page

Copyright and License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 Introduction (3DLDF.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1 Formatting commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2 Preprocessor variables and library files (loader.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 3 Configuration file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3 Library files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 4 Putting loader together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 5 Global items (pspglb.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 6 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 6 Type definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 6 Utility classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 7 Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 7

For compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 7 For the header file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 11

Global constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 11 For compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 11 For the header file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 12

Utility functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 12

Solve quadratic equation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 12 System information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 13

Declare namespace System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 13 Endianness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 13 Get endianness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 14 Is big endian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 14 Is little endian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 15 Register width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 15 Get register width . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 15 Is 32 bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 15 Is 64 bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 16

Forward declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 16 Putting pspglb together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 16 Dynamic allocation for Shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 17 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 17 Dynamic allocation for Shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 17

Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 17 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 18

Putting creatnew together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 18

ii  TABLE OF CONTENTS  3DLDF-1.1.5.1

Get second-largest real value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 19 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 19 Declare namespace System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 19 Get second largest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 19

Calculate second-largest Real . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 21 Loop for testing bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 22

Template function instantiations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 23 Putting gsltmplt together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 23 I/O (io.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 24 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 24 Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 24 I/O functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 25

Initialize I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 25 Write footers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 26 Begin figure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 27 End figure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 28

Putting I/O together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 28 Color (colors.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 29 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 29 Color class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 29 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 29

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 29 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 30 Name and unsigned short arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 30 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 30 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 31 Three real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 31 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 31 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 32

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 33 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 33 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 34

Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 34 Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 34 Inequality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 34 Modifying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 35

Set on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 35 Set name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 35 Set use name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 35 Modify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 35 Set red part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 36 Set green part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 37 Set blue part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 37

Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 38 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 38

Is on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 38 Get Color parts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 39 Get red part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 39 Get green part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 39 Get blue part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 39 Get use name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 39 Get name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 40

3DLDF-1.1.5.1 TABLE OF CONTENTS iii

Output operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 40 Define Colors in METAPOST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 40 Initialize Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 41 Namespace Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 42 Major Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 43

Internal (with initialization) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 43 External . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 44

All Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 44 Global constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 44 Putting Color together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 45

Transformations (transform.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 46 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 46 Transform class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 46 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 46

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 46 Constructor with one real argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 47 Constructor with 16 real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 47

Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 48 Reset to identity matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 48 Setting values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 49 Clean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 49 Epsilon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 50 Test for identity matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 50

Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 50 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 51

Querying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 51

Get element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 51 Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 51 Affine transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 52

Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 52 Shear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 53 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 54 real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 54 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 55 Shift with multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 55 Rotation around the main axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 55 Rotation around an arbitrary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 57 Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 57 Path argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 58

Alignment with an axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 58 Matrix multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 58

With assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 58 real argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 58 Transform argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 58 Plain multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 59 real argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 59 Transform argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 59

Matrix inversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 60 const version (no assignment) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 60 Non-const version (with assignment) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 63

Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 63 Global constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 64

iv  TABLE OF CONTENTS  3DLDF-1.1.5.1

Putting Transform together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 64

Shape (shapes.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 65 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 65 Shape class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 65 Static data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 66 Putting Shape together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 66

Picture and Label (pictures.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 68 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 68

Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 68 Label class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 68 Static data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 68 Declarations for Label functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 69 namespace Projections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 69 namespace Sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 70

Picture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 71 Picture class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 71 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 71

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 71 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 72

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 72 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 72 Adding elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 72

Add Picture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 72 Add Shape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 72 Add Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 73

Suppress Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 73 Unsuppress Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 73 Kill Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 73 Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 74

Affine transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 74 Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 74 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 74 real version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 74 Point version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 74 Rotation around the main axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 74 Rotation around an arbitrary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 75 Set transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 75 Multiplying transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 75

Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 76 Show transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 76 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 77

Focus argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 77 No Focus argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 77

Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 77 Reset transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 77 Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 77 Putting Picture and Label together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 77

Point (points.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 79 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308 79 Point class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 79 Type definitions and utility structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 81

3DLDF-1.1.5.1 TABLE OF CONTENTS v

point pair and bool point pair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 81 bool point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 81 bool point quadruple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 83

Default Constructor for bool point quadruple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 84 bool real point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 84

Default Constructor for bool real point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 85

Global constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 85 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 85

Initialize coordinates and limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 86 Default version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 86 Three real values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 87

Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 87 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 87

Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 88

Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 88

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 89 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 89 Referece argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 89

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 89 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340 90 Set on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 90 Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 91 Clean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 91 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 92

Is identity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 92 Epsilon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350 92 Get Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 92 Getting coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 92

Get all coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 92 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 93 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 93 Get coord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 93 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 94 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 94 Get x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 95 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 95 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 95 Get y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 95 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 95 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 96 Get z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 96 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 96 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 96 Get w . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 96 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 97 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382 97

Get transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 97 Get copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385 97 Is on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 98 Slope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 98 Is on segment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392 99

Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 100

vi  TABLE OF CONTENTS  3DLDF-1.1.5.1

const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 102 Is on line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398 103 Is on Plane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 103 Is in triangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 103

Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 103

Affine transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 103 Rotation around the main axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 104 Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 104 Shear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 104 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410 104

Point versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 104 Three real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412 105 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 105 Transform version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 105 Picture version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417 105

Shift times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418 105 Three real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419 106 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 106

Alignment with an axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 106

Normalize point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 110 Rotation around an arbitrary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 110

Point versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435 110 Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436 111 Path argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 111 Transform version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439 112 Picture version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440 113

Projection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 113

Focus argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442 113 Parallel projection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444 115 Perspective projection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 116

No Focus argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446 117 Applying transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448 117 Set transform to identity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450 118

Drawing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 119

Drawdot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 119 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454 119 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 120

Undrawdot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458 120

Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460 120 Draw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 121

Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 121 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464 121

Draw arrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 121 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 121 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467 122

Undraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468 122 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469 122 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 122

Draw help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 122 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 122 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 123

Showing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474 123

3DLDF-1.1.5.1 TABLE OF CONTENTS vii

Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475 123 Show transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 124

Outputting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 125 Output operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480 125 Suppress output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482 125 Unsuppress output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484 125 Extract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486 126 Get extremes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 127 Get minimum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 127 Get maximum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 128 Get mean z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493 128 Set extremes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495 128 Comparison classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 129

Compare minimum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498 130 Compare maximum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 130 Compare mean z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500 131

Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501 131 Labelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 132

Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504 132 string argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505 133 short argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 135

Dotlabel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509 136 string argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510 137 short argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 137

Get copy of Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515 138 Output Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516 138

Matrix operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 138

Multiplication by a Transform with assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518 138 Vector operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 139

Vector addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521 139 Vector addition with assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 139 Vector subtraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525 140 Vector subtraction with assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527 140 Vector-scalar multipication with assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529 140 Vector-scalar multipication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 141

Member version (Point first) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532 141 Non-member version (scalar first) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534 141

Unary minus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536 141 Vector-scalar division with assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538 142 Vector-scalar division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540 142 Dot product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542 143 Cross product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544 143 Magnitude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546 144 Angle between two vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548 145 Unit vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550 146 With assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551 146 const (no assignment) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553 147 Mediation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555 147 Get normal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557 148

Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558 148

Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559 148 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560 148

viii  TABLE OF CONTENTS  3DLDF-1.1.5.1

const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567 151 Inequality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569 151

Intersection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 152 Vector version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572 152 Trace version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573 152

Picture functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586 159 Assignment operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587 159 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588 159 Combining Pictures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589 160 Clear Picture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 160 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 161

Focus argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592 161 No Focus argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598 165

Focus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599 165 Focus class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600 165 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601 165

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602 166 real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603 166

Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604 166 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606 168

Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608 168 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609 168 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 611 168

Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613 168 Reset angle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615 169 Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617 170 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619 171

Get position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620 171 Get direction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621 171 Get distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622 171 Get up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 171 Get transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624 172 Get transform element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625 172 Get persp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627 173 Get persp element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628 173

Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 173 Putting Point and Focus together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632 174

This is what’s compiled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633 174 This is what’s written to points.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634 174

Line (lines.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635 174 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636 175 Line struct definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637 175 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638 175

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 175 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641 176

Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643 176 Get Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645 177 Get Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646 177 Intersection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647 177 Get distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648 178 Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 181 Global constants for Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654 181

3DLDF-1.1.5.1 TABLE OF CONTENTS ix

Putting Line together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656 181 Plane (planes.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659 182 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660 182 Plane struct definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661 182 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662 182

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663 182 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665 183 Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667 184

Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669 185 Comparing Planes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671 186

Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672 186 Inequality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 674 186

Get distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676 187 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677 187 No argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679 187 Point is on Plane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681 188

Intersection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682 188

Intersection with a line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683 188 Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684 188 Path argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686 189 Intersection of two Planes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687 189

Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689 191 Global constants for Plane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 191 Putting Plane together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 191 Path (paths.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696 193 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697 193 Path class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698 193 Static member variable definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699 194 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700 194 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702 195

Discard points and connectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703 195 Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704 195 Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706 196 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 196 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709 197 Points and one type of connector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711 197 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712 198 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714 198 Variable number of Points and connectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716 199 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717 199 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719 200 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721 201

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723 202 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724 202 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725 202

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 726 202 Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728 203 Get copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730 204 Set on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732 205 Setting drawing and filling data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734 205

Set fill draw value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735 205 Set draw color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737 205

x  TABLE OF CONTENTS  3DLDF-1.1.5.1

Color version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 738 205 Color pointer version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 740 206

Set fill color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742 206 Color version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743 206 Color pointer version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 206

Set dash pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747 206 Set pen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749 207 Set connectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 751 207

Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 753 207

Affine transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754 207

Rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 755 207 Rotation around the main axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756 207 Rotatation around an arbitrary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758 208 Transform version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 759 208 Point version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 760 209 Path versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 761 209 Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762 209 Path arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 764 210

Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766 210 Shear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 768 210 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 770 211

real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771 211 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 773 211

Shift times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775 211 real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 776 212 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 778 212

Applying transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 780 212 Multiplying by a Transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781 212 Applying transform to points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783 212

Projection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 785 213 Functions for lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787 213

Alignment with an axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 788 213

For lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789 213 No assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 790 213 With assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792 214

For non-lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794 215

Adding Points to Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796 215 With assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797 215 Without assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799 215

Adding connectors to Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801 216 Concatenating Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 803 216

Versions using “&” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 804 216 With assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805 216 Without assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 810 217

Appending with a connector argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812 218 Drawing and filling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 815 218

Draw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816 218

Path versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 817 219 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 818 219 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 820 220

Point versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 822 220 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823 220

3DLDF-1.1.5.1 TABLE OF CONTENTS xi

Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824 220

Draw arrow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 825 220

Path versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826 220 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827 221 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829 221 Point versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 831 221 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 832 221 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833 222

Draw help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834 222

Path versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 835 222 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 836 222 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838 222 Point versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 840 223 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 841 223 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 842 223

Fill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 843 223 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 844 223 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 846 224

Filldraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848 225 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849 225 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 851 226

Undraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853 227

Path versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 854 227 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855 227 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 857 227 Point versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 859 227 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860 228 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 861 228

Unfill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 862 228

Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 863 228 Unfilldraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 865 229

Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 866 229 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 868 230

Labelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 870 231

Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 871 231 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 872 231 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 874 232

Dotlabel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 876 232 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 877 233 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 879 233

Outputting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 881 233 Extract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882 233 Set extremes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 884 234 Get extremes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 888 236 Get minimum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 889 236 Get maximum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 891 237 Get mean z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893 237 Suppress output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 895 237 Unsuppress output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 897 238 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899 238

Showing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 908 244 Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 909 244

xii  TABLE OF CONTENTS  3DLDF-1.1.5.1

Show Colors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 911 246 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913 246

Is on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914 246 Is planar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 916 246 Is linear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 918 247 Get line switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 920 248 Test for cycles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921 248 Size (number of points) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 922 248 Slope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 923 249 Subpath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925 249 Get point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931 251

non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932 251 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934 252

Get last point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 936 252 Get size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938 253 Get normal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 939 253

Path version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 940 254 Point version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 945 257

Get plane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 946 257 Point lies within triangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948 258

Manipulating Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951 261 Set cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 952 261 Reverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 954 262

With assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 955 262 No assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 959 263

Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961 263 Intersection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 963 264

Intersection of two linear Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 964 264 Intersection of a linear Path with a Plane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 966 265

Drawing axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 967 265 Length argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968 266 Color argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 973 267

Paths and Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975 268 Get Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 976 268 Get Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978 268

Putting Path together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 979 268 Curves (curves.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982 270 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983 270 Regular closed plane curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 984 270 Reg Cl Plane Curve class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 985 270 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986 271

Is quadratic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 987 271 Is cubic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 988 271 Is quartic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 989 271 Get coefficients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 990 271

Solve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 991 271 Location of a point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 992 271 Angle point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994 276 Intersection points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 996 277

Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 997 277 Degenerate cases, error handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 999 278 Parallel and coplanar cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000 278

3DLDF-1.1.5.1 TABLE OF CONTENTS xiii

Coplanar case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001 279 Parallel case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1006 284 Perpendicular and non-coplanar cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1007 284

Path arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1008 284 Reg Cl Plane Curve segments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1010 285

Segment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1011 285 Half . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1013 286 Quarter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1014 286

Putting Reg Cl Plane Curve together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1015 287 Polygon (polygons.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1017 288 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1018 288 Polygon class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1019 288 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1020 289

Get center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1021 289 non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1022 289 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1024 289

Intersections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1026 290

Intersection with a line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1027 290

Point version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1028 290 Degenerate cases, error handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1030 291 Parallel and coplanar cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1031 291 Coplanar case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1032 292 Parallel case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1033 293 Perpendicular and non-coplanar cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1034 294 End of definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1036 295 Path version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037 295

Intersection with another Polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1039 295 Coplanar case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1041 296 Parallel case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1042 296 Non-parallel, non-coplanar case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1043 297

Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1044 298 Applying a transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1045 298 Rotatation around the main axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1047 299 Rotate around an arbitrary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1049 299

Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1050 299 Path argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1052 299

Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1054 300 Shear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1056 300 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1058 300

real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1059 300 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1061 301

Shift times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1063 301

real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1064 301 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1066 301

Reg Polygon (polygons.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1068 302 Reg Polygon class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1069 302 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1070 302 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1072 303

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1073 303 Center, sides, diameter, and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1075 303

Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1076 303 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1079 304

xiv  TABLE OF CONTENTS  3DLDF-1.1.5.1

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1082 305 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1083 305 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1084 305

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1085 305 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1086 305

Get radius . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1087 305 Circles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1088 306 Enclosed circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1089 306 Draw enclosed circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1090 306

Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1091 306 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1092 306 Surrounding circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1093 306

Draw surrounding circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1094 306 Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1095 306 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1096 307

Putting polygons together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097 307 Rectangle (rectangles.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1099 308 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1100 308 Rectangle class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1101 308 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1102 308

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1103 309 Center, lengths, and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1105 309 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1106 309 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1108 310 Four Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1110 310 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1111 311 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1113 311

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1115 312 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1116 312 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1117 312

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1118 312 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1119 312 Returning Elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1121 313

Is rectangular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1122 313 Returning Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1124 314 Corner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1125 314 Get Mid-point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1127 314 Getting axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1129 315 Get axis h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1130 315 Get axis v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1132 315

Ellipses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1134 316 Surrounding Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1135 316 Enclosed Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1136 316 Draw surrounding Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1137 316 Draw enclosed Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1138 316

Putting Rectangle together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1139 316 Ellipse (ellipses.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1141 318 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1142 318 Ellipse class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1143 318 Static data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1144 319 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1145 319

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1146 319

3DLDF-1.1.5.1 TABLE OF CONTENTS xv

Center, lengths, and angles of rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1148 319 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1149 319 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1151 321

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1153 321 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1154 321 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1155 322

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1156 322 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1157 322 Labelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1159 322

Label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1160 322 Dotlabel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1162 323

Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1163 323 Is elliptical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1164 323 Is quadratic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1166 325 Is cubic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1167 325 Is quartic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1169 326 Solve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1171 326 Get coefficients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1174 328 Get center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1176 328

Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1177 329 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1179 329

Get focus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1181 329 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1182 329 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1184 330

Get linear eccentricity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1186 331 Get numerical eccentricity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1188 331 Get axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1190 332

Get vertical axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1191 332 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1192 332 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1194 332 Get horizontal axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1196 332 const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1197 333 Non-const version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1199 333

Angle point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1201 333 Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1203 334 Location of a point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1205 335 Intersection points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1207 336

Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1208 336 Path argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1210 337 Ellipse argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1212 337

Check intersection point locations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1228 355

Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1229 355

Performing a transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1230 355 Do transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1231 356 Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1233 358

Rotation around the main axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1235 358 Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1237 358 Shear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1239 359 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1241 359

real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1242 359 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1244 359

Shift times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1246 360

xvi  TABLE OF CONTENTS  3DLDF-1.1.5.1

real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1247 360 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1249 360

Rotatation around an arbitrary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1251 360 Point arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1252 361 Path arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1254 361

Rectangles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1256 362 Surrounding rectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1257 362 Inscribed rectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1259 363 Draw surrounding rectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1261 364 Draw inscribed rectangle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1263 364

Rectangle functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1265 365

Ellipses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1266 365 Surrounding Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1267 366 Enclosed Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1268 367 Draw surrounding Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1269 367 Draw enclosed Ellipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1270 368

Putting Ellipse together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1271 368 Circle (circles.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1273 369 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1274 369 Circle class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1275 369 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1277 370

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1278 370 Center, diameters and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1280 370

Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1281 370 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1283 371

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1285 372 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1286 372 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1287 372

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1288 372 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1289 372

Circle argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1290 372 Ellipse argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1292 373

Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1294 374 Is circular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1295 374 Get radius . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1297 375 Get diameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1298 375

Intersections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1299 375 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1300 376 Path argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1302 376 Circle argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1304 377

Reg Polygon functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1306 381 Enclosed circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1307 381 Draw enclosed circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1308 381

Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1309 382 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1310 382

Surrounding circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1311 382 Draw surrounding circle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1312 382

Normal version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1313 383 Picture argument first . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1314 383

Putting Circle together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1315 383 Patterns (patterns.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1317 384 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1318 384

3DLDF-1.1.5.1 TABLE OF CONTENTS xvii

Plane tesselations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1319 384

Hexagonal tesselation 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1320 384 patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1322 388

Epicycloid pattern 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1323 388 Epicycloid pattern 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1325 391 Epicycloid pattern 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1326 391

Putting patterns together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1328 393

Solid (solids.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1331 394 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1332 394 Solid class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1333 394 Define static const Solid data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1334 395 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1335 395

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1336 395 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1338 396

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1340 397 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1341 397 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1342 397

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1343 397 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1345 398 Copying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1348 399 Set on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1350 399 Returning elements and information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1352 400

Get center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1353 400 Getting Shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1355 400

Get Shape pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1356 401 Get Circle pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1358 403 Get Ellipse pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1360 403 Get Path pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1362 404 Get Rectangle pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1364 404 Get Reg Polygon pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1366 405

Getting Shape centers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1368 405 Get Shape center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1369 406 Get Circle center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1371 408 Get Ellipse center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1373 408 Get Rectangle center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1375 408 Get Reg Polygon center . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1377 409

Is on free store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1379 409 Show . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1381 409 Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1383 411 Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1385 411

Multiplying by a Transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1386 411 Applying a transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1388 412 Scale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1390 412 Shear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1392 413 Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1394 413

real arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1395 413 Point argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1397 413

Rotatation around the main axes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1399 414 Rotatation around an arbitrary axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1401 414

Outputting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1403 414 Extract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1404 414 Set extremes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1406 416

xviii  TABLE OF CONTENTS  3DLDF-1.1.5.1

Get extremes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1408 418 Get minimum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1409 418 Get maximum z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1411 419 Get mean z . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1413 419 Suppress output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1415 419 Unsuppress output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1417 420 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1419 420

Drawing and filling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1421 421 Draw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1423 422 Fill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1426 424 Filldraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1429 426 Undraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1432 428 Unfill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1435 429 Unfilldraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1438 430

Putting Solid together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1440 431 Solid Faced (solfaced.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1443 432 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1444 432 Solid Faced class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1445 432 Putting Solid Faced together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1448 433 Cuboid (cuboid.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1451 434 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1452 434 Cuboid class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1453 434 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1454 435

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1455 435 Copy constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1457 435 Center, height, width, depth, and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1459 436

Pseudo-constructor for dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1461 437 Pointer argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1462 437 Reference argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1463 437

Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1464 438 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1466 438 Putting Cuboid together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1468 438 Polyhedra (polyhedra.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1470 439 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1471 439 Polyhedron class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1472 439 Intersection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1473 440 Regular Platonic Polyhedra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1475 441 Tetrahedron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1476 441 Tetrahedron class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1477 441 Define static const Tetrahedron data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1478 441 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1479 442

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1480 442 Center, diameter of triangle, and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1482 442 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1483 442 Setting function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1487 445

Get net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1489 445 Draw net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1491 446 Dodecahedron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1493 449 Dodecahedron class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1494 449 Define static const Dodecahedron data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1495 449 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1496 450

3DLDF-1.1.5.1 TABLE OF CONTENTS xix

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1497 450 Center, diameter of pentagon, and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1499 450 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1500 450

Get net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1503 453 Draw net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1505 454 Icosahedron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1507 456 Icosahedron class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1508 456 Define static const Icosahedron data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1509 456 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1510 456

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1511 456 Center, diameter of triangle, and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1513 457 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1514 457

Get net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1516 459 Draw net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1518 461 Semi-Regular Archimedean Polyhedra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1520 463 Truncated Octahedron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1521 463 Trunc Octahedron class definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1522 463 Define static const Trunc Octahedron data members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1523 463 Constructors and setting functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1524 463

Default constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1525 463 Center, diameter of hexagon, and angles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1527 464 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1528 464

Get net . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1530 466 Putting polyhedra together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1533 468 Parsing (parser.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1536 469 Parse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1538 469 Putting the parser together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1540 470 Main (main.web) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1543 471 Include files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1544 471 Get input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1545 472 Actions in main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1546 472 Process command line options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1548 473 Print version, copyright, and license information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1552 476 Main itself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1555 477 Putting Main together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1558 478 Appendices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1559 478 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1560 478 GNU Free Documentation License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1561 479 GNU General Public License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1562 484 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1563 488

§1  3DLDF-1.1.5.1  COPYRIGHT AND LICENSE 1

1. Copyright and License. Copyright \begin{matrix}c \\ ◯ \end{matrix} 2003 Laurence D. Finston.

See the section ⟨ GNU Free Documentation License 1561 ⟩ for the copying conditions that apply to this document.

The program 3DLDF documented here 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 2 of the License, or (at your option) any later version. See the section ⟨ GNU General Public License 1562 ⟩ in this document.

3DLDF 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 3DLDF; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

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://www.gnu.org/3DLDF. It is also available from

http://www.dante.de/software/ctan/, the Dante www-server and from
http://wwwuser.gwgd.de/~lfinsto1, the author’s website.

Please send bug reports to:

bug-3DLDF@gnu.org

The mailing list help-3DLDF@gnu.org is available for people to ask other users for help. The mailing list info-3DLDF@gnu.org is for sending announcements to users. To subscribe to these mailing lists, send an email with “subscribe ⟨email-address⟩” as the subject.

The author can be contacted at:

Laurence D. Finston

Kreuzbergring 41

D-37075 Goettingen

Germany

lfinsto1@gwdg.de

s246794@stud.uni-goettingen.de

  Web site: http:://wwwuser.gwdg.de/~lfinsto1

2. Introduction (3DLDF.web).

This book contains the program code of 3DLDF, along with explanations. For information on using 3DLDF see the 3DLDF User and Reference Manual, which should have been in the distribution along with this book.

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.

In the text sections of the CWEB documentation, I note things about C^{++} that may be of interest even if they are obvious to people with experience.

The various files that make up 3DLDF are ctangled and compiled separately (see the chapter “Compiling” in the 3DLDF User and Reference Manual) and the resulting object files are then linked. However, the file 3DLDF.web, which contains no C^{++} code and is not ctangled, includes the other files, so that cweave processes them as if they were all one file.

2  INTRODUCTION (3DLDF.WEB)  3DLDF-1.1.5.1 §2
To write my  files, I wrote a  for Emacs and a number of Emacs-Lisp functions to go with

it. It is not currently included in the 3DLDF distribution (Version 1.1.5.1), but I may include it in a later version. However, GNU is at work at an official cweb-mode of its own, so you might want to use it instead, if it’s available.

Plurals of types are typeset with the “s” in the same font as the type, e.g., “Points” and not “Points”. It’s not considered good typographical practice to typeset words with letters from different fonts. The second example does have the advantage that it’s somewhat clearer what the actual name of the type is, but I think the first argument is weightier.

See http://www-cs-faculty.stanford.edu/knuth/cweb.html for more information about CWEB. The

WEB (for Pascal) and CWEB packages are available from the CTAN archive, ftp.dante.de and

http:://www.dante.de.

Donald Knuth’s books TEX: The Program and METAFONT: The Program each include a section “How to read a WEB”, which may be helpful.

Log

[LDF 2002.11.18.] Changed name of this file from cweavedriver.web to cwdriver.web. It now has fewer than 8 letters and can be used under DOS.

[LDF 2003.08.16.] Changed name of this file from cwdriver.web to 3DLDF.web sometime since 2002.11.18. Forgot to note it here.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

3. Formatting commands. cweave formats “ ” as “≡”, “ ” as “≠”, and “ ” as “¬”. Programmers who use these tokens must type them as “ ”, “ , and “!”.

The following formatting commands are for types defined in C^{++} or in the C^{++} Standard Library, but not handled correctly by cweave.

format bitset int
format bool int
format bools bool
format ifstream int
format key type int
format mapped type int
format map int
format ofstream int
format stat int
format stringstream int
format numeric limits int
format pair int
format string char
format tm int
format valarray int
format vector int

§4  3DLDF-1.1.5.1  FORMATTING COMMANDS 3

4. This section contains commands for inputting the CWEB source files, which are invisible in the cweave output.

5. Preprocessor variables and library files (loader.web). [LDF 2002.10.15.] It would, of course, be possible to put this code into a file directly, but it’s convenient to have a CWEB file so that it can be along with the rest of 3DLDF.

[LDF 2003.07.18.] Set the preprocessor macro to 1 in order to compile using gcc version 3.3 20030226 (prerelease) (SuSE Linux). Set it to 0 in order to compile using GCC version 2.95.3 20010315 (SuSE). This can be faster than using GCC 3.3, especially with respect to linking.

Log

[LDF 2003.08.21.] Now including plfmvar.h. It contains #define and #undef preprocessor commands for conditional compilation. There’s a different version of this file in each of the subdirectories used for compiling with a different combination of operating system, compiler, and compiler version.

[LDF 2003.07.25.] Modified the conditional constructions governing compilation slightly.

[LDF 2003.08.14.] Now including getopt.h for the GCC versions under Linux. It’s for processing the command line options.

[LDF 2003.08.14.] Now including streambuf.h, if is defined, otherwise ios. This is for stream formatting.

[LDF 2003.08.29.] Removed getopt.h to main.web, because it’s only used there.

[LDF 2003.09.03.] Added #define in order to be able to conditionally include plfmvar.h. The latter is not included in the version for distribution. Instead, the preprocessor variables are defined or undefined here.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

⟨ Version control identifier 5 ⟩ ≡

static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

See also sections 13, 53, 63, 76, 93, 164, 241, 250, 307, 635, 659, 696, 982, 1017, 1099, 1141, 1273, 1317, 1331, 1443, 1451, 1470,

1536, and 1543. This code is used in sections 11, 51, 61, 74, 91, 162, 239, 248, 305, 633, 657, 694, 980, 1015, 1097, 1139, 1271, 1315, 1329, 1441,

1449, 1468, 1534, 1541, and 1558.

6. Configuration file. This section includes config.h, which is generated by . This is new in 3DLDF 1.1. The script generated by Autoconf tests whether certain library files are present, and defines preprocessor variables in config.h accordingly. These can be used for conditionally compiling code, so that library files are only included if they are really present. However, it will be necessary to add code for handling the case that they aren’t present. I haven’t done this yet, although I have put in conditional code using these variables in a couple of places. TO DO: Work on this. [LDF 2003.11.12.]

Autoconf does not per default check the version of the compiler that’s used, and I’m not sure whether this would really be sensible. 3DLDF already contains conditionally compiled code based on whether the DEC C^{++} compiler, or the GNU C^{++} compiler (GCC) version 2.95 or version 3.3 is used. If the DEC compiler is used, the preprocessor variables or must be undefined by hand below. It defines itself. If GCC is used, one of them must be defined, and the other undefined. Per default, is defined and is undefined. This is because GCC 3.3 is, in general, an improvement over GCC 2.95. However, I usually use GCC 2.95 myself, because linking is significantly faster on the computer I use. [LDF 2003.11.12.]

4  CONFIGURATION FILE  3DLDF-1.1.5.1 §6

[LDF 2003.12.17.] config.h is now not included if I’m with the DEC C^{++} compiler. This is because because building with Autoconf, etc., doesn’t work on the DEC Alpha machine I’m using.

⟨ Include files 6 ⟩ ≡ #ifndef #include #endif

See also sections 7, 8, 9, 14, 54, 64, 77, 94, 165, 242, 251, 308, 636, 660, 697, 983, 1018, 1100, 1142, 1274, 1318, 1332, 1444,

1452, 1471, 1537, and 1544. This code is used in sections 12, 51, 61, 74, 91, 162, 239, 248, 305, 633, 657, 694, 980, 1015, 1097, 1139, 1271, 1315, 1329, 1441,

1449, 1468, 1534, 1541, and 1558.

7. Library files.

Log

[LDF 2003.12.17.] Changed the conditional in which , , and are defined or undefined. Working on compiling with the DEC C^{++} compiler.

⟨ Include files 6 ⟩ +≡ #define #ifndef #ifndef #define #endif #define #undef #endif #ifdef #define /∗ Needed for ”sstream” below. ∗/ #endif #include #include #include #ifdef #if #include /∗ [LDF 2002.12.13.] Needed for . ∗/ #endif #endif #include #include #include #ifdef /∗ For stream formatting. [LDF 2003.08.14.] ∗/ #include #else #include #endif #include #include #include #ifdef #include #else

§7  3DLDF-1.1.5.1  LIBRARY FILES 5

#ifdef #include #endif #endif #include #include #include #ifdef #include #endif #ifdef #include #elif #include #endif

8. streambuf.h is included above, if is defined, instead of ios, which is included in all other cases. [LDF 2003.08.14.] ⟨ Include files 6 ⟩ +≡ #include #include #include

9.

Log

[LDF 2003.07.18.] Added “using namespace std ”. This is needed with GCC 3.3, but not with GCC 2.95 or the DEC C++ compiler.

⟨ Include files 6 ⟩ +≡ using namespace std;

10. Putting loader together.

11. This is what’s compiled. It’s not necessary to include stdlib.h when using GCC 3.3, but I think it’s safer. [LDF 2004.01.06.]

Log

[LDF 2004.01.06.] Added this section. It simplifies the rules for building the executable if loader.c is compiled.

#ifdef #include #elif #include #endif #include

using namespace std;

⟨ Version control identifier 5 ⟩

6  PUTTING LOADER TOGETHER  3DLDF-1.1.5.1 §12

12. This is what’s written to the loader.h.

Log

[LDF 2004.01.06.] Added this section.

⟨ 12 ⟩ ≡ ⟨ Include files 6 ⟩

13. Global items (pspglb.web). Typedefs, global variables and constants, and some non-class functions. (pspglb.web.)

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

14. Include files. ⟨ Include files 6 ⟩ +≡ #include #ifdef #include #else #ifdef #include #else #ifdef #if #include #endif #endif #endif #endif #include

15. Type definitions. [LDF 2002.10.15.] Currently, all floating point variables are declared as reals. I’ve defined real in order to make it easy to switch between using floats and doubles simply by changing the value of the #if expression.

I try to avoid using preprocessor commands (see Introduction), but this is one of the cases where there’s no better alternative to using the preprocessor (I don’t consider commenting out the unwanted version preferable to using the preprocessor).

Log

[LDF 2002.04.10.] Added formatting commands.

[LDF 2002.04.10.] Added declaration of bool real.

[LDF 2002.12.11.] Added the macros  and  . They’re needed below,
where  and  are declared in the GNU/Linux version (using GCC).

[LDF 2003.06.03.] Added real short . It’s the return type of Plane ::get distance( ).

§15  3DLDF-1.1.5.1  TYPE DEFINITIONS 7
[LDF 2003.12.30.] Now using # define instead of @d for the definitions of  and  .

If @d is used, the definitions are only written to pspglb.c. Using # define, and writing ⟨ Type definitions 15 ⟩ to pspglb.h makes the definitions available to the files that include pspglb.h.

format real float
format real pair real
format bool pair real pair
format real pair real short
format Matrix int

⟨ Type definitions 15 ⟩ ≡ #define 1 #define 0 #if

typedef float real; #elif

typedef double real; #else /∗ Default. LDF 2003.12.17. ∗/

typedef float real; #endif

typedef real Matrix[4][4]; typedef pair⟨real, real⟩ real pair; typedef pair⟨real, signed short⟩ real short; typedef pair⟨bool, bool⟩ bool pair; typedef pair⟨bool, real⟩ bool real;

See also sections 312, 313, 315, and 317. This code is cited in section 15. This code is used in sections 51, 52, 633, and 634.

16. Utility classes. ⟨ Utility classes 16 ⟩ ≡

struct real triple { real first ; real second ; real third ; real triple( ) : first (0), second (0), third (0) { } real triple(real a, real b, real c) : first (a), second (b), third (c) { }

};

This code is used in sections 51 and 52.

17. Global variables.

18. For compilation. [LDF 2003.08.25.] GCC 2.95 doesn’t have the numeric limits template, and GCC 3.3 doesn’t seem to have it either.

Log

[LDF 2002.12.11.] BUG FIX: Discovered that the way this was before,  =  −
real limits .epsilon( ) caused  and  to be equal! I didn’t notice the problem until

8  FOR COMPILATION  3DLDF-1.1.5.1 §18
I started to port 3DLDF to GNU/Linux. It also doesn’t work to use  =  −

real limits .min( ).

⟨ Global variables 18 ⟩ ≡

valarray⟨real⟩ null coordinates (4);

See also sections 19, 20, 78, 234, 302, and 630. This code is cited in section 25. This code is used in sections 51, 91, 239, 305, and 633.

19.  is the second largest real value.  is convenient to have for testing when

computing distances.

!! KLUDGE: Using the macros or because the numeric limits template doesn’t seem to be available under GNU/Linux using GCC, at least not on the computer I’m using. [LDF 2002.12.11.]

Log

[LDF 2003.12.08.] Changed the definition of . Previously, it was calculated using .00000003 ∗ , which was a kludge.

[LDF 2003.12.29.] Changed the way and are declared. They can no longer be const, because the value of is set at the beginning of main( ) using get second largest < Real > ( ). The value of is set after this. Their values should never change after this!

must be initialized here, because it’s used in Point ::magnitude( ). [LDF 2003.12.29.]

⟨ Global variables 18 ⟩ +≡ #ifdef

numeric limits⟨real⟩ real limits ;

extern const real = real limits .max ( ); #else #if

extern const real  =  ;
#else  /∗  , or not specified. LDF 2003.12.08. ∗/
extern const real  =  ;

#endif #endif

real = 0;

real = 0;

20. [LDF 2003.08.14.] is false by default. It is set to true by the command line option “--verbose”. If is true, the local verbose variables in functions are set to true.

Log

[LDF 2003.08.14.] Added  and  .

§21  3DLDF-1.1.5.1  FOR COMPILATION 9

⟨ Global variables 18 ⟩ +≡ bool = false; bool = false; 21. ⟨ Declarations for the header file 21 ⟩ ≡

extern bool ; extern bool ; extern const bool ldf real float ; extern const bool ldf real double; extern real ; extern real ;

See also sections 23, 26, 29, 235, 237, 303, 320, 631, 655, and 692. This code is cited in section 24. This code is used in sections 52, 240, 306, 634, 658, and 695.

22.

Log

[LDF 2003.08.14.] Added  and  .

⟨ Global constants 22 ⟩ ≡ #if

extern const bool ldf real float = 1; extern const bool ldf real double = 0;

#elif 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  =  ;
extern const string  =  ␣   ␣      ␣    ␣  ␣        ␣   ␣  ;
extern const string  =  ␣     ␣    ␣          ␣  ␣

    ␣       ␣   ␣    ␣    ␣               ␣   ␣      ␣    ␣            ␣   ␣
    ␣  ␣     ␣             ␣  ␣     ␣         ␣   ␣   ␣    ␣          ␣
    ␣  ␣     ␣       ␣                ␣        ␣      ␣    ␣   ␣    ␣
    ␣    ␣   ␣       ␣  ␣   ␣       ␣            ␣␣␣␣                  ␣␣␣␣

    ␣␣␣␣␣␣  ␣                                   ␣     ␣  ;

See also sections 28, 159, 236, and 319. This code is used in sections 51, 162, 239, and 633.

23.

Log

[LDF 2003.11.28.] Changed from a real to a string. This is necessary, because I now have versions with three digits separated by periods.

⟨ Declarations for the header file 21 ⟩ +≡ extern const string ; extern const string ; extern const string ; extern const bool ldf real float ; extern const bool ldf real double; 24. TO DO: Find out why the library version of trunc( ) can’t be found in the version for GCC 2.95 under Linux! [LDF 2002.12.10.]

The problem doesn’t exist for GCC 3.3 under Linux. [LDF 2003.08.14.]

Log

[LDF 2003.08.14.] Put this function declaration in ⟨ Declare utility functions 24 ⟩. Formerly, it was in ⟨ Declarations for the header file 21 ⟩.

Changed the conditional from #ifdef to #ifdef , because the library version of trunc( ) is found when compiling with GCC 3.3 under Linux.

⟨ Declare utility functions 24 ⟩ ≡ #ifdef

double trunc(double d); #endif

See also section 31. This code is cited in section 24. This code is used in section 52.

25.

Log

[LDF 2003.08.14.] Put this function definition into ⟨ Define utility functions 25 ⟩. Formerly, it was in ⟨ Global variables 18 ⟩.

⟨ Define utility functions 25 ⟩ ≡ #ifdef /∗ KLUDGE!! [LDF 2002.12.1.] trunc( ) isn’t available on the Linux machine

gwdg-wb02.gwdg.de! Find out why not! ∗/ double trunc(double d) {

int i;

i = static cast⟨int⟩(d);

return static cast⟨double⟩(i); }

#endif

See also section 32. This code is cited in section 25. This code is used in section 51.

26. For the header file. ⟨ Declarations for the header file 21 ⟩ +≡

extern valarray⟨real⟩ null coordinates ; #ifdef

extern numeric limits⟨real⟩ real limits ; #endif

27. Global constants. is the largest possible real value, where real is either a synonym for float or for double, depending on how it’s defined. Values are set to or functions return it when something has gone wrong. is also used for the real values in and . Another possibility would be to use exception handling, but so far I’ve found it convenient to use instead. Since the largest float is so large, and epsilon( ) for floats is so small, the loss of the largest possible valid value is insignificant. Using exception handling has its advantages, and if it turns out to be useful, I’ll put in exception handling code, but using an otherwise valid value to signal exceptional conditions or errors does have the advantage of simplifying the path of execution through the program code. [LDF 2002.10.16.] Modified [LDF 2002.10.20.]

Log

[LDF 2002.09.25.] Added this section. Previously, I declared and initialized my global constants in the header file. This meant that each compilation unit that loaded pspglb.h had its own version of , , etc. I didn’t know that consts had internal linkage by default and that I could make their linkage external by using extern in the declaration with the initialization, and put a second declaration, also with extern, in the header file. This is what I’ve done now.

[LDF 2003.06.03.] Added .

28. For compilation. ⟨ Global constants 22 ⟩ +≡

extern const real = 4.0 ∗ atan(1.0);

extern const real pair  (  ,  );
extern const real short  (  , 0);

12  FOR THE HEADER FILE  3DLDF-1.1.5.1 §29

29. For the header file. ⟨ Declarations for the header file 21 ⟩ +≡

extern const real ;

extern const real ;

extern const real pair ;

extern const real short ;

30. Utility functions.

31. Solve quadratic equation. [LDF 2002.09.03.] TO DO: Maybe add functions for solving cubic and quartic equations, if this is practicable.

Log

[LDF 2003.06.1.] Changed return type from pair⟨real, real⟩ to real pair, which is equivalent.

⟨ Declare utility functions 24 ⟩ +≡ real pair solve quadratic(real a, real b, real c);

§32  3DLDF-1.1.5.1  SOLVE QUADRATIC EQUATION 13

32. ⟨ Define utility functions 25 ⟩ +≡

real pair solve quadratic(real a, real b, real c) {

real pair p; try {

p.first = (−b + sqrt ((b ∗ b) − (4 ∗ a ∗ c)))/(2 ∗ a); } catch( …) {

p.first = ; } try {

p.second = (−b − sqrt ((b ∗ b) − (4 ∗ a ∗ c)))/(2 ∗ a); } catch( …) {

p.second = ; } return p;

}

33. System information.

Log

[LDF 2003.12.29.] Added this section.

34. Declare namespace System.

Log

[LDF 2003.12.29.] Added this section.

⟨ Declare namespace System 34 ⟩ ≡

namespace System {

⟨ Declare System functions 36 ⟩ }

See also section 65. This code is used in sections 51, 52, 74, and 75.

35. Endianness.

Log

[LDF 2003.12.29.] Added this section.

14  GET ENDIANNESS  3DLDF-1.1.5.1 §36

36. Get endianness. get endianness ( ) 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( ). [LDF 2003.12.21.]

This function has been adapted from Harbison, Samuel P., and Guy L. Steele Jr. C, A Reference Manual, pp. 163–164. [LDF 2003.12.29.]

Log

[LDF 2003.12.29.] Added this function.

⟨ Declare System functions 36 ⟩ ≡

signed short get endianness (const bool verbose = false);

See also sections 38, 40, 43, 45, 47, 66, 71, and 72. This code is used in sections 34, 52, 65, and 75.

37. ⟨ Define System functions 37 ⟩ ≡

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 ≪ ␣ ␣ ≪ endl ≪ endl ≪ flush; return 0;

}

else if (u.Char [sizeof (long) − 1] ≡ 1) { if (verbose) cout ≪ ␣ ␣ ≪ endl ≪ endl ≪ flush; return 1;

} else {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; return −1;

} }

See also sections 39, 41, 44, 46, 48, 67, and 68. This code is used in sections 51, 74, and 75.

38. Is big endian.

Log

[LDF 2003.12.29.] Added this function.

⟨ Declare System functions 36 ⟩ +≡ bool is big endian(const bool verbose = false);

§39  3DLDF-1.1.5.1  IS BIG ENDIAN 15

39. ⟨ Define System functions 37 ⟩ +≡

bool System ::is big endian(const bool verbose) {

return (get endianness (verbose) ≡ 1); }

40. Is little endian.

Log

[LDF 2003.12.29.] Added this function.

⟨ Declare System functions 36 ⟩ +≡ bool is little endian(const bool verbose = false);

41. ⟨ Define System functions 37 ⟩ +≡

bool System ::is little endian(const bool verbose) {

return (get endianness (verbose) ≡ 0); }

42. Register width.

Log

[LDF 2003.12.29.] Added this section.

43. Get register width.

Log

[LDF 2003.12.29.] Added this function. [LDF 2004.1.2.] Changed the name of this function from get processor size( ) to get register width( ).

⟨ Declare System functions 36 ⟩ +≡ unsigned short get register width( );

44. ⟨ Define System functions 37 ⟩ +≡

unsigned short System ::get register width( ) {

return (sizeof (void ∗) ∗ ); }

45. Is 32 bit.

Log

[LDF 2003.12.29.] Added this function.

⟨ Declare System functions 36 ⟩ +≡ bool is 32 bit ( );

16  IS 32 BIT  3DLDF-1.1.5.1 §46

46. ⟨ Define System functions 37 ⟩ +≡

bool System ::is 32 bit ( ) {

return (get register width( ) ≡ 32); }

47. Is 64 bit.

Log

[LDF 2003.12.29.] Added this function.

⟨ Declare System functions 36 ⟩ +≡ bool is 64 bit ( );

48. ⟨ Define System functions 37 ⟩ +≡

bool System ::is 64 bit ( ) {

return (get register width( ) ≡ 64); }

49. Forward declarations. [LDF 2002.10.16.] In the files that are compiled first, some classes refer to other classes that haven’t been defined yet. Forward declarations make it possible to do this. TO DO: GET CITATION from Stroustrup.

Log

[LDF 2002.04.10.] Added the forward declaration of bool real point. It’s needed because it’s used as the return value of Point ::intersection point ( ), which is, of course, declared within the declaration of class Point. However, bool real point can only be defined after Point is defined. This forward declaration solves the problem.

[LDF 2003.07.16.] Added forward declaration of Ellipse. It’s needed, because I’ve declared Ellipse to be a friend of Path. Formerly, Circle was a friend of Path, but now it must be Ellipse, because I’ve made the “segment” functions segment ( ), half ( ), and quarter ( ) members of Ellipse instead of Circle.

⟨ Forward declarations 49 ⟩ ≡ struct bool point; struct bool real point; class Circle; class Ellipse; struct Focus; struct Line; class Path; class Picture; struct Plane; class Point;

This code is used in sections 51 and 52.

50. Putting pspglb together.

§51  3DLDF-1.1.5.1  PUTTING PSPGLB TOGETHER 17

51. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Type definitions 15 ⟩ ⟨ Utility classes 16 ⟩ ⟨ Global variables 18 ⟩ ⟨ Global constants 22 ⟩ ⟨ Define utility functions 25 ⟩ ⟨ Declare namespace System 34 ⟩ ⟨ Define System functions 37 ⟩ ⟨ Forward declarations 49 ⟩

52. This is what’s written to the pspglb.h. ⟨ 52 ⟩ ≡

⟨ Type definitions 15 ⟩ ⟨ Utility classes 16 ⟩ ⟨ Declarations for the header file 21 ⟩ ⟨ Declare namespace System 34 ⟩

/∗ This doesn’t work, apparently because it’s incompatible with the use of sstream. ∗/ #if 0 #ifdef /∗ Using the DEC C^{++} Compiler. ∗/

const real = ; #endif #endif

⟨ Declare utility functions 24 ⟩ ⟨ Forward declarations 49 ⟩ ⟨ Declare System functions 36 ⟩

53. Dynamic allocation for Shapes.

Log

[LDF 2003.12.29.] Added this template function. [LDF 2004.1.2.] Moved the code in this file from pspglb.web to creatnew.web.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

54. Include files. ⟨ Include files 6 ⟩ +≡ #include #include

55. Dynamic allocation for Shapes.

56. Pointer argument. ⟨ Declare create new ( ) 56 ⟩ ≡

template⟨class C⟩ C∗create new (const C∗arg );

See also section 58.

18  POINTER ARGUMENT  3DLDF-1.1.5.1 §57

57. ⟨ Define create new ( ) 57 ⟩ ≡

template⟨class C⟩ C∗create new (const C∗arg )

{ C ∗ obj = new(C); obj set on free store( ); if (arg ≠ 0) ∗obj = ∗arg ; return obj ;

}

See also section 59. This code is used in sections 61 and 62.

58. Reference argument. ⟨ Declare create new ( ) 56 ⟩ +≡

template⟨class C⟩ C∗create new (const C&arg );

59. ⟨ Define create new ( ) 57 ⟩ +≡

template⟨class C⟩ C∗create new (const C&arg )

{ C ∗ obj = new(C); obj set on free store( ); ∗obj = arg ; return obj ;

}

60. Putting creatnew together.

61. This is what’s compiled. I don’t really need to compile the definition of create new ( ) here, because it must be included in all of the files that instantiate it, anyway. However, that may become unnecessary later, in which case it will have to be compiled here. In addition, if there’s something wrong with the definition, it may be helpful to catch the error here. [LDF 2004.1.2.]

⟨ Include files 6 ⟩

⟨ Version control identifier 5 ⟩

⟨ Define create new ( ) 57 ⟩

§62  3DLDF-1.1.5.1  PUTTING CREATNEW TOGETHER 19

62. This is what’s written to the creatnew.h. The file creatnew.h must be included by all files that define specializations of create new ( ). [LDF 2003.12.29.] ⟨ 62 ⟩ ≡

⟨ Define create new ( ) 57 ⟩

63. Get second-largest real value. ⟨ Version control identifier 5 ⟩ +≡

static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

64. Include files. ⟨ Include files 6 ⟩ +≡ #include #include

65. Declare namespace System.

Log

[LDF 2004.1.2.] Added this section.

⟨ Declare namespace System 34 ⟩ +≡

namespace System {

⟨ Declare System functions 36 ⟩ }

66. Get second largest. This function calculates the second-largest real value. It should be called using float or double as a parameter, e.g., get second largest < float > ( ) or get second largest < double > ( ). or must be passed as an argument. On systems with the numeric limits template, real limits .max ( ) could be used instead. [LDF 2003.12.29.]

get second largest ( ) determines which unsigned integral type has the same size as the template parameter Real . The locally declared type i type is defined to be a synonym for this type using typedef . ip is a pointer to i type. It is assigned a value by casting a pointer to to the type of ip, i.e., a pointer to i type. Then, 1 is subtracted from ∗ip, and the ip is cast back to a pointer to Real . This is the second largest Real value. [LDF 2003.12.29.]

This algorithm works on all of the machines I’ve tested. It doesn’t matter whether they are big or littleendian, whether they have 32 or 64-bit processors. If the exponent of a floating point type is stored in its low order byte or bytes, then this will fail. I haven’t run into this problem yet, though. The commented-out code in ⟨ Loop for testing bits 70 ⟩ may help in finding the second-largest Real value in this case. [LDF 2003.12.29.]

Log

[LDF 2003.12.29.] Added this function.

[LDF 2004.1.2.] Moved this section from pspglb.web to creatnew.web.

⟨ Declare System functions 36 ⟩ +≡ template⟨class Real ⟩ Real get second largest (Real , bool verbose = false); float get second largest (float, bool); double get second largest (double, bool);

67. ⟨ Define System functions 37 ⟩ +≡

20  GET SECOND LARGEST  3DLDF-1.1.5.1 §68

68. ⟨ Define System functions 37 ⟩ +≡

template⟨class Real ⟩Real System ::get second largest (Real , bool verbose) {

const unsigned short = sizeof (unsigned short); const unsigned short = sizeof (unsigned int); const unsigned short = sizeof (unsigned long); const unsigned short = sizeof (unsigned long long); const unsigned short Real SIZE = sizeof (Real ); const unsigned short = sizeof (float); const unsigned short = sizeof (double); const unsigned short = sizeof (long double); const bool Real EQ USHORT = (Real SIZE ≡ ); const bool Real EQ UINT = (Real SIZE ≡ ); const bool Real EQ ULONG = (Real SIZE ≡ ); const bool Real EQ ULONG LONG = (Real SIZE ≡ ); if (verbose) {

cout ≪  ␣␣  ␣ ≪  ≪ endl ≪ flush;
cout ≪  ␣␣  ␣ ≪  ≪ endl ≪ flush;
cout ≪  ␣  ␣ ≪  ≪ endl ≪ flush;
cout ≪  ␣  ␣ ≪  ≪ endl ≪ flush;
cout ≪  ␣␣  ␣ ≪  ≪ endl ≪ flush;
cout ≪  ␣␣  ␣ ≪  ≪ endl ≪ flush;
cout ≪  ␣␣  ␣ ≪  ≪ endl ≪ flush;

cout ≪ ␣␣ ␣ ≪ Real SIZE ≪ endl ≪ flush; } Real ∗ rp; if (Real EQ USHORT ) {

if (verbose) cout ≪ ;

typedef unsigned short i type;

⟨ Calculate second-largest Real 69 ⟩ } else if (Real EQ UINT ) {

if (verbose) cout ≪ ␣ ;

typedef unsigned int i type;

⟨ Calculate second-largest Real 69 ⟩ } else if (Real EQ ULONG ) {

if (verbose) cout ≪ ␣ ;

typedef unsigned long i type;

⟨ Calculate second-largest Real 69 ⟩ } else if (Real EQ ULONG LONG ) {

if (verbose) cout ≪ ;

typedef unsigned long long i type;

⟨ Calculate second-largest Real 69 ⟩ } else {

§68  3DLDF-1.1.5.1  GET SECOND LARGEST 21

    cerr ≪  ␣  ␣  ≪  ␣    ␣        ␣    ␣   ␣    ␣     ␣ ≪

        ␣   ␣        ␣        ␣  ≪  ␣    ␣  ␣    ␣  ≪

␣ ␣ ␣ ␣ ≪ flush;

return −1; } if (verbose) {

cout .precision(25);

cout ≪  ␣  ␣ ≪  ≪ endl ≪  ␣  ␣ ≪ ∗rp ≪ endl ≪
␣  ␣    ␣   ␣ ≪ (  ≡ ∗rp) ≪ endl ≪  ␣ ␣    ␣  ␣ ≪
(  − ∗rp) ≪ endl ≪  ␣ ␣   ␣  ␣ ≪ (  > ∗rp) ≪ endl ≪

␣ ␣ ␣ ␣ ≪ ( < ∗rp) ≪ endl ≪ flush; } if ( ≡ ∗rp) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; exit (1);

}

else if ( < ∗rp) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; exit (1);

}

return ∗rp; }

69. Calculate second-largest Real. ⟨ Calculate second-largest Real 69 ⟩ ≡

{ i type ∗ip = reinterpret cast⟨i type ∗⟩(& ); if (verbose) cout ≪ ␣ ␣ ≪ ∗ip ≪ endl ≪ flush; i type bit pattern i type; i type result ; bit pattern i type = 1; bitset⟨sizeof (i type) ∗ ⟩ b; b = ∗ip; if (verbose) cout ≪ ␣ ␣ ␣ ≪ b ≪ endl ≪ flush; b = bit pattern i type; if (verbose) cout ≪ ␣ ␣ ␣ ≪ b ≪ endl ≪ flush; result = bit pattern i type ⊕ ∗ip; if (verbose) cout ≪ ␣ ␣ ≪ result ≪ endl ≪ flush; b = result ; if (verbose) cout ≪ ␣ ␣ ␣ ≪ b ≪ endl ≪ flush; rp = reinterpret cast ⟨ Real ∗> (&result ); if (verbose) cout ≪ ␣ ␣ ≪ ∗rp ≪ endl ≪ flush; }

This code is used in section 68.

22  LOOP FOR TESTING BITS  3DLDF-1.1.5.1 §70

70. Loop for testing bits. ⟨ Loop for testing bits 70 ⟩ ≡ #if 0

int counter ; for (int i = 0; i < (sizeof (Real ) ∗ ); ^{++}i) { if (verbose) cout ≪ ␣ ␣ ≪ i ≪ endl ≪ flush; /∗ This has only been needed on the DEC Alpha,

so far. ∗/ /∗ This is the case that the highest-order bit of the ∗/ /∗ mantissa is 1, and all of the other bits (in particular, ∗/ /∗ all the bits of the exponent) are 0. In this case, ∗rp ∗/ /∗ is not a number (NAN). The GNU compiler copes with this, ∗/ /∗ the DEC compiler signals a floating point error and dumps ∗/ /∗ core (I believe). I wasn’t able to catch the error with

∗/  /∗ try and catch. ∗/  /∗ START HERE. Change (8 + 1) to (  + 1), except ∗/
/∗  ∗/  /∗ isn’t the right name. Find it, and put here. This ∗/

/∗ assumes the exponent is at the left, which may not be ∗/ /∗ true. Skipping this bit pattern

is necessary on the DEC ∗/ /∗ ALPHA, because the float is not a number. ∗/ /∗ It must be 23 for float, and 52 for double. ∗/

if (i ≡ (sizeof (Real ) ∗ ) − (12)) { if (verbose) cout ≪ ␣ ␣ ≪ i ≪ ␣␣ ␣ ␣ ␣␣ ≪ flush; continue;

} bit pattern i type = 1; bit pattern i type ≪= i; if (verbose)

cout ≪ ␣ ␣ ␣ ≪ i ≪ ␣ ␣ ≪ bit pattern i type ≪ endl ≪ flush; b = bit pattern i type; if (verbose) cout ≪ ␣ ␣ ␣ ≪ b ≪ endl ≪ flush; result = bit pattern i type ⊕ ∗ip; if (verbose) cout ≪ ␣ ␣ ≪ result ≪ endl ≪ flush; b = result ; if (verbose) cout ≪ ␣ ␣ ␣ ≪ b ≪ endl ≪ flush; rp = reinterpret cast ⟨ Real ∗> (&result ); if (verbose) cout ≪ ␣ ␣ ≪ ∗rp ≪ endl ≪ flush; if (∗rp ≤ 0) {

if (verbose) cout ≪ ␣ ␣ ≪ flush;

continue; } else if (∗rp ≥ ) {

if (verbose) cout ≪ ␣ ␣␣ ≪ endl ≪ flush;

continue; } else if (second largest real ≥ ∗rp) {

if (verbose) cout ≪ ␣ ␣ ≪ ≪ flush; continue;

} else if (∗rp > second largest real ∧ ∗rp < ) {

if (verbose) cout ≪  ␣ ␣                   ␣  ␣ ≪  ␣ ␣  ≪ endl ≪
␣                   ␣  ␣  ≪ ␣   ␣       ␣  ␣ ␣ ≪ i ≪  ≪ flush;

second largest real = ∗rp;

counter = i; } else {

if (verbose) cout ≪ ␣ ␣ ␣ ;

continue; }

§70  3DLDF-1.1.5.1  LOOP FOR TESTING BITS 23

} /∗ for ∗/ #endif

This code is cited in section 66.

71. Template function instantiations.

Log

[LDF 2003.12.29.] Added this section.

⟨ Declare System functions 36 ⟩ +≡ float get second largest (float , bool verbose);

72. ⟨ Declare System functions 36 ⟩ +≡

double get second largest (double , bool verbose);

73. Putting gsltmplt together.

74. This is what’s compiled. I don’t really need to compile the definition of get second largest ( ) here, because it must be included in all of the files that instantiate it, anyway. However, that may become unnecessary later, in which case it will have to be compiled here. In addition, if there’s something wrong with the definition, it may be helpful to catch the error here. [LDF 2004.1.2.]

⟨ Include files 6 ⟩

⟨ Version control identifier 5 ⟩

⟨ Declare namespace System 34 ⟩

⟨ Define System functions 37 ⟩

24  PUTTING GSLTMPLT TOGETHER  3DLDF-1.1.5.1 §75

75. This is what’s written to the gsltmplt.h. The file gsltmplt.h must be included by all files that define specializations of get second largest ( ). [LDF 2003.12.29.] ⟨ 75 ⟩ ≡

⟨ Declare namespace System 34 ⟩

⟨ Declare System functions 36 ⟩

⟨ Define System functions 37 ⟩

76. I/O (io.web).

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

77. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include

78. Global variables. [LDF 2002.10.16.] in stream is an input stream attached to a file with user code for input. Currently, it is used, but it fulfills no useful function, because I haven’t defined an input routine yet. out stream is an output stream attached to the file of METAPOST code that 3DLDF currently produces as its output. tex stream is an output stream attached to a file of TEX code. The user can write TEX code to this file and load it into persp.tex or use it for some other purpose. 3DLDF makes no use of it itself.

Log

[LDF 2002.08.30.] Added tex stream so that I can include TEX code in my user code. Code written by 3DLDF to tex stream will be loaded by persp.tex, or whatever TEX file includes the PostScript file generated by METAPOST from the output of 3DLDF. User code is currently in main.web. In production versions user code will be in user.web.

[LDF 2003.07.16.] Added fig num.

format ifstream int
format ofstream int

⟨ Global variables 18 ⟩ +≡ ifstream in stream; ofstream out stream; ofstream tex stream; unsigned short fig num;

§79  3DLDF-1.1.5.1  GLOBAL VARIABLES 25

79. extern declarations for the global variables. ⟨ extern variable declarations 79 ⟩ ≡

extern ifstream in stream;

extern ofstream out stream;

extern ofstream tex stream;

extern unsigned short fig num;

This code is used in section 92.

80. I/O functions.

81. Initialize I/O.

Log

[LDF 2003.08.29.] Changed, so that in stream isn’t opened.

⟨ Declare I/O functions 81 ⟩ ≡

void initialize io(string in stream name, string out stream name, string tex stream name, char

∗program name);

See also sections 84, 86, and 88. This code is used in section 92.

82. ⟨ Define I/O functions 82 ⟩ ≡

void initialize io(string in stream name, string out stream name, string tex stream name, char

∗program name){ time t tt ; tm ∗lt ; tt = time(0); lt = localtime(&tt ); string datestamp(asctime(lt )); datestamp.erase(datestamp.size( ) − 1); /∗ Remove terminal line-feed. ∗/

See also sections 83, 85, 87, and 89. This code is used in section 91.

26  INITIALIZE I/O  3DLDF-1.1.5.1 §83

83. Open out stream and tex stream. in stream is currently not opened. [LDF 2003.08.29.] ⟨ Define I/O functions 82 ⟩ +≡ #if 0

in stream.open(in stream name.c str ( )); #endif

out stream.open(out stream name.c str ( )); #ifdef

out stream.setf (ios base ::fixed , ios base ::floatfield ); #else #ifdef

out stream.setf (ios ::fixed , ios ::floatfield ); #endif #endif

tex stream.open(tex stream name.c str ( )); /∗ Write datestamp to out stream. ∗/

out stream ≪  ␣    ␣  ␣ ≪ out stream name ≪  ≪ endl ≪  ␣         ␣  ␣ ≪
datestamp ≪ ␣    ␣ ≪ program name ≪  ;  /∗ Write datestamp to tex stream. ∗/
tex stream ≪  ␣    ␣  ␣ ≪ tex stream name ≪  ≪ endl ≪  ␣         ␣  ␣ ≪

datestamp ≪ ␣ ␣ ≪ program name ≪ ; }

84. Write footers. [LDF 2002.10.16.] Footers can be written to output stream and tex stream. I use them for Local Variables lists for Emacs. Other users may not want this, which is why this code is commented out here. ⟨ Declare I/O functions 81 ⟩ +≡

void write footers ( );

§85  3DLDF-1.1.5.1  WRITE FOOTERS 27

85. ⟨ Define I/O functions 82 ⟩ +≡

void write footers ( ) {

#if 0

out stream ≪ endl ≪ endl ≪ ␣ ≪ ␣ ≪ endl ≪ ␣ ≪ endl ≪ ␣ ␣ ␣ ␣ ␣ ≪

endl ≪  ␣                   ␣  ≪ endl ≪
␣                   ␣    ␣  ≪ endl ≪ ␣  ≪
endl ≪  ␣  ≪ endl ≪
␣  ≪ endl ≪ ␣  ≪

endl ≪ ␣ ≪ endl ≪ endl ;

tex stream ≪  ␣ ≪  ␣  ≪  ␣  ≪

␣                   ␣    ␣  ≪ ␣  ≪
␣  ≪ ␣  ≪
␣  ≪ ␣  ;

#endif

return; }

86. Begin figure.

Log

[LDF 2003.07.16.] Added silent argument, and a message printed conditionally to stdout , saying which figure is being started. This should help in finding where errors occur.

[LDF 2003.07.16.] Made non-inline. [LDF 2003.08.17.] Made silent non-const. Setting it to true, if is true.

⟨ Declare I/O functions 81 ⟩ +≡ void beginfig (unsigned short i, bool silent = false);

28  BEGIN FIGURE  3DLDF-1.1.5.1 §87

87. ⟨ Define I/O functions 82 ⟩ +≡

void beginfig (unsigned short i, bool silent ) {

if ( ) silent = true;

fig num = i;

out stream ≪  ≪ fig num ≪  ;
if (¬silent ) cout ≪  ␣      ␣ ≪ fig num ≪  ≪ endl ≪ flush;

return; }

88. End figure. The unsigned short argument is “syntactic sugar”. It’s ignored by endfig ( ), but may be convenient for a user for keeping track of what figure is being ended.

Log

[LDF 2003.07.16.] Added silent argument, and a message printed conditionally to stdout , saying which figure is being ended. This should help in finding where errors occur.

[LDF 2003.07.16.] Made non-inline. [LDF 2003.08.17.] Made silent non-const. Setting it to true, if is true.

⟨ Declare I/O functions 81 ⟩ +≡ void endfig (unsigned short i = 0, bool silent = false);

89. ⟨ Define I/O functions 82 ⟩ +≡

void endfig (unsigned short i, bool silent ) {

if ( ) silent = true;

out stream ≪  ≪  ;
if (¬silent ) cout ≪  ␣      ␣ ≪ fig num ≪  ≪ endl ≪ endl ≪ flush;

return; }

90. Putting I/O together.

91. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Global variables 18 ⟩ ⟨ Define I/O functions 82 ⟩

§92  3DLDF-1.1.5.1  PUTTING I/O TOGETHER 29

92. This is what’s written to io.h. ⟨ 92 ⟩ ≡

⟨ extern variable declarations 79 ⟩

⟨ Declare I/O functions 81 ⟩

93. Color (colors.web).

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

94. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include

95. Color class definition. [LDF 2002.09.25.] !! Remember to change the constructors, setting functions, and assignment operator if I add or change anything here!!

Log

[LDF 2002.10.06.] Added. on free store.

⟨ Define class Color 95 ⟩ ≡

class Color { string name; bool use name; bool on free store; real red part ; real green part ; real blue part ;

public: ⟨ Declare Color functions 97 ⟩

};

This code is used in sections 162 and 163.

96. Constructors and setting functions.

97. Default constructor. [LDF 2002.10.06.] Added code to definition. Previously, it was empty. ⟨ Declare Color functions 97 ⟩ ≡

Color( );

and 151. This code is used in section 95.

See also sections 99, 102, 104, 107, 109, 114, 116, 118, 121, 123, 125, 127, 129, 131, 133, 135, 138, 141, 142, 143, 144, 146, 149,

30  DEFAULT CONSTRUCTOR  3DLDF-1.1.5.1 §98

98. ⟨ Define Color functions 98 ⟩ ≡

Color ::Color( ) {

red part = green part = blue part = 0.0; name = ; use name = false; on free store = false;

}

See also sections 100, 103, 105, 108, 110, 115, 117, 119, 122, 124, 126, 128, 130, 132, 134, 136, 139, 145, 150, and 152. This code is used in section 162.

99. Copy constructor. !! Remember to add or change code here if I add or change anything in the class definition!!

Log

[LDF 2002.09.25.] Added this function.

⟨ Declare Color functions 97 ⟩ +≡ Color(const Color &c, const string n = , const bool u = true);

100. ⟨ Define Color functions 98 ⟩ +≡

Color ::Color(const Color &c, const string n, const bool u) {

name = n; red part = c.get red part ( ); green part = c.get green part ( ); blue part = c.get blue part ( ); if (n ≠ ∧ u ≡ true) {

use name = true; } else use name = false; on free store = false; /∗ LDF 2002.10.06. Added. ∗/ return;

}

101. Name and unsigned short arguments.

102. Constructor. ⟨ Declare Color functions 97 ⟩ +≡

§103  3DLDF-1.1.5.1  CONSTRUCTOR 31

Color(const string n, const unsigned short r, const unsigned short g, const unsigned short b, const bool u = true); 103. ⟨ Define Color functions 98 ⟩ +≡

Color ::Color(const string n, const unsigned short r, const unsigned short g, const unsigned

short b, const bool u)

: name(n) { name = n; if (n ≠ ∧ u ≡ true) { use name = true;

}

else use name = false;

on free store = false; /∗ LDF 2002.10.06. Added. ∗/ red part = r/255.0; green part = g/255.0; blue part = b/255.0;

}

104. Setting function. ⟨ Declare Color functions 97 ⟩ +≡

void set (const string n, const unsigned short r, const unsigned short g, const unsigned short b, const bool u = false);

105. ⟨ Define Color functions 98 ⟩ +≡

void Color ::set (const string n, const unsigned short r, const unsigned short g, const unsigned

short b, const bool u)

{ name = n; if (n ≠ ∧ u ≡ true) { use name = true;

}

else use name = false; red part = r/255.0; green part = g/255.0; blue part = b/255.0;

}

106. Three real arguments. [LDF 2002.10.09.] Added the following constructor and setting function. They are for unnamed Colors. The DEC compiler can’t distinguish between real and unsigned short arguments, so the overloaded functions must differ in another way. In this case, these versions have no name argument. I believe that users are most likely to declare Colors using real arguments when they plan to modify them, in which case the output ( ) function should write the red, green and blue values to out stream rather than name. If it turns out to be necessary, more constructors can be added or the existing ones can be changed.

107. Constructor. ⟨ Declare Color functions 97 ⟩ +≡

32  CONSTRUCTOR  3DLDF-1.1.5.1 §108

Color(const real r, const real g, const real b); 108. ⟨ Define Color functions 98 ⟩ +≡

Color ::Color(const real r, const real g, const real b) {

name = ; use name = false; on free store = false; if (r < 0) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣        ␣  ␣  ;

red part = 0; } else if (r > 1) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣        ␣  ␣  ;

red part = 1; } else red part = r; if (g < 0) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣ ␣  ␣␣       ␣          ␣  ␣  ;

green part = 0; } else if (g > 1) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣ ␣  ␣␣       ␣          ␣  ␣  ;

green part = 1; } else green part = g; if (b < 0) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣         ␣  ␣  ;

blue part = 0; } else if (b > 1) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣         ␣  ␣  ;

blue part = 1; } else blue part = b; return;

}

109. Setting function. ⟨ Declare Color functions 97 ⟩ +≡

§110  3DLDF-1.1.5.1  SETTING FUNCTION 33

void set (const real r, const real g, const real b); 110. ⟨ Define Color functions 98 ⟩ +≡

void Color ::set (const real r, const real g, const real b) {

name = ; use name = false; on free store = false; if (r < 0) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣        ␣  ␣  ;

red part = 0; } else if (r > 1) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣        ␣  ␣  ;

red part = 1; } else red part = r; if (g < 0) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣ ␣  ␣␣       ␣          ␣  ␣  ;

green part = 0; } else if (g > 1) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣ ␣  ␣␣       ␣          ␣  ␣  ;

green part = 1; } else green part = g; if (b < 0) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣         ␣  ␣  ;

blue part = 0; } else if (b > 1) {

cerr ≪  ␣  ␣              ␣      ␣    ␣  ≪

      ␣    ␣        ␣  ␣  ␣␣       ␣         ␣  ␣  ;

blue part = 1; } else blue part = b;

}

111. Pseudo-constructor for dynamic allocation.

Log

[LDF 2003.12.30.] Replaced Color ::create new color ( ) with specializations of template⟨class C⟩ C∗create new ( ).

112. Pointer argument. ⟨ Declare non-member template functions for Color 112 ⟩ ≡

Color ∗create new (const Color ∗c);

See also section 113. This code is used in sections 162 and 163.

113. Reference argument.

Log

[LDF 2004.1.2.] Added this declaration.

⟨ Declare non-member template functions for Color 112 ⟩ +≡ Color ∗create new (const Color &c);

114. Assignment. [LDF 2002.09.24.] Added this operator function. ⟨ Declare Color functions 97 ⟩ +≡

void operator=(const Color &c);

115. ⟨ Define Color functions 98 ⟩ +≡

void Color ::operator=(const Color &c)

{ name = ; use name = false; red part = c.red part ; green part = c.green part ; blue part = c.blue part ;

}

116. Equality. [LDF 2002.09.25.] Changed so that only red part , green part and blue part are compared. This way, Colors that differ only in name and/or use name are considered to be equal. [LDF 2002.09.24.] Added this operator function. ⟨ Declare Color functions 97 ⟩ +≡

bool operator≡(const Color &c) const;

117. ⟨ Define Color functions 98 ⟩ +≡

bool Color ::operator≡(const Color &c) const {

return ((red part ≡ c.red part ) ∧ (green part ≡ c.green part ) ∧ (blue part ≡ c.blue part )); }

118. Inequality. [LDF 2002.09.24.] Added this operator function. ⟨ Declare Color functions 97 ⟩ +≡

§119  3DLDF-1.1.5.1  INEQUALITY 35

bool operator≠(const Color &c) const; 119. ⟨ Define Color functions 98 ⟩ +≡

bool Color ::operator≠(const Color &c) const

{

return ¬(∗this ≡ c); }

120. Modifying.

121. Set on free store.

Log

[LDF 2003.12.30.] Added this function.

⟨ Declare Color functions 97 ⟩ +≡ bool set on free store(bool b = true);

122. ⟨ Define Color functions 98 ⟩ +≡

bool Color ::set on free store(bool b)

{ on free store = b; return b;

}

123. Set name. ⟨ Declare Color functions 97 ⟩ +≡

void set name(const string s);

124. ⟨ Define Color functions 98 ⟩ +≡

void Color ::set name(const string s)

{

name = s; }

125. Set use name. ⟨ Declare Color functions 97 ⟩ +≡

void set use name(const bool b);

126. ⟨ Define Color functions 98 ⟩ +≡

void Color ::set use name(const bool b)

{

use name = b; }

127. Modify. ⟨ Declare Color functions 97 ⟩ +≡

void modify (const real r, const real g = 0, const real b = 0);

36  MODIFY  3DLDF-1.1.5.1 §128

128. ⟨ Define Color functions 98 ⟩ +≡

void Color ::modify (const real r, const real g, const real b) {

red part += r; green part += g; blue part += b; if (red part > 1) {

cerr ≪  ␣  ␣  ≪  ␣  ␣        ␣    ␣  ␣ ≪ red part ≪
endl ≪  ␣        ␣   ␣  ;

red part = 1; } else if (red part < 0) {

cerr ≪  ␣  ␣  ≪  ␣  ␣    ␣     ␣  ␣ ≪ red part ≪
endl ≪  ␣        ␣   ␣  ;

red part = 0; } if (green part > 1) {

  cerr ≪  ␣  ␣  ≪  ␣  ␣        ␣    ␣  ␣ ≪

green part ≪ endl ≪  ␣          ␣   ␣  ;

green part = 1; } else if (green part < 0) {

cerr ≪  ␣  ␣  ≪  ␣  ␣    ␣     ␣  ␣ ≪ green part ≪
endl ≪  ␣          ␣   ␣  ;

green part = 0; } if (blue part > 1) {

  cerr ≪  ␣  ␣  ≪  ␣  ␣        ␣    ␣  ␣ ≪

blue part ≪ endl ≪  ␣         ␣   ␣  ;

blue part = 1; } else if (blue part < 0) {

cerr ≪  ␣  ␣  ≪  ␣  ␣    ␣     ␣  ␣ ≪ blue part ≪
endl ≪  ␣         ␣   ␣  ;

blue part = 0; } return;

}

129. Set red part. ⟨ Declare Color functions 97 ⟩ +≡

void set red part (const real r);

§130  3DLDF-1.1.5.1  SET RED PART 37

130. ⟨ Define Color functions 98 ⟩ +≡

void Color ::set red part (const real r) {

if (r > 1) {

cerr ≪  ␣  ␣  ≪ ␣  ␣       ␣    ␣   ␣ ≪ r ≪ endl ≪

      ␣        ␣   ␣  ;

red part = 1; } else if (r < 0) {

cerr ≪  ␣  ␣  ≪ ␣  ␣    ␣    ␣  ␣ ≪ r ≪ endl ≪

      ␣        ␣   ␣  ;

red part = 0; } else red part = r; return;

}

131. Set green part. ⟨ Declare Color functions 97 ⟩ +≡

void set green part (const real g);

132. ⟨ Define Color functions 98 ⟩ +≡

void Color ::set green part (const real g) {

if (g > 1) {

cerr ≪  ␣  ␣  ≪ ␣  ␣       ␣    ␣   ␣ ≪ g ≪
endl ≪  ␣          ␣   ␣  ;

green part = 1; } else if (g < 0) {

cerr ≪  ␣  ␣  ≪ ␣  ␣    ␣    ␣  ␣ ≪ g ≪ endl ≪

      ␣          ␣   ␣  ;

green part = 0; } else green part = g; return;

}

133. Set blue part. ⟨ Declare Color functions 97 ⟩ +≡

void set blue part (const real b);

38  SET BLUE PART  3DLDF-1.1.5.1 §134

134. ⟨ Define Color functions 98 ⟩ +≡

void Color ::set blue part (const real b) {

if (b > 1) {

cerr ≪  ␣  ␣  ≪ ␣  ␣       ␣    ␣   ␣ ≪ b ≪
endl ≪  ␣         ␣   ␣  ;

blue part = 1; } else if (b < 0) {

cerr ≪  ␣  ␣  ≪ ␣  ␣    ␣    ␣  ␣ ≪ b ≪ endl ≪

      ␣         ␣   ␣  ;

blue part = 0; } else blue part = b; return;

}

135. Show. ⟨ Declare Color functions 97 ⟩ +≡

void show (string text = ) const;

136. ⟨ Define Color functions 98 ⟩ +≡

void Color ::show (string text ) const {

if (text ≡ ) text = ; cout ≪ text ≪ endl ; cout ≪ ␣ ␣ ≪ get name( ) ≪ endl ; cout ≪ ␣ ␣ ≪ get use name( ) ≪ endl ; cout ≪ ␣ ␣ ≪ get red part ( ) ≪ endl ; cout ≪ ␣ ␣ ≪ get green part ( ) ≪ endl ; cout ≪ ␣ ␣ ≪ get blue part ( ) ≪ endl ≪ endl ; return;

}

137. Returning elements and information.

138. Is on free store.

Log

[LDF 2004.01.06.] Made non-inline.

⟨ Declare Color functions 97 ⟩ +≡ bool is on free store( ) const;

§139  3DLDF-1.1.5.1  IS ON FREE STORE 39

139. ⟨ Define Color functions 98 ⟩ +≡

bool Color ::is on free store( ) const {

return on free store; }

140. Get Color parts. [LDF 2002.09.24.] These functions always return a real; the argument decimal can’t make them return an unsigned short.

141. Get red part. ⟨ Declare Color functions 97 ⟩ +≡

inline real get red part (bool decimal = false) const {

if (decimal ) return trunc((red part ∗ 255) + .5); else return red part ;

}

142. Get green part. ⟨ Declare Color functions 97 ⟩ +≡

inline real get green part (bool decimal = false) const {

if (decimal ) return trunc((green part ∗ 255) + .5); else return green part ;

}

143. Get blue part. ⟨ Declare Color functions 97 ⟩ +≡

inline real get blue part (bool decimal = false) const {

if (decimal ) return trunc((blue part ∗ 255) + .5); else return blue part ;

}

144. Get use name. ⟨ Declare Color functions 97 ⟩ +≡

bool get use name( ) const;

40  GET USE NAME  3DLDF-1.1.5.1 §145

145. ⟨ Define Color functions 98 ⟩ +≡

bool Color ::get use name( ) const {

return use name; }

146. Get name. ⟨ Declare Color functions 97 ⟩ +≡

inline string get name( ) const {

return name; }

147. Output operator. ⟨ Declare non-member non-template functions for Color 147 ⟩ ≡

ostream & operator≪(ostream & o, const Color &c);

This code is used in section 163.

148. ⟨ Define non-member non-template functions for Color 148 ⟩ ≡

ostream & operator≪(ostream & o, const Color &c) {

if (c.get use name( ) ≡ true) {

o ≪ c.get name( ); } else {

o ≪ ≪ c.get red part ( ) ≪ ␣ ≪ c.get green part ( ) ≪ ␣ ≪ c.get blue part ( ) ≪ ; } return o;

}

This code is used in section 162.

149. Define Colors in METAPOST. ⟨ Declare Color functions 97 ⟩ +≡

void define color mp( ) const;

§150  3DLDF-1.1.5.1  DEFINE COLORS IN METAPOST 41

150. ⟨ Define Color functions 98 ⟩ +≡

void Color ::define color mp( ) const {

if (¬out stream.is open( )) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣␣ ≪ flush; return;

} if (name ≡ ) {

cerr ≪  ␣  ␣  ≪

      ␣  ␣      ␣␣    ␣     ␣        ␣   ␣  ≪ flush;

return; } out stream ≪ ␣ ≪ name ≪ ≪ ␣␣ ≪ name ≪ ␣ ␣ ≪ get red part ( ) ≪ ␣ ≪

get green part ( ) ≪ ␣ ≪ get blue part ( ) ≪ ≪ flush; return;

}

151. Initialize Colors. [LDF 2002.09.25.] This function presupposes the existence of namespace Colors. ⟨ Declare Color functions 97 ⟩ +≡

static void initialize colors ( );

42  INITIALIZE COLORS  3DLDF-1.1.5.1 §152

152. ⟨ Define Color functions 98 ⟩ +≡

void Color ::initialize colors ( ) {

using namespace Colors; if (¬out stream.is open( )) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣␣ ≪ flush; return;

} out stream ≪ ␣ ␣ ;

#if 0 /∗ [LDF 2002.09.25.] These colors are already defined in METAPOST and their definitions are

not likely to change. However, if they do, I can comment these function calls back in. ∗/ red .define color mp( ); green.define color mp( ); blue.define color mp( ); black .define color mp( ); white.define color mp( ); background .define color mp( );

#endif yellow .define color mp( ); cyan.define color mp( ); magenta.define color mp( ); orange.define color mp( ); violet .define color mp( ); purple.define color mp( ); yellow green.define color mp( ); green yellow .define color mp( ); blue violet .define color mp( ); gray .define color mp( ); light gray .define color mp( ); violet red .define color mp( ); default background .define color mp( );

/∗ [LDF 2002.09.25.] Currently, this function does nothing if I’m using all of the colors. ∗/ out stream ≪ ␣ ␣ ␣ ␣ ; return;

}

153. Namespace Colors. Here I can put either ⟨ Major Colors 156 ⟩ or ⟨ All Colors 0 ⟩ into ⟨ Declare namespace Colors 153 ⟩, and comment out the other, depending on what I want. This prevents too much unneeded code from being processed. ⟨ All Colors 0 ⟩ is very long, so I neither want to compile it, write the extern declarations from it to colors.h, nor print out the code when I run cweave, unless I really want to use it. [LDF 2002.09.25.] ⟨ Declare namespace Colors 153 ⟩ ≡

⟨ Major Colors 156 ⟩ /∗ ⟨ All Colors 0 ⟩ ∗/

This code is cited in section 153. This code is used in section 162.

§154  3DLDF-1.1.5.1  NAMESPACE COLORS 43

154. [LDF 2002.09.25.] Here I can put either ⟨ extern Major Colors 157 ⟩ or ⟨ extern All Colors 0 ⟩ into ⟨ extern namespace Colors declaration 154 ⟩ ⟨ extern namespace Colors declaration 154 ⟩ ≡

⟨ extern Major Colors 157 ⟩

This code is cited in sections 154 and 158. This code is used in section 163.

155. Major Colors. The colors “red”, “green”, “blue”, “black”, and “white” are already defined in METAPOST, however, we need them here in order to access the Color functions for them.

!! [LDF 2002.09.24.] If this definition isn’t explicitly written to the header file, as it is below, this causes real problems!! It took me awhile to find out that this was the cause.

156. Internal (with initialization). [LDF 2002.09.25.] !! If I add Colors here, remember to add them in the “External” section below, and in the definition of Color ::initialize colors ( ) below.

Log

[LDF 2002.10.26.] Added help color .

⟨ Major Colors 156 ⟩ ≡

namespace Colors { /∗ Primaries, additive. ∗/ extern const Color red ( , 255, 0, 0, true); extern const Color green( , 0, 255, 0, true); extern const Color blue( , 0, 0, 255, true); /∗ Primaries, subtractive. ∗/ extern const Color cyan( , 0, 255, 255, true); extern const Color yellow ( , 255, 255, 0, true); extern const Color magenta( , 255, 0, 255, true); /∗ [LDF 2002.09.27.] The convention

that I use is that colors like “orange red ” are reds and colors like “red orange” are oranges. ∗/ /∗ Red. ∗/

extern const Color orange red ( , 255, 69, 0);

extern const Color violet red (  , 208, 32, 144);  /∗ Pink. ∗/
extern const Color pink (  , 255, 192, 203);  /∗ Blue. ∗/  /∗ Yellow. ∗/
extern const Color green yellow (  , 173, 255, 47);  /∗ Orange. ∗/
extern const Color orange(  , 255, 165, 0, true);  /∗ Violet. ∗/

extern const Color violet ( , 238, 130, 238, true); extern const Color purple( , 160, 32, 240, true); extern const Color blue violet ( , 138, 43, 226); /∗ Green. ∗/ extern const Color yellow green( , 154, 205, 50);

/∗ “Unbunt” Colors (blacks, whites, and grays). ∗/ extern const Color black ( , 0, 0, 0, true); extern const Color white( , 255, 255, 255, true); extern const Color gray ( , 192, 192, 192); extern const Color light gray ( , 211, 211, 211);

/∗ Defaults. [LDF 2002.09.27.] Note that default color , help color and background color are pointers and that default background is a plain Color. It can be used to access the original background color (currently white), if the user points the background color at some other Color. ∗/

extern const Color default background ( , 255, 255, 255, true); extern const Color ∗default color = &black ; extern const Color ∗background color = &default background ; extern const Color ∗help color = &green; /∗ LDF 2002.10.26. Added. ∗/

/∗ [LDF 2002.09.25.] !! TO DO: default background is a convenience, in case I change “background” in the METAPOST code. Check METAPOST documentation!! I believe it has something similar. ∗/

44  INTERNAL (WITH INITIALIZATION)  3DLDF-1.1.5.1 §156

}

This code is cited in sections 153 and 158. This code is used in section 153.

157. External. ⟨ extern Major Colors 157 ⟩ ≡

namespace Colors { /∗ [LDF 2002.09.27.] The ordering should be as above for the internal

declarations. ∗/ /∗ Primaries, additive. ∗/ extern const Color red ; extern const Color green; extern const Color blue; /∗ Primaries, subtractive. ∗/ extern const Color cyan; extern const Color yellow ; extern const Color magenta; /∗ Red. ∗/ extern const Color orange red ; extern const Color violet red ; /∗ Pink. ∗/ extern const Color pink ; /∗ Blue. ∗/ /∗ Yellow. ∗/ extern const Color green yellow ; /∗ Orange. ∗/ extern const Color orange; /∗ Violet. ∗/ extern const Color violet ; extern const Color purple; extern const Color blue violet ; /∗ Green. ∗/ extern const Color yellow green; /∗ “Unbunt” Colors (black, white, and grays). ∗/ extern const Color black ; extern const Color white; extern const Color gray ; extern const Color light gray ; /∗ Defaults. ∗/ extern const Color default background ; extern Color ∗default color ; extern Color ∗help color ; /∗ LDF 2002.10.26. Added. ∗/ extern Color ∗background color ;

}

This code is cited in section 154. This code is used in section 154.

158. All Colors. !! IF colall.web IS CHANGED, I WILL HAVE TO MAKE SURE THAT THIS FILE is recompiled!! does not check the state of colall.web. ?? Should I do something about this, or is it not worth it? If I work on colall.web, I could just put the code back in here.

[LDF 2002.09.26.] If I want all of the colors declared in colall.web, I can uncomment the following line and use ⟨ All Colors 0 ⟩ instead of ⟨ Major Colors 156 ⟩ in ⟨ extern namespace Colors declaration 154 ⟩ above.

i colall.web (Commented out).

159. Global constants.

Log

[LDF 2002.10.26.] Added help color vector .

⟨ Global constants 22 ⟩ +≡

namespace Colors { extern const vector⟨const Color ∗⟩ default color vector (1, default color );

§159  3DLDF-1.1.5.1  GLOBAL CONSTANTS 45

extern const vector⟨const Color ∗⟩ help color vector (1, help color );

/∗ LDF 2002.10.26. Added. ∗/ extern const vector⟨const Color ∗⟩ background color vector (1, background color );

}

160. ⟨ extern global constant declarations 160 ⟩ ≡

namespace Colors { extern const vector⟨const Color ∗⟩ default color vector ; extern const vector⟨const Color ∗⟩ help color vector ; /∗ LDF 2002.10.26. Added. ∗/ extern const vector⟨const Color ∗⟩ background color vector ;

}

This code is used in section 163.

161. Putting Color together.

162. This is compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩; ⟨ Define class Color 95 ⟩ ⟨ Declare namespace Colors 153 ⟩ ⟨ Define Color functions 98 ⟩ ⟨ Declare non-member template functions for Color 112 ⟩ ⟨ Define non-member non-template functions for Color 148 ⟩ ⟨ Global constants 22 ⟩

46  PUTTING COLOR TOGETHER  3DLDF-1.1.5.1 §163

163. This is written to colors.h. ⟨ 163 ⟩ ≡

⟨ Define class Color 95 ⟩

⟨ extern namespace Colors declaration 154 ⟩

⟨ Declare non-member template functions for Color 112 ⟩

⟨ Declare non-member non-template functions for Color 147 ⟩

⟨ extern global constant declarations 160 ⟩

164. Transformations (transform.web).

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

165. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include

166. Transform class definition. The Transform class has a 4 × 4 transformation matrix as its only data member and a number of member functions. Points, Pictures, and Focuses contain Transforms as data members.

!! Remember to add items to operator=( ) if if I add them to the class definition here.

Log

[LDF 2003.07.04.] Removed friend declaration for Focus. I’ve added set element ( ) and get element ( ), which are used in the Focus functions, so the latter need no longer be a friend of Transform.

format Transform int

⟨ Define class Transform 166 ⟩ ≡

class Transform { friend class Point; Matrix matrix ; /∗ When I’ve got things working, I can try to optimize use of storage by not

storing the parts of the matrix that I don’t need. This is a little complicated, because the row or column which isn’t needed differs between the affine and perspective transformations. ∗/

public: ⟨ Declare Transform functions 168 ⟩

};

This code is used in sections 239 and 240.

167. Constructors.

§168  3DLDF-1.1.5.1  DEFAULT CONSTRUCTOR 47

168. Default constructor. (No arguments). Initializes a new transformation matrix as the identity matrix ⟨ Declare Transform functions 168 ⟩ ≡

Transform( );

See also sections 170, 172, 174, 176, 178, 180, 182, 185, 187, 190, 192, 195, 197, 200, 202, 203, 205, 211, 212, 213, 216, 218, 221,

223, 226, and 232. This code is used in section 166.

169. ⟨ Define Transform functions 169 ⟩ ≡

Transform ::Transform( )

{

reset ( ); }

See also sections 171, 173, 175, 177, 179, 181, 183, 186, 188, 191, 193, 196, 198, 201, 204, 206, 207, 208, 209, 217, 219, 222, 224,

227, 228, 229, 230, 231, 233, 416, 424, 425, 426, 427, 428, 429, 430, 431, 432, 439, and 759. This code is used in sections 239, 633, and 980.

170. Constructor with one real argument. All elements of matrix are set to the real argument r. ⟨ Declare Transform functions 168 ⟩ +≡

Transform(real r);

171. ⟨ Define Transform functions 169 ⟩ +≡

Transform ::Transform(real r)

{

for (int i = 0; i < 4; i^{++})

for (int j = 0; j < 4; j^{++}) matrix [i][j] = r;

}

172. Constructor with 16 real arguments. [LDF 2002.09.06.] Added this constructor. This constructor makes it possible to specify all of the elements of matrix . ⟨ Declare Transform functions 168 ⟩ +≡

Transform(real r0 0 , real r0 1 , 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 );

48  CONSTRUCTOR WITH 16 REAL ARGUMENTS  3DLDF-1.1.5.1 §173

173. ⟨ Define Transform functions 169 ⟩ +≡

Transform ::Transform(real r0 0 , real r0 1 , 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 )

{ matrix [0][0] = r0 0 ; matrix [0][1] = r0 1 ; matrix [0][2] = r0 2 ; matrix [0][3] = r0 3 ; matrix [1][0] = r1 0 ; matrix [1][1] = r1 1 ; matrix [1][2] = r1 2 ; matrix [1][3] = r1 3 ; matrix [2][0] = r2 0 ; matrix [2][1] = r2 1 ; matrix [2][2] = r2 2 ; matrix [2][3] = r2 3 ; matrix [3][0] = r3 0 ; matrix [3][1] = r3 1 ; matrix [3][2] = r3 2 ; matrix [3][3] = r3 3 ;

}

174. Assignment. Sets matrix to be identical to the matrix of another Transform. !! Remember to add items here if I add them to the class definition. ⟨ Declare Transform functions 168 ⟩ +≡

Transform operator=(const Transform &t);

175. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::operator=(const Transform &t) {

for (int i = 0; i < 4; i^{++})

for (int j = 0; j < 4; j^{++}) matrix [i][j] = t.matrix [i][j]; return t;

}

176. Reset to identity matrix. ⟨ Declare Transform functions 168 ⟩ +≡

void reset ( );

§177  3DLDF-1.1.5.1  RESET TO IDENTITY MATRIX 49

177. ⟨ Define Transform functions 169 ⟩ +≡

void Transform ::reset ( ) {

for (int i = 0; i < 4; i^{++}) /∗ Rows. ∗/ for (int j = 0; j < 4; j^{++}) /∗ Columns. ∗/ {

matrix [i][j] = (i ≡ j) ? 1 : 0;

} }

178. Setting values.

Log

[LDF 2003.07.04.] Added this function.

⟨ Declare Transform functions 168 ⟩ +≡ void set element (const unsigned short row , const unsigned short col , real r);

179. ⟨ Define Transform functions 169 ⟩ +≡

void Transform ::set element (const unsigned short row , const unsigned short col , real r) {

matrix [row ][col ] = (fabs (r) < epsilon( )) ? 0 : r; return;

}

180. Clean. clean( ) changes elements in matrix whose absolute values are < epsilon( ) to 0. ⟨ Declare Transform functions 168 ⟩ +≡

50  CLEAN  3DLDF-1.1.5.1 §181

void clean( ); 181. ⟨ Define Transform functions 169 ⟩ +≡

void Transform ::clean( )

{ real eps = epsilon( ); for (int i = 0; i < 4; i^{++}) /∗ Rows. ∗/

for (int j = 0; j < 4; j^{++}) /∗ Columns. ∗/ {

if (fabs (matrix [i][j]) < eps ) matrix [i][j] = 0; }

}

182. Epsilon. Minimum magnitude of values stored in matrix . [LDF 2002.10.16.] The value returned by epsilon( ) has to be fairly large because of the poor precision resulting from the use floats and the Standard Library versions of the trigonometric functions. There is currently no equality operator for Transform, but the precision of the Transforms affects that of Points. TO DO: I hope to be able to solve the problem by finding routines for calculating the trigonometric functions more accurately (and faster) by using integers and bitwise shifts. If this doesn’t work out, I could try redefining real as double (which I don’t want to do), or I could try to use double explicitly when using the trigonometric functions. In the latter case, I would have to truncate the doubles to floats eventually, so I don’t know if this would have any benefit.

Log

[LDF 2004.1.2.] Now returning different values, depending on whether real is float or double. TO DO: Try to find out what values would be best. It will be necessary to check how good the value for double is.

[LDF 2004.1.2.] Made epsilon( ) static and non-inline.

⟨ Declare Transform functions 168 ⟩ +≡ static real epsilon( );

183. ⟨ Define Transform functions 169 ⟩ +≡

real Transform ::epsilon( )

{ #if

return .000000001;

#else

return .00001;

#endif }

184. Test for identity matrix. [LDF 2002.11.16.] TO DO: I should check the elements on the main diagonal for whether they differ from 1 by an amount <epsilon( ). If so, they should be set to 1.

185. Non-const version. ⟨ Declare Transform functions 168 ⟩ +≡

§186  3DLDF-1.1.5.1  NON-CONST VERSION 51

bool is identity ( ); 186. ⟨ Define Transform functions 169 ⟩ +≡

bool Transform ::is identity ( )

{ clean( ); for (int i = 0; i < 4; i^{++}) for (int j = 0; j < 4; j^{++})

if ((i ≡ j ∧ matrix [i][j] ≠ 1) ∨ ((i ≠ j) ∧ matrix [i][j] ≠ 0)) return false; return true;

}

187. const version. ⟨ Declare Transform functions 168 ⟩ +≡

bool is identity ( ) const;

188. ⟨ Define Transform functions 169 ⟩ +≡

bool Transform ::is identity ( ) const

{ Transform t; t = ∗this ; t.clean( ); for (int i = 0; i < 4; i^{++}) for (int j = 0; j < 4; j^{++})

if ((i ≡ j ∧ matrix [i][j] ≠ 1) ∨ ((i ≠ j) ∧ matrix [i][j] ≠ 0)) return false; return true;

}

189. Querying.

190. Get element.

Log

[LDF 2003.07.04.] Added this function.

⟨ Declare Transform functions 168 ⟩ +≡ real get element (const unsigned short row , const unsigned short col ) const;

191. ⟨ Define Transform functions 169 ⟩ +≡

real Transform ::get element (const unsigned short row , const unsigned short col ) const {

return matrix [row ][col ]; }

192. Show. ⟨ Declare Transform functions 168 ⟩ +≡

52  SHOW  3DLDF-1.1.5.1 §193

void show (string text = ) const; 193. ⟨ Define Transform functions 169 ⟩ +≡

void Transform ::show (string text ) const

{ if (text ≡ ) text = ; cout ≪ text ≪ ; for (int i = 0; i < 4; i^{++}) {

for (int j = 0; j < 4; j^{++}) { /∗ !! [LDF 2002.02.07.] Can’t use left here, and I can’t include ios. This causes an error with a reference to something in the C^{++} manual. Must write to K. Heuer and ask if he can fix it. ∗/

cout ≪ setw (7) ≪ setprecision(3) ≪ matrix [i][j] ≪ ␣ ; } cout ≪ endl ;

}

cout ≪ endl ≪ flush; }

194. Affine transformations. [LDF 2002.10.16.] The functions for the affine transformations all return a Transform representing the transformation, not ∗this . This makes it possible to chain expressions using operator∗=( ), e.g.,

Point pt0 ;

Point pt1 (1, 2, 3); Point pt2 (3, 4, 5); Transform t; t.rotate(90, 90, 90); pt0 ∗= pt1 ∗= pt2 ∗= t;

pt0 , pt1 , and pt2 are all rotated 90^{∘} around the x, y, and z-axes.

195. Scale.

Log

[LDF 2002.10.15.] BUG FIX: If the absolute value of an argument is < epsilon( ), the argument is now set to 0 instead of 1. Setting it to 1 causes no scaling to take place, which is not the effect of multiplying the corresponding coordinate by a number of very small magnitude.

[LDF 2003.03.25.] BUG FIX: Fixed conditional that tests whether all the arguments are 1.

§196  3DLDF-1.1.5.1  SCALE 53

⟨ Declare Transform functions 168 ⟩ +≡ Transform scale(real x, real y = 1, real z = 1); 196. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::scale(real x, real y, real z) {

Transform t; if (x ≡ 1 ∧ y ≡ 1 ∧ z ≡ 1) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣ ␣␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; return t;

} real eps = epsilon( ); t.matrix [0][0] = (fabs (x) ≥ eps ) ? x : 0; t.matrix [1][1] = (fabs (y) ≥ eps ) ? y : 0; t.matrix [2][2] = (fabs (z) ≥ eps ) ? z : 0; ∗this ∗= t; clean( ); return t;

}

197. Shear. [LDF 2002.10.15.] Replaced the dummy definition of this function with a proper one. ⟨ Declare Transform functions 168 ⟩ +≡

Transform shear (real xy , real xz = 0, real yx = 0, real yz = 0, real zx = 0, real zy = 0);

54  SHEAR  3DLDF-1.1.5.1 §198

198. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::shear (real xy , real xz , real yx , real yz , real zx , real zy ) {

Transform t; real eps = epsilon( ); if (fabs (xy ) < eps ) xy = 0; if (fabs (xz ) < eps ) xz = 0; if (fabs (yx ) < eps ) yx = 0; if (fabs (yz ) < eps ) yz = 0; if (fabs (zx ) < eps ) zx = 0; if (fabs (zy ) < eps ) zy = 0; if (xy ≡ 0 ∧ xz ≡ 0 ∧ yx ≡ 0 ∧ yz ≡ 0 ∧ zx ≡ 0 ∧ zy ≡ 0) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣ ␣␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; return t;

} t.matrix [1][0] = xy ; t.matrix [2][0] = xz ; t.matrix [0][1] = yx ; t.matrix [2][1] = yz ; t.matrix [0][2] = zx ; t.matrix [1][2] = zy ; (∗this ) ∗= t; clean( ); return t;

}

199. Shift. (Translation.)

200. real arguments. ⟨ Declare Transform functions 168 ⟩ +≡

Transform shift (real x, real y = 0, real z = 0);

201. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::shift (real x, real y, real z) {

real eps = epsilon( ); Transform t; if (x ≡ 0 ∧ y ≡ 0 ∧ z ≡ 0) return t; t.matrix [3][0] = (fabs (x) > eps ) ? x : 0; t.matrix [3][1] = (fabs (y) > eps ) ? y : 0; t.matrix [3][2] = (fabs (z) > eps ) ? z : 0; t.clean( ); (∗this ) ∗= t; clean( ); return t;

}

§202  3DLDF-1.1.5.1  POINT ARGUMENT 55

202. Point argument. [LDF 2002.04.24.] Added this function. It must be defined in points.web, because Point is an incomplete type here. ⟨ Declare Transform functions 168 ⟩ +≡

Transform shift (const Point &p);

203. Shift with multiplication. [LDF 2002.08.22.] Added this function. It takes real arguments and multiplies the appropriate elements of matrix by them. ⟨ Declare Transform functions 168 ⟩ +≡

Transform shift times (real x, real y = 1, real z = 1);

204. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::shift times (real x, real y, real z)

{ bool = false; /∗ true ∗/ if ( ) {

show ( ␣ ); } matrix [3][0] ∗= x; matrix [3][1] ∗= y; matrix [3][2] ∗= z; if ( ) {

show ( ␣ ); } return ∗this ;

}

205. Rotation around the main axes. rotate( ) will perform rotation about the x, y and z-axes in that order if called with multiple, non-zero arguments. Rotation only about the y and/or z-axis requires one or two dummy 0 arguments so that rotate( ) “knows” about which axis (or axes) to rotate. ⟨ Declare Transform functions 168 ⟩ +≡

56  ROTATION AROUND THE MAIN AXES  3DLDF-1.1.5.1 §206

Transform rotate(real x, real y = 0, real z = 0); 206. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::rotate(real x, real y, real z){ bool = false; /∗ true ∗/ Transform t all ; real eps = epsilon( ); if (x ≡ 0 ∧ y ≡ 0 ∧ z ≡ 0) {

if (  ) cerr ≪  ␣           ␣      ␣  ≪

        ␣        ␣     ␣    ␣     ␣         ␣        ␣  ≪ flush;

return t all ; } Transform t x ; Transform t y ; Transform t z ; real ssin; real ccos ; real temp1 ; real temp2 ; int i;

207. Rotation around the x-axis. ⟨ Define Transform functions 169 ⟩ +≡

if (x ≠ 0) { /∗ !! Reversed direction of rotation because I didn’t like the way it was. ∗/ x ∗= − /180.0; /∗ Convert to radians. ∗/ ssin = sin(x); ccos = cos (x); for (i = 0; i < 4; i^{++}) {

temp1 = (t x .matrix [i][1] ∗ ccos ) − (t x .matrix [i][2] ∗ ssin); temp2 = (t x .matrix [i][1] ∗ ssin) + (t x .matrix [i][2] ∗ ccos ); t x .matrix [i][2] = (fabs (temp2 ) ≥ eps ) ? temp2 : 0; t x .matrix [i][1] = (fabs (temp1 ) ≥ eps ) ? temp1 : 0;

} } /∗ if ∗/

208. Rotation around the y-axis. ⟨ Define Transform functions 169 ⟩ +≡

if (y ≠ 0) { /∗ !! Reversed direction of rotation because I didn’t like the way it was. ∗/ y ∗= − /180.0; ssin = sin(y); ccos = cos (y); for (i = 0; i < 4; i^{++}) {

temp1 = (t y .matrix [i][0] ∗ ccos ) + (t y .matrix [i][2] ∗ ssin); temp2 = (−t y .matrix [i][0] ∗ ssin) + (t y .matrix [i][2] ∗ ccos ); t y .matrix [i][2] = (fabs (temp2 ) ≥ eps ) ? temp2 : 0; t y .matrix [i][0] = (fabs (temp1 ) ≥ eps ) ? temp1 : 0;

§209  3DLDF-1.1.5.1  ROTATION AROUND THE MAIN AXES 57

} } /∗ if ∗/ 209. Rotation around the z-axis. ⟨ Define Transform functions 169 ⟩ +≡

if (z ≠ 0) { z ∗= /180.0; ssin = sin(z); ccos = cos (z); for (int i = 0; i < 4; i^{++}) {

temp1 = (t z .matrix [i][0] ∗ ccos ) − (t z .matrix [i][1] ∗ ssin); temp2 = (t z .matrix [i][0] ∗ ssin) + (t z .matrix [i][1] ∗ ccos ); t z .matrix [i][1] = (fabs (temp2 ) ≥ eps ) ? temp2 : 0; t z .matrix [i][0] = (fabs (temp1 ) ≥ eps ) ? temp1 : 0;

} } /∗ if ∗/ t all ∗= t x ; t all ∗= t y ; t all ∗= t z ; t all .clean( ); (∗this ) ∗= t all ; clean( ); return t all ; } /∗ End of rotate( ). ∗/

210. Rotation around an arbitrary axis.

211. Point arguments. Defined in points.web because Point is an incomplete type here.

Log

[LDF 2002.4.7.] Added default value for angle ≡ 180. [LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now

overloads rotate( ) with three real arguments.

58 PATH ARGUMENT 3DLDF-1.1.5.1 §212

⟨ Declare Transform functions 168 ⟩ +≡ Transform rotate(Point p0 , Point p1 , const real angle = 180); 212. Path argument. [LDF 2002.05.03.] Defined in paths.web because Path is an incomplete type here.

Log

[LDF 2002.05.03.] Added this function.

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Transform functions 168 ⟩ +≡ Transform rotate(const Path &p, const real angle = 180);

213. Alignment with an axis. Defined in points.web, because it uses Points, which haven’t been defined yet. ⟨ Declare Transform functions 168 ⟩ +≡

Transform align with axis (Point p0 , Point p1 , char axis = ); /∗ Default is the z-axis. ∗/

214. Matrix multiplication.

215. With assignment.

216. real argument. [LDF 2002.11.19.] This function multiplies each element of Matrix by the real argument r and returns r. This makes it possible to chain invocations of this function. Not currently used anywhere, but it may turn out to be useful for something.

Log

[LDF 2002.08.22.] Added this function.

[LDF 2002.11.19.] Changed return value from ∗this to r.

⟨ Declare Transform functions 168 ⟩ +≡ real operator∗=(real r);

217. ⟨ Define Transform functions 169 ⟩ +≡

real Transform ::operator∗=(real r)

{

for (int i = 0; i < 4; i^{++})

for (int j = 0; j < 4; j^{++}) matrix [i][j] ∗= r; clean( ); return r;

}

218. Transform argument.

Log

[LDF 2002.11.06.] If t is the identity Transform, it is returned right away. If ∗this is, it is set to t using operator=( ). BUG FIX: Now t is always returned, instead of ∗this . This makes it possible to chain expressions using this function.

⟨ Declare Transform functions 168 ⟩ +≡ Transform operator∗=(const Transform &t);

§219  3DLDF-1.1.5.1  TRANSFORM ARGUMENT 59

219. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::operator∗=(const Transform &t) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (t.is identity ( )) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ ␣ ≪ flush; return t;

} else if (is identity ( )) {

if (  ) cout ≪  ␣  ␣   ␣        ␣              ␣ ≪

        ␣     ␣  ␣ ␣    ␣         ␣  ≪ flush;

return (∗this = t); } Matrix temp matrix = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; for (int i = 0; i < 4; i^{++})

for (int k = 0; k < 4; k^{++})

for (int j = 0; j < 4; j^{++}) temp matrix [i][k] += matrix [i][j] ∗ t.matrix [j][k]; for (int i = 0; i < 4; i^{++})

for (int j = 0; j < 4; j^{++}) {

matrix [i][j] = temp matrix [i][j]; }

clean( ); if ( ) cout ≪ ␣ ≪ flush; return t;

}

220. Plain multiplication.

221. real argument. [LDF 2002.08.22.] Added this function. Not currently used anywhere, but it may turn out to be useful for something. ⟨ Declare Transform functions 168 ⟩ +≡

Transform operator∗(const real r) const;

222. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::operator∗(const real r) const {

Transform t = ∗this ; t ∗= r; t.clean( ); return t;

}

223. Transform argument. ⟨ Declare Transform functions 168 ⟩ +≡

Transform operator∗(const Transform t) const;

60 TRANSFORM ARGUMENT 3DLDF-1.1.5.1 §224

224. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::operator∗(const Transform t) const

{ Transform a = ∗this ; a ∗= t; a.clean( ); return a;

}

225. Matrix inversion.

226. const version (no assignment). It would be easy to generate the inverses of the transformations that I call explicitly using rotate( ), shift ( ), etc., as I go along. However, it is not possible to do this for the ones produced using operator∗( ) and operator∗=( ). So, since a matrix inversion routine is needed anyway, I don’t bother to generate the inverses as I go along.

TO DO: Get format for references! inverse( ) uses the Gauß-Jordan algorithm with column pivot search. I’ve taken the algorithm from Stoer, Josef. Numerische Mathematik 1^{1} and adapted it to C^{++}.

Log

[LDF 2002.12.01.] !! Changed hi from real to int because of a warning, when I tried to compile under GNU/Linux. I think hi can be an int, but test to be sure!

⟨ Declare Transform functions 168 ⟩ +≡ Transform inverse( ) const;

1 Stoer, Josef. Numerische Mathematik 1. Achte, neu bearbeitete und erweiterte Auflage. Springer-Verlag. Berlin 1999. ISBN 3-540-66154-9, page 205.

§227  3DLDF-1.1.5.1  CONST VERSION (NO ASSIGNMENT) 61

227. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::inverse( ) const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ endl ≪ flush;

int i; int j; int k; int row ; const int n = 4; real max ; real hr ; int hi ; /∗ [LDF 2002.12.01.] See above in “Log”. ∗/ real hv [n]; Transform t; if ( ) {

cout ≪ ␣ ; } for (i = 0; i < 4; i^{++}) {

for (j = 0; j < 4; j^{++}) { t.matrix [i][j] = matrix [i][j]; if ( ) {

cout ≪ matrix [i][j] ≪ ␣ ; }

}

if ( ) {

cout ≪ ; }

} if ( ) {

cout ≪ ;

t.show ( );

cout ≪ ␣ ␣ ␣ ≪ flush; getchar ( );

} int p[n]; for (int j = 0; j < n; j^{++}) p[j] = j; for (j = 0; j < n; j^{++}) {

62 CONST VERSION (NO ASSIGNMENT) 3DLDF-1.1.5.1 §228

228. Pivot search. ⟨ Define Transform functions 169 ⟩ +≡

max = fabs (t.matrix [j][j]); row = j; for (i = j + 1; i < n; i^{++}) {

if (fabs (t.matrix [i][j]) > max ) { max = fabs (t.matrix [i][j]); row = i;

} /∗ if ∗/ } /∗ inner for ∗/ if ( ) {

cout ≪ ␣ ␣ ≪ max ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ row ≪ endl ≪ flush; } if (max ≡ 0) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣␣ ␣ ≪ flush; return ;

}

229. Row exchange. ⟨ Define Transform functions 169 ⟩ +≡

if (row > j) {

for (k = 0; k < n; k^{++}) { hr = t.matrix [j][k]; t.matrix [j][k] = t.matrix [row ][k]; t.matrix [row ][k] = hr ;

} /∗ for ∗/

hi = p[j];

p[j] = p[row ];

p[row ] = hi ; } /∗ if ∗/

if (  ) cout ≪  ␣   ␣  ≪ flush;

230. Transformation. ⟨ Define Transform functions 169 ⟩ +≡

if ( ) cout ≪ ≪ j ≪ ≪ j ≪ ␣ ␣ ≪ t.matrix [j][j] ≪ endl ≪ flush; hr = 1/t.matrix [j][j]; for (i = 0; i < n; i^{++}) t.matrix [i][j] = hr ∗ t.matrix [i][j]; t.matrix [j][j] = hr ; for (k = 0; k < n; k^{++})

if (k ≠ j) {

for (i = 0; i < n; i^{++})

if (i ≠ j) t.matrix [i][k] −= t.matrix [i][j] ∗ t.matrix [j][k];

t.matrix [j][k] ∗= −hr ; }

} /∗ outer for ∗/

if (  ) cout ≪  ␣  ≪ flush;

231. Column exchange. ⟨ Define Transform functions 169 ⟩ +≡

for (i = 0; i < n; i^{++}) { for (k = 0; k < n; k^{++}) hv [p[k]] = t.matrix [i][k]; for (k = 0; k < n; k^{++}) t.matrix [i][k] = hv [k];

} /∗ for ∗/

if ( ) {

cout ≪  ␣      ␣  ≪ flush;
cout ≪  ␣  ≪ endl ≪ flush;

}

if ( ) cout ≪ ␣ ≪ endl ≪ flush;

return t; }

232. Non-const version (with assignment). [LDF 2002.10.20.] Added this function. I thought of calling in “invert ( )”, but I decided against it, because I thought having two functions called “inverse( )” and “invert ( )” would be confusing.

There is no point in calling this function with assign ≡ false, since it is equivalent to the const version above with no argument. If it is called with assign ≡ false, a warning is issued, the const version is invoked, and its return value is returned. ⟨ Declare Transform functions 168 ⟩ +≡

Transform inverse(bool assign);

233. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::inverse(bool assign)

{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣                       ␣  ≪ flush;

if (assign ≡ false) {

cerr ≪  ␣  ␣                       ␣  ≪

          ␣  ␣      ␣␣       ␣  ␣      ␣  ␣     ␣ ≪
          ␣    ␣        ␣     ␣ ␣         ␣  ≪
          ␣  ␣       ␣  ␣    ␣     ␣␣  ≪ flush;

return inverse( ); } if ( ) cout ≪ ␣ ␣ ≪ flush; return (∗this = inverse( ));

}

234. Global variables. ⟨ Global variables 18 ⟩ +≡

64  GLOBAL VARIABLES  3DLDF-1.1.5.1 §235

Transform user transform; 235. ⟨ Declarations for the header file 21 ⟩ +≡

extern Transform user transform;

236. Global constants. ⟨ Global constants 22 ⟩ +≡

extern const Transform ( ); extern const Transform ;

237. ⟨ Declarations for the header file 21 ⟩ +≡

extern const Transform ; extern const Transform ;

238. Putting Transform together.

239. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Transform 166 ⟩ ⟨ Global variables 18 ⟩ ⟨ Global constants 22 ⟩ ⟨ Define Transform functions 169 ⟩

§240  3DLDF-1.1.5.1  PUTTING TRANSFORM TOGETHER 65

240. This is what’s written to transfor.h. ⟨ 240 ⟩ ≡

⟨ Define class Transform 166 ⟩

⟨ Declarations for the header file 21 ⟩

241. Shape (shapes.web). [LDF 2002.10.20.] Shape is an abstract class. This means that no objects of type Shape may be declared. Shape is used as a base class for all “drawable” classes, e.g., Point, Path, and Dodecahedron. All objects that are put onto a Picture must be either Shapes or Labels.

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

242. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include

243. Shape class definition.

244. class Point is known when shapes.c is compiled, because it’s declared (but not defined) in transfor.web, which is processed by first. ?? Apparently, both the return value and the argument types of pure virtual functions must be the same,

otherwise the derived classes will cause compiler errors. Check where this is stated.

Log

[LDF 2003.05.16.] Added declarations of get minimum z ( ) and get mean z ( ).

format Shape int

⟨ Define Shape class 244 ⟩ ≡

class Shape { protected: static const signed short ; /∗ const values used for output. ∗/

static const signed short ;

static const signed short ;

static const signed short ;

static const signed short ;

static const signed short ;

static const signed short ;

static const signed short ;

See also section 245. This code is used in sections 248 and 249.

66 SHAPE CLASS DEFINITION 3DLDF-1.1.5.1 §245

245. Shape function declarations. All Shape functions are pure virtual functions.

[LDF 2002.10.20.] I’ve thought about getting rid of get copy ( ) a couple of times, and using ⟨type⟩( ) instead, but it’s not possible: get copy ( ) is used in Picture functions for objects of types derived from Shape where the type is not known. The compiler must resolve to the correct version of get copy ( ), so a virtual Shape function is needed. The “ ⟨type⟩( )” functions are not virtual Shape functions, and can’t be, because the names of the types are part of the name of the functions. I could solve this problem by renaming get copy ( ) create new ( ), but what I wanted to do was have a template function create new ( ) (or just create( )). So far, I haven’t been able to get this to work. So, for the time being, I’m leaving things as they are.

[LDF 2002.10.23.] The default arguments to show ( ) are necessary, since ⟨ Define Shape class 244 ⟩ +≡ public: virtual void show (string text = , char coords = , const bool do persp = true, const

bool do apply = true, Focus ∗f = 0, const unsigned short proj = 0, const real factor = 1) const = 0;

virtual Shape ∗get copy ( ) const = 0; virtual bool is on free store( ) const = 0; virtual bool set on free store(bool b = true) = 0; virtual void clear ( ) = 0; virtual void output ( ) = 0; virtual vector⟨Shape ∗⟩ extract (const Focus &, const unsigned short proj , real factor ) = 0; virtual Transform rotate(const real, const real, const real) = 0; virtual Transform scale(real, real, real) = 0; virtual Transform shear (real xy , real xz , real yx , real yz , real zx , real zy ) = 0; virtual Transform shift (real, real, real) = 0; virtual Transform rotate(const Point &, const Point &, const real) = 0; virtual Transform operator∗=(const Transform &) = 0; virtual void apply transform(void) = 0; virtual bool set extremes ( ) = 0; virtual real get minimum z ( ) const = 0; virtual real get maximum z ( ) const = 0; virtual real get mean z ( ) const = 0; virtual const valarray⟨real⟩ get extremes ( ) const = 0; virtual void suppress output ( ) = 0; virtual void unsuppress output ( ) = 0; } ;

246. Static data members. ⟨ Define static Shape member variables 246 ⟩ ≡

const signed short Shape :: = 1; const signed short Shape :: = 2; const signed short Shape :: = 3; const signed short Shape :: = 4; const signed short Shape :: = −1; const signed short Shape :: = −2; const signed short Shape :: = −3; const signed short Shape :: = −4;

This code is used in section 248.

247. Putting Shape together.

§248  3DLDF-1.1.5.1  PUTTING SHAPE TOGETHER 67

248. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define Shape class 244 ⟩ ⟨ Define static Shape member variables 246 ⟩

68  PUTTING SHAPE TOGETHER  3DLDF-1.1.5.1 §249

249. This is what’s written to shapes.h. ⟨ 249 ⟩ ≡

⟨ Define Shape class 244 ⟩

250. Picture and Label (pictures.web).

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

251. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include

252. Label. [LDF 2002.10.20.] Labels are the only objects, other than Shapes, that can be put onto Pictures. They are created by the functions label ( ) and dotlabel ( ), which are currently defined for Points and Paths.

253. Label class definition. A Label contains a pointer to a Point, which is its location, a bool to indicate whether the label should have a dot or not, a string for the text of the label and a string for positioning the text with respect to the label. pt must be a pointer, because Point is an incomplete type

here. position can be any of the strings used in METAFONT, i.e.,  ,  ,  ,  ,  ,
,  , or  .

[LDF 2002.10.09.] Labels are currently only ever created on the free store.

format Label int

⟨ Define classes 253 ⟩ ≡

class Label { friend class Point; friend class Picture; Point ∗pt ; bool dot ; string text ; string position;

public: static bool ;

⟨ Declare Label functions 255 ⟩ };

See also section 261. This code is used in sections 305 and 306.

§254  3DLDF-1.1.5.1  STATIC DATA MEMBERS 69

254. Static data members. is used for globally enabling or suppressing putting Labels onto Pictures: If is false, then label ( ) and dotlabel ( ) have no effect, i.e., no Label is put onto the Picture. Note that Picture has a private data member do labels , which is for enabling or suppressing output of Labels for a single Picture (see below).

Log

[LDF 2002.10.20.] Added this section. was formerly a global variable defined in pspglb.web.

⟨ Initialize static Label data members 254 ⟩ ≡

bool Label :: = true;

This code is used in section 305.

255. Declarations for Label functions. These must be defined in points.web, because they require operations on pt , and Point is an incomplete type in this file.

Log

[LDF 2002.10.23.] Added arguments proj and factor .

⟨ Declare Label functions 255 ⟩ ≡ void output (const Focus &f, const unsigned short proj , real factor , const Transform &t); Label ∗get copy ( ) const;

This code is used in section 253.

256. namespace Projections.

Log

[LDF 2003.05.11.] Added .

⟨ Declare namespace Projections 256 ⟩ ≡

namespace Projections { extern const unsigned short = 0; extern const unsigned short = 1; extern const unsigned short = 2; extern const unsigned short = 3; extern const unsigned short = 4; extern const unsigned short = 5;

};

This code is used in section 305.

70 NAMESPACE PROJECTIONS  3DLDF-1.1.5.1  §257

257. External. ⟨ extern declaration of namespace Projections 257 ⟩ ≡

namespace Projections { extern const unsigned short ; extern const unsigned short ; extern const unsigned short ; extern const unsigned short ; extern const unsigned short ; extern const unsigned short ;

};

This code is used in section 306.

258. namespace Sorting. This namespace contains constants that are passed to Picture ::output ( ) for determining how the Shapes on the Picture are sorted in order to determine the order in which they are output.

Log

[LDF 2003.05.16.] Added this namespace.

⟨ Declare namespace Sorting 258 ⟩ ≡

namespace Sorting { extern const unsigned short = 0; extern const unsigned short = 1; extern const unsigned short = 2; extern const unsigned short = 3;

};

This code is used in section 305.

§259  3DLDF-1.1.5.1  NAMESPACE SORTING  71

259. External. ⟨ extern declaration of namespace Sorting 259 ⟩ ≡

namespace Sorting { extern const unsigned short ; extern const unsigned short ; extern const unsigned short ; extern const unsigned short ;

};

This code is used in section 306.

260. Picture.

format Picture int

261. Picture class definition. [LDF 2002.08.06.] Note that Label has a public static data member named , which is used for globally enabling or suppressing putting Labels onto Pictures (see above).

Picture ::do labels , on the other hand, is for enabling or suppressing the output of Labels for a single Picture. If a Picture is output when do labels is false for that Picture, the Labels are not output. However, the Labels are still on the Picture. If do labels is reset to true and the Picture is output again, the Labels will be output this time.

[LDF 2002.04.25.] Added do labels . It’s set to true in the constructors and can be set to false using suppress labels ( ). ⟨ Define classes 253 ⟩ +≡

class Picture { Transform transform; vector⟨Shape ∗⟩ shapes ; vector⟨Label ∗⟩ labels ; bool do labels ;

public: ⟨ Declare Picture functions 263 ⟩

};

262. Constructors.

263. Default constructor. (No arguments). ⟨ Declare Picture functions 263 ⟩ ≡

Picture( );

See also sections 265, 267, 269, 270, 272, 274, 275, 276, 280, 283, 285, 286, 288, 289, 291, 293, 295, 298, 299, 300, and 301. This code is used in section 261.

264. ⟨ Define Picture functions 264 ⟩ ≡

Picture ::Picture( )

: do labels (true) { }

See also sections 271, 273, 277, 281, 284, 287, 290, 292, 294, 296, 417, 440, 587, 588, 589, 590, 592, 593, 594, 595, 596, 597,

and 598. This code is used in sections 305 and 633.

265. Copy constructor. !! PORTING. [LDF 2002.12.05.] Moved to points.web because I’ve moved Picture ::operator=( ) to points.web, so the latter is undefined in this file. I’ve had to do these things because of differences between the DEC compiler and the GNU compiler. ⟨ Declare Picture functions 263 ⟩ +≡

Picture(const Picture &p);

266. Destructor. [LDF 2002.10.20.] Picture does not currently have a destructor. clear ( ) takes care of deallocating memory and clearing shapes and labels . Defining a destructor would probably cause problems.

267. Assignment. TO DO: Add TEX macro for “PORTING”. !! PORTING. [LDF 2002.12.05.] Moved to points.web because Picture ::clear ( ) and Label ::get copy ( ) are undefined in this file. This didn’t cause a problem with the DEC compiler, but it does with the GNU Compiler. ⟨ Declare Picture functions 263 ⟩ +≡

void operator=(const Picture &p);

268. Adding elements.

269. Add Picture. This function must be defined in points.web, because it uses Point, which is an incompletely defined class here.

[LDF 2002.04.17.] It seems to be most useful to have the argument Picture p be non-const, in order to be able to shift it and add it to ∗this multiple times. For this to work, it must be possible to set p.transform to the identity matrix afterwards. It is possible to do this explicitly by calling reset transform( ) on the Picture following the call to operator+=( ), but it’s more convenient to have it done automatically. If it turns out to be useful, I can add a const version of this function.

Log

[LDF 2002.04.17.] Added this declaration.

⟨ Declare Picture functions 263 ⟩ +≡ void operator+=(const Picture &p);

270. Add Shape. ⟨ Declare Picture functions 263 ⟩ +≡

void operator+=(Shape ∗s);

§271  3DLDF-1.1.5.1  ADD SHAPE 73

271. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::operator+=(Shape ∗s) {

shapes .push back (s); }

272. Add Label. ⟨ Declare Picture functions 263 ⟩ +≡

void operator+=(Label ∗label );

273. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::operator+=(Label ∗label ) {

labels .push back (label ); }

274. Suppress Labels. [LDF 2002.04.25.] Added this function. Sometimes it’s irritating to have the labels when a Picture is copied and transformed, and both the original and the transformed versions are output. ⟨ Declare Picture functions 263 ⟩ +≡

inline void suppress labels ( ) {

do labels = false; }

275. Unsuppress Labels.

Log

[LDF 2002.12.20.] Added this function.

⟨ Declare Picture functions 263 ⟩ +≡ inline void unsuppress labels ( ) {

do labels = true; }

276. Kill Labels.

Log

[LDF 2003.05.07.] Added this function.

⟨ Declare Picture functions 263 ⟩ +≡ void kill labels ( );

74  KILL LABELS  3DLDF-1.1.5.1 §277

277. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::kill labels ( )

{

labels .clear ( ); }

278. Transformations. Transformations for Pictures are saved up, and then performed when the Picture is output.

279. Affine transformations.

280. Scale. ⟨ Declare Picture functions 263 ⟩ +≡

Transform scale(real x, real y = 1, real z = 1);

281. ⟨ Define Picture functions 264 ⟩ +≡

Transform Picture ::scale(real x, real y, real z)

{

return transform.scale(x, y, z); }

282. Shift. (Translation.)

283. real version. ⟨ Declare Picture functions 263 ⟩ +≡

Transform shift (real x, real y = 0, real z = 0);

284. shift ( ) returns a Transform representing the shift, not ∗this . This makes it possible to apply the transformation to other objects. ⟨ Define Picture functions 264 ⟩ +≡

Transform Picture ::shift (real x, real y, real z)

{

return transform.shift (x, y, z); }

285. Point version. This function must defined in points.web, because Point is an incompletely defined type here. ⟨ Declare Picture functions 263 ⟩ +≡

Transform shift (const Point &p);

286. Rotation around the main axes. rotate( ) will perform rotation about the x, y and z-axes in that order if called with multiple, non-zero arguments. Rotation only about the y and/or z-axis requires one or two dummy 0 arguments so that rotate( ) “knows” about which axis (or axes) to rotate. ⟨ Declare Picture functions 263 ⟩ +≡

Transform rotate(const real x, const real y = 0, const real z = 0); 287. ⟨ Define Picture functions 264 ⟩ +≡

Transform Picture ::rotate(const real x, const real y, const real z) {

return transform.rotate(x, y, z); }

288. Rotation around an arbitrary axis. [LDF 2002.05.03.] This function is defined in points.web, because it has Point arguments, and Point is an incomplete type in this file.

Log

[LDF 2002.05.03.] Added this declaration. [LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now

overloads rotate( ) with three real arguments.

⟨ Declare Picture functions 263 ⟩ +≡

Transform rotate(const Point &p0 , const Point &p1 , const real angle = 180); /∗ Remember to add shear! ∗/

289. Set transform.

Log

[LDF 2003.01.17.] Made non-inline and changed t from plain Transform to const Transform &.

⟨ Declare Picture functions 263 ⟩ +≡ Transform set transform(const Transform &t);

290. ⟨ Define Picture functions 264 ⟩ +≡

Transform Picture ::set transform(const Transform &t) {

transform = t;

return t; }

291. Multiplying transform.

Log

[LDF 2003.01.17.] Changed t from plain Transform to const Transform &.

⟨ Declare Picture functions 263 ⟩ +≡ Transform operator∗=(const Transform &t);

76  MULTIPLYING TRANSFORM  3DLDF-1.1.5.1 §292

292. ⟨ Define Picture functions 264 ⟩ +≡

Transform Picture ::operator∗=(const Transform &t) {

transform ∗= t; return t;

}

293. Show. ⟨ Declare Picture functions 263 ⟩ +≡

void show (string text = , bool stop = false);

294. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::show (string text , bool stop) {

cout ≪ ␣ ␣ ≪ text ≪ ≪ flush; transform.show ( ); cout ≪ ␣ ␣ ≪ shapes .size( ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ labels .size( ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ do labels ≪ endl ≪ flush; cout ≪ ␣ ; for (vector⟨Shape ∗⟩::iterator iter = shapes .begin( ); iter ≠ shapes .end ( ); ^{++}iter ) (∗∗iter ).show ( ); if (stop) {

cout ≪ ␣ ␣ ␣ ≪ flush; getchar ( );

} cout ≪ ␣ ␣ ≪ flush;

}

295. Show transform. ⟨ Declare Picture functions 263 ⟩ +≡

void show transform(string text =  ␣    ␣  );

§296  3DLDF-1.1.5.1  SHOW TRANSFORM 77

296. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::show transform(string text )

{

transform.show (text ); }

297. Output. [LDF 2002.09.18.] Added the optional real arguments min x proj , max x proj , etc. The purpose of these is to suppress output of Shapes whose projective extremes fall outside of these limits, whereby the “z” values are not currently checked. They are not set for a particular Focus or Picture, but for a particular invocation of output ( ). I believe the default values are sufficiently generous, but they can always be changed if it turns out that they’re not. Alternatively, I could store them in the Picture or the Focus, if that turns out be more convenient. They are checked in Picture ::check projection limits ( ).

298. Focus argument. ⟨ Declare Picture functions 263 ⟩ +≡

void output (const Focus &f, const unsigned short projection = Projections :: , real factor = 1, const unsigned short sort value = Sorting :: , 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);

299. No Focus argument. ⟨ Declare Picture functions 263 ⟩ +≡

void output (const unsigned short proj = Projections :: , real factor = 1, const unsigned short sort value = Sorting :: , 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);

300. Clear. Defined in points.web. ⟨ Declare Picture functions 263 ⟩ +≡

void clear ( );

301. Reset transform. [LDF 2002.04.17.] Added this function. ⟨ Declare Picture functions 263 ⟩ +≡

inline void reset transform( )

{

transform.reset ( ); }

302. Global variables. ⟨ Global variables 18 ⟩ +≡

Picture current picture;

303. ⟨ Declarations for the header file 21 ⟩ +≡

extern Picture current picture;

304. Putting Picture and Label together.

78  PUTTING PICTURE AND LABEL TOGETHER  3DLDF-1.1.5.1 §305

305. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Declare namespace Projections 256 ⟩ ⟨ Declare namespace Sorting 258 ⟩ ⟨ Define classes 253 ⟩ ⟨ Initialize static Label data members 254 ⟩ ⟨ Global variables 18 ⟩ ⟨ Define Picture functions 264 ⟩

§306  3DLDF-1.1.5.1  PUTTING PICTURE AND LABEL TOGETHER 79

306. This is what’s written to pictures.h. ⟨ 306 ⟩ ≡

⟨ extern declaration of namespace Projections 257 ⟩

⟨ extern declaration of namespace Sorting 259 ⟩

⟨ Define classes 253 ⟩

⟨ Declarations for the header file 21 ⟩

307. Point (points.web).

[LDF 2002.10.20.] Point is the most basic drawable (not fillable!) type. All of the other Shapes contain Points and are ultimately defined by their Points and the relationships among them. It is therefore understandable that points.web is by far the largest of the source files of 3DLDF and that Point has the most functions of any class in 3DLDF. Many of the functions in the other classes do little more than apply the Point version of the function to their Points.

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

308. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include

309. Point class definition. [LDF 2002.10.20.]

• world coordinates contains the coordinates of the Point in the global coordinate system.

• user coordinates and view coordinates are not currently used.

• user coordinates is intended for use with a user-defined coordinate system. For example, it may be convenient to define a coordinate system based on a plane defined by an object in a drawing. The user-defined coordinate system will be defined in terms of the global coordinate system and the world coordinates can be derived from the user coordinates by using the appropriate transformation.

• projective coordinates is used for projecting the three-dimensional Points onto two-dimensions for output. Currently, the only projection routines are for perspective and parallel projection. I plan to add others (axionometric, etc.) soon.

• transform is used for storing the transformations that are applied the Point. It is not necessary to update world coordinates (or user coordinates , if they’re being used) every time a Point is transformed. The transformations can be saved up and their result applied to the Point when needed. This will be when the Point or the Shape or Label containing it is output, or when a function (such as get x ( )) requires up-to-date coordinate values.

• drawdot value, drawdot color , and pen are used in the drawing and undrawing functions and in Point ::output ( ). They are explained below.

80 POINT CLASS DEFINITION 3DLDF-1.1.5.1 §309

• projective extremes is used in outputting Pictures. It’s for culling Points that are invisible using a particular Focus, or that lie outside the boundaries passed as arguments to Picture ::output ( ).

• do output is for enabling or suppressing output of a Point. It’s needed when a Point has been culled, as described above. Culling does not actually remove a Point (or any other Shape) from a Picture, so a way of suppressing output is needed. However, it must be possible to enable output again, because the Picture may be output again using a different Focus and/or different values for the boundaries.

• measurement units is a string that is attached to the numerical values of the projective coordinates when the METAPOST code is output to out stream. It is currently and at the present time (2002.10.20), it’s not a good idea to use more than one value for a single drawing. Changing this will only become urgent when I start writing the input routine. TO DO.

Log

[LDF 2003.04.01.] Added , , , and . They are used in label ( ) for labelling Points using the values in world coordinates , projective coordinates , etc.

[LDF 2003.05.06.] Changed  ,  ,  , and  to  ,
,  , and  . Added  ,  ,

, and for suppressing the z-coordinate.

[LDF 2003.05.20.] Added .

format Point Shape

⟨ Define class Point 309 ⟩ ≡

class Point : protected Shape {

friend Transform Transform ::align with axis (Point, Point, char); private: Transform transform;

bool on free store; valarray⟨real⟩ world coordinates ; valarray⟨real⟩ user coordinates ; valarray⟨real⟩ view coordinates ; valarray⟨real⟩ projective coordinates ; signed short drawdot value; const Color ∗drawdot color ; string pen;

protected: /∗ LDF 2002.09.18. Added projective extremes . It contains the minimum and maximum

values for x, y, and z in projective coordinates . ∗/ valarray⟨real⟩ projective extremes ; bool do output ; /∗ LDF 2002.09.18. Added this data member. ∗/

public: static string measurement units ; static real ; static real ; static const short ; static const short ; static const short ; static const short ; static const short ; static const short ; static const short ; static const short ; static const short ; ⟨ Declare Point constructors 324 ⟩ ⟨ Declare Point functions 329 ⟩

};

This code is used in sections 633 and 634.

§310  3DLDF-1.1.5.1  POINT CLASS DEFINITION 81

310.

Log

LDF 2003.04.01. Added initialization of , , , and . They are used in label ( ) for labelling Points using the values in world coordinates , projective coordinates , etc. !! KLUDGE: Using the macro because the numeric limits template doesn’t seem to be available under GNU/Linux using GCC, at least not on the computer I’m using.

LDF 2003.05.06. Added initialization of  ,  ,  , and
LDF 2003.05.22. BUG FIX: Changed  so that it’s one less than  .

Previously, it had the same value.

⟨ Define static Point data members 310 ⟩ ≡ string Point ::measurement units = ; real Point :: = 0; real Point :: = 0;

const short Point ::  =  ;
const short Point ::  =  − 1;
const short Point ::  =  − 2;
const short Point ::  =  − 3;
const short Point ::  =  − 4;
const short Point ::  =  − 5;
const short Point ::  =  − 6;
const short Point ::  =  − 7;
const short Point ::  =  − 8;

This code is used in section 633.

311. Type definitions and utility structures. Some of the types are simple enough to be defined using typedef , but others require struct definitions.

Log

[LDF 2002.04.10.] Added these formatting instructions. They are duplicated using “@s” in

cwdriver.web.

format point pair Point
format bool point Point
format bool point pair Point
format bool point quadruple Point
format bool real point Point

312. point pair and bool point pair. ⟨ Type definitions 15 ⟩ +≡

typedef pair⟨Point, Point⟩ point pair; typedef pair⟨bool point, bool point⟩ bool point pair;

313. bool point.

Log

LDF 2002.04.15. Added this section. bool point was formerly a simple typedef . I’ve had to change it to a struct, in order for Point ::intersection points ( ) to return one.

82 BOOL POINT  3DLDF-1.1.5.1  §313

LDF 2003.05.30. Removed the definition of the default constructor to the new section ⟨ Define bool point functions 314 ⟩. See below for an explanation.

⟨ Type definitions 15 ⟩ +≡

struct bool point { bool b; Point pt ; bool point( ); bool point(bool bb, const Point &ppt ) : b(bb), pt (ppt ) { } void operator=(const bool point &bp) {

b = bp.b;

pt = bp.pt ; }

};

§314  3DLDF-1.1.5.1  BOOL POINT  83

314.

Log

LDF 2003.05.30. Added this section, and the definition of bool point(void). Previously, b and pt were not set, so their values were unpredictable. I had to remove the definition from the declaration of bool point, because isn’t defined, when the declaration is read by the compiler.

⟨ Define bool point functions 314 ⟩ ≡ bool point ::bool point( ) {

b = false; pt = ;

}

This code is cited in section 313. This code is used in section 633.

315. bool point quadruple. It would be possible to define this as a pair of pairs, but then the individual element s would be nested inconveniently. ⟨ Type definitions 15 ⟩ +≡

struct bool point quadruple { bool point first ; bool point second ; bool point third ; bool point fourth; bool point quadruple( ); bool point quadruple(bool point a, bool point b, bool point c, bool point d) : first (a), second (b), third (c), fourth(d) { } void operator=(const bool point quadruple &arg ) {

first .b = arg .first .b;

first .pt = arg .first .pt ;

second .b = arg .second .b; second .pt = arg .second .pt ; third .b = arg .third .b; third .pt = arg .third .pt ; fourth.b = arg .fourth.b; fourth.pt = arg .fourth.pt ;

} };

84  DEFAULT CONSTRUCTOR FOR BOOL POINT QUADRUPLE  3DLDF-1.1.5.1 §316

316. Default Constructor for bool point quadruple.

Log

LDF 2003.06.1. Added this section. Redefined the default constructor bool point quadruple(void), so that first , second , third , and fourth are all set to . In order to do this, it was necessary to remove the definition from the declaration of bool point quadruple, because when the compiler sees it, isn’t defined yet.

⟨ Define bool point quadruple functions 316 ⟩ ≡ bool point quadruple ::bool point quadruple( ) : first ( ), second ( ), third ( ),

fourth( ) { }

This code is used in section 633.

317. bool real point. [LDF 2002.04.10.] Added this type. Line ::intersection point ( ) returns a bool real point. I may change Point ::intersection point ( ) so that it calls Line ::intersection point ( ) and returns a bool real point, too.

[LDF 2002.10.26.] !! KLUDGE: \newline inserted in the text above to avoid overfull boxes. ⟨ Type definitions 15 ⟩ +≡

struct bool real point { bool b; real r; Point pt ; bool real point( ); /∗ Default constructor. ∗/ bool real point(const bool real point &brp) : b(brp.b), r(brp.r), pt (brp.pt ) { } /∗ Copy constructor. ∗/ bool real point(const bool &bb, const real &rr , const Point &ppt ) : b(bb), r(rr ), pt (ppt ) { } /∗ Construcor with bool, real, and Point arguments. ∗/ void operator=(const bool real point &brp) /∗ Assignment operator. ∗/ {

b = brp.b;

r = brp.r;

pt = brp.pt ; }

};

§318  3DLDF-1.1.5.1  DEFAULT CONSTRUCTOR FOR BOOL REAL POINT 85

318. Default Constructor for bool real point.

Log

LDF 2003.06.1. Added this section. Redefined the default constructor bool real point(void), so that b is set to false, r is set to , and pt is set to . In order to do this, it was necessary to remove the definition from the declaration of bool real point, because when the compiler sees

it,  and  aren’t defined yet.

⟨ Define bool real point functions 318 ⟩ ≡ bool real point ::bool real point( )

: b(false), r(  ), pt (  ) { }

This code is used in section 633.

319. Global constants. [LDF 2002.09.25.] Changed this section. I now know that consts have internal linkage by default and that I must declare them with extern in order to give them external linkage. ⟨ Global constants 22 ⟩ +≡

extern const Point ( , , ); extern const Point origin(0, 0, 0);

extern const bool point  (false,  );
extern const bool point pair  (  ,

);

extern const bool real point  (false,  ,  );
extern const bool point quadruple  (  ,
,  ,  );

320. ⟨ Declarations for the header file 21 ⟩ +≡

extern const Point ; extern const Point origin; extern const bool point ; extern const bool point pair ; extern const bool real point ; extern const bool point quadruple ;

321. Constructors and setting functions.

86  CONSTRUCTORS AND SETTING FUNCTIONS  3DLDF-1.1.5.1 §322

322. The valarrays I use for the various sets of coordinates can be declared in the class declaration, but neither can their size be set nor can they be initialized. null coordinates is defined in pspglb.web and is a valarray of reals with 4 elements = 0. Setting world coordinates , etc. to null coordinates makes them the right size.

323. Initialize coordinates and limits.

Log

[LDF 2002.4.3.] Now setting world coordinates [3], user coordinates [3], and view coordinates [3] = 1. It fixes a bug that showed up when I tried to shift a Point with coordinates ≡ 0.

⟨ Initialize coordinates and limits 323 ⟩ ≡ #ifdef

world coordinates = null coordinates ; user coordinates = null coordinates ; view coordinates = null coordinates ; projective coordinates = null coordinates ;

#endif #ifdef

world coordinates .resize(4, 0); user coordinates .resize(4, 0); view coordinates .resize(4, 0); projective coordinates .resize(4, 0);

#if 1

pen = ; #endif

transform.reset ( ); #endif

world coordinates [3] = 1; user coordinates [3] = 1; view coordinates [3] = 1; projective extremes .resize(6, 0);

This code is used in sections 325, 328, and 332.

324. Default version. No arguments. ⟨ Declare Point constructors 324 ⟩ ≡

Point( );

See also sections 327 and 331. This code is used in section 309.

§325  3DLDF-1.1.5.1  DEFAULT VERSION 87

325. ⟨ Define Point constructors 325 ⟩ ≡

Point ::Point( )

{ ⟨ Initialize coordinates and limits 323 ⟩ on free store = false; do output = true;

}

See also sections 328 and 332. This code is used in section 633.

326. Three real values.

327. Constructor.

Log

[LDF 2002.12.01.] Made arguments const.

⟨ Declare Point constructors 324 ⟩ +≡

Point(const real x, const real y =  , const real z =  );

328. ⟨ Define Point constructors 325 ⟩ +≡

Point ::Point(const real x, const real y, const real z)

{ ⟨ Initialize coordinates and limits 323 ⟩ on free store = false; do output = true;

#if 0 /∗ [LDF 2002.10.23.] user transform is not currently in use. It is intended for use in implementing

user-defined coordinate systems. ∗/ if (user transform.is identity ( ))

#endif

world coordinates [0] = x; world coordinates [1] = y; world coordinates [2] = z; world coordinates [3] = 1;

}

329. Setting function.

Log

[LDF 2002.12.01.] Made arguments const.

[LDF 2003.03.25.] Changed this function, so that it returns ∗this instead of void. This makes it possible to chain invocations of this function.

⟨ Declare Point functions 329 ⟩ ≡

const Point &set (const real x, const real y =  , const real z =  );

See also sections 333, 338, 340, 342, 344, 346, 349, 350, 352, 355, 357, 360, 362, 365, 367, 370, 372, 375, 377, 380, 382, 384, 385, 387, 389, 393, 396, 398, 400, 401, 404, 406, 408, 412, 414, 419, 421, 436, 438, 442, 446, 448, 450, 454, 456, 458, 460, 463, 464, 466, 467, 469, 470, 472, 473, 475, 477, 482, 484, 486, 488, 489, 491, 493, 495, 501, 505, 507, 510, 512, 518, 521, 523, 525, 527, 529, 532, 536, 538, 540, 542, 544, 546, 548, 551, 553, 555, 557, 560, 567, 569, 572, and 573.

This code is used in section 309.

88  SETTING FUNCTION  3DLDF-1.1.5.1 §330

330. ⟨ Define Point functions 330 ⟩ ≡

const Point &Point ::set (const real x, const real y, const real z)

{ Point p(x, y, z); ∗this = p; do output = true; return ∗this ; /∗ LDF 2003.03.25. Added this. Formerly, the return value was void. ∗/

}

See also sections 334, 339, 341, 343, 345, 347, 351, 356, 358, 361, 363, 366, 368, 371, 373, 376, 378, 381, 383, 386, 388, 390, 391, 394, 395, 397, 399, 405, 407, 409, 413, 415, 420, 422, 437, 443, 444, 445, 447, 449, 451, 455, 457, 459, 461, 476, 478, 483, 485, 487, 490, 492, 494, 496, 502, 506, 508, 511, 513, 519, 522, 524, 526, 528, 530, 533, 537, 539, 541, 543, 545, 547, 549, 552, 554, 556, 561, 562, 563, 564, 565, 566, 568, 570, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 645, 647, 681, 760, 823, 824, 832, 833, 841, 842, 860, 861, 945, 948, 949, and 950.

This code is used in sections 633, 657, 694, and 980.

331. Copy constructor. ⟨ Declare Point constructors 324 ⟩ +≡

Point(const Point &p);

332. ⟨ Define Point constructors 325 ⟩ +≡

Point ::Point(const Point &p)

{ ⟨ Initialize coordinates and limits 323 ⟩ ∗this = p; on free store = false; do output = true;

}

333. Setting function. [LDF 2002.10.23.] This function is unnecessary, because it does nothing that the assignment operator can’t do. However, I’ve tried to use set ( ) a couple of times with a Point argument, so it’s convenient to have it. If nothing else, it prevents compilation from failing occasionally.

Log

[LDF 2002.10.23.] Added this function.

⟨ Declare Point functions 329 ⟩ +≡ void set (const Point &p); 334. ⟨ Define Point functions 330 ⟩ +≡

void Point ::set (const Point &p)

{ ∗this = p; do output = true;

}

335. Pseudo-constructor for dynamic allocation. create new < Point > ( ) is meant to be used instead of new ( ) for dynamic allocation of Points. It calls the default constructor (without arguments) and then sets on free store to true.

[LDF 2002.10.11.] It is used in various Point functions, and in Path and some classes derived from Path, currently Ellipse, Reg Polygon, and Rectangle. It is intended that objects of these types be declared, i.e., unlike Reg Cl Plane Curve, they are not meant to be used only as base classes. Reg Cl Plane Curve does not use create new < Point > ( ) and it is unlikely that other classes of this kind will use it.

Log

[LDF 2003.12.30.] Replaced the non-template create new point ( ) functions with versions of the create new ( ) template function. I believe the definitions shouldn’t be necessary, but at present they are. Without them, the templates aren’t instantiated.

[LDF 2003.12.30.] Changed the argument. It’s now a const Point ∗.

[LDF 2003.12.30.] Removed default argument “0”, because this caused a compiler error when using the DEC C^{++} compiler. Apparently, it suffices to declare a default argument in the template declaration.

336. Pointer argument. ⟨ Declare non-member template functions for Point 336 ⟩ ≡

Point ∗create new (const Point ∗p);

See also section 337. This code is used in sections 633 and 634.

337. Referece argument.

Log

[LDF 2003.12.30.] Changed argument from Point to const Point &.

⟨ Declare non-member template functions for Point 336 ⟩ +≡ Point ∗create new (const Point &p);

338. Destructor.

Log

[LDF 2003.08.27.] Added a virtual destructor with an empty definition, because GCC with the “-Wall” option issued the following warning: “‘class Point’ has virtual functions but non-virtual destructor”.

90  DESTRUCTOR  3DLDF-1.1.5.1 §339

⟨ Declare Point functions 329 ⟩ +≡ virtual ∼Point( ); 339. ⟨ Define Point functions 330 ⟩ +≡

Point ::∼Point( )

{ }

340. Assignment.

Log

[LDF 2003.03.25.] Changed this function, so that it returns p instead of void. This makes it possible to chain invocations of this function.

⟨ Declare Point functions 329 ⟩ +≡ const Point &operator=(const Point &p);

341. ⟨ Define Point functions 330 ⟩ +≡

const Point &Point ::operator=(const Point &p)

{ transform = p.transform; drawdot value = p.drawdot value; drawdot color = p.drawdot color ;

#if 1

pen = p.pen;

#endif world coordinates = p.world coordinates ; user coordinates = p.user coordinates ; view coordinates = p.view coordinates ; projective coordinates = p.projective coordinates ; projective extremes = p.projective extremes ; /∗ LDF 2002.09.18. Added this line. I think that it

shouldn’t be necessary to do this, but I’ve added it just to be sure. ∗/ do output = true; /∗ [LDF 2002.09.18.] Probably not necessary, but I might as well. ∗/ return p; /∗ LDF 2003.03.25. Added this. Formerly, the return value was void. ∗/

}

342. Set on free store.

Log

[LDF 2003.12.29.] Made non-inline.

⟨ Declare Point functions 329 ⟩ +≡ virtual bool set on free store(bool b = true);

§343  3DLDF-1.1.5.1  SET ON FREE STORE 91

343. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::set on free store(bool b)

{ on free store = b; return b;

}

344. Clear. I need this function because it’s a virtual function in Shape.

Log

[LDF 2002.10.27.] Redefined this function. Formerly, it was inline and empty. Now it sets all of the x, y, and z coordinates to 0, and resets transform. It doesn’t seem worthwhile to set drawdot value, drawdot color , or pen to any particular values.

⟨ Declare Point functions 329 ⟩ +≡ void clear ( );

345. ⟨ Define Point functions 330 ⟩ +≡

void Point ::clear ( )

{

for (int i = 0; i < 4; i^{++}) {

world coordinates [i] = user coordinates [i] = view coordinates [i] = projective coordinates [i] = 0; } transform.reset ( ); return;

}

346. Clean. ⟨ Declare Point functions 329 ⟩ +≡

void clean(int factor = 1); 347. ⟨ Define Point functions 330 ⟩ +≡

void Point ::clean(int factor )

{ apply transform( ); real eps = epsilon( ) ∗ factor ; for (int i = 0; i < 4; i^{++})

if (fabs (world coordinates [i]) < eps ) world coordinates [i] = 0.0; }

348. Returning elements and information.

349. Is identity. ⟨ Declare Point functions 329 ⟩ +≡

inline bool is identity ( )

{

return (transform.is identity ( )); }

350. Epsilon.

Log

[LDF 2004.1.2.] Now returning different values, depending on whether real is float or double. TO DO: Try to find out what values would be best. It will be necessary to check how good the value for double is.

[LDF 2004.1.2.] Made epsilon( ) non-inline.

⟨ Declare Point functions 329 ⟩ +≡ static real epsilon( );

351. ⟨ Define Point functions 330 ⟩ +≡

real Point ::epsilon( )

{ #if

return .000000001;

#else

return .00001;

#endif }

352. Get Line. Defined in lines.web. Must be defined there, because Line is an incomplete type here. [LDF 2002.04.12.] Removed this function to lines.web.

⟨ Declare Point functions 329 ⟩ +≡ Line get line(const Point &pt ) const;

353. Getting coordinates. ?? Change get x ( ), etc., back to inline??

354. Get all coordinates. [LDF 2002.09.19.] Added this function. ?? [LDF 2002.12.01.] Can I make the Focus ∗ argument const? What is the syntax for a pointer to a const, as opposed to a const pointer? Look up!! Make sure I change this is 3DLDF.texi if I change it here!

355. Non-const version. [LDF 2002.09.19.] Added this function. ⟨ Declare Point functions 329 ⟩ +≡

valarray⟨real⟩ get all coords (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1);

356. ⟨ Define Point functions 330 ⟩ +≡

valarray⟨real⟩ Point ::get all coords (char coords , const bool do persp, const bool do apply , Focus

∗f, const unsigned short proj , real factor )

{ if (do apply ) apply transform( ); coords = tolower (coords ); if (coords ≡ ) return world coordinates ; else if (coords ≡ ) return view coordinates ; else if (coords ≡ ) return user coordinates ; else if (coords ≡ ) {

if (do persp) { if (f ≡ 0) f = &default focus ; project (∗f, proj , factor );

}

return projective coordinates ; } else {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ␣ ≪ coords ≪

␣ ␣ ␣ ≪ flush;

return world coordinates ; }

}

357. const version. [LDF 2002.09.19.] Added this function. ⟨ Declare Point functions 329 ⟩ +≡

valarray⟨real⟩ get all coords (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1) const;

358. ⟨ Define Point functions 330 ⟩ +≡

valarray⟨real⟩ Point ::get all coords (char coords , const bool do persp, const bool do apply , Focus

∗f, const unsigned short proj , real factor ) const

{ Point p(∗this ); valarray⟨real⟩ v = p.get all coords (coords , do persp, do apply , f); return v;

}

359. Get coord. [LDF 2002.09.14.] Added get coord ( ). Fixing a bug that caused get x ( ), etc., to call project ( ) multiple times when doing Path ::output ( ).

94  NON-CONST VERSION  3DLDF-1.1.5.1 §360

360. Non-const version. [LDF 2002.10.27.] The argument c refers to either the x, y, z, or w coordinate. ⟨ Declare Point functions 329 ⟩ +≡

real get coord (char c, char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1);

361. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get coord (char c, char coords , const bool do persp, const bool do apply , Focus ∗f, const

unsigned short proj , real factor )

{ if (do apply ) apply transform( ); if (f ≡ 0) f = &default focus ; unsigned short ctr ; c = tolower (c); if (c ≡ ) ctr = 0; else if (c ≡ ) ctr = 1; else if (c ≡ ) ctr = 2; else if (c ≡ ) ctr = 3; else {

cerr ≪ ␣ ␣ ␣ ≪ ␣ ␣ ␣ ≪ c ≪ ≪

␣ ≪ flush; ctr = 0;

} coords = tolower (coords ); if (coords ≡ ) return world coordinates [ctr ]; else if (coords ≡ ) return user coordinates [ctr ]; else if (coords ≡ ) {

if (do persp) project (∗f, proj , factor );

return projective coordinates [ctr ]; } else if (coords ≡ ) return view coordinates [ctr ]; else {

cerr ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ coords ≪

endl ≪ ␣ ≪ flush; return ;

} }

362. const version. ⟨ Declare Point functions 329 ⟩ +≡

§363  3DLDF-1.1.5.1  CONST VERSION 95

real get coord (char c, char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1) const; 363. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get coord (char c, char coords , const bool do persp, const bool do apply , Focus ∗f, const

unsigned short proj , real factor ) const

{ Point p(∗this ); return p.get coord (c, coords , do persp, do apply , f, proj , factor );

}

364. Get x.

365. Non-const version. ⟨ Declare Point functions 329 ⟩ +≡

real get x (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1);

366. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get x (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor )

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

367. const version. ⟨ Declare Point functions 329 ⟩ +≡

real get x (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1) const;

368. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get x (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor ) const

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

369. Get y.

370. Non-const version. ⟨ Declare Point functions 329 ⟩ +≡

real get y (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1); 371. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get y (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor )

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

372. const version. ⟨ Declare Point functions 329 ⟩ +≡

real get y (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1) const;

373. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get y (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor ) const

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

374. Get z.

375. Non-const version. ⟨ Declare Point functions 329 ⟩ +≡

real get z (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1);

376. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get z (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor )

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

377. const version. ⟨ Declare Point functions 329 ⟩ +≡

real get z (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1) const;

378. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get z (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor ) const

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

379. Get w.

380. Non-const version. ⟨ Declare Point functions 329 ⟩ +≡

real get w (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1);

381. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get w (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor )

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

382. const version. ⟨ Declare Point functions 329 ⟩ +≡

real get w (char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , real factor = 1) const;

383. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get w (char coords , const bool do persp, const bool do apply , Focus ∗f, const unsigned

short proj , real factor ) const

{

return get coord ( , coords , do persp, do apply , f, proj , factor ); }

384. Get transform.

Log

[LDF 2002.10.27.] Made this function const.

⟨ Declare Point functions 329 ⟩ +≡ inline Transform get transform( ) const {

return transform; }

385. Get copy.

Log

[LDF 2002.10.27.] Made this function const.

⟨ Declare Point functions 329 ⟩ +≡ Shape ∗get copy ( ) const;

98  GET COPY  3DLDF-1.1.5.1 §386

386. ⟨ Define Point functions 330 ⟩ +≡

Shape ∗Point ::get copy ( ) const{ Point ∗p = create new < Point > (0); ∗p = ∗this ; return static cast⟨Shape ∗⟩(p); }

387. Is on free store.

Log

[LDF 2004.01.06.] Made non-inline.

⟨ Declare Point functions 329 ⟩ +≡ bool is on free store( ) const;

388. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::is on free store( ) const

{

return on free store; }

389. Slope. [LDF 2002.10.27.] slope( ) returns the slope of the trace of the line from ∗this to p on the plane indicated by the char arguments m and n. These should be , , , , , or .

Log

[LDF 2002.10.27.] Now using world coordinates directly instead of “get” functions.

[LDF 2002.10.27.] Changed argument p from const Point & to Point.

⟨ Declare Point functions 329 ⟩ +≡ real slope(Point p, char m = , char n = ) const;

§390  3DLDF-1.1.5.1  SLOPE 99

390. ⟨ Define Point functions 330 ⟩ +≡

real Point ::slope(Point p, char m, char n) const{ bool = false; /∗ true ∗/ Point a(∗this ); a.apply transform( ); p.apply transform( ); if (a ≡ p) {

  cerr ≪  ␣  ␣  ≪  ␣   ␣   ␣      ␣         ␣

≪ flush; if ( ) {

a.show ( ); p.show ( );

}

return ; } m = tolower (m); n = tolower (n);

if (¬((m ≡  ∨ m ≡  ∨ m ≡ ) ∧ (n ≡  ∨ n ≡  ∨ n ≡ ) ∧ (m ≠ n))) {

  cerr ≪  ␣  ␣  ≪  ␣  ␣    ␣    ␣         ␣   ␣       ␣

␣    ␣   ␣   ␣      ␣ ≪ m ≪ ␣ ≪ n ≪ endl ≪  ␣  ≪

flush; return ;

} int ctr = m − ; real a m coord = a.world coordinates [ctr ]; real p m coord = p.world coordinates [ctr ]; ctr = n − ; real a n coord = a.world coordinates [ctr ]; real p n coord = p.world coordinates [ctr ];

391. We often use slope( ) in order to find out whether a line has slope or not, so an error message is out of place here. A warning is too, probably, but I’m leaving this in here for now, just in case I change my mind. ⟨ Define Point functions 330 ⟩ +≡

if (a m coord ≡ p m coord ) { #if 0

cerr ≪  ␣  ␣  ≪ m ≪

  ␣          ␣  ␣       ␣   ␣     ␣   ␣  ≪  ␣  ;

#endif

return ; } return (a n coord − p n coord )/(a m coord − p m coord ); }

392. Is on segment.

393. Non-const version. [LDF 2002.10.29.] is on segment ( ) returns a bool real with the bool indicating whether ∗this lies on the line segment between p0 and p1 , and a real value t representing the distance of ∗this on the way from p0 to p1 . If the bool is true, then 0 <= t <= 1. If t < 0 or t > 1, then ∗this lies on the line passing through p0 and p1 , but not on the segment. If ∗this doesn’t lie on the line, t will be .

[LDF 2002.10.29.] To check whether ∗this lies on the line, use is on line( ).

Log

[LDF 2002.10.29.] BUG FIX: Added code to check whether the unit vectors ∗this − p0 and p1 − ∗this are equal before calculating r. Before I did this, true was returned for Points that weren’t on the line segment.

[LDF 2002.10.29.] Now using world coordinates directly instead of get x ( ), get y ( ), and get z ( ).

⟨ Declare Point functions 329 ⟩ +≡ bool real is on segment (Point p0 , Point p1 ); 394. ⟨ Define Point functions 330 ⟩ +≡

bool real Point ::is on segment (Point p0 , Point p1 ){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

apply transform( ); p0 .apply transform( ); p1 .apply transform( ); if ( ) {

show ( );

p0 .show ( );

p1 .show ( ); }

if (∗this ≡  ∨ p0 ≡  ∨ p1 ≡  ) {

  cerr ≪  ␣  ␣  ≪  ␣  ␣   ␣      ␣   ␣        ␣ ≪

␣ ␣ ␣ ≪ flush; return pair⟨bool, real⟩(false, );

} bool b; real r; if (p0 ≡ p1 ∧ ∗this ≡ p0 ) {

cerr ≪  ␣  ␣  ≪

      ␣   ␣   ␣         ␣  ␣   ␣  ␣   ␣    ␣      ␣ ≪
      ␣     ␣    ␣  ;

return pair⟨bool, real⟩(false, ); } else if (p0 ≡ p1 ) {

  cerr ≪  ␣  ␣  ≪  ␣  ␣   ␣   ␣   ␣      ␣ ≪
      ␣     ␣    ␣  ;

return pair⟨bool, real⟩(false, ); } else if (∗this ≡ p0 ) {

return pair⟨bool, real⟩(true, 0.0); } else if (∗this ≡ p1 ) {

return pair⟨bool, real⟩(true, 1.0); }

/∗ [LDF 2002.10.29.] Beginning of new code. ∗/ Point v0 (∗this − p0 ); Point v1 (p1 − ∗this ); v0 .apply transform( ); v1 .apply transform( ); if ( ) {

v0 .show ( );

v1 .show ( ); } v0 .unit vector (true); v1 .unit vector (true); if ( ) {

v0 .show ( );

v1 .show ( ); } Point v2 (−v1 ); if ( ) {

v2 .show ( ); } if (v0 ≠ v1 ∧ v0 ≠ v2 ) {

if ( ) cout ≪ ␣ ␣ ;

return pair⟨bool, real⟩(false, ); }

/∗ [LDF 2002.10.29.] End of new code. ∗/

395. [LDF 2002.10.29.] Calculate how far ∗this is on the way from p0 to p1 .

LDF Undated. The value t can be calculated from either the x, y, or z-coordinates. We try them in order and return the first one that works. Because of the limited precision with which we are working, it’s possible that the value of t can differ, depending on what coordinates are used to calculate it. In general, this will not be significant, since we’ll mainly be needing this function to determine whether a Point is on a line segment; the exact value of t will usually not be significant. ⟨ Define Point functions 330 ⟩ +≡

if (p1 .world coordinates [0] ≠ p0 .world coordinates [0])

r = (world coordinates [0]−p0 .world coordinates [0])/(p1 .world coordinates [0]−p0 .world coordinates [0]); else if (p1 .world coordinates [1] ≠ p0 .world coordinates [1])

r = (world coordinates [1]−p0 .world coordinates [1])/(p1 .world coordinates [1]−p0 .world coordinates [1]); else if (p1 .world coordinates [2] ≠ p0 .world coordinates [2])

r = (world coordinates [2]−p0 .world coordinates [2])/(p1 .world coordinates [2]−p0 .world coordinates [2]); else {

cerr ≪  ␣  ␣  ≪

      ␣         ␣  ␣         ␣     ␣   ␣  ≪ flush;

return pair⟨bool, real⟩(false, ); } if (r ≥ 0 ∧ r ≤ 1) b = true; else b = false; return pair⟨bool, real⟩(b, r); }

396. const version.

Log

[LDF 2002.10.29.] Added this function.

⟨ Declare Point functions 329 ⟩ +≡ bool real is on segment (const Point &p0 , const Point &p1 ) const; 397. ⟨ Define Point functions 330 ⟩ +≡

bool real Point ::is on segment (const Point &p0 , const Point &p1 ) const

{ Point a(∗this ); return a.is on segment (p0 , p1 );

}

398. Is on line. [LDF 2002.10.29.] TO DO: Maybe add a non-const version. This isn’t urgent, though.

Log

[LDF 2002.10.29.] Added this function.

⟨ Declare Point functions 329 ⟩ +≡ bool real is on line(const Point &p0 , const Point &p1 ) const;

399. ⟨ Define Point functions 330 ⟩ +≡

bool real Point ::is on line(const Point &p0 , const Point &p1 ) const

{ bool real br = is on segment (p0 , p1 ); if (br .second ≠ ) br .first = true; return br ;

}

400. Is on Plane. [LDF 2003.06.04.] This function returns true, if ∗this lies on the Plane p, otherwise false. It must be defined in planes.web, because Plane is an incomplete type here.

Log

[LDF 2003.06.04.] Added this function.

⟨ Declare Point functions 329 ⟩ +≡ bool is on plane(const Plane &p) const;

401. Is in triangle. [LDF 2003.06.11.] This function returns true, if ∗this lies within the triangle defined by the three Point arguments, otherwise false. Defined in paths.web, because it uses class Path, which is an incompletely defined type here.

Log

[LDF 2003.06.11.] Added this function.

[LDF 2003.06.24.] Removed the argument test points .

⟨ Declare Point functions 329 ⟩ +≡

bool is in triangle(const Point &p0 , const Point &p1 , const Point &p2 , bool verbose = false) const;

402. Transformations.

403. Affine transformations.

404. Rotation around the main axes.

Log

[LDF 2003.01.22.] Replaced body of function. Transform ::rotate( ) returns a Transform representing the rotation only, so I don’t need to use a locally declared Transform t in this function.

⟨ Declare Point functions 329 ⟩ +≡ Transform rotate(const real x, const real y = 0, const real z = 0);

405. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::rotate(const real x, const real y, const real z)

{

return transform.rotate(x, y, z); }

406. Scale.

Log

[LDF 2003.01.22.] Replaced body of function. Transform ::scale( ) returns a Transform representing the rotation only, so I don’t need to use a locally declared Transform t in this function.

⟨ Declare Point functions 329 ⟩ +≡ Transform scale(real x, real y = 1, real z = 1);

407. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::scale(real x, real y, real z)

{

return transform.scale(x, y, z); }

408. Shear.

Log

[LDF 2003.01.22.] Replaced body of function. Transform ::shear ( ) returns a Transform representing the rotation only, so I don’t need to use a locally declared Transform t in this function.

⟨ Declare Point functions 329 ⟩ +≡ Transform shear (real xy , real xz = 0, real yx = 0, real yz = 0, real zx = 0, real zy = 0);

409. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::shear (real xy , real xz , real yx , real yz , real zx , real zy )

{

return transform.shear (xy , xz , yx , yz , zx , zy ); }

410. Shift.

411. Point versions.

§412  3DLDF-1.1.5.1  THREE REAL ARGUMENTS 105

412. Three real arguments. ⟨ Declare Point functions 329 ⟩ +≡

Transform shift (real x, real y = 0, real z = 0);

413. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::shift (real x, real y, real z)

{ Transform t; if (x ≠ 0 ∨ y ≠ 0 ∨ z ≠ 0) transform ∗= t.shift (x, y, z); return t;

}

414. Point argument. ⟨ Declare Point functions 329 ⟩ +≡

Transform shift (const Point &p);

415. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::shift (const Point &p)

{

return shift (p.get x ( ), p.get y ( ), p.get z ( )); }

416. Transform version. Point argument. [LDF 2002.04.24.] Added this function. It’s declared in transfor.web, but must be defined here, because Point is an incomplete type there. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::shift (const Point &p)

{

return shift (p.get x ( ), p.get y ( ), p.get z ( )); }

417. Picture version. Point argument. [LDF 2002.08.08.] Added this function. It’s declared in pictures.web, but must be defined here, because Point is an incomplete type there. ⟨ Define Picture functions 264 ⟩ +≡

Transform Picture ::shift (const Point &p)

{

return shift (p.get x ( ), p.get y ( ), p.get z ( )); }

418. Shift times.

[LDF 2003.01.19.] Note that shift times ( ) will only have an effect if it’s called after a call to shift ( ) and before an operation is applied that causes apply transform( ) to be called.

106  THREE REAL ARGUMENTS  3DLDF-1.1.5.1 §419

419. Three real arguments.

Log

[LDF 2003.01.19.] Added this function.

[LDF 2003.01.22.] Got rid of local Transform t. It wasn’t needed. Now just returning the return value of transform.shift times ( ).

⟨ Declare Point functions 329 ⟩ +≡ Transform shift times (real x, real y = 1, real z = 1);

420. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::shift times (real x, real y, real z)

{

return transform.shift times (x, y, z); }

421. Point argument.

Log

[LDF 2003.01.19.] Added this function.

⟨ Declare Point functions 329 ⟩ +≡ Transform shift times (const Point &p);

422. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::shift times (const Point &p)

{

return transform.shift times (p.get x ( ), p.get y ( ), p.get z ( )); }

423. Alignment with an axis. Declared in transfor.web. Defined here, because it needs Points. [LDF 2002.10.23.] align with axis ( ) returns the Transform needed to align \overrightarrow{p_{0}p_{1}} with one of the main axes.

[LDF 2003.05.04.] BUG: TO DO: Try to find out why I sometimes get erroneous results with rotate(Point, Point, real) (formerly rotate around ( )). I think the problem may be here.

Log

[LDF 2002.12.10.] Made this function a friend in class Point. Now calling p0 .apply transform( ) and p1 .apply transform( ) at the beginning of this function and using p0 .world coordinates and p1 .world coordinates directly instead of get x ( ), get y ( ), and get z ( ).

§424  3DLDF-1.1.5.1  ALIGNMENT WITH AN AXIS 107

424. ⟨ Define Transform functions 169 ⟩ +≡

Transform Transform ::align with axis (Point p0 , Point p1 , char axis )

/∗ Default is the z-axis. ∗/

{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ endl ≪ flush;

p0 .apply transform( ); /∗ LDF 2002.12.10. Added these two lines. ∗/ p1 .apply transform( ); Transform t; axis = tolower (axis ); /∗ Upper- or lowercase is permitted for axis . ∗/

if (axis ≠  ∧ axis ≠  ∧ axis ≠ ) {

  cerr ≪  ␣  ␣                             ␣       ␣        ␣         ␣ ≪

axis ≪ endl ≪  ␣        ␣  ≪ endl ≪ flush;

return t; } real angle;

425. [LDF 2002.10.23.] Shift p0 to origin, and shift p1 the same way, so that the relationship between them remains constant. ⟨ Define Transform functions 169 ⟩ +≡

if (p0 ≠ origin) {

if ( ) { p0 .show ( ); p1 .show ( );

} t.shift (−p0 ); p1 ∗= t; p1 .apply transform( ); p0 .apply transform( );

} ⟨ Normalize point 433 ⟩ /∗ [LDF 2002.10.23.] Transform the Point so that it’s x, y, and z coordinates

are all positive. See below for the explanation. ∗/ if ( ) {

t.show ( ␣ ␣ ␣␣ ); } Point proj on x z plane(p1 ); /∗ [LDF 2002.10.23.] Get the projection of p1 on the x-z plane. ∗/

proj on x z plane.shift (0, −p1 .world coordinates [1]);

if (  ) proj on x z plane.show (  );

108  ALIGNMENT WITH AN AXIS  3DLDF-1.1.5.1 §426

426. [LDF 2002.10.23.] If we’re aligning with the x or y-axis, rotate p1 onto the x-y plane and then to the x-axis. ⟨ Define Transform functions 169 ⟩ +≡

if (axis ≡ ∨ axis ≡ ) { Point pt on x axis ; pt on x axis .set (1); angle = proj on x z plane.angle(pt on x axis ); if ( ) cout ≪ ␣ ␣ ␣ ≪ angle ≪ endl ≪ flush; if (angle ≠ 0 ∧ angle ≠ ) t ∗= p1 .rotate(0, −angle); if ( ) p1 .show ( ␣ ␣ ␣ ␣ ␣ ); angle = p1 .angle(pt on x axis ); if ( ) cout ≪ ␣ ␣ ␣ ≪ angle ≪ endl ≪ flush; if (angle ≠ 0 ∧ angle ≠ ) t ∗= p1 .rotate(0, 0, −angle); if ( ) p1 .show ( ␣ ␣ ␣ ␣ );

}

427. [LDF 2002.10.23.] If we’re aligning with the z-axis, rotate p1 onto the y-z plane and then to the z-axis. ⟨ Define Transform functions 169 ⟩ +≡

else if (axis ≡ ) { Point pt on z axis ; pt on z axis .set (0, 0, 1); /∗ [LDF 2002.10.23.] This assumes that proj on x z plane.get z ( ) ≥ 0. It

should be, but if it isn’t, the following error handling code takes care of the problem. ∗/ if (proj on x z plane.get z ( ) < 0) {

cerr ≪  ␣  ␣  ≪

      ␣ ␣  ≪  ␣        ␣      ␣      ␣    ␣ ≪
      ␣     ␣  ␣  ␣  ≪  ␣   ␣       ␣   ␣    ␣   ␣   ␣   ␣  ≪

endl ≪ endl ≪ flush; pt on z axis .set (0, 0, −1);

}

428.

Log

[LDF 2002.12.10.] Added the following conditional. Trying to fix a bug that occurred while porting to GNU/Linux.

⟨ Define Transform functions 169 ⟩ +≡ 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 );

429. ⟨ Define Transform functions 169 ⟩ +≡

if ( ) cout ≪ ␣ ␣ ␣ ≪ angle ≪ endl ≪ flush; if (angle ≠ 0 ∧ angle ≠ ) t ∗= p1 .rotate(0, angle); if ( ) p1 .show ( ␣ ␣ ␣ ␣ ␣ ); p1 .apply transform( ); 430.

Log

[LDF 2002.12.10.] Added the following conditional. Trying to fix a bug that occurred while porting to GNU/Linux.

[LDF 2003.06.13.] BUG FIX: Changed proj on x z plane to p1 in the “if ” part of the following conditional. The y-coordinate of proj on x z plane is always 0, so angle was always set to 0. I discovered this bug when I tried rotating a Point in the plane of a Reg Polygon about a line from the center of the Reg Polygon in the direction of its normal, and the resulting Point was not in the same plane.

⟨ Define Transform functions 169 ⟩ +≡ if (p1 .world coordinates [1] ≡ 0) angle = 0; else angle = p1 .angle(pt on z axis );

431. ⟨ Define Transform functions 169 ⟩ +≡

if ( ) cout ≪ ␣ ␣ ␣ ≪ angle ≪ endl ≪ flush; if (angle ≠ 0 ∧ angle ≠ ) t ∗= p1 .rotate(−angle); if ( ) p1 .show ( ␣ ␣ ␣ ␣ ); }

432. [LDF 2002.10.23.] If we’re aligning with the y-axis, p1 must be rotated from the x-axis (where it is now) around the z-axis by 90^{∘}. Then it will be on the y-axis. ⟨ Define Transform functions 169 ⟩ +≡

if (axis ≡ ) { t ∗= p1 .rotate(0, 0, 90); if ( ) p1 .show ( ␣ ␣ ␣ ␣ );

} if ( ) {

cout ≪ ␣ ␣ ≪ p1 .magnitude( ) ≪ endl ≪ flush; t.show ( ␣ ␣ ␣ ␣ );

} ∗this ∗= t; if ( ) cout ≪ ␣ ≪ endl ≪ flush; return t; }

110  NORMALIZE POINT  3DLDF-1.1.5.1 §433

433. Normalize point. It makes it easier to determine the correct direction of rotation toward the x-y or y-z plane if p1 ’s coordinates are all >= 0, so we rotate it in order to make them so. The only case that requires more than a rotation around a single axis is the case that x_{p1}, y_{p1}, and z_{p1} are all < 0. It would be nice if I could replace this long conditional with a more elegant construction, but I don’t know one. ⟨ Normalize point 433 ⟩ ≡

{ if ( ) p1 .show ( ␣ ␣ ); if (p1 .world coordinates [0] < 0 ∧ p1 .world coordinates [1] ≥ 0 ∧ p1 .world coordinates [2] ≥ 0)

/∗ x negative, y and z positive. ∗/ t ∗= p1 .rotate(0, −90);

else if (p1 .world coordinates [0] ≥ 0 ∧ p1 .world coordinates [1] < 0 ∧ p1 .world coordinates [2] ≥ 0)

/∗ x positive, y negative, z positive. ∗/ t ∗= p1 .rotate(90);

else if (p1 .world coordinates [0] ≥ 0 ∧ p1 .world coordinates [1] ≥ 0 ∧ p1 .world coordinates [2] < 0)

/∗ x positive, y positive, z negative. ∗/ t ∗= p1 .rotate(−90);

else if (p1 .world coordinates [0] < 0 ∧ p1 .world coordinates [1] < 0 ∧ p1 .world coordinates [2] ≥ 0)

/∗ x negative, y negative, z positive. ∗/ t ∗= p1 .rotate(0, 0, 180);

else if (p1 .world coordinates [0] < 0 ∧ p1 .world coordinates [1] ≥ 0 ∧ p1 .world coordinates [2] < 0)

/∗ x negative, y positive, z negative. ∗/ t ∗= p1 .rotate(0, 180);

else if (p1 .world coordinates [0] ≥ 0 ∧ p1 .world coordinates [1] < 0 ∧ p1 .world coordinates [2] < 0)

/∗ x positive, y negative, z negative. ∗/ t ∗= p1 .rotate(180);

else if (p1 .world coordinates [0] < 0 ∧ p1 .world coordinates [1] < 0 ∧ p1 .world coordinates [2] < 0)

/∗ All negative. ∗/ {

real a = p1 .world coordinates [0]; t ∗= p1 .rotate(180, 180); t ∗= p1 .shift (a); t ∗= p1 .rotate(0, 180); t ∗= p1 .shift (−a);

} p1 .apply transform( ); if ( ) {

p0 .show ( ␣ ␣ ); p1 .show ( ␣ ␣ ); t.show ( ␣ ␣ );

} }

This code is used in section 425.

434. Rotation around an arbitrary axis.

435. Point versions. [LDF 2002.4.7.] Added default value for angle ≡ 180.

§436  3DLDF-1.1.5.1  POINT ARGUMENTS 111

436. Point arguments. This function first checks to see if ∗this lies on the axis. It does this by creating unit vectors in the directions of p1 −p0 and ∗this −p0 . If they are equal, or the latter is the former multiplied by -1, then we don’t bother to perform the rotation. Otherwise, we call Transform ::rotate( ) (defined below).

Log

[LDF 2002.4.7.] Added default value for angle ≡ 180.

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Point functions 329 ⟩ +≡ Transform rotate(const Point &p0 , const Point &p1 , const real angle = 180);

437. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::rotate(const Point &p0 , const Point &p1 , const real angle)

{ Point a = p1 − p0 ; Point b = ∗this − p0 ; a.unit vector (true); b.unit vector (true); Transform t; if (a ≡ b ∨ a ≡ −b) {

      cerr ≪  ␣  ␣  ≪  ␣  ␣  ␣       ␣    ␣  ␣  ≪

␣ ␣ ≪ flush;

return t; } return transform.rotate(p0 , p1 , angle);

}

438. Path argument. Defined in paths.web, because Path is still an incomplete type in this compilation unit.

Log

[LDF 2002.04.07.] Added default value for angle ≡ 180.

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Point functions 329 ⟩ +≡ Transform rotate(const Path &p, const real angle = 180);

112 TRANSFORM VERSION 3DLDF-1.1.5.1 §439

439. Transform version. Declared in transfor.web. [LDF 2002.09.29.] TO DO: Possible BUG!! Actually, the problem that occurred may just have to do choosing the direction of rotation. I’ve changed the place where the problem occurred, so I’ll have to write a routine to test this.

Log

[LDF 2002.10.23.] Changed, so that the direction of \overrightarrow{p_{0}p_{1}} is tested. If it is parallel to the x or y-axis, then that axis is used for alignment. Otherwise, the z-axis is used. This may help reduce inaccuracies caused by rotations. Haven’t tested it yet. TO DO: Test this!

[LDF 2002.11.03.] TO DO: See if I can’t make Point arguments const. [LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now

overloads rotate( ) with three real arguments.

⟨ Define Transform functions 169 ⟩ +≡ Transform Transform ::rotate(Point p0 , Point p1 , const real angle) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

p0 .apply transform( ); p1 .apply transform( ); Point a = p1 − p0 ; a.unit vector (true); char axis ; if (a.get x ( ) ≡ 1 ∨ a.get x ( ) ≡ −1) axis = ; else if (a.get y ( ) ≡ 1 ∨ a.get y ( ) ≡ −1) axis = ; else axis = ; Transform t; t.align with axis (p0 , p1 , axis ); Transform i = t.inverse( ); if (axis ≡ ) t.rotate(angle); else if (axis ≡ ) t.rotate(0, angle); else t.rotate(0, 0, angle); t ∗= i; t.clean( ); ∗this ∗= t; clean( ); return t;

}

§440  3DLDF-1.1.5.1  PICTURE VERSION 113

440. Picture version. [LDF 2002.10.20.] angle is in degrees.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Define Picture functions 264 ⟩ +≡ Transform Picture ::rotate(const Point &p0 , const Point &p1 , const real angle) {

Transform t;

t.rotate(p0 , p1 , angle); transform ∗= t; return t;

}

441. Projection. [LDF 2002.10.23.] For stylistic reasons, and for the sake of clean programming, I believe that the programmer who uses project ( ) should ensure that apply transform( ) has been invoked first. However, transform is checked in project ( ) and apply transform( ) is invoked, if required, so invoking apply transform( ) explicitly beforehand is not strictly speaking necessary.

Log

[LDF 2002.09.09.] The new version now almost works Added division of projective coordinates by the value calculated for w. However, it doesn’t work when I use hex pattern1 ( ). Find out why not!! TO DO: Add routine for calculating z. Then I can add sorting routine in Picture ::output ( ).

[LDF 2002.09.14.] I believe I’ve gotten the new version to work now. LOOK UP: Do I need to divide the derived z value by w? I don’t think it’s necessary. Since the z values of all of the Points would be divided by the same amount, their relative positions would remain the same, since only the relationship “closer or further away” matters, not the exact amounts.

[LDF 2002.09.16.] Added Focus argument to this function. Default is default focus , but it was necessary to write a dummy version of this function in order to make this work, because default focus doesn’t exist at the time that this declaration is compiled.

[LDF 2002.09.18.] Changed name of this function from persp transform( ) to project and added Transform argument.

[LDF 2003.05.09.] BUG FIX: Added loop, setting all elements of projective coordinates to 0. This was done in the conditionally compiled code for the DEC compiler, but I forgot to do it for GCC when added the declaration of temp coordinates and resized it. It took me about 6–7 hours to find this bug!

442. Focus argument.

Log

[LDF 2003.07.11.] Added defaults for proj and factor .

114 FOCUS ARGUMENT 3DLDF-1.1.5.1 §443

⟨ Declare Point functions 329 ⟩ +≡ bool project (const Focus &f, const unsigned short proj = Projections :: , real factor = 1); 443. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::project (const Focus &f, const unsigned short proj , real factor ){ bool = false;

/∗ true ∗/ if ( ) cout ≪ ␣ ≪ flush; if (¬transform.is identity ( )) /∗ LDF 2002.10.23. Added, just to be sure. ∗/

apply transform( );

#ifdef valarray⟨real⟩ temp coordinates ; temp coordinates .resize(4, 0); for (int i = 0; i < 4; ^{++}i) /∗ LDF 2003.05.09. Added this loop. ∗/

projective coordinates [i] = 0;

#else #ifdef

valarray⟨real⟩ temp coordinates = projective coordinates = null coordinates ; #endif #endif

int i; int j; /∗ [LDF 2002.09.18.] Transform temp coordinates by Focus ::transform. ∗/ for (i = 0; i < 4; i^{++}) {

for (j = 0; j < 4; j^{++}) {

temp coordinates [i] += world coordinates [j] ∗ f.get transform element (j, i); }

}

§444  3DLDF-1.1.5.1  PARALLEL PROJECTION 115

444. Parallel projection. [LDF 2002.11.06.] TO DO: Add a way of projecting onto a plane other than the x-y plane. It’s possible to acheive the same effect by rotating the Picture before outputting it, but it would be nice to do so without changing the Picture.

The x and y projective coordinates are simply taken from the world coordinates.

Log

[LDF 2002.10.23.] Added this section.

[LDF 2002.12.18.] Changed  to  and added  and  .

⟨ Define Point functions 330 ⟩ +≡

if (proj ≡ Projections :: ∨ proj ≡ Projections :: ∨ proj ≡

Projections :: ) { using namespace Projections; if (factor ≡ 0) {

  cerr ≪  ␣  ␣  ≪  ␣  ␣  ␣␣           ␣          ␣
      ␣ ␣       ␣    ␣      ␣ ≪  ␣ ␣  ≪ flush;

factor = 1; } unsigned short horizontal ; unsigned short vertical ; if (proj ≡ ∨ proj ≡ ) /∗ [LDF 2002.12.18.] Explain this!! ∗/ horizontal = 0; else horizontal = 2; if (proj ≡ ∨ proj ≡ ) vertical = 1; else vertical = 2; projective coordinates [0] = world coordinates [horizontal ] ∗ factor ; projective coordinates [1] = world coordinates [vertical ] ∗ factor ; projective coordinates [2] = 0; projective coordinates [3] = 1; if ( ) {

cout ≪ ␣ ≪ projective coordinates [0] ≪ ␣ ≪ projective coordinates [1] ≪ ␣ ≪ projective coordinates [2] ≪ ␣ ≪ projective coordinates [3] ≪ ≪ endl ≪ endl ≪ flush;

} return true;

}

116  PERSPECTIVE PROJECTION  3DLDF-1.1.5.1 §445

445. Perspective projection. !! KLUDGE: See below. [LDF 2002.11.08.] TO DO: Get numbers to output using only decimal notation! ⟨ Define Point functions 330 ⟩ +≡

if (temp coordinates [2] + f.get distance( ) ≡ 0) {

cerr ≪  ␣  ␣  ≪  ␣  ␣ ≪ temp coordinates [2] ≪
␣          ␣  ␣ ≪ f.get distance( ) ≪ endl ≪  ␣  ␣  ␣     ␣       ␣  ≪
endl ≪  ␣                      ␣  ␣  ≪ ␣   ␣  ≪

flush; for (i = 0; i < 4; i^{++}) projective coordinates [i] = ; return false;

} else if (temp coordinates [2] + f.get distance( ) < 0) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪ temp coordinates [2] ≪ ␣ ␣ ␣ ≪ f.get distance( ) ≪

endl ≪  ␣   ␣ ␣  ␣      ␣    ␣      ␣  ≪ endl ≪
␣                      ␣  ␣  ≪ ␣   ␣  ≪ flush;

for (i = 0; i < 4; i^{++}) projective coordinates [i] = ; return false;

} real save z = temp coordinates [2]/(temp coordinates [2] + f.get distance( )); if ( ) {

cout ≪ ␣ ␣ ≪ temp coordinates [2] ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ f.get distance( ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ save z ≪ endl ≪ flush;

} for (i = 0; i < 4; i^{++}) {

for (j = 0; j < 4; j^{++}) {

projective coordinates [i] += temp coordinates [j] ∗ f.get persp element (j, i); }

} real eps = epsilon( ); if (projective coordinates [3] ≡ 0) {

cerr ≪  ␣  ␣                 ␣ ≪  ␣  ␣  ≪

    ␣    ␣     ␣ ␣        ␣     ␣  ≪

␣                      ␣  ␣  ≪ ␣   ␣  ≪ flush;

for (i = 0; i < 4; i^{++}) projective coordinates [i] = ; return false;

} for (i = 0; i < 4; i^{++}) {

projective coordinates [i] /= projective coordinates [3]; if (fabs (projective coordinates [i]) < eps ) projective coordinates [i] = 0;

} /∗ [LDF 2002.09.14.] Set the z value of the perspective coordinates in order to be able to use it for

my hidden surface algorith. ∗/ projective coordinates [2] = (fabs (save z ) > eps ) ? save z : 0; if ( ) {

cout ≪ ␣ ; for (i = 0; i < 4; i^{++}) {

cout ≪ projective coordinates [i];

if (i < 3) cout ≪ ␣ ; } cout ≪ ≪ flush;

§445  3DLDF-1.1.5.1  PERSPECTIVE PROJECTION 117

}

for (i = 0; i < 2; i^{++})

/∗ [LDF 2002.11.07.] KLUDGE. Added this loop. The value used for comparison is slightly larger than one that arose while I was testing the constructor of Trunc Octahedron. eps was too small. ∗/

if (fabs (projective coordinates [i]) ≤ 10.0 · 10^{−05}) projective coordinates [i] = 0; if ( ) cout ≪ ␣ ≪ flush; return true; }

446. No Focus argument. [LDF 2002.09.13.] Added this function. This dummy function just passes default focus to project ( const Focus &f …). This is necessary because it’s impossible make the argument f optional with default focus as the default. This is because project ( ) must be declared inside the class declaration of Point, whereas the declaration of Focus must be later, because it contains Points. It’s not a problem to use default focus inside of project ( ), as long as default focus is defined before the function is called. ⟨ Declare Point functions 329 ⟩ +≡

bool project (const unsigned short &proj = Projections :: , real factor = 1);

447. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::project (const unsigned short &proj , real factor )

{

return project (default focus , proj , factor ); }

448. Applying transformations. This version applies the transformation stored in Point ::transform. !! Add a version that applies a Transform supplied as an argument!! [LDF 2002.12.08.] BUG FIX: See below. ⟨ Declare Point functions 329 ⟩ +≡

void apply transform( );

118  APPLYING TRANSFORMATIONS  3DLDF-1.1.5.1 §449

449. ⟨ Define Point functions 330 ⟩ +≡

void Point ::apply transform( ) {

bool = false; /∗ true ∗/ if (transform.is identity ( )) /∗ If transform.matrix is the identity matrix, we don’t need to bother

to perform the matrix multiplication. ∗/ return;

int i; int j; valarray⟨real⟩ new coordinates ; new coordinates .resize(4, 0); /∗ [LDF 2002.12.08.] BUG FIX. For GNU CC. ∗/ if ( ) {

cout ≪ ␣ ␣ ≪ world coordinates [0] ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ world coordinates [1] ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ world coordinates [2] ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ world coordinates [3] ≪ endl ≪ flush; } for (i = 0; i < 4; i^{++}) {

for (j = 0; j < 4; j^{++}) { new coordinates [i] += world coordinates [j] ∗ transform.matrix [j][i]; if (new coordinates [i] ≠ 0) {

if ( ) {

cout ≪ ≪ i ≪ ␣ ␣ ≪ new coordinates [i] ≪ endl ≪ flush; } }

} } real eps = epsilon( ); for (i = 0; i < 4; i^{++}) {

if ( ) {

cout ≪ ≪ i ≪ ␣ ␣ ≪ new coordinates [i] ≪ endl ≪ flush; } world coordinates [i] = (fabs (new coordinates [i]) > eps ) ? new coordinates [i] : 0;

} transform.reset ( );

}

450. Set transform to identity. ⟨ Declare Point functions 329 ⟩ +≡

void reset transform( );

§451  3DLDF-1.1.5.1  SET TRANSFORM TO IDENTITY 119

451. ⟨ Define Point functions 330 ⟩ +≡

void Point ::reset transform( )

{

transform.reset ( ); }

452. Drawing.

453. Drawdot.

[LDF 2002.10.26.] drawdot ( ) copies ∗this and puts the copy onto the vector shapes of the Picture argument picture. The data members drawdot value, drawdot color , and pen are only set on the copy, not on ∗this . All of the drawing and filling functions behave similarly.

[LDF 2003.05.30.] TO DO: Add code for allocating new Color, if ddrawdot color .use name is false, as in the drawing and filling functions for Path and Solid.

454. Normal version.

Log

[LDF 2003.07.11.] Made ppen and drawdot ( ) itself const.

⟨ Declare Point functions 329 ⟩ +≡

void drawdot (const Color &ddrawdot color = ∗Colors ::default color , const string ppen = , Picture &picture = current picture) const;

455. ⟨ Define Point functions 330 ⟩ +≡

void Point ::drawdot (const Color &ddrawdot color , const string ppen, Picture &picture) const{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

Point ∗pt = create new < Point > (0);

∗pt = ∗this ;

pt drawdot value = ;

pt drawdot color = &ddrawdot color ; #if 1

pt pen = ppen; #endif

picture += static cast⟨Shape ∗⟩(pt );

120 PICTURE ARGUMENT FIRST 3DLDF-1.1.5.1 §456

if ( ) cout ≪ ␣ ≪ ≪ flush; } 456. Picture argument first.

Log

[LDF 2002.01.24.] Added this version.

[LDF 2003.01.31.] Removed default for picture. Having a default made calls to drawdot ( ) with no arguments ambiguous.

[LDF 2003.07.11.] Made ppen and drawdot ( ) itself const.

⟨ Declare Point functions 329 ⟩ +≡

void drawdot (Picture &picture, const Color &ddrawdot color = ∗Colors ::default color , const string ppen = ) const;

457. ⟨ Define Point functions 330 ⟩ +≡

void Point ::drawdot (Picture &picture, const Color &ddrawdot color , const string ppen) const {

drawdot (ddrawdot color , ppen, picture); }

458. Undrawdot. [LDF 2002.10.26.] undraw ( ) does not remove a dot from picture, but causes the METAPOST command undrawdot to be written to out stream when picture is output. ⟨ Declare Point functions 329 ⟩ +≡

void undrawdot (string ppen = , Picture &picture = current picture);

459. ⟨ Define Point functions 330 ⟩ +≡

void Point ::undrawdot (string ppen, Picture &picture){ Point ∗pt = create new < Point > (0); ∗pt = ∗this ; pt drawdot value = ; pt drawdot color = Colors ::background color ;

#if 1

pt pen = ppen; #endif

picture += static cast⟨Shape ∗⟩(pt ); }

460. Picture argument first.

Log

[LDF 2002.01.24.] Added this version.

[LDF 2003.01.31.] Removed default for picture. Having a default made calls to undrawdot ( ) with no arguments ambiguous.

§461  3DLDF-1.1.5.1  PICTURE ARGUMENT FIRST 121

⟨ Declare Point functions 329 ⟩ +≡ void undrawdot (Picture &picture, string ppen = ); 461. ⟨ Define Point functions 330 ⟩ +≡

void Point ::undrawdot (Picture &picture, string ppen)

{

undrawdot (ppen, picture); }

462. Draw. [LDF 2002.10.26.] draw ( ) creates a Path with the two Points ∗this and the argument p, and the connector , calls Path ::draw ( ) for it, and returns the Path. The latter is a line, i.e., Path ::get line switch( ) returns true for it.

draw ( ) must be defined in paths.web, because Path is an incomplete type here.

463. Normal version.

Log

[LDF 2003.01.15.] Added the argument aarrow .

⟨ Declare Point functions 329 ⟩ +≡

Path draw (const Point &p, const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , Picture &picture = current picture, bool aarrow = false) const;

464. Picture argument first. [LDF 2003.01.15.] This function is convenient for when I want to pass a Picture argument.

Log

[LDF 2002.09.17.] Added this function.

[LDF 2003.01.15.] Added the argument aarrow .

⟨ Declare Point functions 329 ⟩ +≡

Path draw (Picture &picture, const Point &p, const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , bool aarrow = false);

465. Draw arrow.

466. Normal version. [LDF 2003.01.15.] Defined in paths.web.

Log

[LDF 2003.01.15.] Added this function.

[LDF 2003.06.03.] Made drawarrow ( ) const.

⟨ Declare Point functions 329 ⟩ +≡

Path drawarrow (const Point &p, const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , Picture &picture = current picture) const; 467. Picture argument first. [LDF 2003.01.15.] Defined in paths.web.

Log

[LDF 2003.06.03.] Made drawarrow ( ) const.

⟨ Declare Point functions 329 ⟩ +≡

Path drawarrow (Picture &picture, const Point &p, const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = ) const;

468. Undraw.

469. Normal version. This function must be defined in paths.web, because it uses Path, which is an incomplete type here.

Log

[LDF 2002.4.8.] Added this function.

[LDF 2002.11.03.] Changed this function, so that it returns the Path pa, instead of void.

⟨ Declare Point functions 329 ⟩ +≡

Path undraw (const Point &pt , string ddashed = , string ppen = , Picture &picture = current picture);

470. Picture argument first.

Log

[LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. [LDF 2002.11.03.] Changed this function, so that it returns the Path pa, instead of void.

⟨ Declare Point functions 329 ⟩ +≡ Path undraw (Picture &picture, const Point &pt , string ddashed = , string ppen = );

471. Draw help. [LDF 2002.10.26.] draw help( ) is like draw ( ), except that the Path is only drawn if the static Path data member do help lines ≡ true. This is convenient for drawing construction lines that shouldn’t be output in the final version of a drawing. Also, the default color is ∗Colors ::help color .

472. Normal version. [LDF 2002.4.8.] This function must be defined in paths.web, because it uses Path, which is an incomplete type here.

Log

[LDF 2002.4.8.] Added this function.

[LDF 2003.07.13.] Made this function const.

⟨ Declare Point functions 329 ⟩ +≡

Path draw help(const Point &pt , const Color &ddraw color = ∗Colors ::help color , string ddashed = , string ppen = , Picture &picture = current picture) const; 473. Picture argument first. [LDF 2002.09.17.] This version is convenient for when I want to pass a Picture argument.

Log

[LDF 2002.09.17.] Added this function. [LDF 2003.07.13.] Made this function const.

⟨ Declare Point functions 329 ⟩ +≡

Path draw help(Picture &picture, const Point &pt , const Color &ddraw color = ∗Colors ::help color , string ddashed = , string ppen = ) const;

474. Showing.

475. Show. [LDF 2002.10.26.] The arguments:

string text If text is non-empty, (i.e., not ), it’s written to standard output ( ). If it is empty, or show ( ) is called without any arguments, the default is used, namely .

char coords  One of the characters ,  ,  , or  should be used, to indicate

which set of coordinates should be shown: world coordinates , projective coordinates, user coordinates , or view coordinates , respectively. The latter two exist, but are not currently used. The corresponding uppercase characters can also be used.

const bool do persp Only meaningful if the projective coordinates are being shown (coords argument ). If do persp ≡ true, then project ( ) is called on ∗this before projective coordinates are shown. This is usually what one wants. However, it may sometimes be useful to show the contents of projective coordinates, without calling project ( ), in which case do persp should be false.

const bool do apply Usually, apply transform( ) should be called on ∗this before showing a set of coordinates, so the default for do apply is true. However, it may sometimes be useful to show the values of the coordinates without applying transform, in which case do apply should be false.

Focus ∗f Only meaningful if the projective coordinates are being shown (coords argument ). Refers to the Focus used for projection. If the default is used, or 0 is passed as the argument explicitly, then the global variable default focus is used.

const unsigned short proj Only meaningful if the projective coordinates are being shown (coords argument ). Refers to the projection used. Currently, I’ve only programmed the perspective and the parallel projections. The default is the perspective projection.

const real factor Only meaningful if the projective coordinates are being shown (coords argument ) and the parallel projection is being used. The x and y values in projective coordinates are multiplied by factor , so it can be used to magnify or shrink the projected image. The default is 1 (no magnification or shrinking).

[LDF 2002.10.26.] TO DO: Add case for coords for showing all of the sets of coordinates.

Log

[LDF 2002.10.26.] !! KLUDGE: In the text above, I’ve had to typeset “projective coordinates” using “\it” explicitly in a couple of places, in order to get the hyphenation to work.

[LDF 2002.11.12.] Added “ ” after the arguments to “ ” in the TEX code above in order to suppress a space at the beginning of the first line of the following indented paragraph. I couldn’t figure out a way of suppressing the space within the definition of .

[LDF 2003.04.30.] Changed, so that a newline is not output following text .

⟨ Declare Point functions 329 ⟩ +≡

void show (string text = , char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , const real factor = 1) const;

476. ⟨ Define Point functions 330 ⟩ +≡

void Point ::show (string text , char coords , const bool do persp, const bool do apply , Focus

∗f, const unsigned short proj , const real factor ) const

{ bool = false; /∗ true ∗/ if (text ≡ ) text = ; cout ≪ text ≪ ␣ ; coords = tolower (coords ); if (coords ≡ ) ; /∗ Do nothing. ∗/

else if (coords ≡ ) cout ≪  ␣  ≪ flush;
else if (coords ≡ ) cout ≪  ␣  ≪ flush;
else if (coords ≡ ) cout ≪  ␣  ≪ flush;

else {

  cerr ≪  ␣  ␣         ␣ ≪  ␣         ␣    ␣      ␣  ≪

␣ ␣ ≪ flush; coords = ;

} if (∗this ≡ ) {

cerr ≪ ␣ ␣ ␣ ␣ ␣ ≪ flush;

return; } if ( ) transform.show ( ␣ ␣ ); valarray⟨real⟩ v = get all coords (coords , do persp, do apply , f, proj , factor ); cout ≪ ≪ v[0] ≪ ␣ ≪ v[1] ≪ ␣ ≪ v[2] ≪ ≪ flush; if ( ) {

transform.show (  ␣     ␣  );
cout ≪  ␣  ␣ ≪ on free store ≪  ;

} }

477. Show transform. ⟨ Declare Point functions 329 ⟩ +≡

void show transform(string text = ); 478. ⟨ Define Point functions 330 ⟩ +≡

void Point ::show transform(string text )

{ if (text ≡ ) text = ; cout ≪ text ≪ endl ; transform.show ( );

}

479. Outputting.

480. Output operator. [LDF 2002.10.26.] This function is used in Path ::output ( ) for writing the x and y values of the projective coordinates to out stream. All code using this function must ensure that apply transform( ) and project ( ) are called first!

Log

[LDF 2002.09.16.] Removed calls to apply transform( ) and project ( ).

⟨ Declare non-member non-template functions for Point 480 ⟩ ≡

ostream & operator≪(ostream & o, Point &p);

See also section 534. This code is used in section 634.

481. ⟨ Define non-member non-template functions for Point 481 ⟩ ≡

ostream & operator≪(ostream & o, Point &p)

{

o ≪ ≪ p.get x ( , false, false) ≪ Point ::measurement units ≪ ␣ ≪ p.get y ( , false,

false) ≪ Point ::measurement units ≪ ; return o;

}

See also section 535. This code is used in section 633.

482. Suppress output. [LDF 2002.09.18.] Added this function. It’s needed because trying to erase a Shape ∗ from elements in Picture ::output ( ) causes a memory fault. ⟨ Declare Point functions 329 ⟩ +≡

virtual void suppress output ( );

483. ⟨ Define Point functions 330 ⟩ +≡

void Point ::suppress output ( )

{

do output = false; }

484. Unsuppress output. [LDF 2002.09.18.] Added this function. It’s needed because trying to erase a Shape ∗ from elements in Picture ::output ( ) causes a memory fault. ⟨ Declare Point functions 329 ⟩ +≡

virtual void unsuppress output ( );

126  UNSUPPRESS OUTPUT  3DLDF-1.1.5.1 §485

485. ⟨ Define Point functions 330 ⟩ +≡

void Point ::unsuppress output ( )

{

do output = true; }

486. Extract. [LDF 2002.10.26.] extract ( ) is a pure virtual function in Shape. It’s called by Picture ::output ( ). Each of the Shape pointers on the vector shapes in the Picture must be “extracted”. For Points, this means projecting the Point using the Focus passed to extract ( ) as an argument. If project ( ) succeeds, extract ( ) returns a vector containing this . Otherwise, it returns an empty vector.

[LDF 2002.10.26.] A vector is returned rather than this by itself because it may sometimes be useful to return a collection of Shape pointers rather than a single one. This was formerly the case for Cuboid, but at the present time, no version of extract ( ) returns a vector with more than one pointer to Shape.

Log

[LDF 2002.09.17.] Added const Focus &f argument and error handling code. Now, if the Point cannot be projected onto the projection plane using the Focus f, it is not put onto the vector⟨Shape ∗⟩ Picture ::elements , and consequently never reaches Picture ::output ( ) and Point ::output ( ).

§487  3DLDF-1.1.5.1  EXTRACT 127

⟨ Declare Point functions 329 ⟩ +≡ vector⟨Shape ∗⟩ extract (const Focus &f, const unsigned short proj , real factor ); 487. ⟨ Define Point functions 330 ⟩ +≡

vector⟨Shape ∗⟩ Point ::extract (const Focus &f, const unsigned short proj , real factor ) {

bool = false; /∗ true ∗/ vector⟨Shape ∗⟩ v; /∗ [LDF 2002.09.16.] Added this error checking code. Check ∗this first, to

make sure that it can be drawn with the current value of default focus . ∗/ apply transform( ); if (¬project (f, proj , factor )) {

if ( )

    cerr ≪  ␣  ␣  ≪  ␣  ␣    ␣       ␣  ␣          ␣ ≪

␣ ␣ ␣ ≪ flush;

return v; } if ( ) {

cout ≪ ␣ ␣␣␣␣␣ ≪ world coordinates [0] ≪ ␣ ≪ world coordinates [1] ≪ ␣ ≪ world coordinates [2] ≪ ␣ ≪ world coordinates [3] ≪ ≪ ␣ ≪ projective coordinates [0] ≪ ␣ ≪ projective coordinates [1] ≪ ␣ ≪ projective coordinates [2] ≪ ␣ ≪ projective coordinates [3] ≪ ;

} v.push back (this ); return v;

}

488. Get extremes. [LDF 2002.09.18.] Added this function. Any code that calls get extremes ( ) must ensure that project ( ) has been invoked first. ⟨ Declare Point functions 329 ⟩ +≡

virtual inline const valarray⟨real⟩ get extremes ( ) const {

return projective extremes ; }

489. Get minimum z. [LDF 2002.09.17.] Added this function. ⟨ Declare Point functions 329 ⟩ +≡

virtual real get minimum z ( ) const;

128  GET MINIMUM Z  3DLDF-1.1.5.1 §490

490. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get minimum z ( ) const

{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ endl ≪ flush;
if (  ) cout ≪  ␣  ␣ ≪ projective extremes [4] ≪ endl ≪ flush;
if (  ) cout ≪  ␣  ≪ endl ≪ flush;

return projective extremes [4]; }

491. Get maximum z. [LDF 2002.09.17.] Added this function. ⟨ Declare Point functions 329 ⟩ +≡

virtual real get maximum z ( ) const;

492. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get maximum z ( ) const

{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ endl ≪ flush;
if (  ) cout ≪  ␣  ␣ ≪ projective extremes [5] ≪ endl ≪ flush;
if (  ) cout ≪  ␣  ≪ endl ≪ flush;

return projective extremes [5]; }

493. Get mean z. [LDF 2003.05.16.] Added this function. ⟨ Declare Point functions 329 ⟩ +≡

virtual real get mean z ( ) const;

494. ⟨ Define Point functions 330 ⟩ +≡

real Point ::get mean z ( ) const

{

return ((projective extremes [4] + projective extremes [5])/2); }

495. Set extremes. This function sets “extreme” values for the x, y, and z-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.

[LDF 2002.10.20.] The programmer who uses set extremes ( ) must ensure that apply transform( ) and project ( ) are invoked before set extremes ( )!

Log

[LDF 2002.09.17.] Added this function.

[LDF 2002.09.18.] Changed the name of this function from set minimum z ( ) to set extremes ( ).

§496  3DLDF-1.1.5.1  SET EXTREMES 129

⟨ Declare Point functions 329 ⟩ +≡ virtual bool set extremes ( ); 496. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::set extremes ( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ endl ≪ flush;

for (int i = 0; i < 4; i^{++}) {

if (projective coordinates [i] ≡ ) {

cerr ≪  ␣  ␣  ≪  ≪ i ≪  ≪

        ␣  ␣  ≪  ␣     ␣        ␣  ␣                   ␣ ≪

␣ ␣ ␣ ␣ ≪ flush;

for (int j = 0; j < 6; j^{++}) projective extremes [j] = ;

return false; }

} projective extremes [0] = projective coordinates [0]; /∗ min x ∗/ projective extremes [1] = projective coordinates [0]; /∗ max x ∗/ projective extremes [2] = projective coordinates [1]; /∗ min y ∗/ projective extremes [3] = projective coordinates [1]; /∗ max y ∗/ projective extremes [4] = projective coordinates [2]; /∗ min z ∗/ projective extremes [5] = projective coordinates [2]; /∗ max z ∗/ if ( ) cout ≪ ␣␣ ≪ endl ≪ flush; return true;

}

497. Comparison classes. [LDF 2003.05.16.] The function classes in this section are used in Picture ::output ( ) to sort the pointers to Shape in vector⟨Shape ∗⟩ elements . The argument sort value, which should be one of the constants in namespace Sorting, determines which one is used, or if elements shouldn’t be sorted.

• If Sorting :: is passed to Picture ::output ( ), Compare minimum z is used for sorting. The elements are sorted in descending order of the minimum z-value from their projective extremes .

• If Sorting :: is passed to Picture ::output ( ), Compare maximum z is used for sorting. The elements are then sorted in descending order of the maximum z-value from their projective extremes .

• If Sorting :: is passed to Picture ::output ( ), Compare mean z is used for sorting. The elements are then sorted in descending order of of the mean of the minimum and maximum z-values from their projective extremes . In all three of these cases, the Shapes that are furthest from the Focus are output first, so that they can

be covered, if necessary, by Shapes that are closer.

• If Sorting :: is passed to Picture ::output ( ), elements is not sorted, and the Shapes are output in the order in which they were drawn or filled.

130  COMPARE MINIMUM Z  3DLDF-1.1.5.1 §498

498. Compare minimum z.

Log

[LDF 2003.05.16.] Added this class.

⟨ Define comparison classes 498 ⟩ ≡ class Compare minimum z { public: int operator( )(const Shape ∗s1 , const Shape ∗s2 ) const

{

return s1 get minimum z ( ) > s2 get minimum z ( ); }

};

See also sections 499 and 500. This code is cited in section 596. This code is used in sections 633 and 634.

499. Compare maximum z.

Log

[LDF 2002.09.17.] Added this class. [LDF 2002.09.21.] Changed from “minimum z” to “maximum z”. This works for the more common cases.

⟨ Define comparison classes 498 ⟩ +≡ class Compare maximum z { public: int operator( )(const Shape ∗s1 , const Shape ∗s2 ) const

{

return s1 get maximum z ( ) > s2 get maximum z ( ); }

};

§500  3DLDF-1.1.5.1  COMPARE MEAN Z 131

500. Compare mean z.

Log

[LDF 2002.09.17.] Added this class.

⟨ Define comparison classes 498 ⟩ +≡ class Compare mean z { public: int operator( )(const Shape ∗s1 , const Shape ∗s2 ) const

{

return (((s1 get minimum z ( ) + s1 get maximum z ( ))/2) > ((s2 get minimum z ( ) + s2 get maximum z ( ))/2));

} };

501. Output. [LDF 2002.10.26.] output ( ) is a pure virtual function in Shape. After the Shape pointers on the vector Picture ::shapes have been extracted, output ( ) is called for each of the Shapes they point to (except for the ones, if any, where project ( ) failed). output ( ) writes the METAPOST code to out stream.

Log

[LDF 2002.09.16.] Added Focus argument f. I want the default to be default focus , but I can’t put it in the declaration, as I normally do, because default focus hasn’t been defined yet. I’ve put it in the definition, and it seems to work. Sometimes it doesn’t, and I don’t know why, nor do I know why it works this time. If I run into problems, this may be the reason. If necessary, I can make a dummy version of this function with no argument that calls this version with default focus as its argument.

[LDF 2002.09.17.] Changed the argument f from Focus to const Focus &. Removed the invocations of apply transform( ) and project ( ) and error handling code to extract ( ).

[LDF 2002.10.23.] Removed the argument f. Since extract ( ) takes care of applying project ( ), the projective coordinates are already set, so all output ( ) needs to do is write them to out stream with the proper METAPOST instructions.

132  OUTPUT  3DLDF-1.1.5.1 §502

⟨ Declare Point functions 329 ⟩ +≡ void output ( ); 502. ⟨ Define Point functions 330 ⟩ +≡

void Point ::output ( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (do output ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ flush; return;

}

if (drawdot value ≡  ) out stream ≪  ␣ ;
else if (drawdot value ≡  ) out stream ≪  ␣ ;

else /∗ DRAWDOT ∗/ {

cerr ≪ ␣ ␣ ␣ ≪ drawdot value ≪

␣ ␣ ≪ flush;

#if 0 /∗ !! Define a class for information on the run state. ∗/

if (¬Run State ::non stop) getchar ( ); #endif

out stream ≪ ␣ ; } out stream ≪ ≪ projective coordinates [0] ≪ measurement units ≪ ␣ ≪

projective coordinates [1] ≪ measurement units ≪ ; if (drawdot color ≠ Colors ::default color ) out stream ≪ ␣ ␣ ≪ ∗drawdot color ;

#if 1

if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; #endif

out stream ≪ ; if ( ) cout ≪ ␣ ≪ flush;

}

503. Labelling.

504. Label.

§505  3DLDF-1.1.5.1  STRING ARGUMENT 133

505. string argument. [LDF 2002.10.27.] The arguments:

string text str The text for the label.

string position str Indicates the position of the label text relative to the Point. The same strings are permitted as in METAPOST. They are written unchecked to out stream, so if an invalid string is used, it won’t cause an error in 3DLDF, but it will in METAPOST.

The permitted strings are:  (the default),  ,  ,  ,
(upper left),  (lower left),  (upper right),  (lower right), and

for putting the label right on top of the Point. The empty string must be used explicitly, because is the default.

bool dot If true, then dotlabel is written to out stream rather than label. This argument is mainly for use by the function dotlabel ( ), which calls label ( ) with dot ≡ true.

Picture &picture Indicates the Picture onto which the Label should be placed. The default is current picture .

[LDF 2003.01.15.] TO DO: Add pen argument to label ( ) and dotlabel ( )!!

Log

[LDF 2002.05.14.] Changed text str so that it is no longer optional. It doesn’t make any sense to print empty labels, so I’ve made it a required argument.

[LDF 2002.11.12.] Added “ ” after the arguments to “ ” in the TEX code above in order to suppress a space at the beginning of the first line of the following indented paragraph. I couldn’t figure out a way of suppressing the space within the definition of .

[LDF 2003.07.09.] Made text str , position str , and dot arguments const.

⟨ Declare Point functions 329 ⟩ +≡

void label (const string text str , const string position str = , const bool dot = false, Picture &picture = current picture) const;

134 STRING ARGUMENT 3DLDF-1.1.5.1 §506

506. ⟨ Define Point functions 330 ⟩ +≡

void Point ::label (const string text str , const string position str , const bool dot , Picture &picture)

const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

if (Label :: ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ ≪ flush; return;

} if (∗this ≡ ) {

  cerr ≪  ␣  ␣               ␣ ≪  ␣  ␣                   ␣     ␣

≪ flush; return;

} Label ∗lbl = new (Label); lbl pt = create new < Point > (0); ∗(lbl pt ) = ∗this ; if (dot ≡ true) lbl dot = true; lbl position = position str ; if (text str ≠ ) lbl text = text str ; else lbl text = ; picture += lbl ; /∗ [LDF 2002.10.27.] The Label is pushed onto the vector labels in picture. ∗/ if ( ) cout ≪ ␣ ≪ ≪ flush; return; }

§507  3DLDF-1.1.5.1  SHORT ARGUMENT 135

507. short argument. [LDF 2003.04.01.] TO DO: Make non-const version of this function! TO DO: Make it possible to use to use the values in projective coordinates for the label. This will require adding arguments for use by project ( ).

Log

[LDF 2003.04.01.] Changed this function so that it tests whether text short is equal to , , , or , which are public const static data members in Point. If text short is equal to , ∗this is copied and apply transform( ) is called on the copy. This is necessary, because this function is const. Then, the updated values in the world coordinates vector of the copy are used for the label.

[LDF 2003.05.06.] Added comparison of text short with , , , or , which are used for suppressing the z-coordinate, when the values from one of the sets of coordinates are used for the label. Also, no longer copying ∗this , since get x ( ), get y ( ), and get z ( ) are const anyway.

[LDF 2003.05.20.] Added “ ” case.

[LDF 2003.05.22.] BUG FIX: The “ ” case started with if instead of else if . This caused s.str ( ) to have an erroneous five-digit integer following the closing parenthesis, when or was used. I don’t know why this should have been the case, but changing if to else if fixed the problem. It probably had something to do with the fact that had the same value as . I’ve fixed this above today, too.

[LDF 2003.06.06.] Changed the case, where text short = or text short = : The coordinates surrounded by parentheses are now printed out using TEX’s math mode, i.e., “(x, y, z)” instead of “(x, y, z)”.

[LDF 2003.07.09.] Made text short , position str , and dot arguments const.

⟨ Declare Point functions 329 ⟩ +≡

136 SHORT ARGUMENT 3DLDF-1.1.5.1 §508

void label (const short text short , const string position str = , const bool dot = false, Picture &picture = current picture) const; 508. ⟨ Define Point functions 330 ⟩ +≡

void Point ::label (const short text short , const string position str , const bool dot , Picture

&picture) const

{ bool = false; /∗ true ∗/ stringstream s;

if (text short ≡  ∨ text short ≡  ) {
if (  ) cout ≪  ␣           ␣   ␣  ;

s ≪ ≪ get x ( ) ≪ ␣ ≪ get y ( );

if (text short ≡ ) s ≪ ␣ ≪ get z ( );

s ≪ ; } else if (text short ≡ ) {

if ( ) cout ≪ ␣ ;

s ≪ get z ( ); } else if (text short ≡ ) {

if (  ) cout ≪  ␣  ;
cerr ≪  ␣  ␣  ≪ endl ≪  ␣  ␣            ␣ ≪
␣          ␣     ␣    ␣  ≪  ≪ flush;

return; } else if (text short ≡ ) {

if (  ) cout ≪  ␣  ;
cerr ≪  ␣  ␣  ≪ endl ≪  ␣  ␣            ␣ ≪
␣          ␣     ␣    ␣  ≪  ≪ flush;

return; } else if (text short ≡ ) {

if (  ) cout ≪  ␣  ;
cerr ≪  ␣  ␣  ≪ endl ≪  ␣  ␣            ␣ ≪
␣          ␣     ␣    ␣  ≪  ≪ flush;

return; } else {

if ( ) cout ≪ ␣ ␣ ␣ ;

s ≪ text short ; } if ( ) cout ≪ ␣ ␣ ≪ s.str ( ) ≪ endl ≪ flush; label (s.str ( ), position str , dot , picture); return;

}

509. Dotlabel. TO DO: Add an optional pen argument. If it’s used, use drawdot ( ) with the pen argument, together with label ( ). When I do this, I should also add real arguments (to both label ( ) and dotlabel ( )) for shifting the position of the text, and a version with a Point argument for the same purpose. This is so that the dot won’t cover the text. [LDF 2003.07.16.] 510. string argument.

Log

[LDF 2003.07.09.] Made text str and position str arguments const.

⟨ Declare Point functions 329 ⟩ +≡

void dotlabel (const string text str , const string position str = , Picture &picture = current picture) const;

511. ⟨ Define Point functions 330 ⟩ +≡

void Point ::dotlabel (const string text str , const string position str , Picture &picture) const {

label (text str , position str , true, picture); }

512. short argument.

Log

[LDF 2003.07.09.] Made text short and position str arguments const.

⟨ Declare Point functions 329 ⟩ +≡

void dotlabel (const short text short , const string position str = , Picture &picture = current picture) const;

513. ⟨ Define Point functions 330 ⟩ +≡

void Point ::dotlabel (const short text short , const string position str , Picture &picture) const {

label (text short , position str , true, picture); } 514. [LDF 2002.09.06.] Commented out ∼Label( ). This was the cause of a bug that caused a memory fault when I tried to use a label in figure 2 (beginfig (2)) after having used it in figure 1 and then invoking current picture.clear ( ) in between. ⟨ Define Label functions 514 ⟩ ≡ #if 0

Label ::∼Label( )

{

if (pt ≠ 0) delete pt ; }

#endif

See also sections 515 and 516. This code is used in section 633.

515. Get copy of Label. ⟨ Define Label functions 514 ⟩ +≡

Label ∗ Label ::get copy ( ) const{ Label ∗lbl = new (Label); lbl pt = create new < Point > (0); ∗(lbl pt ) = ∗pt ; lbl dot = dot ; lbl text = text ; lbl position = position; return lbl ; }

516. Output Labels. [LDF 2002.10.23.] Declared in pictures.web. Must be defined here, because Point is an incomplete type there.

Log

[LDF 2002.10.23.] Added arguments proj and factor .

⟨ Define Label functions 514 ⟩ +≡ void Label ::output (const Focus &f, const unsigned short proj , real factor , const Transform &t) {

if (¬t.is identity ( )) ∗pt ∗= t;

pt apply transform( );

if (¬pt project (f, proj , factor )) {

      cerr ≪  ␣  ␣  ≪  ␣  ␣     ␣       ␣  ␣          ␣ ≪

␣ ␣ ≪ flush;

return; } if (dot ≡ true) out stream ≪ ; out stream ≪ ; if (position ≠ ) out stream ≪ ≪ position; out stream ≪ ␣ ≪ text ≪ ␣ ␣ ≪ pt get x ( ,

false) ≪ Point ::measurement units ≪ ␣ ≪ pt get y ( , false) ≪ Point ::measurement units ≪ ;

return; }

517. Matrix operations.

518. Multiplication by a Transform with assignment.

§518  3DLDF-1.1.5.1  MULTIPLICATION BY A TRANSFORM WITH ASSIGNMENT 139

Log

[LDF 2002.11.06.] BUG FIX: This function now returns t instead of transform. This makes it possible to chain expressions using operator∗=( ).

⟨ Declare Point functions 329 ⟩ +≡ Transform operator∗=(const Transform &t);

519. ⟨ Define Point functions 330 ⟩ +≡

Transform Point ::operator∗=(const Transform &t)

{

return (transform ∗= t); }

520. Vector operations. [LDF 2002.10.27.] Note that the vector operations don’t affect the w coordinate.

Log

[LDF 2002.10.27.] In the functions operator+( ),operator+=( ), operator−( ), and operator−=( ): It doesn’t seem worth it to write non-const versions, although I could. Now using the elements of p0 .world coordinates directly instead of using get x ( ), get y ( ), and get z ( ). This is safe, as is calling apply transform( ) on p, and saves the cost of three function calls.

521. Vector addition. ⟨ Declare Point functions 329 ⟩ +≡

Point operator+(Point p) const;

522. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::operator+(Point p) const

{ Point a; a = ∗this ; p.apply transform( ); a.shift (p.world coordinates [0], p.world coordinates [1], p.world coordinates [2]); return a;

}

523. Vector addition with assignment. ⟨ Declare Point functions 329 ⟩ +≡

void operator+=(Point p);

140  VECTOR ADDITION WITH ASSIGNMENT  3DLDF-1.1.5.1 §524

524. ⟨ Define Point functions 330 ⟩ +≡

void Point ::operator+=(Point p) {

p.apply transform( );

shift (p.world coordinates [0], p.world coordinates [1], p.world coordinates [2]); }

525. Vector subtraction. ⟨ Declare Point functions 329 ⟩ +≡

Point operator−(Point p) const;

526. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::operator−(Point p) const {

Point a(∗this );

p.apply transform( );

a.shift (−p.world coordinates [0], −p.world coordinates [1], −p.world coordinates [2]); return a;

}

527. Vector subtraction with assignment. ⟨ Declare Point functions 329 ⟩ +≡

void operator−=(Point p);

528. ⟨ Define Point functions 330 ⟩ +≡

void Point ::operator−=(Point p) {

p.apply transform( );

shift (−p.world coordinates [0], −p.world coordinates [1], −p.world coordinates [2]); }

529. Vector-scalar multipication with assignment.

Log

[LDF 2002.10.27.] Made argument r const. Changed return value from Point & to void. [LDF 2003.05.14.] Changed return value from void to real. It now returns the argument r. This makes

it possible to chain invocations of this function.

⟨ Declare Point functions 329 ⟩ +≡ real operator∗=(const real r);

§530  3DLDF-1.1.5.1  VECTOR-SCALAR MULTIPICATION WITH ASSIGNMENT 141

530. ?? I’m not sure whether multiplication with a scalar is commutative with transformations. I doubt it. Therefore, I apply transform before multiplying. ⟨ Define Point functions 330 ⟩ +≡

real Point ::operator∗=(const real r)

{ apply transform( ); for (int i = 0; i < 3; i^{++}) world coordinates [i] ∗= r; return r;

}

531. Vector-scalar multipication.

532. Member version (Point first).

Log

[LDF 2002.10.27.] Made this function and the argument r const.

⟨ Declare Point functions 329 ⟩ +≡ Point operator∗(const real r) const;

533. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::operator∗(const real r) const

{ Point a(∗this ); a.apply transform( ); a ∗= r; return a;

}

534. Non-member version (scalar first). ⟨ Declare non-member non-template functions for Point 480 ⟩ +≡

Point operator∗(const real, const Point &p);

535. ⟨ Define non-member non-template functions for Point 481 ⟩ +≡

Point operator∗(const real r, const Point &p)

{

return p ∗ r; }

536. Unary minus.

Log

[LDF 2002.10.27.] Made this function const.

⟨ Declare Point functions 329 ⟩ +≡ Point operator−( ) const;

142  UNARY MINUS  3DLDF-1.1.5.1 §537

537. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::operator−( ) const {

Point a(∗this );

a.apply transform( );

a ∗= −1;

return a; }

538. Vector-scalar division with assignment. ?? I’m not sure whether division with a scalar is commutative with transformations. I doubt it. Therefore, I apply transform before dividing.

Log

[LDF 2002.10.27.] Made the argument r const.

⟨ Declare Point functions 329 ⟩ +≡ void operator/=(const real r);

539. ⟨ Define Point functions 330 ⟩ +≡

void Point ::operator/=(const real r) {

apply transform( );

for (int i = 0; i < 3; i^{++}) world coordinates [i] /= r; }

540. Vector-scalar division.

Log

[LDF 2002.10.27.] Made this function and the argument r const.

⟨ Declare Point functions 329 ⟩ +≡ Point operator/(const real r) const;

§541  3DLDF-1.1.5.1  VECTOR-SCALAR DIVISION 143

541. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::operator/(const real r) const {

Point a(∗this );

a.apply transform( );

a /= r;

return a; }

542. Dot product.

Log

[LDF 2002.10.27.] Changed this function and argument p to const. Now using world coordinates directly instead of get x ( ), get y ( ), and get z ( ).

[LDF 2003.07.11.] Changed, so that if the dot product is less than Point ::epsilon( ), 0 will be returned.

⟨ Declare Point functions 329 ⟩ +≡ real dot product (Point p) const;

543. ⟨ Define Point functions 330 ⟩ +≡

real Point ::dot product (Point p) const {

Point a(∗this );

a.apply transform( );

p.apply transform( );

real r = ((a.world coordinates [0] ∗ p.world coordinates [0]) + (a.world coordinates [1] ∗

p.world coordinates [1]) + (a.world coordinates [2] ∗ p.world coordinates [2])); if (fabs (r) < Point ::epsilon( )) r = 0; return r;

}

544. Cross product.

Log

[LDF 2002.10.27.] Changed this function and argument p to const. Now using world coordinates directly instead of get x ( ), get y ( ), and get z ( ).

⟨ Declare Point functions 329 ⟩ +≡ Point cross product (Point p) const;

144  CROSS PRODUCT  3DLDF-1.1.5.1 §545

545. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::cross product (Point p) const

{ Point a(∗this ); a.apply transform( ); p.apply transform( ); Point r; r.world coordinates [0] = (a.world coordinates [1] ∗ p.world coordinates [2]) − (a.world coordinates [2] ∗

p.world coordinates [1]); /∗ x. ∗/ r.world coordinates [1] = (a.world coordinates [2] ∗ p.world coordinates [0]) − (a.world coordinates [0] ∗

p.world coordinates [2]); /∗ y. ∗/ r.world coordinates [2] = (a.world coordinates [0] ∗ p.world coordinates [1]) − (a.world coordinates [1] ∗

p.world coordinates [0]); /∗ z. ∗/ return r;

}

546. Magnitude. [LDF 2002.10.27.] The magnitude of a Point is its distance from the origin and is equal to \sqrt{(x^{2} + y^{2} + z^{2})}. Since floats are so large anyway, and since I can easily redefine real to use double or double double, (or

whatever it’s called Look up!!), it’s not really necessary to use an algorithm to approximate \sqrt{(x^{2} + y^{2} + z^{2})} (viz., “Pythagorean addition” in Knuth, Metafont: The Program. (Get reference!!) However, it might be nice to use it anyway.

Log

[LDF 2002.10.27.] Made this function const. Now using world coordinates directly instead of get x ( ), get y ( ), and get z ( ).

⟨ Declare Point functions 329 ⟩ +≡ real magnitude( ) const;

§547  3DLDF-1.1.5.1  MAGNITUDE 145

547. ⟨ Define Point functions 330 ⟩ +≡

real Point ::magnitude( ) const {

bool = true; /∗ false ∗/ real r; real temp; Point a(∗this ); a.apply transform( ); if ((a.world coordinates [0] > ) ∨ (a.world coordinates [1] >

) ∨ (a.world coordinates [2] > )) {

cerr ≪  ␣  ␣  ≪

      ␣   ␣ ␣          ␣   ␣     ␣   ␣  ≪  ␣  ;

return ; } r = a.world coordinates [0] ∗ a.world coordinates [0]; temp = a.world coordinates [1] ∗ a.world coordinates [1]; if ( − r < temp) {

cerr ≪ ␣ ;

cerr ≪ ␣ ␣ ␣ ␣ ␣ ; /∗ !! This show ( ) outputs to stdout . It

would be nice to output it to stderr instead. Must write function for this. ∗/ cerr ≪ ␣ ; return ;

} r += temp; temp = a.world coordinates [2] ∗ a.world coordinates [2]; if ( − r < temp) {

cerr ≪ ␣ ;

cerr ≪ ␣ ␣ ␣ ␣ ␣ ; /∗ !! This show ( ) outputs to stdout . It

would be nice to output it to stderr instead. Must write function for this. ∗/ cerr ≪ ␣ ; return ;

} r += temp; return sqrt (r);

}

548. Angle between two vectors.

Log

[LDF 2002.10.27.] Made this function const. [LDF 2003.07.27.] Made the argument p a const Point &. No longer copying ∗this . Now using

dot product ( ) instead of calculating the angle “by hand”. Simplified the code of the function.

⟨ Declare Point functions 329 ⟩ +≡ real angle(const Point &p) const;

146  ANGLE BETWEEN TWO VECTORS  3DLDF-1.1.5.1 §549

549. ⟨ Define Point functions 330 ⟩ +≡

real Point ::angle(const Point &p) const

{ bool = false; /∗ true ∗/ real mag = magnitude( ); real p mag = p.magnitude( ); if (mag ≡ ) {

cerr ≪ ␣ ␣ ␣ ␣ ≪ ␣ ␣ ; return ;

}

else if (mag ≡ 0) {

if (  ) cerr ≪  ␣  ␣  ≪  ␣   ␣         ␣  ≪

           ␣  ;

return ; } else if (p mag ≡ ) {

cerr ≪ ␣ ␣ ␣ ␣ ≪ ␣ ␣ ; return ;

}

else if (p mag ≡ 0) {

if (  ) cerr ≪  ␣  ␣  ≪ ␣   ␣         ␣  ≪

           ␣  ;

return ; } else return (180/ ∗ acos (dot product (p)/(mag ∗ p mag )));

}

550. Unit vector.

Log

[LDF 2002.10.27.] Added a second version. If assign is not used, unit vector ( ) can be const, so I now have a const version with no argument and a non-const one for assignment that should be called with the argument true.

551. With assignment. This version should only ever be called with true as its argument. Using false will work, unless ∗this is const, in which case it will cause an compilation error. [LDF 2002.10.27.]

If the optional silent argument is true, warning messages will be suppressed, otherwise, they will be issued. The const version below can’t have an optional silent argument, because that would make a call to this function with one argument ambiguous.

Log

[LDF 2002.10.27.] If magnitude( ) fails, unit vector ( ) now returns instead of origin.

[LDF 2003.07.01.] Added the silent argument to suppress warning messages. I kept getting warnings when this function was called from intersection functions, in cases where it wasn’t a problem, that a Point (vector) had 0 magnitude.

§552  3DLDF-1.1.5.1  WITH ASSIGNMENT 147

⟨ Declare Point functions 329 ⟩ +≡ Point unit vector (const bool assign, const bool silent = false); 552. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::unit vector (const bool assign, const bool silent ) {

if (assign ≡ false) {

if (¬silent ) {

cerr ≪  ␣  ␣  ≪

        ␣    ␣    ␣        ␣    ␣     ␣  ␣    ␣  ≪
        ␣            ␣        ␣  ␣        ␣  ≪

␣ ␣ ␣ ␣ ≪ flush;

}

return unit vector ( ); } apply transform( ); real m = magnitude( ); if (m ≡ 0)

/∗ LDF 2002.04.10. Added this error handling code for the case where *this has no magnitude. ∗/ {

if (¬silent ) {

cerr ≪  ␣  ␣  ≪

        ␣        ␣   ␣   ␣          ␣         ␣  ≪ flush;

}

return ; } for (int i = 0; i < 3; i^{++}) world coordinates [i] /= m; world coordinates [3] = 1; /∗ [LDF 2002.10.27.] Setting the w-coordinate to 1, just to be sure. ∗/ return ∗this ;

}

553. const (no assignment). ⟨ Declare Point functions 329 ⟩ +≡

Point unit vector ( ) const;

554. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::unit vector ( ) const {

Point a(∗this ); return a.unit vector (true);

}

555. Mediation.

Log

[LDF 2003.12.09.] Changed from a non-member to a const member function.

⟨ Declare Point functions 329 ⟩ +≡ Point mediate(Point p, const real r = .5) const;

148  MEDIATION  3DLDF-1.1.5.1 §556

556. ⟨ Define Point functions 330 ⟩ +≡

Point Point ::mediate(Point p, const real r) const

{ Point t(∗this ); t ∗= (1 − r); p ∗= r; return (t + p);

}

557. Get normal. get normal ( ) must be defined in paths.web, because it uses a Path in its definition, which is an incompletely defined type in this file.

Log

[LDF 2003.07.11.] Added this declaration.

⟨ Declare Point functions 329 ⟩ +≡ Point get normal (const Point &p, const Point &q) const;

558. Comparison.

559. Equality. !! I may have to adjust to value of eps . It would be nice to be able to use epsilon( ), but for other purposes epsilon( ) must be smaller. Transformations seem to cause fairly large inaccuracies in the values of the coordinates, so I need greater tolerance in the functions testing for equality and inequality.

This function could be formulated more succinctly, but I had some trouble getting it to work properly, so I’m leaving it in its more verbose form, in case I have to debug it some more.

560. Non-const version.

Log

[LDF 2002.10.27.] Revised this function. Now using Point a and Point q. Added factor and using it as the argument to clean( ) and for calculating eps . Since this function is an operator, it’s not possible to pass factor as an argument, unfortunately. Using clean(factor ) makes it possible to compare the coordinates with 0 directly rather than using fabs ( ) and eps . Also, operator≡( ) now uses world coordinates directly rather than get x ( ), get y ( ), and get z ( ).

[LDF 2003.07.09.] Made this function non-const, and added const version below.

⟨ Declare Point functions 329 ⟩ +≡ bool operator≡(Point p); 561. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::operator≡(Point p){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

unsigned short factor = 10; /∗ LDF 2002.10.27. Added. ∗/ clean(factor ); p.clean(factor ); real eps = epsilon( ) ∗ factor ; /∗ This currently makes eps ≡ .0001. ∗/ real t x = world coordinates [0]; real t y = world coordinates [1]; real t z = world coordinates [2]; real p x = p.world coordinates [0]; real p y = p.world coordinates [1]; real p z = p.world coordinates [2];

562. Points are frequently compared to , so it’s best to suppress debugging output for these comparisons, because they’re probably not the ones we’re interested in. ⟨ Define Point functions 330 ⟩ +≡

if (t x ≡  ∨ t y ≡  ∨ t z ≡  ∨ p x ≡  ∨ p y ≡
∨ p z ≡  )  = false;

563. Debugging output. ⟨ Define Point functions 330 ⟩ +≡

if ( ) { cout ≪ ␣ ␣ ≪ t x ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ t y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ t z ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ p x ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ p y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ p z ≪ endl ≪ flush;

}

564. Check whether the coordinates of both Points are all 0.

Log

[LDF 2002.10.27.] Now that clean(10) and p.clean(10) are called above, it’s no longer necessary to compare the absolute values of the coordinates. I can just compare them with 0 instead.

⟨ Define Point functions 330 ⟩ +≡

if (t x ≡ 0 ∧ p x ≡ 0 ∧ t y ≡ 0 ∧ p y ≡ 0 ∧ t z ≡ 0 ∧ p z ≡ 0) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ; return true;

} 565. Get the signs of the coordinates.

Log

[LDF 2002.10.27.] As in the previous section, changed so that the coordinates are compared with 0, instead of using fabs ( ) and eps .

⟨ Define Point functions 330 ⟩ +≡ signed short t x sign; signed short t y sign; signed short t z sign; signed short p x sign; signed short p y sign; 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 p z sign = 1; if ( ) {

cout ≪ ␣ ␣ ≪ t x sign ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ t y sign ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ t z sign ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ p x sign ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ p y sign ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ p z sign ≪ endl ≪ flush;

} if ((t x sign ≠ p x sign) ∨ (t y sign ≠ p y sign) ∨ (t z sign ≠ p z sign)) {

if ( )

    cout ≪ ␣     ␣   ␣          ␣    ␣   ␣     ␣     ␣       ␣ ≪  ␣  ;

return false; } 566. Get the difference between each pair of x, y, and z-coordinates. ⟨ Define Point functions 330 ⟩ +≡

t x = fabs (t x ); t y = fabs (t y ); t z = fabs (t z ); p x = fabs (p x ); p y = fabs (p y ); p z = fabs (p z ); real delta x = fabs (t x − p x ); real delta y = fabs (t y − p y ); real delta z = fabs (t z − p z ); if ( ) {

cout ≪ ␣ ␣ ≪ delta x ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ delta y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ delta z ≪ endl ≪ flush;

} bool r; /∗ [LDF 2002.10.27.] The return value. It’s only needed for the sake of the debugging code.

Otherwise, this function could just return the result of the following expression. ∗/ r = (delta x < eps ∧ delta y < eps ∧ delta z < eps ); if ( ) cout ≪ ␣ ␣ ≪ r ≪ endl ≪ flush; if ( ) cout ≪ ␣ ≪ ≪ flush; return r; }

567. const version. [LDF 2003.07.09.] This function merely copies ∗this and calls the non-const version on the copy. Here, p can be a const Point &, because this function does nothing but pass it to non-const version, where it is passed by value.

Log

[LDF 2003.07.09.] Added this version. Made the original version non-const.

⟨ Declare Point functions 329 ⟩ +≡ bool operator≡(const Point &p) const;

568. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::operator≡(const Point &p) const {

Point copy (∗this );

return (copy ≡ p); }

569. Inequality. ⟨ Declare Point functions 329 ⟩ +≡

bool operator≠(const Point &p) const;

152  INEQUALITY  3DLDF-1.1.5.1 §570

570. ⟨ Define Point functions 330 ⟩ +≡

bool Point ::operator≠(const Point &p) const

{

return ¬(∗this ≡ p); }

571. Intersection.

[LDF 2002.10.27.] intersection point ( ) takes four Point arguments. It assumes that the first and second represent one line segment and the third and fourth another. It calculates the intersection point of the two lines, if any, and returns a bool point. If the intersection point exists and is on both line segments, the bool is true and the Point is the intersection point. If the intersection point exists, but is not on both line segments, the bool is false and the Point is the intersection point. If no intersection point exists, i.e, the line segments are congruent or parallel, then the bool is false and the Point is .

LDF Date? Note that intersection point ( ) had to be defined as a static member function, because Path ::intersection point ( ) was not able to resolve the call of this version, when it was not callable as “Point ::intersection point ( )”. I got a compiler error, because the call of intersection point ( ) inside Path ::intersection point ( ) with four references to Points as arguments was deemed to have “too many arguments” and the references to Point couldn’t be converted to const references to Path.

572. Vector version. [LDF 2003.06.29.] Defined in lines.web, because Line is an incomplete type here.

The algorithm used in this function is taken from Jones, Huw. Computer Graphics Through Key Mathematics, pp. 208–311. See References for the complete reference.

!! It may be necessary or desirable to add try…catch blocks where calculations are performed below, just in case overflow occurs.

!! Under Linux, both this function and the version of intersection points ( ) using traces have failed in the same cases, which involved coplanar lines which had been rotated about the z-axis or the y and z-axes. I suspect it has to do with the routines for sine and cosine, since I’ve had trouble with rotation in the constructors for Polyhedra. [LDF 2003.06.29.]

Log

[LDF 2002.04.10.] Added this function. It replaces the old version, below.

[LDF 2002.04.12.] Removed the definition of this function to lines.web, because it requires the use of Lines, and Line is an incomplete type here.

[LDF 2003.06.29.] Started using this version again. Bug fixes I’ve made elsewhere seem to have made it function.

⟨ Declare Point functions 329 ⟩ +≡

static bool point intersection point (const Point &pp0 , const Point &pp1 , const Point &qq0 , const Point &qq1 );

573. Trace version. This function finds the intersection point of two lines by finding the intersection points of the traces of the lines on the major planes. I originally wrote it, because the vector version didn’t work. Bug fixes elsewhere seem to have fixed the problem, so this version isn’t really needed anymore.

[LDF 2003.06.29.]

The bool argument trace serves only to distinguish this function from the vector version. It doesn’t matter whether it’s true or false. [LDF 2003.06.29.]

Log

[LDF 2002.10.27.] Changed the const Point & arguments to Point, because I had to copy them anyway in order to call apply transform( ) on them.

§573  3DLDF-1.1.5.1  TRACE VERSION 153

[LDF 2003.06.29.] Added the bool argument trace, in order to be able to use both the vector and trace versions. Previously, the vector version didn’t work, and was commented-out. Now, bug fixes elsewhere seem to have made the vector version work. Both versions, however, failed under Linux. See the TEX section for the vector version, above, for more information.

⟨ Declare Point functions 329 ⟩ +≡ static bool point intersection point (Point p0 , Point p1 , Point q0 , Point q1 , const bool trace);

574. ⟨ Define Point functions 330 ⟩ +≡

bool point Point ::intersection point (Point p0 , Point p1 , Point q0 , Point q1 , const bool trace){

bool = false; /∗ true ∗/ if ( ) {

cout ≪ ␣ ≪ flush; p0 .show ( ); p1 .show ( ); q0 .show ( ); q1 .show ( );

}

bool point bp; /∗ Return value. ∗/

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

575. Apply the transformations, so we have the correct values for x, y, and z in each of the Points. Then assign them to variables. ⟨ Define Point functions 330 ⟩ +≡

p0 .apply transform( ); p1 .apply transform( ); q0 .apply transform( ); q1 .apply transform( ); real p0 x = p0 .world coordinates [0]; real p0 y = p0 .world coordinates [1]; real p0 z = p0 .world coordinates [2]; real p1 x = p1 .world coordinates [0]; real p1 y = p1 .world coordinates [1]; real p1 z = p1 .world coordinates [2]; real q0 x = q0 .world coordinates [0]; real q0 y = q0 .world coordinates [1]; real q0 z = q0 .world coordinates [2]; real q1 x = q1 .world coordinates [0]; real q1 y = q1 .world coordinates [1]; real q1 z = q1 .world coordinates [2];

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

154  TRACE VERSION  3DLDF-1.1.5.1 §576

576. Get deltas. ⟨ Define Point functions 330 ⟩ +≡

real delta x p = p1 x − p0 x ; real delta y p = p1 y − p0 y ; real delta z p = p1 z − p0 z ; real delta x q = q1 x − q0 x ; real delta y q = q1 y − q0 y ; real delta z q = q1 z − q0 z ;

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

577. Slopes for line \overrightarrow{p_{0}p_{1}}. ⟨ Define Point functions 330 ⟩ +≡

real slope p x y = (delta x p ≠ 0) ? delta y p/delta x p : ; real slope p x z = (delta x p ≠ 0) ? delta z p/delta x p : ; real slope p z y = (delta z p ≠ 0) ? delta y p/delta z p : ;

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

578. Slopes for line \overrightarrow{q_{0}q_{1}}. ⟨ Define Point functions 330 ⟩ +≡

real slope q x y = (delta x q ≠ 0) ? delta y q /delta x q : ; real slope q x z = (delta x q ≠ 0) ? delta z q /delta x q : ; real slope q z y = (delta z q ≠ 0) ? delta y q /delta z q : ;

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

579. The traces on the x-y plane. x i , y i , z i , y int p, and y int q are set to so that I can test for whether the routines below succeed in setting them correctly. ⟨ Define Point functions 330 ⟩ +≡

real x i =  ;  /∗ x-coordinate of the intersection point. ∗/
real y i =  ;  /∗ y-coordinate of the intersection point. ∗/
real z i =  ;  /∗ z-coordinate of the intersection point. ∗/
real y int p =  ;  /∗ y-intercept of \overrightarrow{p_{0}p_{1}}. ∗/
real y int q =  ;  /∗ y-intercept of \overrightarrow{q_{0}q_{1}}. ∗/
if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;
if (slope p x y ≠  )  /∗ Δx_{p} ≠ 0. ∗/

{

y int p = p0 y − (slope p x y ∗ p0 x ); } if (slope q x y ≠ ) /∗ Δx_{q} ≠ 0. ∗/ {

y int q = q0 y − (slope q x y ∗ q0 x ); }

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

580.

• If both of the traces of p⃗ and q⃗ in the x-y plane are parallel to the y-axis (i.e., Δx = 0), we test whether p_{x} = q_{x}. If they are, then we set x i to that value. If they’re not, the lines don’t intersect, so we return .

• If the trace of p⃗ or the trace of q⃗ in the x-y plane is parallel to the y-axis, we set x i to its x-value, because in this case, the intersection point must have this x-value.

• If Δx_{p} ≠ 0 and Δx_{q} ≠ 0, we derive x i using the slope and y-intercept of the lines. ⟨ Define Point functions 330 ⟩ +≡

if (y int p ≡ ∧ y int q ≡ )

/∗ p⃗_{xz} and q⃗_{xz} are both parallel to the z-axis. ∗/ {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; if (p0 x ≡ q0 x ) /∗ They have the same value for x. ∗/ {

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;
if (  ) cout ≪  ␣  ␣   ␣      ␣   ␣  ≪ flush;

x i = p0 x ; real y int p z = ; real y int q z = ; if (slope p z y ≠ ) y int p z = p0 y − slope p z y ∗ p0 z ; if (slope q z y ≠ ) y int q z = q0 y − slope q z y ∗ q0 z ;

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;
if (slope p z y ≡  ∧ slope q z y ≡  ) {
if (  ) cout ≪  ␣      ␣  ␣   ␣      ␣   ␣  ≪ flush;
if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;
if (p0 z ≡ q0 z ) cerr ≪  ␣   ␣  ;
else cerr ≪  ␣  ␣   ␣  ;
cerr ≪  ␣  ≪ flush;

return ; } else if (slope p z y ≡ ) {

if (  ) cout ≪  ␣       ␣  ␣  ≪ flush;
if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

z i = p0 z ; y i = z i ∗ slope q z y + y int q z ; if ( ) {

cout ≪ ␣ ␣ ≪ x i ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ y i ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ z i ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ slope q z y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ y int q z ≪ endl ≪ flush;

} } else if (slope q z y ≡ ) {

if (  ) cout ≪  ␣       ␣  ␣  ≪ flush;
if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

z i = q0 z ; y i = z i ∗ slope p z y + y int p z ; if ( ) {

cout ≪ ␣ ␣ ≪ x i ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ y i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ z i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ slope p z y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ y int p z ≪ endl ≪ flush;

} } else {

if (  ) cout ≪  ␣     ␣  ␣  ≪ flush;
if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

z i = (y int q z − y int p z )/(slope p z y − slope q z y ); y i = slope p z y ∗ z i + y int p z ; if ( ) {

cout ≪ ␣ ␣ ≪ x i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ y i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ z i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ slope p z y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ y int p z ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ slope q z y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ y int q z ≪ endl ≪ flush;

} }

} else /∗ They don’t have the same value for x. ∗/ {

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;
cerr ≪  ␣  ␣   ␣  ;

cerr ≪ ≪ p0 x ≪ ␣ ≪ p0 y ≪ ␣ ≪ p0 z ≪ ␣ ␣ ≪ p1 x ≪ ␣ ≪ p1 y ≪ ␣ ≪ p1 z ≪ ≪ q0 x ≪ ␣ ≪ q0 y ≪ ␣ ≪ q0 z ≪ ␣ ␣ ≪ q1 x ≪ ␣ ≪ q1 y ≪ ␣ ≪ q1 z ≪ ␣ ≪ flush;

return ; }

} else if (y int p ≡ ) /∗ p⃗_{xy} is parallel to the y-axis. ∗/ {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; x i = p0 x ; y i = slope q x y ∗ x i + y int q ;

} else if (y int q ≡ ) /∗ q⃗_{xy} is parallel to the y-axis. ∗/ {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; x i = q0 x ; y i = slope p x y ∗ x i + y int p;

} 581. [LDF 2002.11.12.] !! BUG: Occurred when I tried to find an intersection of two lines in the x-z plane. This code shouldn’t be reached. Rotating the objects 90^{∘} around the x-axis, putting them into the x-y plane, fixed the problem. Obviously, the case that the objects are in the x-z plane already isn’t handled properly. ⟨ Define Point functions 330 ⟩ +≡

else /∗ Neither q⃗_{xy} nor q⃗_{xy} is parallel to the y-axis. ∗/ {

if ( ) /∗ [LDF 2002.11.12.] Start working on finding bug here. ∗/ {

cout ≪ ␣ ␣ ␣ ≪ flush;

cout ≪ ␣ ␣ ≪ slope p x y ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ slope q x y ≪ endl ≪ flush;

}

if (slope p x y ≠ slope q x y ) { x i = (y int q − y int p)/(slope p x y − slope q x y ); y i = slope p x y ∗ x i + y int p;

} }

582. The trace on the x-z plane. We don’t need to do this if we’ve calculated z i above, in the case that the traces on the x-y plane are coincident. ⟨ Define Point functions 330 ⟩ +≡

if (z i ≡ ) {

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;
real z int p =  ;  /∗ z-intercept of \overrightarrow{p_{0}p_{1}}. ∗/
real z int q =  ;  /∗ z-intercept of \overrightarrow{q_{0}q_{1}}. ∗/
if (slope p x z ≠  )  /∗ Δx_{p} ≠ 0. ∗/

{

z int p = p0 z − (slope p x z ∗ p0 x ); } if (slope q x z ≠ ) /∗ Δx_{q} ≠ 0. ∗/ {

z int q = q0 z − (slope q x z ∗ q0 x ); } if ( ) {

cout ≪ ␣ ␣ ≪ z int p ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ z int q ≪ endl ≪ flush; }

583. [LDF 2003.06.24.] x i will be equal to , if the traces of the lines on the x-y plane were colinear.

Log

[LDF 2003.06.24.] Added this conditional.

⟨ Define Point functions 330 ⟩ +≡

if (x i ≡ ∧ ¬(z int p ≡ ∨ z int q ≡ )) { x i = (z int q − z int p)/(slope p x z − slope q x z ); y i = p0 y ;

} 584. In the following case, p⃗_{xz} and q⃗_{xz} are both parallel to the z-axis. They have the same value for x. We’ve set x i above, so there’s no need to do so here again. ⟨ Define Point functions 330 ⟩ +≡

if (z int p ≡  ∧ z int q ≡  ) {
if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;

if (p0 x ≠ q0 x ) {

if (  ) cout ≪  ␣     ␣    ␣  ≪ flush;
cerr ≪  ␣  ␣   ␣  ≪  ≪ p0 x ≪ ␣ ≪ p0 z ≪ ␣ ≪
p0 z ≪ ␣ ␣ ≪ p1 x ≪ ␣ ≪ p1 z ≪ ␣ ≪ p1 z ≪ ≪ q0 x ≪
␣ ≪ q0 z ≪ ␣ ≪ q0 z ≪ ␣ ␣ ≪ q1 x ≪ ␣ ≪ q1 z ≪ q1 z ≪
␣ ≪ flush;

return ; }

} else if (z int p ≡ ) {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; z i = p0 z ;

} else if (z int q ≡ ) {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; z i = q0 z ;

} else {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; z i = slope p x z ∗ x i + z int p;

} } 585. [LDF 2002.10.27.] If x i , y i , and z i are all valid, set bp.pt using those values. Otherwise, set it to . If this Point is on both of the line segments \overrightarrow{p_{0}p_{1}} and \overrightarrow{q_{0}q_{1}}, set bp.b to true, otherwise set it to false. ⟨ Define Point functions 330 ⟩ +≡

if ( ) { cout ≪ ␣ ␣ ␣ ≪ flush; cout ≪ ␣ ␣ ≪ x i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ y i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ z i ≪ endl ≪ flush;

} if (x i ≡ ∨ y i ≡ ∨ z i ≡ ) {

return ; if ( ) cout ≪ ␣ ≪ flush;

} else {

bp.pt .set (x i , y i , z i ); if ( ) bp.pt .show ( );

} if (bp.pt .is on segment (p0 , p1 ).first ≡ false ∨ bp.pt .is on segment (q0 , q1 ).first ≡ false) bp.b = false; else bp.b = true; if ( ) {

cout ≪ ␣ ␣ ≪ bp.b ≪ endl ; cout ≪ ␣ ≪ flush;

} return bp; }

586. Picture functions. These functions must be defined here, because they use types which are incompletely defined in pictures.web.

587. Assignment operator. !! PORTING [LDF 2002.12.05.] Moved here from pictures.web. See that file for explanation. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::operator=(const Picture &p) {

clear ( ); transform = p.transform; for (vector⟨Shape ∗⟩::const iterator iter = p.shapes .begin( ); iter ≠ p.shapes .end ( ); iter^{++}) {

shapes .push back ((∗iter ) get copy ( )); } Label ∗lbl ; for (vector⟨Label ∗⟩::const iterator iter = p.labels .begin( ); iter ≠ p.labels .end ( ); iter^{++}) {

lbl = (∗iter ) get copy ( );

labels .push back (lbl ); }

}

588. Copy constructor. !! PORTING [LDF 2002.12.05.] Moved here from pictures.web. See that file for explanation. ⟨ Define Picture functions 264 ⟩ +≡

Picture ::Picture(const Picture &p) : do labels (true) {

160  COPY CONSTRUCTOR  3DLDF-1.1.5.1 §588

∗this = p; }

589. Combining Pictures. [LDF 2002.04.17.] Added this function.

Log

[LDF 2002.10.29.] Made p const and fixed bugs that changed p (see below). [LDF 2002.10.29.] BUG FIX: Now, p.transform is applied to ∗(shapes .back ( )), previously it was applied

to ∗∗iter , which was not what I wanted.

[LDF 2002.10.29.] BUG FIX: Now, p.transform is applied to ∗(labels .back ( ) pt ), previously it was applied to ∗((∗iter ) pt ), which is not what I wanted.

[LDF 2002.10.29.] BUG FIX: Now, p.transform.reset ( ) is no longer called.

⟨ Define Picture functions 264 ⟩ +≡ void Picture ::operator+=(const Picture &p) {

for (vector⟨Shape ∗⟩::const iterator iter = p.shapes .begin( ); iter ≠ p.shapes .end ( ); iter^{++}) { shapes .push back ((∗iter ) get copy ( ));

/∗ [LDF 2002.10.29.] Normally, transform in a Picture is applied to its Shapes when it’s output, however, it must be done now for the copies of the Shapes from Picture p that are copied onto ∗this , because p.transform is only known within p; the Shapes don’t “know” about it. ∗/

∗(shapes .back ( )) ∗= p.transform; } for (vector⟨Label ∗⟩::const iterator iter = p.labels .begin( ); iter ≠ p.labels .end ( ); iter^{++}) {

labels .push back ((∗iter ) get copy ( ));

∗(labels .back ( ) pt ) ∗= p.transform; }

}

590. Clear Picture. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::clear ( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (shapes .size( ) ≤ 0 ∧ labels .size( ) ≤ 0) return; transform.reset ( ); for (vector⟨Shape ∗⟩::iterator iter = shapes .begin( ); iter ≠ shapes .end ( ); iter^{++}) {

(∗iter ) clear ( );

delete (∗iter ); } for (vector⟨Label ∗⟩::iterator iter = labels .begin( ); iter ≠ labels .end ( ); iter^{++}) {

/∗ ?? I tried to use ∼Label( ) here, but it didn’t work. I got run-time errors having to do with “Unaligned access pid=299273…” (didn’t understand). This works, though. If I change the definition of Label, I’ll have to make corresponding changes here. ∗/

delete (∗iter ) pt ;

delete (∗iter ); } shapes .clear ( );

§590  3DLDF-1.1.5.1  CLEAR PICTURE 161

labels .clear ( );

if ( ) cout ≪ ␣ ≪ flush; }

591. Output. The arguments:

• sort value is used to determine how to sort the Shapes. The values to be used are found in namespace Sorting. Sorting :: is used, if they shouldn’t be sorted, because we will have already drawn them in the order we want them rendered. Sorting :: is used for sorting them according to their maximum z-coordinate for “furthest-first” output. Sorting :: is used for sorting them according to their maximum z-coordinate for “nearest-last” output. So far, no other types of sorting have been defined. The simple painter’s algorithm implemented here for surface hiding fails for Shapes where one Shape is

partly in front of and partly behind another. For these cases, it will be necessary to find the intersection points and divide the Shapes into parts. TO DO: Implement a routine for dividing up Shapes. This will not be done soon!

do warnings : Sometimes we’ll want use the min x proj , max x proj , etc., arguments to cut off parts of the image, or we’ll deliberately place the Focus where it won’t be able to “see” part of the image. In these cases, it will be annoying to see the warnings.

Log

[LDF 2002.09.21.] Added the arguments do sort and do warnings . [LDF 2003.05.16.] Changed bool do sort to const unsigned short sort value. About to add namespace

Sorting with constants for different ways of sorting, i.e., “no sort”, “nearest-last”, or “furthest-first”.

592. Focus argument. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::output (const Focus &f, const unsigned short proj , real factor , const unsigned short sort value, const bool do warnings , const real min x proj , const real max x proj , const real min y proj , const real max y proj , const real min z proj , const real max z proj ){ bool = false; /∗ true ∗/

using namespace Sorting;

if ( ) { cout ≪ ␣ ␣ ␣ ≪ flush; cout ≪ ␣ ␣ ≪ min x proj ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ max x proj ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ min y proj ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ max y proj ≪ endl ≪ flush;

} /∗ Check whether the vector shapes has anything in it. If it doesn’t, return. ∗/ if (shapes .size( ) ≤ 0 ∧ labels .size( ) ≤ 0) {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; return;

} 593. [LDF 2002.09.17.] Some Shapes may consist of other Shapes, and not have an output ( ) function of their own, so we must extract their contents recursively until we get to Shapes that have one. So far, only Point, Path, and Solid have output ( ) functions, and all other Shapes reduce to Paths or Solids.

[LDF 2002.09.17.] extract ( ) checks that all of the Points contained in the Shape can be projected with the Focus that is being used. If any of them cannot be, then extract ( ) returns an empty vector of Shapes. This means that any Shape must be entirely projectable; partial Shapes will not be output. problem, too.

Log

[LDF 2003.01.05.] Modified the TEX text above to account for the fact that I’ve added Solid. [LDF 2003.01.05.] BUG FIX: Moved the code that causes transform to be applied to the elements of

shapes . This is now done before the extremes are set. The way it was before didn’t work properly, because extract ( ) used the untransformed values to decide whether a Shape was projectable. In order to do this, I had to make apply transform( ) a Shape function.

⟨ Define Picture functions 264 ⟩ +≡ vector⟨Shape ∗⟩ v; vector⟨Shape ∗⟩ elements ; vector⟨Shape ∗⟩::iterator iter ; bool do transform = ¬transform.is identity ( ); = false; /∗ true ∗/ if ( ) {

if (do transform) { cout ≪ ␣ ; transform.show ( );

}

else cout ≪ ␣ ␣ ; } for (iter = shapes .begin( ); iter ≠ shapes .end ( ); ^{++}iter ) {

if (do transform) {

(∗∗iter ) ∗= transform; } v = (∗iter ) extract (f, proj , factor ); if ( ∧ v.size( ) ≡ 0)

    cerr ≪  ␣  ␣  ≪  ␣        ␣   ␣     ␣       ␣ ≪

≪ flush;

for (vector⟨Shape ∗⟩::iterator i = v.begin( ); i ≠ v.end ( ); ^{++}i) {

elements .push back (∗i); }

} = false;

§594  3DLDF-1.1.5.1  FOCUS ARGUMENT 163

594. Set the extremes for the Shape and handle the error if it returns false. (LDF Undated)

Log

[LDF 2002.09.18.] Changed the error handling code below. Formerly, get minimum z ( ) was invoked, but this is unnecessary, since set extremes ( ) returns false if something goes wrong with setting the extreme values for the Shape.

⟨ Define Picture functions 264 ⟩ +≡ { /∗ [LDF 2003.01.05.] Beginning of group. ∗/ valarray⟨real⟩ extremes (6, 0); for (iter = elements .begin( ); iter ≠ elements .end ( ); ^{++}iter ) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; if (¬(∗∗iter ).set extremes ( )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪

␣ ␣ ␣ ␣ ≪ flush; (∗∗iter ).suppress output ( );

}

595. [LDF 2002.09.18.] Added this routine. It checks for whether the values in the valarray⟨real⟩ projective extremes in the Shape fall within the limits given by the min x proj , max x proj , min y proj , and max x proj arguments to this function (Picture ::output ( )). (Note that min z proj and max z proj are currently not checked.) If they don’t, the Shape ∗ is removed from elements . Note that the projected z-coordinates are not currently checked, but they are used for ordering the Shapes for output (furthest away first). ⟨ Define Picture functions 264 ⟩ +≡

extremes = (∗∗iter ).get extremes ( ); if ( ) /∗ [LDF 2002.09.21.] Show the extremes for this Shape. ∗/ {

for (int i = 0; i < 4; i^{++}) {

cout ≪ ≪ i ≪ ␣ ␣ ≪ extremes [i] ≪ ; } cout ≪ ␣ ␣ ␣ ␣ ≪ (extremes [0] < min x proj ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ␣ ␣ ≪ (extremes [1] > max x proj ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ␣ ␣ ≪ (extremes [2] < min y proj ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ␣ ␣ ≪ (extremes [3] > max y proj ) ≪ endl ≪ flush;

} if (extremes [0] < min x proj ∨ extremes [1] > max x proj ∨ extremes [2] < min y proj ∨ extremes [3] >

max y proj ) { if (do warnings ≡ true) {

    cerr ≪  ␣  ␣  ≪  ␣    ␣       ␣    ␣      ␣   ␣    ␣

␣  ␣  ≪  ␣      ␣    ␣    ␣  ≪ flush;

}

(∗∗iter ).suppress output ( ); } } /∗ for ∗/ } /∗ End of group. ∗/ 596. [LDF 2003.05.16.] Sorting can be performed in different ways, depending on the sort value argument. This is explained in ⟨ Define comparison classes 498 ⟩.

[LDF 2002.09.18.] It’s necessary to make sure that sorting is only performed if elements is non-empty. It could be empty now, if the error handling code above has removed all of the elements because set extremes ( ) returned false for all of them. We can’t just return, because there might still be Labels on the Picture. ⟨ Define Picture functions 264 ⟩ +≡

if (elements .size( ) > 0) { if (sort value ≡ ) sort (elements .begin( ), elements .end ( ), Compare minimum z( )); else if (sort value ≡ ) sort (elements .begin( ), elements .end ( ), Compare maximum z( )); else if (sort value ≡ ) sort (elements .begin( ), elements .end ( ), Compare mean z( )); if ( ) {

if (sort value ≡  ) cout ≪ ␣   ␣     ␣     ␣  ;
else if (sort value ≡  ) cout ≪ ␣   ␣     ␣     ␣  ;
else if (sort value ≡  ) cout ≪ ␣   ␣      ␣     ␣  ;

for (iter = elements .begin( ); iter ≠ elements .end ( ); ^{++}iter ) {

cout ≪ ␣ ␣ ≪ (∗∗iter ).get minimum z ( ) ≪ endl ≪ ␣ ␣ ≪

(∗∗iter ).get maximum z ( ) ≪ endl ≪ ␣ ␣ ≪ (∗∗iter ).get mean z ( ) ≪ endl ≪ endl ; } cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ flush;

}

for (iter = elements .begin( ); iter ≠ elements .end ( ); ^{++}iter ) { (∗∗iter ).output ( ); (∗∗iter ).unsuppress output ( ); /∗ [LDF 2002.09.18.] With a different Focus or different limiting values for the projection, this Shape might be projectable, so we reset do output to true. If it can’t be projected the next time, suppress output ( ) will be invoked again. ∗/

} }

597. Output the labels. LDF Undated. It is necessary to output the labels last because they might otherwise be drawn over by fill ( ) or filldraw ( ) commands.

[LDF 2002.09.17.] I’m not bothering to sort the labels so that the ones behind can be hidden by the ones in front. Labels should all be visible and are not put into perspective, so they shouldn’t overlay one another.

[LDF 2002.04.25.] Added following conditional. Sometimes it’s irritating to have the labels when a Picture is copied and transformed, and both the original and the transformed versions are output. ⟨ Define Picture functions 264 ⟩ +≡

if (do labels ≡ true) {

for (vector⟨Label ∗⟩::iterator i = labels .begin( ); i ≠ labels .end ( ); ^{++}i) {

/∗ [LDF 2002.09.17.] Simplified the following code. Formerly, there was a conditional here that chose which version of Label ::output ( ) to call. I’ve removed the version without a Transform argument and invoke Transform ::is identity ( ) in Label ::output (const Focus &, const Transform &). [LDF 2002.04.25.] This applies transform to the Point Label ::pt . ∗/

(∗∗i).output (f, proj , factor , transform); }

} /∗ [LDF 2002.04.25.] Added following line. This fixes a bug. If I don’t reset transform to identity,

it will be applied again each time I output a Picture, which is not what I want. ∗/ transform.reset ( ); if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; }

§598  3DLDF-1.1.5.1  NO FOCUS ARGUMENT 165

598. No Focus argument. ⟨ Define Picture functions 264 ⟩ +≡

void Picture ::output (const unsigned short proj , real factor , const unsigned short sort value, const bool do warnings , const real min x proj , const real max x proj , const real min y proj , const real max y proj , const real min z proj , const real max z proj )

{

output (default focus , proj , factor , sort value, do warnings , min x proj , max x proj , min y proj ,

max y proj , min z proj , max z proj ); }

599. Focus.

600. Focus class definition. [LDF 2002.09.18.] Made Focus a class (it was formerly a struct). Added char axis data member. It indicates the axis to which position should be transformed to when it’s put in standard position. This determines which plane the image is projected onto. If axis ≡ (the default), the image is projected onto the x-y plane, if axis ≡ , the z-y plane, if , the x-z plane.

At this time, I’m not adding the routines that will do this, which will entail changing transform and possibly persp, I’m just adding axis . I must also add a function for changing axis without changing any of the other data members. TO DO: Add these routines!!

[LDF 2002.09.14.] Added Transform persp. It’s needed because I need to get the z value of the world coordinates after the transformation that puts the Focus into standard position, but before the perspective transformation is performed. This z value can be used in an algorithm for surfaces hiding. If this were not the case, I could combine the transformations, because matrix multiplication is associative (it is not, however, commutative, except with special matrices).

[LDF 2002.09.11.] Added class Focus and the following constructors: The default constructor with no arguments, the one with two Point arguments and a real argument , and the one with seven real arguments.

format Focus int

⟨ Define class Focus 600 ⟩ ≡

class Focus { Point position; Point direction; Point up; real distance; real angle; char axis ; Transform transform; Transform persp;

public: ⟨ Declare Focus functions 602 ⟩

};

This code is used in sections 633 and 634.

601. Constructors and setting functions. [LDF 2002.09.22.] TO DO: Check magnitude of direction − position and make sure it’s non-zero!!

[LDF 2002.10.13.] The effect of using an angle ≠ 0 is similar to that of rotating a camera about an axis through its aperture and perpendicular to the surface of the lens. Because this is possible, it is necessary to indicate the upward direction of a projection. The Point up does this. It is determined in the constructors and setting functions by the vector direction − position and angle. up is first set to (0, 1, 0) if axis ≡ or axis ≡ , or (1, 0, 0) if axis ≡ . If angle ≠ 0, up and transform are then rotated by −angle. Then, up is transformed by the inverse of transform, in order to put it in the correct location with respect to position. This location is “above” position by definition.

[LDF 2002.10.13.] Changed all of the constructors and setting functions except for the default constructor and the first non-default constructor. Now, all the others use the latter to create a Focus locally and use Focus ::operator=( ), which I’ve defined today, to assign to ∗this . This eases maintenance and cuts down on the potential for error through inconsistencies in the different constructors and setting functions.

602. Default constructor. (No arguments). ⟨ Declare Focus functions 602 ⟩ ≡

Focus( )

{ }

See also sections 604, 606, 609, 611, 613, 615, 617, 620, 621, 622, 623, 624, 625, 627, and 628. This code is used in section 600.

603. real arguments. The first three real arguments are for the coordinates of the center of projection (the focus in the narrowest sense) (position), the fourth through the sixth are for the coordinates of the direction of view (direction), dist is for the distance of position to the projection plane (distance), ang is for the angle of rotation around the axis \overrightarrow{pd} where p stands for position and d for direction (angle), and the char argument ax indicates the axis with which \overrightarrow{pd} is to be aligned, and around which up is to be rotated (axis ).

Log

[LDF 2003.07.04.] Now calling persp.set element ( ) instead of accessing the elements of persp directly. The latter is no longer possible, because Focus is no longer a friend of Transform.

604. Constructor. ⟨ Declare Focus functions 602 ⟩ +≡

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 = ); 605. ⟨ Define Focus functions 605 ⟩ ≡

Focus ::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 , char ax )

: distance(dist ), angle(ang ), axis (ax ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣       ␣   ␣    ␣  ≪ flush;

axis = tolower (axis );

if (axis ≠  ∧ axis ≠  ∧ axis ≠ ) {
cerr ≪  ␣  ␣        ␣  ␣    ␣  ≪

␣ ␣ ␣ ␣ ␣ ≪ axis ≪ ␣ ␣ ≪ flush; axis = ;

} position.set (pos x , pos y , pos z ); direction.set (dir x , dir y , dir z );

#if 0

transform.reset ( );

/∗ [LDF 2002.12.10.] This doesn’t seem to be necessary. I believe I added it while debugging. ∗/ #endif

if ( ) {

transform.show ( ␣ ␣ ); } transform.align with axis (position, direction, axis ); if ( ) {

transform.show (  ␣     ␣  );
cout ≪  ␣        ␣  ␣  ≪ flush;

} Transform unalign up = transform.inverse( ); /∗ Use the positive y-axis for the “up” direction,

if axis ≡ or , and the positive x-axis if axis ≡ . ∗/ if (axis ≡ ∨ axis ≡ ) up.set (0, 1, 0); else up.set (1, 0, 0); if (angle ≠ 0) {

if (axis ≡ ) up ∗= transform.rotate(0, 0, −angle);

else if (axis ≡ ) up ∗= transform.rotate(−angle);

else if (axis ≡ ) up ∗= transform.rotate(0, −angle);

else {

cerr ≪  ␣  ␣  ≪  ␣     ␣       ␣
␣    ␣   ␣       ␣      ␣ ≪ axis ≪ endl ≪  ␣      ␣  ≪
␣ ␣ ␣ ␣ ␣ ≪ flush;

up ∗= transform.rotate(0, 0, −angle); } if ( ) up.show ( ␣ ␣ );

} up ∗= unalign up; up.apply transform( ); transform.shift (0, 0, −distance); persp.set element (2, 2, 0); persp.set element (2, 3, 1/distance); if ( ) cout ≪ ␣ ␣ ␣ ␣ ≪ flush;

}

See also sections 607, 610, 612, 614, 616, 618, 626, and 629.

This code is used in section 633.

606. Setting function. [LDF 2002.09.17.] Added this function. ⟨ Declare Focus functions 602 ⟩ +≡

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.0, char ax = );

607. ⟨ Define Focus functions 605 ⟩ +≡

void Focus ::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 , char ax )

{ Focus f(pos x , pos y , pos z , dir x , dir y , dir z , dist , ang , ax ); ∗this = f;

}

608. Point arguments.

609. Constructor. ⟨ Declare Focus functions 602 ⟩ +≡

Focus(const Point &pos , const Point &dir , const real dist , const real ang = 0.0, char ax = );

610. ⟨ Define Focus functions 605 ⟩ +≡

Focus ::Focus(const Point &pos , const Point &dir , const real dist , const real ang , char ax )

{ Focus f(pos .get x ( ), pos .get y ( ), pos .get z ( ), dir .get x ( ), dir .get y ( ), dir .get z ( ), dist , ang , ax ); ∗this = f;

}

611. Setting function. [LDF 2002.09.17.] Added this function. ⟨ Declare Focus functions 602 ⟩ +≡

void set (const Point &pos , const Point &dir , const real dist , const real ang = 0.0, char ax = );

612. ⟨ Define Focus functions 605 ⟩ +≡

void Focus ::set (const Point &pos , const Point &dir , const real dist , const real ang , char ax ) {

Focus f(pos .get x ( ), pos .get y ( ), pos .get z ( ), dir .get x ( ), dir .get y ( ), dir .get z ( ), dist , ang , ax ); ∗this = f;

}

613. Assignment. [LDF 2002.10.13.] Added this function. Now using it in all but the first of the nondefault constructors. This saves on duplicating code and reduces the probability of bugs that might arise from inconsistencies among the constructors and setting functions. ⟨ Declare Focus functions 602 ⟩ +≡

§614  3DLDF-1.1.5.1  ASSIGNMENT 169

const Focus &operator=(const Focus &); 614. ⟨ Define Focus functions 605 ⟩ +≡

const Focus &Focus ::operator=(const Focus &f) {

if (this ≡ &f) /∗ [LDF 2002.10.13.] Prevent self-assignment. ∗/

return ∗this ; position = f.position; direction = f.direction; up = f.up; distance = f.distance; angle = f.angle; axis = f.axis ; transform = f.transform; persp = f.persp; return ∗this ;

}

615. Reset angle. [LDF 2002.10.12.] Added this function. ⟨ Declare Focus functions 602 ⟩ +≡

void reset angle(const real ang );

170  RESET ANGLE  3DLDF-1.1.5.1 §616

616. ⟨ Define Focus functions 605 ⟩ +≡

void Focus ::reset angle(const real ang ) {

angle = ang ; transform.reset ( ); persp.reset ( ); transform.align with axis (position, direction, axis ); Transform unalign up = transform.inverse( ); /∗ Use the positive y-axis for the “up” direction,

if axis ≡ or , and the positive x-axis if axis ≡ . ∗/ if (axis ≡ ∨ axis ≡ ) up.set (0, 1, 0); else up.set (1, 0, 0); if (angle ≠ 0) {

if (axis ≡ ) up ∗= transform.rotate(0, 0, −angle); else if (axis ≡ ) up ∗= transform.rotate(−angle); else if (axis ≡ ) up ∗= transform.rotate(0, −angle); else {

cerr ≪  ␣  ␣  ≪  ␣     ␣       ␣
␣    ␣   ␣       ␣      ␣ ≪ axis ≪ endl ≪  ␣      ␣  ≪
␣ ␣ ␣ ␣ ␣ ≪ flush;

up ∗= transform.rotate(0, 0, −angle); }

} up ∗= unalign up; up.apply transform( ); transform.shift (0, 0, −distance); persp.set element (2, 2, 0); persp.set element (2, 3, 1/distance);

}

617. Show.

Log

[LDF 2002.09.17.] Added this function. [LDF 2003.07.09.] Made the arguments const.

§618  3DLDF-1.1.5.1  SHOW 171

⟨ Declare Focus functions 602 ⟩ +≡ void show (const string text str = , const bool show transforms = false) const; 618. ⟨ Define Focus functions 605 ⟩ +≡

void Focus ::show (const string text str , const bool show transforms ) const {

cout ≪ text str ≪ endl ;

position.show ( );

direction.show ( );

up.show ( );

cout ≪ ␣ ␣ ≪ distance ≪ ␣ ≪ ␣ ␣ ≪ axis ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ angle ≪ endl ≪ flush; if (show transforms ≡ true) {

transform.show ( ); persp.show ( );

}

return; }

619. Returning elements and information. [LDF 2002.09.18.] Added this section. The functions in this section are now necessary, since I’ve made Focus a class (it was formerly a struct), and the data members private.

620. Get position.

Log

[LDF 2002.09.18.] Added this function.

⟨ Declare Focus functions 602 ⟩ +≡ inline const Point &get position( ) const {

return position; }

621. Get direction.

Log

[LDF 2003.07.09.] Added this function.

⟨ Declare Focus functions 602 ⟩ +≡ inline const Point &get direction( ) const {

return direction; }

622. Get distance. [LDF 2002.09.18.] Added this function. ⟨ Declare Focus functions 602 ⟩ +≡

inline const real &get distance( ) const {

return distance; }

623. Get up. [LDF 2002.09.18.] Added this function.

172  GET UP  3DLDF-1.1.5.1 §623

⟨ Declare Focus functions 602 ⟩ +≡ inline const Point &get up( ) const {

return up; }

624. Get transform.

Log

[LDF 2002.09.18.] Added this function.

⟨ Declare Focus functions 602 ⟩ +≡ inline const Transform &get transform( ) const {

return transform; }

625. Get transform element.

Log

[LDF 2002.09.18.] Added this function. [LDF 2003.07.04.] Made non-inline. It now calls Transform ::get element ( ) instead of accessing

transform.matrix directly. This is no longer possible, because Focus is no longer a friend of Transform. [LDF 2003.07.09.] Changed the const unsigned int arguments to const unsigned short.

⟨ Declare Focus functions 602 ⟩ +≡ real get transform element (const unsigned short row , const unsigned short column) const;

§626  3DLDF-1.1.5.1  GET TRANSFORM ELEMENT 173

626. ⟨ Define Focus functions 605 ⟩ +≡

real Focus ::get transform element (const unsigned short row , const unsigned short column) const {

return transform.get element (row , column); }

627. Get persp.

Log

[LDF 2002.09.18.] Added this function.

⟨ Declare Focus functions 602 ⟩ +≡ inline const Transform &get persp( ) const {

return persp; }

628. Get persp element.

Log

[LDF 2002.09.18.] Added this function. [LDF 2003.07.04.] Made non-inline. It now calls Transform ::get element ( ) instead of accessing

transform.matrix directly. This is no longer possible, because Focus is no longer a friend of Transform. [LDF 2003.07.09.] Changed the const unsigned int arguments to const unsigned short.

⟨ Declare Focus functions 602 ⟩ +≡ real get persp element (const unsigned short row , const unsigned short column) const;

629. ⟨ Define Focus functions 605 ⟩ +≡

real Focus ::get persp element (const unsigned short row , const unsigned short column) const {

return persp.get element (row , column); }

630. Global variables. [LDF 2002.12.08.] !! BUG. Commented-out, because of a bug involving transformations.

Default value. Can be changed. ⟨ Global variables 18 ⟩ +≡

Focus default focus (0, 10, −10, 0, 10, 0, 10); 631. ⟨ Declarations for the header file 21 ⟩ +≡

extern Focus default focus ;

632. Putting Point and Focus together.

633. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Point 309 ⟩ ⟨ Declare non-member template functions for Point 336 ⟩ ⟨ Define Point constructors 325 ⟩ ⟨ Define class Focus 600 ⟩ ⟨ Define comparison classes 498 ⟩ ⟨ Define static Point data members 310 ⟩ ⟨ Type definitions 15 ⟩ ⟨ Global constants 22 ⟩ ⟨ Global variables 18 ⟩ ⟨ Define Transform functions 169 ⟩ ⟨ Define Point functions 330 ⟩ ⟨ Define non-member non-template functions for Point 481 ⟩ ⟨ Define bool point functions 314 ⟩ ⟨ Define bool point quadruple functions 316 ⟩ ⟨ Define bool real point functions 318 ⟩ ⟨ Define Focus functions 605 ⟩ ⟨ Define Label functions 514 ⟩ ⟨ Define Picture functions 264 ⟩

634. This is what’s written to points.h. ⟨ 634 ⟩ ≡

⟨ Define class Point 309 ⟩ ⟨ Define class Focus 600 ⟩ ⟨ Define comparison classes 498 ⟩ ⟨ Declare non-member template functions for Point 336 ⟩ ⟨ Declare non-member non-template functions for Point 480 ⟩ ⟨ Type definitions 15 ⟩ ⟨ Declarations for the header file 21 ⟩

635. Line (lines.web). [LDF 2002.10.29.] 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.

[LDF 2003.06.03.] TO DO: Add setting functions.

Log

[LDF 2002.04.08.] Added this section. [LDF 2002.04.12.] Created this file. Removed the code for Line from points.web and put it here.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

§635  3DLDF-1.1.5.1  LINE (LINES.WEB) 175

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

636. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include

637. Line struct definition.

format Line Point

⟨ Define struct Line 637 ⟩ ≡ struct Line { public: Point position;

Point direction;

⟨ Declare Line constructors 639 ⟩ ⟨ Declare Line functions 643 ⟩

};

This code is used in sections 657 and 658.

638. Constructors. [LDF 2002.10.29.] The constructors and assignment operator take Point arguments for position and direction. If you want to get the Line between two Points, use Point ::get line( ).

Log

[LDF 2002.04.12.] It took me a while to figure out why I was having problems with Lines. The constructor was making the opposite assumption, namely, that it was supposed to calculate the Line from its arguments, rather than just taking them as they were. This caused a problem in Plane ::intersection line( ).

639. Default constructor. This constructor takes two optional Point arguments. The default for the Point arguments is origin. ⟨ Declare Line constructors 639 ⟩ ≡

Line(const Point &pos = origin, const Point &dir = origin);

See also section 641. This code is used in section 637.

640. ⟨ Define Line constructors 640 ⟩ ≡

Line ::Line(const Point &pos , const Point &dir )

: position(pos ), direction(dir ) { position.apply transform( ); direction.apply transform( );

}

See also section 642. This code is used in section 657.

641. Copy constructor. [LDF 2002.10.29.] Calling apply transform( ) on position and direction is probably unnecessary, because it will already have been called on l.position and l.direction when l was declared or assigned to. But maybe some function has affected l.position.transform or l.direction.transform, so I’m doing it just to be sure. ⟨ Declare Line constructors 639 ⟩ +≡

Line(const Line &l);

642. ⟨ Define Line constructors 640 ⟩ +≡

Line ::Line(const Line &l)

: position(l.position), direction(l.direction) { position.apply transform( ); direction.apply transform( );

}

643. Assignment. ⟨ Declare Line functions 643 ⟩ ≡

void operator=(const Line &l);

See also sections 646, 648, and 652. This code is used in section 637.

644. ⟨ Define Line functions 644 ⟩ ≡

void Line ::operator=(const Line &l)

{ position = l.position; direction = l.direction;

}

See also sections 649, 650, 651, 653, and 978. This code is used in sections 657 and 980.

645. Get Line. (Point function). LDF Undated. Declared in points.web. Must be defined here, because Line is an incomplete type there.

[LDF 2003.06.06.] get line( ) returns a Line l corresponding to the line from ∗this to p, where l.position is a Point on the Line, and l.direction is a direction vector. l.position will be ∗this , and l.direction will be pt − ∗this .

Log

[LDF 2003.06.06.] BUG FIX: Changed the call to Line( ), so that the argument for direction is pt − ∗this instead of pt .

⟨ Define Point functions 330 ⟩ +≡ Line Point ::get line(const Point &pt ) const {

Line l(∗this , (pt − ∗this )); return l;

}

646. Get Path. [LDF 2003.06.06.] Returns a linear Path consisting of two Points, and corresponding to the Line. Must be defined in paths.web, because Path is an incomplete type here.

Log

[LDF 2003.06.06.] Added this function.

⟨ Declare Line functions 643 ⟩ +≡ Path get path(void) const;

647. Intersection. [LDF 2003.06.06.] Commented-out. This function doesn’t work. Using a different version, that finds the intersection points of the traces of the lines on two or all of the major axes. TO DO: Fix it!

LDF Undated. Declared in points.web, but must be defined here, because Line is an incomplete type in

points.web.

Log

[LDF 2002.04.12.] Moved this function definition here from points.web because it requires the use of Lines, and Line is an incomplete type there.

[LDF 2002.04.15.] Commented-out, because I’m having problems with it. Commented old version in points.web back in. I don’t quite understand this, because it seemed to be working.

[LDF 2002.04.22.] Changed return value to bool point, to correspond with the old version. This facilitates testing, since all I have to do is to comment-out whichever version I don’t want to use, and uncomment-out the other one. Made a few changes in the function definition in order to be able to return a bool point.

178  INTERSECTION  3DLDF-1.1.5.1 §647

⟨ Define Point functions 330 ⟩ +≡ #if 1 /∗ 0 ∗/

bool point Point ::intersection point (const Point &pp0 , const Point &pp1 , const Point

&qq0 , const Point &qq1 )

{ /∗ START HERE. DEBUGGING. [LDF 2003.06.24.] ∗/

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

Line l p = pp0 .get line(pp1 ); Line l q = qq0 .get line(qq1 ); if ( ) {

pp0 .show ( );

pp1 .show ( );

qq0 .show ( );

qq1 .show ( );

l p.show ( );

l q .show ( ); } bool real point brp = l p.get distance(l q ); if ( ) {

cout ≪ ␣ ␣ ≪ brp.b ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ brp.r ≪ endl ≪ flush;

brp.pt .show ( ); } if (brp.r ≠ 0 ∨ brp.b ≡ false ∨ brp.pt ≡ ) return ; bool point bp; bp.pt = brp.pt ; bool real br p = brp.pt .is on segment (pp0 , pp1 ); bool real br q = brp.pt .is on segment (qq0 , qq1 ); if ( ) {

cout ≪ ␣ ␣ ≪ br p.first ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ br p.second ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ br q .first ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ br q .second ≪ endl ≪ flush;

} bp.b = (br p.first ∧ br q .first ); if ( ) cout ≪ ␣ ; return bp;

} #endif

648. Get distance. [LDF 2002.04.22.] Renamed this get distance( ) from intersection point ( ). The old version of Point ::intersection point ( ), which I am currently using again, since the new version wasn’t working, returns a bool point, which is sensible. If I start using the commented-out version above again, I should have it return a bool point too, instead of a bool real point. This will make it easier to switch back to the old version, if I have problems again.

[LDF 2003.06.11.] START HERE. TO DO: get distance( ) may be working now, due to changes I’ve made to Line elsewhere. Read this through and see how it works. Then test. Also, check where it’s used. [LDF 2003.06.03.] When I’ve fixed it, add description to line.texi.

§648  3DLDF-1.1.5.1  GET DISTANCE 179

Log

[LDF 2002.04.10.] Added this function.

⟨ Declare Line functions 643 ⟩ +≡ bool real point get distance(const Line &l) const;

649. ⟨ Define Line functions 644 ⟩ +≡

bool real point Line ::get distance(const Line &l) const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

bool real point brp; Point normal = direction.cross product (l.direction); if ( ) normal .show ( ␣ ␣ ␣ ); Point normal unit = normal .unit vector ( ); if ( ) normal unit .show ( ); if (normal unit ≡ origin) {

if ( ) cout ≪ ␣ ␣ ≪ flush;

brp.b = false; /∗ No intersection. ∗/

brp.pt = ;

Point temp pt (l.position);

temp pt −= position;

temp pt = temp pt .cross product (direction);

brp.r = temp pt .magnitude( )/direction.magnitude( ); /∗ [LDF 2002.10.29.] Distance. ∗/ if ( ) {

cout ≪ ␣ ␣ ≪ brp.r ≪ endl ≪ flush; } if ( ) cout ≪ ␣ ; return brp;

} else { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; brp.r = fabs ((l.position − position).dot product (normal unit ));

if (  ) cout ≪  ␣  ␣ ≪ brp.r ≪ endl ≪ flush;

180  GET DISTANCE  3DLDF-1.1.5.1 §650

650. Lines have an intersection.

Log

[LDF 2003.08.27.] Commented-out the declarations of v x , v y , and v z , since they are not used. I haven’t deleted them, in case I need them someday.

⟨ Define Line functions 644 ⟩ +≡

if (brp.r < Point ::epsilon( )) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; brp.r = 0; brp.b = true; real a x = position.get x ( ); real a y = position.get y ( ); real a z = position.get z ( ); real b x = l.position.get x ( ); real b y = l.position.get y ( ); real b z = l.position.get z ( );

#if 0 real v x = direction.get x ( ); real v y = direction.get y ( ); real v z = direction.get z ( );

#endif real w x = l.direction.get x ( ); real w y = l.direction.get y ( ); real w z = l.direction.get z ( ); real u x = normal .get x ( ); real u y = normal .get y ( ); real u z = normal .get z ( ); real t; if (u z ≠ 0) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ;

t = (((b x − a x ) ∗ w y ) − ((b y − a y ) ∗ w x ))/u z ; } else if (u x ≠ 0) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ;

t = (((b y − a y ) ∗ w z ) − ((b z − a z ) ∗ w y ))/u x ; } else if (u y ≠ 0) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ;

t = (((b z − a z ) ∗ w x ) − ((b x − a x ) ∗ w z ))/u y ; } else {

cerr ≪  ␣     ␣  ≪  ␣  ≪

      ␣  ␣       ␣␣     ␣    ␣      ␣     ␣    ␣ ≪
      ␣      ␣  ␣         ␣  ␣      ␣  ≪

␣ ≪ flush;

return ; } if ( ) cout ≪ ␣ ␣ ≪ t ≪ endl ≪ flush; brp.pt = direction; brp.pt ∗= t; brp.pt += position; if ( ) {

brp.pt .show ( ␣ ); } if ( ) cout ≪ ␣ ; return brp;

}

651. Lines are not parallel, but do not intersect. ⟨ Define Line functions 644 ⟩ +≡

else { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; brp.b = false; brp.pt = ; if ( ) cout ≪ ␣ ; return brp;

} } }

652. Show. ⟨ Declare Line functions 643 ⟩ +≡

void show (string text = );

653. ⟨ Define Line functions 644 ⟩ +≡

void Line ::show (string text ) {

if (text ≡ ) cout ≪ ;

else cout ≪ text ≪ endl ;

position.show ( );

direction.show ( ); }

654. Global constants for Line. ⟨ Line global constants 654 ⟩ ≡

extern const Line  (  ,  );

This code is used in section 657.

655. ⟨ Declarations for the header file 21 ⟩ +≡

extern const Line ;

656. Putting Line together.

657. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define struct Line 637 ⟩ ⟨ Define Line constructors 640 ⟩ ⟨ Line global constants 654 ⟩ ⟨ Define Line functions 644 ⟩ ⟨ Define Point functions 330 ⟩

182  PUTTING LINE TOGETHER  3DLDF-1.1.5.1 §658

658. This is what’s written to lines.h. ⟨ 658 ⟩ ≡

⟨ Define struct Line 637 ⟩

⟨ Declarations for the header file 21 ⟩

659. Plane (planes.web). [LDF 2002.10.29.] 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.

Log

[LDF 2002.04.12.] Created this file. Removed the code for Plane from points.web and put it here.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

660. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include

661. Plane struct definition.

format Plane Line

⟨ Define struct Plane 661 ⟩ ≡ struct Plane { public: Point normal ;

Point point ; real distance; ⟨ Declare Plane functions 663 ⟩

};

This code is used in sections 694 and 695.

662. Constructors.

663. Default constructor. [LDF 2003.06.06.] Creates a degenerate Plane with point ≡normal ≡origin, and distance≡0. I could have made the Plane be equal to , but there’s probably no reason for doing so. A Plane constructed using this constructor will probably be set using the assignment operator or Path ::get plane( ) immediately, or very soon after being declared.

Log

[LDF 2003.06.06.] Added this function.

⟨ Declare Plane functions 663 ⟩ ≡

Plane(void);

See also sections 665, 667, 669, 672, 674, 677, 679, 684, 686, 687, and 689. This code is used in section 661.

664. ⟨ Define Plane functions 664 ⟩ ≡

Plane ::Plane(void) {

normal = point = origin; distance = 0;

}

See also sections 666, 668, 670, 673, 675, 678, 680, 685, 688, 690, and 966. This code is used in sections 694 and 980.

665. Copy constructor.

Log

[LDF 2003.06.06.] Added this function.

⟨ Declare Plane functions 663 ⟩ +≡ Plane(const Plane &p); 666. ⟨ Define Plane functions 664 ⟩ +≡

Plane ::Plane(const Plane &p)

{ ∗this = p; return;

}

667. Point arguments.

Log

[LDF 2003.06.03.] Changed this function. BUG FIX: distance is now calculated, instead of being passed as an argument. normal is now made a unit vector.

[LDF 2003.06.06.] Changed, so that if point or normal is equal to , the other one is also set to , and distance is set to .

[LDF 2003.06.06.] Arguments are no longer optional. I’ve made this change, because I’ve added a default constructor.

[LDF 2003.06.06.] Added conditional to test for case that point ≡normal . In this case, a warning message is printed to standard error, they are both set to , and distance is set to .

[LDF 2003.06.24.] BUG FIX: Formerly, was returned, if point ≡ normal . This has been changed, so that is returned, if normal ≡ origin. There is, of course, no reason why point shouldn’t be equal to normal .

⟨ Declare Plane functions 663 ⟩ +≡ Plane(const Point &p, const Point &n); 668. ⟨ Define Plane functions 664 ⟩ +≡

Plane ::Plane(const Point &p, const Point &n) : normal (n), point (p) {

point .apply transform( ); normal .apply transform( ); if (point ≡ ) {

normal = ;

distance = ;

return; } else if (normal ≡ ) {

point = ;

distance = ;

return; } else if (normal ≡ origin) {

  cerr ≪  ␣  ␣                ␣  ␣        ␣ ≪  ␣  ␣  ≪

flush; point = ; distance = ; return;

} normal .unit vector (true); distance = −point .dot product (normal ); if (fabs (distance) < Point ::epsilon( )) distance = 0; return;

}

669. Assignment.

Log

[LDF 2003.06.06.] Added this function.

⟨ Declare Plane functions 663 ⟩ +≡ const Plane &operator=(const Plane &p);

186  ASSIGNMENT  3DLDF-1.1.5.1 §670

670. ⟨ Define Plane functions 664 ⟩ +≡

const Plane &Plane ::operator=(const Plane &p) {

if (this ≡ &p) /∗ Make sure it’s not self-assignment. [LDF 2003.06.06.] ∗/

return ∗this ; point = p.point ; normal = p.normal ; distance = p.distance; return p;

}

671. Comparing Planes.

Log

[LDF 2003.06.06.] Added this section.

672. Equality.

Log

[LDF 2003.06.06.] Added this function.

⟨ Declare Plane functions 663 ⟩ +≡ bool operator≡(const Plane &p) const;

673. ⟨ Define Plane functions 664 ⟩ +≡

bool Plane ::operator≡(const Plane &p) const {

return ((point ≡ p.point ) ∧ (normal ≡ p.normal ) ∧ (distance ≡ p.distance)); }

674. Inequality.

Log

[LDF 2003.06.06.] Added this function.

⟨ Declare Plane functions 663 ⟩ +≡ bool operator≠(const Plane &p) const; 675. ⟨ Define Plane functions 664 ⟩ +≡

bool Plane ::operator≠(const Plane &p) const

{

return ¬(operator≡(p)); }

676. Get distance.

677. Point argument. [LDF 2003.06.03.] This function returns a real short r, where r.first is the distance of the Point from the Plane. r.first is always positive. r.second can take on the following 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”.

Log

[LDF 2003.06.03.] Changed the definition of this function. The old definition was incorrect. Also changed return type from real to real short.

[LDF 2003.06.04.] BUG FIX: In the case that r fabs < Point ::epsilon( ), now r fabs is set to 0. Previously, r was, which was wrong, because r fabs is returned, not r. Also, I now set r fabs and s to 0 separately, because they are of different types. I don’t believe any compiler would have trouble with this, but I think it’s cleaner if they are assigned to separately.

⟨ Declare Plane functions 663 ⟩ +≡ real short get distance(const Point &p) const;

678. ⟨ Define Plane functions 664 ⟩ +≡

real short Plane ::get distance(const Point &p) const

{ real r = (p − point ).dot product (normal ); real r fabs = fabs (r); signed short s; if (r fabs < Point ::epsilon( )) {

r fabs = 0; s = 0;

}

else s = static cast⟨signed short⟩(r/r fabs ); return real short(r fabs , s);

}

679. No argument. [LDF 2003.06.03.] This version of get distance( ) returns 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. I’m not using origin as the default for an optional Point argument, because of problems that may arise, when I implement user coordinates and view coordinates .

Log

[LDF 2003.06.03.] Added this function.

⟨ Declare Plane functions 663 ⟩ +≡ real short get distance(void) const;

188  NO ARGUMENT  3DLDF-1.1.5.1 §680

680. ⟨ Define Plane functions 664 ⟩ +≡

real short Plane ::get distance(void) const

{ real f = fabs (distance); signed short s = static cast⟨signed short⟩(distance/f); return real short(f, s);

}

681. Point is on Plane. [LDF 2003.06.04.] This function returns true, if the Point lies on the Plane p, otherwise false. Declared in points.web. Must be defined here, because Plane is an incomplete type in that file.

Log

[LDF 2003.06.04.] Added this function.

⟨ Define Point functions 330 ⟩ +≡ bool Point ::is on plane(const Plane &p) const {

if (p.get distance(∗this ).second ≡ 0) return true;

else return false; }

682. Intersection.

683. Intersection with a line.

684. Point arguments.

Log

[LDF 2003.06.03.] Added this function.

⟨ Declare Plane functions 663 ⟩ +≡ bool point intersection point (const Point &p0 , const Point &p1 ) const; 685. ⟨ Define Plane functions 664 ⟩ +≡

bool point Plane ::intersection point (const Point &p0 , const Point &p1 ) const {

bool point bp; real denominator = (p0 − p1 ).dot product (normal ); if (denominator ≡ 0) /∗ !! TO DO: Handle cases: Path is in Plane, and Path is in a parallel

Plane. [LDF 2003.06.03.] ∗/ {

cerr ≪  ␣  ␣                               ␣       ␣     ␣  ≪

      ␣  ␣  ␣␣      ␣       ␣ ≪  ␣  ␣      ␣  ␣      ␣  ␣        ␣

␣  ≪ endl ≪  ␣          ␣      ␣     ␣  ≪ endl ≪

␣ ≪ endl ≪ endl ≪ flush; return ;

} real numerator = p0 .dot product (normal ) + distance; bp.pt = p0 + ((numerator /denominator ) ∗ (p1 − p0 )); bp.b = (bp.pt ≠ ) ? true : false; return bp;

}

686. Path argument. [LDF 2003.06.03.] Defined in paths.web, because Path is an incomplete type in this file.

Log

[LDF 2003.06.03.] Added this function.

⟨ Declare Plane functions 663 ⟩ +≡ bool point intersection point (const Path &p) const;

687. Intersection of two Planes. [LDF 2002.10.29.] TO DO: Look up and explain!

Log

[LDF 2003.06.04.] Changed to const.

⟨ Declare Plane functions 663 ⟩ +≡ Line intersection line(const Plane &pl ) const;

190  INTERSECTION OF TWO PLANES  3DLDF-1.1.5.1 §688

688. ⟨ Define Plane functions 664 ⟩ +≡

Line Plane ::intersection line(const Plane &pl ) const {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

Point pl normal (pl .normal ); Point direction vector = normal .cross product (pl normal ); /∗ [LDF 2002.10.29.] Needed?? ∗/ if ( ) direction vector .show ( ); if (direction vector ≡ origin) {

cerr ≪ ␣ ≪ ␣ ␣ ; if (distance ≡ pl .distance) {

/∗ Ellipse ::intersection points (Ellipse &) calls this function to find out whether two Planes are coincident, so sometimes we don’t want to see these messages. I may decide to add an argument bool silent to this function. ?? Add bool silent ?? ∗/

    cerr ≪  ␣   ␣  ≪  ␣    ␣     ␣      ␣  ␣        ␣  ≪

␣ ␣ ␣ ≪ flush; return ;

}

else { cerr ≪ ␣ ␣ ␣ ≪ ␣ ≪ flush; return ;

} } /∗ Outer if . ∗/ if ( ) cout ≪ ␣ ␣ ␣ ≪ flush;

/∗ At least one of the x, y, or z components of direction vector must be non-zero, otherwise, this

function would have exited by now. ∗/ real x, y, z; real d = distance; real e = pl .distance; real nx = normal .get x ( ); real ny = normal .get y ( ); real nz = normal .get z ( ); real mx = pl .normal .get x ( ); real my = pl .normal .get y ( ); real mz = pl .normal .get z ( ); real vx = direction vector .get x ( ); real vy = direction vector .get y ( ); real vz = direction vector .get z ( ); if (direction vector .get x ( ) ≠ 0) {

x = 0;

y = −1 ∗ ((d ∗ mz − e ∗ nz )/vx );

z = (d ∗ my − e ∗ ny )/vx ; } else if (direction vector .get y ( ) ≠ 0) {

x = (d ∗ mz − e ∗ nz )/vy ;

y = 0;

z = −1 ∗ ((d ∗ mx − e ∗ nx )/vy ); } else {

x = −1 ∗ ((d ∗ my − e ∗ ny )/vz );

§688  3DLDF-1.1.5.1  INTERSECTION OF TWO PLANES 191

y = (d ∗ mx − e ∗ nx )/vz ;

z = 0; } Point point on line(x, y, z); if ( ) {

point on line.show ( );

direction vector .show ( );

getchar ( ); } if ( ) {

cout ≪ ␣ ;

getchar ( ); } return Line(point on line, direction vector );

}

689. Show.

Log

[LDF 2003.06.06.] Minor change to the conditional that handles text . [LDF 2003.06.06.] Made show ( ) const.

⟨ Declare Plane functions 663 ⟩ +≡ void show (string text = ) const;

690. ⟨ Define Plane functions 664 ⟩ +≡

void Plane ::show (string text ) const {

if (text ≡ ) text = ; cout ≪ text ≪ endl ; if (∗this ≡ ) {

cout ≪ ␣ ␣ ≪ endl ≪ endl ≪ flush; return;

} normal .show ( ); point .show ( ); cout ≪ ␣ ␣ ≪ distance ≪ endl ≪ endl ≪ flush;

}

691. Global constants for Plane. ⟨ Plane global constants 691 ⟩ ≡

extern const Plane  (  ,  );

This code is used in section 694.

692. ⟨ Declarations for the header file 21 ⟩ +≡

extern const Plane ;

693. Putting Plane together.

192  PUTTING PLANE TOGETHER  3DLDF-1.1.5.1 §694

694. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define struct Plane 661 ⟩ ⟨ Plane global constants 691 ⟩ ⟨ Define Plane functions 664 ⟩ ⟨ Define Point functions 330 ⟩

§695  3DLDF-1.1.5.1  PUTTING PLANE TOGETHER 193

695. This is what’s written to planes.h. ⟨ 695 ⟩ ≡

⟨ Define struct Plane 661 ⟩

⟨ Declarations for the header file 21 ⟩

696. Path (paths.web).

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

format Path Shape

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

697. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include

698. Path class definition.

Log

[LDF 2002.09.18.] Added projective extremes . It contains the minimum and maximum values for x, y, and z of the Points in points . It’s used in Picture ::output ( ) for surface hiding.

[LDF 2002.4.8.] Added static variables for help lines and curves: help color , help dash pattern, do help lines . The variables for help lines (or curves) are part of Path’s interface and can be set anywhere by anyone.

⟨ Define class Path 698 ⟩ ≡ class Path : protected Shape { protected: bool line switch;

bool cycle switch; bool on free store; bool do output ; /∗ LDF 2002.09.18. Added. ∗/ signed short fill draw value; /∗ Variables for drawing and filling. ∗/ const Color ∗draw color ; const Color ∗fill color ; string dashed ;

194 PATH CLASS DEFINITION 3DLDF-1.1.5.1 §698

string pen;

bool arrow ; /∗ LDF 2003.01.15. Added. Needed for drawarrow ( ). ∗/ valarray⟨real⟩ projective extremes ; /∗ LDF 2002.09.18. Added. ∗/ vector⟨Point ∗⟩ points ; vector⟨string⟩ connectors ;

public: static const Color ∗help color ; static string help dash pattern; static bool do help lines ; ⟨ Declare Path functions 700 ⟩

};

This code is used in sections 980 and 981.

699. Static member variable definitions. ⟨ Define static class Path data members 699 ⟩ ≡

const Color ∗Path ::help color = &Colors ::red ;

string Path ::help dash pattern = ;

bool Path ::do help lines = true;

This code is used in section 980.

700. Assignment.

Log

[LDF 2002.10.23.] Now all of the data members of class Path are assigned to except for on free store. This has become necessary because of changes in Solid ::output ( ), where temporary Paths have to be created in order to sort them.

[LDF 2002.12.18.] Moved here. With the DEC compiler under Compaq Tru64 on the DEC Alpha computer, it worked to have this following the constructors. With the GNU C^{++} compiler (GCC) under GNU/Linux on the Intel i686 computer, it didn’t: The copy constructor used the default assignment operator instead of this function, presumably because this function wasn’t known at the time the copy constructor was compiled, although it had been declared previously! URGENT: Move assignment operators for the other classes before the constructors!

[LDF 2003.04.09.] ?? BUG FIX: Now resizing projective extremes , if after setting it to p.projective extremes , projective extremes .size( ) ≡ 0. This prevents a Memory Fault error at run-time. I don’t know why it should be necessary, though, since all of the constructors of Path and its derived classes resize projective extremes ; at least, I thought they did.

⟨ Declare Path functions 700 ⟩ ≡

virtual Path &operator=(const Path &p);

See also sections 704, 707, 709, 712, 714, 717, 719, 721, 726, 728, 730, 732, 735, 738, 740, 743, 745, 747, 749, 751, 756, 762, 764, 766, 768, 771, 773, 776, 778, 781, 783, 785, 790, 792, 794, 797, 799, 801, 805, 810, 812, 818, 820, 827, 829, 836, 838, 844, 846, 849, 851, 855, 857, 863, 866, 868, 872, 874, 877, 879, 882, 884, 888, 889, 891, 893, 895, 897, 899, 909, 911, 914, 916, 918, 920, 921, 922, 923, 925, 932, 934, 936, 938, 940, 946, 952, 955, 959, 961, 964, and 976.

This code is used in section 698.

701. ⟨ Define Path functions 701 ⟩ ≡

Path &Path ::operator=(const Path &p){

if (this ≡ &p) /∗ Make sure it’s not self-assignment. ∗/

return ∗this ; ⟨ Discard points and connectors 703 ⟩ line switch = p.line switch; cycle switch = p.cycle switch; do output = p.do output ; fill draw value = p.fill draw value; draw color = p.draw color ; /∗ [LDF 2002.10.23.] draw color and fill color point to the same

Color as p.draw color and p.fill color . No memory allocation is performed. ∗/ fill color = p.fill color ; dashed = p.dashed ; pen = p.pen; projective extremes = p.projective extremes ; /∗ LDF 2002.09.18. Added this line. ∗/ if (projective extremes .size( ) ≡ 0) /∗ LDF 2003.04.09. Added this conditional. ∗/

projective extremes .resize(6, 0); for (vector⟨Point ∗⟩::const iterator p iter = p.points .begin( ); p iter ≠ p.points .end ( ); p iter^{++})

points .push back ( create new < Point > (∗p iter ) ) ; for (vector⟨string⟩::const iterator c iter = p.connectors .begin( ); c iter ≠ p.connectors .end ( );

c iter^{++}) { connectors .push back (∗c iter );

} return ∗this ; }

See also sections 705, 708, 710, 713, 715, 718, 720, 722, 727, 729, 731, 733, 736, 739, 741, 744, 746, 748, 750, 752, 757, 763, 765, 767, 769, 772, 774, 777, 779, 782, 784, 786, 791, 793, 795, 798, 800, 802, 806, 807, 808, 809, 811, 813, 814, 819, 821, 828, 830, 837, 839, 845, 847, 850, 852, 856, 858, 864, 867, 869, 873, 875, 878, 880, 883, 885, 886, 887, 890, 892, 894, 896, 898, 900, 901, 902, 903, 904, 905, 906, 910, 912, 915, 917, 919, 924, 926, 927, 928, 929, 930, 933, 935, 937, 941, 942, 943, 944, 947, 953, 956, 957, 958, 960, 962, 965, and 977.

This code is used in section 980.

702. Constructors and setting functions. Each constructor taking an argument has a corresponding function for setting an already existing Path.

Log

[LDF 2003.04.06.] BUG FIX: Now setting dashed = , pen = , and arrow = false in all constructors and setting functions. This fixed a problem I was having with Icosahedron: One of the Reg Polygons was drawn with an arrow.

703. Discard points and connectors. This is useful in the setting functions. ⟨ Discard points and connectors 703 ⟩ ≡

if (points .size( ) > 0) {

for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); ^{++}iter ) {

delete ∗iter ; } points .clear ( );

} if (connectors .size( ) > 0) connectors .clear ( );

This code is used in sections 701, 710, 715, 720, and 729.

704. Default constructor. No arguments. ⟨ Declare Path functions 700 ⟩ +≡

Path( );

705. ⟨ Define Path functions 701 ⟩ +≡

Path ::Path( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣      ␣        ␣  ≪ flush;

on free store = false; line switch = false; cycle switch = false; fill draw value = 0; dashed = ; /∗ LDF 2003.04.06. Added these three lines. ∗/ pen = ; arrow = false; draw color = 0; fill color = 0; do output = true; /∗ LDF 2002.09.18. Added this line. ∗/ projective extremes .resize(6, 0); /∗ LDF 2002.09.18. Added this line. ∗/ if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; return;

}

706. Lines. [LDF 2002.10.15.] Lines in this sense are Paths containing two Points and the connector “^{−}” They should not be confused with the struct Line, which is for vector operations (where the word “vector” is used in its mathematical sense).

707. Constructor. ⟨ Declare Path functions 700 ⟩ +≡

Path(const Point &p0 , const Point &p1 ); 708. ⟨ Define Path functions 701 ⟩ +≡

Path ::Path(const Point &p0 , const Point &p1 ){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣      ␣      ␣  ≪ flush;

on free store = false; line switch = true; cycle switch = false; do output = true; /∗ LDF 2002.09.18. Added this line. ∗/ projective extremes .resize(6, 0); /∗ LDF 2002.09.18. Added this line. ∗/ fill draw value = 0; draw color = 0; fill color = 0; dashed = ; /∗ LDF 2003.04.06. Added these three lines. ∗/ pen = ; arrow = false; points .push back ( create new < Point > (p0 ) ) ; points .push back ( create new <

Point > (p1 ) ) ; connectors .push back ( ); if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; return; }

709. Setting function. ⟨ Declare Path functions 700 ⟩ +≡

void set (const Point &p0 , const Point &p1 );

710. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set (const Point &p0 , const Point &p1 ){ line switch = true; cycle switch = false; do output = true; /∗ LDF 2002.09.18. Added this line. ∗/ fill draw value = 0; draw color = 0; fill color = 0; dashed = ; /∗ LDF 2003.04.06. Added these three lines. ∗/ pen = ; arrow = false; ⟨ Discard points and connectors 703 ⟩ projective extremes = 0; /∗ LDF 2002.09.18. Added this line. ∗/ points .push back ( create new < Point > (p0 ) ) ; points .push back ( create new < Point > (p1 ) ) ; connectors .push back ( ); line switch = true; }

711. Points and one type of connector. This constructor takes a variable number of Point ∗ arguments, but only allows one type of connector. The argument list must end with 0. If the order of the named arguments is reversed, the compiler can’t resolve certain calls to Path( ). It couldn’t resolve between Path(bool cycle, stringconnector …) and Path ( Point ∗first point ptr …). I don’t know why it should have had trouble, though, since pointers to Points are not bools.

[LDF 2002.4.6.] Probably it couldn’t distinguish between a pointer and an int on the one hand and a bool and an int on the other. I hope that bools are more efficiently implemented than as ints , though!

[LDF 2002.10.29.] ?? I don’t know why cweave needs instructions to put thin spaces after the “bool” in the declaration and definition below. Maybe it’s because of the “…”.

712. Constructor. ⟨ Declare Path functions 700 ⟩ +≡

Path(string connector , bool cycle …);

713. ⟨ Define Path functions 701 ⟩ +≡

Path ::Path(string connector , bool cycle …){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣      ␣           ␣      ␣  ≪ flush;

on free store = false; line switch = false; cycle switch = cycle; connectors .push back (connector ); do output = true; /∗ LDF 2002.09.18. Added this line. ∗/ projective extremes .resize(6, 0); /∗ LDF 2002.09.18. Added this line. ∗/ fill draw value = 0; draw color = 0; fill color = 0; dashed = ; /∗ LDF 2003.04.06. Added these three lines. ∗/ pen = ; arrow = false; va list ap; /∗ For the variable length argument list. ∗/ va start (ap, cycle); Point ∗arg ptr ; while ((arg ptr = va arg (ap, Point ∗)) ≠ static cast⟨Point ∗⟩(0))

points .push back ( create new < Point > (arg ptr ) ) ; va end (ap); if ( ) cout ≪ ␣ ␣ ␣ ␣ ≪ flush; return; }

714. Setting function. ⟨ Declare Path functions 700 ⟩ +≡

void set (string connector , bool cycle …); 715. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set (string connector , bool cycle …){ on free store = false; line switch = false; cycle switch = cycle; do output = true; /∗ LDF 2002.09.18. Added this line. ∗/ ⟨ Discard points and connectors 703 ⟩ fill draw value = 0; draw color = 0; fill color = 0; dashed = ; /∗ LDF 2003.04.06. Added these three lines. ∗/ pen = ; arrow = false; projective extremes = 0; /∗ LDF 2002.09.18. Added this line. ∗/ connectors .push back (connector ); va list ap; /∗ For the variable length argument list. ∗/ va start (ap, cycle); Point ∗arg ptr ; while ((arg ptr = va arg (ap, Point ∗)) ≠ static cast⟨Point ∗⟩(0))

points .push back ( create new < Point > (arg ptr ) ) ; va end (ap); }

716. Variable number of Points and connectors. These functions takes a variable number of alternating Point ∗ and connector arguments, starting with a Point ∗. The argument list must end with 0. We don’t need an argument for whether it’s a cycle or not, because if it is, it will have a connector at the end.

Log

[LDF 2002.10.29.] BUG FIX: No longer pushing first point ptr onto points . Copying it instead.

717. Constructor. ⟨ Declare Path functions 700 ⟩ +≡

Path ( Point ∗first point ptr …) ; 718. ⟨ Define Path functions 701 ⟩ +≡

Path ::Path ( Point ∗first point ptr …) { bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣      ␣        ␣  ≪ flush;

on free store = false; line switch = false; cycle switch = false; do output = true; /∗ LDF 2002.09.18. Added this line. ∗/ projective extremes .resize(6, 0); /∗ LDF 2002.09.18. Added this line. ∗/ fill draw value = 0; draw color = 0; fill color = 0; dashed = ; /∗ LDF 2003.04.06. Added these three lines. ∗/ pen = ; arrow = false; points .push back ( create new < Point > (first point ptr ) ) ; va list ap; /∗ For the variable length argument list. ∗/ va start (ap, first point ptr ); Point ∗point ptr ; char ∗connector ptr ; string connector string ; while ((connector ptr = va arg (ap, char ∗)) ≠ static cast⟨char ∗⟩(0)) {

connectors .push back ((connector string = connector ptr )); if ((point ptr = va arg (ap, Point ∗)) ≡ static cast⟨Point ∗⟩(0)) {

cycle switch = true; break;

} points .push back ( create new < Point > (point ptr ) ) ; } va end (ap); if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; }

719. Setting function. ⟨ Declare Path functions 700 ⟩ +≡

void set ( Point ∗first point ptr …) ; 720. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set ( Point ∗first point ptr …) { on free store = false; line switch = false; cycle switch = false; do output = true; /∗ LDF 2002.09.18. Added this line. ∗/ ⟨ Discard points and connectors 703 ⟩ projective extremes = 0; /∗ LDF 2002.09.18. Added this line. ∗/ fill draw value = 0; draw color = 0; fill color = 0; dashed = ; /∗ LDF 2003.04.06. Added these three lines. ∗/ pen = ; arrow = false; points .push back ( create new < Point > (first point ptr ) ) ; va list ap; /∗ For the variable length argument list. ∗/ va start (ap, first point ptr ); Point ∗point ptr ; char ∗connector ptr ; string connector string ; while ((connector ptr = va arg (ap, char ∗)) ≠ (char ∗) 0) {

connectors .push back ((connector string = connector ptr )); if ((point ptr = va arg (ap, Point ∗)) ≡ static cast⟨Point ∗⟩(0)) {

cycle switch = true; break;

} points .push back ( create new < Point > (point ptr ) ) ; } va end (ap); }

721. Copy constructor. [LDF 2003.04.06.] ?? !! BUG: Got a memory fault when I tried to use this function. Haven’t tested it yet. It worked to use the default constructor and then the assignment operator. Maybe it’s not kosher to use “∗this = p” in a copy constructor.

Log

[LDF 2002.10.15.] Rewrote this function. The old version caused a memory fault when I tried to use it. I’ve taken code from the default constructor and the assignment operator and put it here without bothering to see what was causing the problem. Probably the old version didn’t account for changes I’ve made in other places, perhaps in the class definition.

[LDF 2002.11.03.] Rewrote this function. Now just using the assignment operator.

⟨ Declare Path functions 700 ⟩ +≡ Path(const Path &p); 722. ⟨ Define Path functions 701 ⟩ +≡

Path ::Path(const Path &p)

{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣    ␣    ␣  ;

∗this = p;

on free store = false;

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; return;

}

723. Pseudo-constructor for dynamic allocation.

724. Pointer argument.

Log

[LDF 2002.10.29.] Added argument const Path ∗p. If p ≠ 0, the new Path is assigned to using the values from p.

[LDF 2003.12.30.] Replaced this version of Path ::create new path( ) with a specialization of template⟨class C⟩ C∗create new ( ).

[LDF 2003.12.30.] Changed the argument. It’s now a const Path ∗.

[LDF 2003.12.30.] Removed default argument “0”, because this caused a compiler error when using the DEC C^{++} compiler. Apparently, it suffices to declare a default argument in the template declaration.

⟨ Declare non-member template functions for Path 724 ⟩ ≡

Path ∗create new (const Path ∗p);

See also section 725. This code is used in sections 980 and 981.

725. Reference argument.

Log

[LDF 2002.10.29.] Added this function.

[LDF 2003.12.30.] Replaced this version of Path ::create new path( ) with a specialization of template⟨class C⟩ C∗create new ( ).

[LDF 2003.12.30.] Changed argument from Path to const Path &.

⟨ Declare non-member template functions for Path 724 ⟩ +≡ Path ∗create new (const Path &p);

726. Destructor.

Log

[LDF 2003.08.27.] Made virtual, because GCC with the “-Wall” option issued the following warning: “‘class Path’ has virtual functions but non-virtual destructor”.

⟨ Declare Path functions 700 ⟩ +≡ virtual ∼Path( );

§727  3DLDF-1.1.5.1  DESTRUCTOR 203

727. !! Make sure to delete anything else that I allocate dynamically! ⟨ Define Path functions 701 ⟩ +≡

Path ::∼Path( ) {

bool = false; /∗ true ∗/ if ( ) {

cout ≪ ␣ ≪ flush;

show ( );

getchar ( ); } for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++}) {

delete ∗iter ; } points .clear ( );

/∗ [LDF 2002.11.03.] This replaces a while loop in which pop back ( ) was used to empty points . ∗/ connectors .clear ( ); /∗ LDF 2002.11.03. Added. ∗/

/∗ LDF 2002.10.07. Added code for handling draw color and fill color . ∗/ if (draw color ≠ 0 ∧ draw color is on free store( ) ≡ true) {

if ( ) cout ≪ ␣ ;

delete draw color ;

draw color = 0; } else if ( ) {

cout ≪ ␣ ␣ ; } if (fill color ≠ 0 ∧ fill color is on free store( ) ≡ true) {

if ( ) cout ≪ ␣ ;

delete fill color ;

fill color = 0; } else if ( ) {

cout ≪ ␣ ␣ ; } if ( ) {

cout ≪ ␣ ≪ flush;

getchar ( ); }

}

728. Clear. LDF Undated. This function is needed because it’s a pure virtual function in Shape, and for getting rid of items in Picture ::clear ( ).

[LDF 2002.10.07.] clear ( ) is needed because it’s called on the Shapes that are stored in Pictures, and I don’t know of a way of overloading destructors. That is, in Picture ::clear ( ), the actual types of the Shapes are unknown, so I can’t call ∼Path( ), ∼Circle( ), or other destructors directly. But a named function such as clear ( ) can serve the same purpose.

Log

[LDF 2002.10.07.] Added code for deallocating the memory allocated for draw color and fill color , if any.

?? I tried calling ∼Path( ) inside Path : clear ( ), but I got a memory fault. Don’t know why. TO DO: Try to find out. However, this isn’t urgent.

204  CLEAR  3DLDF-1.1.5.1 §728

⟨ Declare Path functions 700 ⟩ +≡ virtual void clear ( );

729. ⟨ Define Path functions 701 ⟩ +≡

void Path ::clear ( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

⟨ Discard points and connectors 703 ⟩

/∗ LDF 2002.10.07. Added code for handling draw color and fill color . ∗/ if (draw color ≠ 0 ∧ draw color is on free store( ) ≡ true) {

if ( ) cout ≪ ␣ ;

delete draw color ;

draw color = 0; } else if ( ) {

cout ≪ ␣ ␣ ; } if (fill color ≠ 0 ∧ fill color is on free store( ) ≡ true) {

if ( ) cout ≪ ␣ ;

delete fill color ;

fill color = 0; } else if ( ) {

cout ≪ ␣ ␣ ; } if ( ) cout ≪ ␣ ;

}

730. Get copy.

Log

[LDF 2002.11.03.] Made virtual. Changed dynamic cast( ) to static cast( ). This may not work. [LDF 2003.01.29.] It seems to work. At least, I haven’t had any problems with it.

⟨ Declare Path functions 700 ⟩ +≡ virtual Shape ∗get copy ( ) const;

§731  3DLDF-1.1.5.1  GET COPY 205

731. ⟨ Define Path functions 701 ⟩ +≡

Shape ∗Path ::get copy ( ) const{ Path ∗p = create new < Path > (0); ∗p = ∗this ; return static cast⟨Shape ∗⟩(p); }

732. Set on free store.

Log

[LDF 2004.01.06.] Made non-inline.

⟨ Declare Path functions 700 ⟩ +≡ virtual bool set on free store(bool b = true);

733. ⟨ Define Path functions 701 ⟩ +≡

bool Path ::set on free store(bool b)

{ on free store = b; return b;

}

734. Setting drawing and filling data.

735. Set fill draw value. ⟨ Declare Path functions 700 ⟩ +≡

virtual void set fill draw value(const signed short s);

736. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set fill draw value(const signed short s)

{ fill draw value = s; return;

}

737. Set draw color.

738. Color version. ⟨ Declare Path functions 700 ⟩ +≡

virtual void set draw color (const Color &c);

739. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set draw color (const Color &c)

{ draw color = &c; return;

}

206 COLOR POINTER VERSION 3DLDF-1.1.5.1 §740

740. Color pointer version. ⟨ Declare Path functions 700 ⟩ +≡

virtual void set draw color (const Color ∗c);

741. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set draw color (const Color ∗c)

{

if (draw color ≠ 0 ∧ draw color is on free store( ) ≡ true) {

delete draw color ; } draw color = c; return;

}

742. Set fill color.

743. Color version. ⟨ Declare Path functions 700 ⟩ +≡

virtual void set fill color (const Color &c);

744. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set fill color (const Color &c)

{ fill color = &c; return;

}

745. Color pointer version. ⟨ Declare Path functions 700 ⟩ +≡

virtual void set fill color (const Color ∗c);

746. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set fill color (const Color ∗c)

{

if (fill color ≠ 0 ∧ fill color is on free store( ) ≡ true) {

delete fill color ; } fill color = c; return;

}

747. Set dash pattern. ⟨ Declare Path functions 700 ⟩ +≡

virtual void set dash pattern(const string s = );

§748  3DLDF-1.1.5.1  SET DASH PATTERN 207

748. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set dash pattern(const string s)

{ dashed = s; return;

}

749. Set pen. ⟨ Declare Path functions 700 ⟩ +≡

virtual void set pen(const string s = );

750. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set pen(const string s)

{ pen = s; return;

}

751. Set connectors. [LDF 2003.02.08.] TO DO: Overload with a version taking a vector⟨string⟩ as its argument. arguments.

Log

[LDF 2003.02.08.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡ virtual void set connectors (const string s = );

752. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set connectors (const string s)

{ connectors .clear ( ); connectors .push back (s);

}

753. Transformations. [LDF 2002.11.03.] All of the transformations return a Transform, so that the same Transform can be applied to multiple objects by chaining expressions.

754. Affine transformations.

755. Rotation.

756. Rotation around the main axes. ⟨ Declare Path functions 700 ⟩ +≡

virtual Transform rotate(const real x, const real y = 0, const real z = 0); 757. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::rotate(const real x, const real y, const real z) {

Transform t;

t.rotate(x, y, z);

return ∗this ∗= t; }

758. Rotatation around an arbitrary axis.

759. Transform version. Declared in transfor.web. Must be defined here, because Path is an incomplete type there.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

[LDF 2003.07.06.] Changed, so that is linear ( ) is used, instead of get line switch( ).

⟨ Define Transform functions 169 ⟩ +≡ Transform Transform ::rotate(const Path &p, const real angle) {

if (¬p.is linear ( )) {

cerr ≪  ␣  ␣                       ␣  ≪

        ␣  ␣   ␣       ␣␣         ␣  ;

return ; } Transform t; t.rotate(p.get point (0), p.get last point ( ), angle); return (∗this ∗= t);

§760  3DLDF-1.1.5.1  POINT VERSION 209

} 760. Point version. Declared in points.web. Must be defined here, because Path is an incomplete type there.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Define Point functions 330 ⟩ +≡ Transform Point ::rotate(const Path &p, const real angle) {

if (¬p.get line switch( )) {

cerr ≪  ␣  ␣                   ␣  ≪

          ␣  ␣   ␣ ␣      ␣␣         ␣  ;

return ; } Point pt0 = p.get point (0); Point pt1 = p.get point (1); return rotate(pt0 , pt1 , angle);

}

761. Path versions.

762. Point arguments.

Log

[LDF 2002.4.7.] Added default value for angle ≡ 180.

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Path functions 700 ⟩ +≡ virtual Transform rotate(const Point &p0 , const Point &p1 , const real angle = 180);

763. TO DO: Change this, so that I use operator∗=(Transform) here and in the other transformation functions. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::rotate(const Point &p0 , const Point &p1 , const real angle)

{ Transform t; t.rotate(p0 , p1 , angle); return (∗this ∗= t);

210 PATH ARGUMENTS 3DLDF-1.1.5.1 §764

} 764. Path arguments.

Log

[LDF 2002.4.7.] Added default value for angle ≡ 180. [LDF 2002.11.03.] Got rid of local Points p0 and p1 . [LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now

overloads rotate( ) with three real arguments.

[LDF 2003.07.13.] Changed, so that is linear ( ) is used instead of checking the return value of get line switch( ). Also, get last point ( ) passed as the second argument to rotate( ), instead of get point (1).

⟨ Declare Path functions 700 ⟩ +≡ Transform rotate(const Path &p, const real angle = 180);

765. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::rotate(const Path &p, const real angle) {

if (¬p.is linear ( )) {

cerr ≪  ␣  ␣                  ␣  ≪

        ␣  ␣   ␣ ␣      ␣␣         ␣  ;

return ; } return rotate(p.get point (0), p.get last point ( ), angle);

}

766. Scale. [LDF 2002.12.20.] TO DO: Make all of the transformations virtual! ⟨ Declare Path functions 700 ⟩ +≡

Transform scale(real x, real y = 1, real z = 1);

767. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::scale(real x, real y, real z) {

Transform t;

t.scale(x, y, z);

return (∗this ∗= t); }

768. Shear. ⟨ Declare Path functions 700 ⟩ +≡

Transform shear (real xy , real xz = 0, real yx = 0, real yz = 0, real zx = 0, real zy = 0);

§769  3DLDF-1.1.5.1  SHEAR 211

769. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::shear (real xy , real xz , real yx , real yz , real zx , real zy )

{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

Transform t;

t.shear (xy , xz , yx , yz , zx , zy );

if ( ) cout ≪ ␣ ; return (∗this ∗= t);

}

770. Shift.

771. real arguments. ⟨ Declare Path functions 700 ⟩ +≡

Transform shift (real x, real y = 0, real z = 0);

772. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::shift (real x, real y, real z)

{ Transform t; t.shift (x, y, z); return (∗this ∗= t);

}

773. Point argument. ⟨ Declare Path functions 700 ⟩ +≡

Transform shift (const Point &p);

774. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::shift (const Point &p)

{

return shift (p.get x ( ), p.get y ( ), p.get z ( )); }

775. Shift times.

[LDF 2003.01.19.] shift times ( ) returns void, because Path doesn’t have a Transform data member, and there’s no guarantee that all of the Points on points will have identical transforms .

[LDF 2003.01.19.] 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.

212 REAL ARGUMENTS 3DLDF-1.1.5.1 §776

776. real arguments.

Log

[LDF 2003.01.19.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡ virtual void shift times (real x, real y = 1, real z = 1);

777. ⟨ Define Path functions 701 ⟩ +≡

void Path ::shift times (real x, real y, real z)

{

for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); ^{++}iter )

(∗∗iter ).shift times (x, y, z); return;

}

778. Point argument.

Log

[LDF 2003.01.19.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡ virtual void shift times (const Point &p);

779. ⟨ Define Path functions 701 ⟩ +≡

void Path ::shift times (const Point &p)

{

return shift times (p.get x ( ), p.get y ( ), p.get z ( )); }

780. Applying transformations.

781. Multiplying by a Transform. ⟨ Declare Path functions 700 ⟩ +≡

virtual Transform operator∗=(const Transform &t);

782. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::operator∗=(const Transform &t)

{ for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++}) (∗∗iter ) ∗= t; return t;

}

783. Applying transform to points. ⟨ Declare Path functions 700 ⟩ +≡

virtual void apply transform( );

§784  3DLDF-1.1.5.1  APPLYING TRANSFORM TO POINTS 213

784. ⟨ Define Path functions 701 ⟩ +≡

void Path ::apply transform( )

{

for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++})

(∗∗iter ).apply transform( ); return;

}

785. Projection. [LDF 2002.12.20.] TO DO: Make this function virtual! ⟨ Declare Path functions 700 ⟩ +≡

bool project (const Focus &f, const unsigned short proj , real factor );

786. ⟨ Define Path functions 701 ⟩ +≡

bool Path ::project (const Focus &f, const unsigned short proj , real factor )

{

for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++}) {

if (¬(∗∗iter ).project (f, proj , factor )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ≪ flush;

return false; } } return true;

}

787. Functions for lines.

788. Alignment with an axis.

789. For lines.

790. No assignment. (Axis argument only). [LDF 2002.11.03.] This function returns the Transform that would transform Path such that it would come to lie on the major axis indicated by its argument (by default, the z-axis). It does not actually perform the transformation on the Path.

Log

[LDF 2002.11.03.] Changed char argument to const char.

⟨ Declare Path functions 700 ⟩ +≡ Transform align with axis (const char axis = ) const;

214  NO ASSIGNMENT  3DLDF-1.1.5.1 §791

791. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::align with axis (const char axis ) const {

Transform t; if (¬get line switch( )) {

cerr ≪  ␣  ␣  ≪

      ␣  ␣   ␣ ␣      ␣␣         ␣  ;

return ; } Point p0 (∗points [0]); Point p1 (∗points [1]); return t.align with axis (p0 , p1 , axis );

}

792. With assignment. [LDF 2002.11.03.] This function should never be called with the bool argument assign ≡ false. It won’t cause any harm, though, since it will just call the const version above.

Log

[LDF 2002.11.03.] Added this function. [LDF 2003.07.18.] Changed, so that is linear ( ) is used, rather than get line switch( ). Also, changed the

way Transform t is set. The latter change was necessary, because GCC 3.3 couldn’t compile this file the way it was before.

⟨ Declare Path functions 700 ⟩ +≡ Transform align with axis (bool assign, const char axis = );

793. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::align with axis (bool assign, const char axis ) {

if (¬is linear ( )) {

cerr ≪  ␣  ␣  ≪

      ␣  ␣   ␣       ␣␣         ␣  ;

return ; } Transform t; t.align with axis (get point (0), get last point ( ), axis ); if (assign ≡ false) {

cerr ≪  ␣  ␣  ≪

      ␣    ␣    ␣        ␣    ␣   ␣          ␣ ≪
      ␣  ␣          ␣     ␣     ␣   ␣      ␣  ≪  ≪

flush; return t;

} return (∗this ∗= t);

}

§794  3DLDF-1.1.5.1  FOR NON-LINES 215

794. For non-lines. (Point and axis arguments). [LDF 2002.11.03.] This function finds the transformation that would align the line segment \overrightarrow{p_{0}p_{1}} with the major axis indicated by the axis argument, and applies it to ∗this . p0 and p1 are not changed.

Log

[LDF 2002.11.03.] Changed Point arguments to const Point & and char argument to const char.

⟨ Declare Path functions 700 ⟩ +≡ Transform align with axis (const Point &p0 , const Point &p1 , const char axis );

795. ⟨ Define Path functions 701 ⟩ +≡

Transform Path ::align with axis (const Point &p0 , const Point &p1 , const char axis = )

{ Transform t; t.align with axis (p0 , p1 , axis ); return (∗this ∗= t);

}

796. Adding Points to Paths.

797. With assignment.

Log

[LDF 2002.4.6.] Added this function. Currently, it doesn’t return a Path. If it turns out that it would be useful to return ∗this , I can change it.

⟨ Declare Path functions 700 ⟩ +≡ void operator+=(const Point &pt );

798. ⟨ Define Path functions 701 ⟩ +≡

void Path ::operator+=(const Point &pt ){ points .push back ( create new < Point > (pt ) ) ; return; }

799. Without assignment.

Log

[LDF 2002.4.6.] Added this function.

216  WITHOUT ASSIGNMENT  3DLDF-1.1.5.1 §800

⟨ Declare Path functions 700 ⟩ +≡ Path operator+(const Point &pt ) const; 800. ⟨ Define Path functions 701 ⟩ +≡

Path Path ::operator+(const Point &pt ) const{ Path pa(∗this ); pa.points .push back ( create new

< Point > (pt ) ) ; return pa; }

801. Adding connectors to Paths.

Log

[LDF 2003.02.09.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡ void operator+=(const string s);

802. ⟨ Define Path functions 701 ⟩ +≡

void Path ::operator+=(const string s)

{ connectors .push back (s); return;

}

803. Concatenating Paths.

804. Versions using “&”.

805. With assignment. This function appends the Path argument pa to ∗this .

Log

[LDF 2002.4.6.] Added this function.

[LDF 2002.11.03.] Made non-inline.

⟨ Declare Path functions 700 ⟩ +≡ void operator&=(const Path &pa);

806. ⟨ Define Path functions 701 ⟩ +≡

void Path ::operator&=(const Path &pa){ if (is cycle( ) ∨ pa.is cycle( )) /∗ Return if either one of the Paths is a cycle. ∗/ {

cerr ≪  ␣  ␣  ≪

           ␣  ␣   ␣     ␣   ␣ ␣      ␣     ␣  ≪  ␣  ;

return; } string last connector ; 807. [LDF 2002.4.6.] If there isn’t an explicit connector for every pair of Points in this points , then we have to fill up connectors so that there are enough. Otherwise, the “&” will be at the wrong place. We don’t have to worry about the connectors for pa. ⟨ Define Path functions 701 ⟩ +≡

if (connectors .size( ) ≡ 0) last connector = ; else last connector = connectors .back ( ); while (connectors .size( ) < points .size( ) − 1) connectors .push back (last connector );

808. [LDF 2002.4.6.] If the Paths don’t touch, they are joined using “..” instead of “&”. This mimics the behavior of METAFONT.

Log

[LDF 2002.11.03.] Now using ∗(points .back ( )) instead of get point (points .size( ) − 1).

⟨ Define Path functions 701 ⟩ +≡

if (∗(points .back ( )) ≠ pa.get point (0)) {

cerr ≪  ␣  ␣  ≪  ␣     ␣  ≪

      ␣      ␣  ␣     ␣    ␣       ␣  ␣  ≪ flush;

connectors .push back ( ); } else connectors .push back ( ); for (vector⟨Point ∗⟩::const iterator iter = pa.points .begin( );

/∗ [LDF 2002.4.6.] Copy the Points in pa and put the copies onto points . ∗/ iter ≠ pa.points .end ( ); iter^{++}) points .push back ( create new < Point > (∗iter ) ) ;

809. [LDF 2002.4.6.] Put the connectors from pa onto the new Path. Since they’re strings, and not pointers, we don’t have to copy them. I tested this to make sure it’s true. I don’t know how strings are implemented, but they seem to be handled like string literals. ⟨ Define Path functions 701 ⟩ +≡

for (vector⟨string⟩::const iterator iter = pa.connectors .begin( ); iter ≠ pa.connectors .end ( ); iter^{++}) {

connectors .push back (∗iter ); } return; }

810. Without assignment.

Log

[LDF 2002.4.6.] Added this function. It behaves the way the operator “&” does in METAFONT.

⟨ Declare Path functions 700 ⟩ +≡ Path operator&(const Path &pa) const; 811. ⟨ Define Path functions 701 ⟩ +≡

Path Path ::operator&(const Path &pa) const

{ Path r(∗this ); r &= pa; return r;

}

812. Appending with a connector argument. [LDF 2002.4.7.] It would not have been possible to specify a connector if I’d defined this function as a binary operator, e.g., operator+=( ), so I’ve made it a named function. It can be useful when, for instance, rotation causes two Points, which should be identical, to differ by a small amount, like 1/10, 000 in one coordinate. This has actually happened, which is why I’ve added this function. METAPOST can recover gracefully by using “ ” instead of “&” to connect the paths, but it issues an error message and stops to wait for a response. Using this function can help to avoid such problems.

Log

[LDF 2002.4.7.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡ Path append (const Path &pa, string connector = , bool assign = true);

813. ⟨ Define Path functions 701 ⟩ +≡

Path Path ::append (const Path &pa, string connector , bool assign){ Path r(∗this );

string last connector ; /∗ [LDF 2002.4.6.] If there isn’t an explicit connector for every pair of Points in this points , then we have to fill up connectors so that there are enough. Otherwise, the “&” will be at the wrong place. We don’t have to worry about the connectors for pa. ∗/

if (r.connectors .size( ) ≡ 0) last connector = ;

else last connector = r.connectors .back ( );

while (r.connectors .size( ) < r.points .size( ) − 1) r.connectors .push back (last connector ); r.connectors .push back (connector );

/∗ [LDF 2002.4.6.] Copy the Points in pa and put the copies onto points . ∗/ for (vector⟨Point ∗⟩::const iterator iter = pa.points .begin( ); iter ≠ pa.points .end ( ); iter^{++})

r.points .push back ( create new < Point > (∗iter ) ) ;

814. Put the connectors from pa onto the new Path. Since they’re strings, and not pointers, we don’t have to copy them. I tested this to make sure it’s true. I don’t know how strings are implemented, but they seem to be handled like string literals. [LDF 2002.4.6.] ⟨ Define Path functions 701 ⟩ +≡

for (vector⟨string⟩::const iterator iter = pa.connectors .begin( ); iter ≠ pa.connectors .end ( ); iter^{++}) {

r.connectors .push back (∗iter ); } if (assign ≡ true) ∗this = r; return r; }

815. Drawing and filling.

816. Draw.

§817  3DLDF-1.1.5.1  PATH VERSIONS 219

817. Path versions.

818. Normal version.

Log

[LDF 2002.10.07.] Added code for handling draw color and fill color .

⟨ Declare Path functions 700 ⟩ +≡

virtual void draw (const Color &ddraw color = ∗Colors ::default color , const string ddashed = , const string ppen = , Picture &picture = current picture, bool aarrow = false) const;

819. ⟨ Define Path functions 701 ⟩ +≡

void Path ::draw (const Color &ddraw color , const string ddashed , const string ppen, Picture

&picture, bool aarrow ) const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (points .size( ) ≡ 0)

/∗ LDF 2002.09.27. Added this error handling code. If the Path is empty, don’t draw it. ∗/ {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush; return;

} Path ∗p = create new < Path > (∗this ); p fill draw value = ; p arrow = aarrow ; if ( )

cout ≪ ␣ ␣ ≪ ddraw color .get use name( ) ≪ endl ≪ flush; if (ddraw color .get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ddraw color ; p draw color = c; } else {

if ( ) cout ≪ ␣ ␣ ≪ ddraw color .get name( ) ≪ endl ≪ flush; p draw color = &ddraw color ;

} p fill color = Colors ::background color ; p dashed = ddashed ; p pen = ppen; picture += static cast⟨Shape ∗⟩(p);

/∗ LDF 2002.11.03. Changed dynamic cast( ) to static cast( ). ∗/ if ( ) cout ≪ ␣ ≪ flush; return; } 820. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. If I want to declare it inline, I must define it within the declaration of class Path. Otherwise, it causes a compiler error. I’ve decided to declare it non-inline, and hope that the compiler will inline it by itself. ⟨ Declare Path functions 700 ⟩ +≡

virtual void draw (Picture &picture, const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , bool aarrow = false) const;

821. ⟨ Define Path functions 701 ⟩ +≡

void Path ::draw (Picture &picture, const Color &ddraw color , string ddashed , string ppen, bool

aarrow ) const

{

draw (ddraw color , ddashed , ppen, picture, aarrow ); }

822. Point versions. Declared in points.web, but must be defined here, because Path is an incomplete type here.

[LDF 2002.11.03.] Unlike the Path versions of draw ( ), this function returns a Path. This can be useful, if you want to use the Path that it creates again for something else.

823. Normal version. ⟨ Define Point functions 330 ⟩ +≡

Path Point ::draw (const Point &p, const Color &ddraw color , string ddashed , string ppen, Picture

&picture, bool aarrow ) const

{ Path pa(∗this , p); pa.draw (ddraw color , ddashed , ppen, picture, aarrow ); return pa;

}

824. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. ⟨ Define Point functions 330 ⟩ +≡

Path Point ::draw (Picture &picture, const Point &p, const Color &ddraw color , string

ddashed , string ppen, bool aarrow )

{

return draw (p, ddraw color , ddashed , ppen, picture, aarrow ); }

825. Draw arrow.

826. Path versions.

§827  3DLDF-1.1.5.1  NORMAL VERSION 221

827. Normal version.

Log

[LDF 2003.01.15.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡

virtual void drawarrow (const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , Picture &picture = current picture) const;

828. ⟨ Define Path functions 701 ⟩ +≡

void Path ::drawarrow (const Color &ddraw color , string ddashed , string ppen, Picture &picture)

const

{

draw (ddraw color , ddashed , ppen, picture, true); }

829. Picture argument first.

Log

[LDF 2003.01.15.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡

virtual void drawarrow (Picture &picture, const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = ) const;

830. ⟨ Define Path functions 701 ⟩ +≡

void Path ::drawarrow (Picture &picture, const Color &ddraw color , string ddashed , string ppen)

const

{

draw (picture, ddraw color , ddashed , ppen, true); }

831. Point versions.

832. Normal version.

Log

[LDF 2003.01.15.] Added this function. [LDF 2003.06.03.] Made drawarrow ( ) const.

⟨ Define Point functions 330 ⟩ +≡

Path Point ::drawarrow (const Point &p, const Color &ddraw color , string ddashed , string

ppen, Picture &picture) const

{ Path pa(∗this , p); pa.drawarrow (ddraw color , ddashed , ppen, picture); return pa;

} 833. Picture argument first.

Log

[LDF 2003.01.15.] Added this function.

[LDF 2003.06.03.] Made drawarrow ( ) const.

⟨ Define Point functions 330 ⟩ +≡

Path Point ::drawarrow (Picture &picture, const Point &p, const Color &ddraw color , string

ddashed , string ppen) const

{

return drawarrow (p, ddraw color , ddashed , ppen, picture); }

834. Draw help.

Log

[LDF 2002.05.10.] Changed the way the default arguments are handled. The way it was didn’t work for both versions, i.e., the Path version and the Point version.

[LDF 2002.4.8.] Added this section. !! It would be nice to do something to make sure that the help lines and curves are not drawn over by filling commands. Maybe it will be possible to take care of this when I implement the hidden surface algorithm in output ( ). [LDF 2002.11.03.] I could have help lines outputted last, if I put them on a vector of their own.

[LDF 2003.07.13.] Made all versions of draw help( ) const.

835. Path versions. [LDF 2002.12.20.] ?? Could these functions be const?

836. Normal version. [LDF 2002.4.8.] Added this function. ⟨ Declare Path functions 700 ⟩ +≡

void draw help(const Color &ddraw color = ∗help color , string ddashed = help dash pattern, string ppen = , Picture &picture = current picture) const;

837. ⟨ Define Path functions 701 ⟩ +≡

void Path ::draw help(const Color &ddraw color , string ddashed , string ppen, Picture &picture)

const

{ if (do help lines ≡ false) return; draw (ddraw color , ddashed , ppen, picture);

}

838. Picture argument first. ⟨ Declare Path functions 700 ⟩ +≡

void draw help(Picture &picture, const Color &ddraw color = ∗help color , string ddashed = help dash pattern, string ppen = ) const; 839. ⟨ Define Path functions 701 ⟩ +≡

void Path ::draw help(Picture &picture, const Color &ddraw color , string ddashed , string ppen)

const

{

draw help(ddraw color , ddashed , ppen, picture); }

840. Point versions.

841. Normal version. [LDF 2002.4.8.] Added this function. Declared in points.web, but must be defined here, because Path is an incomplete type here. ⟨ Define Point functions 330 ⟩ +≡

Path Point ::draw help(const Point &pt , const Color &ddraw color , string ddashed , string

ppen, Picture &picture) const

{ Path pa(∗this , pt ); pa.draw help(ddraw color , ddashed , ppen, picture); return pa;

}

842. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument.

[LDF 2002.10.26.] Declared in points.web. Must be defined here, because Path is an incomplete type there. ⟨ Define Point functions 330 ⟩ +≡

Path Point ::draw help(Picture &picture, const Point &pt , const Color &ddraw color , string

ddashed , string ppen) const

{

return draw help(pt , ddraw color , ddashed , ppen, picture); }

843. Fill.

!! [LDF 2003.02.02.] Filling doesn’t use a pen!! Change everywhere!!.

844. Normal version.

Log

[LDF 2002.10.07.] Added code for handling and fill color .

⟨ Declare Path functions 700 ⟩ +≡

224  NORMAL VERSION  3DLDF-1.1.5.1 §845

void fill (const Color &ffill color = ∗Colors ::default color , Picture &picture = current picture) const; 845. ⟨ Define Path functions 701 ⟩ +≡

void Path ::fill (const Color &ffill color , Picture &picture) const{ bool = false;

/∗ true ∗/ if ( ) cout ≪ ␣ ≪ flush; if (points .size( ) ≡ 0)

/∗ LDF 2002.09.27. Added this error handling code. If the Path is empty, don’t fill it. ∗/ {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush; return;

} Path ∗p = create new < Path > (0); ∗p = ∗this ; p fill draw value = ; if ( )

cout ≪ ␣ ␣ ≪ ffill color .get use name( ) ≪ endl ≪ flush; if (ffill color .get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ffill color ; p fill color = c; } else {

if ( ) cout ≪ ␣ ␣ ≪ ffill color .get name( ) ≪ endl ≪ flush; p fill color = &ffill color ;

} p pen = ; p dashed = ; p draw color = Colors ::background color ; picture += static cast⟨Shape ∗⟩(p); if ( ) cout ≪ ␣ ≪ flush; return; }

846. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. ⟨ Declare Path functions 700 ⟩ +≡

void fill (Picture &picture, const Color &ffill color = ∗Colors ::default color ); 847. ⟨ Define Path functions 701 ⟩ +≡

void Path ::fill (Picture &picture, const Color &ffill color )

{

fill (ffill color , picture); }

848. Filldraw.

[LDF 2002.03.25] ([LDF 2002.11.03.] Revised the following text). At the present time, filldraw ( ) differs from the filldraw command in METAFONT and METAPOST: In the default case, the outline is drawn in the default color (currently black) and the Path is filled with the background color (currently white by default). This makes it possible to hide objects that are behind the Path by using the painter’s algorithm when rendering. If you want a Path to be filled with another color, you will have to use explicit arguments for ddraw color and ffill color . Either or both of these can be , which causes the default color (currently black) to be used. Of course, plain fill ( ) followed by plain draw ( ) will produce the same result.

Log

[LDF 2003.07.16.] Made both versions const.

849. Normal version.

Log

[LDF 2002.10.07.] Added code for handling draw color and fill color .

⟨ Declare Path functions 700 ⟩ +≡

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; 850. ⟨ Define Path functions 701 ⟩ +≡

void Path ::filldraw (const Color &ddraw color , const Color &ffill color , string ddashed , string

ppen, Picture &picture) const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (points .size( ) ≡ 0)

/∗ LDF 2002.09.27. Added this error handling code. If the Path is empty, don’t filldraw it. ∗/ {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush; return;

} Path ∗p = create new < Path > (0); ∗p = ∗this ; p fill draw value = ; if ( )

cout ≪ ␣ ␣ ≪ ddraw color .get use name( ) ≪ endl ≪ flush; if ( )

cout ≪ ␣ ␣ ≪ ffill color .get use name( ) ≪ endl ≪ flush; if (ddraw color .get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ddraw color ; p draw color = c; } else {

if ( ) cout ≪ ␣ ␣ ≪ ddraw color .get name( ) ≪ endl ≪ flush; p draw color = &ddraw color ;

} if (ffill color .get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ffill color ; p fill color = c; } else {

if ( ) cout ≪ ␣ ␣ ≪ ffill color .get name( ) ≪ endl ≪ flush; p fill color = &ffill color ;

} p dashed = ddashed ; p pen = ppen; picture += static cast⟨Shape ∗⟩(p); if ( ) cout ≪ ␣ ≪ flush; return; }

851. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. ⟨ Declare Path functions 700 ⟩ +≡

void filldraw (Picture &picture, const Color &ddraw color = ∗Colors ::default color , const Color &ffill color = ∗Colors ::background color , string ddashed = , string ppen = ) const; 852. ⟨ Define Path functions 701 ⟩ +≡

void Path ::filldraw (Picture &picture, const Color &ddraw color , const Color &ffill color , string

ddashed , string ppen) const

{

filldraw (ddraw color , ffill color , ddashed , ppen, picture); }

853. Undraw.

854. Path versions.

855. Normal version. ⟨ Declare Path functions 700 ⟩ +≡

void undraw (string ddashed = , string ppen = , Picture &picture = current picture);

856. ⟨ Define Path functions 701 ⟩ +≡

void Path ::undraw (string ddashed , string ppen, Picture &picture){

if (points .size( ) ≡ 0)

/∗ LDF 2002.09.27. Added this error handling code. If the Path is empty, don’t undraw it. ∗/ {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush;

return; } Path ∗p = create new < Path > (this ); p fill draw value = ; p draw color = 0; p fill color = 0; p dashed = ddashed ; p pen = ppen; picture += static cast⟨Shape ∗⟩(p); }

857. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. ⟨ Declare Path functions 700 ⟩ +≡

void undraw (Picture &picture, string ddashed = , string ppen = );

858. ⟨ Define Path functions 701 ⟩ +≡

void Path ::undraw (Picture &picture, string ddashed , string ppen)

{

undraw (ddashed , ppen, picture); }

859. Point versions.

860. Normal version. This function is declared in points.web, but must be defined here, because Path is an incomplete type here.

Log

[LDF 2002.4.8.] Added this function. [LDF 2002.11.03.] Changed this function, so that it returns the Path pa, instead of void.

⟨ Define Point functions 330 ⟩ +≡ Path Point ::undraw (const Point &pt , string ddashed , string ppen, Picture &picture) {

Path pa(∗this , pt );

pa.undraw (ddashed , ppen, picture);

return pa; }

861. Picture argument first.

Log

[LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument.

⟨ Define Point functions 330 ⟩ +≡ Path Point ::undraw (Picture &picture, const Point &pt , string ddashed , string ppen) {

return undraw (pt , ddashed , ppen, picture); }

862. Unfill.

863. Normal version. ⟨ Declare Path functions 700 ⟩ +≡

void unfill (Picture &picture = current picture); 864. ⟨ Define Path functions 701 ⟩ +≡

void Path ::unfill (Picture &picture){

if (points .size( ) ≡ 0)

/∗ LDF 2002.09.27. Added this error handling code. If the Path is empty, don’t unfill it. ∗/ {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush; return;

} Path ∗p = create new < Path > (this ); p fill draw value = ; p draw color = 0; p fill color = 0; p dashed = ; p pen = ; picture += static cast⟨Shape ∗⟩(p); }

865. Unfilldraw.

866. Normal version. ⟨ Declare Path functions 700 ⟩ +≡

void unfilldraw (const Color &ddraw color = ∗Colors ::background color , string ddashed = , string ppen = , Picture &picture = current picture); 867. ⟨ Define Path functions 701 ⟩ +≡

void Path ::unfilldraw (const Color &ddraw color , string ddashed , string ppen, Picture &picture){

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (points .size( ) ≡ 0)

/∗ LDF 2002.09.27. Added this error handling code. If the Path is empty, don’t unfilldraw it. ∗/ {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush; return;

} Path ∗p = create new < Path > (this ); p fill draw value = ;

/∗ LDF 2002.10.07. Added code for handling draw color and fill color . Will get rid of this if I do

actually change it to make it act more like unfilldraw in METAPOST. ∗/ if (ddraw color .get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ddraw color ; p draw color = c; } else {

if ( ) cout ≪ ␣ ␣ ≪ ddraw color .get name( ) ≪ endl ≪ flush; p draw color = &ddraw color ;

} p fill color = 0; p dashed = ddashed ; p pen = ppen; picture += static cast⟨Shape ∗⟩(p); if ( ) cout ≪ ␣ ≪ flush; return; }

868. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. ⟨ Declare Path functions 700 ⟩ +≡

void unfilldraw (Picture &picture, const Color &ddraw color = ∗Colors ::background color , string ddashed = , string ppen = ); 869. ⟨ Define Path functions 701 ⟩ +≡

void Path ::unfilldraw (Picture &picture, const Color &ddraw color , string ddashed , string ppen) {

unfilldraw (ddraw color , ddashed , ppen, picture); }

870. Labelling.

871. Label.

Log

[LDF 2002.03.25.] Added argument dot and changed definition of dotlabel ( ) below so that it just calls label ( ).

[LDF 2003.04.01.] BUG FIX: Got rid of the first argument unsigned int i, and made the third argument short text short the first argument. Formerly, the Points in Paths were always numbered starting from 0, because the argument text short was passed to Point ::label ( ), not i. Also changed the following versions of label ( ) and dotlabel ( ), that call this function.

872. Normal version.

Log

[LDF 2003.05.06.] Changed the conditional, where text short is compared with , , etc. I had to change it, because I’ve added , etc. Now, the conditional tests for ≤text short ≤ . Of course, this makes an assumption about the values that are used to signal that coordinate values should be used for the label, but I think it’s worth it, to avoid testing text short against each value individually.

[LDF 2003.07.09.] Made position string and dot arguments const.

⟨ Declare Path functions 700 ⟩ +≡

void label (short text short = 0, const string position string = , const bool dot = false, Picture &picture = current picture) const; 873. ⟨ Define Path functions 701 ⟩ +≡

void Path ::label (short text short , const string position string , const bool dot , Picture &picture)

const

{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

if (Label :: ≡ false) return; if (points .size( ) ≡ 0)

/∗ LDF 2002.09.27. Added this error handling code. If the Path is empty, don’t label it. ∗/ {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush; return;

} for (vector⟨Point ∗⟩::const iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++}) {

(∗∗iter ).label (text short , position string , dot , picture);

if (text short ≤ Point :: ∧ text short ≥ Point :: )

/∗ LDF 2003.05.06. Changed this conditional. ∗/ ; /∗ Do nothing. ∗/

else ^{++}text short ; } if ( ) cout ≪ ␣ ≪ ≪ flush;

}

874. Picture argument first. [LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument.

[LDF 2003.07.09.] Made position string and dot arguments const.

Log

⟨ Declare Path functions 700 ⟩ +≡

void label (Picture &picture, short text short = 0, const string position string = , const bool dot = false) const;

875. ⟨ Define Path functions 701 ⟩ +≡

void Path ::label (Picture &picture, short text short , const string position string , const bool dot )

const

{

label (text short , position string , dot , picture); }

876. Dotlabel.

877. Normal version.

Log

[LDF 2003.07.09.] Made text short and position string arguments const.

⟨ Declare Path functions 700 ⟩ +≡

void dotlabel (const short text short = 0, const string position string = , Picture &picture = current picture) const;

878. ⟨ Define Path functions 701 ⟩ +≡

void Path ::dotlabel (const short text short , const string position string , Picture &picture) const {

label (text short , position string , true, picture); }

879. Picture argument first.

Log

[LDF 2002.09.17.] Added this function. It’s convenient for when I want to pass a Picture argument. [LDF 2003.07.09.] Made text short and position string arguments const.

⟨ Declare Path functions 700 ⟩ +≡

void dotlabel (Picture &picture, const short text short = 0, const string position string = ) const;

880. ⟨ Define Path functions 701 ⟩ +≡

void Path ::dotlabel (Picture &picture, const short text short , const string position string ) const {

dotlabel (text short , position string , picture); }

881. Outputting.

882. Extract. This is needed for outputting a Picture.

[LDF 2003.01.31.] ?? Do I need to call Point ::project ( ) on the Points here and in Path ::project ( )?

Log

[LDF 2002.09.17.] Added const Focus &f argument and error handling code. Now, if any of the Points on vector⟨Point ∗⟩ points cannot be projected onto the projection plane using the Focus f, the Path is not put onto the vector⟨Shape ∗⟩ Picture ::elements , and consequently never reaches Picture ::output ( ) and Path ::output ( ).

[LDF 2003.05.09.] Rewrote this function. It now calls Point ::extract ( ) instead of calling apply transform( ) and project ( ) on the Points directly. This makes much more sense, since any changes to Point ::extract ( ) would otherwise not have been applied to Points on Paths.

⟨ Declare Path functions 700 ⟩ +≡ vector⟨Shape ∗⟩ extract (const Focus &f, const unsigned short proj , real factor );

234  EXTRACT  3DLDF-1.1.5.1 §883

883. ⟨ Define Path functions 701 ⟩ +≡

vector⟨Shape ∗⟩ Path ::extract (const Focus &f, const unsigned short proj , real factor )

{ bool = false; /∗ true ∗/ vector⟨Shape ∗⟩ v; int i = 0; for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++}) {

if ( ) cout ≪ ␣ ≪ i^{++} ≪ ≪ endl ;

v = (∗∗iter ).extract (f, proj , factor );

if ( ) cout ≪ endl ;

if (v.size( ) ≡ 0) /∗ Point ::extract ( ) failed. LDF 2003.05.09. ∗/

return v; } vector⟨Shape ∗⟩ r; r.push back (this ); return r;

}

884. Set extremes. [LDF 2002.09.18.] set extremes ( ) doesn’t check that the projective coordinates in all of the Points on the Path are valid. This is done already in project ( ) and extract ( ), so I don’t think it’s necessary to repeat it here, since extract ( ) (which invokes project ( )), is called before set extremes ( ) in Picture ::output ( ). The latter is the only place where set extremes ( ) is invoked.

[LDF 2002.09.17.] Added this function. ⟨ Declare Path functions 700 ⟩ +≡

virtual bool set extremes ( );

885. ⟨ Define Path functions 701 ⟩ +≡

bool Path ::set extremes ( ){ bool = false; /∗ true ∗/

if ( )

cout ≪ ␣ ≪ endl ≪ flush; /∗ If there are no Points on the Path, set all the elements of projective extremes to and return false. ∗/

if (points .size( ) ≤ 0) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪

␣ ␣ ␣ ␣ ␣ ≪ flush;

projective extremes = ;

return false; } 886. [LDF 2002.09.18.] Added this routine. Set the minimum values to and the maximum values to − . This way, any valid perspective coordinates will replace them on the first iteration of the for loop.

[LDF 2002.09.18.] I had some difficulty debugging this because instead of using − , I defined and used = numeric limits⟨real⟩::min( ). However, this isn’t the negative real with the largest magnitude, but the smallest positive real. ⟨ Define Path functions 701 ⟩ +≡

projective extremes [0] = ; /∗ Minima. ∗/ projective extremes [2] = ; projective extremes [4] = ; projective extremes [1] = − ; /∗ Maxima. ∗/ projective extremes [3] = − ; projective extremes [5] = − ; for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); ^{++}iter ) {

if ( ) { cout ≪ ␣ ␣ ␣ ≪ projective extremes [0] ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ projective extremes [1] ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ (∗∗iter ).get x ( ) ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ (∗∗iter ).get x ( , false, false) ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ projective extremes [2] ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ projective extremes [3] ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ (∗∗iter ).get y ( ) ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ (∗∗iter ).get y ( , false, false) ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ projective extremes [4] ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ projective extremes [5] ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ (∗∗iter ).get z ( ) ≪ endl ; cout ≪ ␣ ␣ ␣ ≪ (∗∗iter ).get z ( , false, false) ≪ endl ;

} projective extremes [0] = min(projective extremes [0], (∗∗iter ).get x ( , false, false)); /∗ Min x ∗/ projective extremes [2] = min(projective extremes [2], (∗∗iter ).get y ( , false, false)); /∗ Min y ∗/ projective extremes [4] = min(projective extremes [4], (∗∗iter ).get z ( , false, false)); /∗ Min z ∗/ projective extremes [1] = max (projective extremes [1], (∗∗iter ).get x ( , false, false)); /∗ Max x ∗/ projective extremes [3] = max (projective extremes [3], (∗∗iter ).get y ( , false, false)); /∗ Max y ∗/ projective extremes [5] = max (projective extremes [5], (∗∗iter ).get z ( , false, false)); /∗ Max z ∗/

} if ( ) {

for (int i = 0; i < 6; i^{++})

236  SET EXTREMES  3DLDF-1.1.5.1 §887

cout ≪ ≪ i ≪ ␣ ␣ ≪ projective extremes [i] ≪ endl ≪ flush; } 887. [LDF 2002.09.18.] Added this error handling code. There is a remote chance that a valid Point could have a coordinate ≡ or ± , however, it is virtually impossible that it would be projectable. If it’s the x or y-coordinate, it would probably lie outside the limits defined for the invocation of Picture ::output ( ), and if it was the z, it would either be behind the Focus or so far away as to be practically invisible. I believe that this is the case, even though the z-coordinates are made smaller by applying the equation z_{p} = z/(z + p). ⟨ Define Path functions 701 ⟩ +≡

for (int i = 0; i < 6; i += 2) { if (projective extremes [i] ≡ /∗ Minima ∗/ ∨ projective extremes [i + 1] ≡ − ) /∗ Maxima ∗/ {

if ( ) { cout ≪ ␣ ␣ ≪ i ≪ endl ≪ flush; cout ≪ ≪ i ≪ ␣ ␣ ≪ projective extremes [i] ≪ endl ≪ flush;

}

      cerr ≪  ␣  ␣  ≪  ␣   ␣      ␣      ␣   ␣  ␣   ␣
          ␣ ≪  ␣    ␣   ␣   ␣           ␣   ␣         ␣  ≪ flush;

projective extremes = ;

return false;

break; }

}

if ( ) cout ≪ ␣ ≪ endl ≪ flush; return true; }

888. Get extremes. [LDF 2002.09.18.] Added this function. Any code that calls get extremes ( ) must ensure that project ( ) has been invoked first. ⟨ Declare Path functions 700 ⟩ +≡

virtual inline const valarray⟨real⟩ get extremes ( ) const

{

return projective extremes ; }

889. Get minimum z. [LDF 2003.05.16.] Added this function. ⟨ Declare Path functions 700 ⟩ +≡

§890  3DLDF-1.1.5.1  GET MINIMUM Z 237

virtual real get minimum z ( ) const; 890. ⟨ Define Path functions 701 ⟩ +≡

real Path ::get minimum z ( ) const {

bool = false; /∗ true ∗/

if ( ) { cout ≪ ␣ ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ projective extremes [4] ≪ endl ≪ flush; cout ≪ ␣ ≪ endl ≪ flush;

}

return projective extremes [4]; }

891. Get maximum z. [LDF 2002.09.17.] Added this function. ⟨ Declare Path functions 700 ⟩ +≡

virtual real get maximum z ( ) const;

892. ⟨ Define Path functions 701 ⟩ +≡

real Path ::get maximum z ( ) const {

bool = false; /∗ true ∗/

if ( ) { cout ≪ ␣ ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ projective extremes [5] ≪ endl ≪ flush; cout ≪ ␣ ≪ endl ≪ flush;

}

return projective extremes [5]; }

893. Get mean z. [LDF 2003.05.16.] Added this function. ⟨ Declare Path functions 700 ⟩ +≡

virtual real get mean z ( ) const;

894. ⟨ Define Path functions 701 ⟩ +≡

real Path ::get mean z ( ) const

{

return ((projective extremes [4] + projective extremes [5])/2); }

895. Suppress output. [LDF 2002.09.18.] Added this function. It’s needed because trying to erase a Shape ∗ from elements in Picture ::output ( ) causes a memory fault. ⟨ Declare Path functions 700 ⟩ +≡

238  SUPPRESS OUTPUT  3DLDF-1.1.5.1 §896

virtual void suppress output ( ); 896. ⟨ Define Path functions 701 ⟩ +≡

void Path ::suppress output ( )

{

do output = false; }

897. Unsuppress output. [LDF 2002.09.18.] Added this function. It’s needed because trying to erase a Shape ∗ from elements in Picture ::output ( ) causes a memory fault. ⟨ Declare Path functions 700 ⟩ +≡

virtual void unsuppress output ( );

898. ⟨ Define Path functions 701 ⟩ +≡

void Path ::unsuppress output ( )

{

do output = true; }

899. Output. [LDF 2002.09.17.] Removed error checking code to extract ( ). Now output ( ) assumes that all of the Points in points can be projected using focus . If they can’t be, extract ( ) will already have ensured that the Path is not on vector⟨Shape ∗⟩ elements in the Picture.

Log

[LDF 2003.01.15.] Added code for writing “drawarrow” to out stream, if arrow ≡ true. This is for the drawarrow ( ) functions for Path and Point that I’ve added today.

⟨ Declare Path functions 700 ⟩ +≡ virtual void output ( );

900. ⟨ Define Path functions 701 ⟩ +≡

void Path ::output ( ){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

if (do output ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ flush; return;

§901  3DLDF-1.1.5.1  OUTPUT 239

} 901. [LDF 2002.09.27.] Added this error handling code. If the Path is empty, don’t output it. This code should never be reached, because the case of a Path containing no Points should be caught in Path ::draw ( ) and the other drawing and filling commands. If it should reach set extremes ( ) and Picture ::output ( ), which also shouldn’t be possible, they would catch it, too. ⟨ Define Path functions 701 ⟩ +≡

if (points .size( ) ≡ 0) {

cerr ≪  ␣     ␣       ␣ ␣  ␣  ≪

        ␣    ␣      ␣      ␣  ␣  ≪  ␣ ␣   ␣  ␣     ␣  ␣        ␣␣ ≪

␣ ␣ ␣ ≪ flush;

getchar ( );

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ≪ flush;

return; } 902. ⟨ Define Path functions 701 ⟩ +≡

vector⟨Point ∗⟩::iterator point iter = points .begin( ); vector⟨string⟩::iterator connector iter = connectors .begin( ); string connector string ; if (connectors .size( ) > 0) connector string = ∗connector iter^{++}; else connector string = ; if (fill draw value ≡ ) {

if ( ) cout ≪ ≪ flush; if (arrow ≡ true) out stream ≪ ␣ ≪ ∗∗point iter^{++}; else out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ /∗ [LDF 2002.09.26.] Comparing pointers seems to work here. I think it

should, but I wasn’t sure that it really would. ∗/ if (draw color ≠ Colors ::default color ) {

out stream ≪ ␣ ␣ ≪ ∗draw color ; } if (dashed ≠ ) out stream ≪ ␣ ␣ ≪ dashed ; if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; out stream ≪ ≪ flush;

} else if (fill draw value ≡ ) {

if ( ) cout ≪ ≪ flush; out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ if (fill color ≠ Colors ::default color ) out stream ≪ ␣ ␣ ≪ ∗fill color ; out stream ≪ ≪ flush;

} else if (fill draw value ≡ ) { if ( ) cout ≪ ≪ flush; if (draw color ≡ fill color ) {

out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ if (draw color ≠ Colors ::default color ) out stream ≪ ␣ ␣ ≪ ∗draw color ; if (dashed ≠ ) out stream ≪ ␣ ␣ ≪ dashed ; if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; out stream ≪ ≪ flush;

} else /∗ We have two different colors, so we have to fill once and draw once. ∗/ { out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ out stream ≪ ␣ ␣ ≪ ∗fill color ; out stream ≪ ≪ flush; point iter = points .begin( ); 903.

Log

[LDF 2002.05.10.] Added the code in this section. It fixes a bug. If it’s not done, then the correct connectors are not used when the Path is output the second time.

⟨ Define Path functions 701 ⟩ +≡ connector iter = connectors .begin( ); if (connectors .size( ) > 0) connector string = ∗connector iter^{++}; else connector string = ;

904. ⟨ Define Path functions 701 ⟩ +≡

if (arrow ≡ true) out stream ≪ ␣ ≪ ∗∗point iter^{++}; else out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ if (draw color ≠ Colors ::default color ) out stream ≪ ␣ ␣ ≪ ∗draw color ; if (dashed ≠ ) out stream ≪ ␣ ␣ ≪ dashed ; if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; out stream ≪ ≪ flush; } } else

if (fill draw value ≡ ) { if ( ) cout ≪ ≪ flush; out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ if (dashed ≠ ) out stream ≪ ␣ ␣ ≪ dashed ; if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; out stream ≪ ≪ flush;

}

else if (fill draw value ≡ ) { if ( ) cout ≪ ≪ flush; out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ out stream ≪ ≪ flush;

} 905. Filldraw case.

Log

[LDF 2003.03.25.] Changed this section, so that the outline of the Path is drawn, if draw color ≠ Colors ::background color .

⟨ Define Path functions 701 ⟩ +≡

else

if (fill draw value ≡ ) { if ( ) cout ≪ ≪ flush; if (draw color ≡ Colors ::background color ) {

out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ if (dashed ≠ ) out stream ≪ ␣ ␣ ≪ dashed ; if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; out stream ≪ ≪ flush;

} else {

out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ out stream ≪ ≪ flush; point iter = points .begin( ); connector iter = connectors .begin( ); if (connectors .size( ) > 0) connector string = ∗connector iter^{++}; else connector string = ; out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ if (draw color ≠ Colors ::default color ) out stream ≪ ␣ ␣ ≪ ∗draw color ; if (dashed ≠ ) out stream ≪ ␣ ␣ ≪ dashed ; if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; out stream ≪ ≪ flush;

}

}  /∗ End of  case. [LDF 2003.03.25.] ∗/

906. Default case. [LDF 2003.03.25.] ⟨ Define Path functions 701 ⟩ +≡

else /∗ Use DRAW as default. [LDF 2003.03.25.] ∗/ {

cerr ≪ ␣ ␣ ␣ ≪ fill draw value ≪ ␣ ␣ ≪

flush;

#if 0 /∗ !! Define a class for information on the run state. ∗/

if (¬Run State ::non stop) getchar ( ); #endif

if (arrow ≡ true) out stream ≪ ␣ ≪ ∗∗point iter^{++}; else out stream ≪ ␣ ≪ ∗∗point iter^{++}; ⟨ Output Path 907 ⟩ if (draw color ≠ Colors ::default color ) out stream ≪ ␣ ␣ ≪ ∗draw color ; if (dashed ≠ ) out stream ≪ ␣ ␣ ≪ dashed ; if (pen ≠ ) out stream ≪ ␣ ␣ ≪ pen; out stream ≪ ≪ flush;

} if ( ) cout ≪ ␣ ≪ ≪ flush; return; } 907. When fill color and draw color are different, this will have to be performed twice, so I’ve made it a named section.

Log

[LDF 2002.11.03.] counter is now initially set to 2 instead of 1. This makes each line have at most two Points. Previously, the first line had 3 Points (if the Path had at least three Points on it).

[LDF 2002.12.20.] Using the manipulator “fixed ” below. It solves the problem of Points being output in scientific format, which Metapost doesn’t understand.

[LDF 2002.12.20.] I had to add preprocessor code for conditional compilation, because “fixed ” is unknown to the GNU C^{++} Compiler. However, it doesn’t need it in this case, since the problem only occurred when using the DEC C^{++} compiler on a DEC Alpha computer under Compaq Tru64.

⟨ Output Path 907 ⟩ ≡ if ( ) cout ≪ ␣ ␣ ≪ flush; for (unsigned short counter = 2; point iter ≠ points .end ( ); ) {

out stream ≪ ␣ ≪ connector string ≪ ␣ ≪ ∗∗point iter^{++}; /∗ This breaks the line and indents after two points ∗/

if (counter ≡ 2 ∧ point iter ≠ points .end ( )) { out stream ≪ ␣␣ ; counter = 1;

} else {

++counter ; } if (connector iter ≠ connectors .end ( )) connector string = ∗connector iter^{++};

}

if (is cycle( )) out stream ≪ ␣ ≪ connector string ≪ ␣ ;

if (  ) cout ≪  ␣      ␣  ≪ flush;

This code is used in sections 902, 904, 905, and 906.

908. Showing.

909. Show.

Log

[LDF 2003.07.13.] Commented-out the line that prints fill draw value to stdout .

[LDF 2003.08.20.] Now printing points .size( ) and connectors .size( ) to stdout . If the latter is 0, a message is printed, that will be used as the connector.

⟨ Declare Path functions 700 ⟩ +≡

void show (string text = , char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , const real factor = 1) const; 910. ⟨ Define Path functions 701 ⟩ +≡

void Path ::show (string text , char coords , const bool do persp, const bool do apply , Focus

∗f, const unsigned short proj , const real factor ) const

{ if (text ≡ ) text = ; cout ≪ text ≪ endl ;

#if 0

cout ≪ ␣ ␣ ≪ fill draw value ≪ endl ≪ flush; #endif

coords = tolower (coords ); if (coords ≡ ) ; /∗ Do nothing. ∗/

else if (coords ≡ ) cout ≪  ␣  ≪ flush;
else if (coords ≡ ) cout ≪  ␣  ≪ flush;
else if (coords ≡ ) cout ≪  ␣  ≪ flush;

else {

  cerr ≪  ␣  ␣         ␣ ≪  ␣         ␣    ␣      ␣  ≪

␣ ␣ ≪ flush; coords = ;

} valarray⟨real⟩ v; v.resize(4, 0); /∗ LDF 2002.12.13. Added this line. Needed for porting to Intel Linux (i686). ∗/ string connector string ; vector⟨string⟩::const iterator connectors iter = connectors .begin( ); cout ≪ ␣ ␣ ≪ points .size( ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ connectors .size( ) ≪ endl ≪ flush; if (connectors .size( ) ≡ 0) {

cout ≪ ␣ ␣ ␣ ≪ flush;

connector string = ; } {

int loop ctr = 0;

for (vector⟨Point ∗⟩::const iterator points iter = points .begin( ); points iter ≠ points .end ( );

++points iter ) { if (points iter ≠ points .begin( )) {

cout ≪ ␣ ≪ connector string ≪ ␣ ; } if (connectors iter ≠ connectors .end ( )) connector string = ∗connectors iter^{++}; if (loop ctr ≡ 2) /∗ Break each line after 2 Points. ∗/ {

cout ≪ endl ; loop ctr = 0;

}

++loop ctr ; v = (∗∗points iter ).get all coords (coords , do persp, do apply , f, proj , factor ); cout ≪ ≪ v[0] ≪ ␣ ≪ v[1] ≪ ␣ ≪ v[2] ≪ ;

} } if (cycle switch) {

if (connectors iter ≠ connectors .end ( )) connector string = ∗connectors iter^{++};

cout ≪ ␣ ≪ connector string ≪ ␣ ≪ endl ; } else cout ≪ ;

}

911. Show Colors. ⟨ Declare Path functions 700 ⟩ +≡

void show colors (bool stop = false);

912. ⟨ Define Path functions 701 ⟩ +≡

void Path ::show colors (bool stop) {

if (draw color ≠ 0) draw color show ( ); else cout ≪ ␣ ␣ ; if (fill color ≠ 0) fill color show ( ); else cout ≪ ␣ ␣ ; if (stop) getchar ( );

}

913. Returning elements and information.

914. Is on free store.

Log

[LDF 2004.01.06.] Made non-inline.

⟨ Declare Path functions 700 ⟩ +≡ bool is on free store( ) const;

915. ⟨ Define Path functions 701 ⟩ +≡

bool Path ::is on free store( ) const {

return on free store; }

916. Is planar. [LDF 2002.11.05.] is planar ( ) uses the return value of get normal ( ) to determine whether ∗this lies in a plane or not. If it does, is planar ( ) returns true, otherwise, it returns false. If ∗this is linear, is planar ( ) issues a warning and returns true.

Log

[LDF 2002.11.03.] Rewrote this function. It should now work for all Paths. [LDF 2002.11.05.] Rewrote this function again. It now uses the new version of get normal ( ). [LDF 2002.11.06.] Added optional const bool verbose and string text arguments for writing a message

to the standard output.

[LDF 2003.08.14.] Made verbose non-const. Setting it to true if is true. Added to pspglb.web today.

⟨ Declare Path functions 700 ⟩ +≡ virtual bool is planar (bool verbose = false, string text = ) const;

§917  3DLDF-1.1.5.1  IS PLANAR 247

917. ⟨ Define Path functions 701 ⟩ +≡

bool Path ::is planar (bool verbose, string text ) const {

bool = false; /∗ true ∗/ if ( ) verbose = true; if ( ∨ verbose) cout ≪ ␣ ; Point p(get normal ( )); if (p ≡ ) {

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; if (verbose) {

if (text ≡ ) text = ;

cout ≪ text ≪ ␣ ␣ ; } return false;

} else if (p ≡ origin) {

cerr ≪  ␣  ␣  ≪  ␣  ␣       ␣␣         ␣  ≪

flush; if (verbose) {

if (text ≡ ) text = ;

cout ≪ text ≪ ␣ ␣ ; } return true;

} else {

if (verbose) { if (text ≡ ) text = ; cout ≪ text ≪ ␣ ␣ ;

} if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; return true;

} }

918. Is linear. [LDF 2003.04.09.] is linear ( ) first checks whether line switch is true. If it is, it returns true right away. Otherwise, it uses the return value of get normal ( ) to determine whether ∗this is linear or not. If it is, is linear ( ) returns true, otherwise, it returns false.

Log

[LDF 2002.11.05.] Added this function. [LDF 2002.11.06.] Added optional const bool verbose and string text arguments for writing a message

to the standard output.

[LDF 2003.04.09.] Now checking whether line switch is true before calling get normal ( ). !! If a Path whose line switch ≡ true is modified such that it’s no longer linear, the programmer must ensure that line switch is set to false!

[LDF 2003.08.14.] Made verbose non-const. Setting it to true if is true. Added to pspglb.web today.

⟨ Declare Path functions 700 ⟩ +≡ bool is linear (bool verbose = false, string text = ) const;

248  IS LINEAR  3DLDF-1.1.5.1 §919

919. ⟨ Define Path functions 701 ⟩ +≡

bool Path ::is linear (bool verbose, string text ) const {

bool = false; /∗ true ∗/ if ( ) verbose = true; if ( ∨ verbose) cout ≪ ␣ ; if (line switch) /∗ LDF 2003.04.09. Added this conditional. ∗/

return true; Point p(get normal ( )); if (p ≡ origin) {

if (verbose) { if (text ≡ ) text = ; cout ≪ text ≪ ␣ ␣ ;

}

if ( ) cout ≪ ␣ ␣ ≪ ␣ ≪ flush; return true;

} else {

if (verbose) { if (text ≡ ) text = ; cout ≪ text ≪ ␣ ␣ ;

}

if ( ) cout ≪ ␣ ␣ ≪ ␣ ≪ flush; return false;

} }

920. Get line switch. [LDF 2002.11.03.] This function returns true for Paths that are created or set using two Points only, and no connectors, as arguments.

Log

[LDF 2002.11.03.] Renamed this function get line switch( ) from is line( ). About to add is linear ( ), which will test whether all the Points are colinear or not.

⟨ Declare Path functions 700 ⟩ +≡ inline bool get line switch( ) const {

return line switch; }

921. Test for cycles. ⟨ Declare Path functions 700 ⟩ +≡

inline bool is cycle( ) const {

return cycle switch; }

922. Size (number of points). ⟨ Declare Path functions 700 ⟩ +≡

§922  3DLDF-1.1.5.1  SIZE (NUMBER OF POINTS) 249

inline int size( )

{

return points .size( ); }

923. Slope. [LDF 2002.11.05.] slope( ) can only be used for linear Paths. It returns a real value representing the slope of the trace of a line on the major plane represented by the char arguments, or , if the Path is non-linear. For example, if \overrightarrow{p_{0}p_{1}} is a Path p and \overrightarrow{q_{0}q_{1}} is the trace of p on the x-y plane, then p.slope( , ) returns a real m such that m = (b − y)/x where b is the y-intercept of \overrightarrow{q_{0}q_{1}} and x and y are the x and y-coordinates of points on \overrightarrow{q_{0}q_{1}}.

Log

[LDF 2002.11.05.] Changed this function, so that is linear ( ) is used instead of get line switch( ) (formerly “is line( )”). Now, it can be used for all linear Paths, not just ones created using the constructor for lines. Also, it was commented-out.

⟨ Declare Path functions 700 ⟩ +≡ real slope(char a = , char b = );

924. ⟨ Define Path functions 701 ⟩ +≡

real Path ::slope(char a, char b)

{

if (¬is linear ( )) {

      cerr ≪  ␣  ␣              ␣    ␣  ␣   ␣  ≪

␣ ≪ flush;

return ; } return points [1] slope(∗points [0], a, b);

}

925. Subpath. [LDF 2002.11.05.] subpath( ) returns a new Path using points [start ] through points [end − 1] from ∗this . If the optional bool argument cycle is used, 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 connectors from ∗this are used.

[LDF 2002.11.05.] start must be < end . It is not possible to have start > end , even if ∗this is a cycle.

Log

[LDF 2002.11.05.] Rewrote this function. Made subpath( ) itself and its arguments const. Added error handling code.

[LDF 2003.07.16.] Please note that start and end cannot be made const.

[LDF 2003.08.27.] Changed int i to size t i in the for loops that compare i to start and end . The way it was before caused GCC with the “-Wall” option to issue a warning.

⟨ Declare Path functions 700 ⟩ +≡ Path subpath(size t start , size t end , const bool cycle = false, const string connector = ) const;

250  SUBPATH  3DLDF-1.1.5.1 §926

926. ⟨ Define Path functions 701 ⟩ +≡

Path Path ::subpath(size t start , size t end , const bool cycle, const string connector ) const{ bool

= false; /∗ true ∗/ Path p;

927. [LDF 2002.11.05.] There is no “ ”, so I return an empty one, if start ≥ end . Since operator≡( ) currently doesn’t exist, there’s not much point in defining , since there’s no way to compare another Path to it. ⟨ Define Path functions 701 ⟩ +≡

if (start ≥ end ) {

  cerr ≪  ␣  ␣  ≪  ␣         ␣        ␣  ␣ ␣   ␣

␣  ≪  ␣     ␣  ≪ flush;

return p; }

928. [LDF 2002.11.05.] More error handling. In these cases, it’s possible to recover. ⟨ Define Path functions 701 ⟩ +≡

if (start > points .size( ) − 1) {

  cerr ≪  ␣  ␣  ≪  ␣        ␣   ␣ ␣            ␣
      ␣  ≪  ␣   ␣  ␣       ␣  ␣       ␣     ␣ ␣  ≪ flush;

start = 0; } if (end > points .size( )) {

cerr ≪  ␣  ␣  ≪  ␣        ␣   ␣ ␣  ≪

      ␣   ␣  ␣       ␣  ␣       ␣   ␣ ␣  ≪ flush;

end = points .size( ); }

929. [LDF 2002.11.05.] If a connector argument is specified, all we have to do is put the appropriate Points from points onto p.points , put connector onto p.connectors , and return p. ⟨ Define Path functions 701 ⟩ +≡

if (connector ≠ ) { for (size t i = start ; i < end ; i^{++}) { if (i ≥ points .size( )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush; break;

} p.points .push back ( create new < Point > (points [i]) ) ; } p.connectors .push back (connector ); p.set cycle(cycle); return p; }

§930  3DLDF-1.1.5.1  SUBPATH 251

930. [LDF 2002.11.05.] If no connector argument is specified, then we have to get the appropriate connectors from ∗this . This is slightly tricky, because connectors doesn’t have to contain a connector for each pair of Points that is joined in a Path. So, first we must fill up p.connectors so that we can tell which ones to use.

[LDF 2002.11.05.] Actually, with the constructors that exist, there will either be only one connector or a connector for each pair of Points that need to be joined. However, it would be easy to write functions that add or remove connectors, so it’s best to have this routine. ⟨ Define Path functions 701 ⟩ +≡

p = ∗this ; unsigned short a = points .size( ); if (¬cycle) a −= 1; int i; string s = connectors .back ( ); for (i = connectors .size( ); i < a; i^{++}) {

p.connectors .push back (s); } if ( ) cout ≪ ␣ ␣ ≪ p.connectors .size( ) ≪ endl ≪ flush; Path q; for (size t i = start ; i < end ; i^{++}) { q.points .push back ( create new < Point > (p.points [i])

) ; if (i < p.connectors .size( )) q.connectors .push back (p.connectors [i]); } q.set cycle(cycle); return q; }

931. Get point.

932. non-const version.

Log

[LDF 2002.11.05.] Made non-inline. Changed return value to const Point &. [LDF 2003.11.28.] BUG FIX: Changed, so that apply transform( ) is called on the Point. This entailed

making this function non-const. Added const version below. This may actually be a bug, rather than a bug fix, depending on how this function is used elsewhere. However, I really think apply transform( ) should be called.

⟨ Declare Path functions 700 ⟩ +≡ const Point &get point (const unsigned short a); 933. ⟨ Define Path functions 701 ⟩ +≡

const Point &Path ::get point (const unsigned short a) {

if (a < points .size( )) { (points [a]) apply transform( ); return ∗points [a];

}

else {

    cerr ≪  ␣  ␣  ≪  ␣  ␣  ␣     ␣  ␣  ≪

␣ ≪ flush;

return ; }

}

934. const version.

Log

[LDF 2003.11.28.] Added this version.

⟨ Declare Path functions 700 ⟩ +≡ Point get point (const unsigned short a) const;

935. ⟨ Define Path functions 701 ⟩ +≡

Point Path ::get point (const unsigned short a) const {

if (a < points .size( )) { Point p = ∗(points [a]); p.apply transform( ); return p;

}

else {

    cerr ≪  ␣  ␣  ≪  ␣  ␣  ␣     ␣  ␣  ≪

␣ ≪ flush;

return ; }

}

936. Get last point.

Log

[LDF 2002.05.10.] Added this function. [LDF 2002.11.05.] Made non-inline. Changed return value to const Point &.

⟨ Declare Path functions 700 ⟩ +≡ const Point &get last point ( ) const;

§937  3DLDF-1.1.5.1  GET LAST POINT 253

937. ⟨ Define Path functions 701 ⟩ +≡

const Point &Path ::get last point ( ) const {

if (points .size( ) ≠ 0) return ∗points [points .size( ) − 1]; else {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ≪ flush;

return ; }

}

938. Get size. ⟨ Declare Path functions 700 ⟩ +≡

virtual inline size t get size( ) const {

return points .size( ); }

939. Get normal.

254 PATH VERSION 3DLDF-1.1.5.1 §940

940. Path version. [LDF 2002.11.05.] get normal ( ) returns a unit vector representing the normal to the plane of the Path ∗this , if ∗this is planar. If the Points on ∗this are colinear and there are no connectors that could make the Path non-linear, then origin ((0, 0, 0)) is returned. If the Path is neither planar nor linear, get normal ( ) returns .

[LDF 2002.11.05.]

• get normal ( ) first checks whether a Path contains no Points or only one Point. If so, get normal ( ) returns .

• Then it checks whether the Path has connnectors that might make the Path non-planar, even if the Points lie in a plane. If it does, it returns . Note that there is no guarantee that the connectors actually will make the Path non-planar.

• Then it checks whether the Path has only two Points. If it does, get normal ( ) returns the Point (0, 0, 0), because the Path will be linear.

• Then it gets the cross product b_{0} of \overrightarrow{p_{0}p_{1}} and \overrightarrow{p_{0}p_{2}}, where p_{0} and p_{1} are the first and second Points on the Path, and p_{2} is the next Point on the Path such that b_{0} ≠ (0, 0, 0). If no Points on the Path fulfill this condition, then all of the Points are colinear, so get normal ( ) returns origin.

• If, however, b_{0} ≠ (0, 0, 0) exists, then cross products b_{x} are calculated using \overrightarrow{p_{0}p_{1}} and the direction vectors \overrightarrow{p_{0}p_{x}} for the rest of the Points p_{x} on the Path. If and only if b_{x} = b_{0}, or b_{x} = −b_{0}, or b_{x} = (0, 0, 0) for all b_{x}, then the Path is planar, and get normal ( ) returns −b_{0} (see explanation of sign below). Otherwise, the Path is non-planar, and get normal ( ) returns . [LDF 2003.06.04.] Reversing the sign of b_{0} ensures that the normal will point in the direction of the positive

y-axis, when a plane figure is created in the x-z plane, using one of the constructors taking a Point argument for the center, real arguments for the dimensions, and three real arguments for the rotation about the major axes. If non-zero arguments are used for rotation, the normal will be rotated accordingly. This direction considered to be “outside”. In 3DLDF, the constructors generally generate Points moving about the figure in the counter-clockwise direction (as seen from a Point with a positive y-coordinate). 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. !! Watch out for problems that may arise from this discrepancy!

Log

[LDF 2002.11.05.] Rewrote this function.

[LDF 2003.06.04.] Changed sign of the normal, when it’s returned, in the cases where a proper normal is found (not or origin). See explanation above.

⟨ Declare Path functions 700 ⟩ +≡ virtual Point get normal ( ) const;

941. ⟨ Define Path functions 701 ⟩ +≡

Point Path ::get normal ( ) const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (points .size( ) ≤ 0) {

cerr ≪  ␣  ␣  ≪

           ␣  ␣     ␣  ␣        ␣    ␣   ␣       ␣ ≪  ␣  ≪

flush; return ;

}

§942  3DLDF-1.1.5.1  PATH VERSION 255

942. [LDF 2002.11.05.] Connectors other than the ones in the conditional below could cause the Path to be non-linear or non-planar, even if the Points lie on a line or in a plane. ⟨ Define Path functions 701 ⟩ +≡

for (vector⟨string⟩::const iterator iter = connectors .begin( ); iter ≠ connectors .end ( ); ^{++}iter ) {

if (¬(∗iter ≡  ∨ ∗iter ≡  ∨ ∗iter ≡  ∨ ∗iter ≡  )) {

      cerr ≪  ␣  ␣  ≪  ␣   ␣    ␣     ␣          ␣  ␣

␣ ≪ ∗iter ≪ endl ≪  ␣  ≪ flush;

return ; }

}

943. [LDF 2002.11.05.] Two points determine a line. ⟨ Define Path functions 701 ⟩ +≡

if (points .size( ) ≡ 2) {

cerr ≪  ␣  ␣  ≪

        ␣   ␣ ␣       ␣ ␣         ␣  ≪ flush;

return origin; } 944. ⟨ Define Path functions 701 ⟩ +≡

vector⟨Point ∗⟩::const iterator iter = points .begin( ); Point p0 (∗∗iter^{++}); Point p1 (∗∗iter^{++}); Point p2 ; Point a0 (p1 − p0 ); Point a1 ; Point b0 ; while (b0 ≡ origin ∧ iter ≠ points .end ( )) {

p2 = ∗∗iter^{++};

a1 = p2 − p0 ;

b0 = a0 .cross product (a1 ); } if (iter ≡ points .end ( ) ∧ b0 ≡ origin) {

if ( ) cout ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪

␣ ≪ flush; return origin;

} if ( ) b0 .show ( ); b0 .unit vector (true); if (iter ≡ points .end ( ) ∧ b0 ≠ origin) {

if ( ) {

    cout ≪  ␣                   ␣ ≪  ␣   ␣   ␣        ␣      ␣   ␣  ≪

␣ ≪ flush;

}

return −b0 ; } Point b1 ; if ( ) cout ≪ ␣ ␣ ≪ flush; while (iter ≠ points .end ( )) {

p2 = ∗∗iter^{++};

a1 = p2 − p0 ;

b1 = a0 .cross product (a1 );

if (b1 ≠ origin)

/∗ [LDF 2002.11.03.] This if merely prevents a warning from being issued by unit vector ( ). ∗/ b1 .unit vector (true);

if ( ) b1 .show ( );

if (¬(b1 ≡ origin ∨ b1 ≡ b0 ∨ b1 ≡ −b0 )) {

if ( )

cout ≪ ␣ ␣ ≪ ␣ ≪ flush; return ;

} } if ( ) cout ≪ ␣ ␣ ≪ ␣ ≪ flush; return −b0 ; } 945. Point version. Point ::get normal ( ) is declared points.web, but it must be defined here, because it calls Path ::get normal ( ). [LDF 2003.07.11.]

Log

[LDF 2003.07.11.] Added this function.

⟨ Define Point functions 330 ⟩ +≡ Point Point ::get normal (const Point &p, const Point &q) const {

Path r; r.set connectors ( ); r += ∗this ; r += p; r += q; if (¬r.is planar ( )) {

cerr ≪  ␣  ␣  ≪

      ␣      ␣  ␣   ␣         ␣ ␣  ≪  ␣  ≪ flush;

return ; } else return r.get normal ( );

}

946. Get plane.

Log

[LDF 2002.11.05.] Rewrote this function to correspond to the new definition of get normal ( ).

⟨ Declare Path functions 700 ⟩ +≡ virtual Plane get plane( ) const;

258  GET PLANE  3DLDF-1.1.5.1 §947

947. ⟨ Define Path functions 701 ⟩ +≡

Plane Path ::get plane( ) const

{ Point normal (get normal ( )); if (normal ≡ ∨ normal ≡ origin) {

cerr ≪  ␣  ␣  ≪

          ␣  ␣   ␣ ␣      ␣         ␣  ≪ flush;

return ; } Point point (get point (0)); return Plane(point , normal );

}

948. Point lies within triangle. [LDF 2003.06.11.] Declared in points.web. Must be defined here, because Path is an incompletely defined type there.

Log

[LDF 2003.06.11.] Added this function.

[LDF 2003.06.24.] Removed the argument test points . Now, planarity is always tested.

[LDF 2003.06.24.] BUG FIX: When the Points all lay in the x-z plane, or a plane parallel to it, lambda denominator was 0. This caused is in triangle( ) to return false, even when ∗this did lie in the triangle. Now, if lambda denominator or mu denominator is equal to 0, the y and z-coordinates are exchanged, and lambda denominator and mu denominator are recalculated. If either of the new values is 0, the x and z-coordinates are exchanged (based on the original coordinate values), and lambda denominator and mu denominator are again recalculated. Only one exchange has been needed in the cases I’ve tested so far.

[LDF 2003.08.14.] Setting verbose to true if  is true. Added  to

pspglb.web today.

⟨ Define Point functions 330 ⟩ +≡

bool Point ::is in triangle(const Point &p0 , const Point &p1 , const Point &p2 , bool verbose)

const{ bool = false; /∗ true ∗/ if ( ) verbose = true; Path q; q += p0 ; q += p1 ; q += p2 ; Plane q pl = q.get plane( ); if (q pl ≡ ) {

if (verbose) {

cerr ≪  ␣  ␣  ≪

             ␣     ␣         ␣  ␣   ␣         ␣ ␣  ≪  ␣  ≪

flush; } return false;

}

else if (¬is on plane(q pl )) { if (verbose) {

§948  3DLDF-1.1.5.1  POINT LIES WITHIN TRIANGLE 259
cerr ≪  ␣  ␣  ≪

        ␣       ␣   ␣   ␣   ␣     ␣          ␣ ≪ ␣   ␣  ≪

␣ ≪ flush;

}

return false; } Point t(∗this ); Point c(p0 ); Point d(p1 ); Point e(p2 ); t.apply transform( ); c.apply transform( ); d.apply transform( ); e.apply transform( ); if ( ) {

show ( ); c.show ( ); d.show ( ); e.show ( );

} real t x = t.world coordinates [0]; real t y = t.world coordinates [1]; real t z = t.world coordinates [2]; real c x = c.world coordinates [0]; real c y = c.world coordinates [1]; real c z = c.world coordinates [2]; real d x = d.world coordinates [0]; real d y = d.world coordinates [1]; real d z = d.world coordinates [2]; real e x = e.world coordinates [0]; real e y = e.world coordinates [1]; real e z = e.world coordinates [2]; real lambda denominator = (((e x − c x ) ∗ (d y − c y )) − ((e y − c y ) ∗ (d x − c x ))); real mu denominator = ((e x − c x ) ∗ (d y − c y )) − ((e y − c y ) ∗ (d x − c x )); bool exchange y z = false; bool exchange x z = false; if (lambda denominator ≡ 0 ∨ mu denominator ≡ 0) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush; real temp; temp = t y ; t y = t z ; t z = temp; temp = c y ; c y = c z ; c z = temp; temp = d y ; d y = d z ; d z = temp; temp = e y ; e y = e z ; e z = temp;

260 POINT LIES WITHIN TRIANGLE 3DLDF-1.1.5.1 §948

lambda denominator = (((e x − c x ) ∗ (d y − c y )) − ((e y − c y ) ∗ (d x − c x ))); 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 (  ) cout ≪  ␣ ␣   ␣             ␣  ≪

           ␣    ␣             ␣    ␣  ␣      ␣  ≪ flush;

exchange y z = true; } else { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush;

949. First, put things back the way they were. It’s wasteful, but less confusing. [LDF 2003.06.24.] ⟨ Define Point functions 330 ⟩ +≡

temp = t y ; t y = t z ; t z = temp; temp = c y ; c y = c z ; c z = temp; temp = d y ; d y = d z ; d z = temp; temp = e y ; e y = e z ; e z = temp; 950. Now, exchange the x and z-coordinates. [LDF 2003.06.24.] ⟨ Define Point functions 330 ⟩ +≡

temp = t x ; t x = t z ; t z = temp; temp = c x ; c x = c z ; c z = temp; temp = d x ; d x = d z ; d z = temp; temp = e x ; e x = e z ; e z = temp; lambda denominator = (((e x − c x ) ∗ (d y − c y )) − ((e y − c y ) ∗ (d x − c x ))); 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 (  ) cout ≪  ␣ ␣   ␣             ␣  ≪

        ␣    ␣             ␣    ␣  ␣      ␣  ≪ flush;

exchange x z = true; } else {

if (verbose ∨ ) {

cerr ≪  ␣  ␣  ≪
␣   ␣             ␣   ␣  ≪  ␣  ≪ flush;

}

return false; } } } real lambda = (((t x − c x ) ∗ (d y − c y )) − ((t y − c y ) ∗ (d x − c x )))/lambda denominator ; real mu = −((((t x − c x ) ∗ (e y − c y )) − ((t y − c y ) ∗ (e x − c x )))/mu denominator ); if ( ) {

cout ≪ ␣ ␣ ≪ lambda ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ mu ≪ endl ≪ flush;

cout ≪ ␣ ␣ ␣ ␣ ≪ lambda + mu ≪ endl ≪ flush;

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ (lambda ≥ 0 ∧ mu ≥

0 ∧ ((lambda + mu) ≤ 1)) ≪ endl ≪ flush; } bool b = (lambda ≥ 0 ∧ mu ≥ 0 ∧ ((lambda + mu) ≤ 1)); if (verbose) {

cout ≪ ␣ ;

if (b) cout ≪  ␣     ␣    ␣       ␣   ␣         ␣ ≪  ␣  ;
else cout ≪  ␣     ␣       ␣    ␣      ␣   ␣         ␣ ≪  ␣  ;

cout ≪ endl ≪ endl ≪ flush; } return b; }

951. Manipulating Paths.

952. Set cycle.

Log

[LDF 2002.4.7.] Changed, so that the argument bool c is true by default.

262  SET CYCLE  3DLDF-1.1.5.1 §952

[LDF 2002.11.05.] Made bool c argument const.

⟨ Declare Path functions 700 ⟩ +≡ void set cycle(const bool c = true);

953. ⟨ Define Path functions 701 ⟩ +≡

void Path ::set cycle(const bool c)

{

cycle switch = c; }

954. Reverse.

955. With assignment.

Log

[LDF 2002.4.6.] Added this function.

[LDF 2003.07.16.] Added error handling code for the case that this function is called with assign ≡ false. I’ve now added a const version, so there’s no need to call this version with assign ≡ false. If assign is false, the const version is called, so I could simplify the code in this version.

⟨ Declare Path functions 700 ⟩ +≡ Path reverse(bool assign);

956. ⟨ Define Path functions 701 ⟩ +≡

Path Path ::reverse(bool assign){ bool = false; /∗ true ∗/ if (is cycle( )) /∗ Return ∗this if ∗this is a cycle. ∗/ {

        cerr ≪  ␣  ␣  ≪  ␣  ␣ ␣      ␣      ␣  ≪
           ␣  ;

return ∗this ; } if (¬assign) {

cerr ≪  ␣  ␣  ≪  ␣  ␣      ␣

           ␣    ␣    ␣        ␣ ≪  ␣     ␣  ␣   ␣  ≪
           ␣         ␣        ␣  ␣        ␣  ≪  ␣  ≪

flush; return reverse( );

} 957. [LDF 2002.4.6.] If there is more than one connector, but there isn’t an explicit connector for every pair of Points in points , then we have to fill up connectors so that there is one for each pair of Points. Otherwise, the connectors and the Points won’t match up properly when we reverse them. ⟨ Define Path functions 701 ⟩ +≡

if (connectors .size( ) > 1 ∧ connectors .size( ) ≠ points .size( ) − 1) { string last connector ; last connector = connectors .back ( ); while (connectors .size( ) < points .size( ) − 1) connectors .push back (last connector );

}

958. [LDF 2002.4.7.] If I don’t explicitly refer to the std namespace here, this function is called, and since the arguments are different from the one used for this function, this causes an error at compile time. ⟨ Define Path functions 701 ⟩ +≡

if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; std ::reverse(connectors .begin( ), connectors .end ( )); std ::reverse(points .begin( ), points .end ( )); if ( ) {

cout ≪ ␣ ;

for (vector⟨string⟩::iterator iter = connectors .begin( ); iter ≠ connectors .end ( ); iter^{++})

cout ≪ ∗iter ≪ endl ; cout ≪ ␣ ; for (vector⟨Point ∗⟩::iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++}) (∗∗iter ).show ( ); getchar ( );

} /∗ if ( ) ∗/

return ∗this ; }

959. No assignment. This version merely copies ∗this and calls reverse(true) on the copy, returning the return value of that function call.

Log

[LDF 2003.07.16.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡ Path reverse(void) const;

960. ⟨ Define Path functions 701 ⟩ +≡

Path Path ::reverse(void) const

{ Path p = ∗this ; return p.reverse(true);

}

961. Equality. TO DO: I’ll need to make all connectors explicit in order to make this work. See operator&( ) for an example of how to make this work. ⟨ Declare Path functions 700 ⟩ +≡ #if 0

virtual bool operator≡(Path &p); #endif

264  EQUALITY  3DLDF-1.1.5.1 §962

962. ⟨ Define Path functions 701 ⟩ +≡ #if 0

virtual bool Path ::operator≡(Path &p)

{ } #endif

963. Intersection.

964. Intersection of two linear Paths. If ∗this is a line and the argument pa is a line, intersection point ( ) calls the version for Points in points.web.

Other kinds of Paths and other classes will need their own versions of this function.

I may have a problem with the constancy of ∗this and pa. If I do, just remove it.

Log

[LDF 2002.04.15.] Changed return value from bool real point to bool point, since I’ve had to commentout the version of Point ::intersection point ( ) that uses the Line version.

[LDF 2002.04.10.] Changed return type to bool real point to correspond with the same change to Point ::intersection point ( ).

[LDF 2003.07.04.] Added trace argument. Added conditional using trace to choose which version of Point ::intersection point ( ) should be called. Changed so that is linear ( ) is used instead of get line switch( ). Now using get last point ( ) instead of ∗points [1].

⟨ Declare Path functions 700 ⟩ +≡ bool point intersection point (const Path &pa, const bool trace = false) const;

§965  3DLDF-1.1.5.1  INTERSECTION OF TWO LINEAR PATHS 265

965. ⟨ Define Path functions 701 ⟩ +≡

bool point Path ::intersection point (const Path &pa, const bool trace) const

{

if (is linear ( ) ∧ pa.is linear ( )) {

if (trace) return Point ::intersection point (∗points [0], get last point ( ), ∗pa.points [0],

pa.get last point ( ), trace); else return Point ::intersection point (∗points [0], get last point ( ), ∗pa.points [0], pa.get last point ( ),

trace);

} else {

cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ ␣ ≪ flush; return ;

} }

966. Intersection of a linear Path with a Plane. [LDF 2003.06.03.] This function must be defined here, because Path is an incomplete type in planes.web.

Log

[LDF 2003.06.03.] Added this function.

⟨ Define Plane functions 664 ⟩ +≡ bool point Plane ::intersection point (const Path &p) const {

if (p.is linear ( )) return intersection point (p.get point (0), p.get last point ( )); else {

cerr ≪ ␣ ␣ ␣ ≪ endl ≪

␣ ␣ ␣ ␣␣ ␣ ≪ endl ≪ endl ≪ flush; return ;

} }

967. Drawing axes. This function draws and labels arrows for the main axes at the origin. It can be helpful for determining whether the “up” direction is correct for a Focus.

[LDF 2003.04.01.] Sometimes placeholders are needed for the dist and position arguments. If dist is a number x ≤ 0, then it’s set to the default, currently 2.5. If a position argument (pos x , pos y , or pos z ) is , it’s set to the default.

Log

[LDF 2003.02.05.] Moved this function from main.web to here, so I can use it in my examples for the Texinfo documentation. Also, added additional arguments specifying the positions of labels and suppressing drawing the axes (and their labels).

[LDF 2003.04.01.] Added arguments for dash pattern (ddashed ) and pen (ppen). Rearranged order of arguments. Also, got rid of the arguments suppress x , suppress y , and suppress z . Now using the empty string ( ) in the arguments pos x , pos y , and pos z to indicate that the corresponding axes should be suppressed. Added error handling code that prints a warning to stderr if all axes are suppressed. ([LDF 2003.05.06.] Note that will never be needed for labelling an axis, because putting the label on top of the Point would interfere with the arrow.)

[LDF 2003.04.01.] Added arguments shift x , shift y , and shift z for adjusting the position of the labels. Note that the adjustment affects the position of the three-dimensional Point within the Label, not the two-dimensional projected point. Therefore, it’s not possible to adjust the position of the Label precisely

266  DRAWING AXES  3DLDF-1.1.5.1 §967

without changing the Metapost code. TO DO: Change label ( ), so that it’s possible to adjust the position of the points in the projection! This may open a can of worms, though, especially if the same code is used to generate drawings using different projections and/or different Focuses .

[LDF 2003.07.13.] Made ddashed and ppen const in both versions.

968. Length argument first. ⟨ Declare draw axes ( ) 968 ⟩ ≡

void draw axes (real dist = 2.5, string pos x = , string pos y = , string pos z = , 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);

See also section 973. This code is used in section 981.

969. ⟨ Define draw axes ( ) 969 ⟩ ≡

void draw axes (real dist , string pos x , string pos y , string pos z , const Color &ddraw color , const string ddashed , const string ppen, const Point &shift x , const Point &shift y , const Point &shift z , Picture &picture){

See also sections 970, 971, 972, and 974. This code is used in section 980.

970. Remember to change this if you change any of the defaults!

Log

[LDF 2003.04.01.] Added this section.

⟨ Define draw axes ( ) 969 ⟩ +≡ if (dist ≤ 0) dist = 2.5; if (pos x ≡ ) pos x = ; if (pos y ≡ ) pos y = ; if (pos z ≡ ) pos z = ;

971.

Log

[LDF 2003.04.01.] Added this error handling code.

⟨ Define draw axes ( ) 969 ⟩ +≡

if (pos x ≡ ∧ pos y ≡ ∧ pos z ≡ ) {

cerr ≪ ␣ ␣ ≪ endl ≪ ␣ ␣ ␣ ␣ ≪

endl ≪ endl ≪ flush; return;

}

§972  3DLDF-1.1.5.1  LENGTH ARGUMENT FIRST 267

972. ⟨ Define draw axes ( ) 969 ⟩ +≡

if (pos x ≠ ) { Point x0 (−dist ); Point x1 (dist ); x0 .drawarrow (x1 , ddraw color , ddashed , ppen, picture); x1 += shift x ; x1 .label ( , pos x , false, picture);

} if (pos y ≠ ) {

Point y0 (0, −dist ); Point y1 (0, dist ); y0 .drawarrow (y1 , ddraw color , ddashed , ppen, picture); y1 += shift y ; y1 .label ( , pos y , false, picture);

} if (pos z ≠ ) {

Point z0 (0, 0, −dist ); Point z1 (0, 0, dist ); z0 .drawarrow (z1 , ddraw color , ddashed , ppen, picture); z1 += shift z ; z1 .label ( , pos z , false, picture);

} return; }

973. Color argument first.

Log

[LDF 2003.05.02.] Added this function.

⟨ Declare draw axes ( ) 968 ⟩ +≡

void draw axes (const Color &ddraw color , real dist = 2.5, string pos x = , string pos y = , string pos z = , 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);

268 COLOR ARGUMENT FIRST 3DLDF-1.1.5.1 §974

974. ⟨ Define draw axes ( ) 969 ⟩ +≡

void draw axes (const Color &ddraw color , real dist , string pos x , string pos y , string pos z , const string ddashed , const string ppen, const Point &shift x , const Point &shift y , const Point &shift z , Picture &picture)

{

draw axes (dist , pos x , pos y , pos z , ddraw color , ddashed , ppen, shift x , shift y , shift z , picture); }

975. Paths and Lines.

Log

[LDF 2003.06.06.] Added this heading.

976. Get Line. Returns a Line corresponding to ∗this , if ∗this is linear. Otherwise, get line( ) returns .

Log

[LDF 2003.06.06.] Added this function.

⟨ Declare Path functions 700 ⟩ +≡ Line get line(void) const;

977. ⟨ Define Path functions 701 ⟩ +≡

Line Path ::get line(void) const {

if (is linear ( )) return points .front ( ) get line(∗(points .back ( )));

else {

    cerr ≪  ␣  ␣  ≪  ␣  ␣   ␣       ␣         ␣

≪ flush;

return ; }

}

978. Get Path. Declared in lines.web. Must be defined here, because Path is an incomplete type there.

Log

[LDF 2003.06.06.] Added this function.

⟨ Define Line functions 644 ⟩ +≡ Path Line ::get path(void) const {

Point p(position + direction);

return Path(position, p); }

979. Putting Path together.

§980  3DLDF-1.1.5.1  PUTTING PATH TOGETHER 269

980. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Path 698 ⟩ ⟨ Define static class Path data members 699 ⟩ ⟨ Define Transform functions 169 ⟩ ⟨ Define Point functions 330 ⟩ ⟨ Define Plane functions 664 ⟩ ⟨ Define Path functions 701 ⟩ ⟨ Define Line functions 644 ⟩ ⟨ Define draw axes ( ) 969 ⟩ ⟨ Declare non-member template functions for Path 724 ⟩

270  PUTTING PATH TOGETHER  3DLDF-1.1.5.1 §981

981. This is what’s written to paths.h. ⟨ 981 ⟩ ≡

⟨ Define class Path 698 ⟩

⟨ Declare draw axes ( ) 968 ⟩

⟨ Declare non-member template functions for Path 724 ⟩

982. Curves (curves.web).

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

format Curve Path

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

983. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include

984. Regular closed plane curve.

Log

[LDF 2002.11.12.] Changed the name “Regular Closed Plane Curve” to “Reg Cl Plane Curve”, because the former caused too many “Overfull boxes” when running cweave.

985. Reg Cl Plane Curve class definition. A Reg Cl Plane Curve is assumed to be closed, planar, convex, and have at least 3 points. The functions that create and modify Reg Cl Plane Curves must ensure that these assumptions are correct!

[LDF 2002.11.05.] Reg Cl Plane Curve is intended to be used as a base class. No objects of type Reg Cl Plane Curve should be defined, however, it is not an abstract class, so it is possible to do so.

format Reg Cl Plane Curve Curve

⟨ Define class Reg Cl Plane Curve 985 ⟩ ≡ class Reg Cl Plane Curve : public Path { protected: Point center ;

unsigned short number of points ; public: ⟨ Declare Reg Cl Plane Curve functions 987 ⟩

§985  3DLDF-1.1.5.1  REG CL PLANE CURVE CLASS DEFINITION 271

};

This code is used in sections 1015 and 1016.

986. Returning elements and information. [LDF 2002.11.05.] The virtual functions in this section are meant to be overloaded by member functions of types derived from Reg Cl Plane Curve.

Log

[LDF 2002.11.03.] Removed Reg Cl Plane Curve ::is planar ( ). A Reg Cl Plane Curve can be manipulated into a non-planar state, so it’s safer to use the Path version, which tests whether it’s really planar or not.

987. Is quadratic. ⟨ Declare Reg Cl Plane Curve functions 987 ⟩ ≡

inline virtual bool is quadratic( ) const {

return false; }

See also sections 988, 989, 990, 991, 992, 994, 997, 1008, 1011, 1013, and 1014. This code is used in section 985.

988. Is cubic. ⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡

inline virtual bool is cubic( ) const {

return false; }

989. Is quartic. ⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡

inline virtual bool is quartic( ) const {

return false; }

990. Get coefficients. ⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡

inline virtual real triple get coefficients (real, real) const {

return real triple( , , ); }

991. Solve. [LDF 2002.11.05.] This virtual function is meant to be overloaded by member functions of types derived from Reg Cl Plane Curve. ⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡

inline virtual pair⟨real, real⟩ solve(char, real) const {

272  LOCATION OF A POINT  3DLDF-1.1.5.1 §992

return pair⟨real, real⟩( , ); } 992. Location of a point. location( ) returns a signed short indicating the location of its Point argument with respect to the Reg Cl Plane Curve.

[LDF 2002.11.05.] TO DO: Currently, the programmer must ensure that a Reg Cl Plane Curve is planar. It might be worthwhile to check that it really is by using Path ::get normal ( ), since some manipulations may cause a Reg Cl Plane Curve to become non-planar.

[LDF 2002.11.05.] The number of Points in a Reg Cl Plane Curve must be a multiple of 4, and that the Point number of points /4 must be at 90^{∘} to Point 0. Also, ref pt can’t be Point 0.

[LDF 2003.07.16.] Reg Cl Plane Curve now has a data member named center . However, a Reg Cl Plane Curve need not have a meaningful center. Usually, when an object of a class derived from Reg Cl Plane Curve calls this function, its center will be passed as the ref pt argument. However, this need not be the case.

TO DO: Check whether it will work if pt0 .x < 0. I think it should.

[LDF 2003.06.14.] !! CHECK. Bug, when Reg Cl Plane Curve is rotated about x and z-axes only. The following values are returned if the Point is in the same plane as ∗this and this function has worked

properly:

-1 The Point lies outside the Reg Cl Plane Curve.

0 The Point lies on the perimeter of the Reg Cl Plane Curve.

1 The Point lies inside the perimeter of the Reg Cl Plane Curve.

These values are returned in cases where errors have occurred:

-2 The Point is not in the same plane as the Reg Cl Plane Curve.

-3 Something has gone terribly wrong.

-4 The normal to the Reg Cl Plane Curve has 0 magnitude, i.e., the Points on the Reg Cl Plane Curve are colinear.

-5 An error occurred in putting the Reg Cl Plane Curve in one of the major planes.

-6 The Reg Cl Plane Curve is non-planar.

Log

[LDF 2002.04.03.] Added and tested all cases. Seems to work properly.

[LDF 2002.11.12.] Added “ ” after the arguments to “ ” in the TEX code above in order to suppress a space at the beginning of the first line of the following indented paragraph. I couldn’t figure out a way of suppressing the space within the definition of (which is currently “ ” to ).

[LDF 2003.06.03.] Changed the line where Plane ::get distance( ) is called below. It now returns a real short, so “. first ” has to be added, in order to get the real value.

[LDF 2003.06.13.] Changed pt0 .epsilon( ) to Point ::epsilon( ).

[LDF 2003.06.14.] Added error handling code for the case that get plane( ) fails.

[LDF 2003.06.14.] No longer taking absolute value of the real value r0 returned by Plane ::get distance( ), since it will always be positive, anyway. Comment at place below, where I made this change.

[LDF 2003.07.01.] Added argument suppress warnings .

[LDF 2003.07.16.] Changed name of center argument to ref pt , because I’ve made center a data member of Reg Cl Plane Curve.

§993  3DLDF-1.1.5.1  LOCATION OF A POINT 273

⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡ virtual signed short location(Point ref pt , Point pt0 , const bool suppress warnings = false) const; 993. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ ≡

signed short Reg Cl Plane Curve ::location(Point ref pt , Point pt0 , const bool suppress warnings )

const

{ bool = false; /∗ true ∗/ if ( ) {

cout ≪ ␣ ;

ref pt .show ( );

pt0 .show ( ); } unsigned short orientation; const unsigned short = 0; const unsigned short = 1; const unsigned short = 2; Plane pl (get plane( )); if (pl ≡ ) /∗ LDF 2003.06.14. Added this error handling code. ∗/ {

cerr ≪  ␣  ␣  ≪
␣                  ␣  ␣  ≪  ␣  ≪ flush;

return −6; } real r0 = pl .get distance(pt0 ).first ; if (r0 > Point ::epsilon( ))

/∗ LDF 2003.06.14. Changed. r0 will always be positive, so I now longer take its absolute value. ∗/ {

if (¬suppress warnings ) cerr ≪  ␣  ␣  ≪

        ␣  ␣   ␣  ␣      ␣  ␣       ␣       ␣     ␣  ≪

␣ ≪ flush;

return −2; } Reg Cl Plane Curve copy (∗this ); if (ref pt ≠ origin) pt0 ∗= ref pt ∗= copy .shift (−ref pt ); /∗ LDF 2002.11.05. Simplified. ∗/ Point copy normal = copy .get normal ( ); if ( ) copy normal .show ( ); if (copy normal .magnitude( ) ≡ 0) {

cerr ≪ ␣ ␣ ≪

␣ ␣ ␣ ␣ ␣ ≪ flush; return −4;

} else if (fabs (copy normal .get x ( )) < Point ::epsilon( )∧fabs (copy normal .get y ( )) < Point ::epsilon( ))

{

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; orientation = ;

} else if (fabs (copy normal .get x ( )) < Point ::epsilon( )∧fabs (copy normal .get z ( )) < Point ::epsilon( ))

{

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; orientation = ;

} else if (fabs (copy normal .get z ( )) < Point ::epsilon( )∧fabs (copy normal .get y ( )) < Point ::epsilon( ))

{ if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; orientation = ;

} else {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; Transform t1 ; t1 .align with axis (ref pt , copy .get point (0), ); copy ∗= ref pt ∗= pt0 ∗= t1 ; Point pt c4 (copy .get point (number of points /4)); Transform t2 ; t2 .align with axis (ref pt , pt c4 , ); copy ∗= ref pt ∗= pt0 ∗= t2 ; orientation = ;

} if ( ) {

cout ≪ ␣ ␣ ≪ orientation ≪ endl ≪ flush; copy .draw (Colors ::blue); copy .show ( ); ref pt .dotlabel ( ); pt0 .dotlabel ( ); pt0 .show ( );

} Transform t3 ; Point pt1 = copy .get point (0); pt1 −= ref pt ; pt1 .unit vector (true); Point x axis (1, 0, 0); Point z axis (0, 0, 1); if (orientation ≡ ∨ orientation ≡ ) {

if (pt1 ≠ x axis ∧ pt1 ≠ −x axis ) { t3 .align with axis (ref pt , pt1 , ); copy ∗= ref pt ∗= pt0 ∗= t3 ;

} } else if (orientation ≡ ) {

if (pt1 ≠ z axis ∧ pt1 ≠ −z axis ) { t3 .align with axis (ref pt , pt1 , ); copy ∗= t3 ; ref pt ∗= t3 ; pt0 ∗= t3 ;

} } real pair rr ; real pt0 v ; /∗ [LDF 2002.11.05.] Vertical. ∗/ real pt0 h; /∗ [LDF 2002.11.05.] Horizontal. ∗/ if (orientation ≡ ) {

pt0 h = pt0 .get x ( ); pt0 v = pt0 .get y ( ); } else if (orientation ≡ ) {

pt0 h = pt0 .get x ( ); pt0 v = pt0 .get z ( );

} else if (orientation ≡ ) {

pt0 h = pt0 .get z ( ); pt0 v = pt0 .get y ( );

} else {

cerr ≪  ␣  ␣  ≪
␣   ␣        ␣      ␣ ≪ orientation ≪  ␣  ≪ flush;

return −5; } rr = solve( , pt0 h); /∗ [LDF 2002.11.05.] TO DO: Explain. ∗/ if (rr .first ≡ ∧ rr .second ≡ ) {

if ( ) {

  cout ≪  ␣  ␣       ␣       ␣      ␣     ␣       ␣ ≪  ␣  ;

cout ≪  ␣  ;

} return −1;

} else if ((fabs (fabs (pt0 v )−fabs (rr .first )) < Point ::epsilon( ))∨(fabs (fabs (pt0 v )−fabs (rr .second )) <

Point ::epsilon( ))) { if ( ) {

  cout ≪  ␣  ␣  ␣       ␣      ␣     ␣       ␣ ≪  ␣  ≪
      ␣  ;

getchar ( ); } return 0;

} else if (fabs (pt0 v ) < fabs (rr .first )) {

if ( ) {

  cout ≪  ␣  ␣      ␣       ␣      ␣     ␣       ␣ ≪  ␣  ;

cout ≪  ␣  ;

getchar ( ); } return 1;

} else if (fabs (pt0 v ) > fabs (rr .first ))

/∗ This case should never occur, I believe. [LDF 2002.11.05.] Why not?? ∗/ {

if ( ) {

  cout ≪  ␣  ␣       ␣       ␣      ␣     ␣       ␣ ≪  ␣  ≪
      ␣  ;

getchar ( ); } return −1;

} else {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪ flush; getchar ( ); if ( ) cout ≪ ␣ ; return −3;

} }

See also sections 995, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1009, and 1012. This code is used in section 1015.

994. Angle point. [LDF 2003.01.05.] TO DO: Find out why this function isn’t const! ⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡

virtual Point angle point (real angle);

§995  3DLDF-1.1.5.1  ANGLE POINT 277

995. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

Point Reg Cl Plane Curve ::angle point (real angle)

{

cerr ≪  ␣  ␣  ≪

        ␣       ␣        ␣       ␣    ␣ ␣     ␣          ␣   ␣ ≪

␣ ␣ ≪ flush;

return ; }

996. Intersection points. [LDF 2002.11.05.] Intersection with a line. intersection points ( ) returns a bool point pair. The bool in a bool point indicates whether the Point is on the line segment in question. If one of the bools is false, but the Point is not ≡ , then the line (as opposed to the segment) does intersect the Reg Cl Plane Curve, and the Point indicates one of the intersection points. So, intersection points ( ) can be used whether you want to restrict the intersection points to ones that are actually on a particular line segment or not.

TO DO: [LDF 2002.04.12.] In the specializations, I should check whether the intersection points are on the curve in question. I should also write a version of this for Lines, where there’s no test for whether the intersection points are on the segment, since there’s no segment.

The versions of intersection points ( ) belonging to classes derived from Reg Cl Plane Curve will most likely call on the functions described in this section, passing center as the ref pt argument. However, this need not be the case, and Reg Cl Plane Curves need not have a meaningful center . ref pt in these functions merely refers to the Point which should be placed at the origin by the transformation. [LDF 2003.07.16.]

997. Point arguments.

Log

[LDF 2003.06.20.] Rewrote this function. The perpendicular and non-parallel, non-coplanar cases are handled in exactly the same way. In these cases, there can only be one intersection point. Plane ::intersection point ( ) and Reg Cl Plane Curve ::location( ) are now used to find it, if it exists.

[LDF 2003.06.20.] The coplanar case was the one that was causing difficulty. The copy of ∗this is now always put into the x-z plane, even if it is in one of the major planes, or in a plane parallel to one of these. The advantage of this, is that it simplifies the code. The disadvantage is, that additional rotations reduce the accuracy of the calculation of the intersection points.

[LDF 2003.06.20.] Transform ::align with axis ( ) is no longer used for putting the copy of ∗this and the line into the x-z plane. It might be possible to use it, but I used Point ::angle( ) while debugging, in order to see what was happening better. It might be possible to go back to using Transform ::align with axis , but I don’t see any advantage to doing so.

[LDF 2003.06.20.] I’ve tested this function for coplanar lines for planes with various orientations. I hope that it works properly for all planes now!

[LDF 2003.07.01.] Added true as silent argument to unit vector ( ) when I call it on cross . This prevents unit vector ( ) from issuing a warning message, when cross has magnitude 0, which occurs when surface vector and pt vector are colinear. Since this case is handled correctly, the warning messages are unnecessary and distracting.

[LDF 2003.07.01.] BUG FIX: Made changes to the way on segment is used in the coplanar case. The way it was before handled certain cases wrong.

[LDF 2003.07.04.] Removed unreachable statement at end of function: return bpp. GCC didn’t complain, but the DEC compiler issued a warning.

[LDF 2003.07.16.] Changed name of center argument to ref pt , because I’ve made center a data member of Reg Cl Plane Curve.

⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡

278 POINT ARGUMENTS 3DLDF-1.1.5.1 §997

virtual bool point pair intersection points (Point ref pt , Point p0 , Point p1 ) const;

998. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

bool point pair Reg Cl Plane Curve ::intersection points (Point ref pt , Point pt0 , Point pt1 )

const{ bool = false; /∗ true ∗/ if ( )

cout ≪ ␣ ␣ ␣ ≪ ≪ flush; bool point pair bpp = ; Plane pl = get plane( ); if ( ) pl .normal .show ( ); Point surface vector = (get point (0) − ref pt ); surface vector .unit vector (true); Point pt vector (pt1 − pt0 ); pt vector .unit vector (true); Point cross = surface vector .cross product (pt vector ); cross .unit vector (true, true); if ( ) {

surface vector .show ( );

pt vector .show ( );

cross .show ( );

pl .normal .show ( ); } short distance = pl .get distance(pt0 ).second ;

999. Degenerate cases, error handling. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

if (pt vector ≡ ∨ pl .normal ≡ ∨ pt vector ≡ origin ∨ pl .normal ≡ origin) {

cerr ≪  ␣  ␣  ≪

  ␣  ␣     ␣     ␣   ␣  ;

pt vector .show ( ); pl .normal .show ( );

cerr ≪  ␣  ≪ flush;
if (  ) cout ≪  ␣  ≪ flush;

return ; }

1000. Parallel and coplanar cases. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

§1001  3DLDF-1.1.5.1  COPLANAR CASE 279

else if (surface vector ≡ pt vector ∨surface vector ≡ −pt vector ∨cross ≡ pl .normal ∨cross ≡ −pl .normal ) { 1001. Coplanar case. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

if (distance ≡ 0) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ; Transform t0 ; Reg Cl Plane Curve copy (∗this ); Point curve 0 = copy .get point (0); if ( ) {

cout ≪ ␣ ≪ endl ;

show ( );

copy .show ( );

curve 0 .show ( ); } t0 ∗= curve 0 ∗= pt0 ∗= pt1 ∗= copy .shift (−ref pt ); if ( ) {

cout ≪ ␣ ≪ endl ;

copy .show ( );

curve 0 .show ( );

pt0 .show ( );

pt1 .show ( ); } if (curve 0 .get x ( ) < 0) {

t0 ∗= curve 0 ∗= pt0 ∗= pt1 ∗= copy .rotate(0, 0, 180); } if ( ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ endl ;

copy .show ( );

curve 0 .show ( );

pt0 .show ( );

pt1 .show ( ); } Point trace x z 0 = curve 0 ; trace x z 0 .shift (0, −(curve 0 .get y ( ))); Point x axis pt (1); real ang = trace x z 0 .angle(x axis pt ); if ( ) {

cout ≪ ␣ ␣ ≪ ang ≪ endl ≪ flush; } if (ang ≠ 0) {

if (curve 0 .get z ( ) > 0) ang ∗= −1;

t0 ∗= curve 0 ∗= pt0 ∗= pt1 ∗= copy .rotate(0, ang ); } if ( ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ endl ; copy .show ( ); curve 0 .show ( ); pt0 .show ( ); pt1 .show ( );

280  COPLANAR CASE  3DLDF-1.1.5.1 §1001

} ang = curve 0 .angle(x axis pt ); if (ang ≠ 0) {

if (curve 0 .get y ( ) > 0) ang ∗= −1;

t0 ∗= curve 0 ∗= pt0 ∗= pt1 ∗= copy .rotate(0, 0, ang ); } if ( ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ endl ; copy .show ( ); pt0 .show ( ); pt1 .show ( );

} Point curve 4 = copy .get point (number of points /4); Point z axis pt (0, 0, 1); ang = curve 4 .angle(z axis pt ); if ( ) {

curve 4 .show ( );

cout ≪ ␣ ␣ ≪ ang ≪ endl ≪ flush; } if (ang ≠ 0) {

if (curve 4 .get y ( ) > 0) ang ∗= −1;

t0 ∗= curve 4 ∗= pt0 ∗= pt1 ∗= copy .rotate(ang ); } if ( ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ endl ; copy .show ( ); curve 4 .show ( ); pt0 .show ( ); pt1 .show ( );

} if ( ) {

copy .draw (Colors ::blue);

pt0 .draw (pt1 , Colors ::black , );

for (int i = 0; i < 16; i += 4) copy .get point (i).dotlabel (i); #if 0

pt0 .dotlabel ( );

pt1 .dotlabel ( );

copy .get center ( ).dotlabel ( ␣ ); #endif

draw axes ( ); } real pt0 h = pt0 .get x ( ); real pt0 v = pt0 .get z ( ); real pt1 h = pt1 .get x ( ); real pt1 v = pt1 .get z ( ); /∗ pt1 v isn’t used. Leaving it here, just in case. [LDF 2003.08.27.] ∗/ real Slope = pt1 .slope(pt0 , , ); if ( ) cout ≪ ␣ ␣ ≪ Slope ≪ endl ≪ flush; real pair rr ; /∗ BEGIN ∗/ 1002. Slope is 0 (line is horizontal). ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

if (Slope ≡ 0) /∗ v is known, h is unknown. ∗/ {

if ( ) {

cout ≪ ␣ ␣ ≪ endl ≪ flush; } rr = solve( , pt0 v ); if (rr .first ≠ ) {

bpp.first .pt .set (rr .first , 0, pt0 v ); } else bpp.first .pt = ; if (rr .second ≠ ) {

bpp.second .pt .set (rr .second , 0, pt0 v ); } else bpp.second .pt = ; if ( ) {

bpp.first .pt .show ( ); bpp.second .pt .show ( );

} } /∗ End Slope ≡ 0. ∗/

1003. Slope is undefined (line is vertical). ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

else

if (Slope ≡ ) {

if ( ) {

cout ≪ ␣ ␣ ; } rr = solve( , pt1 h); if (rr .first ≠ ) {

bpp.first .pt .set (pt0 h, 0, rr .first ); } else bpp.first .pt = ; if (rr .second ≠ ) {

bpp.second .pt .set (pt0 h, 0, rr .second ); } else bpp.second .pt = ;

}  /∗ End Slope ≡  . ∗/

1004. Slope ∈ real is defined and ≠ 0. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

else { real v intercept ; v intercept = pt0 v − (Slope ∗ pt0 h); if ( ) cout ≪ ␣ ␣ ≪ v intercept ≪ endl ≪ flush; real triple coeffs = get coefficients (Slope, v intercept ); /∗ New h-values. ∗/ if (is quadratic( )) {

if ( ) {

cout ≪ ␣ ≪ flush; } rr = solve quadratic(coeffs .first , coeffs .second , coeffs .third );

} else {

cout ≪ ␣ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪ flush; } real v coord ; if (rr .first ≠ ) {

v coord = (Slope ∗ rr .first ) + v intercept ;

bpp.first .pt .set (rr .first , 0, v coord ); } else bpp.first .pt = ; if (rr .second ≠ ) {

v coord = (Slope ∗ rr .second ) + v intercept ;

bpp.second .pt .set (rr .second , 0, v coord ); } else bpp.second .pt = ;

} 1005. Common code for the “coplanar” case. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

bool real on segment ; if (bpp.first .pt ≡ ) {

on segment .first = false;

on segment .second = ; } else on segment = bpp.first .pt .is on segment (pt0 , pt1 ); if ( ) {

cout ≪ ␣ ␣ ≪ on segment .first ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ on segment .second ≪ endl ≪ flush;

} if (on segment .first ≡ true) bpp.first .b = true; else bpp.first .b = false; Transform t inverse; t inverse = t0 .inverse( ); if (bpp.first .pt ≠ ) {

if ( ) cout ≪ ␣ ≪ flush;

bpp.first .pt ∗= t inverse; } else {

if ( ) cout ≪ ␣ ␣ ≪ flush; } if (bpp.second .pt ≡ ) {

on segment .first = false;

on segment .second = ; } else on segment = bpp.second .pt .is on segment (pt0 , pt1 ); if (on segment .first ≡ true) bpp.second .b = true; else bpp.second .b = false; if ( ) {

cout ≪ ␣ ␣ ≪ on segment .first ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ on segment .second ≪ endl ≪ flush;

} if (bpp.second .pt ≠ ) {

if ( ) cout ≪ ␣ ≪ flush; bpp.second .pt ∗= t inverse;

} else {

bpp.second .pt = ;

if ( ) cout ≪ ␣ ␣ ≪ flush; } if ( ) {

cout ≪ ␣ ␣ ≪ rr .first ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ rr .second ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ bpp.first .b ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ bpp.second .b ≪ endl ≪ flush;

bpp.first .pt .show ( );

bpp.second .pt .show ( ); } return bpp; } /∗ End of coplanar case. ∗/

284  PARALLEL CASE  3DLDF-1.1.5.1 §1006

1006. Parallel case. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

else {

cerr ≪  ␣  ␣  ≪

    ␣   ␣                  ␣   ␣  ␣        ␣  ≪

␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; return ;

} } /∗ End of parallel and coplanar cases. ∗/

1007. Perpendicular and non-coplanar cases. [LDF 2003.06.13.] These cases are handled in exactly the same way. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

else {

if (pl .normal ≡ pt vector ∨ pl .normal ≡ −pt vector ) {

if ( )

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ ≪ flush; } else {

if ( )

cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ ␣ ≪ flush; } bool point bp = pl .intersection point (pt0 , pt1 ); if ( ) {

bp.pt .show ( ); } short s = location(ref pt , bp.pt ); if ( ) cout ≪ ␣ ␣ ␣ ≪ s ≪ endl ≪ flush; if (s > −1) {

bpp.first .pt = bp.pt ;

bpp.first .b = bp.pt .is on segment (pt0 , pt1 ).first ;

if ( ) cout ≪ ␣ ␣ ␣ ≪ bpp.first .b ≪ endl ≪ flush; return bpp;

} else return ;

} /∗ End of “Perpendicular and non-coplanar cases”. ∗/ }

1008. Path arguments.

Log

[LDF 2003.06.20.] Added this function. [LDF 2003.07.16.] Changed name of center argument to ref pt , because I’ve made center a data member

of Reg Cl Plane Curve.

⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡ bool point pair intersection points (const Point &ref pt , const Path &p) const;

§1009  3DLDF-1.1.5.1  PATH ARGUMENTS 285

1009. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

bool point pair Reg Cl Plane Curve ::intersection points (const Point &ref pt , const Path &p)

const

{

if (¬p.is linear ( )) {

cerr ≪  ␣  ␣  ≪

          ␣        ␣ ␣  ␣           ␣ ≪  ␣  ≪

flush; return ;

}

return intersection points (ref pt , p.get point (0), p.get last point ( )); }

1010. Reg Cl Plane Curve segments. The functions in this section require that the Reg Cl Plane Curve have a meaningful center , in order to make it possible to rotate the segments.

[LDF 2003.07.16.]

Log

[LDF 2003.07.16.] Added this section and its subsections, including the declarations and definitions of segment ( ), half ( ), and quarter ( ). They were formerly members of Circle.

1011. Segment. [LDF 2002.11.10.] segment ( ) returns a subpath of the Reg Cl Plane Curve representing a segment of ∗this .

int factor Determines how large a segment of the Reg Cl Plane Curve is returned. factor must be > 1 and less than or equal to the number of points on the Reg Cl Plane Curve.

real angle Optional, with 0 as the default. Ifangle is ≠ 0, a Point is found in the direction of the normal to the Reg Cl Plane Curve from the center of the Reg Cl Plane Curve, and the segment is rotated around the center and this Point.

bool closed If true, the Path is made a “cycle” and the ends of the segment are joined by concatenating the curved Path with the straight line segment from its last to its first Point using the connector .

[LDF 2003.07.27.] TO DO: Make arguments const, if possible. angle can’t be, though. If factor ≡ number of points , return ∗this , cast to a Path, with warning.

Log

[LDF 2002.11.12.] Added “ ” after the arguments to “ ” in the TEX code above in order to suppress a space at the beginning of the first line of the following indented paragraph. I couldn’t figure out a way of suppressing the space within the definition of .

[LDF 2003.05.20.] Changed the way the last connector is set when closed ≡ true.

[LDF 2003.07.27.] Made const.

[LDF 2003.08.20.] BUG FIX: Added unsigned short subpath size. Changed the way the subpath is created, when closed is true. Now concatenating the curved subpath with the straight line segment from the last to the first Points of the subpath using .

⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡ Path segment (unsigned int factor , real angle = 0, bool closed = true) const;

286  SEGMENT  3DLDF-1.1.5.1 §1012

1012. ⟨ Define Reg Cl Plane Curve functions 993 ⟩ +≡

Path Reg Cl Plane Curve ::segment (unsigned int factor , real angle, bool closed ) const {

Path p; if (factor ≤ 1 ∨ factor > number of points ) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ factor ≪

      ␣     ␣  ;

return p; } if (fabs (angle) > 360) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ angle ≪ endl ≪ ␣ ␣ ␣ ≪ flush;

} unsigned short subpath size = (number of points /factor ) + 1; p = subpath(0, subpath size, false, ); for (unsigned short i = 1; i < subpath size − 1; ^{++}i) p += ; if (closed ) {

p += ;

p += p.get last point ( );

p += ;

p += p.get point (0);

p += ;

p.set cycle( ); } angle = fmod (angle, 360); if (angle ≠ 0) {

Point normal = get normal ( );

normal .shift (center );

p.rotate(center , normal , angle); } return p;

}

1013. Half. half ( ) creates a curve using half of the points in points starting from point 0. If the argument angle is not zero, the resulting Path is rotated by that amount about a line from center in the direction of the normal to the Reg Cl Plane Curve. If the argument closed is true, then the segment is closed and can be filled using fill ( ) or filldraw ( ). ⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡

inline Path half (real angle = 0, bool closed = true) const {

return segment (2, angle, closed ); }

1014. Quarter. quarter ( ) creates a curve using a quarter of the points in points starting from point 0. If the argument angle is not zero, the resulting Path is rotated by that amount about a line from center in the direction of the normal to the Reg Cl Plane Curve. If the argument closed is true, then the segment is closed and can be filled using fill ( ) or filldraw ( ).

§1014  3DLDF-1.1.5.1  QUARTER 287

⟨ Declare Reg Cl Plane Curve functions 987 ⟩ +≡ inline Path quarter (real angle = 0, bool closed = true) const {

return segment (4, angle, closed ); }

1015. Putting Reg Cl Plane Curve together.

This is what’s compiled. ⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Reg Cl Plane Curve 985 ⟩ ⟨ Define Reg Cl Plane Curve functions 993 ⟩

288  PUTTING REG CL PLANE CURVE TOGETHER  3DLDF-1.1.5.1 §1016

1016. This is what’s written to curves.h.

⟨ 1016 ⟩ ≡

⟨ Define class Reg Cl Plane Curve 985 ⟩

1017. Polygon (polygons.web).

Log

[LDF 2003.07.18.] Removed the transformation sections from Reg Polygon, and made them members of Polygon. Also, removed the Rectangle versions in rectangs.web.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

format Polygon Path

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1018. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include

1019. Polygon class definition. LDF Undated. Polygon is derived from Path. This makes sense, because a Polygon is really just a kind of Path. This way, we don’t have to define the drawing and filling functions, or the transformations.

[LDF 2003.06.06.] Polygon is meant to be used primarily as a base class for more specialized types of polygons. Currently, Reg Polygon and Rectangle are defined. I’ve added Polygon so that I can define intersection functions that will work for both Reg Polygon and Rectangle.

Log

[LDF 2003.06.06.] Added class Polygon.

⟨ Define class Polygon 1019 ⟩ ≡ class Polygon : public Path { protected: Point center ; public: ⟨ Declare Polygon functions 1022 ⟩ };

This code is used in sections 1097 and 1098.

§1020  3DLDF-1.1.5.1  RETURNING ELEMENTS AND INFORMATION 289

1020. Returning elements and information.

1021. Get center.

Log

[LDF 2003.07.18.] Moved these functions from Reg Polygon to Polygon. Also removed the Rectangle versions, since Rectangle inherits the Polygon versions.

1022. non-const version.

Log

[LDF 2002.04.24.] Added this function.

[LDF 2003.05.09.] Changed return value from Point & to const Point &.

⟨ Declare Polygon functions 1022 ⟩ ≡

virtual const Point &get center ( );

See also sections 1024, 1028, 1037, 1039, 1045, 1047, 1050, 1052, 1054, 1056, 1059, 1061, 1064, and 1066. This code is used in section 1019.

1023. ⟨ Define Polygon functions 1023 ⟩ ≡

const Point &Polygon ::get center ( )

{

if (points .size( ) ≡ 0) /∗ LDF 2002.09.27. Added this error handling code. If the Polygon is

empty, don’t return center . ∗/ {

cerr ≪  ␣  ␣  ≪  ␣       ␣

          ␣   ␣       ␣ ≪ ␣  ␣          ␣       ␣    ␣ ␣  ≪

␣ ≪ flush; return const cast⟨Point &⟩( );

}

center .apply transform( );

return center ; }

See also sections 1025, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1038, 1040, 1041, 1042, 1043, 1046, 1048, 1051, 1053,

1055, 1057, 1060, 1062, 1065, and 1067. This code is used in section 1097.

1024. const version. [LDF 2002.09.27.] Note that this version returns a Point whereas the non-const version returns a Point &. That’s because p is a local variable in this function and it would be an error to return a reference to it. [LDF 2002.04.24.] Added this function. ⟨ Declare Polygon functions 1022 ⟩ +≡

Point get center ( ) const;

290 CONST VERSION 3DLDF-1.1.5.1 §1025

1025. ⟨ Define Polygon functions 1023 ⟩ +≡

Point Polygon ::get center ( ) const

{

if (points .size( ) ≡ 0) /∗ LDF 2002.09.27. Added this error handling code. If the Polygon is

empty, don’t return center . ∗/ {

cerr ≪  ␣  ␣  ≪  ␣       ␣

          ␣   ␣       ␣ ≪ ␣  ␣          ␣       ␣    ␣ ␣  ≪

␣ ≪ flush; return const cast⟨Point &⟩( );

}

Point p(center ); p.apply transform( ); return p;

}

1026. Intersections.

1027. Intersection with a line. [LDF 2003.06.13.] A line can intersect with a Polygon at two points at most.

1028. Point version.

Log

[LDF 2003.06.13.] Added this function.

[LDF 2003.06.17.] Minor change. Now using get point (0) and center instead of get point (0) and get last point ( ) to generate surface vector .

⟨ Declare Polygon functions 1022 ⟩ +≡ bool point pair intersection points (const Point &pt0 , const Point &pt1 ) const; 1029. ⟨ Define Polygon functions 1023 ⟩ +≡

bool point pair Polygon ::intersection points (const Point &pt0 , const Point &pt1 ) const{ bool

= false; /∗ true ∗/ if ( ) cout ≪ ␣ ≪ flush; = false; bool point pair bpp = ; /∗ The return value. [LDF 2003.06.13.] ∗/ Plane pl = get plane( ); Point pt vector (pt1 − pt0 ); Point surface vector (get point (0) − center ); if ( ) {

pl .point .show ( );

pl .normal .show ( );

pt0 .show ( );

pt1 .show ( );

pt vector .show ( );

surface vector .show ( ); } Point cross = surface vector .cross product (pt vector ); cross .unit vector (true); if ( ) {

cross .show ( );

pl .normal .show ( ); } short distance = pl .get distance(pt0 ).second ;

1030. Degenerate cases, error handling. ⟨ Define Polygon functions 1023 ⟩ +≡

if (pt vector ≡ ∨ pl .normal ≡ ∨ pt vector ≡ origin ∨ pl .normal ≡ origin) {

cerr ≪  ␣  ␣  ≪

  ␣  ␣     ␣     ␣   ␣  ;

pt vector .show ( ); pl .normal .show ( );

cerr ≪  ␣  ≪ flush;
if (  ) cout ≪  ␣  ≪ flush;

return ; }

1031. Parallel and coplanar cases.

Log

[LDF 2003.06.20.] Now checking surface vector against pt vector in the following conditional.

⟨ Define Polygon functions 1023 ⟩ +≡

else if (surface vector ≡ pt vector ∨surface vector ≡ −pt vector ∨cross ≡ pl .normal ∨cross ≡ −pl .normal ) { 1032. Coplanar case. [LDF 2003.06.13.] Only those intersection points that are on the line segments making of the Polygon are returned in bpp. If an intersection Point lies on both segments, the bool part of the bool point will be true, otherwise false. If a Point lies on a line segment belonging to the Polygon, but not to the line segment \overrightarrow{pt_{0}pt_{1}}, the Point will be put into the bool point, but the bool will be false. The reason for this is, that the angles of the sides of the Polygon can cause intersection points to be found, that the user probably won’t want. ⟨ Define Polygon functions 1023 ⟩ +≡

if (distance ≡ 0) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ; bool found = false; bool point bp; Point q0 ; Point q1 ; if ( ) show ( ); for (vector⟨Point ∗⟩::const iterator iter = points .begin( ); iter ≠ points .end ( ); ^{++}iter ) {

if ((iter + 1) ≡ points .end ( )) { if ( ) cout ≪ ␣ ␣ ; q0 = ∗(points .back ( )); q1 = ∗(points .front ( ));

} else {

if ( ) cout ≪ ␣ ␣ ; q0 = ∗∗iter ; q1 = ∗∗(iter + 1);

} bp = Point ::intersection point (pt0 , pt1 , q0 , q1 ); if (bp.b) /∗ Intersection point is on both segments. ∗/ {

if (¬found ) { bpp.first .b = true; bpp.first .pt = bp.pt ; found = true; if ( ) cout ≪ ␣ ␣ ;

} else {

bpp.second .b = true; bpp.second .pt = bp.pt ; if ( ) cout ≪ ␣ ␣ ␣ ; return bpp;

} } else if (bp.pt ≠ ∧ bp.pt .is on segment (q0 , q1 ).first ) {

if (¬found ) { bpp.first .b = false; bpp.first .pt = bp.pt ; found = true; if ( ) cout ≪ ␣ ␣ ;

} else {

bpp.second .b = false; bpp.second .pt = bp.pt ;

if (  ) cout ≪  ␣      ␣             ␣  ;

return bpp; }

}

else continue; } /∗ for ∗/ return bpp;

} /∗ End of coplanar case. ∗/

1033. Parallel case. ⟨ Define Polygon functions 1023 ⟩ +≡

else {

cerr ≪  ␣  ␣  ≪

    ␣   ␣       ␣    ␣  ␣        ␣  ≪

␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; return ;

} } /∗ End of parallel and coplanar cases. ∗/

294  PERPENDICULAR AND NON-COPLANAR CASES  3DLDF-1.1.5.1 §1034

1034. Perpendicular and non-coplanar cases. [LDF 2003.06.13.] These cases are handled in exactly the same way. ⟨ Define Polygon functions 1023 ⟩ +≡

else { if (pl .normal ≡ pt vector ∨ pl .normal ≡ −pt vector ) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; } else {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; } bool point bp = pl .intersection point (pt0 , pt1 ); if ( ) {

bp.pt .show ( ); } if (bp.pt ≡ center ) {

if ( ) {

cout ≪ ␣ ␣ ≪ endl ≪ flush; } bpp.first .pt = bp.pt ; bpp.first .b = bp.pt .is on segment (pt0 , pt1 ).first ; return bpp;

} Point r0 ; Point r1 ; if ( ) {

show ( ); center .show ( ); cout ≪ ␣ ␣ ≪ points .size( ) ≪ endl ≪ flush;

} for (vector⟨Point ∗⟩::const iterator iter = points .begin( ); iter ≠ points .end ( ); ^{++}iter ) { if ((iter + 1) ≡ points .end ( )) {

r0 = ∗(points .back ( )); r1 = ∗(points .front ( )); if ( ) {

r0 .show ( );

r1 .show ( ); }

} else {

r0 = ∗∗iter ; r1 = ∗∗(iter + 1);

} if (bp.pt ≡ r0 ∨ bp.pt ≡ r1 ) {

if ( ) {

if (bp.pt ≡ r0 ) cout ≪  ␣  ␣  ≪ endl ≪ flush;
else if (bp.pt ≡ r1 ) cout ≪  ␣  ␣  ≪ endl ≪ flush;

} bpp.first .pt = bp.pt ; bpp.first .b = bp.pt .is on segment (pt0 , pt1 ).first ; return bpp;

}

§1035  3DLDF-1.1.5.1  PERPENDICULAR AND NON-COPLANAR CASES 295

1035. [LDF 2003.06.24.] is passed as the verbose argument to is in triangle( ). So, if intersection points ( ) is being debugged, is in triangle( ) will print more information. However, in is in triangle( ) will not be set to true. ⟨ Define Polygon functions 1023 ⟩ +≡

else

if (bp.pt .is in triangle(center , r0 , r1 , )) { if ( ) cout ≪ ␣ ␣ ␣ ␣ ; bpp.first .pt = bp.pt ; bpp.first .b = bp.pt .is on segment (pt0 , pt1 ).first ; return bpp;

} } } /∗ End of “Perpendicular and non-coplanar cases”. ∗/

1036. End of definition. ⟨ Define Polygon functions 1023 ⟩ +≡

if ( ) cout ≪ ␣ ≪ flush;

return bpp; }

1037. Path version. ⟨ Declare Polygon functions 1022 ⟩ +≡

bool point pair intersection points (const Path &p) const;

1038. ⟨ Define Polygon functions 1023 ⟩ +≡

bool point pair Polygon ::intersection points (const Path &p) const

{

if (¬p.is linear ( )) {

cerr ≪  ␣  ␣                                  ␣     ␣  ≪

          ␣ ␣  ␣           ␣␣         ␣  ≪ flush;

return ; } return intersection points (p.get point (0), p.get last point ( ));

}

1039. Intersection with another Polygon. TO DO: Explain what this function does and how it works. [LDF 2003.06.29.]

TO DO: Find out where unit vector ( ) gets called, when this function is called, and try to pass true as its silent argument. [LDF 2003.07.16.]

Log

[LDF 2003.06.29.] Replaced the dummy definition of this function with a real one.

⟨ Declare Polygon functions 1022 ⟩ +≡ vector⟨Point⟩ intersection points (const Polygon &r) const;

296  INTERSECTION WITH ANOTHER POLYGON  3DLDF-1.1.5.1 §1040

1040. ⟨ Define Polygon functions 1023 ⟩ +≡

vector⟨Point⟩ Polygon ::intersection points (const Polygon &r) const{ bool = false;

/∗ true ∗/ vector⟨Point⟩ v; Plane pl = get plane( ); Plane r pl = r.get plane( ); if ( ) {

pl .normal .show ( );

r pl .normal .show ( );

cout ≪ ␣ ␣ ≪ pl .distance ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ r pl .distance ≪ endl ≪ flush; } real distance = fabs (fabs (pl .distance) − fabs (r pl .distance)); if (distance < Point ::epsilon( )) distance = 0; if ( ) cout ≪ ␣ ␣ ≪ distance ≪ endl ≪ flush; if (pl .normal ≡ r pl .normal ) {

1041. Coplanar case. ⟨ Define Polygon functions 1023 ⟩ +≡

if (distance ≡ 0) { if ( ) cout ≪ ; bool point bp; Point ∗ptr ; Point ∗r ptr ; for (vector⟨Point ∗⟩::const iterator iter = points .begin( ); iter ≠ points .end ( ); ^{++}iter ) {

if ((iter + 1) ≡ points .end ( )) ptr = points .front ( ); else ptr = ∗(iter + 1); for (vector⟨Point ∗⟩::const iterator r iter = r.points .begin( ); r iter ≠ r.points .end ( ); ^{++}r iter ) {

if ((r iter + 1) ≡ r.points .end ( )) r ptr = r.points .front ( );

else r ptr = ∗(r iter + 1);

bp = Point ::intersection point (∗∗iter , ∗ptr , ∗∗r iter , ∗r ptr );

if (bp.b) v.push back (bp.pt ); } /∗ Inner for ∗/

} /∗ Outer for ∗/ return v;

}

1042. Parallel case. ⟨ Define Polygon functions 1023 ⟩ +≡

else /∗ Parallel. ∗/ {

cerr ≪  ␣␣  ␣  ≪

  ␣        ␣   ␣   ␣        ␣       ␣ ≪  ␣     ␣  ≪

flush; return v;

} }

§1043  3DLDF-1.1.5.1  NON-PARALLEL, NON-COPLANAR CASE 297

1043. Non-parallel, non-coplanar case. v will contain the intersection points of the Line l with ∗this and r, if any. v can contain a maximum of four Points in this case. v[0] and v[1] will be the intersection points of the Line l with ∗this , and v[2] and v[3] the intersection points of l and r, if they exist. If any intersection point doesn’t exist, will be stored in the corresponding element of v as a placeholder. [LDF 2003.06.29.]

The values in v provide information about the relative positions of the Polygons , e.g., whether they touch, whether lies within the perimeter of the other, etc. However, it’s not possible to include this information in the return value, since the latter is merely a vector⟨Point⟩. The routine below may need to be put into another function in order to use this information. It may be of importance in breaking up Polygons and Solids for an improved surface hiding routine. [LDF 2003.06.29.] ⟨ Define Polygon functions 1023 ⟩ +≡

else { if ( ) cout ≪ ␣ ; Line l = pl .intersection line(r pl ); bool point pair bpp = intersection points (l.position, (l.position + l.direction)); v.push back (bpp.first .pt ); if (bpp.first .pt ≡ bpp.second .pt ) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ; v.push back ( );

} else v.push back (bpp.second .pt ); bpp = r.intersection points (l.position, (l.position + l.direction)); v.push back (bpp.first .pt ); if (bpp.first .pt ≡ bpp.second .pt ) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ; v.push back ( );

} else v.push back (bpp.second .pt ); if (¬(v[0] ≠ ∨ v[1] ≠ ∨ v[2] ≠ ∨ v[3] ≠ ))

{

if ( )

    cout ≪ ␣           ␣       ␣      ␣␣ ≪  ␣     ␣  ≪

flush; v.clear ( ); return v;

} bool real br [4]; if (¬(v[2] ≡ ∨ v[3] ≡ )) {

if (v[0] ≠ ) br [0] = v[0].is on segment (v[2], v[3]);

else { br [0].first = false; br [0].second = 0;

}

if (v[1] ≠ ) br [1] = v[1].is on segment (v[2], v[3]);

else { br [1].first = false; br [1].second = 0;

} } if (¬(v[0] ≡ ∨ v[1] ≡ )) {

if (v[2] ≠ ) br [2] = v[2].is on segment (v[0], v[1]);

298  NON-PARALLEL, NON-COPLANAR CASE  3DLDF-1.1.5.1 §1043

else { br [2].first = false; br [2].second = 0;

}

if (v[3] ≠ ) br [3] = v[3].is on segment (v[0], v[1]);

else { br [3].first = false; br [3].second = 0;

} } if (br [0].first ∧ br [1].first ) {

if (  ) cout ≪  ␣           ␣   ␣     ␣    ␣ ␣    ␣      ␣ ≪

        ␣           ␣   ␣ ␣    ␣  ;

} else if (br [2].first ∧ br [3].first ) {

if (  ) cout ≪  ␣           ␣   ␣ ␣    ␣ ␣    ␣      ␣ ≪

        ␣           ␣   ␣     ␣    ␣  ;

} else if (br [0].first ∨ br [1].first ∨ br [2].first ∨ br [3].first ) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; } else {

  if (  ) cout ≪  ␣            ␣   ␣     ␣   ␣ ␣    ␣  ␣     ␣       ␣  ␣  ;

} return v;

} /∗ else. End of non-parallel, non-coplanar case. ∗/ }

1044. Transformations.

Log

[LDF 2002.08.07.] Copied the entire “Transformations” section from ellipses.web and made the appropriate changes.

[LDF 2003.04.27.] The previous comment was out-of-date. I may have removed the transformation functions. At any rate, there were only a couple here. I have now copied the rest of them from ellipses.web and made the appropriate changes.

[LDF 2003.07.18.] [LDF 2003.07.18.] Moved “Transformations” section, including operator∗=(const Transform &) from Reg Polygon to Polygon. Also removed the Rectangle versions in rectangs.web. The Polygon versions are now inherited by Reg Polygon and Rectangle.

1045. Applying a transformation.

Log

[LDF 2002.11.06.] Now calling Path ::operator∗=( ) instead of looping through points . This way, if I change Path ::operator∗=( ), the change will automatically be reflected here.

⟨ Declare Polygon functions 1022 ⟩ +≡ virtual Transform operator∗=(const Transform &t);

§1046  3DLDF-1.1.5.1  APPLYING A TRANSFORMATION 299

1046. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::operator∗=(const Transform &t)

{ Path ::operator∗=(t); return (center ∗= t);

}

1047. Rotatation around the main axes. ⟨ Declare Polygon functions 1022 ⟩ +≡

virtual Transform rotate(const real x, const real y = 0, const real z = 0);

1048. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::rotate(const real x, const real y, const real z)

{ Transform t; t.rotate(x, y, z); return (∗this ∗= t);

}

1049. Rotate around an arbitrary axis.

1050. Point arguments.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Polygon functions 1022 ⟩ +≡ virtual Transform rotate(const Point &p0 , const Point &p1 , const real angle = 180);

1051. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::rotate(const Point &p0 , const Point &p1 , const real angle)

{ Transform t; t.rotate(p0 , p1 , angle); return (∗this ∗= t);

}

1052. Path argument.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Polygon functions 1022 ⟩ +≡ virtual Transform rotate(const Path &p, const real angle = 180); 1053. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::rotate(const Path &p, const real angle)

{

if (¬p.is linear ( )) {

cerr ≪  ␣  ␣                     ␣  ≪

          ␣  ␣   ␣ ␣      ␣␣         ␣  ;

return ; } return rotate(p.get point (0), p.get last point ( ), angle);

}

1054. Scale. ⟨ Declare Polygon functions 1022 ⟩ +≡

virtual Transform scale(real x, real y = 1, real z = 1);

1055. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::scale(real x, real y, real z)

{ Transform t; t.scale(x, y, z); return (∗this ∗= t);

}

1056. Shear. ⟨ Declare Polygon functions 1022 ⟩ +≡

virtual Transform shear (real xy , real xz = 0, real yx = 0, real yz = 0, real zx = 0, real zy = 0);

1057. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::shear (real xy , real xz , real yx , real yz , real zx , real zy )

{ Transform t; t.shear (xy , xz , yx , yz , zx , zy ); return (∗this ∗= t);

}

1058. Shift.

1059. real arguments. ⟨ Declare Polygon functions 1022 ⟩ +≡

virtual Transform shift (real x, real y = 0, real z = 0);

§1060  3DLDF-1.1.5.1  REAL ARGUMENTS 301

1060. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::shift (real x, real y, real z)

{ Transform t; t.shift (x, y, z); return (∗this ∗= t);

}

1061. Point argument. ⟨ Declare Polygon functions 1022 ⟩ +≡

virtual Transform shift (const Point &p);

1062. ⟨ Define Polygon functions 1023 ⟩ +≡

Transform Polygon ::shift (const Point &p)

{

return shift (p.get x ( ), p.get y ( ), p.get z ( )); }

1063. Shift times.

1064. real arguments. ⟨ Declare Polygon functions 1022 ⟩ +≡

virtual void shift times (real x, real y = 1, real z = 1);

1065. ⟨ Define Polygon functions 1023 ⟩ +≡

void Polygon ::shift times (real x, real y, real z)

{ Path ::shift times (x, y, z); center .shift times (x, y, z); return;

}

1066. Point argument. ⟨ Declare Polygon functions 1022 ⟩ +≡

302 POINT ARGUMENT 3DLDF-1.1.5.1 §1067

virtual void shift times (const Point &p); 1067. ⟨ Define Polygon functions 1023 ⟩ +≡

void Polygon ::shift times (const Point &p)

{

return shift times (p.get x ( ), p.get y ( ), p.get z ( )); }

1068. Reg Polygon (polygons.web). [LDF 2003.04.15.] TO DO: It will be necessary to supply Reg Polygon with a complete set of transformation functions, so that center will be transformed along with the Points pointed to by the pointers on points . Some are present already, but not all.

[LDF 2003.04.15.] TO DO: Add in circle( ), out circle( ). Align a line from center in the direction of a normal with the y-axis. Use the inverse of the Transform to transform the Circle.

format Reg Polygon Polygon

1069. Reg Polygon class definition. Reg Polygon is derived from Polygon.

Log

[LDF 2003.04.15.] Changed, so that Reg Polygon is derived from Path. Previously, it was derived from Reg Cl Plane Curve.

[LDF 2003.04.27.] Changed protected data members to private. They no longer need to be protected, because Rectangle is no longer derived from Reg Polygon.

[LDF 2003.06.06.] Changed, so that Reg Polygon is derived from Polygon, which I’ve just added above.

⟨ Define class Reg Polygon 1069 ⟩ ≡

class Reg Polygon : public Polygon { real internal angle; real radius ; unsigned short sides ; bool on free store;

public: ⟨ Declare Reg Polygon functions 1070 ⟩

};

This code is used in sections 1097 and 1098.

1070. Assignment.

Log

[LDF 2002.12.18.] Moved here. With the DEC compiler under Compaq Tru64 on the DEC Alpha computer, it worked to have the assignment operators following the constructors. With the GNU C^{++} compiler (GCC) under GNU/Linux on the Intel i686 computer, it didn’t. See Path ::operator=( ) in paths.web for more information.

⟨ Declare Reg Polygon functions 1070 ⟩ ≡

const Reg Polygon &operator=(const Reg Polygon &p);

See also sections 1073, 1076, 1079, 1087, 1089, 1091, 1092, 1093, 1095, and 1096. This code is used in section 1069.

1071. ⟨ Define Reg Polygon functions 1071 ⟩ ≡

const Reg Polygon &Reg Polygon ::operator=(const Reg Polygon &p) {

clear ( ); Path ::operator=(p); internal angle = p.internal angle; radius = p.radius ; sides = p.sides ; center = p.center ; return ∗this ;

}

See also sections 1074, 1077, 1078, 1080, 1081, 1307, 1309, 1310, 1311, 1313, and 1314. This code is used in sections 1097 and 1315.

1072. Constructors and setting functions.

1073. Default constructor. No arguments. ⟨ Declare Reg Polygon functions 1070 ⟩ +≡

Reg Polygon( );

1074. ⟨ Define Reg Polygon functions 1071 ⟩ +≡

Reg Polygon ::Reg Polygon( ) {

on free store = false; line switch = false; cycle switch = true; projective extremes .resize(6, 0); /∗ LDF 2003.04.09. Added this line. ∗/

}

1075. Center, sides, diameter, and angles.

1076. Constructor. ⟨ Declare Reg Polygon functions 1070 ⟩ +≡

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); 1077.

Log

[LDF 2003.08.27.] Reversed the order of the initializations following “:”, because GCC with the “--Wall” option issued the following warning: “‘Reg Polygon ::sides ’ will be initialized after ‘real Reg Polygon ::radius ’”.

⟨ Define Reg Polygon functions 1071 ⟩ +≡

Reg Polygon ::Reg Polygon(const Point &ccenter , const unsigned short ssides , const real ddiameter , const real angle x , const real angle y , const real angle z ): radius (ddiameter /2),

sides (ssides ) { bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣                          ␣ ≪

␣ ␣ ␣ ≪ flush; center = ccenter , on free store = false; internal angle = 360.0/sides ; cycle switch = true; projective extremes .resize(6, 0); /∗ LDF 2003.04.09. Added this line. ∗/ center .apply transform( );

1078. For regular polygons with an even number of sides, we rotate them so that a flat side is at the “top” (in the direction of the positive z-axis, if angle x , angle y , and angle z are all 0). ⟨ Define Reg Polygon functions 1071 ⟩ +≡

for (int i = 0; i < sides ; i^{++}) { Point ∗vertex = create new < Point > (0); vertex set (0, 0, radius ); if (sides % 2 ≡ 0) vertex rotate(0, internal angle/2, 0); if (i > 0) /∗ [LDF 2002.11.06.] Only rotate if the angle ≠ 0, i.e., don’t rotate the first time. ∗/

vertex rotate(0, i ∗ internal angle, 0); 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 ); } if ( )

cout ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪

flush; return; }

1079. Setting function. ⟨ Declare Reg Polygon functions 1070 ⟩ +≡

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);

1080. ?? [LDF 2002.10.07.] See below. ⟨ Define Reg Polygon functions 1071 ⟩ +≡

void Reg Polygon ::set (const Point &ccenter , const unsigned short ssides , const real

ddiameter , const real angle x , const real angle y , const real angle z ){ bool = false; /∗ true ∗/ if ( )

cout ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪ flush; 1081. ?? [LDF 2002.10.07.] At exactly this place, Path ::Path( ) (the default version with no arguments) is invoked. When set ( ) exits, ∼Path( ) is called on the empty Path. When ≡ true, the following message is printed before ∼Path( ) is entered. I don’t know why Path( ) is invoked and this bothers me a bit. However, it’s destroyed cleanly, so I don’t have to worry about leakage. ⟨ Define Reg Polygon functions 1071 ⟩ +≡

Reg Polygon p(ccenter , ssides , ddiameter , angle x , angle y , angle z );

∗this = p;

if ( )

cout ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪ flush; return; }

1082. Pseudo-constructor for dynamic allocation.

1083. Pointer argument.

Log

[LDF 2002.11.06.] Added optional Reg Polygon pointer argument. Made non-inline.

[LDF 2003.12.30.] Replaced Reg Polygon ::create new reg polygon( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Reg Polygon.

⟨ Declare non-member template functions for Reg Polygon 1083 ⟩ ≡

Reg Polygon ∗create new (const Reg Polygon ∗r);

See also section 1084. This code is used in sections 1097 and 1098.

1084. Reference argument.

Log

[LDF 2002.11.06.] Added this function.

[LDF 2003.12.30.] Replaced Reg Polygon ::create new reg polygon( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Reg Polygon.

⟨ Declare non-member template functions for Reg Polygon 1083 ⟩ +≡ Reg Polygon ∗create new (const Reg Polygon &r);

1085. Destructor. [LDF 2002.10.09.] Removed the destructor. Path ::∼Path( ) or Path ::clear ( ) should be used instead, unless I add dynamically allocated data members to Reg Polygon (rather than Path).

1086. Returning elements and information.

Log

[LDF 2002.11.03.] Removed Reg Polygon ::is planar ( ). A Reg Polygon can be manipulated into a non-planar state, so it’s safer to use the Path version, which tests whether it’s really planar or not.

1087. Get radius.

Log

[LDF 2003.06.13.] Added this function.

306  GET RADIUS  3DLDF-1.1.5.1 §1087

⟨ Declare Reg Polygon functions 1070 ⟩ +≡ inline real get radius ( ) const {

return radius ; }

1088. Circles. [LDF 2003.06.13.] The functions in this section are all defined in circles.web, because Circle is an incomplete type in this file.

Log

[LDF 2003.06.13.] Added this section.

1089. Enclosed circle.

Log

[LDF 2003.06.13.] Added this function.

⟨ Declare Reg Polygon functions 1070 ⟩ +≡ Circle in circle( ) const;

1090. Draw enclosed circle.

1091. Normal version. ⟨ Declare Reg Polygon functions 1070 ⟩ +≡

Circle draw in circle(const Color &ddraw color = ∗Colors ::default color , const string ddashed = , const string ppen = , Picture &picture = current picture) const;

1092. Picture argument first.

Log

[LDF 2003.07.04.] Removed default argument for picture. Having one made it impossible for the compiler to resove calls to draw in circle( ) with no arguments.

⟨ Declare Reg Polygon functions 1070 ⟩ +≡

Circle draw in circle(Picture &picture, const Color &ddraw color = ∗Colors ::default color , const string ddashed = , const string ppen = ) const;

1093. Surrounding circle. ⟨ Declare Reg Polygon functions 1070 ⟩ +≡

Circle out circle( ) const;

1094. Draw surrounding circle.

1095. Normal version. ⟨ Declare Reg Polygon functions 1070 ⟩ +≡

Circle draw out circle(const Color &ddraw color = ∗Colors ::default color , const string ddashed = , const string ppen = , Picture &picture = current picture) const; 1096. Picture argument first.

Log

[LDF 2003.07.04.] Removed default argument for picture. Having one made it impossible for the compiler to resove calls to draw out circle( ) with no arguments.

⟨ Declare Reg Polygon functions 1070 ⟩ +≡

Circle draw out circle(Picture &picture, const Color &ddraw color = ∗Colors ::default color , const string ddashed = , const string ppen = ) const;

1097. Putting polygons together. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Polygon 1019 ⟩ ⟨ Define class Reg Polygon 1069 ⟩ ⟨ Define Reg Polygon functions 1071 ⟩ ⟨ Define Polygon functions 1023 ⟩ ⟨ Declare non-member template functions for Reg Polygon 1083 ⟩

308  PUTTING POLYGONS TOGETHER  3DLDF-1.1.5.1 §1098

1098. This is what’s written to polygons.h.

⟨ 1098 ⟩ ≡

⟨ Define class Polygon 1019 ⟩

⟨ Define class Reg Polygon 1069 ⟩

⟨ Declare non-member template functions for Reg Polygon 1083 ⟩

1099. Rectangle (rectangles.web).

Log

[LDF 2003.07.18.] Removed the “Transformations” section, including operator∗=(const Transform &). Also moved the Reg Polygon versions to Polygon in polygons.web. These are now inherited by Rectangle.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

format Rectangle Reg Polygon

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1100. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1101. Rectangle class definition. [LDF 2003.07.18.] TO DO: axis h and axis v are not recalculated when a Rectangle is transformed. I should do something about this. ⟨ Define class Rectangle 1101 ⟩ ≡

class Rectangle : public Polygon { real axis h; real axis v ; bool on free store;

public: ⟨ Declare Rectangle functions 1103 ⟩

};

This code is used in sections 1139 and 1140.

1102. Constructors and setting functions.

1103. Default constructor. No arguments. ⟨ Declare Rectangle functions 1103 ⟩ ≡

Rectangle( );

See also sections 1106, 1108, 1111, 1113, 1119, 1122, 1125, 1127, 1130, 1132, 1135, 1136, 1137, and 1138. This code is used in section 1101.

1104. ⟨ Define Rectangle functions 1104 ⟩ ≡

Rectangle ::Rectangle( )

{ on free store = false; line switch = false; cycle switch = true;

}

See also sections 1107, 1109, 1112, 1114, 1120, 1123, 1126, 1128, 1131, 1133, 1267, 1268, 1269, and 1270. This code is used in sections 1139 and 1271.

1105. Center, lengths, and angles. [LDF 2002.11.06.] The following constructor and setting function create the Rectangle in the x-z plane and then rotate according to the arguments angle x , angle y , and angle z , if at least one of them is non-zero.

1106. Constructor.

Log

[LDF 2002.11.06.] Made real arguments const.

[LDF 2003.07.18.] BUG FIX: Now, axis h and axis v are no longer divided by 2, when I initialize axis h half and axis v half . I mistakenly used /= instead of /.

⟨ Declare Rectangle functions 1103 ⟩ +≡

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); 1107. ⟨ Define Rectangle functions 1104 ⟩ +≡

Rectangle ::Rectangle(const Point &ccenter , const real aaxis h, const real aaxis v , const real angle x , const real angle y , const real angle z ): axis h(aaxis h), axis v (aaxis v ) { on free store = false;

line switch = false; cycle switch = true; center = ccenter ; center .apply transform( ); real axis h half = axis h/2; real axis v half = axis v /2; Point bot lft (−axis h half , 0, −axis v half ); Point bot rt (axis h half , 0, −axis v half ); Point top lft (−axis h half , 0, axis v half ); Point top rt (axis h half , 0, axis v half ); 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 ); bot rt .rotate(angle x , angle y , angle z ); top lft .rotate(angle x , angle y , angle z ); top rt .rotate(angle x , angle y , angle z );

} /∗ Put around center . ∗/ bot lft .shift (center ); bot rt .shift (center ); top lft .shift (center ); top rt .shift (center ); for (int i = 0; i < 4; i^{++}) points .push back ( create new < Point > (0) ) ; ∗points [0] = bot lft ; ∗points [1] = bot rt ; ∗points [2] = top rt ; ∗points [3] = top lft ; }

1108. Setting function.

Log

[LDF 2002.11.06.] Made real arguments const.

⟨ Declare Rectangle functions 1103 ⟩ +≡

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);

1109. ⟨ Define Rectangle functions 1104 ⟩ +≡

void Rectangle ::set (const Point &ccenter , const real aaxis h, const real aaxis v , const real

angle x , const real angle y , const real angle z )

{ Rectangle r(ccenter , aaxis h, aaxis v , angle x , angle y , angle z ); ∗this = r;

}

1110. Four Points. The Point arguments must be so ordered, that they are contiguous in the resulting Rectangle.

1111. Constructor. ⟨ Declare Rectangle functions 1103 ⟩ +≡

Rectangle(const Point &pt0 , const Point &pt1 , const Point &pt2 , const Point &pt3 );

1112. ⟨ Define Rectangle functions 1104 ⟩ +≡

Rectangle ::Rectangle(const Point &pt0 , const Point &pt1 , const Point &pt2 , const Point

&pt3 ){ Point pt4 = pt1 − pt0 ; /∗ Check that the Point arguments are coplanar. ∗/ Point pt5 = pt2 − pt0 ; Point pt6 = pt3 − pt0 ; Point pt7 = pt4 .cross product (pt5 ); pt7 .unit vector (true); Point pt8 = pt4 .cross product (pt6 ); pt8 .unit vector (true); if (pt7 ≡ pt8 ∨ pt7 ≡ −pt8 ) /∗ If they are, create a Rectangle. ∗/ { on free store = false; line switch = false; cycle switch = true; center = pt0 .mediate(pt2 ); axis h = (pt1 − pt0 ).magnitude( ); axis v = (pt2 − pt1 ).magnitude( ); points .push back ( create new < Point > (pt0 ) ) ;

points .push back ( create new < Point > (pt1 ) ) ; points .push back ( create new < Point > (pt2 ) ) ; points .push back ( create new < Point > (pt3 ) ) ;

connectors .push back ( ); } else {

  cerr ≪  ␣  ␣           ␣    ␣    ␣     ␣  ≪

␣ ␣ ␣ ␣␣ ≪ flush; } return; }

1113. Setting function. ⟨ Declare Rectangle functions 1103 ⟩ +≡

void set (const Point &pt0 , const Point &pt1 , const Point &pt2 , const Point &pt3 ); 1114. ⟨ Define Rectangle functions 1104 ⟩ +≡

void Rectangle ::set (const Point &pt0 , const Point &pt1 , const Point &pt2 , const Point &pt3 ) {

Rectangle r(pt0 , pt1 , pt2 , pt3 ); ∗this = r;

}

1115. Pseudo-constructor for dynamic allocation.

1116. Pointer argument.

Log

[LDF 2003.12.30.] Replaced Rectangle ::create new rectangle( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Rectangle.

⟨ Declare non-member template functions for Rectangle 1116 ⟩ ≡

Rectangle ∗create new (const Rectangle ∗c);

See also section 1117. This code is used in sections 1139 and 1140.

1117. Reference argument.

Log

[LDF 2003.12.30.] Replaced Rectangle ::create new rectangle( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Rectangle.

⟨ Declare non-member template functions for Rectangle 1116 ⟩ +≡ Rectangle ∗create new (const Rectangle &c);

1118. Destructor. [LDF 2002.10.09.] Removed the destructor. Path ::∼Path( ) or Path ::clear ( ) should be used instead, unless I add dynamically allocated data members to Rectangle (rather than Reg Polygon or Path).

1119. Assignment.

Log

[LDF 2002.11.06.] Changed return value from void to const Rectangle &.

⟨ Declare Rectangle functions 1103 ⟩ +≡ const Rectangle &operator=(const Rectangle &c); 1120. !! Remember to put anything specific to Rectangles in here! ⟨ Define Rectangle functions 1104 ⟩ +≡

const Rectangle &Rectangle ::operator=(const Rectangle &c)

{ clear ( ); Path ::operator=(c); center = c.center ; axis h = c.axis h; axis v = c.axis v ; return ∗this ;

}

1121. Returning Elements and information.

Log

[LDF 2003.04.15.] Added this section. It’s become necessary, since I’m deriving Rectangle from Path now, and not from Reg Polygon.

1122. Is rectangular. is rectangular ( ) tests whether a Rectangle is rectangular. It first tests if the Rectangle is planar. Then it creates vectors from the points on the Rectangle, and checks their angles to one another. If they are within Point ::epsilon( ) (exclusive) of 180^{∘} in one case, and 90^{∘} in the other two, is rectangular ( ) returns 1, otherwise 0. [LDF 2003.12.02.]

Log

[LDF 2003.11.28.] Added this function.

[LDF 2003.12.02.] Added test of planarity at beginning of function.

[LDF 2003.12.09.] Now using cross product ( ) to test for parallelity of the sides. TO DO: Add Path ::is parallel ( ) and a version for Points.

⟨ Declare Rectangle functions 1103 ⟩ +≡ bool is rectangular ( ) const;

314  IS RECTANGULAR  3DLDF-1.1.5.1 §1123

1123. ⟨ Define Rectangle functions 1104 ⟩ +≡

bool Rectangle ::is rectangular ( ) const {

if (¬is planar ( )) return false;

Point a = (get point (1) − get point (0));

Point b = (get point (2) − get point (3));

Point c = (get point (3) − get point (0));

Point d = (get point (2) − get point (1));

return (a.cross product (b) ≡ origin ∧ c.cross product (d) ≡ origin ∧ fabs (fabs (a.angle(d)) − 90) <

Point ::epsilon( )); }

1124. Returning Points.

Log

[LDF 2002.11.06.] Got rid of get center ( ). It’s not needed, since Reg Polygon ::get center ( ) does the trick.

[LDF 2003.04.15.] Added get center ( ) again, since I’m no longer deriving Rectangle from Reg Polygon, but from Path.

[LDF 2003.07.18.] Got rid of get center ( ) again, because Rectangle is now derived from Polygon, and I’ve moved the Reg Polygon versions to Polygon.

1125. Corner. The argument c should be in the range 0 <= c <= 3. ⟨ Declare Rectangle functions 1103 ⟩ +≡

Point corner (unsigned short c);

1126. ⟨ Define Rectangle functions 1104 ⟩ +≡

Point Rectangle ::corner (unsigned short c) {

if (c > 3) {

cerr ≪ ␣ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ␣ ≪ flush;

return ; } return ∗points [c];

}

1127. Get Mid-point. The argument c should be in the range 0 <= c <= 3.

Log

[LDF 2002.11.06.] Changed this function so that it uses mediate( ). [LDF 2003.05.09.] Renamed this function get mid point ( ). Formerly, it was called mid point ( ). [LDF 2003.07.18.] Made const.

⟨ Declare Rectangle functions 1103 ⟩ +≡ Point get mid point (unsigned short c) const;

§1128  3DLDF-1.1.5.1  GET MID-POINT 315

1128. ⟨ Define Rectangle functions 1104 ⟩ +≡

Point Rectangle ::get mid point (unsigned short c) const {

if (c > 3) {

cerr ≪ ␣ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ␣ ≪ flush;

return ; } Point p0 ; Point p1 ; Point p2 ; p0 = ∗points [c]; p1 = (c < 3) ? ∗points [c + 1] : ∗points [0]; return p0 .mediate(p1 );

}

1129. Getting axes. [LDF 2003.07.18.] TO DO: axis h and axis v are not recalculated when a Rectangle is transformed. I should do something about this.

Log

[LDF 2003.07.18.] Added this section.

1130. Get axis h. ⟨ Declare Rectangle functions 1103 ⟩ +≡

real get axis h( ) const;

1131. ⟨ Define Rectangle functions 1104 ⟩ +≡

real Rectangle ::get axis h( ) const

{

return axis h; }

1132. Get axis v. ⟨ Declare Rectangle functions 1103 ⟩ +≡

real get axis v ( ) const;

316  GET AXIS V  3DLDF-1.1.5.1 §1133

1133. ⟨ Define Rectangle functions 1104 ⟩ +≡

real Rectangle ::get axis v ( ) const {

return axis v ; }

1134. Ellipses.

Log

[LDF 2003.07.18.] Added this section. These functions must be defined in ellipses.web, because Ellipse is an incomplete type in this file.

1135. Surrounding Ellipse.

Log

[LDF 2003.07.18.] Added this function.

⟨ Declare Rectangle functions 1103 ⟩ +≡ Ellipse out ellipse( ) const;

1136. Enclosed Ellipse.

Log

[LDF 2003.07.18.] Added this function.

⟨ Declare Rectangle functions 1103 ⟩ +≡ Ellipse in ellipse( ) const;

1137. Draw surrounding Ellipse.

Log

[LDF 2003.07.18.] Added this function.

⟨ Declare Rectangle functions 1103 ⟩ +≡

Ellipse draw out ellipse(const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , Picture &picture = current picture) const;

1138. Draw enclosed Ellipse.

Log

[LDF 2003.07.18.] Added this function.

⟨ Declare Rectangle functions 1103 ⟩ +≡

Ellipse draw in ellipse(const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , Picture &picture = current picture) const;

1139. Putting Rectangle together. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩

§1139  3DLDF-1.1.5.1  PUTTING RECTANGLE TOGETHER 317

⟨ Define class Rectangle 1101 ⟩ ⟨ Define Rectangle functions 1104 ⟩ ⟨ Declare non-member template functions for Rectangle 1116 ⟩

318  PUTTING RECTANGLE TOGETHER  3DLDF-1.1.5.1 §1140

1140. This is what’s written to rectangs.h.

⟨ 1140 ⟩ ≡

⟨ Define class Rectangle 1101 ⟩

⟨ Declare non-member template functions for Rectangle 1116 ⟩

1141. Ellipse (ellipses.web).

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

format Ellipse Path

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1142. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1143. Ellipse class definition.

Log

[LDF 2003.07.25.] Added focus0 , focus1 , and linear eccentricity .

[LDF 2003.07.27.] Added numerical eccentricity .

⟨ Define class Ellipse 1143 ⟩ ≡ class Ellipse : public Reg Cl Plane Curve { protected: Point focus0 ;

Point focus1 ;

real linear eccentricity ; real numerical eccentricity ; real axis h; real axis v ; static unsigned short ;

§1143  3DLDF-1.1.5.1  ELLIPSE CLASS DEFINITION 319

public: ⟨ Declare Ellipse functions 1146 ⟩ };

This code is used in sections 1271 and 1272.

1144. Static data members. ⟨ Define static Ellipse data members 1144 ⟩ ≡

unsigned short Ellipse :: = 16;

/∗ [LDF 2002.11.06.] Must be a multiple of 4. ∗/

This code is used in section 1271.

1145. Constructors.

1146. Default constructor. No arguments. ⟨ Declare Ellipse functions 1146 ⟩ ≡

Ellipse( );

See also sections 1149, 1151, 1157, 1160, 1162, 1164, 1166, 1167, 1169, 1171, 1174, 1177, 1179, 1182, 1184, 1186, 1188, 1192, 1194, 1197, 1199, 1201, 1203, 1205, 1208, 1210, 1214, 1231, 1233, 1235, 1237, 1239, 1242, 1244, 1247, 1249, 1252, 1254, 1257, 1259, 1261, and 1263.

This code is used in section 1143.

1147. ⟨ Define Ellipse functions 1147 ⟩ ≡

Ellipse ::Ellipse( ) {

on free store = false;

line switch = false;

cycle switch = true; }

See also sections 1150, 1152, 1158, 1161, 1165, 1168, 1170, 1172, 1173, 1175, 1178, 1180, 1183, 1185, 1187, 1189, 1193, 1195, 1198, 1200, 1202, 1204, 1206, 1209, 1211, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1226, 1227, 1232, 1234, 1236, 1238, 1240, 1243, 1245, 1248, 1250, 1253, 1255, 1258, 1260, 1262, and 1264.

This code is used in section 1271.

1148. Center, lengths, and angles of rotation.

1149. Constructor. The ellipse is always generated in the x-z plane with the center at the origin. Then it is rotated about the main axes according to the values of the angle arguments and shifted to center .

Log

[LDF 2002.11.06.] Made real arguments const. [LDF 2003.07.25.] Added code for setting focus0 , focus1 , and linear eccentricity . [LDF 2003.07.27.] Added code for setting numerical eccentricity .

⟨ Declare Ellipse functions 1146 ⟩ +≡

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 = ); 1150. ⟨ Define Ellipse functions 1147 ⟩ +≡

Ellipse ::Ellipse(const Point &ccenter , const real aaxis h, const real aaxis v , const real angle x , const real angle y , const real angle z , const unsigned short nnumber of points ): axis h(aaxis h), axis v (aaxis v ) { center = ccenter ;

center .apply transform( ); focus0 = origin; focus1 = origin; real axis h half = axis h/2; real axis v half = axis v /2; if (axis h ≥ axis v ) {

linear eccentricity = sqrt ((axis h half ∗ axis h half ) − (axis v half ∗ axis v half )); focus0 .shift (−linear eccentricity ); focus1 .shift (linear eccentricity ); numerical eccentricity = linear eccentricity /axis h half ;

} else {

linear eccentricity = sqrt ((axis v half ∗ axis v half ) − (axis h half ∗ axis h half )); focus0 .shift (0, 0, −linear eccentricity ); focus1 .shift (0, 0, linear eccentricity ); numerical eccentricity = linear eccentricity /axis v half ;

} if (nnumber of points % 4 ≠ 0) {

  cerr ≪  ␣  ␣          ␣       ␣     ␣    ␣  ≪

nnumber of points ≪  ≪ endl ≪  ␣       ␣        ␣ ≪

≪ endl ≪ flush; number of points = ;

} else number of points = nnumber of points ; on free store = false; line switch = false; cycle switch = true; connectors .push back ( ); Transform t; if (angle x ≠ 0 ∨ angle y ≠ 0 ∨ angle z ≠ 0) t.rotate(angle x , angle y , angle z ); t.shift (center ); focus0 ∗= focus1 ∗= t; real curr angle; real curr x ; real curr z ; for (int i = 0; i < number of points ; i^{++})

/∗ LDF 2002.11.06. Modified this code. ∗/ { curr angle = 2 ∗ i ∗ /number of points ; curr x = axis h/2 ∗ cos (curr angle); curr z = axis v /2 ∗ sin(curr angle); points .push back ( create new < Point > (0) ) ; points .back ( ) set (curr x , 0, curr z ); ∗(points .back ( )) ∗= t;

/∗ Rotate ∗(points .back ( )) around the x, y, and z-axes and shift it to center . ∗/ } } 1151. Setting function.

Log

[LDF 2003.03.01.] Added this function.

⟨ Declare Ellipse functions 1146 ⟩ +≡

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 = );

1152. ⟨ Define Ellipse functions 1147 ⟩ +≡

void Ellipse ::set (const Point &ccenter , const real aaxis h, const real aaxis v , const real

angle x , const real angle y , const real angle z , const unsigned short nnumber of points )

{ Ellipse e(ccenter , aaxis h, aaxis v , angle x , angle y , angle z , nnumber of points ); ∗this = e;

}

1153. Pseudo-constructor for dynamic allocation.

1154. Pointer argument.

Log

[LDF 2002.11.06.] Added optional const Ellipse ∗ argument.

[LDF 2003.12.30.] Replaced Ellipse ::create new ellipse( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Ellipse.

⟨ Declare non-member template functions for Ellipse 1154 ⟩ ≡

Ellipse ∗create new (const Ellipse ∗c);

See also section 1155. This code is used in sections 1271 and 1272.

322  REFERENCE ARGUMENT  3DLDF-1.1.5.1 §1155

1155. Reference argument.

Log

[LDF 2002.11.06.] Added this function.

[LDF 2003.12.30.] Replaced Ellipse ::create new ellipse( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Ellipse.

⟨ Declare non-member template functions for Ellipse 1154 ⟩ +≡ Ellipse ∗create new (const Ellipse &c);

1156. Destructor. [LDF 2002.10.09.] Removed the destructor. Path ::∼Path( ) or Path ::clear ( ) should be used instead, unless I add dynamically allocated data members to Ellipse (rather than Path).

1157. Assignment.

Log

[LDF 2002.11.06.] Added error handling code to prevent self-assignment.

[LDF 2002.11.10.] Changed return value to Ellipse &.

⟨ Declare Ellipse functions 1146 ⟩ +≡ Ellipse &operator=(const Ellipse &e);

1158. !! Remember to put anything specific to Ellipses in here! ⟨ Define Ellipse functions 1147 ⟩ +≡

Ellipse &Ellipse ::operator=(const Ellipse &e)

{

if (this ≡ &e) /∗ [LDF 2002.11.06.] Make sure it’s not self-assignment. ∗/

return ∗this ; Path ::operator=(e); center = e.center ; /∗ Ellipse members. ∗/ axis h = e.axis h; axis v = e.axis v ; focus0 = e.focus0 ; focus1 = e.focus1 ; number of points = e.number of points ; /∗ Reg Cl Plane Curve members. ∗/ return ∗this ;

}

1159. Labelling.

1160. Label. ⟨ Declare Ellipse functions 1146 ⟩ +≡

void label (const string pos = , const bool dot = false, Picture &picture = current picture) const;

§1161  3DLDF-1.1.5.1  LABEL 323

1161. ⟨ Define Ellipse functions 1147 ⟩ +≡

void Ellipse ::label (const string pos , const bool dot , Picture &picture) const

{

if (Label :: ≡ false) {

return; } string s; char c = ; for (vector⟨Point ∗⟩::const iterator iter = points .begin( ); iter ≠ points .end ( ); iter^{++}) {

s = c;

(∗∗iter ).label (s, pos , dot , picture); c^{++};

} }

1162. Dotlabel.

Log

[LDF 2002.11.06.] Changed this function so that it just calls Ellipse ::label ( ) with dot = true. Made it inline.

⟨ Declare Ellipse functions 1146 ⟩ +≡ inline void dotlabel (string pos = , Picture &picture = current picture) const {

label (pos , true, picture); }

1163. Returning elements and information.

1164. Is elliptical. [LDF 2003.07.20.] is elliptical ( ) first checks whether ∗this is planar by calling get normal ( ). If the latter function returns , then is elliptical ( ) returns false. Otherwise, it makes a copy of ∗this called e, puts e into the x-z plane, and rotates it, so that ∗(e.points [0]) lies on the x-axis. Then, it plugs the x and z-coordinates of the Points on e into the ellipse equation, i.e., x^{2}/a^{2} + z^{2}/b^{2} = 1, where a is half of the horizontal axis of the ellipse, and b is half of the vertical axis. Let r = x^{2}/a^{2} + z^{2}/b^{2} and ϵ stand for the return value of Point ::epsilon( ). If |r − 1| > ϵ for any of the Points on e, is elliptical ( ) returns false, otherwise it returns true.

Log

[LDF 2003.07.20.] Added this function.

[LDF 2003.07.25.] Now checking normal ≡ . If it is, is elliptical ( ) returns false.

⟨ Declare Ellipse functions 1146 ⟩ +≡ bool is elliptical ( ) const;

324  IS ELLIPTICAL  3DLDF-1.1.5.1 §1165

1165. ⟨ Define Ellipse functions 1147 ⟩ +≡

bool Ellipse ::is elliptical ( ) const {

bool = false; /∗ true ∗/ Point normal = get normal ( ); if (normal ≡ ) {

if ( )

cerr ≪ ␣                         ␣ ≪  ␣         ␣  ≪
endl ≪  ␣  ␣           ␣         ␣  ≪ endl ≪ endl ≪ flush;

return false; } Ellipse e = ∗this ; normal .shift (center ); Transform t; t.align with axis (center , normal , ); e.do transform(t); if ( ) e.show ( ␣ ␣ ); Point x axis pt (1); Point p0 = e.get point (0); real ang = p0 .angle(x axis pt ); t.reset ( ); t.rotate(0, ang ); p0 ∗= e.do transform(t); p0 .unit vector (true); if (p0 ≠ x axis pt ) {

t.reset ( );

t.rotate(0, −2 ∗ ang );

e.do transform(t); } p0 = e.get point (0); p0 .unit vector (true); if (p0 ≠ x axis pt ) {

if ( )

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

flush; return false;

} if ( ) e.show ( ␣ ␣ ␣ ␣ ␣ ); real x; real z; real a = (e.get point (0) − e.get center ( )).magnitude( ); real b = (e.get point (number of points /4) − e.get center ( )).magnitude( ); if ( ) {

cout ≪ ␣ ␣ ≪ a ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ b ≪ endl ≪ flush;

} real r; int i = 0;

§1165  3DLDF-1.1.5.1  IS ELLIPTICAL 325

for (vector⟨Point ∗⟩::const iterator iter = e.points .begin( ); iter ≠ e.points .end ( ); ^{++}iter ) { x = (∗∗iter ).get x ( ); z = (∗∗iter ).get z ( ); if ( ) {

cout ≪ ␣ ≪ i ≪ ␣ ≪ endl ≪ flush;

(∗∗iter ).show ( );

cout ≪ ␣ ␣ ≪ x ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ z ≪ endl ≪ flush; } r = ((x ∗ x)/(a ∗ a)) + ((z ∗ z)/(b ∗ b)); if ( ) cout ≪ ␣ ␣ ≪ r ≪ endl ≪ flush; if (fabs (r − 1) > Point ::epsilon( )) {

if ( ) cout ≪ ␣ ≪ i ≪ ␣ ␣ ␣ ␣ ≪

␣ ≪ flush; return false;

} ++i;

} if ( )

cout ≪ ␣ ␣␣ ␣ ≪ endl ≪ endl ≪ flush; return true;

}

1166. Is quadratic. ⟨ Declare Ellipse functions 1146 ⟩ +≡

inline bool is quadratic( ) const {

return true; }

1167. Is cubic.

Log

[LDF 2003.07.27.] Made virtual and non-inline.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual bool is cubic( ) const;

326  IS CUBIC  3DLDF-1.1.5.1 §1168

1168. ⟨ Define Ellipse functions 1147 ⟩ +≡

bool Ellipse ::is cubic( ) const {

return false; }

1169. Is quartic.

Log

[LDF 2003.07.27.] Made virtual and non-inline.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual bool is quartic( ) const;

1170. ⟨ Define Ellipse functions 1147 ⟩ +≡

bool Ellipse ::is quartic( ) const {

return false; }

1171. Solve. [LDF 2002.11.06.] solve( ) assumes that the Ellipse lies in a major plane with its center at the origin. Code that calls it must ensure that these conditions are fulfilled. solve( ) returns the two possible values for either the horizontal or the vertical coordinate.

TO DO: Read through, and then explain this function.

Log

[LDF 2003.07.20.] Now using get axis v ( ) and get axis h( ), instead of accessing axis h and axis v directly. [LDF 2003.07.25.] Removed some commented-out code, and an explanatory comment.

⟨ Declare Ellipse functions 1146 ⟩ +≡ real pair solve(char axis unknown, real known) const;

§1172  3DLDF-1.1.5.1  SOLVE 327

1172. ⟨ Define Ellipse functions 1147 ⟩ +≡

real pair Ellipse ::solve(char axis unknown, real known) const{ real radius known; real radius unknown; axis unknown = tolower (axis unknown); real pair r; if (axis unknown ≡ ) {

radius known = get axis v ( )/2;

radius unknown = get axis h( )/2; } else if (axis unknown ≡ ) {

radius known = get axis h( )/2;

radius unknown = get axis v ( )/2; } else {

cerr ≪  ␣  ␣  ≪  ␣         ␣    ␣            ␣ ≪
axis unknown ≪  ␣  ≪ flush;

return ; } if (fabs (known) > radius known) {

return ; }

328  SOLVE  3DLDF-1.1.5.1 §1173

1173. The equation for an ellipse in the x-y plane with its center at the origin is

x^{2}/a^{2} + y^{2}/b^{2} = 1

where a is half the horizontal axis and b is half the vertical axis. Therefore,

y = \sqrt{(1 − x^{2}/a^{2}) × b^{2}}

and

x = \sqrt{(1 − y^{2}/b^{2}) × a^{2}}.

⟨ Define Ellipse functions 1147 ⟩ +≡ r.first = sqrt ((1−((known ∗known)/(radius known ∗radius known)))∗(radius unknown ∗radius unknown)); r.second = −r.first ; return r; }

1174. Get coefficients. This is used for getting the coefficients of the quadratic equation that results from replacing y with mx + b from the line equation, where m is the slope and b the intercept with the vertical axis, (whichever that might be in a particular case; it needn’t be the y-axis) in the equation for the ellipse

x^{2}/α^{2} + y^{2}/β^{2} = 1

namely !! START HERE. Check this. I think the x in the coefficient for x^{2} is wrong.

x^{2}/α^{2} + (mx + b)^{2}/β^{2} − 1 = 0 ≡ (β^{2}x + α^{2}m^{2})x^{2} + 2α^{2}bmx + (α^{2}b^{2} − α^{2}β^{2}) = 0.

The coefficients are returned in the struct 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}).

Log

[LDF 2003.07.20.] Now using get axis v ( ) and get axis h( ), instead of accessing axis h and axis v directly. [LDF 2003.07.27.] Corrected a typo in the math mode material showing the coefficients.

⟨ Declare Ellipse functions 1146 ⟩ +≡ real triple get coefficients (real Slope, real v intercept ) const;

1175. ⟨ Define Ellipse functions 1147 ⟩ +≡

real triple Ellipse ::get coefficients (real Slope, real v intercept ) const

{ real triple r; real ax h = get axis h( ); real ax v = get axis v ( ); r.first = ((ax v /2) ∗ (ax v /2)) + (((ax h/2) ∗ (ax h/2)) ∗ (Slope ∗ Slope)); /∗ a ∗/ r.second = 2 ∗ Slope ∗ v intercept ∗ ((ax h/2) ∗ (ax h/2)); /∗ b ∗/ r.third = (((ax h/2)∗(ax h/2))∗(v intercept ∗v intercept ))−(((ax v /2)∗(ax v /2))∗((ax h/2)∗(ax h/2)));

/∗ c ∗/ return r;

}

1176. Get center.

1177. Non-const version.

Log

[LDF 2002.11.10.] Made this function virtual and non-inline. [LDF 2003.05.09.] Changed return value from Point & to const Point &.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual const Point &get center ( );

1178. ⟨ Define Ellipse functions 1147 ⟩ +≡

const Point &Ellipse ::get center ( ) {

center .apply transform( ); return center ;

}

1179. const version.

Log

[LDF 2002.11.10.] Made this function virtual and non-inline.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Point get center ( ) const;

1180. ⟨ Define Ellipse functions 1147 ⟩ +≡

Point Ellipse ::get center ( ) const {

Point p(center );

p.apply transform( );

return p; }

1181. Get focus.

1182. Non-const version.

Log

[LDF 2003.07.25.] Added this function.

⟨ Declare Ellipse functions 1146 ⟩ +≡ const Point &get focus (const unsigned short s); 1183. ⟨ Define Ellipse functions 1147 ⟩ +≡

const Point &Ellipse ::get focus (const unsigned short s) {

if (s ≡ 0) { focus0 .apply transform( ); return focus0 ;

} else if (s ≡ 1) {

focus1 .apply transform( );

return focus1 ; } else {

cerr ≪  ␣  ␣  ≪  ␣         ␣ ≪ s ≪ endl ≪
␣         ␣    ␣ ␣   ␣  ≪  ␣  ≪ flush;

return ; }

}

1184. const version.

Log

[LDF 2003.07.25.] Added this function.

⟨ Declare Ellipse functions 1146 ⟩ +≡ Point get focus (const unsigned short s) const; 1185. ⟨ Define Ellipse functions 1147 ⟩ +≡

Point Ellipse ::get focus (const unsigned short s) const {

Point p;

if (s ≡ 0) { p = focus0 ; p.apply transform( ); return p;

}

else if (s ≡ 1) { p = focus1 ; p.apply transform( ); return p;

}

else {

cerr ≪  ␣  ␣  ≪  ␣         ␣ ≪ s ≪ endl ≪
␣         ␣    ␣ ␣   ␣  ≪  ␣  ≪ flush;

return ; }

}

1186. Get linear eccentricity.

Log

[LDF 2003.07.25.] Added this function.

⟨ Declare Ellipse functions 1146 ⟩ +≡ real get linear eccentricity ( ) const;

1187. ⟨ Define Ellipse functions 1147 ⟩ +≡

real Ellipse ::get linear eccentricity ( ) const {

return linear eccentricity ; }

1188. Get numerical eccentricity.

Log

[LDF 2003.07.27.] Added this function.

⟨ Declare Ellipse functions 1146 ⟩ +≡ real get numerical eccentricity ( ) const;

332  GET NUMERICAL ECCENTRICITY  3DLDF-1.1.5.1 §1189

1189. ⟨ Define Ellipse functions 1147 ⟩ +≡

real Ellipse ::get numerical eccentricity ( ) const

{

return numerical eccentricity ; }

1190. Get axes.

Log

[LDF 2003.07.20.] Rewrote the const versions of the functions in this section, and added non-const versions. All of them now check whether ∗this is still elliptical using is ellipse( ). If it is, the value axis v or axis h should have is recalculated, and this value is returned. In the non-const versions, axis v or axis h is reset to the new value. If ∗this is no longer elliptical, the function returns , and axis h or axis v is set to in the non-const versions.

[LDF 2003.07.20.] axis h and axis v are updated by the transformation functions, and these are presumably the only ones that could cause an Ellipse to become non-elliptical. So, checking and recalculating them here is probably redundant. However, this may change, so it’s safer to do this here.

[LDF 2003.07.25.] BUG FIX: axis h and axis v were too small by half. Now multiplying by 2 in all versions of get axis h( ) and get axis v ( ).

1191. Get vertical axis.

1192. const version. ⟨ Declare Ellipse functions 1146 ⟩ +≡

real get axis v ( ) const;

1193. ⟨ Define Ellipse functions 1147 ⟩ +≡

real Ellipse ::get axis v ( ) const

{ if (is elliptical ( )) return (2 ∗ (get point (number of points /4) − get center ( )).magnitude( )); else return ;

}

1194. Non-const version. ⟨ Declare Ellipse functions 1146 ⟩ +≡

real get axis v ( );

1195. ⟨ Define Ellipse functions 1147 ⟩ +≡

real Ellipse ::get axis v ( )

{ if (is elliptical ( )) axis v = ((get point (number of points /4) − get center ( )).magnitude( ) ∗ 2); else axis v = ; return axis v ;

}

1196. Get horizontal axis.

1197. const version. ⟨ Declare Ellipse functions 1146 ⟩ +≡

real get axis h( ) const;

1198. ⟨ Define Ellipse functions 1147 ⟩ +≡

real Ellipse ::get axis h( ) const

{ if (is elliptical ( )) return ((get point (0) − get center ( )).magnitude( ) ∗ 2); else return ;

}

1199. Non-const version. ⟨ Declare Ellipse functions 1146 ⟩ +≡

real get axis h( );

1200. ⟨ Define Ellipse functions 1147 ⟩ +≡

real Ellipse ::get axis h( )

{ if (is elliptical ( )) axis h = (get point (0) − get center ( )).magnitude( ) ∗ 2; else axis h = ; return axis h;

}

1201. Angle point. angle point ( ) returns a point on the ellipse given an angle. Effectively, point [0] is rotated about the center in the plane of the ellipse and the intersection of the ray from the center through point [0] and the ellipse is returned.

[LDF 2003.07.27.] TO DO: Try to get the rotation to always go in the direction I would like.

Log

[LDF 2003.07.01.] BUG FIX: Now returning bpp.first .pt if it’s not equal to . Otherwise, bpp.second .pt is returned. The latter may be a valid Point, or . Before, was returned if bpp.first .b and bpp.second .b were false, but this is the case, if the intersection points didn’t lie on the line segment between center and pt0 .

BUG FIX: Now checking to make sure that the intersection point lies in the proper direction. Now that the intersection point doesn’t have to be on the line segment, it’s necessary to check this.

[LDF 2003.07.20.] Now using get axis v ( ) and get axis h( ), instead of accessing axis h and axis v directly. [LDF 2003.07.27.] Made const. Made angle argument const. Now using get center ( ) instead of center .

⟨ Declare Ellipse functions 1146 ⟩ +≡ Point angle point (const real angle) const;

334  ANGLE POINT  3DLDF-1.1.5.1 §1202

1202. ⟨ Define Ellipse functions 1147 ⟩ +≡

Point Ellipse ::angle point (const real angle) const {

Point Center = get center ( ); Point normal = get normal ( ); normal .shift (Center ); Point pt0 = get point (0); pt0 −= Center ; pt0 .unit vector (true); pt0 ∗= max (get axis h( ), get axis v ( ))/2;

/∗ [LDF 2002.11.06.] pt0 will either lie on the perimeter of the Ellipse or beyond it. ∗/ pt0 .shift (Center ); pt0 .rotate(Center , normal , angle); bool point pair bpp = intersection points (Center , pt0 ); Point direction line(pt0 − Center ); direction line.unit vector (true); Point direction pt ; if (bpp.first .pt ≠ ) {

direction pt = bpp.first .pt ;

direction pt −= Center ;

direction pt .unit vector (true);

if (direction pt ≡ direction line) return bpp.first .pt ; } return bpp.second .pt ;

}

1203. Equality. TO DO: I’ll need to define Path ::operator≡( ) in order to be able to define this function. ⟨ Declare Ellipse functions 1146 ⟩ +≡ #if 0

virtual bool operator≡(const Ellipse &e); #endif

§1204  3DLDF-1.1.5.1  EQUALITY 335

1204. ⟨ Define Ellipse functions 1147 ⟩ +≡ #if 0

virtual bool Ellipse ::operator≡(const Ellipse &e)

{ } #endif

1205. Location of a point. [LDF 2003.07.25.] This function overloads Reg Cl Plane Curve ::location( ). It’s simpler, because it doesn’t need to copy the Ellipse and transform the copy into a major plane. Nor does it require the use of solve( ).

[LDF 2003.07.25.] If the Point argument P lies in the same plane as ∗this , location( ) compares the sum of the distances of P from the foci to 2 times the maximum of axis h and axis v .

[LDF 2003.07.25.] Let m stand for (P − focus0 ).magnitude( ) + (P − focus0 ).magnitude( ), d for 2 ∗ max (axis h, axis v ), and ϵ for Point ::epsilon( ). The return values are as follows:

0 |m − d| < ϵ. P lies on the perimeter of the Ellipse.

-1 m > d. P lies outside the Ellipse.

1 m < d. P lies inside the perimeter of the Ellipse.

-2 P is not in the same plane as the Ellipse.

-3 The Ellipse is non-elliptical.

Log

[LDF 2003.07.25.] Added this function.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual signed short location(const Point &p) const; 1206. ⟨ Define Ellipse functions 1147 ⟩ +≡

signed short Ellipse ::location(const Point &p) const {

bool = false; /∗ true ∗/ real ax h = get axis h( ); real ax v = get axis v ( );

if (ax h ≡  ∨ ax v ≡  ) {
cerr ≪  ␣  ␣  ≪
␣ ␣ ␣ ␣ ≪ flush;

return −3; } if (¬p.is on plane(get plane( ))) {

cerr ≪  ␣  ␣  ≪

      ␣       ␣   ␣   ␣     ␣  ␣  ≪  ␣  ≪ flush;

return −2; } real max ax = max (ax h, ax v ); Point q = p − get focus (0); real mag = q.magnitude( ); q = p − get focus (1); mag += q.magnitude( ); if (fabs (mag − max ax ) < Point ::epsilon( )) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ; return 0;

} else if (mag > max ax ) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ; return −1;

} else {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ; return 1;

} }

1207. Intersection points.

1208. Point arguments.

Log

[LDF 2003.07.27.] Made the arguments const Point &.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual bool point pair intersection points (const Point &p0 , const Point &p1 ) const; 1209. ⟨ Define Ellipse functions 1147 ⟩ +≡

bool point pair Ellipse ::intersection points (const Point &pt0 , const Point &pt1 ) const {

return Reg Cl Plane Curve ::intersection points (center , pt0 , pt1 ); }

1210. Path argument. This function just checks to be sure that Path p is a line, extracts the Points, and calls the version with Point arguments, returning the latter’s return value.

Log

[LDF 2003.07.09.] Made virtual. [LDF 2003.07.27.] Made argument p a const Path &. Changed, so that is linear ( ) is used, and

get last point ( ) rather than get point (1).

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual bool point pair intersection points (const Path &p) const;

1211. ⟨ Define Ellipse functions 1147 ⟩ +≡

bool point pair Ellipse ::intersection points (const Path &p) const {

if (¬p.is linear ( )) {

cerr ≪  ␣  ␣                                  ␣  ≪

        ␣        ␣  ␣  ≪  ␣          ␣     ␣    ␣  ≪

␣ ≪ endl ≪ endl ≪ flush; return ;

}

return intersection points (p.get point (0), p.get last point ( )); }

1212. Ellipse argument. TO DO: Read through and explain. [LDF 2002.11.06.]

The step argument is used in the case that the Ellipses have different centers and/or axis orientation. It is the number of degrees of rotation performed while the algorithm is searching for an intersection. The default is 3, which should work as long as the Ellipses don’t differ too much in size. [LDF 2004.01.12.]

If the verbose argument is true, information about the intersection points is printed to standard output.

[LDF 2003.07.01.]

If the Ellipses are coplanar, the intersection points of the perimeters of the Ellipses are returned. If the planes of the Ellipses are perpendicular or skew, the intersection line of the planes is found. Then, the intersection points of the this line with the Ellipses, if they exist.

TO DO: [LDF 2003.07.20.] The following code found only one intersection: #if 0

Ellipse t(origin, 5, 4, 90); Circle c(origin, 3, 90); c.shift (3); c.rotate(0, 0, 30); bool point quadruple bpq = t.intersection points (c);

338 ELLIPSE ARGUMENT 3DLDF-1.1.5.1 §1213

#endif 1213. When c was rotated by 15^{∘} or 45^{∘}, intersection points ( ) found both intersections. Try to find out why! I want to write a Circle version with an Ellipse argument, and vice versa. If I do, I may not have to worry about this problem.

1214. [LDF 2003.07.20.]

Log

[LDF 2002.04.12.] Actually, it looks as if the equations Dr. Schwardmann gave me won’t do the trick. They assume both ellipses are centered about the origin. When I tried to have Mathematica solve the equations for x^{2}/a^{2} + y^{2}/b^{2} = (x − m)^{2}/c^{2} + (y − n)^{2}/d^{2}, Mathematica produced solutions that took up over 35,000 lines of text!

[LDF 2002.04.12.] I’ve rewritten the other cases (parallel, perpendicular, and skew) in this function completely, and it seems like it wasn’t really worth the effort. The new version does however make use of Planes and Lines, which is not a bad thing, and it checks whether the intersection Points are on the Ellipse, so it wasn’t a total loss.

[LDF 2002.04.12.] I’ve written to Dr. Schwardmann and asked him about this problem. It may just be my ignorance, or perhaps I’ve overlooked something simple. I’m not too hopeful, however, so I’ll probably have to implement the numerical solution I’d started, after all.

[LDF 2002.04.12.] Removed old definition. Dr. Ulrich Schwardmann of the Gesellschaft für wissenschaftliche Datenverarbeitung, Göttingen, Germany showed me how to use Mathematica’s “Solve” command to solve the systems of equations that describe the intersections between two ellipses. Therefore, I’ve removed the old definition of this function, which wasn’t complete, anyway, and I’ll put in a new definition soon.

[LDF 2002.04.14.] About to start work on implementing the coplanar case again. The equations produced by Mathematica will work for the case that the ellipses have the same center. I will catch the case that they are congruent and have the same center and the case that they are non-congruent and have the same center before going on to implement a numerical solution for the case that they have different centers.

[LDF 2002.04.14.] Changed argument from const Ellipse & to Ellipse, since I was having to copy it, anyway.

[LDF 2003.07.01.] Added verbose argument.

[LDF 2003.07.01.] Changed “perpendicular and skew case”. Debugged coplanar case, where the Ellipses don’t have the same centers and/or axis orientation.

[LDF 2003.07.06.] Made a minor change to the conditional that determines whether the Ellipses are coplanar or not.

[LDF 2003.08.14.] Setting verbose to true if  is true. Added  to

pspglb.web today.

[LDF 2004.01.12.] Added real step argument, with 3 as its default value.

⟨ Declare Ellipse functions 1146 ⟩ +≡

§1215  3DLDF-1.1.5.1  ELLIPSE ARGUMENT 339

virtual bool point quadruple intersection points (Ellipse e, const real step = 3, bool verbose = false) const; 1215. ⟨ Define Ellipse functions 1147 ⟩ +≡

bool point quadruple Ellipse ::intersection points (Ellipse e, const real step, bool verbose) const{

bool = false; /∗ true ∗/ if ( ) verbose = true; if ( ∨ verbose)

cout ≪ ␣ ␣ ␣ ␣ ␣ ≪

endl ; bool point quadruple bpq = ; Plane this plane = this get plane( ); Plane e plane = e.get plane( ); if ( ) {

this plane.show ( );

e plane.show ( ); } if (this plane.normal ≡ e plane.normal ∨ this plane.normal ≡ −e plane.normal ) {

1216. Coplanar case.

Log

[LDF 2003.07.20.] Now using get axis v ( ) and get axis h( ), instead of accessing axis h and axis v directly.

⟨ Define Ellipse functions 1147 ⟩ +≡ if (fabs (fabs (this plane.distance) − fabs (e plane.distance)) < Point ::epsilon( )) { if ( ) {

cout ≪ ␣ ␣ ≪ flush; } real ax h = get axis h( ); real ax v = get axis v ( ); 1217. Congruent, same location and axis orientation. [LDF 2002.04.15.] Added check for the axis orientation. If the axes are not all vertical or horizontal, then this fails (floating exception). This means that the circular case will not be caught here, but I plan to program a specialization for Circles, so this shouldn’t cause too much of a problem.

[LDF 2002.04.14.] Added this section. This routine only works if the axis orientation of the Ellipses is the same, or rotated 90^{∘} or 180^{∘} about

an axis through the center in the direction of the normal to the plane of the Ellipse, or in the opposite direction. The axis orientation is tested on the basis of the vector from the center to points [0]. If the axis orientation is the same, or rotated 180^{∘} about the above-mentioned axis, then axis h of ∗this must equal axis h of e and axis v of ∗this must equal axis v of e. If the axis orientation is rotated at an angle of ±90^{∘}, then axis h of ∗this must equal axis v of e and axis v of ∗this must equal axis h of e.

The maximum number of intersection points of two non-congruent ellipses is four, so checking five points eliminates the possibility that we could accidentally choose intersection points on two non-congruent ellipses and mistakenly conclude that they are congruent. ⟨ Define Ellipse functions 1147 ⟩ +≡

Point this axis orientation(get point (0)); this axis orientation −= get center ( ); this axis orientation.unit vector (true); Point e axis orientation(e.get point (0)); e axis orientation −= e.get center ( ); e axis orientation.unit vector (true); if ( ) {

this axis orientation.show ( ); e axis orientation.show ( );

} Point normal point (this plane.normal ); normal point .unit vector (true); if ( ) normal point .show ( ); Point e axis orientation rotated (e axis orientation); 1218. [LDF 2002.09.26.] START HERE. Added the if condition. I think this should be done, but I should check to be sure. Apparently I haven’t programmed the case that the centers aren’t the same, but it would be easy enough to do, I think. ⟨ Define Ellipse functions 1147 ⟩ +≡

if (e axis orientation ≠ this axis orientation) e axis orientation rotated .rotate(origin, normal point , 90); if ( ) e axis orientation rotated .show ( ); if (this center ≡ e.center ∧ ((this axis orientation ≡ e axis orientation ∨ this axis orientation ≡

−e axis orientation) ∨ (this axis orientation ≡ e axis orientation rotated ∨ this axis orientation ≡ −e axis orientation rotated ))) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush;

/∗ [LDF 2002.04.14.] Pick the maximum of axis h and axis v and multiply it by 1.5. We’ll use a line segment of this length to find intersection points with the two Ellipses. Using this length guarantees we’ll find them. Actually, max (axis h, axis v ) ought to do the trick. ∗/

Point pt0 ; if (ax h ≥ ax v ) pt0 = get point (0); else pt0 = get point (number of points /4); pt0 −= center ; pt0 ∗= 1.5; pt0 .shift (center ); if ( ) {

this plane.normal .show ( );

center .show ( ); } /∗ [LDF 2002.04.14.] We’ll rotate pt0 around the normal to the plane of the ellipse from center ,

i.e., the line segment from center to pt1 . ∗/ Point pt1 (this plane.normal ); pt1 .shift (center ); if ( ) pt1 .show ( ); /∗ [LDF 2002.04.14.] pt2 is the intersection of the line from center

to pt0 with ∗this , and pt3 is the intersection of the same line with e. ∗/ Point pt2 ; Point pt3 ; bool point pair bpp this ; bool point pair bpp e; bool congruent flag = true; /∗ [LDF 2002.04.14.] We’ll find intersection points for five values

of pt0 . If one set of intersection points are not the same, this means the we Ellipses are not congruent and in the same location, so we break out of the loop. ∗/

for (int i = 0; i < 5; i^{++}) { if ( ) cout ≪ ␣ ␣ ≪ i ≪ endl ≪ flush; if (i ≠ 0) pt0 .rotate(center , pt1 , 30); if ( ) pt0 .dotlabel ( ); bpp this = intersection points (center , pt0 ); bpp e = e.intersection points (center , pt0 ); if (bpp this .first .b ≡ true) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ;

pt2 = bpp this .first .pt ; } else if (bpp this .second .b ≡ true) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ;

pt2 = bpp this .second .pt ; } else {

cerr ≪  ␣  ≪
␣     ␣      ␣  ≪  ␣   ␣  ␣  ≪ flush;

pt2 = ; } if (bpp e.first .b ≡ true) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ; pt3 = bpp e.first .pt ;

} else if (bpp e.second .b ≡ true) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ; pt3 = bpp e.second .pt ;

} else {

cerr ≪  ␣  ≪

      ␣     ␣      ␣          ␣   ␣  ␣  ≪ flush;

pt3 = ; } if ( ) {

pt2 .show ( );

pt2 .dotlabel ( );

pt3 .show ( );

pt3 .dotlabel ( , ); }

if (pt2 ≡  ∨ pt3 ≡  ∨ pt2 ≠ pt3 ) {
if (  ) cout ≪  ␣   ␣   ␣          ␣  ;

congruent flag = false;

break; } else continue;

} /∗ for ∗/ if ( ) {

cout ≪ ␣ ␣ ≪ congruent flag ≪ endl ≪ flush; } if (congruent flag ≡ true) {

cerr ≪  ␣  ␣  ≪

    ␣   ␣         ␣   ␣  ␣   ␣    ␣  ≪

␣ ≪ flush;

return ; } else if ( ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; }

} /∗ End of test of congruency and same location. ∗/

/∗ [LDF 2002.09.26.] START HERE. Programm this case!! ∗/ else if ( ) {

cout ≪  ␣       ␣   ␣          ␣  ␣   ␣␣     ␣          ␣ ≪
  ␣          ␣  ␣      ␣ ≪  ␣          ␣     ␣    ␣  ;

} Ellipse copy (∗this ); Point copy center (copy .get center ( )); Transform t; Transform t inverse; 1219. Shift to origin (if necessary). ⟨ Define Ellipse functions 1147 ⟩ +≡

if (copy center ≠ origin) {

if ( ) {

cout ≪ ␣ ␣ ␣ ≪ flush; } t.shift (−copy center .get x ( ), −copy center .get y ( ), −copy center .get z ( )); copy ∗= t; copy center ∗= t; e ∗= t;

} else if ( ) {

cout ≪ ␣ ␣ ␣ ␣ ≪ flush; }

1220. Get coordinates of normal. ⟨ Define Ellipse functions 1147 ⟩ +≡

real normal x = this plane.normal .get x ( ); real normal y = this plane.normal .get y ( ); real normal z = this plane.normal .get z ( ); 1221. Determine the orientation of the ellipse and rotate, if it’s not already in a plane parallel to a major plane. Rotating the Ellipse can cause inaccuracies in the coordinate values, so if the ellipse is already in a major plane, (i.e., one perpendicular to a major axis), we leave it where it is.

Log

[LDF 2003.08.27.] Commented-out the declaration of , because it’s never used. I haven’t deleted it, just in case.

⟨ Define Ellipse functions 1147 ⟩ +≡ unsigned short orientation; const unsigned short = 0; const unsigned short = 1; const unsigned short = 2;

#if 0

const unsigned short = 3; #endif

if (normal x ≡ 0 ∧ normal y ≡ 0 ∧ normal z ≡ 0) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ≪

␣ ≪ flush; return ;

} else if (normal x ≡ 0 ∧ normal y ≡ 0) /∗ Ellipse lies in a plane parallel to x-y plane. ∗/ {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; orientation = ;

} else if (normal x ≡ 0 ∧ normal z ≡ 0) /∗ Ellipse lies in a plane parallel to x-z plane. ∗/ {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; orientation = ;

} else if (normal z ≡ 0 ∧ normal y ≡ 0) /∗ Ellipse lies in a plane parallel to z-y plane. ∗/ {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; orientation = ;

} else /∗ Ellipse doesn’t lie in a plane parallel to a major plane. ∗/ {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush;

/∗ Put it in x-z plane. ∗/ if ( ) {

copy center .dotlabel ( ); } Point ellipse pt0 = copy .get point (0); Transform t0 ; t0 .align with axis (copy center , ellipse pt0 , ); copy ∗= t0 ; copy center ∗= t0 ; ellipse pt0 ∗= t0 ; e ∗= t0 ; if ( ) { ellipse pt0 .show ( ); ellipse pt0 .dotlabel ( );

} Point ellipse pt4 = copy .get point (number of points /4); if ( ) ellipse pt4 .show ( ); Transform t1 ; t1 .align with axis (copy center , ellipse pt4 , ); copy ∗= t1 ; copy center ∗= t1 ; e ∗= t1 ; ellipse pt4 ∗= t1 ; t ∗= t0 ; t ∗= t1 ; orientation = ;

} t inverse = t.inverse( ); Point e center = e.get center ( ); if ( ) {

copy center .show ( ); e center .show ( );

} 1222. Ellipses have the same center and orientation. If they do, then there is an algebraic solution we can apply to find the intersection points. ⟨ Define Ellipse functions 1147 ⟩ +≡

Point copy axis orientation(copy .get point (0)); copy axis orientation −= copy center ; copy axis orientation.unit vector (true); e axis orientation = e.get point (0); e axis orientation −= e center ; e axis orientation.unit vector (true); if ((e center ≡ origin ∧ copy center ≡

origin) ∧ ((copy axis orientation ≡ e axis orientation ∨ copy axis orientation ≡

−e axis orientation) ∨ (copy axis orientation ≡ e axis orientation rotated ∨ copy axis orientation ≡ −e axis orientation rotated ))) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; Point pt20 ; Point pt21 ; Point pt22 ; Point pt23 ; real x; real y; real a = ax h/2.0; real b = ax v /2.0; real c = e.get axis h( )/2.0; real d = e.get axis v ( )/2.0; if ( ) {

cout ≪ ␣ ␣ ≪ a ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ b ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ c ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ d ≪ endl ≪ flush; } real aa = (a ∗ a); real bb = (b ∗ b); real cc = (c ∗ c); real dd = (d ∗ d); if ( ) {

cout ≪ ␣ ␣ ≪ aa ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ bb ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ cc ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ dd ≪ endl ≪ flush; } real denominator ; real numerator ; if ( ) cout ≪ ␣ ; denominator = (aa − ((bb ∗ cc)/dd )) ∗ dd ; numerator = bb ∗ (aa − cc); if ( ) {

cout ≪ ␣ ␣ ≪ numerator ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ denominator ≪ endl ≪ flush;

} if (denominator ≡ 0) {

if (  ) cout ≪ ␣  ␣  ;

x = ; } else {

try {

x = −(c ∗ sqrt (1 − (numerator /denominator ))); } catch( …) {

x = ;

if ( ) cout ≪ ␣ ␣ ; }

} if ( ) {

cout ≪ ␣ ␣ ≪ x ≪ endl ≪ flush; cout ≪ ␣ ;

} numerator = b ∗ sqrt (fabs (aa − cc)); denominator = sqrt (fabs (aa − ((bb ∗ cc)/dd ))); if ( ) {

cout ≪ ␣ ␣ ≪ numerator ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ denominator ≪ endl ≪ flush;

} if (denominator ≡ 0) {

if ( ) cout ≪ ␣ ␣ ; y = ;

} else {

try {

y = −(numerator /denominator ); } catch( …) {

y = ;

if ( ) cout ≪ ␣ ␣ ; }

} if ( ) {

cout ≪ ␣ ␣ ≪ y ≪ endl ≪ flush; } 1223. The ellipses can intersect at no points, two points, or four points.

• If they do not intersect, then one of the ellipses must be inside the other.

• If they intersect at two points, then either x = 0 or y = 0 (but not both).

• Otherwise, they intersect at four points. ⟨ Define Ellipse functions 1147 ⟩ +≡

if (x ≡  ∨ y ≡  ) {
cerr ≪  ␣  ␣  ≪

    ␣     ␣          ␣ ≪  ␣  ;

return ; } else if (orientation ≡ ) {

pt20 .set (x, y, 0); pt21 .set (−x, −y, 0); if (y ≠ 0 ∧ x ≠ 0) {

pt22 .set (x, −y, 0);

pt23 .set (−x, y, 0); } else {

pt22 = ; pt23 = ;

} } else if (orientation ≡ ) {

pt20 .set (x, 0, y); pt21 .set (−x, 0, −y); if (y ≠ 0 ∧ x ≠ 0) {

pt22 .set (x, 0, −y);

pt23 .set (−x, 0, y); } else {

pt22 = ; pt23 = ;

} } else if (orientation ≡ ) {

pt20 .set (0, y, x); pt21 .set (0, −y, −x); if (x ≠ 0 ∧ y ≠ 0) {

pt22 .set (0, y, −x);

pt23 .set (0, −y, x); } else {

pt22 = ; pt23 = ;

} } else {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ orientation ≪ endl ≪ ␣ ␣ ␣ ␣ ≪ flush;

} if ( ) { pt20 .show ( ); pt20 .dotlabel ( ); pt21 .show ( ); pt21 .dotlabel ( ); pt22 .show ( ); pt22 .dotlabel ( ); pt23 .show ( ); pt23 .dotlabel ( );

} signed short ss copy ; signed short ss e; if (pt20 ≠ ) {

ss copy = copy .location(pt20 ); if ( ) cout ≪ ␣ ␣ ≪ ss copy ≪ endl ≪ flush; ss e = e.location(pt20 ); if ( ) cout ≪ ␣ ␣ ≪ ss e ≪ endl ≪ flush;

} if (ss copy ≡ 0 ∧ ss e ≡ 0) {

pt20 ∗= t inverse; pt21 ∗= t inverse; bpq .first .b = true; bpq .first .pt = pt20 ; bpq .second .b = true; bpq .second .pt = pt21 ; if (pt22 ≠ ) {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ;

pt22 ∗= t inverse;

bpq .third .b = true;

bpq .third .pt = pt22 ; } else {

if ( ) cout ≪ ␣ ␣ ␣ ␣ ; } if (pt23 ≠ ) {

pt23 ∗= t inverse;

bpq .fourth.b = true;

bpq .fourth.pt = pt23 ; } return bpq ;

} /∗ if ∗/ else {

cerr ≪ ␣ ␣ ; ss e = e.location(copy .get point (0)); if (ss e ≡ 1) cerr ≪ ␣ ␣ ␣ ␣ ; else if (ss e ≡ −1) cerr ≪ ␣ ␣ ␣ ␣ ; else {

cerr ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ ss e ≪ endl ; } cerr ≪ ␣ ≪ ␣ ; return ;

} } /∗ End of “Ellipses have the same center and axis orientation”. ∗/ 1224. Ellipses have different centers and/or axis orientation. There is no simple algebraic solution for this case, so I have to implement a numerical one here. ⟨ Define Ellipse functions 1147 ⟩ +≡

else {

if (  ) cout ≪  ␣   ␣        ␣      ␣    ␣   ␣    ␣      ␣      ␣ ≪

    ␣    ␣           ␣  ␣  ;

Point curr point ; signed short curr location; signed short location switch; unsigned short intersection ctr = 0; real save angle; real in angle; real out angle; real test angle; if ( ) {

e.show ( ); copy .show ( );

}

cout ≪  ␣  ≪

  ␣   ␣        ␣             ␣ ≪  ␣   ␣    ␣    ␣  ≪ flush;

for (real i = 0; i < 360; i += step) { if ( ) cout ≪ ␣ ␣ ≪ i ≪ endl ≪ flush; curr point = copy .angle point (i); if ( ) curr point .show ( ); curr location = e.location(curr point ); if ( ) cout ≪ ␣ ␣ ≪ curr location ≪ endl ≪ flush; if (curr location ≡ 0) {

if ( ) { cout ≪ ␣ ␣ ␣ ; curr point .show ( );

}

⟨ Handle intersection point 1225 ⟩

i += .5;

save angle = i;

curr point = copy .angle point (i);

location switch = e.location(curr point );

continue; } /∗ if . End of “Found an intersection point”. ∗/ else if (i ≡ 0) {

location switch = curr location;

save angle = 0;

continue; } else if (curr location ≡ 1) {

if ( ) cout ≪ ␣ ␣ ␣ ; } else if (curr location ≡ −1) {

if ( ) cout ≪ ␣ ␣ ␣ ; } else {

cerr ≪  ␣  ␣  ≪

␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ curr location ≪ ␣ ≪ ␣ ≪ flush;

return ; } if (curr location ≠ location switch) {

if ( ) { cout ≪ ␣ ␣ ; cout ≪ ␣ ␣ ≪ i ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ save angle ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ curr location ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ location switch ≪ endl ≪ flush;

} if (location switch ≡ 1) {

in angle = save angle; out angle = i;

} else {

in angle = i; out angle = save angle;

} while (true) {

test angle = (in angle + out angle)/2; curr point = copy .angle point (test angle); curr location = e.location(curr point ); if (curr location ≡ 0) {

if ( ) { cout ≪ ␣ ␣ ␣ ; curr point .show ( );

}

⟨ Handle intersection point 1225 ⟩

i = floor (test angle);

i += .5;

if (i < test angle) i += .5;

save angle = i;

curr point = copy .angle point (i);

location switch = e.location(curr point );

break; } else if (curr location ≡ 1) {

in angle = test angle;

continue; } else if (curr location ≡ −1) {

out angle = test angle;

continue; } else {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ curr location ≪ ␣ ≪ flush;

return ;

} } /∗ while ∗/

} /∗ if ∗/ } /∗ for ∗/ cout ≪ ␣ ␣ ␣ ␣ ≪ endl ≪ endl ≪ flush;

} /∗ End of “Ellipses have different centers and/or axis orientation”. ∗/ } /∗ End of coplanar case. ∗/

1225. Handle intersection point. ⟨ Handle intersection point 1225 ⟩ ≡

{ ++intersection ctr ; if ( ) {

cout ≪ ␣ ␣ ≪ intersection ctr ≪ endl ≪ flush; } if (intersection ctr ≡ 1) {

bpq .first .b = true; bpq .first .pt = curr point ; bpq .first .pt ∗= t inverse;

} else if (intersection ctr ≡ 2) {

bpq .second .b = true; bpq .second .pt = curr point ; bpq .second .pt ∗= t inverse;

} else if (intersection ctr ≡ 3) {

bpq .third .b = true; bpq .third .pt = curr point ; bpq .third .pt ∗= t inverse;

} else if (intersection ctr ≡ 4) {

bpq .fourth.b = true; bpq .fourth.pt = curr point ; bpq .fourth.pt ∗= t inverse; if ( ∨ verbose) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ≪

      ␣      ␣            ␣  ≪  ␣  ;

} return bpq ;

} else {

cerr ≪  ␣  ␣  ≪

    ␣     ␣       ␣ ␣       ␣     ␣   ␣ ≪  ␣ ≪

intersection ctr ≪  ␣  ;

return ; }

}

This code is used in section 1224.

1226. Parallel and non-coplanar case. ⟨ Define Ellipse functions 1147 ⟩ +≡

else {

cerr ≪  ␣  ␣  ≪

      ␣   ␣  ␣        ␣       ␣ ≪ ␣    ␣     ␣  ≪
      ␣  ;

return ; } } 1227. Perpendicular and skew cases. These cases are handled in exactly the same way. ⟨ Define Ellipse functions 1147 ⟩ +≡

else { if ( ) cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ≪ flush; Line isect line(this plane.intersection line(e plane)); if ( ) isect line.show ( ); Point pt0 (isect line.direction); pt0 .shift (isect line.position); bool point pair bpp = intersection points (isect line.position, pt0 ); if ( ) {

cout ≪ ␣ ␣ ≪ bpp.first .b ≪ endl ≪ flush; bpp.first .pt .show ( ␣ ␣ ); cout ≪ ␣ ␣ ≪ bpp.second .b ≪ endl ≪ flush; bpp.second .pt .show ( ␣ ␣ );

} bpq .first .pt = bpp.first .pt ; bpq .first .b = (bpp.first .pt ≡ ) ? false : true; bpq .second .pt = bpp.second .pt ; bpq .second .b = (bpp.second .pt ≡ ) ? false : true; bpp = e.intersection points (isect line.position, pt0 ); bpq .third .pt = bpp.first .pt ; bpq .third .b = (bpp.first .pt ≡ ) ? false : true; bpq .fourth.pt = bpp.second .pt ; bpq .fourth.b = (bpp.second .pt ≡ ) ? false : true; signed short s t ; signed short s e; bool temp bool ; string temp string ; if (bpq .first .b) {

s t = location(bpq .first .pt );

s e = e.location(bpq .first .pt );

temp bool = bpq .first .b;

temp string = ;

⟨ Check intersection point locations 1228 ⟩ } else if (verbose) cout ≪ ␣ ␣ ␣ ␣ ; if (bpq .second .b) {

s t = location(bpq .second .pt );

s e = e.location(bpq .second .pt );

temp bool = bpq .second .b;

temp string = ;

⟨ Check intersection point locations 1228 ⟩ } else if (verbose) cout ≪ ␣ ␣ ␣ ␣ ; if (bpq .third .b) {

s t = location(bpq .third .pt );

s e = e.location(bpq .third .pt );

temp bool = bpq .third .b;

temp string = ;

⟨ Check intersection point locations 1228 ⟩ } else if (verbose) cout ≪ ␣ ␣ ␣ ␣ ; if (bpq .fourth.b) {

s t = location(bpq .fourth.pt ); s e = e.location(bpq .fourth.pt ); temp bool = bpq .fourth.b; temp string = ; ⟨ Check intersection point locations 1228 ⟩

} else if (verbose) cout ≪ ␣ ␣ ␣ ␣ ;

} /∗ else. End of perpendicular and skew cases. ∗/ if ( ∨ verbose) cout ≪ ␣ ≪ flush; return bpq ; }

1228. Check intersection point locations. This is used in the “Perpendicular and Skew Cases” of intersection points (Ellipse e, const bool verbose). [LDF 2003.07.01.]

Log

[LDF 2003.07.01.] Added this section.

⟨ Check intersection point locations 1228 ⟩ ≡

if (temp bool ) {

if (verbose) {

if (s t ≡ 0 ∧ s e ≡ 0)

cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; else if (s t ≡ 0) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; else if (s t ≡ −1) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ; else if (s t ≡ 1) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ; else if (s t ≡ −2) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; if (s e ≡ 0 ∧ s t ≠ 0) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ; if (s e ≡ −1) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ; else if (s e ≡ 1) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ; else if (s e ≡ −2) cout ≪ temp string ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

} }

This code is used in section 1227.

1229. Transformations.

Log

[LDF 2003.04.27.] Finished adding the transformation functions. I already had shift ( ), now I have the rest of them.

1230. Performing a transformation.

356  DO TRANSFORM  3DLDF-1.1.5.1 §1231

1231. Do transform. [LDF 2003.07.20.] Performs a transformation on ∗this .

If check ≡ true, is elliptical ( ) is called on ∗this following the transformation. If the latter causes ∗this to become non-elliptical, axis h, axis v , linear eccentricity , and numerical eccentricity are set to , and a warning is issued to stderr . center , focus0 , and focus1 are not set to . They 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 ≡ true, and the transformation does not cause ∗this to become non-elliptical, axis h and axis v are recalculated.

Log

[LDF 2003.07.20.] Added this function. It makes it possible to perform a transformation on an Ellipse, optionally calling is elliptical ( ). It is called in is elliptical ( ) with check ≡ false. This prevents operator∗=( ) and is elliptical ( ) from calling each other ad infinitum.

[LDF 2003.07.25.] Added code for recalculating linear eccentricity , focus0 and focus1 .

[LDF 2003.07.25.] BUG FIX: axis h and axis v were too small by half. Now multiplying by 2.

[LDF 2003.07.25.] Added code for recalculating numerical eccentricity .

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform do transform(const Transform &t, bool check = false);

§1232  3DLDF-1.1.5.1  DO TRANSFORM 357

1232. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::do transform(const Transform &t, bool check ) {

bool = false; /∗ true ∗/ focus0 ∗= focus1 ∗= center ∗= Path ::operator∗=(t); real old axis h = axis h; real old axis v = axis v ; if (check ) {

if (is elliptical ( )) { Point c = get center ( ); axis h = (get point (0) − c).magnitude( ) ∗ 2; axis v = (get point (number of points /4) − c).magnitude( ) ∗ 2; real axis h half = axis h/2; real axis v half = axis v /2; if (fabs (axis h − old axis h) > Point ::epsilon( ) ∨ fabs (axis v − old axis v ) > Point ::epsilon( )) {

if ( ) cout ≪ ␣ ␣ ≪

␣ ␣ ≪ flush; if (axis h ≥ axis v ) {

linear eccentricity = sqrt ((axis h half ∗ axis h half ) − (axis v half ∗ axis v half )); numerical eccentricity = linear eccentricity /axis h half ; focus1 = focus0 = (get point (0) − get center ( ));

}

else { linear eccentricity = sqrt ((axis v half ∗ axis v half ) − (axis h half ∗ axis h half )); numerical eccentricity = linear eccentricity /axis v half ; focus1 = focus0 = (get point (number of points /4) − get center ( ));

}

focus0 .unit vector (true);

focus1 .unit vector (true);

focus0 ∗= −linear eccentricity ;

focus1 ∗= linear eccentricity ;

focus1 ∗= focus0 .shift (get center ( )); } else if ( )

cout ≪ ␣ ␣ ␣ ␣ ≪ ␣ ␣ ≪ flush; } /∗ if (is elliptical ( )) ∗/ else {

cerr ≪ ␣ ␣ ␣ ≪

␣ ␣ ␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; axis h = axis v = linear eccentricity = ; numerical eccentricity = ;

} } return t;

}

358  OPERATOR  3DLDF-1.1.5.1 §1233

1233. Operator.

Log

[LDF 2002.04.12.] Added this section.

[LDF 2003.07.20.] Changed, so that it calls do transform( ) with check ≡ true, so that is elliptical ( ) is called.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform operator∗=(const Transform &t);

1234. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::operator∗=(const Transform &t)

{

return do transform(t, true); }

1235. Rotation around the main axes.

Log

[LDF 2003.07.25.] Changed, so that do transform( ) is called with check ≡ false. Rotation can neither change the lengths of axis h or axis v , nor make an Ellipse non-elliptical, so there’s no need to check ∗this after rotation.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform rotate(const real x, const real y = 0, const real z = 0);

1236. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::rotate(const real x, const real y, const real z)

{ Transform t; t.rotate(x, y, z); return do transform(t, false);

}

1237. Scale.

Log

[LDF 2003.07.20.] Added check for whether ∗this is still elliptical after the scaling operation.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform scale(real x, real y = 1, real z = 1); 1238. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::scale(real x, real y, real z)

{ Transform t; t.scale(x, y, z); return (∗this ∗= t);

}

1239. Shear.

Log

[LDF 2003.07.20.] Added check for whether ∗this is still elliptical after the shearing operation.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform shear (real xy , real xz = 0, real yx = 0, real yz = 0, real zx = 0, real zy = 0);

1240. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::shear (real xy , real xz , real yx , real yz , real zx , real zy )

{ Transform t; t.shear (xy , xz , yx , yz , zx , zy ); return (∗this ∗= t);

}

1241. Shift.

1242. real arguments.

Log

[LDF 2003.07.25.] Changed, so that do transform( ) is called with check ≡ false. Shifting can neither change the lengths of axis h or axis v , nor make an Ellipse non-elliptical, so there’s no need to check ∗this after shifting.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform shift (real xx , real yy = 0, real zz = 0);

1243. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::shift (real xx , real yy , real zz )

{ Transform t; t.shift (xx , yy , zz ); return do transform(t, false);

}

1244. Point argument. ⟨ Declare Ellipse functions 1146 ⟩ +≡

virtual Transform shift (const Point &p); 1245. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::shift (const Point &p)

{

return shift (p.get x ( ), p.get y ( ), p.get z ( )); }

1246. Shift times.

1247. real arguments.

Log

[LDF 2003.07.25.] Now performing shift times ( ) on focus0 and focus1 , too.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual void shift times (real x, real y = 1, real z = 1);

1248. ⟨ Define Ellipse functions 1147 ⟩ +≡

void Ellipse ::shift times (real x, real y, real z)

{ Path ::shift times (x, y, z); focus1 .shift times (x, y, z); focus0 .shift times (x, y, z); center .shift times (x, y, z); return;

}

1249. Point argument. ⟨ Declare Ellipse functions 1146 ⟩ +≡

virtual void shift times (const Point &p);

1250. ⟨ Define Ellipse functions 1147 ⟩ +≡

void Ellipse ::shift times (const Point &p)

{

return shift times (p.get x ( ), p.get y ( ), p.get z ( )); }

1251. Rotatation around an arbitrary axis.

1252. Point arguments.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

[LDF 2003.07.25.] Changed, so that do transform( ) is called with check ≡ false. Rotation can neither change the lengths of axis h or axis v , nor make an Ellipse non-elliptical, so there’s no need to check ∗this after rotation.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform rotate(const Point &p0 , const Point &p1 , const real angle = 180);

1253. ⟨ Define Ellipse functions 1147 ⟩ +≡

Transform Ellipse ::rotate(const Point &p0 , const Point &p1 , const real angle)

{ Transform t; t.rotate(p0 , p1 , angle); return do transform(t, false);

}

1254. Path arguments.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Ellipse functions 1146 ⟩ +≡ virtual Transform rotate(const Path &p, const real angle = 180); 1255.

Log

[LDF 2003.04.27.] Changed get point (1) to get last point ( ).

⟨ Define Ellipse functions 1147 ⟩ +≡ Transform Ellipse ::rotate(const Path &p, const real angle) {

if (¬p.is linear ( )) {

cerr ≪  ␣  ␣                     ␣  ≪

        ␣  ␣   ␣ ␣      ␣␣         ␣  ;

return ; } return rotate(p.get point (0), p.get last point ( ), angle);

}

1256. Rectangles.

1257. Surrounding rectangle.

Log

[LDF 2003.07.18.] Made const.

⟨ Declare Ellipse functions 1146 ⟩ +≡ Rectangle out rectangle( ) const;

§1258  3DLDF-1.1.5.1  SURROUNDING RECTANGLE 363

1258. ⟨ Define Ellipse functions 1147 ⟩ +≡

Rectangle Ellipse ::out rectangle( ) const {

Point C(get center ( )); Point pt0 (get point (0)); Point pt1 (get point (number of points /2)); Path pa0 (pt0 , pt1 ); Point pt2 (get point (number of points /4)); Point pt3 (get point (3 ∗ number of points /4)); Point pt4 (pt1 ); pt4 −= C; Point pt5 (pt2 ); pt5 .shift (pt4 ); Point pt6 (pt3 ); pt6 .shift (pt4 ); Point pt7 (pt0 ); pt7 −= C; Point pt8 (pt2 ); pt8 .shift (pt7 ); Point pt9 (pt3 ); pt9 .shift (pt7 );

#if 0 pt0 .dotlabel ( ); pt1 .dotlabel ( ); pt2 .dotlabel ( ); pt3 .dotlabel ( ); pt5 .dotlabel ( ); pt6 .dotlabel ( ); pt8 .dotlabel ( ); pt9 .dotlabel ( );

#endif Rectangle r(pt6 , pt9 , pt8 , pt5 ); return r;

}

1259. Inscribed rectangle.

Log

[LDF 2003.07.18.] Made const.

⟨ Declare Ellipse functions 1146 ⟩ +≡ Rectangle in rectangle( ) const;

364  INSCRIBED RECTANGLE  3DLDF-1.1.5.1 §1260

1260. ⟨ Define Ellipse functions 1147 ⟩ +≡

Rectangle Ellipse ::in rectangle( ) const {

Rectangle r0 = out rectangle( );

bool point pair bpp0 = intersection points (r0 .get point (0), r0 .get point (2)); bool point pair bpp1 = intersection points (r0 .get point (1), r0 .get point (3)); if (bpp0 .first .pt ≡ ∨ bpp0 .second .pt ≡ ∨ bpp1 .first .pt ≡

∨ bpp1 .second .pt ≡ ) { cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪ flush; Rectangle r2 ; return r2 ;

}

Rectangle r1 (bpp0 .second .pt , bpp1 .first .pt , bpp0 .first .pt , bpp1 .second .pt );

return r1 ; }

1261. Draw surrounding rectangle.

Log

[LDF 2003.07.01.] Changed the return value from void to Rectangle. Now the surrounding Rectangle is returned.

[LDF 2003.07.18.] Made const.

⟨ Declare Ellipse functions 1146 ⟩ +≡

Rectangle draw out rectangle(const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , Picture &picture = current picture) const;

1262. ⟨ Define Ellipse functions 1147 ⟩ +≡

Rectangle Ellipse ::draw out rectangle(const Color &ddraw color , string ddashed , string

ppen, Picture &picture) const

{ Rectangle r = out rectangle( ); r.draw (ddraw color , ddashed , ppen, picture); return r;

}

1263. Draw inscribed rectangle.

Log

[LDF 2003.07.01.] Changed the return value from void to Rectangle. Now the inscribed Rectangle is returned.

[LDF 2003.07.18.] Made const.

⟨ Declare Ellipse functions 1146 ⟩ +≡

Rectangle draw in rectangle(const Color &ddraw color = ∗Colors ::default color , string ddashed = , string ppen = , Picture &picture = current picture) const;

§1264  3DLDF-1.1.5.1  DRAW INSCRIBED RECTANGLE 365

1264. ⟨ Define Ellipse functions 1147 ⟩ +≡

Rectangle Ellipse ::draw in rectangle(const Color &ddraw color , string ddashed , string

ppen, Picture &picture) const

{ Rectangle r = in rectangle( ); r.draw (ddraw color , ddashed , ppen, picture); return r;

}

1265. Rectangle functions. [LDF 2003.07.18.] TO DO: Add undraw in ellipse( ), fill out ellipse( ), etc. Also, I should add versions with the Picture argument first.

Log

[LDF 2003.07.18.] Added this section. These functions are declared in rectangs.web, but must be defined here, because Ellipse is an incomplete type there.

1266. Ellipses.

366  SURROUNDING ELLIPSE  3DLDF-1.1.5.1 §1267

1267. Surrounding Ellipse.

Log

[LDF 2003.07.18.] Added this function.

⟨ Define Rectangle functions 1104 ⟩ +≡ Ellipse Rectangle ::out ellipse( ) const {

Point C = get center ( ); Point p0 = get point (0); Point M = get mid point (1); Point normal = get normal ( ); normal .shift (C); real out distance = (p0 − C).magnitude( ); Transform t; real h length = (get point (1) − p0 ).magnitude( ); real v length = (get point (3) − p0 ).magnitude( ); p0 ∗= M ∗= C ∗= t.align with axis (C, normal , ); Point x axis pt (1); real angle = M.angle(x axis pt ); p0 ∗= M ∗= t.rotate(0, angle); if (M.unit vector ( ) ≠ x axis pt ) {

  cerr ≪  ␣  ␣  ≪ ␣  ␣   ␣   ␣  ␣  ;

M.show ( );

/∗ I’d rather output this to stderr , but I don’t have a way to do this yet. [LDF 2003.07.18.] ∗/ cout ≪ endl ≪ flush;

} Ellipse e(origin, h length, v length); bool point pair bpp = e.intersection points (origin, p0 ); real in distance; if (bpp.first .b) {

in distance = bpp.first .pt .magnitude( ); } else if (bpp.second .b) {

in distance = bpp.second .pt .magnitude( ); } else {

cerr ≪  ␣  ␣  ≪
␣    ␣            ␣  ≪  ␣     ␣  ≪ flush;

Ellipse r;

return r; } real scale value = out distance/in distance; e.scale(scale value, 0, scale value); e ∗= t.inverse( ); return e;

}

§1268  3DLDF-1.1.5.1  ENCLOSED ELLIPSE 367

1268. Enclosed Ellipse.

Log

[LDF 2003.07.18.] Added this function.

⟨ Define Rectangle functions 1104 ⟩ +≡ Ellipse Rectangle ::in ellipse( ) const {

Point C = get center ( ); Point M = get mid point (1); Point normal = get normal ( ); normal .shift (C); Transform t; real h length = (get point (1) − get point (0)).magnitude( ); real v length = (get point (3) − get point (0)).magnitude( ); M ∗= C ∗= t.align with axis (C, normal , ); Point x axis pt (1); real angle = M.angle(x axis pt ); M ∗= t.rotate(0, angle); if (M.unit vector ( ) ≠ x axis pt ) {

  cerr ≪  ␣  ␣  ≪ ␣  ␣   ␣   ␣  ␣  ;

M.show ( );

/∗ I’d rather output this to stderr , but I don’t have a way to do this yet. [LDF 2003.07.18.] ∗/ cout ≪ endl ≪ flush;

} Ellipse e(origin, h length, v length); e ∗= t.inverse( ); return e;

}

1269. Draw surrounding Ellipse. [LDF 2003.07.18.] TO DO: Add version with Picture argument first.

Log

[LDF 2003.07.18.] Added this function.

⟨ Define Rectangle functions 1104 ⟩ +≡

Ellipse Rectangle ::draw out ellipse(const Color &ddraw color , string ddashed , string ppen, Picture

&picture) const

{ Ellipse e = out ellipse( ); e.draw (ddraw color , ddashed , ppen, picture); return e;

}

368  DRAW ENCLOSED ELLIPSE  3DLDF-1.1.5.1 §1270

1270. Draw enclosed Ellipse. [LDF 2003.07.18.] TO DO: Add version with Picture argument first.

Log

[LDF 2003.07.18.] Added this function.

⟨ Define Rectangle functions 1104 ⟩ +≡

Ellipse Rectangle ::draw in ellipse(const Color &ddraw color , string ddashed , string ppen, Picture

&picture) const

{ Ellipse e = in ellipse( ); e.draw (ddraw color , ddashed , ppen, picture); return e;

}

1271. Putting Ellipse together. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Ellipse 1143 ⟩ ⟨ Define static Ellipse data members 1144 ⟩ ⟨ Define Ellipse functions 1147 ⟩ ⟨ Define Rectangle functions 1104 ⟩ ⟨ Declare non-member template functions for Ellipse 1154 ⟩

§1272  3DLDF-1.1.5.1  PUTTING ELLIPSE TOGETHER 369

1272. This is what’s written to ellipses.h.

⟨ 1272 ⟩ ≡

⟨ Define class Ellipse 1143 ⟩

⟨ Declare non-member template functions for Ellipse 1154 ⟩

1273. Circle (circles.web). It won’t be possible to make circles recede to the central vanishing point. !! Get quote from book!!

Log

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.01.] Put the version control identifiers back into the release versions, because I’ve put them in their own RCS repository.

format Circle Shape

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1274. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1275. Circle class definition.

370 CIRCLE CLASS DEFINITION 3DLDF-1.1.5.1 §1276

1276. ⟨ Define class Circle 1276 ⟩ ≡

class Circle : public Ellipse {

real radius ; public: ⟨ Declare Circle functions 1278 ⟩ };

This code is used in sections 1315 and 1316.

1277. Constructors and setting functions.

1278. Default constructor. No arguments. ⟨ Declare Circle functions 1278 ⟩ ≡

Circle( );

See also sections 1281, 1283, 1290, 1292, 1295, 1297, 1298, 1300, 1302, and 1304. This code is used in section 1276.

1279. ⟨ Define Circle functions 1279 ⟩ ≡

Circle ::Circle( ) {

on free store = false; line switch = false; cycle switch = true;

}

See also sections 1282, 1284, 1291, 1293, 1296, 1301, 1303, and 1305. This code is used in section 1315.

1280. Center, diameters and angles.

1281. Constructor. ⟨ Declare Circle functions 1278 ⟩ +≡

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 = );

1282. ⟨ Define Circle functions 1279 ⟩ +≡

Circle ::Circle(const Point &ccenter , const real ddiameter , const real angle x , const real

angle y , const real angle z , const unsigned short nnumber of points )

: radius (ddiameter /2) { on free store = false; line switch = false; cycle switch = true; center = ccenter ; center .apply transform( ); axis h = axis v = ddiameter ; number of points = nnumber of points ; Ellipse e(center , axis h, axis v , angle x , angle y , angle z , number of points ); ∗this = e;

} 1283. Setting function.

Log

[LDF 2003.05.06.] Added the argument nnumber of points . Without it, this setting function didn’t match the constructor above.

⟨ Declare Circle functions 1278 ⟩ +≡

void set (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 = ); 1284. ⟨ Define Circle functions 1279 ⟩ +≡

void Circle ::set (const Point &ccenter , const real ddiameter , const real angle x , const real

angle y , const real angle z , const unsigned short nnumber of points )

{ Circle c(ccenter , ddiameter , angle x , angle y , angle z , nnumber of points ); ∗this = c; return;

}

1285. Pseudo-constructor for dynamic allocation.

1286. Pointer argument.

Log

[LDF 2003.07.27.] Made non-inline. Made argument p const Circle ∗.

[LDF 2003.08.10.] Removed redefinition of the default argument const Circle ∗p = 0 from the definition. The DEC compiler complained, but GCC didn’t.

[LDF 2003.12.30.] Replaced Circle ::create new circle( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Circle.

[LDF 2003.12.30.] Changed the argument. It’s now a const Circle ∗.

[LDF 2003.12.30.] Removed default argument “0”, because this caused a compiler error when using the DEC C^{++} compiler. Apparently, it suffices to declare a default argument in the template declaration.

⟨ Declare non-member template functions for Circle 1286 ⟩ ≡

Circle ∗create new (const Circle ∗c);

See also section 1287. This code is used in sections 1315 and 1316.

1287. Reference argument.

Log

[LDF 2003.07.27.] Made non-inline.

[LDF 2003.12.30.] Replaced Circle ::create new circle( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Circle.

[LDF 2003.12.30.] Changed argument from Circle to const Circle &.

⟨ Declare non-member template functions for Circle 1286 ⟩ +≡ Circle ∗create new (const Circle &c);

1288. Destructor. [LDF 2002.10.09.] Removed the destructor. Path ::∼Path( ) or Path ::clear ( ) should be used instead, unless I add dynamically allocated data members to Circle (rather than Ellipse or Path).

1289. Assignment.

1290. Circle argument. This function returns a reference to ∗this , which can be used for further assignment.

Log

[LDF 2002.11.10.] Changed and simplified this function. It now uses Ellipse ::operator=( ).

§1290  3DLDF-1.1.5.1  CIRCLE ARGUMENT 373

⟨ Declare Circle functions 1278 ⟩ +≡ Circle &operator=(const Circle &c);

1291. ⟨ Define Circle functions 1279 ⟩ +≡

Circle &Circle ::operator=(const Circle &c)

{ radius = c.radius ; Ellipse ::operator=(c); return ∗this ;

}

1292. Ellipse argument. This function returns a reference to ∗this , which can be used for further assignment.

Log

[LDF 2002.11.10.] Changed and simplified this function. It now uses Ellipse ::operator=( ).

[LDF 2003.08.14.] Added code for handling the case that e.axis v and e.axis h differ by a small amount, possible due to imprecision (see below).

⟨ Declare Circle functions 1278 ⟩ +≡ Circle &operator=(const Ellipse &e); 1293. If e.axis v ≠ e.axis h, it’s quite possible that the difference is negligible, and the result of imprecision resulting from the representation of floating point numbers, or calculations performed on them. Therefore, we compare the absolute value of their difference with Point ::epsilon( ) instead of checking whether they’re equal. [LDF 2003.08.14.]

It’s also possible that one of them has an integer value, i.e., it has only zeroes following the decimal point, and the other deviates by a small amount. In this case, we want to set radius to half of the former, because it’s probably the correct value. So, if e axis v ≡ floor (e axis v ), we set radius to e axis v /2. Otherwise, we set radius to e axis h without further ado. If e axis h ≡ floor (e axis h), so much the better, and if it isn’t, neither it nor e axis v has an integer value, so it doesn’t matter which one we use to set radius .

[LDF 2003.08.14.]

⟨ Define Circle functions 1279 ⟩ +≡ Circle &Circle ::operator=(const Ellipse &e) {

real e axis v = e.get axis v ( ); real e axis h = e.get axis h( ); if (e axis v ≠ e axis h) {

if (fabs (e axis v − e axis h) > Point ::epsilon( )) {

cerr ≪  ␣  ␣  ≪  ␣   ␣        ␣     ␣ ≪

           ␣       ␣           ␣  ;

return ∗this ; } else if (e axis v ≡ floor (e axis v )) radius = e axis v /2.0; else radius = e axis h/2.0;

}

else radius = e.get axis v ( )/2.0; Ellipse ::operator=(e); return ∗this ;

}

1294. Returning elements and information.

1295. Is circular. Tests whether ∗this is circular. Operations such as scale( ) and shear ( ) can cause Circles to become non-circular. [LDF 2003.07.25.]

is circular ( ) first tests whether ∗this is planar using is planar ( ). If it’s not, false is returned. Otherwise, the Point p is set to ∗(points [0]), and Point c = get center ( ) is is subtracted from p. p.magnitude( ) is then stored in real mag0 . [LDF 2003.07.25.]

Then, p is set to each of the other Points on the Circle in turn, c is subtracted from p, and p.magnitude( ) is stored in real mag . If the absolute value of the difference mag − mag0 is greater than Point ::epsilon( ), is circular ( ) immediated returns false. If fabs (mag − mag0 ) ≤ Point ::epsilon( ) for all of the Points ∗(points [n]) for n > 0, is circular ( ) returns true. [LDF 2003.07.25.]

Log

[LDF 2003.07.25.] Added this function.

⟨ Declare Circle functions 1278 ⟩ +≡ bool is circular (void) const;

§1296  3DLDF-1.1.5.1  IS CIRCULAR 375

1296. ⟨ Define Circle functions 1279 ⟩ +≡

bool Circle ::is circular (void) const {

bool  = true;  /∗ false ∗/
if (  ) cout ≪  ␣  ;

if (¬is planar ( )) {

if ( )

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

endl ≪ endl ≪ flush; return false;

} Point p; Point c = get center ( ); real mag0 ; real mag ; vector⟨Point ∗⟩::const iterator iter = points .begin( ); p = ∗∗iter^{++} − c; mag0 = p.magnitude( ); for (int i = 1; iter ≠ points .end ( ); ^{++}iter ) {

p = ∗∗iter − c;

mag = p.magnitude( );

if (fabs (mag − mag0 ) > Point ::epsilon( )) {

if (  ) cerr ≪  ␣ ≪ i ≪ ␣       ␣   ␣  ␣  ≪
␣  ≪  ␣  ≪ flush;

return false; } ++i;

} if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; return true;

}

1297. Get radius.

Log

[LDF 2002.05.10.] Added this function.

⟨ Declare Circle functions 1278 ⟩ +≡ inline real get radius ( ) {

return radius ; }

1298. Get diameter. [LDF 2002.05.10.] Added this function. ⟨ Declare Circle functions 1278 ⟩ +≡

inline real get diameter ( ) {

return (2 ∗ radius ); }

376  INTERSECTIONS  3DLDF-1.1.5.1 §1299

1299. Intersections. Neither GCC nor the DEC compiler could resolve a call to intersection points ( ) with Point arguments to Ellipse ::intersection points ( ), after a Circle version with a Circle argument had been declared. TO DO: I didn’t think this would happen, so I should probably review the rules governing resolution of calls to functions on objects of derived classes. [LDF 2003.07.09.]

Therefore, I’ve added Circle versions of this function, with Point and Path arguments, that simply call the Ellipse versions, and return their return values. This solves the problem. [LDF 2003.07.09.]

The program executed correctly under Linux, after I recompiled with GCC. However, under Tru65, the program caused a “Memory fault” error. After I removed the object files, and recompiled (with the DEC compiler), the problem disappeared. [LDF 2003.07.09.]

[LDF 2003.07.18.] TO DO: Add Circle ::intersection points (const Ellipse &) and Ellipse ::intersection points (const Circle &).

1300. Point argument.

Log

[LDF 2003.07.09.] Added this function.

⟨ Declare Circle functions 1278 ⟩ +≡ virtual bool point pair intersection points (const Point &pt0 , const Point &pt1 ) const;

1301. ⟨ Define Circle functions 1279 ⟩ +≡

bool point pair Circle ::intersection points (const Point &pt0 , const Point &pt1 ) const {

return Ellipse ::intersection points (pt0 , pt1 ); }

1302. Path argument.

Log

[LDF 2003.07.09.] Added this function.

⟨ Declare Circle functions 1278 ⟩ +≡ virtual bool point pair intersection points (const Path &p) const;

§1303  3DLDF-1.1.5.1  PATH ARGUMENT 377

1303. ⟨ Define Circle functions 1279 ⟩ +≡

bool point pair Circle ::intersection points (const Path &p) const {

return Ellipse ::intersection points (p); }

1304. Circle argument.

Log

[LDF 2003.07.20.] Wrote the definition of this function. Tested all cases. It should probably be tested more thoroughly.

[LDF 2003.08.14.] Made verbose argument non-const. Setting verbose to true if is true. Added to pspglb.web today.

[LDF 2003.08.27.] Removed the declaration real c radius = c.radius , since c radius was never used.

378 CIRCLE ARGUMENT 3DLDF-1.1.5.1 §1305

⟨ Declare Circle functions 1278 ⟩ +≡ virtual bool point quadruple intersection points (const Circle &c, bool verbose = false) const; 1305. ⟨ Define Circle functions 1279 ⟩ +≡

bool point quadruple Circle ::intersection points (const Circle &c, bool verbose) const {

bool = false; /∗ true ∗/ if ( ) verbose = true;

if (  ∨ verbose) cout ≪  ≪

␣                                 ␣  ;

bool point quadruple bpq = ; Plane this plane = get plane( ); Plane c plane = c.get plane( ); if (¬(this plane.normal ≡ c plane.normal ∨ this plane.normal ≡ −c plane.normal )) {

if (verbose ∨ ) cout ≪ ␣ ␣ ␣ ≪

␣ ≪ flush; bpq = Ellipse ::intersection points (c, verbose); if ( )

cout ≪ ␣ ␣ ≪ endl ≪ endl ≪ flush; return bpq ;

} else {

if (verbose ∨ ) cout ≪ ␣ ␣ ; real dist = (c.center − center ).magnitude( ); if ( ) cout ≪ ␣ ␣ ≪ dist ≪ endl ≪ flush; if (dist ≡ 0) {

if (verbose ∨ ) cout ≪ ␣ ␣ ␣ ; if (radius ≡ c.radius ) {

if (verbose ∨ ) {

cout ≪ ␣ ␣ ␣ ≪ ␣

≪ flush; } if ( ) cout ≪ ␣ ␣ ≪

endl ≪ endl ≪ flush; return ;

} else if (radius > c.radius ) {

if (verbose ∨ ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ≪ endl ≪

␣ ≪ flush; } if ( ) cout ≪ ␣ ␣ ≪

endl ≪ endl ≪ flush; return ;

} else if (radius < c.radius ) {

if (verbose ∨ ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ endl ≪

␣ ≪ flush; } if ( ) cout ≪ ␣ ␣ ≪

endl ≪ endl ≪ flush; return ; } else {

cerr ≪  ␣  ␣ ≪  ␣  ≪ endl ≪

      ␣     ␣  ≪  ␣      ␣        ␣    ␣       ␣  ≪

␣ ␣ ≪ radius ≪ endl ≪ ␣ ␣ ≪ c.radius ≪ endl ≪ ␣ ≪ flush;

if ( ) cout ≪ ␣ ␣ ≪

endl ≪ endl ≪ flush; return ;

} } /∗ if (dist ≡ 0) ∗/ else if (dist > (radius + c.radius )) {

if (verbose ∨ )

  cout ≪  ␣   ␣ ␣   ␣       ␣  ␣    ␣      ␣ ≪ ␣  ≪

␣ ≪ flush; if ( ) cout ≪ ␣ ␣ ≪ endl ≪

endl ≪ flush; return ;

} else if (dist ≡ (radius + c.radius )) {

if (verbose ∨  ) cout ≪  ␣   ␣ ␣    ␣ ␣       ␣  ␣   ␣       ␣ ≪

      ␣           ␣  ;

bpq .first .pt .set (c.center − center ); bpq .first .pt .unit vector (true); bpq .first .pt ∗= radius ; bpq .first .pt .shift (center ); bpq .first .b = true; if ( ) cout ≪ ␣ ␣ ≪ endl ≪

endl ≪ flush; return bpq ;

} else if (dist ≡ max (radius , c.radius ) − min(radius , c.radius )) {

if (verbose ∨  ) cout ≪  ␣   ␣ ␣    ␣ ␣       ␣  ␣   ␣       ␣ ≪

      ␣           ␣  ;

if (radius > c.radius ) { if (verbose ∨ ) cout ≪ ␣ ␣ ␣ ; bpq .first .pt .set (c.center − center );

} else {

if (verbose ∨ ) cout ≪ ␣ ␣ ␣ ;

bpq .first .pt .set (center − c.center ); } bpq .first .pt .unit vector (true); bpq .first .pt ∗= radius ; bpq .first .pt .shift (center ); bpq .first .b = true; if ( ) cout ≪ ␣ ␣ ≪ endl ≪

endl ≪ flush; return bpq ;

} else if (dist < (radius + c.radius )) {

if (dist > max (radius , c.radius ) − min(radius , c.radius )) {

if (verbose ∨  ) cout ≪ ␣   ␣ ␣    ␣ ␣  ;

real a = radius ; real bb = c.radius ∗ c.radius ; real beta = 2 ∗ atan(sqrt ((bb − ((dist − a) ∗ (dist − a)))/(((dist + a) ∗ (dist + a)) − bb))); beta ∗= 180/ ; if (verbose ∨ ) cout ≪ ␣ ␣ ≪ beta ≪ endl ≪ flush; Point P (c.center − center ); P .unit vector (true); P ∗= radius ; P .shift (center ); Point normal = get normal ( ); normal .shift (center ); if ( ) {

P .dotlabel ( );

P .show ( );

normal .show ( ); } bpq .first .b = true; bpq .first .pt = P; bpq .first .pt .rotate(center , normal , beta); if ( ) bpq .first .pt .show ( ); bpq .second .b = true; bpq .second .pt = P; bpq .second .pt .rotate(center , normal , −beta);

if (  ) bpq .second .pt .show (  );
if (  ) cout ≪  ␣                                 ␣  ≪

endl ≪ endl ≪ flush; return bpq ;

} else if (radius > c.radius ) {

if (verbose ∨ )

  cout ≪ ␣    ␣      ␣       ␣         ␣       ␣ ≪  ␣  ≪
      ␣  ;

if (  ) cout ≪  ␣                                 ␣  ≪

endl ≪ endl ≪ flush; return ;

} else {

if (verbose ∨ )

  cout ≪  ␣    ␣      ␣   ␣         ␣       ␣ ≪  ␣  ≪
      ␣  ;

if (  ) cout ≪  ␣                                 ␣  ≪

endl ≪ endl ≪ flush; return ;

} } /∗ else if (dist < (radius + c.radius )) ∗/ else {

cerr ≪  ␣  ␣                                 ␣  ≪

  ␣     ␣             ␣    ␣     ␣         ␣  ≪

␣ ≪ endl ≪ flush;

if (  ) cout ≪  ␣                                 ␣  ≪ endl ≪

endl ≪ flush; return ;

} } /∗ else (Coplanar case). ∗/

}

1306. Reg Polygon functions. [LDF 2003.06.13.] The functions in this section are declared in polygons.web. They must be defined here, because Circle is an incomplete type there.

Log

[LDF 2003.06.13.] Added this section.

1307. Enclosed circle.

Log

[LDF 2003.06.13.] Added this function. [LDF 2003.12.09.] Changed call to Point ::mediate( ) below. It’s now a member function.

⟨ Define Reg Polygon functions 1071 ⟩ +≡ Circle Reg Polygon ::in circle( ) const {

Circle c; if (¬is planar ( )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ␣ ≪ flush; return c;

} if (points .size( ) < 3) {

cerr ≪  ␣  ␣  ≪

      ␣   ␣     ␣    ␣ ␣  ≪  ␣     ␣  ≪ flush;

return c; } Point mid pt = points [0] mediate(∗points [1]); mid pt −= center ; real r = mid pt .magnitude( ); c.set (origin, 2 ∗ r); Point normal = get normal ( ); normal .shift (center ); Transform t; t.align with axis (center , normal , ); c ∗= t.inverse( ); return c;

}

1308. Draw enclosed circle.

1309. Normal version. ⟨ Define Reg Polygon functions 1071 ⟩ +≡

Circle Reg Polygon ::draw in circle(const Color &ddraw color , const string ddashed , const string

ppen, Picture &picture) const

{ Circle c = in circle( ); c.draw (ddraw color , ddashed , ppen, picture); return c;

}

1310. Picture argument first. ⟨ Define Reg Polygon functions 1071 ⟩ +≡

Circle Reg Polygon ::draw in circle(Picture &picture, const Color &ddraw color , const string

ddashed , const string ppen) const

{

return draw in circle(ddraw color , ddashed , ppen, picture); }

1311. Surrounding circle.

Log

[LDF 2003.06.13.] Added this function.

⟨ Define Reg Polygon functions 1071 ⟩ +≡ Circle Reg Polygon ::out circle( ) const {

Circle c; if (¬is planar ( )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ␣ ≪ flush; return c;

} if (points .size( ) < 3) {

cerr ≪  ␣  ␣  ≪

      ␣   ␣     ␣    ␣ ␣  ≪  ␣     ␣  ≪ flush;

return c; } Point normal = get normal ( ); normal .shift (center ); c.set (origin, 2 ∗ radius ); Transform t; t.align with axis (center , normal , ); c ∗= t.inverse( ); return c;

}

1312. Draw surrounding circle.

1313. Normal version.

Log

[LDF 2003.06.13.] Added this function.

⟨ Define Reg Polygon functions 1071 ⟩ +≡

Circle Reg Polygon ::draw out circle(const Color &ddraw color , const string ddashed , const

string ppen, Picture &picture) const

{ Circle c = out circle( ); c.draw (ddraw color , ddashed , ppen, picture); return c;

}

1314. Picture argument first.

Log

[LDF 2003.06.13.] Added this function.

⟨ Define Reg Polygon functions 1071 ⟩ +≡

Circle Reg Polygon ::draw out circle(Picture &picture, const Color &ddraw color , const string

ddashed , const string ppen) const

{

return draw out circle(ddraw color , ddashed , ppen, picture); }

1315. Putting Circle together. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Circle 1276 ⟩ ⟨ Define Circle functions 1279 ⟩ ⟨ Define Reg Polygon functions 1071 ⟩ ⟨ Declare non-member template functions for Circle 1286 ⟩

384  PUTTING CIRCLE TOGETHER  3DLDF-1.1.5.1 §1316

1316. This is what’s written to circles.h.

⟨ 1316 ⟩ ≡

⟨ Define class Circle 1276 ⟩

⟨ Declare non-member template functions for Circle 1286 ⟩

1317. Patterns (patterns.web). [LDF 2002.09.21.] NOTE: When you add a new .web file and move code to it by copying it from another .web file, remember to change the name of the header file that it writes. Otherwise, this can cause problems and it’s not obvious what’s caused them.

Log

[LDF 2002.09.21.] Started using this file again. Moved hex pattern 1 ( ) here. Made the appropriate changes

to cmplprsp.web and main.web.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1318. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1319. Plane tesselations.

1320. Hexagonal tesselation 1.

[LDF 2003.08.10.] TO DO: Change, so that it’s possible to put the pattern into a rectangular area.

Log

§1320  3DLDF-1.1.5.1  HEXAGONAL TESSELATION 1 385

[LDF 2002.09.22.] Added arguments. hex pattern 1 ( ) can now be used to make a pattern with up to three nested hexagons which can be drawn and filled. Each hexagon has its own argument for the draw color, the fill color and the pen to be used. hex pattern 1 ( ) does not have arguments for dash patterns, but they could be added, if necessary. If the argument for the diameter of the middle or the inner hexagon is 0, then that hexagon is not drawn or filled. In this case, the arguments for the draw and fill colors are ignored for that hexagon. The default pen for the outer hexagon is thicker than the pens for the other two (.5mm and .3mm, respectively).

[LDF 2002.09.20.] Rewrote this function. It now works with the new project ( ) function. hex pattern 1 ( ) makes a “honeycomb” pattern on the x-z plane using a single hexagon (i.e., there aren’t nested hexagons yet, as in the old version). In the next version, I plan to add arguments for optionally putting two smaller hexagons inside the large one, and for filling and unfilling.

This version contains arguments for the drawing command, including a Picture argument, so that hex pattern 1 ( ) need not be put onto current picture.

⟨ Declare Pattern functions 1320 ⟩ ≡

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, /∗ Arguments for the drawing and filling commands. ∗/

Color draw color outer = ∗Colors ::default color , /∗ Outer ∗/

Color fill color outer = ∗Colors ::background color , Color draw color middle = ∗Colors ::default color ,

/∗ Middle ∗/ Color fill color middle = ∗Colors ::background color , Color draw color inner = ∗Colors ::default color ,

/∗ Inner ∗/

Color fill color inner = ∗Colors ::background color , string pen outer =  ␣      ␣  ,
string pen middle =  ␣      ␣  , string pen inner =  ␣      ␣  ,

Picture &picture = current picture, unsigned int max hexagons = 1000);

See also sections 1323 and 1326. This code is used in sections 1329 and 1330.

386  HEXAGONAL TESSELATION 1  3DLDF-1.1.5.1 §1321

1321. ⟨ Define Pattern functions 1321 ⟩ ≡

unsigned int hex pattern 1 (real diameter outer , real diameter middle, real diameter inner , unsigned short first row , unsigned short double rows , unsigned short row shift , /∗ Arguments for the drawing and filling commands. ∗/

Color draw color outer , /∗ Outer ∗/ Color fill color outer , Color draw color middle, /∗ Middle ∗/ Color fill color middle, Color draw color inner , /∗ Inner ∗/ Color fill color inner , string pen outer , string pen middle, string pen inner , Picture

&picture, unsigned int max hexagons )

{

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

if (first row < 1) {

cerr ≪  ␣  ␣  ≪  ␣   ␣        ␣      ␣ ≪ first row ≪
␣    ␣  ␣        ␣  ≪  ␣        ␣  ≪ flush;

first row = abs (first row );

cerr ≪ ␣ ␣ ␣ ≪ first row ≪ ≪ endl ≪ flush; } if (first row > 25) /∗ [LDF 2002.09.22.] This can’t be else if because the preceding condition

might have produced a value > 25. ∗/ {

cerr ≪  ␣  ␣  ≪  ␣   ␣        ␣      ␣ ≪ first row ≪

      ␣   ␣  ␣  ␣    ␣  ≪  ␣         ␣   ␣  ≪ flush;

first row = 25; } if (fill color outer ≡ ∗Colors ::default color )

/∗ 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. !! [LDF 2002.09.22.] This is necessary, because Path ::fill ( ) interprets “ ” as . 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 ”. ∗/

fill color outer = ∗Colors ::background color ; if (fill color middle ≡ ∗Colors ::default color ) fill color middle = ∗Colors ::background color ; if (fill color inner ≡ ∗Colors ::default color ) fill color inner = ∗Colors ::background color ; bool do middle; /∗ [LDF 2002.09.22.] Having do middle and do inner is a convenience, so I don’t

have to check whether diameter middle and diameter inner are ≡ 0 below, which wouldn’t be as clearly understandable. ∗/

bool do inner ; do middle = (diameter middle ≡ 0) ? false : true; do inner = (diameter inner ≡ 0) ? false : true; Point pt0 ; /∗ origin. ∗/ Reg Polygon p outer (pt0 , 6, diameter outer ); Reg Polygon p middle; Reg Polygon p inner ; /∗ [LDF 2002.09.22.] The middle and inner hexagons are only set (and

used) if do middle and/or do inner are true. ∗/ if (do middle) p middle.set (pt0 , 6, diameter middle); if (do inner ) p inner .set (pt0 , 6, diameter inner ); Reg Polygon p outer copy ; /∗ These Reg Polygons are used for copying. ∗/ Reg Polygon p middle copy ; Reg Polygon p inner copy ;

#if 0

if ( ) p outer .dotlabel ( ); #endif

real right shift = p outer .get point (4).get x ( ) + p outer .get point (3).get x ( ) −

p outer .get point (1).get x ( ) − p outer .get point (2).get x ( ); real left shift = −right shift ; /∗ Center the first row on the origin. ∗/ Transform t; t.shift ((first row /2) ∗ left shift ); if (first row % 2 ≡ 0) t.shift (.5 ∗ right shift ); p outer ∗= t; if (do middle) p middle ∗= t; if (do inner ) p inner ∗= t; Transform offset ;

/∗ [LDF 2002.09.22.] offset is for moving the hexagons to the second row in the double row, which is

offset with respect to the first (and will contain one more set of nested hexagons). ∗/ offset .shift (p outer .get point (4) − p outer .get point (2)); Transform move back ; /∗ [LDF 2002.09.22.] move back is for moving in the direction of the

positive z-axis before starting the next double row. ∗/ move back .shift (p outer .get point (5) − p outer .get point (3));

/∗ [LDF 2002.09.22.] The number of sets of hexagons in the rows differs, so we use i min and i max

for controlling the for loop that shifts and draws and fills the hexagons. ∗/ signed short i min = 0; unsigned short i max = first row ;

/∗ [LDF 2002.09.20.] I could just use first row instead of declaring a new variable, but the name

i max makes more sense in the loop, so I think it’s worth doing for the sake of clarity. ∗/ short i, j, k; unsigned int hexagon ctr = 0; /∗ Each time a hexagon is drawn, hexagon ctr is incremented.

hexagon ctr is the return value of this function (hex pattern 1 ( )). ∗/ for (k = 0; k < double rows ; ^{++}k) /∗ k is the number of double lines. [LDF 2002.09.22.] This loop

takes care of moving back in the direction of the positive z-axis. ∗/ { /∗ [LDF 2002.09.20.] If 0 is passed as the row shift argument, don’t do any shifting. Otherwise,

every row shift rows, increase the number of hexagons in the rows by 2. The rows remain centered around the z-axis. row shift applies to the double rows. The offset row which is drawn when j ≡ 1 already has one hexagon more than the first row drawn, so when row shift ≡ 1, the effect is that each single row is one hexagon longer than the last. This makes the edges recede diagonally. ∗/

if (k ≠ 0 ∧ row shift ≠ 0 ∧ k % row shift ≡ 0) { −i min; ++i max ; t = p outer .shift (left shift ); if (do middle) p middle ∗= t; if (do inner ) p inner ∗= t;

}

for (j = 0; j < 2; ^{++}j) /∗ This loop makes the second line in each set of double lines. ∗/ {

p outer copy = p outer ;

if (do middle) p middle copy = p middle; if (do inner ) p inner copy = p inner ; if (j ≡ 1) {

p outer copy ∗= offset ; if (do middle) p middle copy ∗= offset ; if (do inner ) p inner copy ∗= offset ; −i min; t = p outer copy .shift (left shift ); if (do middle) p middle copy ∗= t; if (do inner ) p inner copy ∗= t;

} for (i = i min; i < i max ; ^{++}i)

/∗ [LDF 2002.09.22.] This loop draws and/or fills the horizontal rows. ∗/ {

if (fill color outer ≡ ∗Colors ::background color )

p outer copy .draw (draw color outer , , pen outer , picture); else if (draw color outer ≡ fill color outer ) p outer copy .fill (fill color outer , picture); else p outer copy .filldraw (draw color outer , fill color outer , , pen outer , picture); if (do middle) {

if (fill color middle ≡ fill color outer )

p middle copy .draw (draw color middle, , pen middle, picture); else if (draw color middle ≡ fill color middle) p middle copy .fill (fill color middle, picture); else p middle copy .filldraw (draw color middle, fill color middle, , pen middle, picture);

} if (do inner ) {

if (fill color inner ≡ fill color middle)

p inner copy .draw (draw color inner , , pen inner , picture); else if (draw color inner ≡ fill color middle) p inner copy .fill (fill color inner , picture); else p inner copy .filldraw (draw color inner , fill color inner , , pen inner , picture);

} ++hexagon ctr ; if (hexagon ctr ≥ max hexagons ) {

  cerr ≪  ␣  ␣  ≪  ␣    ␣    ␣  ␣         ␣ ≪

hexagon ctr ≪ ␣␣ ≪ endl ≪ flush; return hexagon ctr ;

} t = p outer copy .shift (right shift ); if (do middle) p middle copy ∗= t; if (do inner ) p inner copy ∗= t;

} } p outer ∗= move back ; if (do middle) p middle ∗= move back ; if (do inner ) p inner ∗= move back ; ++i min;

} if ( ) cout ≪ ␣ ≪ flush; return hexagon ctr ;

}

See also sections 1324 and 1327. This code is used in section 1329.

1322. patterns.

§1323  3DLDF-1.1.5.1  EPICYCLOID PATTERN 1 389

1323. Epicycloid pattern 1. [LDF 2003.02.11.] This functions works well for outer Circles with radii that are divisors (with no remainder) of the radius of the inner Circle. Each outer Circle is rolled around the inner Circle once only. If the radius of the outer Circle is a divisor of the inner Circle, the end of the epicycloid will meet up with the beginning. If the radius of the outer Circle is not a divisor of the inner Circle, it won’t. See epicycloid pattern 3 ( ) below, for a pattern that works well for outer Circles, whose radii are not divisors of the radius of the inner Circle. !! START HERE. TO DO: Start from beginning of Color ∗ vector, if I get to the end.

Log

[LDF 2003.02.09.] Added this function.

[LDF 2003.08.27.] Removed the declaration const Color ∗curr color , since curr color was never used.

⟨ Declare Pattern functions 1320 ⟩ +≡

390  EPICYCLOID PATTERN 1  3DLDF-1.1.5.1 §1324

unsigned int epicycloid pattern 1 (real diameter inner , real diameter outer start , real diameter outer end , real step, unsigned int offsets , vector⟨const Color ∗⟩ colors = Colors ::default color vector , int arc divisions = 72); 1324. ⟨ Define Pattern functions 1321 ⟩ +≡

unsigned int epicycloid pattern 1 (real diameter inner , real diameter outer start , real diameter outer end , real step, unsigned int offsets , vector⟨const Color ∗⟩ colors , int arc divisions )

{ bool = false; /∗ true ∗/ if (diameter inner < diameter outer start ) {

cerr ≪  ␣              ␣ ␣  ≪

      ␣  ␣      ␣  ␣     ␣  ␣       ␣  ≪  ≪ flush;

} using namespace Colors; unsigned int spiral counter = 0; real radius outer ; real phi ; Path spiral ; spiral += ; real radius inner = diameter inner /2; Circle inner circle(origin, diameter inner ); inner circle.draw ( ); if ( ) inner circle.get center ( ).dotlabel ( , ); Circle outer circle; Point outer circle center ; Point normal ; Point p0 ; real theta = 360.0/arc divisions ; Circle temp circle; Point p2 ; Point temp circle center ; Point temp circle normal ; if (offsets < 1) {

cerr ≪ ␣ ␣ ␣ ␣ ␣ ≪ offsets ≪ endl ≪

      ␣    ␣  ␣  ␣   ␣␣       ␣  ␣  ≪ flush;

offsets = 1; } real diameter outer ; vector⟨const Color ∗⟩::iterator iter = colors .begin( ); for (diameter outer = diameter outer start ; diameter outer ≥ diameter outer end ;

diameter outer −= step) { if (iter ≠ colors .end ( ) − 1) ^{++}iter ; radius outer = diameter outer /2; outer circle center .set (0, 0, radius inner + radius outer ); normal = outer circle center ; normal .shift (0, 1); p0 .set (0, 0, radius inner + diameter outer ); outer circle.set (outer circle center , diameter outer ); if (colors .size( ) ≡ 0) colors .push back (default color ); for (unsigned int i = 0; i < offsets ; ^{++}i) {

if (i ≠ 0) outer circle center ∗= normal ∗= p0 ∗= outer circle.rotate(0, 360.0/offsets ); else { if ( ) {

p0 .dotlabel ( ); outer circle.draw (blue);

} } if ( ) {

p0 .dotlabel ( , );

outer circle.draw (green, ); } spiral += p0 ; phi = theta ∗ radius inner /radius outer ; temp circle = outer circle; temp circle center = outer circle center ; temp circle normal = normal ; p2 = p0 ; for (int j = 1; j ≤ arc divisions ; ^{++}j) {

p2 ∗= temp circle normal ∗= temp circle center ∗= temp circle.rotate(0, theta); p2 .rotate(temp circle center , temp circle normal , phi ); spiral += p2 ; if ( ) {

p2 .dotlabel ( , );

temp circle.draw (black , ); }

} spiral .draw (∗∗iter ); ++spiral counter ; spiral .clear ( ); spiral += ;

} } return spiral counter ;

}

1325. Epicycloid pattern 2. [LDF 2003.02.11.] This pattern should be like epicycloid pattern 1 ( ), except that the offsets are not made by rotating the outer Circle around the center of the inner Circle, but by rotating the Point used for tracing the epicycloid about the center of the outer Circle.

1326. Epicycloid pattern 3. [LDF 2003.02.11.] This function works well for outer Circles with radii that are not even divisors of the radius of the inner Circle.

Log

[LDF 2003.02.11.] Added this function. [LDF 2003.08.27.] Removed the declaration real radius ratio = radius outer /radius inner , since

radius ratio was never used.

⟨ Declare Pattern functions 1320 ⟩ +≡

unsigned int epicycloid pattern 3 (real diameter inner , real diameter outer , vector⟨const Color ∗⟩ colors = Colors ::default color vector , unsigned int limit = 100, int arc divisions = 72); 1327. ⟨ Define Pattern functions 1321 ⟩ +≡

unsigned int epicycloid pattern 3 (real diameter inner , real diameter outer , vector⟨const Color ∗⟩

colors , unsigned int limit , int arc divisions )

{ using namespace Colors; bool = false; /∗ true ∗/ vector⟨const Color ∗⟩::iterator color iter = colors .begin( ); real radius outer = diameter outer /2; real radius inner = diameter inner /2; real theta = 360.0/arc divisions ; real phi = theta ∗ radius inner /radius outer ; real theta total = 0; Circle inner circle(origin, diameter inner ); inner circle.draw ( ); Point outer circle center (0, 0, radius inner + radius outer ); Circle outer circle(outer circle center , diameter outer ); outer circle.draw ( ); Point normal (outer circle center ); normal .shift (0, 1); Point p0 (0, 0, radius inner + diameter outer ); p0 .dotlabel ( ); Path spiral ; spiral += ; spiral += p0 ; Point start pt (p0 ); unsigned int spiral counter = 1; unsigned int iter ctr = 0; while (true) {

if (theta total ≥ 360) {

cout ≪ ␣ ␣ ≪ theta total ≪ endl ≪ ␣ ␣ ␣ ≪

(theta total − 360) ≪ endl ≪ flush; theta total −= 360; ++iter ctr ; spiral .draw (∗∗color iter^{++}); spiral .clear ( ); spiral += ; if (color iter ≡ colors .end ( )) color iter = colors .begin( );

}

if (iter ctr > limit ) { cout ≪ ␣ ␣␣ ␣ ␣ ≪ iter ctr ≪ endl ≪ ≪ flush; break;

}

else if (iter ctr > 0 ∧ (fmod ((iter ctr ∗ radius outer ), radius inner ) ≡ 0)) {

cout ≪ ␣ ␣ ≪ ␣ ␣ ≪ iter ctr ≪ endl ≪ ␣ ␣ ␣ ␣ ␣ ≪ fmod ((iter ctr ∗radius outer ), radius inner ) ≪ endl ≪ ≪ flush;

break; } outer circle center ∗= normal ∗= p0 ∗= outer circle.rotate(0, theta); p0 .rotate(outer circle center , normal , phi ); theta total += theta; if ( ) {

outer circle.draw (black , ); p0 .dotlabel ( );

} spiral += p0 ; ++spiral counter ;

} return spiral counter ;

}

1328. Putting patterns together.

1329. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Declare Pattern functions 1320 ⟩ ⟨ Define Pattern functions 1321 ⟩

394  PUTTING PATTERNS TOGETHER  3DLDF-1.1.5.1 §1330

1330. This is what’s written to patterns.h.

⟨ 1330 ⟩ ≡

⟨ Declare Pattern functions 1320 ⟩

1331. Solid (solids.web). [LDF 2002.11.12.] TO DO: Add get center ( ). Must set center in the Polyhedra before this is useful.

Log

[LDF 2002.09.29.] Created this file.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1332. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1333. Solid class definition.

Log

[LDF 2002.09.30.] Added the data members circles , ellipses , polygons , and paths . On the one hand, this is wasteful, since most if not all Solids will contain only one kind of Path; on the other hand, it’s an advantage to be able to have the drawing and filling functions be members of Solid, since they don’t have to know what kind of a Path a Path is, in order to draw or fill it. This way, I don’t have to define the drawing and filling functions for Sphere, Ellipsoid , Polyhedron, etc.

[LDF 2002.10.01.] Added the data member projective extremes .

[LDF 2003.04.11.] Added the static const data members , , , , and . Currently, their only use is as arguments to get shape ptr ( ) and get shape center ( ).

[LDF 2003.04.11.] Renamed polygons to reg polygons . This is in case I decide to make it possible to have irregular polygons. In this case, I may define a class Polygon and derived Reg Polygon from it.

§1333  3DLDF-1.1.5.1  SOLID CLASS DEFINITION 395

⟨ Define class Solid 1333 ⟩ ≡ class Solid : public Shape { protected: bool on free store;

Point center ;

bool do output ; /∗ LDF 2002.10.01. Added. ∗/

vector⟨Circle ∗⟩ circles ; vector⟨Ellipse ∗⟩ ellipses ; vector⟨Path ∗⟩ paths ; vector⟨Rectangle ∗⟩ rectangles ; vector⟨Reg Polygon ∗⟩ reg polygons ; valarray⟨real⟩ projective extremes ;

public: static const unsigned short ; static const unsigned short ; static const unsigned short ; static const unsigned short ; static const unsigned short ; ⟨ Declare Solid functions 1336 ⟩

};

This code is used in sections 1441 and 1442.

1334. Define static const Solid data members.

Log

[LDF 2003.04.11.] Added this section.

⟨ Define static const Solid data members 1334 ⟩ ≡ const unsigned short Solid :: = 0; const unsigned short Solid :: = 1; const unsigned short Solid :: = 2; const unsigned short Solid :: = 3; const unsigned short Solid :: = 4;

This code is used in section 1441.

1335. Constructors.

1336. Default constructor. (No arguments.) [LDF 2002.10.02.] Solid will not normally be used in user code, since it is intended to be a base class only. Therefore, objects of type Solid will not normally be declared as automatic variables and there will be no static global Solids. However, create new < Solid > ( ) is used in the drawing and filling functions, in order to put Solids onto Pictures. If we didn’t have a constructor, projective extremes wouldn’t initially have the right size and on free store and do output would both be false (assuming the compiler set s the initial values of uninitialized bools to false). None of this would really matter, because presumably an assignment would follow immediately, which would take care of everything, but there’s no harm in making sure. ⟨ Declare Solid functions 1336 ⟩ ≡

Solid( );

See also sections 1338, 1343, 1345, 1348, 1350, 1353, 1356, 1358, 1360, 1362, 1364, 1366, 1369, 1371, 1373, 1375, 1377, 1379, 1381, 1383, 1386, 1388, 1390, 1392, 1395, 1397, 1399, 1401, 1404, 1406, 1408, 1409, 1411, 1413, 1415, 1417, 1419, 1423, 1426, 1429, 1432, 1435, and 1438.

This code is used in section 1333.

1337. ⟨ Define Solid functions 1337 ⟩ ≡

Solid ::Solid( )

{ on free store = false; do output = true; projective extremes .resize(6, 0);

}

See also sections 1339, 1344, 1346, 1347, 1349, 1351, 1354, 1357, 1359, 1361, 1363, 1365, 1367, 1370, 1372, 1374, 1376, 1378, 1380, 1382, 1384, 1387, 1389, 1391, 1393, 1396, 1398, 1400, 1402, 1405, 1407, 1410, 1412, 1414, 1416, 1418, 1420, 1424, 1427, 1430, 1433, 1436, and 1439.

This code is used in section 1441.

1338. Copy constructor. [LDF 2002.10.02.] ⟨ Declare Solid functions 1336 ⟩ +≡

Solid(const Solid &s);

§1339  3DLDF-1.1.5.1  COPY CONSTRUCTOR 397

1339. ⟨ Define Solid functions 1337 ⟩ +≡

Solid ::Solid(const Solid &s){ on free store = false; do output = true; projective extremes .resize(6, 0); for (vector⟨Path ∗⟩::const iterator iter = s.paths .begin( ); iter ≠ s.paths .end ( ); ^{++}iter ) { paths .push back ( create new < Path > (0) ) ; ∗(paths .back ( )) = ∗∗iter ; } for (vector⟨Circle ∗⟩::const iterator iter = s.circles .begin( ); iter ≠ s.circles .end ( ); ^{++}iter ) { circles .push back ( create new < Circle > (0) ) ; ∗(circles .back ( )) = ∗∗iter ; } for (vector⟨Ellipse ∗⟩::const iterator iter = s.ellipses .begin( ); iter ≠ s.ellipses .end ( ); ^{++}iter ) { ellipses .push back ( create new < Ellipse > (0) ) ;

∗(ellipses .back ( )) = ∗∗iter ; } for (vector⟨Reg Polygon ∗⟩::const iterator iter = s.reg polygons .begin( ); iter ≠ s.reg polygons .end ( ); ++iter ) { reg polygons .push back ( create new < Reg Polygon > (0) ) ;

∗(reg polygons .back ( )) = ∗∗iter ; } for (vector⟨Rectangle ∗⟩::const iterator iter = s.rectangles .begin( ); iter ≠ s.rectangles .end ( ); ^{++}iter ) { rectangles .push back ( create new < Rectangle > (0) ) ;

∗(rectangles .back ( )) = ∗∗iter ; } }

1340. Pseudo-constructor for dynamic allocation.

1341. Pointer argument.

Log

[LDF 2003.12.30.] Replaced Solid ::create new solid ( ) with a specialization of template⟨class C⟩ C∗create new ( ) for Solid. The argument is now const.

⟨ Declare non-member template functions for Solid 1341 ⟩ ≡

Solid ∗create new (const Solid ∗c);

See also section 1342. This code is used in sections 1441 and 1442.

1342. Reference argument.

Log

LDF 2003.12.30. Added this function.

⟨ Declare non-member template functions for Solid 1341 ⟩ +≡ Solid ∗create new (const Solid &c);

1343. Destructor.

Log

[LDF 2003.08.27.] Added a virtual destructor with an empty definition, because GCC with the “-Wall” option issued the following warning: “‘class Solid’ has virtual functions but non-virtual destructor”.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual ∼Solid( ); 1344. ⟨ Define Solid functions 1337 ⟩ +≡

Solid ::∼Solid( ) { }

1345. Assignment. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual const Solid &operator=(const Solid &s);

1346. ⟨ Define Solid functions 1337 ⟩ +≡

const Solid &Solid ::operator=(const Solid &s){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

if (this ≡ &s) /∗ Make sure it’s not self-assignment. ∗/

return ∗this ; center = s.center ; /∗ LDF 2002.10.06. Added this line, because center is now a member of

Solid. ∗/ /∗ [LDF 2002.10.02.] First, call the destructor on all of the elements of paths , circles , ellipses , reg polygons , and rectangles , because they’ve been allocated dynamically. Then clear out the vectors. ∗/

if (paths .size( ) > 0) { for (vector⟨Path ∗⟩::iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter ) (∗∗iter ).clear ( ); paths .clear ( );

} if (circles .size( ) > 0) {

for (vector⟨Circle ∗⟩::iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter )

(∗∗iter ).clear ( ); circles .clear ( );

} if (ellipses .size( ) > 0) {

for (vector⟨Ellipse ∗⟩::iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter )

(∗∗iter ).clear ( ); ellipses .clear ( );

} if (reg polygons .size( ) > 0) {

for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) (∗∗iter ).clear ( ); reg polygons .clear ( );

} if (rectangles .size( ) > 0) {

for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); ^{++}iter )

(∗∗iter ).clear ( ); rectangles .clear ( );

} 1347. Now, create new Path, Circle, Ellipse, Reg Polygon, and Rectangle pointers, allocate memory for them, assign values to the objects they point to from s, and push them onto the appropriate vectors.

[LDF 2002.10.02.]

⟨ Define Solid functions 1337 ⟩ +≡

Path ∗p; for (vector⟨Path ∗⟩::const iterator iter = s.paths .begin( ); iter ≠ s.paths .end ( ); ^{++}iter ) {

p = create new < Path > (0); paths .push back (p); ∗(paths .back ( )) = ∗∗iter ; } for (vector⟨Circle ∗⟩::const iterator iter = s.circles .begin( );

iter ≠ s.circles .end ( ); ^{++}iter ) { circles .push back ( create new < Circle > (0) ) ; ∗(circles .back ( )) = ∗∗iter ; } for (vector⟨Ellipse ∗⟩::const iterator iter = s.ellipses .begin( );

iter ≠ s.ellipses .end ( ); ^{++}iter ) { ellipses .push back ( create new < Ellipse > (0) ) ; ∗(ellipses .back ( )) = ∗∗iter ; } for (vector⟨Reg Polygon ∗⟩::const iterator iter = s.reg polygons .begin( );

iter ≠ s.reg polygons .end ( ); ^{++}iter ) { reg polygons .push back ( create new < Reg Polygon > (0) ) ;

∗(reg polygons .back ( )) = ∗∗iter ; } for (vector⟨Rectangle ∗⟩::const iterator iter = s.rectangles .begin( );

iter ≠ s.rectangles .end ( ); ^{++}iter ) { rectangles .push back ( create new < Rectangle > (0) ) ; ∗(rectangles .back ( )) = ∗∗iter ; } projective extremes = 0; /∗ For output. ∗/ do output = true; if ( ) {

cout ≪ ␣ ␣ ≪ paths .size( ) ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ circles .size( ) ≪ endl ≪ flush;

cout ≪ ␣ ␣ ≪ ellipses .size( ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ reg polygons .size( ) ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ rectangles .size( ) ≪ endl ≪ flush;

} if ( ) cout ≪ ␣ ; return ∗this ; }

1348. Copying.

Log

[LDF 2003.05.06.] BUG FIX: Changed s from Shape ∗ to Solid ∗. I noticed this bug when I tried to copy a Picture containing a Cuboid, and the copy contained a single empty Shape ∗ on shapes .

⟨ Declare Solid functions 1336 ⟩ +≡ virtual Shape ∗get copy ( ) const;

1349. ⟨ Define Solid functions 1337 ⟩ +≡

Shape ∗Solid ::get copy ( ) const{ Solid ∗s = create new < Solid > (0); ∗s = ∗this ; return dynamic cast⟨Shape ∗⟩(s); }

1350. Set on free store.

Log

[LDF 2004.01.06.] Made non-inline.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual bool set on free store(bool b = true);

400  SET ON FREE STORE  3DLDF-1.1.5.1 §1351

1351. ⟨ Define Solid functions 1337 ⟩ +≡

bool Solid ::set on free store(bool b)

{ on free store = b; return b;

}

1352. Returning elements and information. [LDF 2003.04.11.] The functions get shape ptr ( ), get circle ptr ( ), get ellipse ptr ( ), get path ptr ( ), get rectangle ptr ( ), and get reg polygon ptr ( ) all return const pointers to Shape, Circle, Ellipse, etc. Therefore, they must be invoked in such a way, that the const qualifier is not discarded. For example, following Dodecahedron d(origin, 5);, two ways of invoking get reg polygon ptr ( ) are: const Reg Polygon ∗ptr = d.get reg polygon ptr (5); and Reg Polygon A = ∗d.get reg polygon ptr (5);.

Log

[LDF 2003.05.09.] Changed the names of get shape( ), get circle( ), get ellipse( ), get path( ), get rectangle( ), and get reg polygon( ) to get shape ptr ( ), get circle ptr ( ), get ellipse ptr ( ), get path ptr ( ), get rectangle ptr ( ), and get reg polygon ptr ( ). The names without “ ptr ” were confusing, because they didn’t make clear that the functions returned pointers.

1353. Get center.

Log

[LDF 2003.05.06.] Added this function.

[LDF 2003.08.10.] Made this function const.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Point &get center ( ) const;

1354. ⟨ Define Solid functions 1337 ⟩ +≡

const Point &Solid ::get center ( ) const

{

return center ; }

1355. Getting Shapes.

Log

[LDF 2003.04.30.] Changed the functions get circle ptr ( ), get ellipse ptr ( ), get path ptr ( ), get rectangle ptr ( ), and get reg polygon ptr ( ). They no longer use get shape ptr ( ). There’s no good reason for casting pointers from one type to another. I rather doubt that get shape ptr ( ) is needed, anyway.

§1356  3DLDF-1.1.5.1  GET SHAPE POINTER 401

1356. Get Shape pointer. [LDF 2003.05.30.] This function copies one of the objects on one of the vectors of Shape ∗ belonging to the Solid, and returns a pointer to Shape that points to the copy. Currently, a Solid contains the vectors circles , ellipses , paths , rectangles , and reg polygons . The argument shape type indicates which vector should be accessed. Normally, the corresponding public static const data members , , , , or should be passed as the shape type argument, e.g., Circle ∗c ptr = static cast⟨Circle ∗⟩(get shape ptr (Solid :: , 3)).

[LDF 2003.04.30.] This function was mainly intended for use in the functions get circle ptr ( ), get ellipse ptr ( ), etc., and was not intended for use in user code. I now doubt whether this function is needed at all, especially since it is no longer used in the functions mentioned above.

Log

[LDF 2003.04.11.] Added this function.

[LDF 2003.04.30.] Now using get copy ( ) instead of static cast⟨const Shape ∗⟩( ). The way it was caused compilation errors under Tru64 (DEC ALPHA).

[LDF 2003.05.30.] Changed return value to Shape ∗ from const Shape ∗. The way it was before caused “Memory fault” errors at run-time.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual Shape ∗get shape ptr (const unsigned short shape type, const unsigned short s) const;

402  GET SHAPE POINTER  3DLDF-1.1.5.1 §1357

1357. ⟨ Define Solid functions 1337 ⟩ +≡

Shape ∗Solid ::get shape ptr (const unsigned short shape type, const unsigned short s) const {

bool = false; /∗ true ∗/ if ( ) {

cout ≪ ␣ ≪ flush; } if (shape type ≡ ) {

if (s < circles .size( )) {

return circles [s] get copy ( ); } else {

cerr ≪  ␣  ␣  ≪ ␣ ≪ s ≪ ␣ ␣             ␣ ≪
circles .size( ) ≪  ␣ ␣     ␣       ␣  ≪ flush;

return static cast⟨Shape ∗⟩(0); }

} else if (shape type ≡ ) {

if (s < ellipses .size( )) {

return ellipses [s] get copy ( ); } else {

cerr ≪ ␣ ␣ ≪ ␣ ≪ s ≪ ␣ ␣ ␣ ≪ ellipses .size( ) ≪ ␣ ␣ ␣ ␣ ≪ flush;

return static cast⟨Shape ∗⟩(0); }

} else if (shape type ≡ ) {

if (s < paths .size( )) {

return paths [s] get copy ( ); } else {

cerr ≪  ␣  ␣  ≪ ␣ ≪ s ≪ ␣ ␣           ␣ ≪
paths .size( ) ≪  ␣ ␣     ␣       ␣  ≪ flush;

return static cast⟨Shape ∗⟩(0); }

} else if (shape type ≡ ) {

if (s < rectangles .size( )) {

return rectangles [s] get copy ( ); } else {

cerr ≪ ␣ ␣ ≪ ␣ ≪ s ≪ ␣ ␣ ␣ ≪ rectangles .size( ) ≪ ␣ ␣ ␣ ␣ ≪ flush;

return static cast⟨Shape ∗⟩(0); }

} else if (shape type ≡ ) {

if (s < reg polygons .size( )) {

return reg polygons [s] get copy ( ); } else {

cerr ≪ ␣ ␣ ≪ ␣ ≪ s ≪ ␣ ␣ ␣ ≪ reg polygons .size( ) ≪ ␣ ␣ ␣ ␣ ≪ flush;

return static cast⟨Shape ∗⟩(0); }

}

else {

cerr ≪  ␣  ␣  ≪  ␣     ␣   ␣           ␣ ≪
shape type ≪ endl ≪  ␣ ␣    ␣       ␣  ≪ flush;

return static cast⟨Shape ∗⟩(0); }

}

1358. Get Circle pointer.

Log

[LDF 2003.04.11.] Added this function. [LDF 2003.04.30.] Changed this function, so that it no longer uses get shape ptr ( ).

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Circle ∗get circle ptr (const unsigned short s) const;

1359. ⟨ Define Solid functions 1337 ⟩ +≡

const Circle ∗Solid ::get circle ptr (const unsigned short s) const {

if (circles .size( ) > s) {

return circles [s]; } else {

return static cast⟨const Circle ∗⟩(0); }

}

1360. Get Ellipse pointer.

Log

[LDF 2003.04.11.] Added this function. [LDF 2003.04.30.] Changed this function, so that it no longer uses get shape ptr ( ).

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Ellipse ∗get ellipse ptr (const unsigned short s) const;

404  GET ELLIPSE POINTER  3DLDF-1.1.5.1 §1361

1361. ⟨ Define Solid functions 1337 ⟩ +≡

const Ellipse ∗Solid ::get ellipse ptr (const unsigned short s) const {

if (ellipses .size( ) > s) {

return ellipses [s]; } else {

return static cast⟨const Ellipse ∗⟩(0); }

}

1362. Get Path pointer.

Log

[LDF 2003.04.11.] Added this function. [LDF 2003.04.30.] Changed this function, so that it no longer uses get shape ptr ( ).

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Path ∗get path ptr (const unsigned short s) const;

1363. ⟨ Define Solid functions 1337 ⟩ +≡

const Path ∗Solid ::get path ptr (const unsigned short s) const {

if (paths .size( ) > s) {

return paths [s]; } else {

return static cast⟨const Path ∗⟩(0); }

}

1364. Get Rectangle pointer.

Log

[LDF 2003.04.11.] Added this function. [LDF 2003.04.30.] Changed this function, so that it no longer uses get shape ptr ( ).

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Rectangle ∗get rectangle ptr (const unsigned short s) const;

§1365  3DLDF-1.1.5.1  GET RECTANGLE POINTER 405

1365. ⟨ Define Solid functions 1337 ⟩ +≡

const Rectangle ∗Solid ::get rectangle ptr (const unsigned short s) const {

if (rectangles .size( ) > s) {

return rectangles [s]; } else {

return static cast⟨const Rectangle ∗⟩(0); }

}

1366. Get Reg Polygon pointer.

Log

[LDF 2003.04.11.] Added this function. [LDF 2003.04.30.] Changed this function, so that it no longer uses get shape ptr ( ).

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Reg Polygon ∗get reg polygon ptr (const unsigned short s) const;

1367. ⟨ Define Solid functions 1337 ⟩ +≡

const Reg Polygon ∗Solid ::get reg polygon ptr (const unsigned short s) const {

if (reg polygons .size( ) > s) {

return reg polygons [s]; } else {

return static cast⟨const Reg Polygon ∗⟩(0); }

}

1368. Getting Shape centers. [LDF 2003.04.30.] TO DO: I think it might be possible to code the functions in this section more succinctly.

406  GET SHAPE CENTER  3DLDF-1.1.5.1 §1369

1369. Get Shape center. This function returns the center of the Circle, Ellipse, Rectangle, or Reg Polygon number s in circles , ellipses , rectangles , or reg polygons , respectively. If s is larger than ⟨vector⟩. size( ), an error message is issued and is returned.

One of the following public static const data members of Solid can (and probably should) be used as the shape type argument: , , , and .

!! Note that this function will have to be changed, if new vectors of Shape pointers are added to class Solid!

Log

[LDF 2002.10.16.] Added this function.

[LDF 2003.04.09.] Moved this function from Polyhedron to Solid.

[LDF 2003.04.11.] Changed this function from get polygon center ( ) to get shape center ( ). Added the char argument shape type to indicate whether it should return the center of a Circle, Ellipse, Rectangle, or Reg Polygon.

[LDF 2003.04.11.] Changed the shape type argument from char to const unsigned short.

⟨ Declare Solid functions 1336 ⟩ +≡

virtual const Point &get shape center (const unsigned short shape type, const unsigned short s) const;

§1370  3DLDF-1.1.5.1  GET SHAPE CENTER 407

1370. ⟨ Define Solid functions 1337 ⟩ +≡

const Point &Solid ::get shape center (const unsigned short shape type, const unsigned short s)

const

{

if (shape type ≡ ) { if (s < circles .size( )) return circles [s] get center ( ); else {

cerr ≪  ␣  ␣  ≪ ␣ ≪ s ≪
␣ ␣             ␣ ≪ circles .size( ) ≪  ␣  ≪

flush; return ;

} } else if (shape type ≡ ) {

if (s < ellipses .size( )) return ellipses [s] get center ( ); else {

cerr ≪  ␣  ␣  ≪ ␣ ≪ s ≪
␣ ␣               ␣ ≪ ellipses .size( ) ≪  ␣  ≪

flush; return ;

} } else if (shape type ≡ ) {

if (s < rectangles .size( )) return rectangles [s] get center ( ); else {

cerr ≪ ␣ ␣ ≪ ␣ ≪ s ≪ ␣ ␣ ␣ ≪ rectangles .size( ) ≪ ␣ ≪ flush;

return ; }

} else if (shape type ≡ ) {

if (s < reg polygons .size( )) return reg polygons [s] get center ( ); else {

cerr ≪ ␣ ␣ ≪ ␣ ≪ s ≪ ␣ ␣ ␣ ≪ reg polygons .size( ) ≪ ␣ ≪ flush;

return ; }

} else {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪ shape type ≪ endl ≪ ␣ ≪ flush;

return ; }

}

408  GET CIRCLE CENTER  3DLDF-1.1.5.1 §1371

1371. Get Circle center.

Log

[LDF 2003.04.11.] Added this function.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Point &get circle center (const unsigned short s) const;

1372. ⟨ Define Solid functions 1337 ⟩ +≡

const Point &Solid ::get circle center (const unsigned short s) const {

return get shape center ( , s); }

1373. Get Ellipse center.

Log

[LDF 2003.04.11.] Added this function.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Point &get ellipse center (const unsigned short s) const;

1374. ⟨ Define Solid functions 1337 ⟩ +≡

const Point &Solid ::get ellipse center (const unsigned short s) const {

return get shape center ( , s); }

1375. Get Rectangle center.

Log

[LDF 2003.04.11.] Added this function.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Point &get rectangle center (const unsigned short s) const;

1376. ⟨ Define Solid functions 1337 ⟩ +≡

const Point &Solid ::get rectangle center (const unsigned short s) const {

return get shape center ( , s); }

§1377  3DLDF-1.1.5.1  GET REG POLYGON CENTER 409

1377. Get Reg Polygon center.

Log

[LDF 2003.04.11.] Added this function.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual const Point &get reg polygon center (const unsigned short s) const;

1378. ⟨ Define Solid functions 1337 ⟩ +≡

const Point &Solid ::get reg polygon center (const unsigned short s) const

{

return get shape center ( , s); }

1379. Is on free store. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual bool is on free store( ) const;

1380. ⟨ Define Solid functions 1337 ⟩ +≡

bool Solid ::is on free store( ) const

{ bool b = true; return b;

}

1381. Show. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void show (string text = , char coords = , const bool do persp = true, const bool do apply = true, Focus ∗f = 0, const unsigned short proj = Projections :: , const real factor = 1) const; 1382. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::show (string text , char coords , const bool do persp, const bool do apply , Focus

∗f, const unsigned short proj , const real factor ) const

{ if (text ≡ ) text = ; cout ≪ text ≪ endl ; cout ≪ ␣ ␣ ≪ on free store ≪ endl ≪ flush; stringstream g; int i; if (paths .size( ) > 0) {

cout ≪ ␣ ;

i = 0;

for (vector⟨Path ∗⟩::const iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter ) { g ≪ ␣ ≪ i^{++} ≪ ; (∗∗iter ).show (g.str ( ), coords , do persp, do apply , f, proj , factor ); g.str ( );

} } else cout ≪ ␣ ␣ ; if (circles .size( ) > 0) {

cout ≪ ␣ ;

i = 0;

for (vector⟨Circle ∗⟩::const iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter ) { g ≪ ␣ ≪ i^{++} ≪ ; (∗∗iter ).show (g.str ( ), coords , do persp, do apply , f, proj , factor ); g.str ( );

} } else cout ≪ ␣ ␣ ; if (ellipses .size( ) > 0) {

cout ≪ ␣ ;

i = 0;

for (vector⟨Ellipse ∗⟩::const iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter ) { g ≪ ␣ ≪ i^{++} ≪ ; (∗∗iter ).show (g.str ( ), coords , do persp, do apply , f, proj , factor ); g.str ( );

} } else cout ≪ ␣ ␣ ; if (reg polygons .size( ) > 0) {

cout ≪ ␣ ;

i = 0;

for (vector⟨Reg Polygon ∗⟩::const iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) { g ≪ ␣ ≪ i^{++} ≪ ; (∗∗iter ).show (g.str ( ), coords , do persp, do apply , f, proj , factor ); g.str ( );

} }

else cout ≪  ␣  ␣  ;

if (rectangles .size( ) > 0) { cout ≪ ␣ ; i = 0; for (vector⟨Rectangle ∗⟩::const iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( );

++iter ) { g ≪ ␣ ≪ i^{++} ≪ ; (∗∗iter ).show (g.str ( ), coords , do persp, do apply , f, proj , factor ); g.str ( );

} } else cout ≪ ␣ ␣ ; cout ≪ endl ≪ flush; return;

}

1383. Clear. [LDF 2002.10.07.] Replaced dummy definition with a real one. Now, clear ( ) is called for all of the objects in the Solid. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void clear ( );

1384. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::clear ( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

for (vector⟨Path ∗⟩::iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter ) (∗∗iter ).clear ( ); paths .clear ( ); for (vector⟨Circle ∗⟩::iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter ) (∗∗iter ).clear ( ); circles .clear ( ); for (vector⟨Ellipse ∗⟩::iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter )

(∗∗iter ).clear ( ); ellipses .clear ( ); for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) (∗∗iter ).clear ( ); reg polygons .clear ( ); for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); ^{++}iter )

(∗∗iter ).clear ( ); rectangles .clear ( ); if ( ) cout ≪ ␣ ≪ flush; return;

}

1385. Transformations.

1386. Multiplying by a Transform. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual Transform operator∗=(const Transform &t);

412  MULTIPLYING BY A TRANSFORM  3DLDF-1.1.5.1 §1387

1387. ⟨ Define Solid functions 1337 ⟩ +≡

Transform Solid ::operator∗=(const Transform &t) {

center ∗= t; for (vector⟨Path ∗⟩::iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter ) ∗∗iter ∗= t; for (vector⟨Ellipse ∗⟩::iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter ) ∗∗iter ∗= t; for (vector⟨Circle ∗⟩::iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter ) ∗∗iter ∗= t; for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) ∗∗iter ∗= t; for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); ^{++}iter )

∗∗iter ∗= t; return t;

}

1388. Applying a transformation.

Log

[LDF 2003.01.05.] Added this function. It’s now needed because I’ve made apply transform( ) a pure virtual function in class Shape. BUG FIX: I’ve done this in an attempt to fix a bug in Picture ::output ( ), where the Points on a Path were not transformed when I used “Transform t; current picture ∗= t”.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual void apply transform(void);

1389. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::apply transform(void) {

center .apply transform( ); for (vector⟨Path ∗⟩::iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter )

(∗∗iter ).apply transform( ); for (vector⟨Ellipse ∗⟩::iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter )

(∗∗iter ).apply transform( ); for (vector⟨Circle ∗⟩::iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter )

(∗∗iter ).apply transform( ); for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) (∗∗iter ).apply transform( ); for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); ^{++}iter )

(∗∗iter ).apply transform( ); }

1390. Scale. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual Transform scale(real xx , real yy = 0, real zz = 0); 1391. ⟨ Define Solid functions 1337 ⟩ +≡

Transform Solid ::scale(real xx , real yy , real zz )

{ Transform t; t.scale(xx , yy , zz ); ∗this ∗= t; return t;

}

1392. Shear. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual Transform shear (real xy , real xz = 0, real yx = 0, real yz = 0, real zx = 0, real zy = 0);

1393. ⟨ Define Solid functions 1337 ⟩ +≡

Transform Solid ::shear (real xy , real xz , real yx , real yz , real zx , real zy )

{ Transform t; t.shear (xy , xz , yx , yz , zx , zy ); ∗this ∗= t; return t;

}

1394. Shift.

1395. real arguments. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual Transform shift (real xx , real yy = 0, real zz = 0);

1396. ⟨ Define Solid functions 1337 ⟩ +≡

Transform Solid ::shift (real xx , real yy , real zz )

{ Transform t; t.shift (xx , yy , zz ); ∗this ∗= t; return t;

}

1397. Point argument. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual Transform shift (const Point &pt ); 1398. ⟨ Define Solid functions 1337 ⟩ +≡

Transform Solid ::shift (const Point &pt )

{ Transform t; t.shift (pt ); ∗this ∗= t; return t;

}

1399. Rotatation around the main axes. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual Transform rotate(const real xx , const real yy = 0, const real zz = 0);

1400. ⟨ Define Solid functions 1337 ⟩ +≡

Transform Solid ::rotate(const real xx , const real yy , const real zz )

{ Transform t; t.rotate(xx , yy , zz ); ∗this ∗= t; return t;

}

1401. Rotatation around an arbitrary axis.

Log

[LDF 2003.05.02.] Changed name of this function from rotate around ( ) to rotate( ). This function now overloads rotate( ) with three real arguments.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual Transform rotate(const Point &p0 , const Point &p1 , const real angle = 180);

1402. ⟨ Define Solid functions 1337 ⟩ +≡

Transform Solid ::rotate(const Point &p0 , const Point &p1 , const real angle)

{ Transform t; t.rotate(p0 , p1 , angle); ∗this ∗= t; return t;

}

1403. Outputting.

1404. Extract. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual vector⟨Shape ∗⟩ extract (const Focus &f, const unsigned short proj , real factor ); 1405. ⟨ Define Solid functions 1337 ⟩ +≡

vector⟨Shape ∗⟩ Solid ::extract (const Focus &f, const unsigned short proj , real factor ) {

vector⟨Shape ∗⟩ v; for (vector⟨Path ∗⟩::iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter ) {

(∗∗iter ).apply transform( ); if (¬(∗∗iter ).project (f, proj , factor )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush; return v; break;

} } for (vector⟨Ellipse ∗⟩::iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter ) {

(∗∗iter ).apply transform( ); if (¬(∗∗iter ).project (f, proj , factor )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush; return v; break;

} } for (vector⟨Circle ∗⟩::iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter ) {

(∗∗iter ).apply transform( ); if (¬(∗∗iter ).project (f, proj , factor )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush; return v; break;

} } for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) { (∗∗iter ).apply transform( ); if (¬(∗∗iter ).project (f, proj , factor )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush; return v; break;

} } for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); ^{++}iter ) {

(∗∗iter ).apply transform( ); if (¬(∗∗iter ).project (f, proj , factor )) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush; return v; break;

} } v.push back (this );

416  EXTRACT  3DLDF-1.1.5.1 §1405

return v; }

1406. Set extremes. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual bool set extremes ( ); 1407. ⟨ Define Solid functions 1337 ⟩ +≡

bool Solid ::set extremes ( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

valarray⟨real⟩ v; v.resize(6, 0); /∗ LDF 2002.12.13. Added. Needed for compiling under GNU/Linux using GCC on

the Intel i686 computer gwdu101.gwdg.de. ∗/ for (vector⟨Path ∗⟩::iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter ) {

if (¬(∗∗iter ).set extremes ( )) {

cerr ≪  ␣  ␣  ≪
␣        ␣      ␣ ≪  ␣  ≪ flush;

return false; } v = (∗∗iter ).get extremes ( ); for (int i = 0; i < 3; ^{++}i) /∗ Minima. ∗/ {

projective extremes [i] = min(projective extremes [i], v[i]); } for (int i = 3; i < 6; ^{++}i) /∗ Maxima. ∗/ {

projective extremes [i] = max (projective extremes [i], v[i]); }

} for (vector⟨Ellipse ∗⟩::iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter ) {

if (¬(∗∗iter ).set extremes ( )) {

cerr ≪  ␣  ␣  ≪
␣        ␣      ␣ ≪  ␣  ≪ flush;

return false; } v = (∗∗iter ).get extremes ( ); for (int i = 0; i < 3; ^{++}i) /∗ Minima. ∗/ {

projective extremes [i] = min(projective extremes [i], v[i]); } for (int i = 3; i < 6; ^{++}i) /∗ Maxima. ∗/ {

projective extremes [i] = max (projective extremes [i], v[i]); }

} for (vector⟨Circle ∗⟩::iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter ) {

if (¬(∗∗iter ).set extremes ( )) {

cerr ≪  ␣  ␣  ≪
␣        ␣      ␣ ≪  ␣  ≪ flush;

return false; } v = (∗∗iter ).get extremes ( ); for (int i = 0; i < 3; ^{++}i) /∗ Minima. ∗/ {

projective extremes [i] = min(projective extremes [i], v[i]); } for (int i = 3; i < 6; ^{++}i) /∗ Maxima. ∗/ {

projective extremes [i] = max (projective extremes [i], v[i]); }

} for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) { if (¬(∗∗iter ).set extremes ( )) {

cerr ≪  ␣  ␣  ≪
␣        ␣      ␣ ≪  ␣  ≪ flush;

return false; } v = (∗∗iter ).get extremes ( ); for (int i = 0; i < 3; ^{++}i) /∗ Minima. ∗/ {

projective extremes [i] = min(projective extremes [i], v[i]); } for (int i = 3; i < 6; ^{++}i) /∗ Maxima. ∗/ {

projective extremes [i] = max (projective extremes [i], v[i]); }

} for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); ^{++}iter ) {

if (¬(∗∗iter ).set extremes ( )) {

cerr ≪  ␣  ␣  ≪
␣        ␣      ␣ ≪  ␣  ≪ flush;

return false; } v = (∗∗iter ).get extremes ( ); for (int i = 0; i < 3; ^{++}i) /∗ Minima. ∗/ {

projective extremes [i] = min(projective extremes [i], v[i]); } for (int i = 3; i < 6; ^{++}i) /∗ Maxima. ∗/ {

projective extremes [i] = max (projective extremes [i], v[i]); }

} if ( ) cout ≪ ␣ ≪ ≪ flush; return true;

}

1408. Get extremes. ⟨ Declare Solid functions 1336 ⟩ +≡

inline virtual const valarray⟨real⟩ get extremes ( ) const {

return projective extremes ; }

1409. Get minimum z. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual real get minimum z ( ) const;

1410. ⟨ Define Solid functions 1337 ⟩ +≡

real Solid ::get minimum z ( ) const {

bool = false; /∗ true ∗/

if ( ) { cout ≪ ␣ ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ projective extremes [4] ≪ endl ≪ flush; cout ≪ ␣ ≪ endl ≪ flush;

}

return projective extremes [4]; }

1411. Get maximum z. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual real get maximum z ( ) const;

1412. ⟨ Define Solid functions 1337 ⟩ +≡

real Solid ::get maximum z ( ) const {

bool = false; /∗ true ∗/

if ( ) { cout ≪ ␣ ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ projective extremes [5] ≪ endl ≪ flush; cout ≪ ␣ ≪ endl ≪ flush;

}

return projective extremes [5]; }

1413. Get mean z. [LDF 2003.05.16.] Added this function. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual real get mean z ( ) const;

1414. ⟨ Define Solid functions 1337 ⟩ +≡

real Solid ::get mean z ( ) const {

return ((projective extremes [4] + projective extremes [5])/2); }

1415. Suppress output. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void suppress output ( ); 1416. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::suppress output ( )

{ do output = false; return;

}

1417. Unsuppress output. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void unsuppress output ( );

1418. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::unsuppress output ( )

{ do output = true; return;

}

1419. Output. [LDF 2002.10.02.] In Picture ::output ( ), shapes is sorted according to the values in projective extremes for each Shape. However, it’s possible (and even likely) that the individual Paths in a Solid are not ordered in such a way that they will be output in the correct order. Therefore, I declare a vector⟨Shape ∗⟩ s and put the Paths from paths , circles , ellipses , reg polygons , and rectangles onto it. Then I sort s and call output ( ) for each Shape. Currently, output ( ) will resolve to Path ::output ( ), because output ( ) hasn’t been overloaded for Circle, Ellipse, Reg Polygon, or Rectangle (and probably won’t be).

The invocation of push back ( ) in each of the four loops depends on the fact that Path ::extract ( ) returns a vector containing only one element. That’s why I use front ( ). There is no operator or function for concatenating vectors, at least I couldn’t find one in Stroustrup. TO DO: Get reference! ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void output ( ); 1420. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::output ( ) {

bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ;

vector⟨Shape ∗⟩ s; for (vector⟨Path ∗⟩::iterator iter = paths .begin( ); iter ≠ paths .end ( ); ^{++}iter )

s.push back ((∗∗iter ).get copy ( )); for (vector⟨Circle ∗⟩::iterator iter = circles .begin( ); iter ≠ circles .end ( ); ^{++}iter )

s.push back ((∗∗iter ).get copy ( )); for (vector⟨Ellipse ∗⟩::iterator iter = ellipses .begin( ); iter ≠ ellipses .end ( ); ^{++}iter )

s.push back ((∗∗iter ).get copy ( )); for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) s.push back ((∗∗iter ).get copy ( )); for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); ^{++}iter )

s.push back ((∗∗iter ).get copy ( )); sort (s.begin( ), s.end ( ), Compare maximum z( )); for (vector⟨Shape ∗⟩::iterator iter = s.begin( ); iter ≠ s.end ( ); ^{++}iter ) {

(∗∗iter ).output ( );

delete (∗iter ); } if ( ) cout ≪ ␣ ;

}

1421. Drawing and filling.

422  DRAWING AND FILLING  3DLDF-1.1.5.1 §1422

1422. Process vectors for draw(). [LDF 2002.10.09.] Added this section. The same things are done to each of the Shape ∗ vectors paths , ellipses , circles , reg polygons , and rectangles , so I’ve put the code in this named section. Each time it it’s used, iter is an iterator for a different vector. ⟨ Process vectors for draw ( ) 1422 ⟩ ≡

{ if (c iter ≠ v.end ( )) {

color ptr = ∗c iter^{++}; } (∗∗iter ).set fill draw value( ); /∗ LDF 2002.10.09. Added code for handling draw color . ∗/ if ( ) {

cout ≪ ␣ ␣ ≪ color ptr get use name( ) ≪ endl ≪ flush; } if (color ptr get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ∗color ptr ; (∗∗iter ).set draw color (c); } else {

if ( ) cout ≪ ␣ ␣ ≪ color ptr get name( ) ≪ endl ≪ flush; (∗∗iter ).set draw color (color ptr );

} (∗∗iter ).set fill color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set dash pattern(ddashed ); (∗∗iter ).set pen(ppen); }

This code is used in section 1424.

1423. Draw. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void draw (const vector⟨const Color ∗⟩ v = Colors ::default color vector , const string ddashed = , const string ppen = , Picture &picture = current picture) const;

§1424  3DLDF-1.1.5.1  DRAW 423

1424. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::draw (const vector⟨const Color ∗⟩ v, const string ddashed , const string ppen, Picture

&picture) const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

Solid ∗s = create new < Solid > (0); ∗s = ∗this ; const Color ∗color ptr = Colors ::default color ; vector⟨const Color ∗⟩::const iterator c iter = v.begin( ); for (vector⟨Path ∗⟩::const iterator iter = s paths .begin( ); iter ≠ s paths .end ( ); ^{++}iter ) {

⟨ Process vectors for draw ( ) 1422 ⟩ } c iter = v.begin( ); for (vector⟨Circle ∗⟩::const iterator iter = s circles .begin( ); iter ≠ s circles .end ( ); ^{++}iter ) {

⟨ Process vectors for draw ( ) 1422 ⟩ } c iter = v.begin( ); for (vector⟨Ellipse ∗⟩::const iterator iter = s ellipses .begin( ); iter ≠ s ellipses .end ( ); ^{++}iter ) {

⟨ Process vectors for draw ( ) 1422 ⟩ } /∗ for ∗/ c iter = v.begin( ); for (vector⟨Reg Polygon ∗⟩::const iterator iter = s reg polygons .begin( );

iter ≠ s reg polygons .end ( ); ^{++}iter ) { ⟨ Process vectors for draw ( ) 1422 ⟩

} for (vector⟨Rectangle ∗⟩::const iterator iter = s rectangles .begin( ); iter ≠ s rectangles .end ( );

++iter ) { ⟨ Process vectors for draw ( ) 1422 ⟩

} picture += dynamic cast⟨Shape ∗⟩(s); if ( ) {

cout ≪ ␣ ≪ ≪ flush; } }

424  DRAW  3DLDF-1.1.5.1 §1425

1425. Process vectors for fill(). [LDF 2002.10.09.] Added this section. The same things are done to each of the Shape ∗ vectors paths , ellipses , circles , reg polygons , and rectangles , so I’ve put the code in this named section. Each time it it’s used, iter is an iterator for a different vector.

Log

[LDF 2003.08.10.] Now setting pen to , because I’ve removed the pen argument from fill ( ).

⟨ Process vectors for fill ( ) 1425 ⟩ ≡ { if (c iter ≠ v.end ( )) {

color ptr = ∗c iter^{++}; } (∗∗iter ).set fill draw value( );

/∗ LDF 2002.10.09. Added code for handling draw color and fill color . ∗/ if ( ) {

cout ≪ ␣ ␣ ≪ color ptr get use name( ) ≪ endl ≪ flush; } if (color ptr get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ∗color ptr ; (∗∗iter ).set fill color (c); } else {

if ( ) cout ≪ ␣ ␣ ≪ color ptr get name( ) ≪ endl ≪ flush; (∗∗iter ).set fill color (color ptr );

} (∗∗iter ).set draw color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set dash pattern( ); (∗∗iter ).set pen( ); }

This code is used in section 1427.

1426. Fill.

Log

[LDF 2003.08.10.] Removed pen argument, since filling doesn’t use a pen.

⟨ Declare Solid functions 1336 ⟩ +≡

virtual void fill (const vector⟨const Color ∗⟩ v = Colors ::default color vector , Picture &picture = current picture) const;

§1427  3DLDF-1.1.5.1  FILL 425

1427. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::fill (const vector⟨const Color ∗⟩ v, Picture &picture) const{ bool = false;

/∗ true ∗/ if ( ) cout ≪ ␣ ≪ ≪ flush; Solid ∗s = create new < Solid > (0); ∗s = ∗this ; const Color ∗color ptr = Colors ::default color ; vector⟨const Color ∗⟩::const iterator c iter = v.begin( ); for (vector⟨Path ∗⟩::const iterator iter = s paths .begin( ); iter ≠ s paths .end ( ); ^{++}iter ) {

⟨ Process vectors for fill ( ) 1425 ⟩ } c iter = v.begin( ); for (vector⟨Circle ∗⟩::const iterator iter = s circles .begin( ); iter ≠ s circles .end ( ); ^{++}iter ) {

⟨ Process vectors for fill ( ) 1425 ⟩ } c iter = v.begin( ); for (vector⟨Ellipse ∗⟩::const iterator iter = s ellipses .begin( ); iter ≠ s ellipses .end ( ); ^{++}iter ) {

⟨ Process vectors for fill ( ) 1425 ⟩ } c iter = v.begin( ); for (vector⟨Reg Polygon ∗⟩::const iterator iter = s reg polygons .begin( );

iter ≠ s reg polygons .end ( ); ^{++}iter ) { ⟨ Process vectors for fill ( ) 1425 ⟩

} c iter = v.begin( ); for (vector⟨Rectangle ∗⟩::const iterator iter = s rectangles .begin( ); iter ≠ s rectangles .end ( );

++iter ) { ⟨ Process vectors for fill ( ) 1425 ⟩

} picture += dynamic cast⟨Shape ∗⟩(s); if ( ) {

cout ≪ ␣ ≪ ≪ flush; } }

426  FILL  3DLDF-1.1.5.1 §1428

1428. Process vectors for filldraw(). [LDF 2002.10.09.] Added this section. The same things are done to each of the Shape ∗ vectors paths , ellipses , circles , reg polygons , and rectangles , so I’ve put the code in this named section. Each time it it’s used, iter is an iterator for a different vector. ⟨ Process vectors for filldraw ( ) 1428 ⟩ ≡

{ if (draw color iter ≠ draw colors .end ( )) {

draw color ptr = ∗draw color iter^{++}; } if (fill color iter ≠ fill colors .end ( )) {

fill color ptr = ∗fill color iter^{++}; } (∗∗iter ).set fill draw value( ); if ( ) {

cout ≪ ␣ ␣ ≪ draw color ptr get use name( ) ≪ endl ≪ flush; } if (draw color ptr get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ∗draw color ptr ; (∗∗iter ).set draw color (c); } else {

if ( )

cout ≪ ␣ ␣ ≪ draw color ptr get name( ) ≪ endl ≪ flush; (∗∗iter ).set draw color (draw color ptr );

} if ( ) {

cout ≪ ␣ ␣ ≪ fill color ptr get use name( ) ≪ endl ≪ flush; } if (fill color ptr get use name( ) ≡ false) { if ( ) cout ≪ ␣ ␣ ␣ ≪ flush; Color ∗c = create new < Color > (0); ∗c = ∗fill color ptr ; (∗∗iter ).set fill color (c); } else {

if ( )

cout ≪ ␣ ␣ ≪ fill color ptr get name( ) ≪ endl ≪ flush; (∗∗iter ).set fill color (fill color ptr );

} (∗∗iter ).set pen(ppen); (∗∗iter ).set dash pattern(ddashed ); }

This code is used in section 1430.

1429. Filldraw. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual 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) const;

§1430  3DLDF-1.1.5.1  FILLDRAW 427

1430. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::filldraw (const vector⟨const Color ∗⟩ draw colors , const vector⟨const Color ∗⟩ fill colors , const string ddashed , const string ppen, Picture &picture) const{ bool = false; /∗ true ∗/

if ( ) cout ≪ ␣ ≪ ≪ flush; Solid ∗s = create new < Solid > (0); ∗s = ∗this ; const Color ∗draw color ptr ; const Color ∗fill color ptr ; vector⟨const Color ∗⟩::const iterator draw color iter = draw colors .begin( ); vector⟨const Color ∗⟩::const iterator fill color iter = fill colors .begin( ); for (vector⟨Path ∗⟩::const iterator iter = s paths .begin( ); iter ≠ s paths .end ( ); ^{++}iter ) {

⟨ Process vectors for filldraw ( ) 1428 ⟩ } draw color iter = draw colors .begin( ); fill color iter = fill colors .begin( ); for (vector⟨Circle ∗⟩::const iterator iter = s circles .begin( ); iter ≠ s circles .end ( ); ^{++}iter ) {

⟨ Process vectors for filldraw ( ) 1428 ⟩ } draw color iter = draw colors .begin( ); fill color iter = fill colors .begin( ); for (vector⟨Ellipse ∗⟩::const iterator iter = s ellipses .begin( ); iter ≠ s ellipses .end ( ); ^{++}iter ) {

⟨ Process vectors for filldraw ( ) 1428 ⟩ } draw color iter = draw colors .begin( ); fill color iter = fill colors .begin( ); for (vector⟨Reg Polygon ∗⟩::const iterator iter = s reg polygons .begin( );

iter ≠ s reg polygons .end ( ); ^{++}iter ) { ⟨ Process vectors for filldraw ( ) 1428 ⟩

} for (vector⟨Rectangle ∗⟩::const iterator iter = s rectangles .begin( ); iter ≠ s rectangles .end ( );

++iter ) { ⟨ Process vectors for filldraw ( ) 1428 ⟩

} picture += dynamic cast⟨Shape ∗⟩(s); if ( ) {

cout ≪ ␣ ≪ ≪ flush; } }

428  FILLDRAW  3DLDF-1.1.5.1 §1431

1431. Process vectors for undraw(). [LDF 2002.10.09.] Added this section. The same things are done to each of the Shape ∗ vectors paths , ellipses , circles , reg polygons , and rectangles , so I’ve put the code in this named section. Each time it it’s used, iter is an iterator for a different vector. ⟨ Process vectors for undraw ( ) 1431 ⟩ ≡

{ (∗∗iter ).set fill draw value( ); (∗∗iter ).set draw color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set fill color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set dash pattern(ddashed ); (∗∗iter ).set pen(ppen);

}

This code is used in section 1433.

1432. Undraw. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void undraw (const string ddashed = , const string ppen = , Picture &picture = current picture) const;

1433. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::undraw (const string ddashed , const string ppen, Picture &picture) const{ bool

= false; /∗ true ∗/ if ( ) cout ≪ ␣ ≪ ≪ flush; Solid ∗s = create new < Solid > (0); ∗s = ∗this ; for (vector⟨Path ∗⟩::const iterator iter = s paths .begin( ); iter ≠ s paths .end ( ); ^{++}iter ) {

⟨ Process vectors for undraw ( ) 1431 ⟩ } for (vector⟨Circle ∗⟩::const iterator iter = s circles .begin( ); iter ≠ s circles .end ( ); ^{++}iter ) {

⟨ Process vectors for undraw ( ) 1431 ⟩ } for (vector⟨Ellipse ∗⟩::const iterator iter = s ellipses .begin( ); iter ≠ s ellipses .end ( ); ^{++}iter ) {

⟨ Process vectors for undraw ( ) 1431 ⟩ } for (vector⟨Reg Polygon ∗⟩::const iterator iter = s reg polygons .begin( );

iter ≠ s reg polygons .end ( ); ^{++}iter ) { ⟨ Process vectors for undraw ( ) 1431 ⟩

} for (vector⟨Rectangle ∗⟩::const iterator iter = s rectangles .begin( ); iter ≠ s rectangles .end ( );

++iter ) { ⟨ Process vectors for undraw ( ) 1431 ⟩

} picture += dynamic cast⟨Shape ∗⟩(s); if ( ) {

cout ≪ ␣ ≪ ≪ flush; } }

§1434  3DLDF-1.1.5.1  UNDRAW 429

1434. Process vectors for unfill().

Log

[LDF 2002.10.09.] Added this section. The same things are done to each of the Shape ∗ vectors paths , ellipses , circles , reg polygons , and rectangles , so I’ve put the code in this named section. Each time it it’s used, iter is an iterator for a different vector.

[LDF 2003.08.10.] Now setting pen to , since I’ve removed the pen argument to unfill ( ).

⟨ Process vectors for unfill ( ) 1434 ⟩ ≡

{ (∗∗iter ).set fill draw value( ); (∗∗iter ).set draw color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set fill color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set dash pattern( ); (∗∗iter ).set pen( );

}

This code is used in section 1436.

1435. Unfill.

Log

[LDF 2003.08.10.] Removed the pen argument, since unfilling doesn’t use a pen.

⟨ Declare Solid functions 1336 ⟩ +≡ virtual void unfill (Picture &picture = current picture) const;

430  UNFILL  3DLDF-1.1.5.1 §1436

1436. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::unfill (Picture &picture) const{ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪  ≪ flush;

Solid ∗s = create new < Solid > (0); ∗s = ∗this ; for (vector⟨Path ∗⟩::const iterator iter = s paths .begin( ); iter ≠ s paths .end ( ); ^{++}iter ) {

⟨ Process vectors for unfill ( ) 1434 ⟩ } for (vector⟨Circle ∗⟩::const iterator iter = s circles .begin( ); iter ≠ s circles .end ( ); ^{++}iter ) {

⟨ Process vectors for unfill ( ) 1434 ⟩ } for (vector⟨Ellipse ∗⟩::const iterator iter = s ellipses .begin( ); iter ≠ s ellipses .end ( ); ^{++}iter ) {

⟨ Process vectors for unfill ( ) 1434 ⟩ } for (vector⟨Reg Polygon ∗⟩::const iterator iter = s reg polygons .begin( );

iter ≠ s reg polygons .end ( ); ^{++}iter ) { ⟨ Process vectors for unfill ( ) 1434 ⟩

} for (vector⟨Rectangle ∗⟩::const iterator iter = s rectangles .begin( ); iter ≠ s rectangles .end ( );

++iter ) { ⟨ Process vectors for unfill ( ) 1434 ⟩

} picture += dynamic cast⟨Shape ∗⟩(s); if ( ) {

cout ≪ ␣ ≪ ≪ flush; } }

1437. Process vectors for unfilldraw(). [LDF 2002.10.09.] Added this section. The same things are done to each of the Shape ∗ vectors paths , ellipses , circles , reg polygons , and rectangles , so I’ve put the code in this named section. Each time it it’s used, iter is an iterator for a different vector. ⟨ Process vectors for unfilldraw ( ) 1437 ⟩ ≡

{ (∗∗iter ).set fill draw value( ); (∗∗iter ).set draw color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set fill color (static cast⟨Color ∗⟩(0)); (∗∗iter ).set dash pattern(ddashed ); (∗∗iter ).set pen(ppen);

}

This code is used in section 1439.

1438. Unfilldraw. [LDF 2002.10.09.] Unlike Path ::unfilldraw ( ), Solid ::unfilldraw ( ) behaves like METAPOST’s unfilldraw command, i.e., it unfills and undraws. I intend to change Path ::unfilldraw ( ) so that it also behaves this way.

!! [LDF 2002.10.09.] Check this: the correct code is written to out stream, but after filldraw ( ) and unfill draw ( ), the outline is visible, but no lines inside the outline. TO DO: Check what filldraw and unfilldraw mean in METAPOST and METAFONT. ⟨ Declare Solid functions 1336 ⟩ +≡

virtual void unfilldraw (const string ddashed = , const string ppen = , Picture &picture = current picture) const;

§1439  3DLDF-1.1.5.1  UNFILLDRAW 431

1439. ⟨ Define Solid functions 1337 ⟩ +≡

void Solid ::unfilldraw (const string ddashed , const string ppen, Picture &picture) const{ bool

= false; /∗ true ∗/ if ( ) cout ≪ ␣ ≪ ≪ flush; Solid ∗s = create new < Solid > (0); ∗s = ∗this ; for (vector⟨Path ∗⟩::const iterator iter = s paths .begin( ); iter ≠ s paths .end ( ); ^{++}iter ) {

⟨ Process vectors for unfilldraw ( ) 1437 ⟩ } /∗ for ∗/ for (vector⟨Circle ∗⟩::const iterator iter = s circles .begin( ); iter ≠ s circles .end ( ); ^{++}iter ) {

⟨ Process vectors for unfilldraw ( ) 1437 ⟩ } for (vector⟨Ellipse ∗⟩::const iterator iter = s ellipses .begin( ); iter ≠ s ellipses .end ( ); ^{++}iter ) {

⟨ Process vectors for unfilldraw ( ) 1437 ⟩ } for (vector⟨Reg Polygon ∗⟩::const iterator iter = s reg polygons .begin( );

iter ≠ s reg polygons .end ( ); ^{++}iter ) { ⟨ Process vectors for unfilldraw ( ) 1437 ⟩

} for (vector⟨Rectangle ∗⟩::const iterator iter = s rectangles .begin( ); iter ≠ s rectangles .end ( );

++iter ) { ⟨ Process vectors for unfilldraw ( ) 1437 ⟩

} picture += dynamic cast⟨Shape ∗⟩(s); if ( ) {

cout ≪ ␣ ≪ ≪ flush; } }

1440. Putting Solid together.

1441. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Solid 1333 ⟩ ⟨ Define static const Solid data members 1334 ⟩ ⟨ Define Solid functions 1337 ⟩ ⟨ Declare non-member template functions for Solid 1341 ⟩

432  PUTTING SOLID TOGETHER  3DLDF-1.1.5.1 §1442

1442. This is what’s written to solids.h.

⟨ 1442 ⟩ ≡

⟨ Define class Solid 1333 ⟩

⟨ Declare non-member template functions for Solid 1341 ⟩

1443. Solid Faced (solfaced.web).

Log

[LDF 2002.09.26.] Created this file.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1444. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1445. Solid Faced class definition. ⟨ Define class Solid Faced 1445 ⟩ ≡

class Solid Faced : public Solid {

protected: unsigned short faces ; unsigned short vertices ; unsigned short edges ;

public: ⟨ Declare Solid Faced functions 1446 ⟩

};

This code is used in sections 1449 and 1450.

1446. ⟨ Declare Solid Faced functions 1446 ⟩ ≡

This code is used in section 1445.

§1447  3DLDF-1.1.5.1  SOLID FACED CLASS DEFINITION 433

1447. ⟨ Define Solid Faced functions 1447 ⟩ ≡

This code is used in section 1449.

1448. Putting Solid Faced together.

1449. This is what’s compiled.

⟨ Include files 6 ⟩

⟨ Version control identifier 5 ⟩

⟨ Define class Solid Faced 1445 ⟩ ⟨ Define Solid Faced functions 1447 ⟩

434  PUTTING SOLID FACED TOGETHER  3DLDF-1.1.5.1 §1450

1450. This is what’s written to solfaced.h.

⟨ 1450 ⟩ ≡

⟨ Define class Solid Faced 1445 ⟩

1451. Cuboid (cuboid.web).

Log

[LDF 2002.04.22.] Created this file. When I’ve found out what the English word is for “Quader”, I’ll change it globally.

[LDF 2002.04.22.] Cuboid is the first three-dimensional object I’ve defined. I’ve just quickly put it together for use in a drawing. Ultimately, I’d like to derive it from Shape, which will require defining versions of all the pure virtual functions in Shape.

[LDF 2002.04.23.] Changed Quader to Cuboid. Haven’t changed name of file, because this is more complicated, because of RCS (the source code control system).

[LDF 2002.05.03.] Changed the name of this file from quader.web to cuboid.web. This means that if you need to compare this file with revisions earlier than the initial version of this file, you’ll have to check revisions of quader.web.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

format Cuboid Solid

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1452. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1453. Cuboid class definition.

§1453  3DLDF-1.1.5.1  CUBOID CLASS DEFINITION 435

Log

[LDF 2002.04.22.] Added this class declaration. [LDF 2003.08.10.] Removed dihedral angle.

⟨ Define class Cuboid 1453 ⟩ ≡ class Cuboid : public Solid Faced { protected: real height ;

real width;

real depth; public: ⟨ Declare Cuboid functions 1455 ⟩ };

This code is used in sections 1468 and 1469.

1454. Constructors and setting functions.

1455. Default constructor. No arguments. [LDF 2002.04.22.] Added this function. ⟨ Declare Cuboid functions 1455 ⟩ ≡

Cuboid( );

See also sections 1457, 1459, 1464, and 1466. This code is used in section 1453.

1456. ⟨ Define Cuboid functions 1456 ⟩ ≡

Cuboid ::Cuboid( ) {

on free store = false;

do output = true;

projective extremes .resize(6, 0); faces = 6; vertices = 8; edges = 12;

}

See also sections 1458, 1460, 1465, and 1467. This code is used in section 1468.

1457. Copy constructor. [LDF 2002.05.03.] Added this function. ⟨ Declare Cuboid functions 1455 ⟩ +≡

Cuboid(const Cuboid &c); 1458. ⟨ Define Cuboid functions 1456 ⟩ +≡

Cuboid ::Cuboid(const Cuboid &c){ on free store = false; do output = true; projective extremes .resize(6, 0); faces = 6; vertices = 8; edges = 12; for (vector⟨Rectangle ∗⟩::const iterator iter = c.rectangles .begin( );

iter ≠ c.rectangles .end ( ); iter^{++}) { rectangles .push back ( create new < Rectangle > (0) ) ; ∗(rectangles .back ( )) = ∗∗iter ; } }

1459. Center, height, width, depth, and angles. [LDF 2002.10.06.] Added this constructor. ⟨ Declare Cuboid functions 1455 ⟩ +≡

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);

§1460  3DLDF-1.1.5.1  CENTER, HEIGHT, WIDTH, DEPTH, AND ANGLES 437

1460. ⟨ Define Cuboid functions 1456 ⟩ +≡

Cuboid ::Cuboid(const Point &c, const real h, const real w, const real d, const real x, const

real y, const real z): height (h), width(w), depth(d) { bool = false; /∗ true ∗/ on free store = false; do output = true; projective extremes .resize(6, 0); center = c; faces = 6; vertices = 8; edges = 12; Point pts [9]; pts [1].shift (−.5 ∗ width, −.5 ∗ height , −.5 ∗ depth); pts [2].shift (.5 ∗ width, −.5 ∗ height , −.5 ∗ depth); pts [3].shift (.5 ∗ width, .5 ∗ height , −.5 ∗ depth); pts [4].shift (−.5 ∗ width, .5 ∗ height , −.5 ∗ depth); pts [5].shift (−.5 ∗ width, −.5 ∗ height , .5 ∗ depth); pts [6].shift (.5 ∗ width, −.5 ∗ height , .5 ∗ depth); pts [7].shift (.5 ∗ width, .5 ∗ height , .5 ∗ depth); pts [8].shift (−.5 ∗ width, .5 ∗ height , .5 ∗ depth); for (int i = 0; i < 6; i^{++}) { rectangles .push back (

create new < Rectangle > (0) ) ; } rectangles [0] set (pts [1], pts [2], pts [3], pts [4]); /∗ front ∗/

rectangles [1] set (pts [5], pts [6], pts [7], pts [8]); /∗ back ∗/ rectangles [2] set (pts [1], pts [4], pts [8], pts [5]); /∗ left ∗/ rectangles [3] set (pts [2], pts [6], pts [7], pts [3]); /∗ right ∗/ rectangles [4] set (pts [3], pts [7], pts [8], pts [4]); /∗ top ∗/ rectangles [5] set (pts [1], pts [2], pts [6], pts [5]); /∗ bottom ∗/ rotate(x, y, z); shift (c); if ( )

for (int i = 1; i < 9; i^{++}) pts [i].dotlabel (i); }

1461. Pseudo-constructor for dynamic allocation.

1462. Pointer argument.

Log

[LDF 2002.04.22.] Added this function. [LDF 2003.12.30.] Replaced Cuboid ::create new cuboid ( ) with a specialization of template⟨class C⟩

C∗create new ( ) for Cuboid. The argument is now const.

⟨ Declare non-member template functions for Cuboid 1462 ⟩ ≡

Cuboid ∗create new (const Cuboid ∗c);

See also section 1463. This code is used in sections 1468 and 1469.

1463. Reference argument.

Log

LDF 2003.12.30. Added this function.

⟨ Declare non-member template functions for Cuboid 1462 ⟩ +≡ Cuboid ∗create new (const Cuboid &c);

1464. Destructor. !! Make sure to delete anything else that I allocate dynamically! ⟨ Declare Cuboid functions 1455 ⟩ +≡

∼Cuboid( );

1465. ⟨ Define Cuboid functions 1456 ⟩ +≡

Cuboid ::∼Cuboid( ) {

for (vector⟨Rectangle ∗⟩::iterator iter = rectangles .begin( ); iter ≠ rectangles .end ( ); iter^{++}) {

delete ∗iter ; } rectangles .clear ( );

}

1466. Assignment. ⟨ Declare Cuboid functions 1455 ⟩ +≡

void operator=(const Cuboid &c);

1467. ⟨ Define Cuboid functions 1456 ⟩ +≡

void Cuboid ::operator=(const Cuboid &c) {

this Solid ::operator=(c);

height = c.height ;

width = c.width;

depth = c.depth; }

1468. Putting Cuboid together. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Cuboid 1453 ⟩ ⟨ Define Cuboid functions 1456 ⟩ ⟨ Declare non-member template functions for Cuboid 1462 ⟩

§1469  3DLDF-1.1.5.1  PUTTING CUBOID TOGETHER 439

1469. This is what’s written to cuboid.h.

⟨ 1469 ⟩ ≡

⟨ Define class Cuboid 1453 ⟩

⟨ Declare non-member template functions for Cuboid 1462 ⟩

1470. Polyhedra (polyhedra.web). [LDF 2002.11.12.] TO DO: Set center for Dodecahedron, Icosahedron, and Trunc Octahedron. Find out how to set it for Tetrahedron.

[LDF 2002.11.12.] TO DO: Add assignment operators for Polyhedra! The individual types will need there own, but they can call Polyhedron ::operator=( ).

Log

[LDF 2002.09.26.] Created this file.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1471. Include files. ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1472. Polyhedron class definition. [LDF 2002.10.06.] Polyhedron is meant to be used only as a base class, so there’s no need for constructors or setting functions.

TO DO: [LDF 2003.08.15.] If I add any functions, I should add an explanation to “@node Polyhedron Getstart” in DOCUMENTATION/gssolfig.texi about abstract or non-abstract base classes.

Log

[LDF 2002.11.08.] Got rid of pure virtual function Polyhedron ::get net ( ). I’ve made it static in the classes derived from Polyhedron, which makes more sense. virtual functions must be non-static.

440 POLYHEDRON CLASS DEFINITION 3DLDF-1.1.5.1 §1472

format Polyhedron Reg Polygon

⟨ Define class Polyhedron 1472 ⟩ ≡ class Polyhedron : public Solid Faced { protected: unsigned short number of polygon types ;

real face radius ; real edge radius ; real vertex radius ;

public: ⟨ Declare Polyhedron functions 1473 ⟩ };

This code is used in sections 1534 and 1535.

1473. Intersection. !! [LDF 2003.04.15.] START HERE. This function doesn’t work yet.

Log

[LDF 2003.04.09.] Added this section, and the function it contains. [LDF 2003.04.15.] Commented-out this function, since I need to get Reg Polygon ::intersection points ( )

working first.

⟨ Declare Polyhedron functions 1473 ⟩ ≡ #if 0

virtual vector⟨Point⟩ intersection points (const Reg Polygon &r) const; #endif

This code is used in section 1472.

§1474  3DLDF-1.1.5.1  INTERSECTION 441

1474. ⟨ Define Polyhedron functions 1474 ⟩ ≡ #if 0

vector⟨Point⟩ Polyhedron ::intersection points (const Reg Polygon &r) const {

vector⟨Point⟩ v;

vector⟨Point⟩ w;

for (vector⟨Reg Polygon ∗⟩::const iterator iter0 = reg polygons .begin( ); iter0 ≠ reg polygons .end ( );

++iter0 ) { for (vector⟨Reg Polygon ∗⟩::const iterator iter1 = iter0 + 1; iter1 ≠ reg polygons .end ( );

++iter1 ) { v = (∗∗iter0 ).intersection points (∗∗iter1 ); cout ≪ ␣ ␣ ≪ v.size( ) ≪ endl ≪ flush; for (vector⟨Point⟩::iterator pt iter = v.begin( ); pt iter ≠ v.end ( ); ^{++}pt iter )

w.push back (∗pt iter ); }

}

return w; }

#endif

This code is used in section 1534.

1475. Regular Platonic Polyhedra.

1476. Tetrahedron.

Log

[LDF 2002.11.12.] Added this section.

1477. Tetrahedron class definition.

Log

[LDF 2002.11.12.] Added this section.

format Tetrahedron Polyhedron

⟨ Define class Tetrahedron 1477 ⟩ ≡ class Tetrahedron : public Polyhedron { protected: static const real dihedral angle; /∗ In radians! ∗/

real triangle radius ; public: ⟨ Declare Tetrahedron functions 1480 ⟩ };

This code is used in sections 1534 and 1535.

1478. Define static const Tetrahedron data members.

Log

[LDF 2002.11.12.] Added this section.

⟨ Define static const Tetrahedron data members 1478 ⟩ ≡ const real Tetrahedron ::dihedral angle = ∗ (70 + 32/60.0)/180.0;

442  DEFINE STATIC CONST TETRAHEDRON DATA MEMBERS  3DLDF-1.1.5.1 §1478

This code is used in section 1534.

1479. Constructors and setting functions.

1480. Default constructor. (No arguments.)

Log

[LDF 2002.11.12.] Added this function.

⟨ Declare Tetrahedron functions 1480 ⟩ ≡

Tetrahedron( );

See also sections 1483, 1487, 1489, and 1491. This code is used in section 1477.

1481. ⟨ Define Tetrahedron functions 1481 ⟩ ≡

Tetrahedron ::Tetrahedron( )

{ on free store = false; /∗ from Solid. ∗/ do output = true; faces = 4; /∗ from Solid Faced. ∗/ vertices = 4; edges = 6; center = ; /∗ from Polyhedron. ∗/ number of polygon types = 1; face radius = edge radius = vertex radius = ; triangle radius = ; /∗ From Tetrahedron. ∗/

}

See also sections 1484, 1485, 1486, 1488, 1490, and 1492. This code is used in section 1534.

1482. Center, diameter of triangle, and angles.

1483. Constructor.

Log

[LDF 2002.11.12.] Added this function.

[LDF 2003.04.27.] Got this function to work, at least in a rudimentary way.

[LDF 2002.08.12.] Rewrote this function. It now works properly.

⟨ Declare Tetrahedron functions 1480 ⟩ +≡

Tetrahedron(const Point &p, const real diameter of triangle, real angle x = 0, real angle y = 0, real angle z = 0); 1484. ⟨ Define Tetrahedron functions 1481 ⟩ +≡

Tetrahedron ::Tetrahedron(const Point &p, const real triangle diameter , real angle x , real

angle y , real angle z ){ bool = true; /∗ false ∗/ on free store = false; /∗ from Solid. ∗/ do output = true; faces = 4; /∗ from Solid Faced. ∗/ vertices = 4; edges = 6; number of polygon types = 1;

#if 0 /∗ START HERE. TO DO: Must calculate these! ∗/ face radius = 0; edge radius = 0; vertex radius = 0;

#endif triangle radius = triangle diameter /2.0; reg polygons = get net (triangle diameter ); real angle = 180 − (dihedral angle ∗ 180/ ); Point pts [11]; int i; for (i = 0; i < 3; ^{++}i) pts [i] = reg polygons [0] get point (i); reg polygons [1] rotate(pts [0], pts [1], angle); reg polygons [2] rotate(pts [2], pts [0], angle); reg polygons [3] rotate(pts [1], pts [2], −angle);

#if 0

for (i = 0; i < 3; ^{++}i) pts [i].label (i, ); #endif

for (i = 3; i < 7; ^{++}i) {

pts [i] = reg polygons [i − 3] get center ( );

#if 0

pts [i].label (i, );

#endif } pts [7] = reg polygons [3] get point (0);

#if 0

pts [7].label (7, ); #endif

pts [8] = pts [0].mediate(pts [1]); pts [9] = pts [1].mediate(pts [2]); pts [10] = pts [2].mediate(pts [0]);

#if 0

for (i = 8; i < 11; i^{++}) pts [i].label (i); #endif

using namespace Colors; #if 0

pts [0].draw (pts [6], blue); pts [1].draw (pts [5], red ); pts [2].draw (pts [4], green); pts [3].draw (pts [7], orange);

#endif 1485. center is the intersection point of the line segments from the vertices of ∗(reg polygons [0]) to the centers of the opposite faces. distance is the distance along one of these line segments to the intersection point divided by the length of the entire line segment. [LDF 2002.08.12.]

Since this ratio should be the same for all Tetrahedra, there’s no need to recalculate it each time a Tetrahedron is constructed. In addition, intersections can’t always be found, because of inaccuracies caused by rotating the triangles. [LDF 2002.08.12.]

Therefore, I’ve calculated distance using the commented-out code below, and now simply use the value I found. [LDF 2002.08.12.] ⟨ Define Tetrahedron functions 1481 ⟩ +≡

real distance = 0.74997889995574951171875; #if 0

Point = Point ::intersection point (pts [0], pts [6], pts [1], pts [5]).pt ; .show ( ␣ ␣ ␣ ␣ ␣ ); Point ::intersection point (pts [0], pts [6], pts [2], pts [4]).pt .show ( ␣ ␣ ␣ ); Point ::intersection point (pts [0], pts [6], pts [3], pts [7]).pt .show ( ␣ ␣ ␣ ); Point ::intersection point (pts [1], pts [5], pts [2], pts [4]).pt .show ( ␣ ␣ ␣ ); Point ::intersection point (pts [1], pts [5], pts [3], pts [7]).pt .show ( ␣ ␣ ␣ ); Point ::intersection point (pts [2], pts [4], pts [3], pts [7]).pt .show ( ␣ ␣ ␣ ); Point = pts [5] − pts [1]; Point = − pts [1]; .show ( ); cout ≪ ␣␣ ␣ ␣ ≪ .magnitude( ) ≪ endl ≪ flush; .show ( ); cout ≪ ␣ ␣ ≪ .magnitude( ) ≪ endl ≪ flush; distance = ( .magnitude( )/ .magnitude( )); cout .precision(25); cout ≪ ␣ ␣ ≪ distance ≪ endl ≪ flush; cout .precision(6);

#endif

1486. ⟨ Define Tetrahedron functions 1481 ⟩ +≡

center = pts [1].mediate(pts [5], distance); for (i = 0; i < 4; ^{++}i) reg polygons [i] shift (−center ); center .shift (−center ); if (angle x ≠ 0 ∨ angle y ≠ 0 ∨ angle z ≠ 0) {

for (i = 0; i < 4; ^{++}i) reg polygons [i] rotate(angle x , angle y , angle z ); } if (p ≠ origin) {

center = p;

for (i = 0; i < 4; ^{++}i) reg polygons [i] shift (p); } return; } 1487. Setting function. [LDF 2002.11.12.] !! This works, but it fails to assign to the data members of Tetrahedron that are defined in its own class declaration. That’s because neither Tetrahedron nor Polyhedron has an assignment operator yet. TO DO: Write assignment operators for Polyhedra!

Log

[LDF 2002.11.12.] Added this function.

⟨ Declare Tetrahedron functions 1480 ⟩ +≡

void set (const Point &p, const real diameter of triangle, real angle x = 0, real angle y = 0, real angle z = 0);

1488. ⟨ Define Tetrahedron functions 1481 ⟩ +≡

void Tetrahedron ::set (const Point &p, const real triangle diameter , real angle x , real angle y , real

angle z )

{ Tetrahedron t(p, triangle diameter , angle x , angle y , angle z ); ∗this = t; return;

}

1489. Get net. [LDF 2002.11.12.] Unlike the get net ( ) functions for some of the other Polyhedra, this function has no “bool do half ” argument. It doesn’t pay for a Tetrahedron.

Log

[LDF 2002.11.12.] Added this function.

[LDF 2002.08.12.] Removed center 0 argument.

446  GET NET  3DLDF-1.1.5.1 §1490

⟨ Declare Tetrahedron functions 1480 ⟩ +≡ static vector⟨Reg Polygon ∗⟩ get net (const real triangle diameter ); 1490. ⟨ Define Tetrahedron functions 1481 ⟩ +≡

vector⟨Reg Polygon ∗⟩ Tetrahedron ::get net (const real triangle diameter ){ vector⟨Reg Polygon

∗⟩ triangles ; int i; for (i = 0; i < 4; i^{++}) triangles .push back ( create new < Reg Polygon > (0) ) ; triangles [0] set (origin, 3, triangle diameter , 0, 180); triangles [1] set (origin, 3, triangle diameter ); Point pts [6]; for (i = 0; i < 3; ^{++}i) {

pts [i] = triangles [0] get point (i); } for (i = 3; i < 6; ^{++}i) {

pts [i] = triangles [1] get point (i − 3); } ∗triangles [2] = ∗triangles [3] = ∗triangles [1]; triangles [1] shift (pts [0] − pts [4]); triangles [2] shift (pts [0] − pts [5]); triangles [3] shift (pts [2] − pts [4]); return triangles ; }

1491. Draw net. [LDF 2002.11.12.] As of this date it’s necessary to rotate the triangles into the x-y plane, because Point ::intersection point ( ) has a bug that I discovered when I tried to call it on Points in the x-z plane. It’s not so terrible, because as of this date it’s necessary to put the Picture in the x-y plane in order to use the parallel projection. The latter currently only works for the x-y plane. TO DO: Fix the bug and get parallel projection onto other major planes to work!

Log

[LDF 2002.11.12.] Added this function.

§1492  3DLDF-1.1.5.1  DRAW NET 447

⟨ Declare Tetrahedron functions 1480 ⟩ +≡ static void draw net (const real triangle diameter , bool make tabs = true); 1492. ⟨ Define Tetrahedron functions 1481 ⟩ +≡

void Tetrahedron ::draw net (const real triangle diameter , bool make tabs ) {

vector⟨Reg Polygon ∗⟩ v = get net (triangle diameter ); int i; for (i = 0; i < 4; i^{++}) {

v[i] rotate(90);

v[i] draw ( );

v[i] get center ( ).label (i, ); } if (¬make tabs ) return; Point pts [32]; pts [0] = v[2] get point (1); pts [1] = v[2] get point (2); pts [2] = v[1] get point (2); pts [3] = v[1] get point (0); pts [4] = v[3] get point (0); pts [5] = v[3] get point (1); pts [6] = pts [0].mediate(pts [5], .075); pts [7] = pts [5].mediate(pts [0], .075); pts [8] = pts [6]; pts [9] = pts [7]; pts [8] ∗= pts [9].shift (0, 0, 1); pts [10] = pts [0]; pts [11] = pts [5]; pts [10].rotate(pts [6], pts [8], −110); pts [11].rotate(pts [7], pts [9], 110); pts [10] = pts [6].mediate(pts [10], 1.5); pts [11] = pts [7].mediate(pts [11], 1.5);

#if 0 for (i = 0; i < 8; i^{++}) pts [i].dotlabel (i); pts [10].dotlabel (10); pts [11].dotlabel (11);

#endif Path p[6]; p[0].set ( , true, &pts [6], &pts [10], &pts [11], &pts [7], 0); p[0].draw ( ); pts [12] = pts [6].mediate(pts [7]); pts [13] = pts [10].mediate(pts [11]);

#if 0 pts [12].dotlabel (12); pts [13].dotlabel (13);

#endif

p[1].set (pts [12], pts [13]); #if 0

p[1].draw help(∗Colors ::help color , ); #endif

pts [14] = pts [12].mediate(pts [13]); #if 0

448  DRAW NET  3DLDF-1.1.5.1 §1492

pts [14].dotlabel (14); #endif

pts [15] = pts [6].mediate(pts [7], .25); #if 0

pts [15].dotlabel (15); #endif

pts [16] = pts [14]; pts [16].shift (pts [15] − pts [12]);

#if 0

pts [16].dotlabel (16); #endif

bool point bp = Point ::intersection point (pts [14], pts [16], pts [6], pts [10]); pts [17] = bp.pt ;

#if 0

pts [17].dotlabel (17); #endif

bp = Point ::intersection point (pts [14], pts [16], pts [7], pts [11]); pts [18] = bp.pt ;

#if 0

pts [18].dotlabel (18); #endif

p[2].set (pts [17], pts [18]); #if 0

p[2].draw help(∗Colors ::help color , ); #endif

for (i = 1; i < 16; ^{++}i) { pts [19] = pts [17].mediate(pts [18], i/16.0); pts [19].drawdot (∗Colors ::default color , ␣ ␣ );

} pts [20] = pts [17]; pts [21] = pts [18]; p[3] = p[0]; Transform t; t.shift (pts [4] − pts [5]); t.rotate(pts [4], pts [5]); pts [20] ∗= pts [21] ∗= p[3] ∗= t; p[3].draw ( ); for (i = 1; i < 16; ^{++}i) {

pts [19] = pts [20].mediate(pts [21], i/16.0);

pts [19].drawdot (∗Colors ::default color , ␣ ␣ ); } t.reset ( ); t.rotate(pts [4], pts [1]); pts [20] ∗= pts [21] ∗= p[3] ∗= t; p[3].draw ( ); for (i = 1; i < 16; ^{++}i) {

pts [19] = pts [20].mediate(pts [21], i/16.0);

pts [19].drawdot (∗Colors ::default color , ␣ ␣ ); } pts [20] = pts [17]; pts [21] = pts [18]; p[3] = p[0]; pts [20] ∗= pts [21] ∗= p[3] ∗= t; p[3].draw ( ); for (i = 1; i < 16; ^{++}i) {

pts [19] = pts [20].mediate(pts [21], i/16.0);

pts [19].drawdot (∗Colors ::default color , ␣ ␣ ); } t.reset ( ); pts [22] = v[2] get center ( ); pts [23] = pts [22]; pts [23].shift (0, 0, 1); t.rotate(pts [22], pts [23], 120); pts [20] = pts [17]; pts [21] = pts [18]; p[3] = p[0]; pts [20] ∗= pts [21] ∗= p[3] ∗= t; p[3].draw ( ); for (i = 1; i < 16; ^{++}i) {

pts [19] = pts [20].mediate(pts [21], i/16.0);

pts [19].drawdot (∗Colors ::default color , ␣ ␣ ); } t.rotate(pts [4], pts [1]); t.rotate(pts [0], pts [2]); pts [20] = pts [17]; pts [21] = pts [18]; p[3] = p[0]; pts [20] ∗= pts [21] ∗= p[3] ∗= t; p[3].draw ( ); for (i = 1; i < 16; ^{++}i) {

pts [19] = pts [20].mediate(pts [21], i/16.0);

pts [19].drawdot (∗Colors ::default color , ␣ ␣ ); }

}

1493. Dodecahedron.

1494. Dodecahedron class definition.

format Dodecahedron Polyhedron

⟨ Define class Dodecahedron 1494 ⟩ ≡ class Dodecahedron : public Polyhedron { protected: static const real dihedral angle; /∗ In radians! ∗/

real pentagon radius ; public: ⟨ Declare Dodecahedron functions 1497 ⟩ };

This code is used in sections 1534 and 1535.

1495. Define static const Dodecahedron data members.

Log

[LDF 2003.07.18.] Now passing “2.0” instead of “2.0” as the argument to atan( ). GCC 3.3 couldn’t compile this file, the way it was before.

450  DEFINE STATIC CONST DODECAHEDRON DATA MEMBERS  3DLDF-1.1.5.1 §1495

⟨ Define static const Dodecahedron data members 1495 ⟩ ≡

const real Dodecahedron ::dihedral angle = − atan(2.0);

This code is used in section 1534.

1496. Constructors and setting functions.

1497. Default constructor. (No arguments.) [LDF 2002.09.29.] TO DO: I should set the data members of other classes to , , etc., in the default constructors, too. ⟨ Declare Dodecahedron functions 1497 ⟩ ≡

Dodecahedron( );

See also sections 1500, 1503, and 1505. This code is used in section 1494.

1498. ⟨ Define Dodecahedron functions 1498 ⟩ ≡

Dodecahedron ::Dodecahedron( )

{ on free store = false; /∗ from Solid. ∗/ do output = true; faces = 12; /∗ from Solid Faced. ∗/ vertices = 20; edges = 30; center = ; /∗ from Polyhedron. ∗/ number of polygon types = 1; face radius = edge radius = vertex radius = ; pentagon radius = ; /∗ From Dodecahedron. ∗/

}

See also sections 1501, 1502, 1504, and 1506. This code is used in section 1534.

1499. Center, diameter of pentagon, and angles.

1500. Constructor. [LDF 2003.08.10.] TO DO: Check the way I specify the rotations. If its not the way I think it should be, check Transform ::align with axis ( ) and any other functions that are involved. This may be a long-term project.

Log

[LDF 2002.10.16.] Added shift to center and rotation.

[LDF 2003.08.10.] Rewrote this function. It had suddenly stopped working properly, probably because of changes I made to Transform ::align with axis ( ). I’m still not entirely happy with the way I’ve had to specify the rotations, see the “TO DO” note of this date, above.

⟨ Declare Dodecahedron functions 1497 ⟩ +≡

Dodecahedron(const Point &p, const real pentagon diameter , real angle x = 0, real angle y = 0, real angle z = 0); 1501. ⟨ Define Dodecahedron functions 1498 ⟩ +≡

Dodecahedron ::Dodecahedron(const Point &p, const real pentagon diameter , real angle x , real

angle y , real angle z ){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

on free store = false; /∗ from Solid. ∗/ do output = true; faces = 12; /∗ from Solid Faced. ∗/ vertices = 20; edges = 30; number of polygon types = 1;

#if 0 /∗ START HERE. TO DO: Must calculate these! ∗/ face radius = 0; edge radius = 0; vertex radius = 0;

#endif pentagon radius = pentagon diameter /2.0; reg polygons = get net (pentagon diameter , true); Point pts [8]; int i = 0; for (i = 0; i < 5; ^{++}i) {

pts [i] = reg polygons [0] get point (i); } real angle = 180 − (dihedral angle ∗ 180.0/ ); 1502. [LDF 2003.08.10.] Check this, as noted above. ⟨ Define Dodecahedron functions 1498 ⟩ +≡

reg polygons [1] rotate(pts [0], pts [1], angle); reg polygons [2] rotate(pts [4], pts [0], angle); reg polygons [3] rotate(pts [3], pts [4], angle); reg polygons [4] rotate(pts [3], pts [2], angle); reg polygons [5] rotate(pts [1], pts [2], angle);

#if 0 using namespace Colors; vector⟨const Color ∗⟩ col vec; col vec.push back (&black ); col vec.push back (&red ); col vec.push back (&green); col vec.push back (&blue); col vec.push back (&cyan); col vec.push back (&magenta); col vec.push back (&orange);

#endif

if ( ) { i = 0; for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) {

#if 0

(∗∗iter ).draw (∗(col vec[i])); #endif

++i; } reg polygons [0] draw ( );

} for (i = 0; i < 6; ^{++}i) { reg polygons .push back ( create new < Reg Polygon > (0) ) ; ∗reg polygons .back ( ) = ∗reg polygons [i]; reg polygons .back ( ) rotate(180); } pts [5] = reg polygons [1] get point (4); pts [6] = reg polygons [10] get point (2); if ( ) {

pts [5].dotlabel ( );

pts [6].dotlabel ( ); } pts [7] = pts [5] − pts [6]; for (i = 6; i < 12; ^{++}i) reg polygons [i] shift (pts [7]);

#if 0

if ( ) {

for (i = 6; i < 12; ^{++}i) reg polygons [i] draw (∗(col vec[i − 6])); }

#endif Point center 0 = reg polygons [0] get center ( ); Point center 6 = reg polygons [6] get center ( ); center = center 0 .mediate(center 6 ); Transform t = center .shift (−center ); if (angle x ≠ 0 ∨ angle y ≠ 0 ∨ angle z ≠ 0) t.rotate(angle x , angle y , angle z ); if (p ≠ origin) center ∗= t.shift (p); for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( ); ^{++}iter )

(∗∗iter ) ∗= t; if ( ) cout ≪ ␣ ≪ flush; return; }

1503. Get net. [LDF 2002.09.29.] Changed this function. TO DO. I’ve removed rotate( ) and now rotate the pentagons in the x-z plane only in order to avoid having the y-coordinates be off by small amounts. This might not happen with rotate( ) once I implement the routine in Salomon ( !! Get reference!) for calculating sine and cosine using integers.

const Point &center 0 is only ever used when do half ≡ false, that is, when the net isn’t just being generated for use by a constructor. If get net ( ) is called by a constructor, the net is always made with the center of pentagon 0 at the origin. Even if center 0 is used, the net is always generated in a plane parallel to the x-z plane.

Log

[LDF 2002.08.12.] Removed center 0 argument.

⟨ Declare Dodecahedron functions 1497 ⟩ +≡ static vector⟨Reg Polygon ∗⟩ get net (const real pentagon diameter , bool do half = false); 1504. ⟨ Define Dodecahedron functions 1498 ⟩ +≡

vector⟨Reg Polygon ∗⟩ Dodecahedron ::get net (const real pentagon diameter , bool do half ){ int i;

vector⟨Reg Polygon ∗⟩ pents ; for (i = 0; i < 6; ^{++}i) pents .push back ( create new <

Reg Polygon > (0) ) ; pents [0] set (origin, 5, pentagon diameter , 0, 180); /∗ The middle pentagon. ∗/ Point pts [10]; for (i = 0; i < 5; i^{++}) {

pts [i] = pents [0] get point (i); } ∗pents [1] = ∗pents [0]; pents [1] rotate(0, 36); ∗pents [5] = ∗pents [4] = ∗pents [3] = ∗pents [2] = ∗pents [1]; for (i = 5; i < 10; i^{++}) pts [i] = pents [1] get point (i − 5); pents [1] shift (pts [0] − pts [8]); pents [2] shift (pts [0] − pts [6]); pents [3] shift (pts [4] − pts [5]); pents [4] shift (pts [3] − pts [9]); pents [5] shift (pts [1] − pts [9]); if (do half ≡ true)

/∗ [LDF 2002.09.29.] We only need half of the net, if we’re using it to make a polyhedron. In that

case, we copy and transform the half we’ve already got and the copy on top of the first half. ∗/ {

for (i = 0; i < 6; ^{++}i) {

for (int j = 0; j < 5; j^{++})

if (pents [i] get point (j).get y ( ) ≠ 0) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush;

} } return pents ;

} for (i = 6; i < 12; i^{++}) { pents .push back ( create new < Reg Polygon > (0) ) ; ∗pents [i] = ∗pents [i − 6]; pents [i] rotate(0, 180); } pts [0] = pents [11] get point (0); pts [1] = pents [5] get point (1); for (i = 6; i < 12; ^{++}i) pents [i] shift (pts [1] − pts [0]); for (i = 0; i < 12; ^{++}i) {

for (int j = 0; j < 5; j^{++})

if (pents [i] get point (j).get y ( ) ≠ 0) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush;

} } return pents ; }

1505. Draw net. [LDF 2002.11.10.] This function is for drawing the net of a Dodecahedron. Normally, this will be done in order to make a cardboard model, which will require tabs for gluing the pentagons together. If no tabs are desired, passing false as the make tabs argument will suppress the tabs.

[LDF 2002.11.10.] TO DO: The arrays Point pts and Path p have too many members. In working on this function, I ended up getting rid of some of the members of these arrays after I’d already used members following them. I should go through and reassign the numbers, so that no members are skipped.

[LDF 2002.11.10.] TO DO: Add the usual arguments for drawing and filling commands. [LDF 2002.11.10.] TO DO: portrait doesn’t work right. Fix it! !! KLUDGE: portrait is set to false at the

beginning of this function and a warning is issued.

Log

[LDF 2002.11.10.] Added this function. [LDF 2002.11.10.] Tried to get output in portrait format to work, but it doesn’t yet.

⟨ Declare Dodecahedron functions 1497 ⟩ +≡ static void draw net (const real pentagon diameter , bool portrait = true, bool make tabs = true); 1506. ⟨ Define Dodecahedron functions 1498 ⟩ +≡

void Dodecahedron ::draw net (const real pentagon diameter , bool portrait , bool make tabs )

{ vector⟨Reg Polygon ∗⟩ v = get net (pentagon diameter ); for (vector⟨Reg Polygon ∗⟩::iterator iter = v.begin( ); iter ≠ v.end ( ); ^{++}iter ) {

if (portrait ) (∗∗iter ).rotate(0, 90); #if 0

(∗∗iter ).rotate(90); #endif

}

Point p[32];

int i;

for (i = 0; i < 5; i^{++}) { p[i] = v[3] get point (i);

#if 0

p[i].dotlabel (i); #endif

} /∗ START HERE. ∗/

i = 0;

for (vector⟨Reg Polygon ∗⟩::iterator iter = v.begin( ); iter ≠ v.end ( ); ^{++}iter ) { (∗∗iter ).draw ( ); (∗∗iter ).get center ( ).label (i^{++}, );

}

if (¬make tabs ) return;

return; }

1507. Icosahedron.

1508. Icosahedron class definition. ⟨ Define class Icosahedron 1508 ⟩ ≡

class Icosahedron : public Polyhedron {

protected: static const real dihedral angle; /∗ In radians! ∗/

real triangle radius ; public: ⟨ Declare Icosahedron functions 1511 ⟩ };

This code is used in sections 1534 and 1535.

1509. Define static const Icosahedron data members. ⟨ Define static const Icosahedron data members 1509 ⟩ ≡

const real Icosahedron ::dihedral angle = − asin(2.0/3.0);

This code is used in section 1534.

1510. Constructors and setting functions.

1511. Default constructor. (No arguments.) ⟨ Declare Icosahedron functions 1511 ⟩ ≡

Icosahedron( );

See also sections 1514, 1516, and 1518. This code is used in section 1508.

1512. ⟨ Define Icosahedron functions 1512 ⟩ ≡

Icosahedron ::Icosahedron( ) {

on free store = false; /∗ from Solid. ∗/ do output = true; faces = 20; /∗ from Solid Faced. ∗/ vertices = 12; edges = 30; center = ; /∗ from Polyhedron. ∗/ number of polygon types = 1; face radius = edge radius = vertex radius = ; triangle radius = ;

}

See also sections 1515, 1517, and 1519. This code is used in section 1534.

1513. Center, diameter of triangle, and angles.

1514. Constructor. [LDF 2002.12.18.] !! START HERE. Must fix this constructor. There’s a problem with rotation. I’ve already done so for the Dodecahedron constructor.

Log

[LDF 2002.10.16.] Defined this function.

⟨ Declare Icosahedron functions 1511 ⟩ +≡

Icosahedron(const Point &p, const real diameter of triangle, real angle x = 0, real angle y = 0, real angle z = 0); 1515. ⟨ Define Icosahedron functions 1512 ⟩ +≡

Icosahedron ::Icosahedron(const Point &p, const real triangle diameter , real angle x , real

angle y , real angle z ){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

on free store = false; /∗ from Solid. ∗/ do output = true; faces = 20; /∗ from Solid Faced. ∗/ vertices = 12; edges = 30; number of polygon types = 1;

#if 0 /∗ START HERE. TO DO: Must calculate these! ∗/ face radius = 0; edge radius = 0; vertex radius = 0;

#endif triangle radius = triangle diameter /2.0; int i; reg polygons .push back ( create new < Reg Polygon > (0) ) ; reg polygons .front ( ) set (origin, 3, triangle diameter ); Point pts [7]; for (i = 0; i < 3; ^{++}i) pts [i] = reg polygons .front ( ) get point (i); for (i = 1; i < 6; ^{++}i) { reg polygons .push back ( create new <

Reg Polygon > (reg polygons .front ( )) ) ; } reg polygons [1] shift (pts [2] − pts [1]); reg polygons [2] shift (pts [1] − pts [2]); reg polygons [3] shift (pts [0] − pts [2]); reg polygons [4] shift (pts [0] − pts [1]); if ( ) origin.label ( , ); reg polygons [5] rotate(0, 180); reg polygons [5] shift (pts [1] − reg polygons [5] get point (0)); for (i = 6; i < 10; ^{++}i) {

reg polygons .push back ( create new < Reg Polygon > (reg polygons [5]) ) ; } reg polygons [6] shift (pts [2] − pts [1]);

reg polygons [7] shift (pts [1] − pts [0]); reg polygons [8] shift (pts [2] − pts [0]); reg polygons [9] shift (pts [2] − pts [0]); reg polygons [9] shift (pts [2] − pts [1]); pts [3] = reg polygons [2] get point (1); pts [4] = reg polygons [2] get point (0); pts [5] = reg polygons [1] get point (2); pts [6] = reg polygons [1] get point (0); real angle = 180.0 − (dihedral angle ∗ 180.0/ ); ∗reg polygons [9] ∗= ∗reg polygons [8] ∗= reg polygons [7] rotate(pts [3], pts [5], −angle); ∗reg polygons [3] ∗= reg polygons [4] rotate(pts [4], pts [6], angle); ∗reg polygons [2] ∗= reg polygons [7] rotate(pts [1], pts [4], −angle); ∗reg polygons [7] ∗= ∗reg polygons [2] ∗= ∗reg polygons [3] ∗= reg polygons [5] rotate(pts [1], pts [0],

−angle); ∗reg polygons [1] ∗= reg polygons [9] rotate(pts [2], pts [6], angle); ∗reg polygons [9] ∗= ∗reg polygons [1] ∗= ∗reg polygons [6] ∗= reg polygons [4] rotate(pts [2],

pts [0], angle); for (i = 10; i < 20; ^{++}i) { reg polygons .push back ( create new < Reg Polygon > (reg polygons [i − 10]) ) ;

reg polygons .back ( ) rotate(180); reg polygons .back ( ) shift (0, 12); } if ( ) {

reg polygons [4] dotlabel ( );

reg polygons [19] dotlabel ( ); } real y shift = reg polygons [4] get point (0).get y ( ) − reg polygons [19] get point (0).get y ( ); for (i = 10; i < 20; ^{++}i) reg polygons [i] shift (0, y shift ); center = reg polygons [0] get center ( ).mediate(reg polygons [10] get center ( )); for (i = 0; i < 20; ^{++}i) reg polygons [i] shift (−center ); center = origin; if (angle x ≠ 0 ∨ angle y ≠ 0 ∨ angle z ≠ 0)

for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) (∗∗iter ).rotate(angle x , angle y , angle z );

if (p ≠ origin) {

for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) { (∗∗iter ).shift (p − center );

}

center = p; } if ( ) {

cout ≪ ␣ ≪ flush; } return; }

1516. Get net.

Log

[LDF 2002.11.10.] BUG FIX: Removed erroneous code that created 6 extra triangles. [LDF 2002.08.12.] Removed center 0 argument. [LDF 2003.08.27.] Added size t triangles size and added size t i to a for loop, where it’s compared to

triangles size. This occurs in debugging code.

⟨ Declare Icosahedron functions 1511 ⟩ +≡ static vector⟨Reg Polygon ∗⟩ get net (const real triangle diameter , bool do half = false); 1517. ⟨ Define Icosahedron functions 1512 ⟩ +≡

vector⟨Reg Polygon ∗⟩ Icosahedron ::get net (const real triangle diameter , bool do half ){ bool

= false; /∗ true ∗/ vector⟨Reg Polygon ∗⟩ triangles ; int i; for (i = 0; i < 10; ^{++}i) triangles .push back ( create new < Reg Polygon > (0) ) ;

/∗ The bottom left triangle. ∗/ triangles [0] set (origin, 3, triangle diameter , 0, 180); Point pts [4]; pts [0] = triangles [0] get point (0); pts [1] = triangles [0] get point (1); pts [2] = triangles [0] get point (2); ∗triangles [1] = ∗triangles [0]; triangles [1] rotate(0, 180); triangles [1] shift (pts [2] − triangles [1] get point (1)); pts [3] = triangles [1] get point (0); ∗triangles [2] = ∗triangles [0]; triangles [2] shift (pts [3] − pts [2]); ∗triangles [3] = ∗triangles [1]; triangles [3] shift (pts [3] − pts [2]); for (i = 0; i < 4; ^{++}i) {

∗triangles [4 + i] = ∗triangles [i];

triangles [4 + i] shift (pts [1] − pts [2]); } if ( )

for (i = 0; i < 4; ^{++}i) pts [i].dotlabel (i); if (do half ≡ true) {

∗triangles [8] = ∗triangles [4];

∗triangles [9] = ∗triangles [5];

∗triangles [8] ∗= triangles [9] shift (pts [1] − pts [2]); for (i = 0; i < 10; ^{++}i) {

for (int j = 0; j < 3; j^{++})

if (triangles [i] get point (j).get y ( ) ≠ 0) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush;

} } return triangles ;

} /∗ Do the second half. ∗/ if ( ) cout ≪ ␣ ␣ ␣ ; for (i = 0; i < 10; ^{++}i) triangles .push back ( create new < Reg Polygon > (0) ) ; for (int j = 8; j ≤ 16; j += 4)

for (i = 0; i < 4; ^{++}i) { ∗triangles [j + i] = ∗triangles [j − 4 + i]; triangles [j + i] shift (pts [1] − pts [2]);

} if ( ) {

size t triangles size = triangles .size( );

for (size t i = 0; i < triangles size; ^{++}i)

if (triangles [i] size( ) > 0) triangles [i] get center ( ).label (i, ); }

§1517  3DLDF-1.1.5.1  GET NET 461
for (i = 0; i < 20; ^{++}i) {

for (int j = 0; j < 3; j^{++})

if (triangles [i] get point (j).get y ( ) ≠ 0) {

cerr ≪ ␣ ␣ ≪ ␣ ␣ ≪

␣ ␣ ␣ ≪ flush;

} } return triangles ; }

1518. Draw net. TO DO: Add parallel projections onto planes other than the x-y plane.

Log

[LDF 2002.11.10.] Added this function. portrait works, unlike Dodecahedron ::draw net ( )polyhed .web (as of this date).

[LDF 2002.08.12.] Changed, so that net is drawn in x-z plane.

[LDF 2002.08.12.] This function now returns before the code for making the tabs can be executed, because it doesn’t work yet. TO DO: Write code for tabs.

⟨ Declare Icosahedron functions 1511 ⟩ +≡ static void draw net (const real triangle diameter , bool portrait = true, bool make tabs = true); 1519. ⟨ Define Icosahedron functions 1512 ⟩ +≡

void Icosahedron ::draw net (const real triangle diameter , bool portrait , bool make tabs ) {

vector⟨Reg Polygon ∗⟩ v = get net (triangle diameter ); int i = 0; for (vector⟨Reg Polygon ∗⟩::iterator iter = v.begin( ); iter ≠ v.end ( ); ^{++}iter ) {

if (portrait ) (∗∗iter ).rotate(0, 90); (∗∗iter ).get center ( ).label (i^{++}, ); (∗∗iter ).draw ( );

} return; /∗ Delete, when I start writing code for tabs. [LDF 2002.08.12.] ∗/ if (¬make tabs ) return; Path p[11]; Point pts [11];

#if 0

v[0] dotlabel ( ); #endif

pts [0] = v[0] get point (0); pts [1] = v[0] get point (1); pts [2] = v[0] get point (2); pts [3] = pts [0].mediate(pts [1], .1); pts [4] = pts [1].mediate(pts [0], .1);

#if 0 pts [3].dotlabel (2); pts [4].dotlabel (3);

#endif pts [5] = pts [0].mediate(pts [3], .1); pts [6] = pts [1].mediate(pts [4], .1); pts [7] = pts [3]; pts [7].shift (0, 0, 1); pts [8] = pts [4]; pts [8].shift (0, 0, 1); pts [5].rotate(pts [3], pts [7], 90); pts [6].rotate(pts [8], pts [4], 90);

#if 0 pts [5].dotlabel (4); pts [6].dotlabel (5);

#endif pts [9] = pts [5].mediate(pts [6], .1); pts [10] = pts [6].mediate(pts [5], .1);

#if 0 pts [9].dotlabel (8); pts [10].dotlabel (9);

#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]; p[1].shift (v[4] get point (1) − pts [1]); p[2].shift (v[8] get point (1) − pts [1]); p[3].shift (v[12] get point (1) − pts [1]); p[4].shift (v[16] get point (1) − pts [1]); p[5].shift (v[18] get point (1) − pts [1]); p[6] = p[0]; p[6].rotate(0, 0, 240); p[6].rotate(pts [0], pts [2]);

#if 0

v[3] dotlabel ( ); #endif

p[7] = p[8] = p[9] = p[10] = p[6]; p[6].shift (v[3] get point (0) − pts [2]); p[7].shift (v[7] get point (0) − pts [2]); p[8].shift (v[11] get point (0) − pts [2]); p[9].shift (v[15] get point (0) − pts [2]); p[10].shift (v[19] get point (0) − pts [2]); for (i = 0; i < 11; i^{++}) p[i].draw ( ); return;

}

1520. Semi-Regular Archimedean Polyhedra.

1521. Truncated Octahedron.

1522. Trunc Octahedron class definition. ⟨ Define class Trunc Octahedron 1522 ⟩ ≡

class Trunc Octahedron : public Polyhedron { protected: static const real angle hex square; /∗ In radians! ∗/

static const real angle hex hex ; /∗ In radians! ∗/ real hexagon radius ;

public: ⟨ Declare Trunc Octahedron functions 1525 ⟩ };

This code is used in sections 1534 and 1535.

1523. Define static const Trunc Octahedron data members. ⟨ Define static const Trunc Octahedron data members 1523 ⟩ ≡

const real Trunc Octahedron ::angle hex square = (125 + (16.0/60.0)) ∗ ( /180.0); const real Trunc Octahedron ::angle hex hex = (109 + (28.0/60.0)) ∗ ( /180.0);

This code is used in section 1534.

1524. Constructors and setting functions.

Log

[LDF 2003.04.15.] Commented-out the constructors and get net ( ). They made use of the fact, which is no longer true, that Rectangle was formerly derived from Reg Polygon. Now that Rectangle is derived from Path, some of the code in these functions doesn’t work. TO DO: Fix these functions!

1525. Default constructor. (No arguments.) ⟨ Declare Trunc Octahedron functions 1525 ⟩ ≡

Trunc Octahedron( );

See also sections 1528 and 1530. This code is used in section 1522.

1526. ⟨ Define Trunc Octahedron functions 1526 ⟩ ≡

Trunc Octahedron ::Trunc Octahedron( ) {

on free store = false; /∗ from Solid. ∗/ do output = true; faces = 14; /∗ from Solid Faced. [LDF 2002.10.29.] Truncated octahedrons consist of 6 squares

and 8 hexagons. ∗/ vertices = 24; edges = 36; center = ; /∗ from Polyhedron. ∗/ number of polygon types = 2; face radius = edge radius = vertex radius = ; hexagon radius = ;

}

See also sections 1529, 1531, and 1532. This code is used in section 1534.

1527. Center, diameter of hexagon, and angles.

1528. Constructor.

Log

[LDF 2002.11.08.] Added this function.

⟨ Declare Trunc Octahedron functions 1525 ⟩ +≡ #if 0

Trunc Octahedron(const Point &p, const real diameter of hexagon, real angle x = 0, real

angle y = 0, real angle z = 0); #endif 1529. ⟨ Define Trunc Octahedron functions 1526 ⟩ +≡ #if 0

Trunc Octahedron ::Trunc Octahedron(const Point &p, const real hexagon diameter , real

angle x , real angle y , real angle z ){ bool  = false;  /∗ true ∗/
if (  ) cout ≪  ␣  ≪ flush;

center = p; on free store = false; /∗ from Solid. ∗/ do output = true; /∗ START HERE. TO DO: Must calculate these! ∗/ face radius = 0; edge radius = 0; vertex radius = 0; faces = 14; /∗ from Solid Faced. [LDF 2002.10.29.] Truncated octahedrons consist of 6 squares

and 8 hexagons. ∗/ vertices = 24; edges = 36; number of polygon types = 2; hexagon radius = hexagon diameter /2.0; reg polygons = get net (hexagon diameter , true); Point pts [24]; int i; for (i = 0; i < 6; i^{++}) pts [i] = reg polygons [0] get point (i);

#if 0 pts [0].dotlabel (0); pts [1].dotlabel (1, ); pts [2].dotlabel (2, ); pts [3].dotlabel (3, ); pts [4].dotlabel (4, ); pts [5].dotlabel (5);

#endif real angle h h = 180.0 − (angle hex hex ∗ 180.0/ ); reg polygons [1] rotate(pts [4], pts [5], angle h h); reg polygons [2] rotate(pts [3], pts [2], −angle h h); reg polygons [3] rotate(pts [0], pts [1], angle h h); real angle h s = 180.0 − (angle hex square ∗ 180.0/ ); reg polygons [4] rotate(pts [0], pts [5], angle h s ); reg polygons [5] rotate(pts [1], pts [2], angle h s ); reg polygons [6] rotate(pts [3], pts [4], angle h s );

/∗ [LDF 2002.11.07.] Do something about these comments! ∗/ /∗ 7 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [0]) ) ; /∗ 8 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [1]) ) ; /∗ 9 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [2]) ) ; /∗ 10 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [3]) ) ; /∗ 11 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [4]) ) ; /∗ 12 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [5]) ) ; /∗ 13 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [6]) ) ; Transform t; t.rotate(180); t.shift (0, 15); for (i = 7; i < 14; i^{++}) ∗reg polygons [i] ∗= t; t.reset ( ); t.shift (reg polygons [2] get point (2) − reg polygons [11] get point (3)); for (i = 7; i < 14; i^{++}) ∗reg polygons [i] ∗= t; i = 0; for (vector⟨Reg Polygon ∗⟩::iterator iter = reg polygons .begin( ); iter ≠ reg polygons .end ( );

++iter ) { if (center ≠ origin) (∗∗iter ).shift (center );

} if ( ) {

cout ≪ ␣ ≪ endl ≪ endl ≪ flush; } return; }

#endif

1530. Get net.

Log

[LDF 2002.11.08.] Added this function. [LDF 2002.08.12.] Removed center 0 argument.

⟨ Declare Trunc Octahedron functions 1525 ⟩ +≡ #if 0

static vector⟨Reg Polygon ∗⟩ get net (const real hexagon diameter , bool do half = false); #endif 1531. ⟨ Define Trunc Octahedron functions 1526 ⟩ +≡ #if 0

vector⟨Reg Polygon ∗⟩ Trunc Octahedron ::get net (const real hexagon diameter , bool do half ){

bool = false; /∗ true ∗/ vector⟨Reg Polygon ∗⟩ reg polygons ; int i; reg polygons .push back ( create new < Reg Polygon > (0) ) ; reg polygons [0] set (origin, 6, hexagon diameter ); Point pts [24]; for (i = 0; i < 6; i^{++}) pts [i] = reg polygons [0] get point (i); reg polygons .push back ( create new < Reg Polygon > (reg polygons [0]) ) ; reg polygons [1] shift (pts [4] − pts [2]); reg polygons .push back ( create new <

Reg Polygon > (reg polygons [0]) ) ; reg polygons [2] shift (pts [3] − pts [5]); reg polygons .push back ( create new <

Reg Polygon > (reg polygons [0]) ) ; reg polygons [3] shift (pts [1] − pts [3]); real side length = pts [5].get x ( ) − pts [0].get x ( ); pts [6] = pts [0]; pts [6].shift (0, 0, side length); pts [7] = pts [5]; pts [7].shift (0, 0, side length); Rectangle r(pts [0], pts [5], pts [7], pts [6]); reg polygons .push back ( create new < Reg Polygon > (r)

) ; pts [8] = pts [2]; pts [9] = pts [1]; pts [9].shift (0, 1); pts [8].rotate(pts [9], pts [1], −90); pts [10] = pts [8]; pts [10].shift (pts [2] − pts [1]); r.set (pts [10], pts [2], pts [1], pts [8]); reg polygons .push back ( create new < Reg Polygon > (r) ) ; pts [11] = pts [3]; pts [12] = pts [4]; pts [12].shift (0, 1); pts [11].rotate(pts [4], pts [12], 90); pts [13] = pts [11]; pts [13].shift (pts [3] − pts [4]); r.set (pts [11], pts [4], pts [3], pts [13]); reg polygons .push back ( create new < Reg Polygon > (r) ) ; if (do half ) return reg polygons ;

#endif 1532. [LDF 2002.11.08.] If we just want the net, reg polygons [5] and reg polygons [6] must be changed, because I’ve made the net a bit differently from the way it’s done in Cundy. Get reference!! Page 104. I made two of the squares slanted, in order to avoid having to rotate them twice. ⟨ Define Trunc Octahedron functions 1526 ⟩ +≡ #if 0

∗reg polygons [6] = ∗reg polygons [5] = ∗reg polygons [4]; pts [14] = reg polygons [4] get point (2); pts [15] = reg polygons [4] get point (3); reg polygons [5] shift (pts [1] − pts [14]); reg polygons [6] shift (pts [4] − pts [15]); reg polygons .push back ( create new <

Reg Polygon > (reg polygons [0]) ) ; /∗ 7 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [4]) ) ; /∗ 8 ∗/ ∗reg polygons [7] ∗= reg polygons [8] shift (pts [1] + pts [2] − pts [3] − pts [4]); reg polygons .push back (

create new < Reg Polygon > (reg polygons [0]) ) ; /∗ 9 ∗/ reg polygons [9] shift (pts [4] + pts [0] − (2 ∗ pts [2])); reg polygons .push back ( create new <

Reg Polygon > (reg polygons [4]) ) ; /∗ 10 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [0]) ) ; /∗ 11 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [1]) ) ; /∗ 12 ∗/ reg polygons .push back ( create new < Reg Polygon > (reg polygons [6]) ) ; /∗ 13 ∗/ ∗reg polygons [10] ∗= ∗reg polygons [11] ∗= ∗reg polygons [12] ∗=

reg polygons [13] shift (pts [4] + pts [3] − pts [2] − pts [1]); return reg polygons ; }

#endif

1533. Putting polyhedra together.

1534. This is what’s compiled.

⟨ Include files 6 ⟩ ⟨ Version control identifier 5 ⟩ ⟨ Define class Polyhedron 1472 ⟩ ⟨ Define class Tetrahedron 1477 ⟩ ⟨ Define static const Tetrahedron data members 1478 ⟩ ⟨ Define class Dodecahedron 1494 ⟩ ⟨ Define static const Dodecahedron data members 1495 ⟩ ⟨ Define class Icosahedron 1508 ⟩ ⟨ Define static const Icosahedron data members 1509 ⟩ ⟨ Define class Trunc Octahedron 1522 ⟩ ⟨ Define static const Trunc Octahedron data members 1523 ⟩ ⟨ Define Polyhedron functions 1474 ⟩ ⟨ Define Tetrahedron functions 1481 ⟩ ⟨ Define Dodecahedron functions 1498 ⟩ ⟨ Define Icosahedron functions 1512 ⟩ ⟨ Define Trunc Octahedron functions 1526 ⟩

§1535  3DLDF-1.1.5.1  PUTTING POLYHEDRA TOGETHER 469

1535. This is what’s written to polyhed.h.

⟨ 1535 ⟩ ≡

⟨ Define class Polyhedron 1472 ⟩

⟨ Define class Tetrahedron 1477 ⟩

⟨ Define class Dodecahedron 1494 ⟩

⟨ Define class Icosahedron 1508 ⟩

⟨ Define class Trunc Octahedron 1522 ⟩

1536. Parsing (parser.web).

Log

Removed the code from this file. I plan to use Bison for making the parser. [LDF 2003.08.25.] [LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of

3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.10.] Put the version control identifiers back into my release versions for 3DLDF 1.1.4. I’ve already put some of them back in, now I’m doing the rest of them. However, the release versions are now in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1537. Include files. map.h is currently not needed, but I plan to use it for the input routine. [LDF 2004.01.06.] ⟨ Include files 6 ⟩ +≡ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

1538. Parse. ⟨ Declare parser functions 1538 ⟩ ≡

This code is used in section 1542.

470  PARSE  3DLDF-1.1.5.1 §1539

1539. ⟨ Define parser functions 1539 ⟩ ≡

This code is used in section 1541.

1540. Putting the parser together.

1541. This is what’s compiled.

⟨ Include files 6 ⟩

⟨ Version control identifier 5 ⟩ ⟨ Define parser functions 1539 ⟩

§1542  3DLDF-1.1.5.1  PUTTING THE PARSER TOGETHER 471

1542. This is what’s written to parser.h.

⟨ 1542 ⟩ ≡

⟨ Declare parser functions 1538 ⟩

1543. Main (main.web).

Log

[LDF 2002.11.18.] Changed name of this file from persp.web to main.web. It now has fewer than 8 letters and can be used under DOS.

[LDF 2003.08.29.] Moved getopt.h from loader.web to here, because it’s only used here. TO DO: Move the rest of the include commands to the files where they’re needed, and get rid of loader.web.

[LDF 2003.11.12.] Removed the version control identifiers from the CWEB files for the distribution of 3DLDF 1.1. They’re still used in my development versions.

[LDF 2003.12.01.] Put the version control identifiers back into the release versions, because I’ve put them in their own RCS repository.

⟨ Version control identifier 5 ⟩ +≡ static string rcs id = ␣ ␣ ␣ ␣ ␣ ␣ ␣ ;

1544. Include files. getopt.h is included for processing the command line options. [LDF 2003.08.14.] ⟨ Include files 6 ⟩ +≡ #include #include #ifdef #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include

472  GET INPUT  3DLDF-1.1.5.1 §1545

1545. Get input. I plan to use Flex and Bison to handle scanning and parsing input. I haven’t started work on this yet. [LDF 2003.08.20.] ⟨ Get input 1545 ⟩ ≡

1546. Actions in main. ⟨ Actions in main 1546 ⟩ ≡

using namespace Colors; using namespace Projections; if (ldf real float ) = System ::get second largest <

float > ( , false); else if (ldf real double) = System ::get second largest < double > ( , false);

= sqrt ( ); vector⟨const Color ∗⟩ v; v.push back (&red ); v.push back (&green); v.push back (&blue); v.push back (&cyan); v.push back (&yellow );

#if 0 v.push back (&magenta); v.push back (&orange); v.push back (&violet ); v.push back (&yellow green); v.push back (&green yellow ); v.push back (&blue violet ); v.push back (&red ); v.push back (&green); v.push back (&blue); v.push back (&cyan); v.push back (&yellow ); v.push back (&magenta); v.push back (&orange); v.push back (&violet ); v.push back (&yellow green); v.push back (&green yellow ); v.push back (&blue violet ); v.push back (&violet red );

#endif

See also section 1547. This code is used in section 1557.

§1547  3DLDF-1.1.5.1  ACTIONS IN MAIN 473

1547. Your code here! ⟨ Actions in main 1546 ⟩ +≡

beginfig (1);

Point p;

Point q(1, 1, 1);

Circle c(p, 2, 90);

c.filldraw ( );

p.draw (q);

current picture.output ( );

endfig ( );

1548. Process command line options. This section includes one of (currently) two other sections, one for the GCC/Linux version and one for the DEC version. The section to be included is chosen by testing whether preprocessor macros are defined or not. Put another way, the command line option processing code is conditionally compiled. [LDF 2003.08.14.]

The problem is that, unlike GCC, the DEC C^{++} compiler doesn’t support long command line options, So I have to implement the command line option processing code separately for each version. [LDF 2003.08.14.]

Log

[LDF 2003.08.14.] Added this section.

⟨ Process command line options 1548 ⟩ ≡ #ifdef

⟨ GCC command line option processing 1549 ⟩ #else #ifdef

⟨ DEC command line option processing 1551 ⟩ #endif #endif

This code is used in section 1555.

474  PROCESS COMMAND LINE OPTIONS  3DLDF-1.1.5.1 §1549

1549. GCC version of command line processing.

Log

[LDF 2003.08.14.] Added this section. [LDF 2003.08.14.] Added code for handling the “--silent” option, including the constant .

⟨ GCC command line option processing 1549 ⟩ ≡

{ bool = false; /∗ true ∗/ int option ctr ; int digit optind = 0; const unsigned short = 0; const unsigned short = 1; const unsigned short = 2; const unsigned short = 3; static struct option long options [ ] = {{ , 0, 0, 0}, { , 0, 0, 0}, { , 0, 0, 0},

{ , 0, 0, 0}, {0, 0, 0, 0}}; int option index = 0; int this option optind = optind ? optind : 1; while (1) {

option ctr = getopt long only (argc, argv , , long options , &option index ); if ( ) {

cout ≪ ␣ ␣ ≪ option ctr ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ option index ≪ endl ≪ flush; cout ≪ ␣ ␣ ≪ optarg ≪ endl ≪ flush;

}

if (option ctr ≡ −1) { if ( ) cout ≪ ␣ ␣ ≪ endl ≪ endl ≪ flush; break;

}

if (option ctr ≡ 0) {

if ( ) { cout ≪ ␣ ≪ long options [option index ].name; if (optarg ) cout ≪ ␣ ␣ ␣ ≪ optarg ; cout ≪ endl ;

}

if (option index ≡ ) {

cout ≪  ␣       ␣ ≪  ≪ ␣ ≪  ≪
endl ≪  ␣       ␣   ␣      ␣  ≪ endl ≪

          ␣␣␣␣␣␣      ␣    ␣       ␣   ␣      ␣ ≪  ␣      ␣     ␣  ≪

endl ≪ endl ≪  ␣␣␣␣          ␣    ␣      ␣  ␣        ␣  ≪

          endl ≪ ␣␣␣␣␣␣␣␣␣␣␣␣␣   ␣        ␣     ␣    ␣      ␣  ␣  ≪ endl ≪
          endl ≪  ␣␣␣       ␣      ␣          ␣   ␣  ␣       ␣ ≪
          ␣        ␣  ≪ endl ≪ ␣␣␣␣␣␣␣␣␣␣␣␣␣    ␣     ␣  ␣  ≪

endl ≪ endl ≪  ␣␣␣       ␣   ␣       ␣      ␣   ␣  ≪ endl ≪

          ␣␣␣␣␣␣␣␣␣␣␣␣␣  ␣        ␣      ␣   ␣ ≪  ␣    ␣      ␣      ␣  ≪

endl ≪ endl ≪ flush; if ( ) cout ≪ ␣ ␣ ␣ ␣ ≪ endl ≪ flush; exit (0);

}

else if (option index ≡ ) {

if (  ) cout ≪  ␣             ␣  ␣  ≪ endl ;

§1549  3DLDF-1.1.5.1  PROCESS COMMAND LINE OPTIONS 475

= true; } else if (option index ≡ ) {

if ( ) cout ≪ ␣ ␣ ␣ ≪ endl ;

= true; } else if (option index ≡ ) {

cout ≪  ␣       ␣ ≪  ≪ ␣ ≪  ≪ endl ≪ flush;
if (  ) cout ≪  ␣    ␣       ␣     ␣  ≪ endl ≪ flush;

exit (0); } else {

cerr ≪  ␣     ␣       ␣ ≪  ␣   ␣        ␣      ␣ ≪ option index ≪
endl ≪  ␣   ␣  ␣  ≪ endl ≪ endl ≪ flush;

} } else if (option ctr ≡ ) {

cerr ≪ ␣ ␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; break;

} else {

cerr ≪ ␣ ␣ ␣ ≪ endl ≪ flush; } if ( ) cout ≪ ;

} /∗ while ∗/ if (optind < argc) {

cout ≪ ␣ ␣ ; while (optind < argc) cout ≪ argv [optind^{++}] ≪ endl ; cout ≪ endl ≪ flush;

} if ( ) {

cout ≪ ␣ ␣ ␣ ␣ ␣ ≪ endl ≪ endl ≪ flush; exit (0);

} } /∗ End of group. ∗/

This code is used in section 1548.

1550. DEC version.

1551. This section doesn’t contain any code yet.

Log

[LDF 2003.08.14.] Added this section.

⟨ DEC command line option processing 1551 ⟩ ≡ /∗ Do nothing. ∗/

This code is used in section 1548.

1552. Print version, copyright, and license information. The version, copyright, and license information is printed to standard output when 3DLDF is run, unless the “--silent” option was used. The code for this differs for the GCC 2.95/Linux version on the one hand, and the other versions (currently, GCC 3.3/Linux and DEC) on the other. The reason for this is, that GCC 2.95 doesn’t handle stream formatting in the same way as the others. I assume that the others adhere to the standard and that GCC 2.95 doesn’t, but I haven’t checked this. At any rate, the non-GCC 2.95 version corresponds to what Stroustrup describes in The C^{++} Programming Language.

Log

[LDF 2003.08.14.] Added this section.

⟨ Print version, copyright, and license information 1552 ⟩ ≡

if (¬ ) { #ifdef

⟨ GCC 2.95 print version, copyright, and license information 1553 ⟩ #else

⟨ GCC 3.3 and DEC print version, copyright, and license information 1554 ⟩ #endif

}

This code is used in section 1556.

1553. GCC 2.95 version.

Log

[LDF 2003.08.14.] Added this section.

⟨ GCC 2.95 print version, copyright, and license information 1553 ⟩ ≡ cout .setf (ios ::fixed , ios ::floatfield ); cout .precision(1); cout ≪ ␣ ␣ ≪ ≪ ≪ endl ≪ ≪ endl ≪

≪ endl ≪ endl ≪ flush; cout .setf (ios ::fmtflags (0), ios ::floatfield ); /∗ Reset to defaults. [LDF 2003.08.14.] ∗/ cout .precision(6);

This code is used in section 1552.

§1554  3DLDF-1.1.5.1  PRINT VERSION, COPYRIGHT, AND LICENSE INFORMATION 477

1554. GCC 3.3 and DEC version.

Log

[LDF 2003.08.14.] Added this section.

⟨ GCC 3.3 and DEC print version, copyright, and license information 1554 ⟩ ≡ cout .precision(1); cout ≪ ␣ ␣ ≪ ≪ ≪ endl ≪ ≪ endl ≪

≪ endl ≪ endl ≪ flush; cout .precision(6);

This code is used in section 1552.

1555. Main itself. ⟨ Main 1555 ⟩ ≡

int main(int argc, char ∗argv [ ]){ ⟨ Process command line options 1548 ⟩;

See also sections 1556 and 1557. This code is used in section 1558.

1556.

Log

[LDF 2003.08.29.] Changed the string that’s passed to initialize io( ) as the name of the input file. It’s a dummy name, since I’ve changed initialize io( ) today, so that no in stream isn’t opened. Also, commentedout the line where in stream is closed.

[LDF 2003.11.28.] Removed TEX text above, that referred to the precision used when printing out . This is no longer relevant, because is now a string rather than a real.

⟨ Main 1555 ⟩ +≡ ⟨ Print version, copyright, and license information 1552 ⟩;

478  MAIN ITSELF  3DLDF-1.1.5.1 §1557

1557. ⟨ Main 1555 ⟩ +≡

initialize io( , , , argv [0]); Color ::initialize colors ( ); ⟨ Actions in main 1546 ⟩; write footers ( );

#if 0

in stream.close( ); #endif

out stream.close( );

tex stream.close( );

if (¬ ) {

cout ≪ ␣ ␣ ␣ ≪ ≪ ≪ flush; } return (0); }

1558. Putting Main together. This is what’s compiled.

⟨ Include files 6 ⟩

⟨ Version control identifier 5 ⟩

⟨ Main 1555 ⟩

1559. Appendices.

1560. References.

Cundy, H. Martyn and A.P. Rollet. Mathematical Models. Oxford 1961. Oxford University Press. Unfortunately out of print.

Finston, Laurence D. 3DLDF User and Reference Manual. Göttingen 2003.

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

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. A User’s Manual for MetaPost. ATT 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.

§1560  3DLDF-1.1.5.1  REFERENCES 479

Knuth, Donald E. and Silvio Levy. The CWEB System of Structured Documentation.

Version 3.64—February 2002.

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

Stoer, Josef. Numerische Mathematik 1. Achte, neu bearbeitete und erweiterte Auflage. Springer-Verlag. Berlin 1999. ISBN 3-540-66154-9.

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.

1561. GNU Free Documentation License. The GNU Free Documentation License, which follows, applies to this document.

GNU Free Documentation License Version 1.2, November 2002

Copyright \begin{matrix}c \\ ◯ \end{matrix} 2000,2001,2002 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

0. 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.

1. 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 worldwide, 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.

480  GNU FREE DOCUMENTATION LICENSE  3DLDF-1.1.5.1 §1561

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.

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.

2. VERBATIM COPYING

§1561  3DLDF-1.1.5.1  GNU FREE DOCUMENTATION LICENSE 481

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.

3. 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.

4. 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:

A. 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. B. 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. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. 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. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice. H. Include an unaltered copy of this License. I. 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. J. 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. K. 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. L. 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. M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section. O. 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.

5. 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”.

6. 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.

7. 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.

8. 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.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

10. 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.

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 \begin{matrix}c \\ ◯ \end{matrix} 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.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”.

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. ⟨ GNU Free Documentation License 1561 ⟩ ≡ /∗ This section contains no C^{++} code. ∗/

This code is cited in section 1.

1562. GNU General Public License. The GNU General Public License, which follows, applies to the program 3DLDF described in this document.

GNU GENERAL PUBLIC LICENSE Version 2, June 1991

Copyright \begin{matrix}c \\ ◯ \end{matrix} 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software–to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation’s software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

§1562  3DLDF-1.1.5.1  GNU GENERAL PUBLIC LICENSE 485

Also, for each author’s protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors’ reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone’s free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The “Program”, below, refers to any such program or work, and a “work based on the Program” means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term “modification”.) Each licensee is addressed as “you”.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

1. You may copy and distribute verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.

b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.

c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)

486  GNU GENERAL PUBLIC LICENSE  3DLDF-1.1.5.1 §1562

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.

In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:

a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.

4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.

6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients’ exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.

7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License.

If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

9. The Free Software Foundation may publish revised and/or new versions of the General Public 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.

Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and “any later version”, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.

10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTH-ERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IM-PLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABIL-ITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFEC-TIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR RE-DISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PRO-GRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

⟨one line to give the program’s name and a brief idea of what it does.⟩ Copyright (C) ⟨year⟩ ⟨name of author⟩

This program 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 2 of the License, or (at your option) any later version.

This program 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

Gnomovision version 69, Copyright \begin{matrix}c \\ ◯ \end{matrix} year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’. This is free software, and you are welcome to redistribute it under certain conditions; type ‘show c’ for details.

The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than ‘show w’ and ‘show c’; they could even be mouse-clicks or menu items–whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a “copyright disclaimer” for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in the program ‘Gnomovision’ (which makes passes at compilers) written by James Hacker.

⟨signature of Ty Coon⟩, 1 April 1989 Ty Coon, President of Vice

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ⟨ GNU General Public License 1562 ⟩ ≡ /∗ This section contains no C^{++} code. ∗/

This code is cited in section 1.

§1563  3DLDF-1.1.5.1  INDEX 489

1563. Index. [LDF 2002.10.09.] The way CWEAVE handles indexing is not ideal for C^{++}. It doesn’t index identifiers that include non-alphanumeric characters, so that neither Path ::draw ( ) nor operator≪( ) are indexed automatically. Nor is there any indication of whether an identifier refers to a variable or a function.

I have added indexing commands in the source files for operators and class member functions. However, the alphabetization routine is naïve and doesn’t ignore the characters of the TEX macros that I use for formatting the index entries, so the order of the entries is a bit peculiar. For example, \cfunc{z} would come before \ofunc{a} (\cfunc is for class functions, and \ofunc is for operators that aren’t members of a class).

First come the index entries which start with “??” and “!!”. These are followed by the non-operator class member functions for all of the classes. Then come the class member operators for all of the classes, followed by the non-class operators. Currently, I’m only putting index entries in by hand where the class member functions and operators are declared.

[LDF 2002.10.11.] Another problem is that “operator& ” and “operator&=” use the italic ampersand. It would be possible to fix this, but slightly tricky. TO DO: Fix this!

BUG FIX: 18, 195, 218, 448, 593, 700, 702,

871, 1388, 1516. !!: 95, 99, 155, 156, 158, 166, 174, 193, 207, 208,

226, 354, 448, 480, 502, 546, 547, 559, 572, 727, 834, 843, 906, 918, 940, 970, 1120, 1158, 1273, 1320, 1369, 1438, 1464, 1473, 1487, 1503, 1532.

!! BUG: 423, 581, 721. !! KLUDGE: 19, 310, 317, 445, 475, 1505. !! LOOK UP: 441. !! NOTE: 1317. !! TO DO: 6, 24, 31, 49, 182, 184, 226, 267, 309,

350, 398, 423, 439, 441, 444, 445, 453, 475, 505, 507, 509, 591, 600, 601, 635, 647, 648, 687, 698, 728, 751, 763, 766, 785, 961, 967, 992, 994, 996, 1011, 1039, 1068, 1101, 1122, 1129, 1171, 1201, 1203, 1212, 1265, 1269, 1270, 1299, 1320, 1323, 1331, 1368, 1419, 1438, 1470, 1472, 1487, 1491, 1497, 1500, 1503, 1505, 1518, 1524, 1543, 1563.

!! URGENT: 700. ??: 158, 244, 353, 354, 530, 538, 590, 688, 700,

711, 721, 728, 835, 882, 1080, 1081. Circle::Circle: 1278, 1281. Circle::create new circle: 1286. Circle::get diameter : 1298. Circle::get radius : 1297. Circle::intersection points : 1300, 1302, 1304. Circle::is circular : 1295. Circle::set : 1283. Color::Color : 97, 99, 102, 107. Color::define color mp: 149. Color::get blue part : 143. Color::get green part : 142. Color::get name: 146. Color::get red part : 141. Color::get use name: 144. Color::initialize colors : 151. Color::is on free store: 138.

Color::modify : 127. Color::set blue part : 133. Color::set green part : 131. Color::set name: 123. Color::set on free store: 121. Color::set red part : 129. Color::set use name: 125. Color::set : 104, 109. Color::show : 135. Cuboid::˜ Cuboid : 1464. Cuboid::Cuboid : 1455, 1457, 1459. Dodecahedron::Dodecahedron: 1497, 1500. Dodecahedron::draw net : 1505. Dodecahedron::get net : 1503. Ellipse::˜ Ellipse: 1156. Ellipse::angle point : 1201. Ellipse::dotlabel : 1162. Ellipse::draw out rectangle: 1261. Ellipse::Ellipse: 1146, 1149. Ellipse::get axis h: 1197, 1199. Ellipse::get axis v : 1192, 1194. Ellipse::get center : 1177, 1179. Ellipse::get coefficients : 1174. Ellipse::get focus : 1182, 1184. Ellipse::in rectangle: 1259. Ellipse::intersection points : 1208, 1210, 1212. Ellipse::is cubic: 1167. Ellipse::is elliptical : 1164. Ellipse::is quadratic: 1166. Ellipse::is quartic: 1169. Ellipse::label : 1160. Ellipse::location: 1205. Ellipse::out rectangle: 1257. Ellipse::rotate: 1235, 1252, 1254. Ellipse::scale: 1237. Ellipse::set : 1151. Ellipse::shear : 1239.

490  INDEX  3DLDF-1.1.5.1 §1563

Ellipse::shift times : 1247, 1249. Ellipse::shift : 1242, 1244. Ellipse::solve: 1171. Focus::Focus : 602, 604, 609. Focus::get direction: 621. Focus::get distance: 622. Focus::get persp element : 628. Focus::get persp: 627. Focus::get position: 620. Focus::get transform element : 625. Focus::get transform: 624. Focus::get up: 623. Focus::reset angle: 615. Focus::set : 606, 611. Focus::show : 617. Icosahedron::draw net : 1518. Icosahedron::get net : 1516. Icosahedron::Icosahedron: 1511, 1514. Label::get copy : 515. Label::output : 516. Line::get distance: 648. Line::get path: 646, 978. Line::Line: 639, 641. Line::show : 652. Path::˜ Path: 726. Path::align with axis : 790, 792, 794. Path::append : 812. Path::apply transform: 783. Path::clear : 728. Path::dotlabel : 877, 879. Path::draw help: 836, 838. Path::draw : 818, 820. Path::drawarrow : 827, 829. Path::extract : 882. Path::fill : 844, 846. Path::filldraw : 849, 851. Path::get copy : 730. Path::get extremes : 888. Path::get last point : 936. Path::get line switch: 920. Path::get line: 976. Path::get maximum z : 891. Path::get mean z : 893. Path::get minimum z : 889. Path::get normal : 940. Path::get plane: 946. Path::get point : 932, 934. Path::get size: 938. Path::intersection point : 964. Path::is cycle: 921. Path::is linear : 918. Path::is on free store: 914.

Path::is planar : 916. Path::label : 872, 874. Path::output : 899. Path::Path: 704, 707, 712, 717, 721. Path::project : 785. Path::reverse: 955, 959. Path::rotate: 756, 762, 764. Path::scale: 766. Path::set connectors : 751. Path::set cycle: 952. Path::set dash pattern: 747. Path::set draw color : 738, 740. Path::set extremes : 884. Path::set fill color : 743, 745. Path::set fill draw value: 735. Path::set on free store: 732. Path::set pen: 749. Path::set : 709, 714, 719. Path::shear : 768. Path::shift times : 776, 778. Path::shift : 771, 773. Path::show colors : 911. Path::show : 909. Path::size: 922. Path::slope: 923. Path::subpath: 925. Path::suppress output : 895. Path::undraw : 855, 857. Path::unfill : 863. Path::unfilldraw : 866, 868. Path::unsuppress output : 897. Picture::clear : 300, 590. Picture::kill labels : 276. Picture::output : 298, 299, 592, 598. Picture::Picture: 263, 265. Picture::reset transform: 301. Picture::rotate: 286, 288, 440. Picture::scale: 280. Picture::set transform: 289. Picture::shift : 283, 417. Picture::show transform: 295. Picture::show : 293. Picture::suppress labels : 274. Picture::unsuppress labels : 275. Plane::get distance: 677, 679. Plane::intersection line: 687. Plane::intersection point : 966. Plane::Plane: 663, 665, 667. Plane::show : 689. Point::˜ Point : 338. Point::angle: 548. Point::apply transform: 448.

Point::clean: 346. Point::cross product : 544. Point::dot product : 542. Point::dotlabel : 510, 512. Point::draw help: 472, 473, 841, 842. Point::draw : 463, 464, 823, 824. Point::drawarrow : 466, 467, 832, 833. Point::drawdot : 454, 456. Point::epsilon: 350. Point::extract : 486. Point::get all coords : 355, 357. Point::get coord : 360, 362. Point::get extremes : 488. Point::get line: 352, 645. Point::get maximum z : 491. Point::get mean z : 493. Point::get minimum z : 489. Point::get normal : 557, 945. Point::get transform: 384. Point::get w : 380, 382. Point::get x : 365, 367. Point::get y : 370, 372. Point::get z : 375, 377. Point::intersection point : 572, 573, 647. Point::is identity : 349. Point::is in triangle: 401. Point::is on line: 398. Point::is on plane: 400. Point::is on segment : 393, 396. Point::label : 505, 507. Point::magnitude: 546. Point::mediate: 555. Point::output : 501. Point::Point : 324, 327, 331. Point::project : 442, 446. Point::reset transform: 450. Point::rotate: 404, 436, 438, 760. Point::scale: 406. Point::set extremes : 495. Point::set on free store: 342. Point::set : 329, 333. Point::shear : 408. Point::shift times : 419, 421. Point::shift : 285, 412, 414. Point::show transform: 477. Point::show : 475. Point::slope: 389. Point::suppress output : 482. Point::undraw : 469, 470, 860, 861. Point::undrawdot : 458, 460. Point::unit vector : 551, 553. Point::unsuppress output : 484.

Polygon::get center : 1022, 1024.

Polygon::intersection points : 1028, 1037, 1039. Polygon::rotate: 1047, 1050, 1052. Polygon::scale: 1054. Polygon::shear : 1056. Polygon::shift times : 1064, 1066. Polygon::shift : 1059, 1061. Polyhedron::intersection points : 1473. Rectangle::˜ Rectangle: 1118. Rectangle::corner : 1125. Rectangle::is rectangular : 1122. Rectangle::mid point : 1127. Rectangle::Rectangle: 1103, 1106, 1111. Rectangle::set : 1108, 1113. Reg Cl Plane Curve::angle point : 994. Reg Cl Plane Curve::get coefficients : 990. Reg Cl Plane Curve::half : 1013. Reg Cl Plane Curve::intersection points : 997,

1008. Reg Cl Plane Curve::is cubic: 988. Reg Cl Plane Curve::is quadratic: 987. Reg Cl Plane Curve::is quartic: 989. Reg Cl Plane Curve::location: 992. Reg Cl Plane Curve::quarter : 1014. Reg Cl Plane Curve::segment : 1011. Reg Cl Plane Curve::solve: 991. Reg Polygon::draw in circle: 1091, 1092, 1309,

1310. Reg Polygon::draw out circle: 1095, 1096, 1312,

1313, 1314. Reg Polygon::get radius : 1087. Reg Polygon::in circle: 1089, 1307. Reg Polygon::out circle: 1093, 1311. Reg Polygon::Reg Polygon: 1073, 1076. Reg Polygon::set : 1079. Solid::˜ Solid : 1343. Solid::apply transform: 1388. Solid::clear : 1383. Solid::draw : 1423. Solid::extract : 1404. Solid::fill : 1426. Solid::filldraw : 1429. Solid::get center : 1353. Solid::get circle center : 1371. Solid::get circle ptr : 1358. Solid::get copy : 1348. Solid::get ellipse center : 1373. Solid::get ellipse ptr : 1360. Solid::get extremes : 1408. Solid::get maximum z : 1411. Solid::get mean z : 1413. Solid::get minimum z : 1409.

Solid::get path ptr : 1362. Solid::get rectangle center : 1375. Solid::get rectangle ptr : 1364. Solid::get reg polygon center : 1377. Solid::get reg polygon ptr : 1366. Solid::get shape center : 1369. Solid::get shape ptr : 1356. Solid::is on free store: 1379. Solid::output : 1419. Solid::rotate: 1399, 1401. Solid::scale: 1390. Solid::set extremes : 1406. Solid::set on free store: 1350. Solid::shear : 1392. Solid::shift : 1395, 1397. Solid::show : 1381. Solid::Solid : 1336, 1338. Solid::suppress output : 1415. Solid::undraw : 1432. Solid::unfill : 1435. Solid::unfilldraw : 1438. Solid::unsuppress output : 1417. Tetrahedron::draw net : 1491. Tetrahedron::get net : 1489. Tetrahedron::set : 1487. Tetrahedron::Tetrahedron: 1480, 1483. Transform::align with axis : 213, 423. Transform::clean: 180. Transform::epsilon: 182. Transform::get element : 190. Transform::inverse: 226, 232. Transform::is identity : 185, 187. Transform::reset : 176. Transform::rotate: 205, 211, 212, 439, 759. Transform::scale: 195. Transform::set element : 178. Transform::shear : 197. Transform::shift : 200, 202, 203, 416. Transform::show : 192. Transform::Transform: 168, 170, 172. Trunc Octahedron::get net : 1530. Trunc Octahedron::Trunc Octahedron: 1525,

1528. Circle::operator=: 1290, 1292. Color::operator!=: 118. Color::operator==: 116. Color::operator=: 114. Cuboid::operator=: 1466. Ellipse::operator*=: 1233. Ellipse::operator=: 1157. Ellipse::operatordo transform: 1231. Line::operator=: 643.

Path::operator*=: 781.

Path::operator+=: 797, 801.

Path::operator+: 799. Path::operator==: 961. Path::operator=: 700. Path::operator&=: 805. Path::operator& : 810. Picture::operator*=: 291. Picture::operator+=: 269, 270, 272, 589. Picture::operator=: 267. Point::operator!=: 569. Point::operator*=: 518, 529. Point::operator* : 532. Point::operator+=: 523. Point::operator+: 521. Point::operator-=: 527. Point::operator-: 525, 536. Point::operator/=: 538. Point::operator/ : 540. Point::operator==: 559, 560, 567. Point::operator=: 340. Polygon::operator*=: 1045. Rectangle::operator=: 1119. Reg Polygon::operator=: 1070. Solid::operator*=: 1386. Solid::operator=: 1345. Transform::operator*=: 216, 218. Transform::operator* : 221, 223. Transform::operator=: 174. operator≪: 147, 480. operator* : 534. : 52. : 6, 7, 11, 14, 19, 26, 52, 83, 323,

443, 1548. : 7, 24, 83, 323, 443, 1544, 1548. : \underline{7}. : \underline{7}. ptr : 1352. A: \underline{1352}. a: \underline{16}, \underline{31}, \underline{32}, \underline{224}, \underline{315}, \underline{390}, \underline{397}, \underline{433}, \underline{437}, \underline{439}, \underline{522}, \underline{526}, \underline{533}, \underline{537}, \underline{541}, \underline{543}, \underline{545}, \underline{547}, \underline{554}, \underline{560}, \underline{923}, \underline{924}, \underline{930}, \underline{932}, \underline{933}, \underline{934}, \underline{935}, \underline{1123},

\underline{1165}, \underline{1222}, \underline{1305}.

a m coord : \underline{390}, 391. a n coord : \underline{390}, 391. a x : \underline{650}. a y : \underline{650}. a z : \underline{650}. aa: \underline{1222}. aarrow : \underline{463}, \underline{464}, \underline{818}, \underline{819}, \underline{820}, \underline{821}, \underline{823}, \underline{824}. aaxis h: \underline{1106}, \underline{1107}, \underline{1108}, \underline{1109}, \underline{1149}, \underline{1150},

\underline{1151}, \underline{1152}.

aaxis v : \underline{1106}, \underline{1107}, \underline{1108}, \underline{1109}, \underline{1149}, \underline{1150},

\underline{1151}, \underline{1152}. abs : 1321. acos : 549. align with axis : \underline{213}, \underline{309}, 423, \underline{424}, 439, 605, 616,

\underline{790}, \underline{791}, \underline{792}, \underline{793}, \underline{794}, \underline{795}, 993, 997, 1165, 1221, 1267, 1268, 1307, 1311, 1500.

ang : 603, \underline{604}, \underline{605}, \underline{606}, \underline{607}, \underline{609}, \underline{610}, \underline{611}, \underline{612},

\underline{615}, \underline{616}, \underline{1001}, \underline{1165}. angle: \underline{211}, \underline{212}, \underline{288}, \underline{424}, 426, 428, 429, 430, 431,

435, \underline{436}, \underline{437}, \underline{438}, \underline{439}, \underline{440}, \underline{548}, \underline{549}, \underline{600}, 601, 603, 605, 614, 616, 618, \underline{759}, \underline{760}, \underline{762}, \underline{763}, \underline{764}, \underline{765}, \underline{994}, \underline{995}, 997, 1001, \underline{1011}, \underline{1012}, \underline{1013}, \underline{1014}, \underline{1050}, \underline{1051}, \underline{1052}, \underline{1053}, 1123, 1165, \underline{1201}, \underline{1202}, \underline{1252}, \underline{1253}, \underline{1254}, \underline{1255}, \underline{1267}, \underline{1268}, \underline{1401}, \underline{1402}, \underline{1484}, \underline{1501}, 1502, \underline{1515}.

angle h h: \underline{1529}. angle h s : \underline{1529}. angle hex hex : \underline{1522}, \underline{1523}, 1529. angle hex square: \underline{1522}, \underline{1523}, 1529. angle point : \underline{994}, \underline{995}, \underline{1201}, \underline{1202}, 1224. angle x : \underline{1076}, \underline{1077}, 1078, \underline{1079}, \underline{1080}, 1081, 1105,

\underline{1106}, \underline{1107}, \underline{1108}, \underline{1109}, \underline{1149}, \underline{1150}, \underline{1151}, \underline{1152}, \underline{1281}, \underline{1282}, \underline{1283}, \underline{1284}, \underline{1483}, \underline{1484}, 1486, \underline{1487}, \underline{1488}, \underline{1500}, \underline{1501}, 1502, \underline{1514}, \underline{1515}, \underline{1528}, \underline{1529}.

angle y : \underline{1076}, \underline{1077}, 1078, \underline{1079}, \underline{1080}, 1081, 1105, \underline{1106}, \underline{1107}, \underline{1108}, \underline{1109}, \underline{1149}, \underline{1150}, \underline{1151}, \underline{1152}, \underline{1281}, \underline{1282}, \underline{1283}, \underline{1284}, \underline{1483}, \underline{1484}, 1486, \underline{1487}, \underline{1488}, \underline{1500}, \underline{1501}, 1502, \underline{1514}, \underline{1515}, \underline{1528}, \underline{1529}.

angle z : \underline{1076}, \underline{1077}, 1078, \underline{1079}, \underline{1080}, 1081, 1105, \underline{1106}, \underline{1107}, \underline{1108}, \underline{1109}, \underline{1149}, \underline{1150}, \underline{1151}, \underline{1152}, \underline{1281}, \underline{1282}, \underline{1283}, \underline{1284}, \underline{1483}, \underline{1484}, 1486, \underline{1487}, \underline{1488}, \underline{1500}, \underline{1501}, 1502, \underline{1514}, \underline{1515}, \underline{1528}, \underline{1529}.

ap: \underline{713}, \underline{715}, \underline{718}, \underline{720}. append : \underline{812}, \underline{813}. apply transform: \underline{245}, 347, 356, 361, 390, 394, 418,

423, 424, 425, 429, 433, 439, 441, 443, \underline{448}, \underline{449}, 475, 480, 487, 495, 501, 507, 516, 520, 522, 524, 526, 528, 530, 533, 537, 539, 541, 543, 545, 547, 552, 573, 575, 593, 605, 616, 640, 641, 642, 668, 775, \underline{783}, \underline{784}, 882, 932, 933, 935, 948, 1023, 1025, 1077, 1107, 1150, 1178, 1180, 1183, 1185, 1282, \underline{1388}, \underline{1389}, 1405.

arc divisions : \underline{1323}, \underline{1324}, \underline{1326}, \underline{1327}. arg : \underline{56}, \underline{57}, \underline{58}, \underline{59}, \underline{315}. arg ptr : \underline{713}, \underline{715}. argc: 1549, \underline{1555}. argument : \underline{600}. argv : 1549, \underline{1555}, 1557. arrow : \underline{698}, 702, 705, 708, 710, 713, 715, 718,

720, 819, 899, 902, 904, 906. asctime: 82. asin: 1509. assign: \underline{232}, \underline{233}, 550, \underline{551}, \underline{552}, \underline{792}, \underline{793}, \underline{812},

\underline{813}, 814, \underline{955}, \underline{956}. atan: 28, 1305, 1495. ax : 603, \underline{604}, \underline{605}, \underline{606}, \underline{607}, \underline{609}, \underline{610}, \underline{611}, \underline{612}. ax h: \underline{1175}, \underline{1206}, \underline{1216}, 1218, 1222. ax v : \underline{1175}, \underline{1206}, \underline{1216}, 1218, 1222. axis : \underline{213}, \underline{424}, 426, 427, 432, \underline{439}, \underline{600}, 601, 603,

605, 614, 616, 618, \underline{790}, \underline{791}, \underline{792}, \underline{793}, \underline{794}, \underline{795}. axis h: \underline{1101}, 1106, 1107, 1112, 1120, 1129, 1131,

\underline{1143}, 1150, 1158, 1171, 1174, 1190, 1200, 1201, 1205, 1216, 1217, 1218, 1231, 1232, 1235, 1242, 1252, 1282, 1292, 1293.

axis h half : 1106, \underline{1107}, \underline{1150}, \underline{1232}. axis unknown: \underline{1171}, \underline{1172}. axis v : \underline{1101}, 1106, 1107, 1112, 1120, 1129, 1133,

\underline{1143}, 1150, 1158, 1171, 1174, 1190, 1195, 1201, 1205, 1216, 1217, 1218, 1231, 1232, 1235, 1242, 1252, 1282, 1292, 1293.

axis v half : 1106, \underline{1107}, \underline{1150}, \underline{1232}. : \underline{256}, \underline{257}. a0 : \underline{944}. a1 : \underline{944}. b: \underline{16}, \underline{31}, \underline{32}, \underline{69}, \underline{102}, \underline{103}, \underline{104}, \underline{105}, \underline{107}, \underline{108}, \underline{109},

\underline{110}, \underline{121}, \underline{122}, \underline{125}, \underline{126}, \underline{127}, \underline{128}, \underline{133}, \underline{134}, \underline{245}, \underline{313}, \underline{315}, \underline{317}, \underline{342}, \underline{343}, \underline{394}, \underline{437}, \underline{732}, \underline{733}, \underline{923}, \underline{924}, \underline{950}, \underline{1123}, \underline{1165}, \underline{1222}, \underline{1350}, \underline{1351}, \underline{1380}.

b x : \underline{650}. b y : \underline{650}. b z : \underline{650}. back : 589, 807, 808, 813, 930, 957, 977, 1032,

1034, 1150, 1339, 1347, 1458, 1502, 1515. background : 152, 1321. background color : \underline{156}, \underline{157}, 159, 459, 819, 845,

849, 851, 866, 868, 905, 1320, 1321. background color vector : \underline{159}, \underline{160}, 1429. bb: \underline{313}, \underline{317}, \underline{1222}, \underline{1305}. begin: 294, 587, 589, 590, 593, 594, 596, 597, 701,

703, 727, 777, 782, 784, 786, 808, 809, 813, 814, 873, 883, 886, 902, 903, 905, 910, 942, 944, 958, 1032, 1034, 1041, 1161, 1165, 1296, 1324, 1327, 1339, 1346, 1347, 1382, 1384, 1387, 1389, 1405, 1407, 1420, 1424, 1427, 1430, 1433, 1436, 1439, 1458, 1465, 1474, 1502, 1506, 1515, 1519, 1529.

beginfig : \underline{86}, \underline{87}, 514, 1547. beta: \underline{1305}. bit pattern i type: \underline{69}, 70. bitset: 69. black : 152, \underline{156}, \underline{157}, 1001, 1324, 1327, 1502. blue: 152, \underline{156}, \underline{157}, 993, 1001, 1324, 1484,

1502, 1546. blue part : \underline{95}, 98, 100, 103, 105, 108, 110, 115,

116, 117, 128, 134, 143. blue violet : 152, \underline{156}, \underline{157}, 1546. bool pair: \underline{15}. bool point: \underline{49}, 312, \underline{313}, \underline{314}, 315, 319, 320, 571,

572, 573, 574, 647, 648, 684, 685, 686, 964, 965, 966, 996, 1007, 1032, 1034, 1041, 1492.

bool point pair: \underline{312}, 319, 320, 996, 997, 998, 1008, 1009, 1028, 1029, 1037, 1038, 1043, 1202, 1208, 1209, 1210, 1211, 1218, 1227, 1260, 1267, 1300, 1301, 1302, 1303.

bool point quadruple: \underline{315}, \underline{316}, 319, 320,

1212, 1214, 1215, 1304, 1305. bool real: \underline{15}, 393, 394, 396, 397, 398, 399,

647, 1005, 1043. bool real point: \underline{49}, \underline{317}, \underline{318}, 319, 320, 647,

648, 649, 964. bools: 711, 996, 1336. bot lft : \underline{1107}. bot rt : \underline{1107}. bp: \underline{313}, \underline{574}, 585, \underline{647}, \underline{685}, \underline{1007}, \underline{1032}, \underline{1034},

1035, \underline{1041}, \underline{1492}. bpp: 997, \underline{998}, 1002, 1003, 1004, 1005, 1007,

\underline{1029}, 1032, 1034, 1035, 1036, \underline{1043}, 1201, \underline{1202}, \underline{1227}, \underline{1267}.

bpp e: \underline{1218}. bpp this : \underline{1218}. bpp0 : \underline{1260}. bpp1 : \underline{1260}. bpq : \underline{1212}, \underline{1215}, 1223, 1225, 1227, \underline{1305}. br : \underline{399}, \underline{1043}. br p: \underline{647}. br q : \underline{647}. brp: \underline{317}, \underline{647}, \underline{649}, 650, 651. BUG FIX: 195, 310, 393, 430, 441, 507, 518,

589, 645, 667, 677, 716, 932, 948, 997, 1011, 1106, 1190, 1201, 1231, 1348.

BUGS: 439. b0 : \underline{944}. b1 : \underline{944}. C: \underline{56}, \underline{57}, \underline{58}, \underline{59}, \underline{111}, \underline{724}, \underline{725}, \underline{1083}, \underline{1084},

\underline{1116}, \underline{1117}, \underline{1154}, \underline{1155}, \underline{1258}, \underline{1267}, \underline{1268}, \underline{1286}, \underline{1287}, \underline{1341}, \underline{1462}.

c: \underline{16}, \underline{31}, \underline{32}, \underline{99}, \underline{100}, \underline{112}, \underline{113}, \underline{114}, \underline{115}, \underline{116}, \underline{117}, \underline{118}, \underline{119}, \underline{147}, \underline{148}, \underline{315}, \underline{360}, \underline{361}, \underline{362}, \underline{363}, \underline{738}, \underline{739}, \underline{740}, \underline{741}, \underline{743}, \underline{744}, \underline{745}, \underline{746}, \underline{819}, \underline{845}, \underline{850}, \underline{867}, \underline{948}, \underline{952}, \underline{953}, \underline{1116}, \underline{1117}, \underline{1119}, \underline{1120}, \underline{1123}, \underline{1125}, \underline{1126}, \underline{1127}, \underline{1128}, \underline{1154}, \underline{1155}, \underline{1161}, \underline{1212}, \underline{1222}, \underline{1232}, \underline{1284}, \underline{1286}, \underline{1287}, \underline{1290}, \underline{1291}, \underline{1295}, \underline{1296}, \underline{1304}, \underline{1305}, \underline{1307}, \underline{1309}, \underline{1311}, \underline{1313}, \underline{1341}, \underline{1342}, \underline{1422}, \underline{1425}, \underline{1428}, \underline{1457}, \underline{1458}, \underline{1459}, \underline{1460}, \underline{1462}, \underline{1463}, \underline{1466}, \underline{1467}, \underline{1547}. c iter : 701, 1422, 1424, 1425, 1427. c plane: \underline{1305}. c ptr : \underline{1356}. c radius : \underline{1304}. c str : 83. c x : \underline{948}, 950. c y : \underline{948}, 949, 950. c z : \underline{948}, 949, 950. cc: \underline{1222}. ccenter : \underline{1076}, \underline{1077}, \underline{1079}, \underline{1080}, 1081, \underline{1106}, \underline{1107},

\underline{1108}, \underline{1109}, \underline{1149}, \underline{1150}, \underline{1151}, \underline{1152}, \underline{1281}, \underline{1282}, \underline{1283}, \underline{1284}.

ccos : \underline{206}, 207, 208, 209. Center : \underline{1202}. center : \underline{985}, 992, 996, 997, 1008, 1010, 1012,

1013, 1014, \underline{1019}, 1023, 1025, 1028, 1029, 1034, 1035, 1046, 1065, 1068, 1071, 1077, 1078, 1107, 1112, 1120, 1149, 1150, 1158, 1165, 1178, 1180, 1201, 1209, 1218, 1231, 1232, 1248, 1282, 1305, 1307, 1311, 1331, \underline{1333}, 1346, 1354, 1387, 1389, 1460, 1470, 1481, 1485, 1486, 1498, 1500, 1502, 1512, 1515, 1526, 1529.

center 0 : 1489, \underline{1502}, \underline{1503}, 1516, 1530. center 6 : \underline{1502}. cerr : 37, 68, 108, 110, 128, 130, 132, 134, 150,

152, 196, 198, 206, 228, 233, 356, 361, 390, 391, 394, 395, 424, 427, 437, 444, 445, 476, 487, 496, 502, 506, 508, 516, 547, 549, 552, 580, 584, 593, 594, 595, 605, 616, 650, 668, 685, 688, 759, 760, 765, 786, 791, 793, 806, 808, 819, 845, 850, 856, 864, 867, 873, 885, 887, 901, 906, 910, 917, 924, 927, 928, 929, 933, 935, 937, 941, 942, 943, 945, 947, 948, 950, 956, 966, 971, 977, 993, 995, 999, 1006, 1009, 1012, 1023, 1025, 1030, 1033, 1038, 1042, 1053, 1112, 1126, 1128, 1150, 1165, 1172, 1183, 1185, 1206, 1211, 1218, 1221, 1223, 1224, 1225, 1226, 1232, 1255, 1260, 1267, 1268, 1293, 1296, 1305, 1307, 1311, 1321, 1324, 1357, 1370, 1405, 1407, 1504, 1517, 1549.

Char : \underline{37}. : 44, 69, 70. check : \underline{1231}, \underline{1232}, 1233, 1235, 1242, 1252. check projection limits : 297. : \underline{1333}, \underline{1334}, 1356, 1357, 1369, 1370, 1372. Circle: \underline{49}, 728, 1010, 1068, 1088, 1089, 1091,

1092, 1093, 1095, 1096, 1212, 1213, \underline{1276}, 1278, \underline{1279}, 1281, \underline{1282}, 1284, 1286, 1287, 1288, 1290, 1291, 1292, 1293, 1295, 1296, 1299, 1301, 1303, 1304, 1305, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1323, 1324, 1325, 1326, 1327, 1333, 1339, 1346, 1347, 1352, 1356, 1358, 1359, 1369, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1424,

1427, 1430, 1433, 1436, 1439, 1547. circles : \underline{1333}, 1339, 1346, 1347, 1356, 1357, 1359,

1369, 1370, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1431, 1433, 1434, 1436, 1437, 1439.

Circles: 1217, 1295, 1323, 1326. classes : 700. clean: \underline{180}, \underline{181}, 186, 188, 196, 198, 201, 209, 217,

219, 222, 224, \underline{346}, \underline{347}, 439, 560, 561, 564. clear : \underline{245}, 266, 267, 277, \underline{300}, \underline{344}, \underline{345}, 514,

587, \underline{590}, 703, 727, \underline{728}, \underline{729}, 752, 1043, 1071, 1085, 1118, 1120, 1156, 1288, 1324, 1327, 1346, \underline{1383}, \underline{1384}, 1465.

close: 1557. closed : \underline{1011}, \underline{1012}, \underline{1013}, \underline{1014}. coeffs : \underline{1004}. col : \underline{178}, \underline{179}, \underline{190}, \underline{191}. col vec: \underline{1502}. Color: \underline{95}, 97, \underline{98}, 99, \underline{100}, 102, \underline{103}, 105, 107,

\underline{108}, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 122, 124, 126, 128, 130, 132, 134, 136, 139, 145, 147, 148, 150, 152, 155, 156, 157, 159, 160, 309, 453, 454, 455, 456, 457, 463, 464, 466, 467, 472, 473, 698, 699, 701, 738, 739, 740, 741, 743, 744, 745, 746, 818, 819, 820, 821, 823, 824, 827, 828, 829, 830, 832, 833, 836, 837, 838, 839, 841, 842, 844, 845, 846, 847, 849, 850, 851, 852, 866, 867, 868, 869, 968, 969, 973, 974, 1091, 1092, 1095, 1096, 1137, 1138, 1261, 1262, 1263, 1264, 1269, 1270, 1309, 1310, 1313, 1314, 1320, 1321, 1323, 1324, 1326, 1327, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1434, 1437, 1502, 1546, 1557.

color iter : 1327. color ptr : 1422, \underline{1424}, 1425, \underline{1427}. Colors: 106, 116, 151, \underline{152}, \underline{156}, \underline{157}, \underline{159}, \underline{160},

454, 456, 459, 463, 464, 466, 467, 471, 472, 473, 502, 699, 818, 819, 820, 827, 829, 844, 845, 846, 849, 851, 866, 868, 902, 904, 905, 906, 968, 993, 1001, 1091, 1092, 1095, 1096, 1137, 1138, 1261, 1263, 1320, 1321, 1323, \underline{1324}, 1326, \underline{1327}, 1423, 1424, 1426, 1427, 1429, \underline{1484}, 1492, \underline{1502}, \underline{1546}.

colors : \underline{1323}, \underline{1324}, \underline{1326}, \underline{1327}. column: \underline{625}, \underline{626}, \underline{628}, \underline{629}. Compare maximum z: 497, \underline{499}, 596, 1420. Compare mean z: 497, \underline{500}, 596. Compare minimum z: 497, \underline{498}, 596. Compiling: 1317. congruent flag : \underline{1218}. connector : 711, \underline{712}, \underline{713}, \underline{714}, \underline{715}, \underline{812}, \underline{813},

\underline{925}, \underline{926}, 929, 930. connector iter : 902, 903, 905, 907. connector ptr : \underline{718}, \underline{720}. connector string : \underline{718}, \underline{720}, \underline{902}, 903, 905, 907, \underline{910}. connectors : \underline{698}, 701, 703, 708, 710, 713, 715,

718, 720, 727, 752, 802, 807, 808, 809, 813, 814, 902, 903, 905, 907, 909, 910, 929, 930, 942, 957, 958, 1112, 1150.

connectors iter : 910. const iterator : 587, 589, 701, 808, 809, 813, 814,

873, 910, 942, 944, 1032, 1034, 1041, 1161, 1165, 1296, 1339, 1347, 1382, 1424, 1427, 1430, 1433, 1436, 1439, 1458, 1474.

consts : 27, 319. coords : \underline{245}, \underline{355}, \underline{356}, \underline{357}, \underline{358}, \underline{360}, \underline{361}, \underline{362},

\underline{363}, \underline{365}, \underline{366}, \underline{367}, \underline{368}, \underline{370}, \underline{371}, \underline{372}, \underline{373}, \underline{375}, \underline{376}, \underline{377}, \underline{378}, \underline{380}, \underline{381}, \underline{382}, \underline{383}, \underline{475}, \underline{476}, \underline{909}, \underline{910}, \underline{1381}, \underline{1382}.

copy : \underline{568}, \underline{993}, \underline{1001}, \underline{1218}, 1219, 1221, 1222,

1223, 1224. copy axis orientation: \underline{1222}. copy center : \underline{1218}, 1219, 1221, 1222. copy normal : \underline{993}. : \underline{22}, \underline{23}, 1549, 1553, 1554. corner : \underline{1125}, \underline{1126}. cos : 207, 208, 209, 1150. counter : \underline{70}, \underline{907}. cout : 37, 68, 69, 70, 87, 89, 136, 193, 219, 227,

228, 229, 230, 231, 233, 294, 394, 424, 426, 429, 431, 432, 439, 443, 444, 445, 449, 455, 476, 478, 487, 490, 492, 496, 502, 506, 508, 561, 563, 564, 565, 566, 574, 575, 576, 577, 578, 579, 580, 581, 582, 584, 585, 590, 592, 593, 594, 595, 596, 597, 605, 618, 647, 649, 650, 651, 653, 688, 690, 705, 708, 713, 718, 722, 727, 729, 769, 819, 845, 850, 867, 873, 883, 885, 886, 887, 890, 892, 900, 902, 904, 905, 906, 907, 910, 912, 917, 919, 930, 941, 944, 948, 950, 958, 965, 993, 998, 999, 1001, 1002, 1003, 1004, 1005, 1007, 1029, 1030, 1032, 1034, 1035, 1036, 1040, 1041, 1043, 1077, 1078, 1080, 1081, 1165, 1206, 1215, 1216, 1218, 1219, 1221, 1222, 1223, 1224, 1225, 1227, 1228, 1232, 1267, 1268, 1296, 1305, 1321, 1327, 1346, 1347, 1357, 1382, 1384, 1407, 1410, 1412, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1433, 1436, 1439, 1474, 1485, 1501, 1502, 1515, 1517, 1529, 1549, 1553, 1554, 1557.

create: 245. create new : \underline{56}, \underline{57}, \underline{58}, \underline{59}, 61, 62, \underline{111}, \underline{112}, \underline{113},

245, 335, \underline{336}, \underline{337}, 386, 455, 459, 506, 515, 701, 708, 710, 713, 715, 718, 720, \underline{724}, \underline{725}, 731, 798, 800, 808, 813, 819, 845, 850, 856, 864, 867, 929, 930, 1078, \underline{1083}, \underline{1084}, 1107, 1112, \underline{1116}, \underline{1117}, 1150, \underline{1154}, \underline{1155}, \underline{1286}, \underline{1287}, 1336, 1339, \underline{1341}, \underline{1342}, 1347, 1349, 1422, 1424, 1425, 1427, 1428, 1430, 1433, 1436, 1439, 1458, 1460, \underline{1462}, \underline{1463}, 1490, 1502, 1504, 1515, 1517, 1529, 1531, 1532.

create new circle: 1286, 1287. create new color : 111. create new cuboid : 1462. create new ellipse: 1154, 1155. create new path: 724, 725. create new point : 335. create new rectangle: 1116, 1117. create new reg polygon: 1083, 1084. create new solid : 1341. cross : 997, \underline{998}, 1000, \underline{1029}, 1031. cross product : \underline{544}, \underline{545}, 649, 688, 944, 998, 1029,

1112, 1122, 1123. ctr : \underline{361}, \underline{390}. Cuboid: 486, 1348, 1451, \underline{1453}, 1455, \underline{1456},

1457, \underline{1458}, 1459, \underline{1460}, 1462, 1463, 1464, \underline{1465}, 1466, 1467.

curr angle: \underline{1150}. curr color : \underline{1323}. curr location: \underline{1224}. curr point : \underline{1224}, 1225. curr x : \underline{1150}. : \underline{309}, \underline{310}, 327, 329. : \underline{309}, \underline{310}, 327, 329. curr z : \underline{1150}. current picture: \underline{302}, \underline{303}, 454, 458, 463, 466, 469,

472, 505, 507, 510, 512, 514, 818, 827, 836, 844, 849, 855, 863, 866, 872, 877, 968, 973, 1091, 1095, 1137, 1138, 1160, 1162, 1261, 1263, 1320, 1388, 1423, 1426, 1429, 1432, 1435, 1438, 1547.

curve 0 : \underline{1001}. curve 4 : \underline{1001}. cyan: 152, \underline{156}, \underline{157}, 1502, 1546. cycle: \underline{711}, 712, 713, 714, 715, \underline{925}, \underline{926}, 929, 930. cycle switch: \underline{698}, 701, 705, 708, 710, 713, 715,

718, 720, 910, 921, 953, 1074, 1077, 1104, 1107, 1112, 1147, 1150, 1279, 1282.

d: \underline{24}, \underline{25}, \underline{315}, \underline{688}, \underline{948}, \underline{1123}, \underline{1222}, \underline{1352},

\underline{1459}, \underline{1460}. d x : \underline{948}, 950. d y : \underline{948}, 949, 950. d z : \underline{948}, 949, 950. dashed : \underline{698}, 701, 702, 705, 708, 710, 713, 715,

718, 720, 748, 819, 845, 850, 856, 864, 867, 902, 904, 905, 906.

datestamp: \underline{82}, 83. : 19, 66, 1546. : \underline{68}. dd : \underline{1222}. ddashed : \underline{463}, \underline{464}, \underline{466}, \underline{467}, \underline{469}, \underline{470}, \underline{472}, \underline{473},

\underline{818}, \underline{819}, \underline{820}, \underline{821}, \underline{823}, \underline{824}, \underline{827}, \underline{828}, \underline{829}, \underline{830}, \underline{832}, \underline{833}, \underline{836}, \underline{837}, \underline{838}, \underline{839}, \underline{841}, \underline{842}, \underline{849}, \underline{850}, \underline{851}, \underline{852}, \underline{855}, \underline{856}, \underline{857}, \underline{858}, \underline{860}, \underline{861}, \underline{866}, \underline{867}, \underline{868}, \underline{869}, 967, \underline{968}, \underline{969}, 972, \underline{973}, \underline{974}, \underline{1091}, \underline{1092}, \underline{1095}, \underline{1096}, \underline{1137}, \underline{1138}, \underline{1261}, \underline{1262}, \underline{1263}, \underline{1264}, \underline{1269}, \underline{1270}, \underline{1309}, \underline{1310}, \underline{1313}, \underline{1314}, 1422, \underline{1423}, \underline{1424}, 1428, \underline{1429}, \underline{1430}, 1431, \underline{1432}, \underline{1433}, 1437, \underline{1438}, \underline{1439}.

ddiameter : \underline{1076}, \underline{1077}, \underline{1079}, \underline{1080}, 1081, \underline{1281},

\underline{1282}, \underline{1283}, \underline{1284}. ddraw color : \underline{463}, \underline{464}, \underline{466}, \underline{467}, \underline{472}, \underline{473}, \underline{818},

\underline{819}, \underline{820}, \underline{821}, \underline{823}, \underline{824}, \underline{827}, \underline{828}, \underline{829}, \underline{830}, \underline{832}, \underline{833}, \underline{836}, \underline{837}, \underline{838}, \underline{839}, \underline{841}, \underline{842}, 848, \underline{849}, \underline{850}, \underline{851}, \underline{852}, \underline{866}, \underline{867}, \underline{868}, \underline{869}, \underline{968}, \underline{969}, 972, \underline{973}, \underline{974}, \underline{1091}, \underline{1092}, \underline{1095}, \underline{1096}, \underline{1137}, \underline{1138}, \underline{1261}, \underline{1262}, \underline{1263}, \underline{1264}, \underline{1269}, \underline{1270}, \underline{1309}, \underline{1310}, \underline{1313}, \underline{1314}.

ddrawdot color : 453, \underline{454}, \underline{455}, \underline{456}, \underline{457}. : \underline{204}, \underline{206}, \underline{219}, \underline{227}, 228, 229, 230, 231, \underline{233},

\underline{390}, \underline{394}, \underline{424}, 425, 426, 429, 431, 432, 433, \underline{439}, \underline{443}, 444, 445, \underline{449}, \underline{455}, \underline{476}, \underline{487}, \underline{490}, \underline{492}, \underline{496}, \underline{502}, \underline{506}, \underline{508}, \underline{547}, \underline{549}, \underline{561}, 562, 563, 564, 565, 566, \underline{574}, 575, 576, 577, 578, 579, 580, 581, 582, 584, 585, \underline{590}, \underline{592}, 593, 594, 595, 596, 597, \underline{605}, \underline{647}, \underline{649}, 650, 651, \underline{688}, \underline{705}, \underline{708}, \underline{713}, \underline{718}, \underline{722}, \underline{727}, \underline{729}, \underline{769}, \underline{819}, \underline{845}, \underline{850}, \underline{867}, \underline{873}, \underline{883}, \underline{885}, 886, 887, \underline{890}, \underline{892}, \underline{900}, 902, 904, 905, 906, 907, \underline{917}, \underline{919}, \underline{926}, 930, \underline{941}, 944, \underline{948}, 950, \underline{956}, 958, \underline{993}, \underline{998}, 999, 1001, 1002, 1003, 1004, 1005, 1007, \underline{1029}, 1030, 1032, 1034, 1035, 1036, \underline{1040}, 1041, 1043, \underline{1077}, 1078, \underline{1080}, 1081, \underline{1165}, \underline{1206}, \underline{1215}, 1216, 1217, 1218, 1219, 1221, 1222, 1223, 1224, 1225, 1227, \underline{1232}, \underline{1296}, \underline{1305}, \underline{1321}, \underline{1324}, \underline{1327}, \underline{1346}, 1347, \underline{1357}, \underline{1384}, \underline{1407}, \underline{1410}, \underline{1412}, \underline{1420}, 1422, \underline{1424}, 1425, \underline{1427}, 1428, \underline{1430}, \underline{1433}, \underline{1436}, \underline{1439}, \underline{1460}, \underline{1484}, \underline{1501}, 1502, \underline{1515}, \underline{1517}, \underline{1529}, \underline{1531}, \underline{1549}.

decimal : 140, \underline{141}, \underline{142}, \underline{143}. default background : 152, \underline{156}, \underline{157}. default color : \underline{156}, \underline{157}, 159, 454, 456, 463, 464,

466, 467, 502, 818, 820, 827, 829, 844, 846, 849, 851, 902, 904, 905, 906, 968, 1091, 1092, 1095, 1096, 1137, 1138, 1261, 1263, 1320, 1321, 1324, 1424, 1427, 1492.

default color vector : \underline{159}, \underline{160}, 1323, 1326, 1423,

1426, 1429. default focus : 356, 361, 441, 446, 447, 475, 487,

501, 598, \underline{630}, \underline{631}. : \underline{1143}, \underline{1144}, 1149,

1150, 1151, 1281, 1283. define color mp: \underline{149}, \underline{150}, 152. delta x : \underline{566}. delta x p: \underline{576}, 577. delta x q : \underline{576}, 578. delta y : \underline{566}. delta y p: \underline{576}, 577. delta y q : \underline{576}, 578. delta z : \underline{566}. delta z p: \underline{576}, 577. delta z q : \underline{576}, 578. denominator : \underline{685}, \underline{1222}. depth: \underline{1453}, 1460, 1467. diameter inner : \underline{1320}, \underline{1321}, \underline{1323}, \underline{1324}, \underline{1326},

\underline{1327}. diameter middle: \underline{1320}, \underline{1321}. diameter of hexagon: \underline{1528}. diameter of triangle: \underline{1483}, \underline{1487}, \underline{1514}. diameter outer : \underline{1320}, \underline{1321}, \underline{1324}, \underline{1326}, \underline{1327}. diameter outer end : \underline{1323}, \underline{1324}. diameter outer start : \underline{1323}, \underline{1324}. digit optind : \underline{1549}. dihedral angle: 1453, \underline{1477}, \underline{1478}, 1484, \underline{1494},

\underline{1495}, 1501, \underline{1508}, \underline{1509}, 1515. dir : \underline{609}, \underline{610}, \underline{611}, \underline{612}, \underline{639}, \underline{640}. dir x : \underline{604}, \underline{605}, \underline{606}, \underline{607}. dir y : \underline{604}, \underline{605}, \underline{606}, \underline{607}. dir z : \underline{604}, \underline{605}, \underline{606}, \underline{607}. direction: \underline{600}, 601, 603, 605, 614, 616, 618, 621,

\underline{637}, 638, 640, 641, 642, 644, 645, 649, 650, 653, 978, 1043, 1227.

direction line: \underline{1202}. direction pt : \underline{1202}. direction vector : \underline{688}. : \underline{22}, \underline{23}, 1553, 1554. dist : 603, \underline{604}, \underline{605}, \underline{606}, \underline{607}, \underline{609}, \underline{610}, \underline{611}, \underline{612},

967, \underline{968}, \underline{969}, 970, 972, \underline{973}, \underline{974}, \underline{1305}. distance: \underline{600}, 603, 605, 614, 616, 618, 622, \underline{661},

663, 664, 667, 668, 670, 673, 679, 680, 685, 688, 690, \underline{998}, 1001, \underline{1029}, 1032, \underline{1040}, 1041, 1216, \underline{1485}, 1486.

do apply : \underline{245}, \underline{355}, \underline{356}, \underline{357}, \underline{358}, \underline{360}, \underline{361}, \underline{362}, \underline{363}, \underline{365}, \underline{366}, \underline{367}, \underline{368}, \underline{370}, \underline{371}, \underline{372}, \underline{373}, \underline{375}, \underline{376}, \underline{377}, \underline{378}, \underline{380}, \underline{381}, \underline{382}, \underline{383}, \underline{475},

\underline{476}, \underline{909}, \underline{910}, \underline{1381}, \underline{1382}.

do half : \underline{1489}, \underline{1503}, \underline{1504}, \underline{1516}, \underline{1517}, \underline{1530}, \underline{1531}. do help lines : 471, \underline{698}, \underline{699}, 837. do inner : \underline{1321}. do labels : 254, \underline{261}, 264, 274, 275, 294, 588, 597. : \underline{253}, \underline{254}, 261, 506, 873, 1161. do middle: \underline{1321}. do output : \underline{309}, 325, 328, 330, 332, 334, 341, 483,

485, 502, 596, \underline{698}, 701, 705, 708, 710, 713,

715, 718, 720, 896, 898, 900, \underline{1333}, 1336, 1337,

1339, 1347, 1416, 1418, 1456, 1458, 1460, 1481, 1484, 1498, 1501, 1512, 1515, 1526, 1529. do persp: \underline{245}, \underline{355}, \underline{356}, \underline{357}, \underline{358}, \underline{360}, \underline{361}, \underline{362}, \underline{363}, \underline{365}, \underline{366}, \underline{367}, \underline{368}, \underline{370}, \underline{371}, \underline{372}, \underline{373}, \underline{375}, \underline{376}, \underline{377}, \underline{378}, \underline{380}, \underline{381}, \underline{382}, \underline{383}, \underline{475}, \underline{476}, \underline{909}, \underline{910}, \underline{1381}, \underline{1382}.

do sort : \underline{591}.

do transform: \underline{593}, 1165, \underline{1231}, \underline{1232}, 1233, 1234,

1235, 1236, 1242, 1243, 1252, 1253. do warnings : \underline{298}, \underline{299}, 591, \underline{592}, 595, \underline{598}. Dodecahedron: 241, 1352, 1470, \underline{1494}, 1495, 1497, \underline{1498}, 1500, \underline{1501}, 1504, 1505, 1506, 1514, 1518.

dot : \underline{253}, \underline{505}, \underline{506}, \underline{507}, \underline{508}, 515, 516, 871, \underline{872},

\underline{873}, \underline{874}, \underline{875}, \underline{1160}, \underline{1161}, 1162. dot product : \underline{542}, \underline{543}, 548, 549, 649, 668, 678, 685. dotlabel : 252, 254, 505, 509, \underline{510}, \underline{511}, \underline{512}, \underline{513},

871, \underline{877}, \underline{878}, \underline{879}, \underline{880}, 993, 1001, \underline{1162}, 1218, 1221, 1223, 1258, 1305, 1321, 1324, 1327, 1460, 1492, 1502, 1506, 1515, 1517, 1519, 1529.

double rows : \underline{1320}, \underline{1321}.

doubles : 15, 182.

draw : 462, \underline{463}, \underline{464}, 471, \underline{818}, \underline{819}, \underline{820}, \underline{821}, 822, \underline{823}, \underline{824}, 828, 830, 837, 848, 901, 993, 1001, 1262, 1264, 1269, 1270, 1309, 1313, 1321, 1324, 1327, \underline{1423}, \underline{1424}, 1484, 1492, 1502, 1506, 1519, 1547, 1563. : \underline{244}, \underline{246}, 819, 902, 1422.

draw axes : \underline{968}, \underline{969}, \underline{973}, \underline{974}, 1001.

draw color : \underline{698}, 701, 705, 708, 710, 713, 715, 718, 720, 727, 728, 729, 739, 741, 818, 819, 845, 849, 850, 856, 864, 867, 902, 904, 905, 906, 907, 912, 1422, 1425. draw color inner : \underline{1320}, \underline{1321}. draw color iter : 1428, 1430. draw color middle: \underline{1320}, \underline{1321}. draw color outer : \underline{1320}, \underline{1321}. draw color ptr : 1428, \underline{1430}. draw colors : 1428, \underline{1429}, \underline{1430}. draw help: 471, \underline{472}, \underline{473}, 834, \underline{836}, \underline{837}, \underline{838},

\underline{839}, \underline{841}, \underline{842}, 1492.

draw in circle: \underline{1091}, \underline{1092}, \underline{1309}, \underline{1310}.

draw in ellipse: \underline{1138}, \underline{1270}. draw in rectangle: \underline{1263}, \underline{1264}. draw net : \underline{1491}, \underline{1492}, \underline{1505}, \underline{1506}, \underline{1518}, \underline{1519}. draw out circle: \underline{1095}, \underline{1096}, \underline{1313}, \underline{1314}. draw out ellipse: \underline{1137}, \underline{1269}. draw out rectangle: \underline{1261}, \underline{1262}. drawarrow : \underline{466}, \underline{467}, 698, \underline{827}, \underline{828}, \underline{829}, \underline{830},

\underline{832}, \underline{833}, 899, 972.

: \underline{244}, \underline{246}, 455, 502.

drawdot : 453, \underline{454}, \underline{455}, \underline{456}, \underline{457}, 509, 1492. drawdot color : \underline{309}, 341, 344, 453, 455, 459, 502. drawdot value: \underline{309}, 341, 344, 453, 455, 459, 502. e: \underline{688}, \underline{948}, \underline{1152}, \underline{1157}, \underline{1158}, \underline{1165}, \underline{1203}, \underline{1204},

\underline{1214}, \underline{1215}, \underline{1228}, \underline{1267}, \underline{1268}, \underline{1269}, \underline{1270}, \underline{1282}, \underline{1292}, \underline{1293}.

e axis h: \underline{1293}. e axis orientation: \underline{1217}, 1218, 1222. e axis orientation rotated : \underline{1217}, 1218, 1222. e axis v : \underline{1293}. e center : \underline{1221}, 1222. e plane: \underline{1215}, 1216, 1227. e x : \underline{948}, 950. e y : \underline{948}, 949, 950. e z : \underline{948}, 949, 950. edge radius : \underline{1472}, 1481, 1484, 1498, 1501, 1512,

1515, 1526, 1529. edges : \underline{1445}, 1456, 1458, 1460, 1481, 1484, 1498,

1501, 1512, 1515, 1526, 1529. elements : 482, 484, 486, \underline{497}, \underline{593}, 594, 595, 596,

882, 895, 897, \underline{899}. : \underline{1333}, \underline{1334}, 1356, 1357, 1369, 1370, 1374. Ellipse: \underline{49}, 335, 688, 1134, 1135, 1136, 1137,

1138, \underline{1143}, 1144, 1146, \underline{1147}, 1149, \underline{1150}, 1152, 1154, 1155, 1156, 1157, 1158, 1161, 1162, 1165, 1168, 1170, 1171, 1172, 1175, 1178, 1180, 1183, 1185, 1187, 1189, 1190, 1193, 1195, 1198, 1200, 1202, 1203, 1204, 1205, 1206, 1209, 1211, 1212, 1213, 1214, 1215, 1217, 1218, 1221, 1228, 1231, 1232, 1234, 1235, 1236, 1238, 1240, 1242, 1243, 1245, 1248, 1250, 1252, 1253, 1255, 1258, 1260, 1262, 1264, 1265, 1267, 1268, 1269, 1270, 1276, 1282, 1288, 1290, 1291, 1292, 1293, 1299, 1301, 1303, 1305, 1333, 1339, 1346, 1347, 1352, 1360, 1361, 1369, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1424, 1427, 1430, 1433, 1436, 1439.

ellipse pt0 : \underline{1221}. ellipse pt4 : \underline{1221}. Ellipses: 1158, 1212, 1214, 1217, 1218, 1224. ellipses : \underline{1333}, 1339, 1346, 1347, 1356, 1357, 1361,

1369, 1370, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1431, 1433, 1434, 1436, 1437, 1439.

Ellipsoid : 1333. end : 294, 587, 589, 590, 593, 594, 596, 597, 701,

703, 727, 777, 782, 784, 786, 808, 809, 813, 814, 873, 883, 886, 907, 910, \underline{925}, \underline{926}, 927, 928, 929, 930, 942, 944, 958, 1032, 1034, 1041, 1161, 1165, 1296, 1324, 1327, 1339, 1346, 1347, 1382, 1384, 1387, 1389, 1405, 1407, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1433, 1436, 1439, 1458, 1465, 1474, 1502, 1506, 1515, 1519, 1529.

endfig : \underline{88}, \underline{89}, 1547. endl : 37, 68, 69, 70, 83, 85, 87, 89, 128, 130, 132,

134, 136, 193, 196, 198, 227, 228, 230, 231, 294, 361, 390, 424, 426, 427, 429, 431, 432, 444, 445, 449, 478, 490, 492, 496, 508, 563, 565, 566, 580, 581, 582, 585, 592, 595, 596, 605, 616, 618, 647, 649, 650, 653, 685, 690, 819, 845, 850, 867, 883, 885, 886, 887, 890, 892, 910, 930, 942, 950, 958, 966, 971, 993, 1001, 1002, 1004, 1005, 1006, 1007, 1012, 1033, 1034, 1040, 1150, 1165, 1183, 1185, 1211, 1215, 1218, 1222, 1223, 1224, 1225, 1227, 1232, 1267, 1268, 1296, 1305, 1321, 1324, 1327, 1347, 1357, 1370, 1382, 1410, 1412, 1422, 1425, 1428, 1474, 1485, 1529, 1549, 1553, 1554.

epicycloid pattern 1 : \underline{1323}, \underline{1324}, 1325. epicycloid pattern 3 : 1323, \underline{1326}, \underline{1327}. eps : \underline{181}, \underline{196}, \underline{198}, \underline{201}, \underline{206}, 207, 208, 209, \underline{347},

\underline{445}, \underline{449}, 559, 560, \underline{561}, 565, 566. epsilon: 18, 27, 179, 180, 181, \underline{182}, \underline{183}, 184, 195,

196, 198, 201, 206, 347, \underline{350}, \underline{351}, 445, 449, 542, 543, 559, 561, 650, 668, 677, 678, 992, 993, 1040, 1122, 1123, 1164, 1165, 1205, 1206, 1216, 1232, 1293, 1295, 1296.

erase: 82. exchange x z : \underline{948}, 950. exchange y z : \underline{948}. exit : 68, 1549. extract : \underline{245}, \underline{486}, \underline{487}, 501, 593, \underline{882}, \underline{883}, 884,

899, \underline{1404}, \underline{1405}, 1419. extremes : 593, \underline{594}, 595. f: \underline{245}, \underline{255}, \underline{298}, \underline{355}, \underline{356}, \underline{357}, \underline{358}, \underline{360}, \underline{361}, \underline{362},

\underline{363}, \underline{365}, \underline{366}, \underline{367}, \underline{368}, \underline{370}, \underline{371}, \underline{372}, \underline{373}, \underline{375}, \underline{376}, \underline{377}, \underline{378}, \underline{380}, \underline{381}, \underline{382}, \underline{383}, \underline{442}, \underline{443}, \underline{446}, \underline{475}, \underline{476}, \underline{486}, \underline{487}, \underline{516}, \underline{592}, \underline{607}, \underline{610}, \underline{612}, \underline{614}, \underline{680}, \underline{785}, \underline{786}, \underline{882}, \underline{883}, \underline{909}, \underline{910}, \underline{1381}, \underline{1382}, \underline{1404}, \underline{1405}.

fabs : 179, 181, 196, 198, 201, 207, 208, 209, 228, 347, 445, 449, 543, 560, 565, 566, 649, 668, 678, 680, 993, 1012, 1040, 1123, 1165, 1172, 1206, 1216, 1222, 1232, 1293, 1295, 1296.

face radius : \underline{1472}, 1481, 1484, 1498, 1501, 1512,

1515, 1526, 1529. faces : \underline{1445}, 1456, 1458, 1460, 1481, 1484, 1498,

1501, 1512, 1515, 1526, 1529. factor : \underline{245}, \underline{255}, \underline{298}, \underline{299}, \underline{346}, \underline{347}, \underline{355}, \underline{356},

\underline{357}, \underline{358}, \underline{360}, \underline{361}, \underline{362}, \underline{363}, \underline{365}, \underline{366}, \underline{367}, \underline{368}, \underline{370}, \underline{371}, \underline{372}, \underline{373}, \underline{375}, \underline{376}, \underline{377}, \underline{378}, \underline{380}, \underline{381}, \underline{382}, \underline{383}, \underline{442}, \underline{443}, 444, \underline{446}, \underline{447}, \underline{475}, \underline{476}, \underline{486}, \underline{487}, \underline{516}, 560, \underline{561}, \underline{592}, 593, 597, \underline{598}, \underline{785}, \underline{786}, \underline{882}, \underline{883}, \underline{909}, \underline{910}, \underline{1011}, \underline{1012}, \underline{1381}, \underline{1382}, \underline{1404}, \underline{1405}.

false: 20, 36, 38, 40, 66, 86, 88, 98, 100, 103, 104, 105, 108, 110, 115, 141, 142, 143, 186, 188, 204, 206, 219, 227, 232, 233, 254, 261, 274, 293, 314, 318, 319, 325, 328, 332, 390, 394, 395, 400, 401, 424, 439, 443, 445, 449, 453, 455, 463, 464, 475, 476, 481, 483, 487, 490, 492, 496, 502, 505, 506, 507, 508, 516, 547, 549, 551, 552, 561, 562, 565, 571, 573, 574, 585, 590, 592, 593, 594, 596, 605, 617, 647, 649, 651, 681, 685, 688, 702, 705, 708, 710, 713, 715, 718, 720, 722, 727, 729, 769, 786, 792, 793, 818, 819, 820, 837, 845, 850, 867, 872, 873, 874, 883, 885, 886, 887, 890, 892, 896, 900, 911, 916, 917, 918, 919, 925, 926, 941, 948, 950, 955, 956, 964, 972, 987, 988, 989, 992, 993, 996, 998, 1005, 1012, 1029, 1032, 1040, 1043, 1074, 1077, 1080, 1104, 1107, 1112, 1123, 1147, 1150, 1160, 1161, 1164, 1165, 1168, 1170, 1201, 1206, 1214, 1215, 1218, 1227, 1231, 1232, 1235, 1236, 1242, 1243, 1252, 1253, 1279, 1282, 1295, 1296, 1304, 1305, 1321, 1324, 1327, 1336, 1337, 1339, 1346, 1357, 1384, 1407, 1410, 1412, 1416, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1433, 1436, 1439, 1456, 1458, 1460, 1481, 1484, 1498, 1501, 1503, 1505, 1512, 1515, 1516, 1517, 1526, 1529, 1530, 1531, 1546, 1549.

ffill color : \underline{844}, \underline{845}, \underline{846}, \underline{847}, 848, \underline{849}, \underline{850},

\underline{851}, \underline{852}. fig num: \underline{78}, \underline{79}, 87, 89. fill : 597, \underline{844}, \underline{845}, \underline{846}, \underline{847}, 848, 1013, 1014,

1321, 1425, \underline{1426}, \underline{1427}. : \underline{244}, \underline{246}, 845, 902, 1425. fill color : \underline{698}, 701, 705, 708, 710, 713, 715,

718, 720, 727, 728, 729, 744, 746, 818, 819, 844, 845, 849, 850, 856, 864, 867, 902, 907, 912, 1321, 1425.

fill color inner : \underline{1320}, \underline{1321}. fill color iter : 1428, 1430. fill color middle: \underline{1320}, \underline{1321}. fill color outer : \underline{1320}, \underline{1321}. fill color ptr : 1428, \underline{1430}. fill colors : 1428, \underline{1429}, \underline{1430}. fill draw value: \underline{698}, 701, 705, 708, 710, 713, 715,

718, 720, 736, 819, 845, 850, 856, 864, 867, 902, 904, 905, 906, 909, 910.

fill out ellipse: 1265. filldraw : 597, 848, \underline{849}, \underline{850}, \underline{851}, \underline{852}, 1013, 1014,

1321, \underline{1429}, \underline{1430}, 1438, 1547. : \underline{244}, \underline{246}, 850, 902, 1428. first : \underline{16}, 32, \underline{315}, 316, 399, 585, 647, 677, 992,

993, 1002, 1003, 1004, 1005, 1007, 1032, 1034, 1035, 1043, 1173, 1174, 1175, 1201, 1202, 1218, 1223, 1225, 1227, 1260, 1267, 1305.

first point ptr : \underline{711}, 716, \underline{717}, \underline{718}, \underline{719}, \underline{720}. first row : \underline{1320}, \underline{1321}. fixed : 83, 907, 1553. floatfield : 83, 1553. floats : 15, 27, 182, 546. floor : 1224, 1293. : 70. : 7, 19, 66, 1546. : \underline{68}. flush: 37, 68, 69, 70, 87, 89, 150, 152, 193, 196,

198, 206, 219, 227, 228, 229, 230, 231, 233, 294, 356, 361, 390, 394, 395, 424, 426, 427, 429, 431, 432, 437, 443, 444, 445, 449, 455, 476, 487, 490, 492, 496, 502, 506, 508, 516, 552, 561, 563, 565, 566, 574, 575, 576, 577, 578, 579, 580, 581, 582, 584, 585, 590, 592, 593, 594, 595, 596, 597, 605, 616, 618, 647, 649, 650, 651, 668, 685, 688, 690, 705, 708, 713, 718, 722, 727, 786, 793, 808, 819, 845, 850, 856, 864, 867, 873, 885, 886, 887, 890, 892, 900, 901, 902, 904, 905, 906, 907, 910, 917, 919, 924, 927, 928, 929, 930, 933, 935, 937, 941, 942, 943, 944, 945, 947, 948, 950, 956, 958, 965, 966, 971, 977, 993, 995, 998, 999, 1001, 1002, 1004, 1005, 1006, 1007, 1009, 1012, 1023, 1025, 1029, 1030, 1033, 1034, 1036, 1038, 1040, 1042, 1043, 1077, 1078, 1080, 1081, 1112, 1126, 1128, 1150, 1165, 1172, 1183, 1185, 1206, 1211, 1216, 1218, 1219, 1221, 1222, 1223, 1224, 1225, 1227, 1232, 1260, 1267, 1268, 1296, 1305, 1307, 1311, 1321, 1324, 1327, 1347, 1357, 1370, 1382, 1384, 1405, 1407, 1410, 1412, 1422, 1424, 1425, 1427, 1428, 1430, 1433, 1436, 1439, 1474, 1485, 1501, 1502, 1504, 1515, 1517, 1529, 1549, 1553, 1554, 1557.

fmod : 1012, 1327. fmtflags : 1553. focus : 899. Focus: \underline{49}, 166, 245, 255, 297, 298, 309, 354, 355, 356, 357, 358, 360, 361, 362, 363, 365, 366, 367, 368, 370, 371, 372, 373, 375, 376, 377, 378, 380, 381, 382, 383, 441, 442, 443, 446, 475, 476, 486, 487, 497, 501, 516, 591, 592, 593, 596, 597, \underline{600}, 601, \underline{602}, 603, 604, \underline{605}, 607, 609, \underline{610}, 612, 613, 614, 616, 618, 619, 625, 626, 628, 629, 630, 631, 785, 786, 882, 883, 887, 909, 910, 967, 1381, 1382, 1404, 1405.

Focuses : 166, 967.

focus0 : \underline{1143}, 1149, 1150, 1158, 1183, 1185, 1205,

1231, 1232, 1247, 1248. focus1 : \underline{1143}, 1149, 1150, 1158, 1183, 1185, 1231,

1232, 1247, 1248. found : \underline{1032}. fourth: \underline{315}, 316, 1223, 1225, 1227. front : 977, 1032, 1034, 1041, 1419, 1515. g: \underline{102}, \underline{103}, \underline{104}, \underline{105}, \underline{107}, \underline{108}, \underline{109}, \underline{110}, \underline{127},

\underline{128}, \underline{131}, \underline{132}, \underline{1382}. get all coords : \underline{355}, \underline{356}, \underline{357}, \underline{358}, 476, 910. get axis h: \underline{1130}, \underline{1131}, 1171, 1172, 1174, 1175,

1190, \underline{1197}, \underline{1198}, \underline{1199}, \underline{1200}, 1201, 1202, 1206, 1216, 1222, 1293.

get axis v : \underline{1132}, \underline{1133}, 1171, 1172, 1174, 1175, 1190, \underline{1192}, \underline{1193}, \underline{1194}, \underline{1195}, 1201, 1202, 1206, 1216, 1222, 1293.

get blue part : 100, 136, \underline{143}, 148, 150. get center : 1001, \underline{1022}, \underline{1023}, \underline{1024}, \underline{1025}, 1124,

1165, \underline{1177}, \underline{1178}, \underline{1179}, \underline{1180}, 1193, 1195, 1198, 1200, 1201, 1202, 1217, 1218, 1221, 1232, 1258, 1267, 1268, 1295, 1296, 1324, 1331, \underline{1353}, \underline{1354}, 1370, 1484, 1492, 1502, 1506, 1515, 1517, 1519.

get circle: 1352. get circle center : \underline{1371}, \underline{1372}. get circle ptr : 1352, 1355, 1356, \underline{1358}, \underline{1359}. get coefficients : \underline{990}, 1004, \underline{1174}, \underline{1175}. get coord : 359, \underline{360}, \underline{361}, \underline{362}, \underline{363}, 366, 368, 371,

373, 376, 378, 381, 383. get copy : \underline{245}, \underline{255}, 267, \underline{385}, \underline{386}, \underline{515}, 587, 589,

\underline{730}, \underline{731}, \underline{1348}, \underline{1349}, 1356, 1357, 1420. get diameter : \underline{1298}. get direction: \underline{621}. get distance: 15, 445, \underline{622}, 647, \underline{648}, \underline{649}, \underline{677}, \underline{678},

\underline{679}, \underline{680}, 681, 992, 993, 998, 1029. get element : 166, \underline{190}, \underline{191}, 625, 626, 628, 629. get ellipse: 1352. get ellipse center : \underline{1373}, \underline{1374}. get ellipse ptr : 1352, 1355, 1356, \underline{1360}, \underline{1361}. get endianness : \underline{36}, \underline{37}, 39, 41. get extremes : \underline{245}, \underline{488}, 595, \underline{888}, 1407, \underline{1408}. get focus : \underline{1182}, \underline{1183}, \underline{1184}, \underline{1185}, 1206. get green part : 100, 136, \underline{142}, 148, 150. get last point : 759, 764, 765, 793, \underline{936}, \underline{937},

964, 965, 966, 1009, 1012, 1028, 1038, 1053, 1210, 1211, 1255.

get line: \underline{352}, 638, \underline{645}, 647, \underline{976}, \underline{977}. get line switch: 462, 759, 760, 764, 791, 792,

\underline{920}, 923, 964. get linear eccentricity : \underline{1186}, \underline{1187}. get maximum z : \underline{245}, \underline{491}, \underline{492}, 499, 500, 596,

\underline{891}, \underline{892}, \underline{1411}, \underline{1412}. get mean z : 244, \underline{245}, \underline{493}, \underline{494}, 596, \underline{893}, \underline{894},

\underline{1413}, \underline{1414}. get mid point : \underline{1127}, \underline{1128}, 1267, 1268. get minimum z : 244, \underline{245}, \underline{489}, \underline{490}, 498, 500, 594,

596, \underline{889}, \underline{890}, \underline{1409}, \underline{1410}. get name: 136, \underline{146}, 148, 819, 845, 850, 867,

1422, 1425, 1428. get net : 1472, 1484, \underline{1489}, \underline{1490}, 1492, 1501, \underline{1503}, \underline{1504}, 1506, \underline{1516}, \underline{1517}, 1519, 1524, 1529, \underline{1530}, \underline{1531}.

get normal : \underline{557}, 916, 917, 918, 919, \underline{940}, \underline{941}, \underline{945},

946, 947, 992, 993, 1012, 1164, 1165, 1202, 1267, 1268, 1305, 1307, 1311. get numerical eccentricity : \underline{1188}, \underline{1189}.

get path: \underline{646}, \underline{978}, 1352.
get path ptr : 1352, 1355, \underline{1362}, \underline{1363}.
get persp: \underline{627}.
get persp element : 445, \underline{628}, \underline{629}.

get plane: 663, \underline{946}, \underline{947}, 948, 992, 993, 998, 1029,

1040, 1206, 1215, 1305. get point : 759, 760, 764, 765, 793, 808, \underline{932}, \underline{933}, \underline{934}, \underline{935}, 947, 966, 993, 998, 1001, 1009, 1012, 1028, 1029, 1038, 1053, 1123, 1165, 1193, 1195, 1198, 1200, 1202, 1210, 1211, 1217, 1218, 1221, 1222, 1223, 1232, 1255, 1258, 1260, 1267, 1268, 1321, 1484, 1490, 1492, 1501, 1502, 1504, 1506, 1515, 1517, 1519, 1529, 1531, 1532.

get polygon center : 1369.

get position: \underline{620}. get processor size: 43. get radius : \underline{1087}, \underline{1297}. get rectangle: 1352. get rectangle center : \underline{1375}, \underline{1376}. get rectangle ptr : 1352, 1355, \underline{1364}, \underline{1365}. get red part : 100, 136, \underline{141}, 148, 150. get reg polygon: 1352. get reg polygon center : \underline{1377}, \underline{1378}. get reg polygon ptr : 1352, 1355, \underline{1366}, \underline{1367}. get register width: \underline{43}, \underline{44}, 46, 48. get second largest : 19, \underline{66}, \underline{68}, \underline{71}, \underline{72}, 74, 75, 1546. get shape: 1352. get shape center : 1333, \underline{1369}, \underline{1370}, 1372, 1374,

1376, 1378. get shape ptr : 1333, 1352, 1355, \underline{1356}, \underline{1357}, 1358,

1360, 1362, 1364, 1366. get size: \underline{938}.

get transform: \underline{384}, \underline{624}.
get transform element : 443, \underline{625}, \underline{626}.
get up: \underline{623}.

get use name: 136, \underline{144}, \underline{145}, 148, 819, 845, 850,

867, 1422, 1425, 1428. get w : \underline{380}, \underline{381}, \underline{382}, \underline{383}. get x : 309, 353, 359, \underline{365}, \underline{366}, \underline{367}, \underline{368}, 393, 415, 416, 417, 422, 423, 439, 481, 507, 508, 516, 520, 542, 544, 546, 560, 610, 612, 650, 688, 774, 779, 886, 993, 1001, 1062, 1067, 1165, 1219, 1220, 1245, 1250, 1321, 1531.

get y : \underline{370}, \underline{371}, \underline{372}, \underline{373}, 393, 415, 416, 417, 422, 423, 439, 481, 507, 508, 516, 520, 542, 544, 546, 560, 610, 612, 650, 688, 774, 779, 886, 993, 1001, 1062, 1067, 1219, 1220, 1245, 1250, 1504, 1515, 1517.

get z : \underline{375}, \underline{376}, \underline{377}, \underline{378}, 393, 415, 416, 417, 422, 423, 427, 507, 508, 520, 542, 544, 546, 560, 610, 612, 650, 688, 774, 779, 886, 993, 1001, 1062, 1067, 1165, 1219, 1220, 1245, 1250.

getchar : 227, 294, 502, 688, 727, 901, 906,

912, 958, 993. getopt long only : 1549. gray : 152, \underline{156}, \underline{157}. green: 152, \underline{156}, \underline{157}, 1324, 1484, 1502, 1546. green part : \underline{95}, 98, 100, 103, 105, 108, 110, 115,

116, 117, 128, 132, 142. green yellow : 152, \underline{156}, \underline{157}, 1546. h: \underline{1459}, \underline{1460}. h length: \underline{1267}, \underline{1268}. half : 49, 1010, \underline{1013}. : 7. : 14. : 7, 11. height : \underline{1453}, 1460, 1467. help color : \underline{156}, \underline{157}, 159, 471, 472, 473, \underline{698},

\underline{699}, 836, 838, 1492. help color vector : \underline{159}, \underline{160}. help dash pattern: \underline{698}, \underline{699}, 836, 838. : \underline{1549}. hex pattern 1 : 1317, \underline{1320}, \underline{1321}. hex pattern1 : 441. hexagon ctr : \underline{1321}. hexagon diameter : \underline{1529}, \underline{1530}, \underline{1531}. hexagon radius : \underline{1522}, 1526, 1529. hi : 226, \underline{227}, 229. horizontal : \underline{444}. hr : \underline{227}, 229, 230. hv : \underline{227}, 231. i: \underline{25}, \underline{70}, \underline{86}, \underline{87}, \underline{88}, \underline{89}, \underline{171}, \underline{175}, \underline{177}, \underline{181}, \underline{186},

\underline{188}, \underline{193}, \underline{206}, \underline{209}, \underline{217}, \underline{219}, \underline{227}, \underline{345}, \underline{347}, \underline{439}, \underline{443}, \underline{449}, \underline{496}, \underline{530}, \underline{539}, \underline{552}, \underline{595}, \underline{871}, \underline{883}, \underline{886}, \underline{887}, \underline{925}, \underline{929}, \underline{930}, \underline{1001}, \underline{1012}, \underline{1078}, \underline{1107}, \underline{1150}, \underline{1165}, \underline{1218}, \underline{1224}, \underline{1296}, \underline{1321}, \underline{1324}, \underline{1382}, \underline{1407}, \underline{1460}, \underline{1484}, \underline{1490}, \underline{1492}, \underline{1501}, \underline{1504}, \underline{1506}, \underline{1515}, \underline{1516}, \underline{1517}, \underline{1519}, \underline{1529}, \underline{1531}.

i max : \underline{1321}. i min: \underline{1321}. i type: 66, \underline{68}, 69. Icosahedron: 702, 1470, \underline{1508}, 1509, 1511, \underline{1512},

1514, \underline{1515}, 1517, 1519. : \underline{236}, \underline{237}. ifstream: 78, 79. in angle: \underline{1224}. in circle: 1068, \underline{1089}, \underline{1307}, 1309. in distance: \underline{1267}.

in ellipse: \underline{1136}, \underline{1268}, 1270.
in rectangle: \underline{1259}, \underline{1260}, 1264.
in stream: \underline{78}, \underline{79}, 81, 83, 1556, 1557.
in stream name: \underline{81}, \underline{82}, 83.
initialize colors : \underline{151}, \underline{152}, 156, 1557.
initialize io: \underline{81}, \underline{82}, 1556, 1557.
inner circle: \underline{1324}, \underline{1327}.
internal angle: \underline{1069}, 1071, 1077, 1078.
intersection ctr : \underline{1224}, 1225.
intersection line: 638, \underline{687}, \underline{688}, 1043, 1227.
intersection point : 49, 317, 571, \underline{572}, \underline{573}, \underline{574},

\underline{647}, 648, \underline{684}, \underline{685}, \underline{686}, \underline{964}, \underline{965}, \underline{966}, 997, 1007, 1032, 1034, 1041, 1485, 1491, 1492. intersection points : 313, 572, 688, 996, \underline{997}, \underline{998}, \underline{1008}, \underline{1009}, \underline{1028}, \underline{1029}, 1035, \underline{1037}, \underline{1038}, \underline{1039}, \underline{1040}, 1043, 1202, \underline{1208}, \underline{1209}, \underline{1210}, \underline{1211}, 1212, 1213, \underline{1214}, \underline{1215}, 1218, 1227, 1228, 1260, 1267, 1299, \underline{1300}, \underline{1301}, \underline{1302}, \underline{1303}, \underline{1304}, \underline{1305}, \underline{1473}, \underline{1474}.

ints : 711.

: 316, 318, \underline{319}, \underline{320}, 580,

584, 585, 647, 685, 965, 966. : \underline{319}, \underline{320}, 998, 999,

1006, 1007, 1009, 1029, 1030, 1033, 1038, 1211. : \underline{319}, \underline{320}, 1215, 1218, 1221, 1223, 1224, 1225, 1226, 1305.

: \underline{319}, \underline{320}, 650. : \underline{654}, \underline{655}, 688, 976, 977. : 927. : 663, 667, 690, \underline{691}, \underline{692}, 947,

948, 993. : 27, 314, 318, \underline{319}, \underline{320}, 394, 476, 506, 551, 552, 562, 571, 580, 585, 647, 649, 651, 654, 667, 668, 685, 691, 917, 933, 935, 937, 940, 941, 942, 944, 945, 947, 995, 996, 999, 1002, 1003, 1004, 1005, 1023, 1025, 1030, 1032, 1043, 1126, 1128, 1164, 1165, 1183, 1185, 1201, 1202, 1218, 1223, 1227, 1231, 1260, 1369, 1370, 1481, 1497, 1498, 1512, 1526. : 15, 18, \underline{19}, 27, 28, \underline{29}, 32, 236,

318, 319, 361, 390, 391, 393, 394, 395, 399, 426, 429, 431, 445, 496, 547, 549, 562, 577, 578, 579, 580, 582, 583, 584, 585, 667, 668, 885, 887, 923, 924, 990, 991, 993, 1002, 1003, 1004, 1005, 1190, 1193, 1195, 1198, 1200, 1206, 1222, 1223, 1231, 1232, 1481, 1497, 1498, 1512, 1526.

: \underline{28}, \underline{29}, 1172.

: 27, \underline{28}, \underline{29}.

: 27, 228, \underline{236}, \underline{237}, 759, 760,

765, 791, 793, 1053, 1255. inverse: \underline{226}, \underline{227}, \underline{232}, \underline{233}, 439, 605, 616, 1005,

1221, 1267, 1268, 1307, 1311. invert : 232. ios : 83, 1553. ios base: 83. ip: 66, \underline{69}, 70. is big endian: 36, \underline{38}, \underline{39}. is circular : \underline{1295}, \underline{1296}. is cubic: \underline{988}, \underline{1167}, \underline{1168}. is cycle: 806, 907, \underline{921}, 956. is ellipse: 1190. is elliptical : \underline{1164}, \underline{1165}, 1193, 1195, 1198, 1200,

1231, 1232, 1233. is identity : \underline{185}, \underline{186}, \underline{187}, \underline{188}, 219, 328, \underline{349},

443, 449, 516, 593, 597. is in triangle: \underline{401}, \underline{948}, 1035. is line: 920, 923. is linear : 759, 764, 765, 792, 793, \underline{918}, \underline{919}, 920,

923, 924, 964, 965, 966, 977, 1009, 1038, 1053, 1210, 1211, 1255.

is little endian: 36, \underline{40}, \underline{41}. is on free store: \underline{138}, \underline{139}, \underline{245}, \underline{387}, \underline{388}, 727, 729,

741, 746, \underline{914}, \underline{915}, \underline{1379}, \underline{1380}. is on line: 393, \underline{398}, \underline{399}. is on plane: \underline{400}, \underline{681}, 948, 1206. is on segment : \underline{393}, \underline{394}, \underline{396}, \underline{397}, 399, 585, 647,

1005, 1007, 1032, 1034, 1035, 1043. is open: 150, 152. is parallel : 1122. is planar : \underline{916}, \underline{917}, 945, 986, 1086, 1123, 1295,

1296, 1307, 1311. is quadratic: \underline{987}, 1004, \underline{1166}. is quartic: \underline{989}, \underline{1169}, \underline{1170}. is rectangular : \underline{1122}, \underline{1123}. is 32 bit : \underline{45}, \underline{46}. is 64 bit : \underline{47}, \underline{48}. isect line: \underline{1227}. : \underline{256}, \underline{257}. iter : 294, 587, 589, 590, 593, 594, 595, 596, 703,

727, 777, 782, 784, 786, 808, 809, 813, 814, 873, 883, 886, 942, 944, 958, 1032, 1034, 1041, 1161, 1165, 1296, 1324, 1339, 1346, 1347, 1382, 1384, 1387, 1389, 1405, 1407, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1431, 1433, 1434, 1436, 1437, 1439, 1458, 1465, 1502, 1506, 1515, 1519, 1529.

iter ctr : \underline{1327}. iterator : 294, 590, 593, 597, 703, 727, 777, 782,

784, 786, 883, 886, 902, 958, 1324, 1327, 1346, 1384, 1387, 1389, 1405, 1407, 1420, 1465, 1474, 1502, 1506, 1515, 1519, 1529.

iter0 : 1474. iter1 : 1474. j: \underline{171}, \underline{175}, \underline{177}, \underline{181}, \underline{186}, \underline{188}, \underline{193}, \underline{217}, \underline{219}, \underline{227},

\underline{443}, \underline{449}, \underline{496}, \underline{1321}, \underline{1324}, \underline{1504}, \underline{1517}. k: \underline{219}, \underline{227}, \underline{1321}. kill labels : \underline{276}, \underline{277}. known: \underline{1171}, \underline{1172}, 1173. l: \underline{641}, \underline{642}, \underline{643}, \underline{644}, \underline{645}, \underline{648}, \underline{649}, \underline{1043}. l p: \underline{647}. l q : \underline{647}. label : 252, 254, \underline{272}, \underline{273}, 309, 310, \underline{505}, \underline{506}, \underline{507},

\underline{508}, 509, 511, 513, 871, \underline{872}, \underline{873}, \underline{874}, \underline{875}, 878, 967, 972, \underline{1160}, \underline{1161}, 1162, 1484, 1492, 1506, 1515, 1517, 1519.

Label: \underline{253}, 254, 255, 261, 267, 272, 273, 309, 505, 506, \underline{514}, 515, 516, 587, 589, 590, 597, 873, 967, 1161.

Labels: 241, 252, 253, 254, 261, 596. labels : \underline{261}, 266, 273, 277, 294, \underline{506}, 587, 589,

590, 592, 597. lambda: \underline{950}. lambda denominator : \underline{948}, 950. last connector : \underline{806}, 807, \underline{813}, \underline{957}. lbl : \underline{506}, \underline{515}, \underline{587}. : 5, 6, 7, 8, 14, 24, 25, 1552. : 5, 6, \underline{7}, 14. : 5, \underline{7}. ldf real double: \underline{21}, \underline{22}, \underline{23}, 1546. : \underline{15}, 19, 22, 183, 351. : \underline{15}, 19, 22. ldf real float : \underline{21}, \underline{22}, \underline{23}, 1546. left : 193. left shift : \underline{1321}. light gray : 152, \underline{156}, \underline{157}. limit : \underline{1326}, \underline{1327}. Line: \underline{49}, 317, 352, 572, 635, \underline{637}, 638, 639,

\underline{640}, 641, \underline{642}, 643, 644, 645, 646, 647, 648, 649, 653, 654, 655, 687, 688, 706, 964, 976, 977, 978, 1043, 1227.

line switch: \underline{698}, 701, 705, 708, 710, 713, 715, 718, 720, 918, 919, 920, 1074, 1104, 1107, 1112, 1147, 1150, 1279, 1282.

linear eccentricity : \underline{1143}, 1149, 1150, 1187,

1231, 1232. Lines: 572, 635, 638, 647, 996, 1214. localtime: 82. location: \underline{992}, \underline{993}, 997, 1007, \underline{1205}, \underline{1206}, 1223,

1224, 1227. location switch: \underline{1224}. Long : \underline{37}. : \underline{68}. long options : \underline{1549}. loop ctr : \underline{910}. lt : \underline{82}. M: \underline{1267}, \underline{1268}. m: \underline{389}, \underline{390}, \underline{552}. mag : \underline{549}, \underline{1206}, \underline{1295}, \underline{1296}. magenta: 152, \underline{156}, \underline{157}, 1502, 1546. magnitude: 19, 432, \underline{546}, \underline{547}, 549, 551, 552,

601, 649, 993, 1112, 1165, 1193, 1195, 1198, 1200, 1205, 1206, 1232, 1267, 1268, 1295, 1296, 1305, 1307, 1485.

mag0 : \underline{1295}, \underline{1296}. main: 19, \underline{1555}. make tabs : \underline{1491}, \underline{1492}, \underline{1505}, \underline{1506}, \underline{1518}, \underline{1519}. Matrix: \underline{15}, 166, 216, 219. matrix : \underline{166}, 170, 171, 172, 173, 174, 175, 177,

179, 180, 181, 182, 186, 188, 191, 193, 196, 198, 201, 203, 204, 207, 208, 209, 217, 219, 227, 228, 229, 230, 231, 449, 625, 628.

max : 19, 66, \underline{227}, 228, 886, 1202, 1205, 1206,

1218, 1305, 1407. max ax : \underline{1206}. max hexagons : \underline{1320}, \underline{1321}. : 15, 18, \underline{19}, \underline{21}, 547, 886, 887, 1546. : \underline{19}, \underline{21}, 547, 1546. : 66, 68, 69, 70, \underline{71}, \underline{72}. max x proj : 297, \underline{298}, \underline{299}, 591, \underline{592}, 595, \underline{598}. max y proj : \underline{298}, \underline{299}, \underline{592}, 595, \underline{598}. : \underline{258}, \underline{259}, 298, 299, 497, 591, 596. max z proj : \underline{298}, \underline{299}, \underline{592}, 595, \underline{598}. : \underline{258}, \underline{259}, 497, 596. measurement units : \underline{309}, \underline{310}, 481, 502, 516. mediate: \underline{555}, \underline{556}, 1112, 1127, 1128, 1307, 1484,

1486, 1492, 1502, 1515, 1519. mid point : 1127. mid pt : \underline{1307}. min: 18, 886, 1305, 1407. : 886, 887. min x proj : 297, \underline{298}, \underline{299}, 591, \underline{592}, 595, \underline{598}. min y proj : \underline{298}, \underline{299}, \underline{592}, 595, \underline{598}. : \underline{258}, \underline{259}, 497, 591, 596. min z proj : \underline{298}, \underline{299}, \underline{592}, 595, \underline{598}. modify : \underline{127}, \underline{128}. move back : \underline{1321}. mu: \underline{950}. mu denominator : \underline{948}, 950. mx : \underline{688}. my : \underline{688}. mz : \underline{688}. n: \underline{99}, \underline{100}, \underline{102}, \underline{103}, \underline{104}, \underline{105}, \underline{227}, \underline{389}, \underline{390},

\underline{667}, \underline{668}. name: \underline{95}, 98, 100, 103, 105, 106, 108, 110, 115,

116, 124, 146, 150, 1549. new coordinates : \underline{449}. nnumber of points : \underline{1149}, \underline{1150}, \underline{1151}, \underline{1152}, \underline{1281},

\underline{1282}, \underline{1283}, \underline{1284}. : \underline{258}, \underline{259}, 497, 591. non stop: 502, 906. normal : \underline{649}, 650, \underline{661}, 663, 664, 667, 668, 670, 673, 678, 685, 688, 690, \underline{947}, 998, 999, 1000, 1007, \underline{1012}, 1029, 1030, 1031, 1034, 1040, 1164, \underline{1165}, \underline{1202}, 1215, 1217, 1218, 1220, \underline{1267}, \underline{1268}, \underline{1305}, \underline{1307}, \underline{1311}, \underline{1324}, \underline{1327}.

normal point : \underline{1217}, 1218.

normal unit : \underline{649}. normal x : \underline{1220}, 1221. normal y : \underline{1220}, 1221. normal z : \underline{1220}, 1221. null coordinates : \underline{18}, \underline{26}, 322, 323, 443. number of points : \underline{985}, 992, 993, 1001, 1011, 1012, 1150, 1158, 1165, 1193, 1195, 1218, 1221, 1232, 1258, 1282.

number of polygon types : \underline{1472}, 1481, 1484, 1498,

1501, 1512, 1515, 1526, 1529. numerator : \underline{685}, \underline{1222}. numeric limits: 18, 19, 26, 66, 310, 886. numerical eccentricity : \underline{1143}, 1149, 1150, 1189,

1231, 1232. nx : \underline{688}. ny : \underline{688}. nz : \underline{688}. obj : 57, 59. offset : \underline{1321}. offsets : \underline{1323}, \underline{1324}. ofstream: 78, 79. old axis h: \underline{1232}. old axis v : \underline{1232}. on free store: \underline{95}, 98, 100, 103, 108, 110, 122, 139, \underline{309}, 325, 328, 332, 335, 343, 388, 476, \underline{698}, 700, 705, 708, 713, 715, 718, 720, 722, 733, 915, \underline{1069}, 1074, 1077, \underline{1101}, 1104, 1107, 1112, 1147, 1150, 1279, 1282, \underline{1333}, 1336, 1337, 1339, 1351, 1382, 1456, 1458, 1460, 1481, 1484, 1498, 1501, 1512, 1515, 1526, 1529.

on segment : 997, \underline{1005}.

open: 83. optarg : 1549. optind : 1549. option: 1549. option ctr : \underline{1549}. option index : \underline{1549}. orange: 152, \underline{156}, \underline{157}, 1484, 1502, 1546. orange red : \underline{156}, \underline{157}. orientation: \underline{993}, \underline{1221}, 1223. origin: \underline{319}, \underline{320}, 425, 551, 639, 649, 663, 664, 667, 668, 679, 688, 917, 919, 940, 943, 944, 947, 968, 973, 993, 999, 1030, 1123, 1150, 1212, 1218, 1219, 1222, 1267, 1268, 1307, 1311, 1324, 1327, 1352, 1486, 1490, 1502, 1504, 1515, 1517, 1529, 1531.

ostream: 147, \underline{148}, 480, \underline{481}. : \underline{1221}. out angle: \underline{1224}. out circle: 1068, \underline{1093}, \underline{1311}, 1313. out distance: \underline{1267}. out ellipse: \underline{1135}, \underline{1267}, 1269. out rectangle: \underline{1257}, \underline{1258}, 1260, 1262. out stream: \underline{78}, \underline{79}, 83, 85, 87, 89, 106, 150, 152,

309, 458, 480, 501, 502, 505, 516, 899, 902, 904, 905, 906, 907, 1438, 1557.

out stream name: \underline{81}, \underline{82}, 83. outer circle: \underline{1324}, \underline{1327}. outer circle center : \underline{1324}, \underline{1327}. output : 84, 106, \underline{245}, \underline{255}, 258, 297, \underline{298}, \underline{299}, 309,

359, 441, 480, 482, 484, 486, 497, \underline{501}, \underline{502}, \underline{516}, \underline{592}, 593, 595, 596, 597, \underline{598}, 698, 700, 834, 882, 884, 887, 895, 897, \underline{899}, \underline{900}, 901, 1388, \underline{1419}, \underline{1420}, 1547.

P: \underline{1305}. p: \underline{32}, \underline{202}, \underline{212}, \underline{227}, \underline{265}, \underline{267}, \underline{269}, \underline{285}, \underline{330}, \underline{331},

\underline{332}, \underline{333}, \underline{334}, \underline{336}, \underline{337}, \underline{340}, \underline{341}, \underline{358}, \underline{363}, \underline{386}, \underline{389}, \underline{390}, \underline{400}, \underline{414}, \underline{415}, \underline{416}, \underline{417}, \underline{421}, \underline{422}, \underline{438}, \underline{463}, \underline{464}, \underline{466}, \underline{467}, \underline{480}, \underline{481}, \underline{521}, \underline{522}, \underline{523}, \underline{524}, \underline{525}, \underline{526}, \underline{527}, \underline{528}, \underline{534}, \underline{535}, \underline{542}, \underline{543}, \underline{544}, \underline{545}, \underline{548}, \underline{549}, \underline{555}, \underline{556}, \underline{557}, \underline{560}, \underline{561}, \underline{567}, \underline{568}, \underline{569}, \underline{570}, \underline{587}, \underline{588}, \underline{589}, \underline{665}, \underline{666}, \underline{667}, \underline{668}, \underline{669}, \underline{670}, \underline{672}, \underline{673}, \underline{674}, \underline{675}, \underline{677}, \underline{678}, \underline{681}, \underline{686}, \underline{700}, \underline{701}, \underline{721}, \underline{722}, \underline{724}, \underline{725}, \underline{731}, \underline{759}, \underline{760}, \underline{764}, \underline{765}, \underline{773}, \underline{774}, \underline{778}, \underline{779}, \underline{819}, \underline{823}, \underline{824}, \underline{832}, \underline{833}, \underline{845}, \underline{850}, \underline{856}, \underline{864}, \underline{867}, \underline{917}, \underline{919}, \underline{923}, \underline{926}, \underline{935}, \underline{945}, \underline{960}, \underline{961}, \underline{962}, \underline{966}, \underline{978}, \underline{1008}, \underline{1009}, \underline{1012}, \underline{1025}, \underline{1037}, \underline{1038}, \underline{1052}, \underline{1053}, \underline{1061}, \underline{1062}, \underline{1066}, \underline{1067}, \underline{1070}, \underline{1071}, \underline{1081}, \underline{1180}, \underline{1185}, \underline{1205}, \underline{1206}, \underline{1210}, \underline{1211}, \underline{1244}, \underline{1245}, \underline{1249}, \underline{1250}, \underline{1254}, \underline{1255}, \underline{1286}, \underline{1295}, \underline{1296}, \underline{1302}, \underline{1303}, \underline{1347}, \underline{1483}, \underline{1484}, \underline{1487}, \underline{1488}, \underline{1492}, \underline{1500}, \underline{1501}, \underline{1505}, \underline{1506}, \underline{1514}, \underline{1515}, \underline{1519}, \underline{1528}, \underline{1529}, \underline{1547}.

p inner : \underline{1321}. p inner copy : \underline{1321}. p iter : 701. p m coord : \underline{390}, 391. p mag : \underline{549}. p middle: \underline{1321}. p middle copy : \underline{1321}. p n coord : \underline{390}, 391. p outer : \underline{1321}. p outer copy : \underline{1321}. p x : \underline{561}, 562, 563, 564, 565, 566. p x sign: \underline{565}. p y : \underline{561}, 562, 563, 564, 565, 566. p y sign: \underline{565}. p z : \underline{561}, 562, 563, 564, 565, 566. p z sign: \underline{565}. pa: \underline{469}, \underline{470}, \underline{800}, \underline{805}, \underline{806}, 807, 808, 809, \underline{810},

\underline{811}, \underline{812}, \underline{813}, 814, \underline{823}, \underline{832}, \underline{841}, \underline{860}, \underline{964}, \underline{965}. pair: 15, 31, 312, 315, 394, 395, 991. pairs: 315. : 444. : \underline{256}, \underline{257}, 444. : \underline{256}, \underline{257}, 444. : \underline{256}, \underline{257}, 444. Path: \underline{49}, 212, 241, 335, 359, 401, 438, 453, 462,

463, 464, 466, 467, 469, 470, 471, 472, 473, 480, 557, 571, 593, 646, 663, 685, 686, \underline{698}, 699, 700, 701, 702, 704, \underline{705}, 707, \underline{708}, 710, 711, 712, \underline{713}, 715, 717, 718, 720, 721, \underline{722}, 724, 725, \underline{726}, \underline{727}, 728, 729, 731, 733, 736, 739, 741, 744, 746, 748, 750, 752, 757, 759, 760, 763, 764, 765, 767, 769, 772, 774, 775, 777, 779, 782, 784, 786, 790, 791, 793, 795, 797, 798, 799, 800, 802, 805, 806, 809, 810, 811, 812, 813, 814, 819, 820, 821, 822, 823, 824, 828, 830, 832, 833, 834, 837, 839, 841, 842, 845, 847, 848, 850, 852, 856, 858, 860, 861, 864, 867, 869, 873, 875, 878, 880, 882, 883, 884, 885, 890, 892, 894, 896, 898, 899, 900, 901, 903, 905, 907, 910, 912, 915, 917, 918, 919, 923, 924, 925, 926, 927, 930, 933, 935, 937, 940, 941, 942, 945, 947, 948, 953, 955, 956, 959, 960, 961, 962, 964, 965, 966, 977, 978, 985, 986, 992, 1008, 1009, 1011, 1012, 1013, 1014, 1019, 1037, 1038, 1045, 1046, 1052, 1053, 1065, 1069, 1070, 1071, 1081, 1085, 1086, 1118, 1120, 1121, 1122, 1124, 1156, 1158, 1203, 1210, 1211, 1232, 1248, 1254, 1255, 1258, 1288, 1299, 1302, 1303, 1321, 1324, 1327, 1333, 1339, 1346, 1347, 1362, 1363, 1382, 1384, 1387, 1388, 1389, 1405, 1407, 1419, 1420, 1424, 1427, 1430, 1433, 1436, 1438, 1439, 1492, 1505, 1519, 1524, 1563.

: \underline{1333}, \underline{1334}, 1356, 1357. Paths: 252, 593, 700, 706, 806, 808, 871, 882,

916, 920, 923, 964, 1419. paths : \underline{1333}, 1339, 1346, 1347, 1356, 1357, 1363,

1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1431, 1433, 1434, 1436, 1437, 1439.

pa0 : \underline{1258}. pen: \underline{309}, 323, 341, 344, 453, 455, 459, 502, 505,

509, \underline{698}, 701, 702, 705, 708, 710, 713, 715, 718, 720, 750, 819, 845, 850, 856, 864, 867, 902, 904, 905, 906.

pen inner : \underline{1320}, \underline{1321}. pen middle: \underline{1320}, \underline{1321}. pen outer : \underline{1320}, \underline{1321}. pentagon diameter : \underline{1500}, \underline{1501}, \underline{1503}, \underline{1504},

\underline{1505}, \underline{1506}. pentagon radius : \underline{1494}, 1498, 1501. pents : \underline{1504}. persp: \underline{600}, 603, 605, 614, 616, 618, 627, 629. : \underline{256}, \underline{257}, 298, 299, 355, 357, 360, 362,

365, 367, 370, 372, 375, 377, 380, 382, 442, 446, 475, 909, 1381.

persp transform: 441. phi : \underline{1324}, \underline{1327}. : 27, \underline{28}, \underline{29}, \underline{52}, 207, 208, 209, 549, 1150, 1305,

1478, 1484, 1495, 1501, 1509, 1515, 1523, 1529. picture: 453, \underline{454}, \underline{455}, \underline{456}, \underline{457}, \underline{458}, \underline{459}, \underline{460},

\underline{461}, \underline{463}, \underline{464}, \underline{466}, \underline{467}, \underline{469}, \underline{470}, \underline{472}, \underline{473}, \underline{505}, \underline{506}, \underline{507}, \underline{508}, \underline{510}, \underline{511}, \underline{512}, \underline{513}, \underline{818}, \underline{819}, \underline{820}, \underline{821}, \underline{823}, \underline{824}, \underline{827}, \underline{828}, \underline{829}, \underline{830}, \underline{832}, \underline{833}, \underline{836}, \underline{837}, \underline{838}, \underline{839}, \underline{841}, \underline{842}, \underline{844}, \underline{845}, \underline{846}, \underline{847}, \underline{849}, \underline{850}, \underline{851}, \underline{852}, \underline{855}, \underline{856}, \underline{857}, \underline{858}, \underline{860}, \underline{861}, \underline{863}, \underline{864}, \underline{866}, \underline{867}, \underline{868}, \underline{869}, \underline{872}, \underline{873}, \underline{874}, \underline{875}, \underline{877}, \underline{878}, \underline{879}, \underline{880}, \underline{968}, \underline{969}, 972, \underline{973}, \underline{974}, \underline{1091}, \underline{1092}, \underline{1095}, \underline{1096}, \underline{1137}, \underline{1138}, \underline{1160}, \underline{1161}, \underline{1162}, \underline{1261}, \underline{1262}, \underline{1263}, \underline{1264}, \underline{1269}, \underline{1270}, \underline{1309}, \underline{1310}, \underline{1313}, \underline{1314}, \underline{1320}, \underline{1321}, \underline{1423}, \underline{1424}, \underline{1426}, \underline{1427}, \underline{1429}, \underline{1430}, \underline{1432}, \underline{1433}, \underline{1435}, \underline{1436}, \underline{1438}, \underline{1439}.

Picture: \underline{49}, 241, 245, \underline{253}, 254, 258, \underline{261}, 263, \underline{264}, 265, 266, 267, 269, 271, 273, 274, 277, 278, 281, 284, 287, 290, 292, 294, 296, 297, 302, 303, 309, 417, 440, 441, 444, 453, 454, 455, 456, 457, 458, 459, 460, 461, 463, 464, 466, 467, 469, 470, 472, 473, 482, 484, 486, 497, 501, 505, 506, 507, 508, 510, 511, 512, 513, 587, \underline{588}, 589, 590, 592, 595, 596, 597, 598, 698, 728, 818, 819, 820, 821, 823, 824, 827, 828, 829, 830, 832, 833, 836, 837, 838, 839, 841, 842, 844, 845, 846, 847, 849, 850, 851, 852, 855, 856, 857, 858, 860, 861, 863, 864, 866, 867, 868, 869, 872, 873, 874, 875, 877, 878, 879, 880, 882, 884, 887, 895, 897, 899, 901, 968, 969, 973, 974, 1091, 1092, 1095, 1096, 1137, 1138, 1160, 1161, 1162, 1261, 1262, 1263, 1264, 1265, 1269, 1270, 1309, 1310, 1313, 1314, 1320, 1321, 1348, 1388, 1419, 1423, 1424, 1426, 1427, 1429, 1430, 1432, 1433, 1435, 1436, 1438, 1439, 1491.

Pictures: 166, 252, 254, 261, 278, 309, 728, 1336. pink : \underline{156}, \underline{157}. pl : \underline{687}, \underline{688}, \underline{993}, \underline{998}, 999, 1000, 1007, \underline{1029},

1030, 1031, 1034, \underline{1040}, 1043. pl normal : \underline{688}. Plane: 15, \underline{49}, 400, 638, 659, \underline{661}, 663, \underline{664}, 665,

\underline{666}, 667, \underline{668}, 669, 670, 672, 673, 674, 675, 677, 678, 679, 680, 681, 685, 687, 688, 690, 691, 692, 946, 947, 948, 966, 992, 993, 997, 998, 1029, 1040, 1215, 1305.

Planes: 659, 688, 1214. Point: 2, 19, \underline{49}, \underline{166}, 194, 202, 211, 213, 241,

244, 245, \underline{253}, 255, 269, 285, 288, 307, \underline{309}, 310, 312, 313, 317, 319, 320, 323, 324, \underline{325}, 327, \underline{328}, 329, 330, 331, \underline{332}, 333, 334, 335, 336, 337, \underline{338}, \underline{339}, 340, 341, 343, 345, 347, 351, 352, 356, 358, 361, 363, 366, 368, 371, 373, 376, 378, 381, 383, 386, 388, 389, 390, 393, 394, 395, 396, 397, 398, 399, 401, 405, 407, 409, 413, 414, 415, 416, 417, 420, 421, 422, 423, 424, \underline{425}, 426, 427, 430, 436, 437, 439, 440, 443, 446, 447, 448, 449, 451, 455, 457, 459, 461, 463, 464, 466, 467, 469, 470, 472, 473, 476, 478, 480, 481, 483, 485, 486, 487, 490, 492, 494, 496, 502, 505, 506, 507, 508, 509, 511, 513, 515, 516, 519, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 532, 533, 534, 535, 536, 537, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 551, 552, 553, 554, 555, 556, 557, 560, 561, 567, 568, 569, 570, 571, 572, 573, 574, 585, 593, 597, 600, 601, 609, 610, 611, 612, 620, 621, 623, 635, 637, 638, 639, 640, 645, 647, 648, 649, 650, 659, 661, 667, 668, 677, 678, 679, 681, 684, 685, 688, 698, 701, 703, 707, 708, 709, 710, 711, 713, 715, 716, 717, 718, 719, 720, 727, 760, 762, 763, 773, 774, 775, 777, 778, 779, 782, 784, 786, 791, 794, 795, 797, 798, 799, 800, 808, 813, 823, 824, 832, 833, 834, 841, 842, 860, 861, 871, 873, 882, 883, 886, 887, 899, 902, 910, 917, 919, 929, 930, 932, 933, 934, 935, 936, 937, 940, 941, 944, 945, 947, 948, 958, 964, 965, 967, 968, 969, 972, 973, 974, 978, 985, 992, 993, 994, 995, 996, 997, 998, 1001, 1008, 1009, 1011, 1012, 1019, 1022, 1023, 1024, 1025, 1028, 1029, 1032, 1034, 1039, 1040, 1041, 1043, 1050, 1051, 1061, 1062, 1066, 1067, 1076, 1077, 1078, 1079, 1080, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1122, 1123, 1125, 1126, 1127, 1128, 1143, 1149, 1150, 1151, 1152, 1161, 1164, 1165, 1177, 1178, 1179, 1180, 1182, 1183, 1184, 1185, 1201, 1202, 1205, 1206, 1208, 1209, 1210, 1216, 1217, 1218, 1221, 1222, 1224, 1227, 1232, 1244, 1245, 1249, 1250, 1252, 1253, 1258, 1267, 1268, 1281, 1282, 1283, 1284, 1293, 1295, 1296, 1299, 1300, 1301, 1305, 1307, 1311, 1321, 1324, 1325, 1327, 1333, 1353, 1354, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1397, 1398, 1401, 1402, 1459, 1460, 1473, 1474, 1483, 1484, 1485, 1487, 1488, 1490, 1491, 1492, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1514, 1515, 1517, 1519, 1528, 1529, 1531, 1547. point : \underline{661}, 663, 664, 667, 668, 670, 673, 678,

690, \underline{947}, 1029, 1201. point iter : 902, 904, 905, 906, 907. point on line: \underline{688}. point pair: \underline{312}. point ptr : \underline{718}, \underline{720}. Points: 2, 166, 182, 213, 252, 307, 309, 310, 335,

393, 423, 441, 446, 462, 486, 495, 562, 564, 571, 575, 593, 638, 646, 698, 706, 711, 764, 775, 807, 808, 812, 813, 871, 882, 884, 885, 899, 901, 907, 910, 920, 929, 930, 940, 942, 948, 957, 964, 992, 1011, 1043, 1068, 1122, 1164, 1210, 1214, 1295, 1388, 1491.

points : \underline{698}, 701, 703, 708, 710, 713, 715, 716, 718, 720, 727, 775, 777, 782, 784, 786, 791, 798, 800, 807, 808, 813, 819, 845, 850, 856, 864, 867, 873, \underline{882}, 883, 885, 886, 899, 901, 902, 905, 907, 909, 910, 922, 924, 925, 928, 929, 930, 933, 935, 937, 938, 941, 943, 944, 957, 958, 964, 965, 977, 1013, 1014, 1023, 1025, 1032, 1034, 1041, 1045, 1068, 1078, 1107, 1112, 1126, 1128, 1150, 1161, 1164, 1165, 1217, \underline{1295}, 1296, 1307, 1311.

points iter : 910. Polygon: 1017, \underline{1019}, 1021, 1023, 1025, 1027,

1029, 1032, 1038, 1039, 1040, 1044, 1046, 1048, 1051, 1053, 1055, 1057, 1060, 1062, 1065, 1067, 1069, 1099, 1101, 1124, 1333.

Polygons : 1043. polygons : 1333. polyhed : 1518. Polyhedra: 572, 1331, 1470, 1487, 1489. Polyhedron: 1333, 1369, 1470, \underline{1472}, 1474, 1477,

1481, 1487, 1494, 1498, 1508, 1512, 1522, 1526. pop back : 727. porting: 700. Porting: 907. portrait : \underline{1505}, \underline{1506}, \underline{1518}, \underline{1519}. pos : \underline{609}, \underline{610}, \underline{611}, \underline{612}, \underline{639}, \underline{640}, \underline{1160}, \underline{1161}, \underline{1162}. pos x : \underline{604}, \underline{605}, \underline{606}, \underline{607}, 967, \underline{968}, \underline{969}, 970,

971, 972, \underline{973}, \underline{974}. pos y : \underline{604}, \underline{605}, \underline{606}, \underline{607}, 967, \underline{968}, \underline{969}, 970,

971, 972, \underline{973}, \underline{974}. pos z : \underline{604}, \underline{605}, \underline{606}, \underline{607}, 967, \underline{968}, \underline{969}, 970,

971, 972, \underline{973}, \underline{974}. position: \underline{253}, 506, 515, 516, \underline{600}, 601, 603, 605,

614, 616, 618, 620, \underline{637}, 638, 640, 641, 642, 644, 645, 649, 650, 653, 978, 1043, 1227.

position str : \underline{505}, \underline{506}, \underline{507}, \underline{508}, \underline{510}, \underline{511}, \underline{512}, \underline{513}. position string : \underline{872}, \underline{873}, \underline{874}, \underline{875}, \underline{877}, \underline{878},

\underline{879}, \underline{880}. ppen: \underline{454}, \underline{455}, \underline{456}, \underline{457}, \underline{458}, \underline{459}, \underline{460}, \underline{461}, \underline{463},

\underline{464}, \underline{466}, \underline{467}, \underline{469}, \underline{470}, \underline{472}, \underline{473}, \underline{818}, \underline{819}, \underline{820}, \underline{821}, \underline{823}, \underline{824}, \underline{827}, \underline{828}, \underline{829}, \underline{830}, \underline{832}, \underline{833}, \underline{836}, \underline{837}, \underline{838}, \underline{839}, \underline{841}, \underline{842}, \underline{849}, \underline{850}, \underline{851}, \underline{852}, \underline{855}, \underline{856}, \underline{857}, \underline{858}, \underline{860}, \underline{861}, \underline{866}, \underline{867}, \underline{868}, \underline{869}, \underline{967}, \underline{968}, \underline{969}, 972, \underline{973}, \underline{974}, \underline{1091}, \underline{1092}, \underline{1095}, \underline{1096}, \underline{1137}, \underline{1138}, \underline{1261}, \underline{1262}, \underline{1263}, \underline{1264}, \underline{1269}, \underline{1270}, \underline{1309}, \underline{1310}, \underline{1313}, \underline{1314}, 1422, \underline{1423}, \underline{1424}, 1428, \underline{1429}, \underline{1430}, 1431, \underline{1432}, \underline{1433}, 1437, \underline{1438}, \underline{1439}.

ppt : \underline{313}, \underline{317}. pp0 : \underline{572}, \underline{647}. pp1 : \underline{572}, \underline{647}. precision: 68, 1485, 1553, 1554. program name: \underline{81}, \underline{82}, 83. proj : \underline{245}, \underline{255}, \underline{299}, \underline{355}, \underline{356}, \underline{357}, \underline{358}, \underline{360}, \underline{361},

\underline{362}, \underline{363}, \underline{365}, \underline{366}, \underline{367}, \underline{368}, \underline{370}, \underline{371}, \underline{372}, \underline{373}, \underline{375}, \underline{376}, \underline{377}, \underline{378}, \underline{380}, \underline{381}, \underline{382}, \underline{383}, \underline{442}, \underline{443}, 444, \underline{446}, \underline{447}, \underline{475}, \underline{476}, \underline{486}, \underline{487}, \underline{516}, \underline{592}, 593, 597, \underline{598}, \underline{785}, \underline{786}, \underline{882}, \underline{883}, \underline{909}, \underline{910}, \underline{1381}, \underline{1382}, \underline{1404}, \underline{1405}.

proj on x z plane: \underline{425}, 426, 427, 428, 430. : 309. : \underline{309}, \underline{310}, 507, 508, 872. : \underline{309}, \underline{310}, 507. project : 356, 359, 361, 441, \underline{442}, \underline{443}, \underline{446}, \underline{447},

475, 480, 486, 487, 488, 495, 501, 507, 516, \underline{785}, \underline{786}, 882, 884, 888, 1320, 1405.

projection: \underline{298}. Projections: \underline{256}, \underline{257}, 298, 299, 355, 357, 360,

362, 365, 367, 370, 372, 375, 377, 380, 382, 442, \underline{444}, 446, 475, 909, 1381, \underline{1546}.

projective coordinates : \underline{309}, 310, 323, 341, 345, 356, 361, 441, 443, 444, 445, 475, 480, 487, 496, 501, 502, 507, 884.

projective extremes : 297, \underline{309}, 323, 341, 488, 490, 492, 494, 496, 497, \underline{595}, \underline{698}, 700, 701, 705, 708, 710, 713, 715, 718, 720, 885, 886, 887, 888, 890, 892, 894, 1074, 1077, \underline{1333}, 1336, 1337, 1339, 1347, 1407, 1408, 1410, 1412, 1414, 1419, 1456, 1458, 1460.

pt : \underline{253}, 255, \underline{313}, 314, 315, \underline{317}, 318, \underline{352}, \underline{455}, \underline{459}, \underline{469}, \underline{470}, \underline{472}, \underline{473}, 506, 514, 515, 516, 585, 589, 590, 597, \underline{645}, 647, 649, 650, 651, 685, \underline{797}, \underline{798}, \underline{799}, \underline{800}, \underline{841}, \underline{842}, \underline{860}, \underline{861}, 1002, 1003, 1004, 1005, 1007, 1032, 1034, 1035, 1041, 1043, 1201, 1202, 1218, 1223, 1225, 1227, 1260, 1267, 1305, \underline{1397}, \underline{1398}, 1485, 1492.

pt c4 : \underline{993}. pt iter : 1474. pt on x axis : \underline{426}. pt on z axis : \underline{427}, 428, 430. pt vector : 997, \underline{998}, 999, 1000, 1007, \underline{1029}, 1030,

1031, 1034. ptr : \underline{1041}, \underline{1352}. pts : \underline{1460}, \underline{1484}, 1485, 1486, \underline{1490}, \underline{1492}, \underline{1501},

1502, \underline{1504}, \underline{1505}, \underline{1515}, \underline{1517}, \underline{1519}, \underline{1529}, \underline{1531}, 1532.

pt0 : \underline{194}, \underline{760}, \underline{992}, \underline{993}, \underline{998}, 1001, 1005, 1007, \underline{1028}, \underline{1029}, 1032, 1034, 1035, \underline{1111}, \underline{1112}, \underline{1113}, \underline{1114}, 1201, \underline{1202}, \underline{1209}, \underline{1218}, \underline{1227}, \underline{1258}, \underline{1300}, \underline{1301}, \underline{1321}.

pt0 h: \underline{993}, \underline{1001}, 1003, 1004. pt0 v : \underline{993}, \underline{1001}, 1002, 1004. pt1 : \underline{194}, \underline{760}, \underline{993}, \underline{998}, 1001, 1005, 1007, \underline{1028},

\underline{1029}, 1032, 1034, 1035, \underline{1111}, \underline{1112}, \underline{1113}, \underline{1114}, \underline{1209}, \underline{1218}, \underline{1258}, \underline{1300}, \underline{1301}.

pt1 h: \underline{1001}, 1003. pt1 v : \underline{1001}. pt2 : \underline{194}, \underline{1111}, \underline{1112}, \underline{1113}, \underline{1114}, \underline{1218}, \underline{1258}. pt20 : \underline{1222}, 1223. pt21 : \underline{1222}, 1223. pt22 : \underline{1222}, 1223. pt23 : \underline{1222}, 1223. pt3 : \underline{1111}, \underline{1112}, \underline{1113}, \underline{1114}, \underline{1218}, \underline{1258}. pt4 : \underline{1112}, \underline{1258}. pt5 : \underline{1112}, \underline{1258}. pt6 : \underline{1112}, \underline{1258}. pt7 : \underline{1112}, \underline{1258}. pt8 : \underline{1112}, \underline{1258}. pt9 : \underline{1258}. purple: 152, \underline{156}, \underline{157}. push back : 271, 273, 487, 587, 589, 593, 701, 708,

710, 713, 715, 718, 720, 752, 798, 800, 802, 807, 808, 809, 813, 814, 883, 929, 930, 957, 1041, 1043, 1078, 1107, 1112, 1150, 1324, 1339, 1347, 1405, 1419, 1420, 1458, 1460, 1474, 1490, 1502, 1504, 1515, 1517, 1529, 1531, 1532, 1546.

p0 : \underline{211}, \underline{213}, \underline{288}, \underline{393}, \underline{394}, 395, \underline{396}, \underline{397}, \underline{398}, \underline{399}, \underline{401}, 423, \underline{424}, 425, 433, \underline{436}, \underline{437}, \underline{439}, \underline{440}, 520, \underline{573}, \underline{574}, 575, 585, \underline{684}, \underline{685}, \underline{707}, \underline{708}, \underline{709}, \underline{710}, \underline{762}, \underline{763}, \underline{764}, \underline{791}, \underline{794}, \underline{795}, \underline{944}, \underline{948}, \underline{997}, \underline{1050}, \underline{1051}, \underline{1128}, \underline{1165}, \underline{1208}, \underline{1252}, \underline{1253}, \underline{1267}, \underline{1324}, \underline{1327}, \underline{1401}, \underline{1402}.

: \underline{1485}. p0 x : \underline{575}, 576, 579, 580, 582, 584. p0 y : \underline{575}, 576, 579, 580, 583. p0 z : \underline{575}, 576, 580, 582, 584. p1 : \underline{211}, \underline{213}, \underline{288}, \underline{393}, \underline{394}, 395, \underline{396}, \underline{397}, \underline{398},

\underline{399}, \underline{401}, 423, \underline{424}, 425, 426, 427, 429, 430, 431, 432, 433, \underline{436}, \underline{437}, \underline{439}, \underline{440}, \underline{573}, \underline{574}, 575, 585, \underline{684}, \underline{685}, \underline{707}, \underline{708}, \underline{709}, \underline{710}, \underline{762}, \underline{763}, 764, \underline{791}, \underline{794}, \underline{795}, \underline{944}, \underline{948}, \underline{997}, \underline{1050}, \underline{1051}, \underline{1128}, \underline{1208}, \underline{1252}, \underline{1253}, \underline{1401}, \underline{1402}.

: \underline{1485}. p1 x : \underline{575}, 576, 580, 584. p1 y : \underline{575}, 576, 580. p1 z : \underline{575}, 576, 580, 584. p2 : \underline{401}, \underline{944}, \underline{948}, \underline{1128}, \underline{1324}. : \underline{1485}. q: \underline{557}, \underline{560}, \underline{930}, \underline{945}, \underline{948}, \underline{1206}, \underline{1547}. q pl : \underline{948}. qq0 : \underline{572}, \underline{647}. qq1 : \underline{572}, \underline{647}. Quader : 1451. quarter : 49, 1010, \underline{1014}. q0 : \underline{573}, \underline{574}, 575, 585, \underline{1032}. q0 x : \underline{575}, 576, 579, 580, 582, 584. q0 y : \underline{575}, 576, 579, 580. q0 z : \underline{575}, 576, 580, 582, 584. q1 : \underline{573}, \underline{574}, 575, 585, \underline{1032}. q1 x : \underline{575}, 576, 580, 584. q1 y : \underline{575}, 576, 580. q1 z : \underline{575}, 576, 580, 584. r: \underline{102}, \underline{103}, \underline{104}, \underline{105}, \underline{107}, \underline{108}, \underline{109}, \underline{110}, \underline{127}, \underline{128},

\underline{129}, \underline{130}, \underline{170}, \underline{171}, \underline{178}, \underline{179}, \underline{216}, \underline{217}, \underline{221}, \underline{222}, \underline{317}, \underline{394}, \underline{529}, \underline{530}, \underline{532}, \underline{533}, \underline{535}, \underline{538}, \underline{539}, \underline{540}, \underline{541}, \underline{543}, \underline{545}, \underline{547}, \underline{555}, \underline{556}, \underline{566}, \underline{677}, \underline{678}, \underline{811}, \underline{813}, \underline{883}, \underline{945}, \underline{1039}, \underline{1040}, \underline{1083}, \underline{1084}, \underline{1109}, \underline{1114}, \underline{1165}, \underline{1172}, \underline{1175}, \underline{1258}, \underline{1262}, \underline{1264}, \underline{1267}, \underline{1307}, \underline{1473}, \underline{1474}, \underline{1531}.

r fabs : 677, \underline{678}. r iter : 1041. r pl : \underline{1040}, 1043. r ptr : \underline{1041}. radius : \underline{1069}, 1071, \underline{1077}, 1078, 1087, \underline{1276}, 1282,

1291, 1293, 1297, 1298, 1304, 1305, 1311. radius inner : \underline{1324}, 1326, \underline{1327}. radius known: \underline{1172}, 1173. radius outer : \underline{1324}, 1326, \underline{1327}. radius ratio: \underline{1326}. radius unknown: \underline{1172}, 1173. rcs id : \underline{5}, \underline{13}, \underline{53}, \underline{63}, \underline{76}, \underline{93}, \underline{164}, \underline{241}, \underline{250}, \underline{307},

\underline{635}, \underline{659}, \underline{696}, \underline{982}, \underline{1017}, \underline{1099}, \underline{1141}, \underline{1273},

\underline{1317}, \underline{1331}, \underline{1443}, \underline{1451}, \underline{1470}, \underline{1536}, \underline{1543}.

Real : 19, \underline{66}, 68, 69, 70. real: \underline{15}, 16, 18, 19, 21, 23, 26, 27, 28, 29, 31, 32,

52, 66, 95, 106, 107, 108, 109, 110, 127, 128, 129, 130, 131, 132, 133, 134, 140, 141, 142, 143, 170, 171, 172, 173, 178, 179, 181, 182, 183, 190, 191, 195, 196, 197, 198, 200, 201, 203, 204, 205, 206, 211, 212, 216, 217, 221, 222, 226, 227, 245, 255, 280, 281, 283, 284, 286, 287, 288, 297, 298, 299, 309, 310, 317, 327, 328, 329, 330, 347, 350, 351, 355, 356, 357, 358, 360, 361, 362, 363, 365, 366, 367, 368, 370, 371, 372, 373, 375, 376, 377, 378, 380, 381, 382, 383, 389, 390, 393, 394, 395, 404, 405, 406, 407, 408, 409, 412, 413, 419, 420, 423, 424, 433, 436, 437, 438, 439, 440, 442, 443, 445, 446, 447, 449, 475, 476, 486, 487, 488, 489, 490, 491, 492, 493, 494, 509, 516, 529, 530, 532, 533, 534, 535, 538, 539, 540, 541, 542, 543, 546, 547, 548, 549, 552, 555, 556, 561, 566, 575, 576, 577, 578, 579, 580, 582, 592, 594, 595, 598, 600, 603, 604, 605, 606, 607, 609, 610, 611, 612, 615, 616, 622, 625, 626, 628, 629, 650, 661, 677, 678, 680, 685, 688, 698, 756, 757, 759, 760, 762, 763, 764, 765, 766, 767, 768, 769, 771, 772, 776, 777, 785, 786, 882, 883, 886, 888, 889, 890, 891, 892, 893, 894, 909, 910, 923, 924, 940, 948, 950, 968, 969, 973, 974, 990, 991, 992, 993, 994, 995, 1001, 1004, 1011, 1012, 1013, 1014, 1040, 1047, 1048, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1059, 1060, 1064, 1065, 1069, 1076, 1077, 1079, 1080, 1087, 1101, 1106, 1107, 1108, 1109, 1130, 1131, 1132, 1133, 1143, 1149, 1150, 1151, 1152, 1165, 1171, 1172, 1174, 1175, 1186, 1187, 1188, 1189, 1192, 1193, 1194, 1195, 1197, 1198, 1199, 1200, 1201, 1202, 1206, 1214, 1215, 1216, 1220, 1222, 1224, 1232, 1235, 1236, 1237, 1238, 1239, 1240, 1242, 1243, 1247, 1248, 1252, 1253, 1254, 1255, 1267, 1268, 1276, 1281, 1282, 1283, 1284, 1293, 1295, 1296, 1297, 1298, 1304, 1305, 1307, 1320, 1321, 1323, 1324, 1326, 1327, 1333, 1381, 1382, 1390, 1391, 1392, 1393, 1395, 1396, 1399, 1400, 1401, 1402, 1404, 1405, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1453, 1459, 1460, 1472, 1477, 1478, 1483, 1484, 1485, 1487, 1488, 1489, 1490, 1491, 1492, 1494, 1495, 1500, 1501, 1503, 1504, 1505, 1506, 1508, 1509, 1514, 1515, 1516, 1517, 1518, 1519, 1522, 1523, 1528, 1529, 1530, 1531, 1556.

Real EQ UINT : \underline{68}. Real EQ ULONG : \underline{68}. Real EQ ULONG LONG : \underline{68}. Real EQ USHORT : \underline{68}. real limits : 18, \underline{19}, \underline{26}, 66. real pair: \underline{15}, 28, 29, 31, 32, 993, 1001, 1171,

1172. real short: \underline{15}, 28, 29, 677, 678, 679, 680, 992. Real SIZE : \underline{68}. real triple: \underline{16}, 990, 1004, 1174, 1175. reals: 15, 322. : \underline{1333}, \underline{1334}, 1356, 1357, 1369, 1370,

1376. Rectangle: 335, 1017, 1019, 1021, 1044, 1069,

1099, \underline{1101}, 1103, \underline{1104}, 1105, 1106, \underline{1107}, 1109, 1110, 1111, \underline{1112}, 1114, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1126, 1128, 1129, 1131, 1133, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1267, 1268, 1269, 1270, 1333, 1339, 1346, 1347, 1364, 1365, 1369, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1424, 1427, 1430, 1433, 1436, 1439, 1458, 1460, 1465, 1524, 1531.

rectangles : \underline{1333}, 1339, 1346, 1347, 1356, 1357, 1365, 1369, 1370, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1431, 1433, 1434, 1436, 1437, 1439, 1458, 1460, 1465.

Rectangles: 1120.

red : 152, \underline{156}, \underline{157}, 699, 1484, 1502, 1546.

red orange: 156.

red part : \underline{95}, 98, 100, 103, 105, 108, 110, 115,

116, 117, 128, 130, 141. ref pt : \underline{992}, \underline{993}, 996, \underline{997}, \underline{998}, 1001, 1007,

\underline{1008}, \underline{1009}. Reg Cl Plane Curve: 335, 984, \underline{985}, 986, 991, 992, 993, 995, 996, 997, 998, 1001, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1069, 1143, 1158, 1205, 1209.

Reg Cl Plane Curves: 985, 996.

: \underline{1333}, \underline{1334}, 1356, 1357, 1369,

1370, 1378. Reg Polygon: 335, 430, 1017, 1019, 1021, 1044, 1068, \underline{1069}, 1070, 1071, 1073, \underline{1074}, 1076, \underline{1077}, 1080, 1081, 1083, 1084, 1085, 1086, 1099, 1118, 1121, 1124, 1307, 1309, 1310, 1311, 1313, 1314, 1321, 1333, 1339, 1346, 1347, 1352, 1366, 1367, 1369, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1424, 1427, 1430, 1433, 1436, 1439, 1473, 1474, 1489, 1490, 1492, 1502, 1503, 1504, 1506, 1515, 1516, 1517, 1519, 1524, 1529, 1530, 1531, 1532. Reg Polygons: 702, 1321. reg polygons : \underline{1333}, 1339, 1346, 1347, 1356, 1357, 1367, 1369, 1370, 1382, 1384, 1387, 1389, 1405, 1407, 1419, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1431, 1433, 1434, 1436, 1437, 1439, 1474, 1484, 1485, 1486, 1501, 1502, 1515, 1529, \underline{1531}, 1532. Regular Closed Plane Curve: 984. reset : 169, \underline{176}, \underline{177}, 301, 323, 345, 449, 451, 589, 590, 597, 605, 616, 1165, 1492, 1529.

reset angle: \underline{615}, \underline{616}.

reset transform: 269, \underline{301}, \underline{450}, \underline{451}.

resize: 323, 443, 449, 701, 705, 708, 713, 718, 910, 1074, 1077, 1337, 1339, 1407, 1456, 1458, 1460.

result : \underline{69}, 70.

reverse: \underline{955}, \underline{956}, 958, \underline{959}, \underline{960}.
right shift : \underline{1321}.

rotate: 194, \underline{205}, \underline{206}, 209, \underline{211}, \underline{212}, 226, \underline{245}, \underline{286}, \underline{287}, \underline{288}, \underline{404}, \underline{405}, 423, 426, 429, 431, 432, 433, \underline{436}, \underline{437}, \underline{438}, \underline{439}, \underline{440}, 605, 616, \underline{756}, \underline{757}, \underline{759}, \underline{760}, \underline{762}, \underline{763}, \underline{764}, \underline{765}, 1001, 1012, \underline{1047}, \underline{1048}, \underline{1050}, \underline{1051}, \underline{1052}, \underline{1053}, 1078, 1107, 1150, 1165, 1202, 1212, 1218, \underline{1235}, \underline{1236}, \underline{1252}, \underline{1253}, \underline{1254}, \underline{1255}, 1267, 1268, 1305, 1324, 1327, \underline{1399}, \underline{1400}, \underline{1401}, \underline{1402}, 1460, 1484, 1486, 1492, 1502, 1503, 1504, 1506, 1515, 1517, 1519, 1529, 1531.

rotate around : 211, 212, 288, 423, 436, 438, 439, 440, 759, 760, 762, 764, 1050, 1052, 1252, 1254, 1401.

row : \underline{178}, \underline{179}, \underline{190}, \underline{191}, \underline{227}, 228, 229, \underline{625},

\underline{626}, \underline{628}, \underline{629}. row shift : \underline{1320}, \underline{1321}. rp: 68, 69, 70. rr : \underline{317}, \underline{993}, \underline{1001}, 1002, 1003, 1004, 1005. Run State: 502, 906. r0 : 992, \underline{993}, \underline{1034}, 1035, \underline{1260}. r0 0 : \underline{172}, \underline{173}. r0 1 : \underline{172}, \underline{173}. r0 2 : \underline{172}, \underline{173}. r0 3 : \underline{172}, \underline{173}. r1 : \underline{1034}, 1035, \underline{1260}. r1 0 : \underline{172}, \underline{173}. r1 1 : \underline{172}, \underline{173}. r1 2 : \underline{172}, \underline{173}. r1 3 : \underline{172}, \underline{173}. r2 : \underline{1260}. r2 0 : \underline{172}, \underline{173}. r2 1 : \underline{172}, \underline{173}. r2 2 : \underline{172}, \underline{173}. r2 3 : \underline{172}, \underline{173}. r3 0 : \underline{172}, \underline{173}. r3 1 : \underline{172}, \underline{173}. r3 2 : \underline{172}, \underline{173}. r3 3 : \underline{172}, \underline{173}. s: \underline{123}, \underline{124}, \underline{270}, \underline{271}, \underline{508}, \underline{678}, \underline{680}, \underline{735}, \underline{736}, \underline{747},

\underline{748}, \underline{749}, \underline{750}, \underline{751}, \underline{752}, \underline{801}, \underline{802}, \underline{930}, \underline{1007}, \underline{1161}, \underline{1182}, \underline{1183}, \underline{1184}, \underline{1185}, \underline{1338}, \underline{1339}, \underline{1345}, \underline{1346}, \underline{1349}, \underline{1356}, \underline{1357}, \underline{1358}, \underline{1359}, \underline{1360}, \underline{1361}, \underline{1362}, \underline{1363}, \underline{1364}, \underline{1365}, \underline{1366}, \underline{1367}, \underline{1369}, \underline{1370}, \underline{1371}, \underline{1372}, \underline{1373}, \underline{1374}, \underline{1375}, \underline{1376}, \underline{1377}, \underline{1378}, \underline{1419}, \underline{1420}, \underline{1424}, \underline{1427}, \underline{1430}, \underline{1433}, \underline{1436}, \underline{1439}.

s e: \underline{1227}, 1228. s t : \underline{1227}, 1228. save angle: \underline{1224}. save z : \underline{445}. scale: \underline{195}, \underline{196}, \underline{245}, \underline{280}, \underline{281}, \underline{406}, \underline{407}, \underline{766}, \underline{767},

\underline{1054}, \underline{1055}, \underline{1237}, \underline{1238}, 1267, 1295, \underline{1390}, \underline{1391}. scale value: \underline{1267}. second : \underline{16}, 32, \underline{315}, 316, 399, 647, 677, 681, 993,

998, 1002, 1003, 1004, 1005, 1029, 1032, 1043, 1173, 1174, 1175, 1201, 1202, 1218, 1223, 1225, 1227, 1260, 1267, 1305. second largest real : 70. segment : 49, 1010, \underline{1011}, \underline{1012}, 1013, 1014. set : \underline{104}, \underline{105}, \underline{109}, \underline{110}, \underline{329}, \underline{330}, \underline{333}, \underline{334}, 426, 427, 585, 605, \underline{606}, \underline{607}, \underline{611}, \underline{612}, 616, \underline{709}, \underline{710}, \underline{714}, \underline{715}, 719, 720, 1002, 1003, 1004, 1078, \underline{1079}, \underline{1080}, 1081, \underline{1108}, \underline{1109}, \underline{1113}, \underline{1114}, 1150, \underline{1151}, \underline{1152}, 1223, \underline{1283}, \underline{1284}, 1305, 1307, 1311, 1321, 1324, 1460, \underline{1487}, \underline{1488}, 1490, 1492, 1504, 1515, 1517, 1519, 1531.

set blue part : \underline{133}, \underline{134}.

set connectors : \underline{751}, \underline{752}, 945.
set cycle: 929, 930, \underline{952}, \underline{953}, 1012.
set dash pattern: \underline{747}, \underline{748}, 1422, 1425, 1428,

1431, 1434, 1437. set draw color : \underline{738}, \underline{739}, \underline{740}, \underline{741}, 1422, 1425,

1428, 1431, 1434, 1437. set element : 166, \underline{178}, \underline{179}, 603, 605, 616. set extremes : \underline{245}, \underline{495}, \underline{496}, 594, 596, \underline{884}, \underline{885},

901, \underline{1406}, \underline{1407}.

set fill color : \underline{743}, \underline{744}, \underline{745}, \underline{746}, 1422, 1425,

1428, 1431, 1434, 1437. set fill draw value: \underline{735}, \underline{736}, 1422, 1425, 1428,

1431, 1434, 1437. set green part : \underline{131}, \underline{132}. set minimum z : 495. set name: \underline{123}, \underline{124}. set on free store: 57, 59, \underline{121}, \underline{122}, \underline{245}, \underline{342}, \underline{343},

\underline{732}, \underline{733}, \underline{1350}, \underline{1351}. set pen: \underline{749}, \underline{750}, 1422, 1425, 1428, 1431, 1434,

1437. set red part : \underline{129}, \underline{130}. set transform: \underline{289}, \underline{290}. set use name: \underline{125}, \underline{126}. setf : 83, 1553. setprecision: 193. setw : 193. Shape: 241, \underline{244}, 245, 246, 261, 270, 271, 294,

309, 344, 385, 386, 455, 459, 482, 484, 486, 487, 497, 498, 499, 500, 501, 587, 589, 590, 591, 593, 594, 595, 596, 698, 728, 730, 731, 819, 845, 850, 856, 864, 867, 882, 883, 895, 897, 899, 1333, 1348, 1349, 1352, 1356, 1357, 1369, 1388, 1404, 1405, 1419, 1420, 1422, 1424, 1425, 1427, 1428, 1430, 1431, 1433, 1434, 1436, 1437, 1439, 1451.

shape type: \underline{1356}, \underline{1357}, \underline{1369}, \underline{1370}.

Shapes: 241, 252, 258, 297, 307, 497, 501, 589,

591, 593, 595, 635, 659, 728. shapes : \underline{261}, 266, 271, 294, \underline{453}, \underline{486}, \underline{501}, 587,

589, 590, 592, 593, 1348, 1419. shear : \underline{197}, \underline{198}, \underline{245}, \underline{408}, \underline{409}, \underline{768}, \underline{769}, \underline{1056}, \underline{1057}, \underline{1239}, \underline{1240}, 1295, \underline{1392}, \underline{1393}.

shift : \underline{200}, \underline{201}, \underline{202}, 226, \underline{245}, \underline{283}, \underline{284}, \underline{285}, \underline{412}, \underline{413}, \underline{414}, \underline{415}, \underline{416}, \underline{417}, 418, 425, 433, 522, 524, 526, 528, 605, 616, \underline{771}, \underline{772}, \underline{773}, \underline{774}, 775, 993, 1001, 1012, \underline{1059}, \underline{1060}, \underline{1061}, \underline{1062}, 1078, 1107, 1150, 1165, 1202, 1212, 1218, 1219, 1227, 1229, 1232, \underline{1242}, \underline{1243}, \underline{1244}, \underline{1245}, 1258, 1267, 1268, 1305, 1307, 1311, 1321, 1324, 1327, \underline{1395}, \underline{1396}, \underline{1397}, \underline{1398}, 1460, 1486, 1490, 1492, 1502, 1504, 1515, 1517, 1519, 1529, 1531, 1532.

shift times : \underline{203}, \underline{204}, 418, \underline{419}, \underline{420}, \underline{421}, \underline{422}, 775, \underline{776}, \underline{777}, \underline{778}, \underline{779}, \underline{1064}, \underline{1065}, \underline{1066}, \underline{1067}, \underline{1247}, \underline{1248}, \underline{1249}, \underline{1250}.

shift x : 967, \underline{968}, \underline{969}, 972, \underline{973}, \underline{974}. shift y : 967, \underline{968}, \underline{969}, 972, \underline{973}, \underline{974}. shift z : 967, \underline{968}, \underline{969}, 972, \underline{973}, \underline{974}. show : \underline{135}, \underline{136}, \underline{192}, \underline{193}, 204, 227, \underline{245}, \underline{293}, \underline{294},

296, 390, 394, 425, 426, 429, 431, 432, 433, \underline{475}, \underline{476}, 478, 547, 574, 585, 593, 605, \underline{617}, \underline{618}, 647, 649, 650, \underline{652}, \underline{653}, 688, \underline{689}, \underline{690}, 727, \underline{909}, \underline{910}, 912, 944, 948, 958, 993, 998, 999, 1001, 1002, 1005, 1007, 1029, 1030, 1032, 1034, 1040, 1165, 1215, 1217, 1218, 1221, 1223, 1224, 1227, 1267, 1268, 1305, \underline{1381}, \underline{1382}, 1485.

show colors : \underline{911}, \underline{912}. show transform: \underline{295}, \underline{296}, \underline{477}, \underline{478}. show transforms : \underline{617}, \underline{618}. : 310. side length: \underline{1531}. sides : \underline{1069}, 1071, 1077, 1078. silent : \underline{86}, \underline{87}, \underline{88}, \underline{89}, \underline{551}, \underline{552}, \underline{688}, 997, 1039. : \underline{20}, \underline{21}, 86, 87, 88, 89, 1549,

1552, 1557. : \underline{1549}. sin: 207, 208, 209, 1150. size: 82, 294, 590, 592, 593, 596, 700, 701, 703,

807, 808, 813, 819, 845, 850, 856, 864, 867, 873, 883, 885, 901, 902, 903, 905, 909, 910, \underline{922}, 928, 929, 930, 933, 935, 937, 938, 941, 943, 957, 1023, 1025, 1034, 1307, 1311, 1324, 1346, 1347, 1357, 1359, 1361, 1363, 1365, 1367, 1369, 1370, 1382, 1474, 1517.

Slope: \underline{1001}, 1002, 1003, 1004, \underline{1174}, \underline{1175}. slope: \underline{389}, \underline{390}, 391, \underline{923}, \underline{924}, 1001. slope p x y : \underline{577}, 579, 580, 581. slope p x z : \underline{577}, 582, 583, 584. slope p z y : \underline{577}, 580. slope q x y : \underline{578}, 579, 580, 581. slope q x z : \underline{578}, 582, 583. slope q z y : \underline{578}, 580. Solid: 453, 593, 700, \underline{1333}, 1334, 1336, \underline{1337},

1338, \underline{1339}, 1341, 1342, \underline{1343}, \underline{1344}, 1345, 1346, 1348, 1349, 1351, 1354, 1356, 1357, 1359, 1361, 1363, 1365, 1367, 1369, 1370, 1372, 1374, 1376, 1378, 1380, 1382, 1383, 1384, 1387, 1389, 1391, 1393, 1396, 1398, 1400, 1402, 1405, 1407, 1410, 1412, 1414, 1416, 1418, 1419, 1420, 1424, 1427, 1430, 1433, 1436, 1438, 1439, 1445, 1467, 1481, 1484, 1498, 1501, 1512, 1515, 1526, 1529. Solid Faced: \underline{1445}, 1453, 1472, 1481, 1484, 1498,

1501, 1512, 1515, 1526, 1529. Solids: 593, 1043, 1333, 1336. solve: \underline{991}, 993, 1002, 1003, \underline{1171}, \underline{1172}, 1205. solve quadratic: \underline{31}, \underline{32}, 1004. sort : 596, 1420. sort value: \underline{298}, \underline{299}, 497, \underline{591}, \underline{592}, 596, \underline{598}. Sorting: \underline{258}, \underline{259}, 298, 299, 497, 591, \underline{592}. Sphere: 1333. spiral : \underline{1324}, \underline{1327}. spiral counter : \underline{1324}, \underline{1327}. sqrt : 32, 547, 1150, 1173, 1222, 1232, 1305, 1546. ss copy : \underline{1223}. ss e: \underline{1223}. ssides : \underline{1076}, \underline{1077}, \underline{1079}, \underline{1080}, 1081. ssin: \underline{206}, 207, 208, 209. start : \underline{925}, \underline{926}, 927, 928, 929, 930. start pt : \underline{1327}. std: \underline{9}, \underline{11}, 958. stderr : 547, 967, 1231, 1267, 1268. stdout : 86, 88, 547, 909. step: 1212, \underline{1214}, \underline{1215}, 1224, \underline{1323}, \underline{1324}. stop: \underline{293}, \underline{294}, \underline{911}, \underline{912}. str : 507, 508, 1382. stream: 84. string: 5, 13, 22, 23, 53, 63, 76, 81, 82, 93, 95,

99, 100, 102, 103, 104, 105, 123, 124, 135, 136, 146, 164, 192, 193, 241, 245, 250, 253, 293, 294, 295, 296, 307, 309, 310, 454, 455, 456, 457, 458, 459, 460, 461, 463, 464, 466, 467, 469, 470, 472, 473, 475, 476, 477, 478, 505, 506, 507, 508, 510, 511, 512, 513, 617, 618, 635, 652, 653, 659, 689, 690, 696, 698, 699, 701, 711, 712, 713, 714, 715, 718, 720, 747, 748, 749, 750, 751, 752, 801, 802, 806, 809, 812, 813, 814, 818, 819, 820, 821, 823, 824, 827, 828, 829, 830, 832, 833, 836, 837, 838, 839, 841, 842, 849, 850, 851, 852, 855, 856, 857, 858, 860, 861, 866, 867, 868, 869, 872, 873, 874, 875, 877, 878, 879, 880, 902, 909, 910, 916, 917, 918, 919, 925, 926, 930, 942, 957, 958, 968, 969, 973, 974, 982, 1017, 1091, 1092, 1095, 1096, 1099, 1137, 1138, 1141, 1160, 1161, 1162, 1227, 1261, 1262, 1263, 1264, 1269, 1270, 1273, 1309, 1310, 1313, 1314, 1317, 1320, 1321, 1331, 1381, 1382, 1423, 1424, 1429, 1430, 1432, 1433, 1438, 1439, 1443, 1451, 1470, 1536, 1543, 1556.

strings: 505, 809, 814, 1321. stringstream: 508, 1382. subpath: \underline{925}, \underline{926}, 1012. subpath size: \underline{1011}, \underline{1012}. suppress labels : 261, \underline{274}. suppress output : \underline{245}, \underline{482}, \underline{483}, 594, 595, 596,

\underline{895}, \underline{896}, \underline{1415}, \underline{1416}. suppress warnings : \underline{992}, \underline{993}. suppress x : 967. suppress y : 967. suppress z : 967. surface hiding: 1043. surface vector : 997, \underline{998}, 1000, 1028, \underline{1029}, 1031. System: \underline{34}, 37, 39, 41, 44, 46, 48, \underline{65}, 68, 1546. s1 : \underline{498}, \underline{499}, \underline{500}. s2 : \underline{498}, \underline{499}, \underline{500}. t: \underline{174}, \underline{175}, \underline{188}, \underline{194}, \underline{196}, \underline{198}, \underline{201}, \underline{218}, \underline{219}, \underline{222},

\underline{223}, \underline{224}, \underline{227}, \underline{255}, \underline{289}, \underline{290}, \underline{291}, \underline{292}, \underline{404}, \underline{406}, \underline{408}, \underline{413}, \underline{419}, \underline{424}, \underline{437}, \underline{439}, \underline{440}, \underline{516}, \underline{518}, \underline{519}, \underline{556}, \underline{650}, \underline{757}, \underline{759}, \underline{763}, \underline{767}, \underline{769}, \underline{772}, \underline{781}, \underline{782}, \underline{791}, \underline{792}, \underline{793}, \underline{795}, \underline{948}, \underline{1045}, \underline{1046}, \underline{1048}, \underline{1051}, \underline{1055}, \underline{1057}, \underline{1060}, \underline{1150}, \underline{1165}, \underline{1212}, \underline{1218}, \underline{1231}, \underline{1232}, \underline{1233}, \underline{1234}, \underline{1236}, \underline{1238}, \underline{1240}, \underline{1243}, \underline{1253}, \underline{1267}, \underline{1268}, \underline{1307}, \underline{1311}, \underline{1321}, \underline{1386}, \underline{1387}, \underline{1388}, \underline{1391}, \underline{1393}, \underline{1396}, \underline{1398}, \underline{1400}, \underline{1402}, \underline{1488}, \underline{1492}, \underline{1502}, \underline{1529}.

t all : \underline{206}, 209. t inverse: \underline{1005}, \underline{1218}, 1221, 1223, 1225. t x : \underline{206}, 207, 209, \underline{561}, 562, 563, 564, 565,

566, \underline{948}, 950. t x sign: \underline{565}. t y : \underline{206}, 208, 209, \underline{561}, 562, 563, 564, 565, 566,

\underline{948}, 949, 950. t y sign: \underline{565}. t z : \underline{206}, 209, \underline{561}, 562, 563, 564, 565, 566,

\underline{948}, 949, 950. t z sign: \underline{565}. temp: \underline{547}, \underline{948}, 949, 950. temp bool : \underline{1227}, 1228. temp circle: \underline{1324}. temp circle center : \underline{1324}. temp circle normal : \underline{1324}. temp coordinates : 441, \underline{443}, 445. temp matrix : \underline{219}. temp pt : \underline{649}. temp string : \underline{1227}, 1228. temp1 : \underline{206}, 207, 208, 209. temp2 : \underline{206}, 207, 208, 209. test angle: \underline{1224}. test points : 401, 948. Tetrahedra: 1485. Tetrahedron: 1470, \underline{1477}, 1478, 1480, \underline{1481},

1483, \underline{1484}, 1485, 1487, 1488, 1489, 1490, 1492.

tex stream: \underline{78}, \underline{79}, 83, 84, 85, 1557.
tex stream name: \underline{81}, \underline{82}, 83.
text : \underline{135}, \underline{136}, \underline{192}, \underline{193}, \underline{245}, \underline{253}, \underline{293}, \underline{294},

\underline{295}, \underline{296}, \underline{475}, \underline{476}, \underline{477}, \underline{478}, 506, 515, 516, \underline{652}, \underline{653}, \underline{689}, \underline{690}, \underline{909}, \underline{910}, \underline{916}, \underline{917}, \underline{918}, \underline{919}, \underline{1381}, \underline{1382}.

text short : \underline{507}, \underline{508}, \underline{512}, \underline{513}, \underline{871}, \underline{872}, \underline{873}, \underline{874},

\underline{875}, \underline{877}, \underline{878}, \underline{879}, \underline{880}.

text str : \underline{505}, \underline{506}, \underline{510}, \underline{511}, \underline{617}, \underline{618}.
theta: \underline{1324}, \underline{1327}.
theta total : \underline{1327}.
third : \underline{16}, \underline{315}, 316, 1004, 1174, 1175, 1223,

1225, 1227. this : 119, 188, 194, 196, 198, 201, 204, 209, 216,

218, 219, 222, 224, 233, 269, 284, 329, 330, 332, 334, 358, 363, 386, 389, 390, 393, 394, 395, 397, 400, 401, 432, 436, 437, 439, 453, 455, 459, 462, 475, 476, 486, 487, 506, 507, 522, 526, 533, 537, 541, 543, 545, 547, 548, 551, 552, 554, 556, 567, 568, 570, 588, 589, 601, 607, 610, 612, 614, 645, 666, 670, 681, 690, 701, 721, 722, 731, 757, 759, 763, 767, 769, 772, 793, 794, 795, 797, 800, 805, 807, 811, 813, 814, 819, 823, 832, 841, 845, 850, 856, 860, 864, 867, 883, 916, 918, 925, 930, \underline{940}, 945, 948, 956, 958, 959, 960, 964, 976, 992, 993, 997, 1001, 1011, 1043, 1048, 1051, 1055, 1057, 1060, 1071, 1081, 1109, 1114, 1120, 1152, 1158, 1164, 1165, 1190, 1205, 1215, 1217, 1218, 1231, 1235, 1237, 1238, 1239, 1240, 1242, 1252, 1282, 1284, 1290, 1291, 1292, 1293, 1295, 1346, 1347, 1349, 1391, 1393, 1396, 1398, 1400, 1402, 1405, 1424, 1427, 1430, 1433, 1436, 1439, 1467, 1488.

this axis orientation: \underline{1217}, 1218.

this option optind : \underline{1549}.

this plane: \underline{1215}, 1216, 1217, 1218, 1220, 1227,

\underline{1305}. time: 82. tm: 82. tolower : 356, 361, 390, 424, 476, 605, 910, 1172. top lft : \underline{1107}. top rt : \underline{1107}. trace: \underline{573}, \underline{574}, \underline{964}, \underline{965}. trace x z 0 : \underline{1001}. Transform: \underline{166}, 168, \underline{169}, 170, \underline{171}, 172, \underline{173},

174, 175, 177, 179, 181, 182, 183, 186, 188, 191, 193, 194, 195, 196, 197, 198, 200, 201, 202, 203, 204, 205, 206, 211, 212, 213, 217, 218, 219, 221, 222, 223, 224, 226, 227, 232, 233, 234, 235, 236, 237, 245, 255, 261, 280, 281, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 309, 384, 404, 405, 406, 407, 408, 409, 412, 413, 414, 415, 416, 417, 419, 420, 421, 422, 423, 424, 436, 437, 438, 439, 440, 441, 448, 516, 518, 519, 597, 600, 603, 605, 616, 624, 625, 627, 628, 753, 756, 757, 759, 760, 762, 763, 764, 765, 766, 767, 768, 769, 771, 772, 773, 774, 775, 781, 782, 790, 791, 792, 793, 794, 795, 993, 997, 1001, 1005, 1044, 1045, 1046, 1047, 1048, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1059, 1060, 1061, 1062, 1068, 1099, 1150, 1165, 1218, 1221, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1242, 1243, 1244, 1245, 1252, 1253, 1254, 1255, 1267, 1268, 1307, 1311, 1321, 1386, 1387, 1388, 1390, 1391, 1392, 1393, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1492, 1500, 1502, 1529.

transform: \underline{261}, 269, 281, 284, 287, 290, 292, 294, 296, 301, \underline{309}, 323, 341, 344, 345, 349, 384, 405, 407, 409, 413, 419, 420, 422, 437, 440, 441, 443, 448, 449, 451, 475, 476, 478, 518, 519, 530, 538, 587, 589, 590, 593, 597, \underline{600}, 601, 605, 614, 616, 618, 624, 625, 626, 628, 641.

transforms : 775. Transforms: 166, 182. triangle diameter : \underline{1484}, \underline{1488}, \underline{1489}, \underline{1490}, \underline{1491},

\underline{1492}, \underline{1515}, \underline{1516}, \underline{1517}, \underline{1518}, \underline{1519}. triangle radius : \underline{1477}, 1481, 1484, \underline{1508}, 1512,

1515. triangles : \underline{1490}, \underline{1517}. triangles size: \underline{1516}, \underline{1517}. true: 20, 86, 87, 88, 89, 99, 100, 102, 103, 105,

121, 148, 156, 186, 188, 204, 206, 219, 227, 233, 245, 254, 261, 264, 275, 298, 299, 325, 328, 330, 332, 334, 335, 341, 342, 355, 357, 360, 362, 365, 367, 370, 372, 375, 377, 380, 382, 390, 393, 394, 395, 399, 400, 401, 424, 437, 439, 443, 444, 445, 449, 455, 462, 471, 475, 476, 485, 487, 490, 492, 496, 502, 505, 506, 508, 511, 513, 516, 547, 550, 551, 554, 561, 564, 571, 573, 574, 585, 588, 590, 592, 593, 595, 596, 597, 605, 618, 647, 649, 650, 668, 681, 685, 688, 699, 705, 708, 710, 713, 715, 718, 720, 722, 727, 729, 732, 741, 746, 769, 786, 812, 814, 819, 828, 830, 845, 850, 867, 873, 878, 883, 885, 887, 890, 892, 898, 899, 900, 902, 904, 906, 909, 916, 917, 918, 919, 920, 926, 941, 944, 948, 950, 952, 956, 959, 960, 993, 997, 998, 1005, 1011, 1013, 1014, 1029, 1032, 1035, 1039, 1040, 1074, 1077, 1080, 1081, 1104, 1107, 1112, 1147, 1150, 1162, 1164, 1165, 1166, 1202, 1212, 1214, 1215, 1217, 1218, 1222, 1223, 1224, 1225, 1227, 1231, 1232, 1233, 1234, 1279, 1282, 1295, 1296, 1304, 1305, 1321, 1327, 1337, 1339, 1346, 1347, 1350, 1357, 1380, 1381, 1384, 1407, 1410, 1412, 1418, 1420, 1424, 1427, 1430, 1433, 1436, 1439, 1456, 1458, 1460, 1481, 1484, 1491, 1492, 1498, 1501, 1504, 1505, 1512, 1515, 1517, 1518, 1519, 1526, 1529, 1531, 1549.

trunc: \underline{24}, \underline{25}, 141, 142, 143.

Trunc Octahedron: 445, 1470, \underline{1522}, 1523,

1525, \underline{1526}, 1528, \underline{1529}, 1531. tt : \underline{82}. t0 : \underline{1001}, 1005, \underline{1221}. t1 : \underline{993}, \underline{1221}. t2 : \underline{993}. t3 : \underline{993}. u: \underline{37}, \underline{99}, \underline{100}, \underline{102}, \underline{103}, \underline{104}, \underline{105}. u x : \underline{650}. u y : \underline{650}. u z : \underline{650}. : \underline{68}. : \underline{68}. : \underline{68}. unalign up: \underline{605}, \underline{616}. : \underline{244}, \underline{246}, 856, 904, 1431. undraw : 458, \underline{469}, \underline{470}, \underline{855}, \underline{856}, \underline{857}, \underline{858}, \underline{860},

\underline{861}, \underline{1432}, \underline{1433}. undraw in ellipse: 1265. : \underline{244}, \underline{246}, 459, 502. undrawdot : \underline{458}, \underline{459}, \underline{460}, \underline{461}. : \underline{244}, \underline{246}, 864, 904, 1434. unfill : \underline{863}, \underline{864}, 1434, \underline{1435}, \underline{1436}. unfill draw : 1438. : \underline{244}, \underline{246}, 867, 905, 1437. unfilldraw : \underline{866}, \underline{867}, \underline{868}, \underline{869}, \underline{1438}, \underline{1439}. unit vector : 394, 437, 439, 550, \underline{551}, \underline{552}, \underline{553}, \underline{554}, 649, 668, 944, 993, 997, 998, 1029, 1039, 1112, 1165, 1202, 1217, 1222, 1232, 1267, 1268, 1305.

unsuppress labels : \underline{275}.

unsuppress output : \underline{245}, \underline{484}, \underline{485}, 596, \underline{897}, \underline{898},

\underline{1417}, \underline{1418}. up: \underline{600}, 601, 603, 605, 614, 616, 618, 623, 967. use name: \underline{95}, 98, 100, 103, 105, 108, 110, 115,

116, 126, 145, 453. user coordinates : \underline{309}, 323, 341, 345, 356, 361,

475, 679. user transform: \underline{234}, \underline{235}, 328. : 309. : \underline{309}, \underline{310}, 507, 508. : \underline{309}, \underline{310}, 507. : \underline{68}. v: \underline{358}, \underline{476}, \underline{487}, \underline{593}, \underline{883}, \underline{910}, \underline{1040}, \underline{1405},

\underline{1407}, \underline{1423}, \underline{1424}, \underline{1426}, \underline{1427}, \underline{1474}, \underline{1492},
\underline{1506}, \underline{1519}, \underline{1546}.

v coord : \underline{1004}.

v intercept : \underline{1004}, \underline{1174}, \underline{1175}.

v length: \underline{1267}, \underline{1268}.

v x : \underline{650}. v y : \underline{650}. v z : \underline{650}. va arg : 713, 715, 718, 720. va end : 713, 715, 718, 720. va start : 713, 715, 718, 720. valarray: 18, 26, 245, 309, 322, 355, 356, 357,

358, 443, 449, 476, 488, 594, 595, 698, 888, 910, 1333, 1407, 1408.

valarrays: 322. vector: 159, 160, 245, 261, 294, 453, 486, 487,

497, 501, 506, 587, 589, 590, 592, 593, 597, 698, 701, 703, 727, 751, 777, 782, 784, 786, 808, 809, 813, 814, 834, 873, 882, 883, 886, 899, 902, 910, 942, 944, 958, 1032, 1034, 1039, 1040, 1041, 1043, 1161, 1165, 1296, 1323, 1324, 1326, 1327, 1333, 1339, 1346, 1347, 1382, 1384, 1387, 1389, 1404, 1405, 1407, 1419, 1420, 1423, 1424, 1426, 1427, 1429, 1430, 1433, 1436, 1439, 1458, 1465, 1473, 1474, 1489, 1490, 1492, 1502, 1503, 1504, 1506, 1515, 1516, 1517, 1519, 1529, 1530, 1531, 1546.

vectors: 1419. verbose: 20, \underline{36}, \underline{37}, \underline{38}, \underline{39}, \underline{40}, \underline{41}, \underline{66}, \underline{68}, 69, 70,

\underline{71}, \underline{72}, \underline{401}, \underline{916}, \underline{917}, \underline{918}, \underline{919}, \underline{948}, 950, 1035, 1212, \underline{1214}, \underline{1215}, 1225, 1227, \underline{1228}, \underline{1304}, \underline{1305}.

: \underline{20}, \underline{21}, 916, 917, 918, 919, 948,

1214, 1215, 1304, 1305, 1549. : \underline{1549}. : \underline{1549}. : \underline{22}, \underline{23}, 1549, 1553, 1554, 1556,

1557. vertex : \underline{1078}. vertex radius : \underline{1472}, 1481, 1484, 1498, 1501, 1512,

1515, 1526, 1529. vertical : \underline{444}. vertices : \underline{1445}, 1456, 1458, 1460, 1481, 1484, 1498,

1501, 1512, 1515, 1526, 1529. view coordinates : \underline{309}, 323, 341, 345, 356, 361,

475, 679. : 309. : \underline{309}, \underline{310}, 507, 508, 873. : \underline{309}, \underline{310}, 507, 872. violet : 152, \underline{156}, \underline{157}, 1546. violet red : 152, \underline{156}, \underline{157}, 1546. vx : \underline{688}. vy : \underline{688}. vz : \underline{688}. v0 : \underline{394}. v1 : \underline{394}. v2 : \underline{394}. w: \underline{1459}, \underline{1460}, \underline{1474}. w x : \underline{650}. w y : \underline{650}. w z : \underline{650}. web: 1518. white: 152, \underline{156}, \underline{157}. width: \underline{1453}, 1460, 1467. world coordinates : \underline{309}, 310, 322, 323, 328, 341,

345, 347, 356, 361, 389, 390, 393, 395, 423, 425, 428, 430, 433, 443, 444, 449, 475, 487, 507, 520, 522, 524, 526, 528, 530, 539, 542, 543, 544, 545, 546, 547, 552, 560, 561, 575, 600, 948.

: 309. : \underline{309}, \underline{310}, 507, 508, 872, 873. : \underline{309}, \underline{310}, 507, 508, 872. : \underline{309}, \underline{310}, 507, 508. write footers : \underline{84}, \underline{85}, 1557. x: \underline{195}, \underline{196}, \underline{200}, \underline{201}, \underline{203}, \underline{204}, \underline{205}, \underline{206}, \underline{280}, \underline{281},

\underline{283}, \underline{284}, \underline{286}, \underline{287}, \underline{327}, \underline{328}, \underline{329}, \underline{330}, \underline{404}, \underline{405}, \underline{406}, \underline{407}, \underline{412}, \underline{413}, \underline{419}, \underline{420}, \underline{688}, \underline{756}, \underline{757}, \underline{766}, \underline{767}, \underline{771}, \underline{772}, \underline{776}, \underline{777}, \underline{1047}, \underline{1048}, \underline{1054}, \underline{1055}, \underline{1059}, \underline{1060}, \underline{1064}, \underline{1065}, \underline{1165}, \underline{1222}, \underline{1235}, \underline{1236}, \underline{1237}, \underline{1238}, \underline{1247}, \underline{1248}, \underline{1459}, \underline{1460}.

x axis : \underline{993}. x axis pt : \underline{1001}, \underline{1165}, \underline{1267}, \underline{1268}. x i : \underline{579}, 580, 581, 583, 584, 585. : \underline{993}, \underline{1221}, 1223. : \underline{993}, \underline{1221}, 1223. xx : \underline{1242}, \underline{1243}, \underline{1390}, \underline{1391}, \underline{1395}, \underline{1396}, \underline{1399}, \underline{1400}. xy : \underline{197}, \underline{198}, \underline{245}, \underline{408}, \underline{409}, \underline{768}, \underline{769}, \underline{1056}, \underline{1057},

\underline{1239}, \underline{1240}, \underline{1392}, \underline{1393}. xz : \underline{197}, \underline{198}, \underline{245}, \underline{408}, \underline{409}, \underline{768}, \underline{769}, \underline{1056}, \underline{1057},

\underline{1239}, \underline{1240}, \underline{1392}, \underline{1393}. x0 : \underline{972}. x1 : \underline{972}. y: \underline{195}, \underline{196}, \underline{200}, \underline{201}, \underline{203}, \underline{204}, \underline{205}, \underline{206}, \underline{280}, \underline{281},

\underline{283}, \underline{284}, \underline{286}, \underline{287}, \underline{327}, \underline{328}, \underline{329}, \underline{330}, \underline{404}, \underline{405}, \underline{406}, \underline{407}, \underline{412}, \underline{413}, \underline{419}, \underline{420}, \underline{688}, \underline{756}, \underline{757}, \underline{766}, \underline{767}, \underline{771}, \underline{772}, \underline{776}, \underline{777}, \underline{1047}, \underline{1048}, \underline{1054}, \underline{1055}, \underline{1059}, \underline{1060}, \underline{1064}, \underline{1065}, \underline{1222}, \underline{1235}, \underline{1236}, \underline{1237}, \underline{1238}, \underline{1247}, \underline{1248}, \underline{1459}, \underline{1460}.

y i : \underline{579}, 580, 581, 583, 585. y int p: \underline{579}, 580, 581. y int p z : \underline{580}. y int q : \underline{579}, 580, 581. y int q z : \underline{580}. y shift : \underline{1515}. yellow : 152, \underline{156}, \underline{157}, 1546. yellow green: 152, \underline{156}, \underline{157}, 1546. yx : \underline{197}, \underline{198}, \underline{245}, \underline{408}, \underline{409}, \underline{768}, \underline{769}, \underline{1056}, \underline{1057},

\underline{1239}, \underline{1240}, \underline{1392}, \underline{1393}. yy : \underline{1242}, \underline{1243}, \underline{1390}, \underline{1391}, \underline{1395}, \underline{1396}, \underline{1399}, \underline{1400}. yz : \underline{197}, \underline{198}, \underline{245}, \underline{408}, \underline{409}, \underline{768}, \underline{769}, \underline{1056}, \underline{1057},

\underline{1239}, \underline{1240}, \underline{1392}, \underline{1393}. y0 : \underline{972}. y1 : \underline{972}. z: \underline{195}, \underline{196}, \underline{200}, \underline{201}, \underline{203}, \underline{204}, \underline{205}, \underline{206}, \underline{280}, \underline{281},

\underline{283}, \underline{284}, \underline{286}, \underline{287}, \underline{327}, \underline{328}, \underline{329}, \underline{330}, \underline{404}, \underline{405}, \underline{406}, \underline{407}, \underline{412}, \underline{413}, \underline{419}, \underline{420}, \underline{688}, \underline{756}, \underline{757}, \underline{766}, \underline{767}, \underline{771}, \underline{772}, \underline{776}, \underline{777}, \underline{1047}, \underline{1048}, \underline{1054}, \underline{1055}, \underline{1059}, \underline{1060}, \underline{1064}, \underline{1065}, \underline{1165}, \underline{1235}, \underline{1236}, \underline{1237}, \underline{1238}, \underline{1247}, \underline{1248}, \underline{1459}, \underline{1460}.

z axis : \underline{993}. z axis pt : \underline{1001}. z i : \underline{579}, 580, 582, 584, 585. z int p: \underline{582}, 583, 584. z int q : \underline{582}, 583, 584. : \underline{993}, \underline{1221}, 1223. zx : \underline{197}, \underline{198}, \underline{245}, \underline{408}, \underline{409}, \underline{768}, \underline{769}, \underline{1056}, \underline{1057},

\underline{1239}, \underline{1240}, \underline{1392}, \underline{1393}. zy : \underline{197}, \underline{198}, \underline{245}, \underline{408}, \underline{409}, \underline{768}, \underline{769}, \underline{1056}, \underline{1057},

\underline{1239}, \underline{1240}, \underline{1392}, \underline{1393}. zz : \underline{1242}, \underline{1243}, \underline{1390}, \underline{1391}, \underline{1395}, \underline{1396}, \underline{1399}, \underline{1400}. z0 : \underline{972}. z1 : \underline{972}.

3DLDF-1.1.5.1 NAMES OF THE SECTIONS 515

⟨ Actions in main 1546, 1547 ⟩ Used in section 1557. ⟨ All Colors 0 ⟩ Cited in sections 153 and 158.

⟨ Calculate second-largest Real 69 ⟩ Used in section 68. ⟨ Check intersection point locations 1228 ⟩ Used in section 1227. ⟨ DEC command line option processing 1551 ⟩ Used in section 1548.

⟨ Declarations for the header file 21, 23, 26, 29, 235, 237, 303, 320, 631, 655, 692 ⟩ Cited in section 24. Used in

sections 52, 240, 306, 634, 658, and 695. ⟨ Declare I/O functions 81, 84, 86, 88 ⟩ Used in section 92. ⟨ Declare Pattern functions 1320, 1323, 1326 ⟩ Used in sections 1329 and 1330. ⟨ Declare namespace Projections 256 ⟩ Used in section 305. ⟨ Declare namespace Sorting 258 ⟩ Used in section 305.

⟨ Declare non-member non-template functions for Color 147 ⟩ Used in section 163. ⟨ Declare non-member non-template functions for Point 480, 534 ⟩ Used in section 634. ⟨ Declare non-member template functions for Circle 1286, 1287 ⟩ Used in sections 1315 and 1316. ⟨ Declare non-member template functions for Color 112, 113 ⟩ Used in sections 162 and 163. ⟨ Declare non-member template functions for Cuboid 1462, 1463 ⟩ Used in sections 1468 and 1469. ⟨ Declare non-member template functions for Ellipse 1154, 1155 ⟩ Used in sections 1271 and 1272. ⟨ Declare non-member template functions for Path 724, 725 ⟩ Used in sections 980 and 981. ⟨ Declare non-member template functions for Point 336, 337 ⟩ Used in sections 633 and 634. ⟨ Declare non-member template functions for Rectangle 1116, 1117 ⟩ Used in sections 1139 and 1140. ⟨ Declare non-member template functions for Reg Polygon 1083, 1084 ⟩ Used in sections 1097 and 1098. ⟨ Declare non-member template functions for Solid 1341, 1342 ⟩ Used in sections 1441 and 1442. ⟨ Declare parser functions 1538 ⟩ Used in section 1542.

⟨ Declare utility functions 24, 31 ⟩ Cited in section 24. Used in section 52. ⟨ Declare Circle functions 1278, 1281, 1283, 1290, 1292, 1295, 1297, 1298, 1300, 1302, 1304 ⟩ Used in section 1276. ⟨ Declare Color functions 97, 99, 102, 104, 107, 109, 114, 116, 118, 121, 123, 125, 127, 129, 131, 133, 135, 138, 141, 142,

143, 144, 146, 149, 151 ⟩ Used in section 95. ⟨ Declare Cuboid functions 1455, 1457, 1459, 1464, 1466 ⟩ Used in section 1453. ⟨ Declare Dodecahedron functions 1497, 1500, 1503, 1505 ⟩ Used in section 1494. ⟨ Declare Ellipse functions 1146, 1149, 1151, 1157, 1160, 1162, 1164, 1166, 1167, 1169, 1171, 1174, 1177, 1179, 1182,

1184, 1186, 1188, 1192, 1194, 1197, 1199, 1201, 1203, 1205, 1208, 1210, 1214, 1231, 1233, 1235, 1237, 1239, 1242, 1244, 1247, 1249, 1252, 1254, 1257, 1259, 1261, 1263 ⟩ Used in section 1143.

⟨ Declare Focus functions 602, 604, 606, 609, 611, 613, 615, 617, 620, 621, 622, 623, 624, 625, 627, 628 ⟩ Used in

section 600. ⟨ Declare Icosahedron functions 1511, 1514, 1516, 1518 ⟩ Used in section 1508. ⟨ Declare Label functions 255 ⟩ Used in section 253. ⟨ Declare Line constructors 639, 641 ⟩ Used in section 637. ⟨ Declare Line functions 643, 646, 648, 652 ⟩ Used in section 637. ⟨ Declare Path functions 700, 704, 707, 709, 712, 714, 717, 719, 721, 726, 728, 730, 732, 735, 738, 740, 743, 745, 747, 749,

751, 756, 762, 764, 766, 768, 771, 773, 776, 778, 781, 783, 785, 790, 792, 794, 797, 799, 801, 805, 810, 812, 818, 820, 827, 829, 836, 838, 844, 846, 849, 851, 855, 857, 863, 866, 868, 872, 874, 877, 879, 882, 884, 888, 889, 891, 893, 895, 897, 899, 909, 911, 914, 916, 918, 920, 921, 922, 923, 925, 932, 934, 936, 938, 940, 946, 952, 955, 959, 961, 964, 976 ⟩ Used in section 698.

⟨ Declare Picture functions 263, 265, 267, 269, 270, 272, 274, 275, 276, 280, 283, 285, 286, 288, 289, 291, 293, 295, 298,

299, 300, 301 ⟩ Used in section 261. ⟨ Declare Plane functions 663, 665, 667, 669, 672, 674, 677, 679, 684, 686, 687, 689 ⟩ Used in section 661. ⟨ Declare Point constructors 324, 327, 331 ⟩ Used in section 309. ⟨ Declare Point functions 329, 333, 338, 340, 342, 344, 346, 349, 350, 352, 355, 357, 360, 362, 365, 367, 370, 372, 375, 377,

380, 382, 384, 385, 387, 389, 393, 396, 398, 400, 401, 404, 406, 408, 412, 414, 419, 421, 436, 438, 442, 446, 448, 450, 454, 456, 458, 460, 463, 464, 466, 467, 469, 470, 472, 473, 475, 477, 482, 484, 486, 488, 489, 491, 493, 495, 501, 505, 507, 510, 512, 518, 521, 523, 525, 527, 529, 532, 536, 538, 540, 542, 544, 546, 548, 551, 553, 555, 557, 560, 567, 569, 572, 573 ⟩ Used in section 309.

⟨ Declare Polygon functions 1022, 1024, 1028, 1037, 1039, 1045, 1047, 1050, 1052, 1054, 1056, 1059, 1061, 1064, 1066 ⟩

Used in section 1019. ⟨ Declare Polyhedron functions 1473 ⟩ Used in section 1472. ⟨ Declare Rectangle functions 1103, 1106, 1108, 1111, 1113, 1119, 1122, 1125, 1127, 1130, 1132, 1135, 1136, 1137, 1138 ⟩

Used in section 1101. ⟨ Declare Reg Cl Plane Curve functions 987, 988, 989, 990, 991, 992, 994, 997, 1008, 1011, 1013, 1014 ⟩ Used in

section 985. ⟨ Declare Reg Polygon functions 1070, 1073, 1076, 1079, 1087, 1089, 1091, 1092, 1093, 1095, 1096 ⟩ Used in

section 1069. ⟨ Declare Solid Faced functions 1446 ⟩ Used in section 1445. ⟨ Declare Solid functions 1336, 1338, 1343, 1345, 1348, 1350, 1353, 1356, 1358, 1360, 1362, 1364, 1366, 1369, 1371, 1373,

1375, 1377, 1379, 1381, 1383, 1386, 1388, 1390, 1392, 1395, 1397, 1399, 1401, 1404, 1406, 1408, 1409, 1411, 1413, 1415, 1417, 1419, 1423, 1426, 1429, 1432, 1435, 1438 ⟩ Used in section 1333.

⟨ Declare System functions 36, 38, 40, 43, 45, 47, 66, 71, 72 ⟩ Used in sections 34, 52, 65, and 75. ⟨ Declare Tetrahedron functions 1480, 1483, 1487, 1489, 1491 ⟩ Used in section 1477. ⟨ Declare Transform functions 168, 170, 172, 174, 176, 178, 180, 182, 185, 187, 190, 192, 195, 197, 200, 202, 203, 205,

211, 212, 213, 216, 218, 221, 223, 226, 232 ⟩ Used in section 166. ⟨ Declare Trunc Octahedron functions 1525, 1528, 1530 ⟩ Used in section 1522.

⟨ Declare create new ( ) 56, 58 ⟩

⟨ Declare draw axes ( ) 968, 973 ⟩ Used in section 981. ⟨ Declare namespace Colors 153 ⟩ Cited in section 153. Used in section 162. ⟨ Declare namespace System 34, 65 ⟩ Used in sections 51, 52, 74, and 75. ⟨ Define I/O functions 82, 83, 85, 87, 89 ⟩ Used in section 91. ⟨ Define Pattern functions 1321, 1324, 1327 ⟩ Used in section 1329. ⟨ Define classes 253, 261 ⟩ Used in sections 305 and 306. ⟨ Define comparison classes 498, 499, 500 ⟩ Cited in section 596. Used in sections 633 and 634.

⟨ Define non-member non-template functions for Color 148 ⟩ Used in section 162. ⟨ Define non-member non-template functions for Point 481, 535 ⟩ Used in section 633. ⟨ Define parser functions 1539 ⟩ Used in section 1541.

⟨ Define utility functions 25, 32 ⟩ Cited in section 25. Used in section 51. ⟨ Define Circle functions 1279, 1282, 1284, 1291, 1293, 1296, 1301, 1303, 1305 ⟩ Used in section 1315. ⟨ Define Color functions 98, 100, 103, 105, 108, 110, 115, 117, 119, 122, 124, 126, 128, 130, 132, 134, 136, 139, 145, 150,

152 ⟩ Used in section 162. ⟨ Define Cuboid functions 1456, 1458, 1460, 1465, 1467 ⟩ Used in section 1468. ⟨ Define Dodecahedron functions 1498, 1501, 1502, 1504, 1506 ⟩ Used in section 1534. ⟨ Define Ellipse functions 1147, 1150, 1152, 1158, 1161, 1165, 1168, 1170, 1172, 1173, 1175, 1178, 1180, 1183, 1185,

1187, 1189, 1193, 1195, 1198, 1200, 1202, 1204, 1206, 1209, 1211, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1226, 1227, 1232, 1234, 1236, 1238, 1240, 1243, 1245, 1248, 1250, 1253, 1255, 1258, 1260, 1262, 1264 ⟩ Used in section 1271.

⟨ Define Focus functions 605, 607, 610, 612, 614, 616, 618, 626, 629 ⟩ Used in section 633. ⟨ Define Icosahedron functions 1512, 1515, 1517, 1519 ⟩ Used in section 1534. ⟨ Define Label functions 514, 515, 516 ⟩ Used in section 633. ⟨ Define Line constructors 640, 642 ⟩ Used in section 657. ⟨ Define Line functions 644, 649, 650, 651, 653, 978 ⟩ Used in sections 657 and 980. ⟨ Define Path functions 701, 705, 708, 710, 713, 715, 718, 720, 722, 727, 729, 731, 733, 736, 739, 741, 744, 746, 748, 750,

752, 757, 763, 765, 767, 769, 772, 774, 777, 779, 782, 784, 786, 791, 793, 795, 798, 800, 802, 806, 807, 808, 809, 811, 813, 814, 819, 821, 828, 830, 837, 839, 845, 847, 850, 852, 856, 858, 864, 867, 869, 873, 875, 878, 880, 883, 885, 886, 887, 890, 892, 894, 896, 898, 900, 901, 902, 903, 904, 905, 906, 910, 912, 915, 917, 919, 924, 926, 927, 928, 929, 930, 933, 935, 937, 941, 942, 943, 944, 947, 953, 956, 957, 958, 960, 962, 965, 977 ⟩ Used in section 980.

⟨ Define Picture functions 264, 271, 273, 277, 281, 284, 287, 290, 292, 294, 296, 417, 440, 587, 588, 589, 590, 592, 593,

594, 595, 596, 597, 598 ⟩ Used in sections 305 and 633. ⟨ Define Plane functions 664, 666, 668, 670, 673, 675, 678, 680, 685, 688, 690, 966 ⟩ Used in sections 694 and 980.

⟨ Define Point constructors 325, 328, 332 ⟩ Used in section 633. ⟨ Define Point functions 330, 334, 339, 341, 343, 345, 347, 351, 356, 358, 361, 363, 366, 368, 371, 373, 376, 378, 381, 383,

386, 388, 390, 391, 394, 395, 397, 399, 405, 407, 409, 413, 415, 420, 422, 437, 443, 444, 445, 447, 449, 451, 455, 457, 459, 461, 476, 478, 483, 485, 487, 490, 492, 494, 496, 502, 506, 508, 511, 513, 519, 522, 524, 526, 528, 530, 533, 537, 539, 541, 543, 545, 547, 549, 552, 554, 556, 561, 562, 563, 564, 565, 566, 568, 570, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 645, 647, 681, 760, 823, 824, 832, 833, 841, 842, 860, 861, 945, 948, 949, 950 ⟩ Used in sections 633, 657, 694, and 980.

⟨ Define Polygon functions 1023, 1025, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1038, 1040, 1041, 1042, 1043,

1046, 1048, 1051, 1053, 1055, 1057, 1060, 1062, 1065, 1067 ⟩ Used in section 1097. ⟨ Define Polyhedron functions 1474 ⟩ Used in section 1534. ⟨ Define Rectangle functions 1104, 1107, 1109, 1112, 1114, 1120, 1123, 1126, 1128, 1131, 1133, 1267, 1268, 1269, 1270 ⟩

Used in sections 1139 and 1271. ⟨ Define Reg Cl Plane Curve functions 993, 995, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1009,

1012 ⟩ Used in section 1015. ⟨ Define Reg Polygon functions 1071, 1074, 1077, 1078, 1080, 1081, 1307, 1309, 1310, 1311, 1313, 1314 ⟩ Used in

sections 1097 and 1315. ⟨ Define Shape class 244, 245 ⟩ Used in sections 248 and 249. ⟨ Define Solid Faced functions 1447 ⟩ Used in section 1449. ⟨ Define Solid functions 1337, 1339, 1344, 1346, 1347, 1349, 1351, 1354, 1357, 1359, 1361, 1363, 1365, 1367, 1370, 1372,

1374, 1376, 1378, 1380, 1382, 1384, 1387, 1389, 1391, 1393, 1396, 1398, 1400, 1402, 1405, 1407, 1410, 1412, 1414, 1416, 1418, 1420, 1424, 1427, 1430, 1433, 1436, 1439 ⟩ Used in section 1441.

⟨ Define System functions 37, 39, 41, 44, 46, 48, 67, 68 ⟩ Used in sections 51, 74, and 75. ⟨ Define Tetrahedron functions 1481, 1484, 1485, 1486, 1488, 1490, 1492 ⟩ Used in section 1534. ⟨ Define Transform functions 169, 171, 173, 175, 177, 179, 181, 183, 186, 188, 191, 193, 196, 198, 201, 204, 206, 207,

208, 209, 217, 219, 222, 224, 227, 228, 229, 230, 231, 233, 416, 424, 425, 426, 427, 428, 429, 430, 431, 432, 439, 759 ⟩ Used in sections 239, 633, and 980.

⟨ Define Trunc Octahedron functions 1526, 1529, 1531, 1532 ⟩ Used in section 1534. ⟨ Define bool point quadruple functions 316 ⟩ Used in section 633. ⟨ Define bool point functions 314 ⟩ Cited in section 313. Used in section 633. ⟨ Define bool real point functions 318 ⟩ Used in section 633. ⟨ Define class Circle 1276 ⟩ Used in sections 1315 and 1316. ⟨ Define class Color 95 ⟩ Used in sections 162 and 163. ⟨ Define class Cuboid 1453 ⟩ Used in sections 1468 and 1469. ⟨ Define class Dodecahedron 1494 ⟩ Used in sections 1534 and 1535. ⟨ Define class Ellipse 1143 ⟩ Used in sections 1271 and 1272. ⟨ Define class Focus 600 ⟩ Used in sections 633 and 634. ⟨ Define class Icosahedron 1508 ⟩ Used in sections 1534 and 1535. ⟨ Define class Path 698 ⟩ Used in sections 980 and 981. ⟨ Define class Point 309 ⟩ Used in sections 633 and 634. ⟨ Define class Polygon 1019 ⟩ Used in sections 1097 and 1098. ⟨ Define class Polyhedron 1472 ⟩ Used in sections 1534 and 1535. ⟨ Define class Rectangle 1101 ⟩ Used in sections 1139 and 1140. ⟨ Define class Reg Cl Plane Curve 985 ⟩ Used in sections 1015 and 1016. ⟨ Define class Reg Polygon 1069 ⟩ Used in sections 1097 and 1098. ⟨ Define class Solid Faced 1445 ⟩ Used in sections 1449 and 1450. ⟨ Define class Solid 1333 ⟩ Used in sections 1441 and 1442. ⟨ Define class Tetrahedron 1477 ⟩ Used in sections 1534 and 1535. ⟨ Define class Transform 166 ⟩ Used in sections 239 and 240. ⟨ Define class Trunc Octahedron 1522 ⟩ Used in sections 1534 and 1535. ⟨ Define create new ( ) 57, 59 ⟩ Used in sections 61 and 62. ⟨ Define draw axes ( ) 969, 970, 971, 972, 974 ⟩ Used in section 980. ⟨ Define static Point data members 310 ⟩ Used in section 633.

⟨ Define static const Dodecahedron data members 1495 ⟩ Used in section 1534. ⟨ Define static const Icosahedron data members 1509 ⟩ Used in section 1534. ⟨ Define static const Solid data members 1334 ⟩ Used in section 1441. ⟨ Define static const Tetrahedron data members 1478 ⟩ Used in section 1534. ⟨ Define static const Trunc Octahedron data members 1523 ⟩ Used in section 1534. ⟨ Define static Ellipse data members 1144 ⟩ Used in section 1271.

⟨ Define static Shape member variables 246 ⟩ Used in section 248.

⟨ Define static class Path data members 699 ⟩ Used in section 980. ⟨ Define struct Line 637 ⟩ Used in sections 657 and 658. ⟨ Define struct Plane 661 ⟩ Used in sections 694 and 695. ⟨ Discard points and connectors 703 ⟩ Used in sections 701, 710, 715, 720, and 729. ⟨ Forward declarations 49 ⟩ Used in sections 51 and 52.

⟨ GCC 2.95 print version, copyright, and license information 1553 ⟩ Used in section 1552. ⟨ GCC 3.3 and DEC print version, copyright, and license information 1554 ⟩ Used in section 1552. ⟨ GCC command line option processing 1549 ⟩ Used in section 1548. ⟨ GNU Free Documentation License 1561 ⟩ Cited in section 1. ⟨ GNU General Public License 1562 ⟩ Cited in section 1. ⟨ Get input 1545 ⟩

⟨ Global constants 22, 28, 159, 236, 319 ⟩ Used in sections 51, 162, 239, and 633. ⟨ Global variables 18, 19, 20, 78, 234, 302, 630 ⟩ Cited in section 25. Used in sections 51, 91, 239, 305, and 633.

⟨ Handle intersection point 1225 ⟩ Used in section 1224.

⟨ Include files 6, 7, 8, 9, 14, 54, 64, 77, 94, 165, 242, 251, 308, 636, 660, 697, 983, 1018, 1100, 1142, 1274, 1318, 1332, 1444, 1452, 1471, 1537, 1544 ⟩ Used in sections 12, 51, 61, 74, 91, 162, 239, 248, 305, 633, 657, 694, 980, 1015, 1097, 1139, 1271, 1315, 1329, 1441, 1449, 1468, 1534, 1541, and 1558.

⟨ Initialize coordinates and limits 323 ⟩ Used in sections 325, 328, and 332. ⟨ Initialize static Label data members 254 ⟩ Used in section 305. ⟨ Loop for testing bits 70 ⟩ Cited in section 66.

⟨ Main 1555, 1556, 1557 ⟩ Used in section 1558. ⟨ Major Colors 156 ⟩ Cited in sections 153 and 158. Used in section 153. ⟨ Normalize point 433 ⟩ Used in section 425. ⟨ Output Path 907 ⟩ Used in sections 902, 904, 905, and 906.

⟨ Print version, copyright, and license information 1552 ⟩ Used in section 1556. ⟨ Process command line options 1548 ⟩ Used in section 1555.

⟨ Process vectors for draw ( ) 1422 ⟩ Used in section 1424. ⟨ Process vectors for fill ( ) 1425 ⟩ Used in section 1427. ⟨ Process vectors for filldraw ( ) 1428 ⟩ Used in section 1430. ⟨ Process vectors for undraw ( ) 1431 ⟩ Used in section 1433. ⟨ Process vectors for unfill ( ) 1434 ⟩ Used in section 1436. ⟨ Process vectors for unfilldraw ( ) 1437 ⟩ Used in section 1439. ⟨ Type definitions 15, 312, 313, 315, 317 ⟩ Cited in section 15. Used in sections 51, 52, 633, and 634. ⟨ Utility classes 16 ⟩ Used in sections 51 and 52. ⟨ Version control identifier 5, 13, 53, 63, 76, 93, 164, 241, 250, 307, 635, 659, 696, 982, 1017, 1099, 1141, 1273, 1317, 1331,

1443, 1451, 1470, 1536, 1543 ⟩ Used in sections 11, 51, 61, 74, 91, 162, 239, 248, 305, 633, 657, 694, 980, 1015, 1097, 1139, 1271, 1315, 1329, 1441, 1449, 1468, 1534, 1541, and 1558.

⟨ 1316 ⟩ ⟨ 163 ⟩

⟨ 62 ⟩

⟨ 1469 ⟩ ⟨ 1016 ⟩ ⟨ 1272 ⟩

⟨ 75 ⟩ ⟨ 92 ⟩

⟨ 658 ⟩

⟨ 12 ⟩

⟨ 1542 ⟩ ⟨ 981 ⟩ ⟨ 1330 ⟩ ⟨ 306 ⟩ ⟨ 695 ⟩ ⟨ 634 ⟩ ⟨ 1098 ⟩ ⟨ 1535 ⟩

⟨ 52 ⟩

⟨ 1140 ⟩ ⟨ 249 ⟩ ⟨ 1450 ⟩ ⟨ 1442 ⟩ ⟨ 240 ⟩ ⟨ Line global constants 654 ⟩ Used in section 657. ⟨ Plane global constants 691 ⟩ Used in section 694. ⟨ extern All Colors 0 ⟩ Cited in section 154. ⟨ extern Major Colors 157 ⟩ Cited in section 154. Used in section 154.

⟨ extern declaration of namespace Projections 257 ⟩ Used in section 306. ⟨ extern declaration of namespace Sorting 259 ⟩ Used in section 306. ⟨ extern global constant declarations 160 ⟩ Used in section 163. ⟨ extern variable declarations 79 ⟩ Used in section 92.

⟨ extern namespace Colors declaration 154 ⟩ Cited in sections 154 and 158. Used in section 163.