Close
About
FAQ
Home
Collections
Login
USC Login
Register
0
Selected
Invert selection
Deselect all
Deselect all
Click here to refresh results
Click here to refresh results
USC
/
Digital Library
/
University of Southern California Dissertations and Theses
/
Interactive C++ program to generate plank system lines for timber rib shell structures
(USC Thesis Other)
Interactive C++ program to generate plank system lines for timber rib shell structures
PDF
Download
Share
Open document
Flip pages
Contact Us
Contact Us
Copy asset link
Request this asset
Transcript (if available)
Content
INFORMATION TO USERS This manuscript has been reproduced from the microfilm master. UMI films the text directly from the original or copy submitted. Thus, some thesis and dissertation copies are in typewriter face, while others may be from any type of computer printer. The quality of this reproduction is dependent upon the quality of the copy submitted. Broken or indistinct print, colored or poor quality illustrations and photographs, print bleedthrough, substandard margins, and improper alignment can adversely affect reproduction. In the unlikely event that the author did not send UMI a complete manuscript and there are missing pages, these will be noted. Also, if unauthorized copyright material had to be removed, a note will indicate the deletion. Oversize materials (e.g., maps, drawings, charts) are reproduced by sectioning the original, beginning at the upper left-hand comer and continuing from left to right in equal sections with small overlaps. Photographs included in the original manuscript have been reproduced xerographically in this copy. Higher quality 6” x 9” black and white photographic prints are available for any photographs or illustrations appearing in this copy for an additional charge. Contact UMI directly to order. ProQuest Information and Learning 300 North Zeeb Road, Ann Arbor, M l 48106-1346 USA 800-521-0600 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. INTERACTIVE C++ PROGRAM TO GENERATE PLANK SYSTEM LINES FOR TIMBER RIB SHELL STRUCTURES by Judith Leuppi A Thesis Presented to the FACULTY OF THE SCHOOL OF ARCHITECTURE UNIVERSITY OF SOUTHERN CALIFORNIA In Partial Fulfillment of the Requirements for the Degree MASTER OF BUILDING SCIENCE August 2000 Copyright 2000 Judith Leuppi Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. UMI Number: 1405245 __ ___ __® UMI UMI Microform 1405245 Copyright 2001 by Bell & Howell Information and Learning Company. All rights reserved. This microform edition is protected against unauthorized copying under Title 17, United States Code. Bell & Howell Information and Learning Company 300 North Zeeb Road P.O. Box 1346 Ann Arbor, Ml 48106-1346 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. U N IV E R S IT Y O F S O U T H E R N C A L IF O R N IA T H E GRADUATE SC H O O L U N IV ER SITY PA R K L O S A N G ELES. C A LIFO R N IA 1 0 0 0 7 This thesis, •written by JucfiiU L g & f f ij__________ under the direction of h& s z Thesis Committee, and approved by all its members, has been pre sented to and accepted by the Dean of The G raduate School, in partial fulfillm ent of the requirem ents fo r the degree of I 2.0 0 THESIS COMMITTEE Chmi r mmm Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. ACKNOWLEDGMENTS I would like to thank my thesis advisors Professors G. G. Schierle, M. Schiler, K. Kensek, R. Wagner for their generous help and availability. I would also like to thank Professor J. Natterer, and his coworkers in the department IBOIS, and offices BCN and IEZ for using their pictures and tapping their knowledge. Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. TABLE OF CONTENTS ACKNOWLEDGMENTS____________________________________________________________ II TABLE OF CONTENTS ____________________________________________________________in LIST OF FIGURES_________________________________________________________________ VI ABSTRACT______________________________________________________________________ VIII 1. INTRODUCTION_________________________________________________________________ 1 1.1. Hypothesis_______________________________________________________________________1 1.2. Problem Definition_______________________________________________________________ 1 2. HISTORICAL BACKGROUND____________________________________________________ 2 2.1. Today’s challenge: timber structures_______________________________________________3 2.2. Existing Timber Rib Timber Shells_________________________________________________ 8 2.3. Examples o f executed projects_____________________________________________________ 9 2.3.1. Pilot project “Polydome”, Lausanne, Switzerland, 1991______________________________9 2.3.2. Expo 2000, Hanover, Germany_________________________________________________ 11 2.3.3. Airport, Kloten, Switzerland, Competition_______________________________________ 12 2.3.4. Temporary hall for galley construction, Morges, Switzerland, 1996___________________ 13 2.4. Choice of shapes________________________________________________________________ 14 3. EXISTING DESIGN METHODS __________________________________________________ 15 3.1.1. How is the design o f the rib shell structures being done today?_____________________ 15 3.2. Existing Computer Tools_________________________________________________________17 3.3. Inter-Relationship of Existing Computer Tools_____________________________________ 19 3.4. Integration of the New Computer Tool_____________________________________________20 3.5. Integration of RIPS______________________________________________________________ 22 4. PROGRAM OBJECTIVES _______________________________________________________ 23 4.1. Definitions_____________________________________________________________________ 25 4.2. Finite Element Approach_________________________________________________________28 iii Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 5. HOW TO RUN TH E PROGRAM 32 5.1. AutoCAD draw ing____________________________________________________________ 32 5.1.1. How to draw a surface in AutoCAD___________________________________________ 32 5.2. Running of RIPS______________________________________________________________ 34 5.3. Output example________________________________________________________________37 5.3.1. Output with plank lines diagonal to the edges____________________________________ 37 5.3.2. Output with plank lines parallel to the edges______________________________________ 38 5.3.3. Discussion o f results_________________________________________________________ 39 6. PROGRAM____________________________________________________________________ 41 6.1. DXF Files_____________________________________________________________________ 41 6.1.1. Structure of a DXF file ______________________________________________________ 41 6.1.2. Entities Section_____________ 43 6.2. Specification __________________________________________________________________44 6.2.1. Principle of Algorithm over the shape___________________________________________ 45 6.2.2. Algorithm for one finite element grid___________________________________________ 46 7. PROGRAM DESIG N___________________________________________________________ 50 7.1. Classes needed for reading the DXF-file__________________________________________ 50 7.1.1. DXFgroupCode______________________________________________________________51 7.1.2. DXFassocValue_____________ 51 7.2. Classes needed for the finite element mesh________________________________________ 54 7.2.1. Point_______________________________________________________________________ 54 7.2.2. Point member functions_______________________________________________________ 54 7.2.3. Line_______________________________________________________________________ 54 7.2.4. Line member functions_______________________________________________________ 55 7.2.5. Face_______________________________________________________________________ 55 7.2.6. Face member functions_______________________________________________________ 56 7.2.7. Shape______________________________________________________________________ 56 7.3. Inter-relationship of finite element classes________________________________________ 58 7.4. Classes needed for the algorithm of the plank line ________________________________ 60 7.4.1. PlankPoint__________________________________________________________________ 60 7.4.2. Member function “set_directionX” _____________________________________________ 61 7.4.3. Geometry3D library_________________________________________________________ 62 7.4.4. LocalAxis________________ 64 7.5. Structure of the main program_________________________________________________ 65 8. PROGRAM VALIDATION______________________________________________________70 9. PROGRAM OPTIMIZATION____________ 75 iv Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 9.1. Problems related to AutoCAD___________________________________________________ 75 9.1.1. Text strings longer than 255 characters___________________________________________ 75 9.1.2. Saving in DXF-format_________________________________________________________ 75 9.1.3. Conversion form AutoCAD 2000 to AutoCAD 14_________________________________ 76 9.2. Problems related to the c o d in g __________________________________________________ 76 9.2.1. Static arrays — dynamic arrays__________________________________________________ 76 9.2.2. Interactive user interface___________ 76 9.3. Improvement of the logic design and user input___________________________________ 77 9.3.1. Connecting two edge points_____________________________________________________77 9.3.2. Bending Check________________________________________________________________ 78 9.3.3. Intersection Points_____________________________________________________________78 9.3.4. DXF-format__________________________________________________________________ 78 9.3.5. Proposing meaningful solutions__________________________________________________ 79 10. CONCLUSIONS________________________________________________________________80 11. BIBLIOGRAPHY_______________________________________________________________ 81 11.1.1. Books______________________________________________________________________ 81 11.1.2. Journals____________________________________________________________________ 81 11.1.3. From the World Wide W eb____________________________________________________82 11.1.4. Companies, Institutes_________________________________________________________ 82 12. APPENDIX 83 12.1. DXF-sample file________________________________________________________________83 12.1.1. Picture of the original AutoCAD drawing________________________________________ 83 12.1.2. DXF source file ______________________ 83 12.2. Program co d e_________________________________________________________________ 97 12.2.1. RIPS.cpp___________________________________________________________________ 97 12.2.2. PlankLine.h_______________________________________________________________ 119 12.2.3. PlankLine.cpp______________________________________________________________ 132 12.2.4. Geometry3D.h______________________________________________________________ 161 12.2.5. Geometry3D.cpp____________________________________________________________ 166 v Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. LIST OF FIGURES Fig. 1: Energy use and CO2 production (and stocking) o f different construction materials_______ 4 Fig. 2: Some possible shapes___________________________________________________________ 6 Fig. 3: Construction principal o f the ribs_________________________________________________ 7 Fig. 4: Properties of a timber plank_____________________________________________________ 7 Fig. 5: Rough structure, mounted_______________________________________________________ 9 Fig. 6: Edge detail, from below and above______________________________________________ 10 Fig. 7: One of the four comer details, with foundation.____________________________________ 10 Fig. 8: During mounting. The planks bend naturally in their weak axis o f inertia._____________ 10 Fig. 9: Model of the roof structure for the central fair o f EXPO 2000, Hanover, Germany______ 11 Fig. 10: Drawings o f the roof shape for the EXPO 2000___________________________________ 11 Fig. 11: Construction principal o f the wave shaped shed roof structure_______________________12 Fig. 12: Axonometric view from the outside of a part of the structure________________________13 Fig. 13: Plan view. Note that the plank lines are S-shaped in plan view.______________________13 Fig. 14: Examples o f membrane design by ’’Cadisi” and “Isimem” from Technet GmbH._______17 Fig. 15: Examples o f cutting pattern design by ’’Easy” from Technet GmbH._________________ 18 Fig. 16: Existing computer tools_______________________________________________________ 19 Fig. 17: Integration o f the new computer tool____________________________________________20 Fig. 18: Integration o f RIPS__________________________________________________________ 22 Fig. 19: Sphere: indicated curve is not a valid plank line! The others (great circles) are valid 24 Fig. 20: Cylinder cut with two-dimensional planes. (The oblique line is not a valid plank line!) 24 Fig. 21: Local Coordinate System_____________________________________________________ 26 Fig. 22: Two different groups o f shapes: geometrically definable shapes and free form shapes 28 Fig. 23: Schematic representation o f the finite element approach___________________________ 30 Fig. 24: Different finite element mesh densities__________________________________________ 31 Fig. 25: Step one: draw four “polylines”________________________________________________ 32 Fig. 26: Step two: draw an edge surface________________________________________________ 33 Fig. 27: RIPS - user prompt for file name______________________________________________ 34 Fig. 28: RIPS - user prompt for number of ribs__________________________________________ 35 Fig. 29: RIPS - user prompt for start directions__________________________________________ 35 Fig. 30: Definition o f starting angles___________________________________________________ 35 Fig. 3 1: RIPS - user prompt for plank line______________________________________________ 36 Fig. 32: Definition o f Start Positions___________________________________________________ 36 Fig. 33: Original finite element mesh drawn in AutoCAD (surftabI = suftab2 = 24)___________ 37 Fig. 34: Output with plank lines diagonal to the edges____________________________________ 38 Fig. 35: Output with plank lines parallel to the edges_____________________________________ 38 Fig. 36: Output with plank lines from two opposite edges__________________________________39 Fig. 37: Output of crossing plank lines (Zoom)__________________________________________ 40 Fig. 38: Part of a DXF-file____________________________________________________________42 Fig. 39: Example of a 3DFACE in DXF-format_________________________________________ 43 Fig. 40: Visualization of a sub-line (part o f a plank line within one finite element grid)________ 45 Fig. 41: Definition o f local coordinate system___________________________________________ 46 Fig. 42: Plan view and elevation o f a finite element grid__________________________________ 47 Fig. 43: X-orientation of the X-axis____________________________________________________ 47 Fig. 44: Cross product of two vectors in the plane gives Z-axis (normal to the plane)__________ 48 Fig. 45: Cross product of Z-axis and X-orientation gives Z-axis (tangential to the plane)_______ 48 Fig. 46: Cross product of Z-axis and Y-axis gives the X-axis (tangential to the plane)_________ 48 Fig. 47: Intersection o f the XZ-plane with the edge of the finite element_____________________ 49 Fig. 48: Classes “DXFgroupCode” and “DXFassocValue”_________________________________50 Fig. 49: Storing data in Entity Array___________________________________________________ 52 Fig. 50: Sample section o f a DXF-source file showing two typical problems_________________ 53 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Fig. 51: Point class__________________________________________________________________ 54 Fig. 52: Line class___________________________________________________________________55 Fig. 53: Face class___________________________________________________________________55 Fig. 54: Shape class_________________________________________________________________ 56 Fig. 55: Finite element mesh classes___________________________________________________ 57 Fig. 56: Organization of finite element mesh classes before redistribution o f Lines and Points 58 Fig. 57: Final organization o f finite element classes, after redistribution o f Lines and Points____ 59 Fig. 58: PlankPoint class_____________________________________________________________ 61 Fig. 59: Precondition o f PlankLine class________________________________________________ 62 Fig. 60: Member function “set_directionX”_____________________________________________ 63 Fig. 61: Postcondition o f PlankPoint class______________________________________________ 63 Fig. 62: LocaLAxis class______________________________________________________________64 Fig. 63: Precondition o f LocaLAxis class________________________________________________ 64 Fig. 64: Postcondition o f LocaLAxis class_______________________________________________ 64 Fig. 65: Graphic representation o f entity Array___________________________________________ 66 Fig. 66: Graphic representation of arrayOfFaces_________________________________________ 67 Fig. 67: Finite element mesh before redistribution of Lines and Points_______________________68 Fig. 68: Finite element mesh after redistribution o f Lines and Points________________________ 69 Fig. 69: Free shape__________________________________________________________________ 70 Fig. 70: Hyperbolic-paraboloid Shape__________________________________________________ 71 Fig. 71: Hyperbolic-paraboloid shape with parallel lines__________________________________ 71 Fig. 72: Anticlastic shape (similar to roof EXPO 2000, see “examples of executed projects”) 72 Fig. 73: Barrel Vault_________________________________________________________________72 Fig. 74: Spherical Shape (similar to Polydome, see “examples o f executed projects”)__________72 Fig. 75: Spherical Shape, with sloping edge arc__________________________________________ 73 Fig. 76: Spherical Shape, with vertical edge arc__________________________________________ 73 Fig. 77: T T ie “Line” may not be able to connect to the “Endpoint”__________________________ 78 vii Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. ABSTRACT This thesis is about a computer program developed to compute the crossing points o f two directional plank system lines on an arbitrary smooth surface curved in a three dimensional space. Plank lines are lines on a surface over which a wooden plank can be laid out without breaking. Given its small th ickness and large width, a plank can be bent only in one direction (direction o f its thickness) but not in the perpendicular direction. The program therefore computes lines with the tw o following main properties: curvature is allowed only in the direction normal to the plane, and the imaginary width o f the line is constrained to lie tangential to the surface. LJltimately, the program is to help the design process o f timber rib shell structures. Keywords: Geodesic lines, plank system lines, finite element algorithm, rib timber shell structures, lightweight structures, timber construction, C++ Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 1. INTRODUCTION Wood construction will be a big application field in the future. Wood is the only renewable construction material available; it is cost efficient; it has excellent structural characteristics and good energy economy. The main reason why it is not used more often, especially for large structures, is because it demands a considerable planning effort, more than steel and concrete structures. Since the structure itself is usually less expensive than concrete or steel, and with planners’ contracts based on the end construction cost, a planning office is usually confronted with a very small design budget, or even a loss. This tool should help to simplify the planning process and help timber construction to gain a larger field o f realization, especially for rib shell structures. 1.1. Hypothesis The following hypothesis is the basis o f this thesis: Every double curved surface has a certain number o f lines that bend with one degree o f freedom only. A computer tool can be developed that determines those lines geom etrically and shows them graphically and numerically. 1.2. Problem Definition This thesis describes a computer program created to help the architect and structural engineer in the design process of timber rib shell structures. This specific program applies only to a limited scope o f structures. The following two chapters describe the timber rib shell structures in order for the reader to fully understand the use o f the computer program. Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2. HISTORICAL BACKGROUND The development in construction has shown strong tendencies towards large span roofing. Three dimensional membrane structures are an efficient way to cover large spans. Under static considerations, the optimal shape o f a membrane for any load is a shape with no bending stress in the structure, (membrane shapes). Only tensile forces (respectively only compression forces for an inverse shape) are present. Frei Otto was one o f the first and most important developers o f these kinds o f structures. Many o f his ideas have been realized (Roland, 1970). Otto’s research focused on form finding o f optimal shapes for membranes. As computer and three dimensional drawing tools were not yet available, this was not an easy task. Most o f his projects have been designed with the help o f physical models, which were photographed to find out the optimal configuration and to make the construction drawings (Otto, 1967). Later, computer programs have been developed to help the form finding and design process. As example figure the paper about a search method for finding the minimal surface o f quadrilateral shapes, by Schierle (1977). Another example is the program “Cadisi”, by Technet GmbH, Germany (http://www.technet-gmbh.com), which is a form- finding tool for membrane shapes. For given boundary conditions, the program finds the shape with the minimal surface, which is the same surface than the one which a soap bubble would have, strained over the same boundary lines. Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2.1. Today’s challenge: timber structures The shape o f the minimal surface, mentioned above, is perfect for textile structures as w ell as for isotropic1 , cast materials like concrete, which can take any arbitrary form. For concrete structures, the membrane shape would typically be inversed, in order for the structure to work in compression rather than in tension. But it is more difficult to design the optimal shape (especially what concerns the design o f the structural elements) for anisotropic? structure systems like rib shells made o f wooden planks. This construction method is quite new but promises increase in application because o f its cost efficiency, esthetics, structural performance (it covers large spans and is lightweight), and it uses renewable materials. Planks in particular are (in the opposite o f highly processed timber products like particle boards and glue-laminated girders) an optimal construction material in consideration o f the issues o f gray energy, o f recycling, limitation o f toxic components. As a bad example for gray energy use, consider the particle boards in prefabricated w ood frame structures. It is not unusual for the timber components o f the board to travel more than once around the globe, before they find a final destination as a built-in state. By contrast, a plank is a direct product o f the saw-mill. Saw-mills get the wood most o f the time from nearby forests. If the timber industry is governed by locals, it is also more likely that these peoples entertain healthy forests which gives them income, protection, and leisure (Natterer, 1996). 1 Isotropic: material with the same elastic properties in both x and y directions 2 Anisotropic: material with different elastic properties in x and y directions Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. DEPENSE ENERGETIQUE ET EMISSION DE CO 2 POUR LA FABRICATION D'UNE POUTRE SIMPLE pcids propre : (voir ci-dessous) charge permanente : 75 kg/m surcharge: 300 kg/m L- 7.50 m ALUMINIUM BETON SECTIONS 'I poids propre : 5 216 En6rgie consommee [GJ] 15- 1 0 - 5- 16.5(330) avec recyclaga [ * l 5.0 (100) 1 3.8 (76) ■ Energie stockee [GJ] S . ACIER BOIS T I Ijl 15 29 300 mm _L_ COz d igage [kg] I L - (300) - (200) -( 100) (0) 0.3 (6.5) T 5.0(100) H100) COz stocke [kg] EPFL IBOIS Ecole polytechniaue Federate de L ausanne CHAIRE DE CONSTRUCTION EN BOIS Professeur: Julius NATTERER Fig. 1: Energy use and C 02 production (and stocking) o f different construction materials Figure 1 shows timber compared with other construction materials regarding energy use and CO2 production (respectively stocking o f CO2 for wood, as long it is in a build in state. When wood bums or perishes, it releases the stocked C 0 2 to the atmosphere, which closes the cycle and sets the end balance to zero). Source IBOIS, Switzerland. 4 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. The physical properties o f a wooden plank are governed by the fibers grown in its longitudinal direction. This leads to a structural behavior that is different from those o f a soap bubble. A lso, the dimensions o f the structural elements are lim ited to the naturally grown dim ensions o f a tree. The behavior o f the structural elements and feasibility o f the construction is therefore an important factor for finding the ideal form. In comparison with a concrete or steel structure, it is often easier to build an equivalent structure in timber, and it also needs few er and simpler construction installations. But the timber structure needs more thinking and planning effort, especially in the early design process o f the project, for the structure to be executable and to avoid very cost intensive details. Som e possible shape configurations are presented below (Fig. 2). The m odels result from a research study about the optimal shape o f the structure and distribution o f the ribs, in consideration o f structural performance and stress distribution, by IBOIS, Switzerland. Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Fig. 2: Some possible shapes The typical construction o f rib shell structures consists o f wooden planks to form the ribs. These planks are approximately 3x 16 cm, and several interlocked layers are used to form each rib. The planks are screwed together, usually without glue. Each layer o f planks is continuous in one direction. The gaps between the continuous layers are filled with filling boards, which contribute to the stiffness o f the structure. 6 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Fig. 3: Construction principal of the ribs (without filling boards) The problem o f this technique is that planks can easily be curved in one direction (in their weak axes o f inertia) but they break if bertt in the direction o f their strong axes o f inertia (Fig. 4). This implies that the planks hav& to be laid out in the direction where the shape is curved in one direction only. Plank curved in its weak axis o f inertia (Curvature exaggerated!) , Plank curved in its strong axis of inertia. This is impossible without failure o f the plank Fig. 4: Properties o f a timber plank To find these lines for a given shape is a geom etrical problem that can usually be resolved with mathematical formulas, but until n o w no specific computer tool exists for Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. computing those lines. The ideal is to have a tool that interacts with the common computer tools used by architects, structural engineers, and carpenters; for instance, AutoCAD, Cadwork, and structural analysis programs. 2.2. Existing Timber Rib Timber Shells The leading player for this type o f structures is Julius Natterer, Professor at the Federal Technical Institute in Lausanne (EPFL, Switzerland), and chair for the Institute o f Timber Construction (IBOIS, Switzerland). He is also the chief and owner o f the two timber engineering offices Bois Consult Natterer (BCN, Switzerland), and Internationales Entwicklungszentrum fur Holzkonstruktionen Natterer GmbH (IEZ, Germay). Since he developed the first prototype o f this kind, the Polydome, Lausanne, in 1991 (see section 2.3), several ribbed timber roof structures have been built in Switzerland, Germany, and France, for all kinds o f different uses (exposition halls, sport halls, equestrian centers, kindergartens, swimming pools, and temporary structures), o f different shapes (barrel vault, spherical domes o f different base sections, and anticlastic membranes) and for different spans (from 10 m to 40 m). With more structures in planning, the demand is steadily growing. A few examples are presented below (Fig. 5 to Fig. 13), for more examples refer to Natterer, Herzog, and V olz (1998). All examples, which are presented here, were executed by Bois Consult Natterer (BCN, Switzerland), except the Expodach (Fig. 9), which was executed by IEZ Natterer (IEZ, Germany). Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2.3. Examples of executed projects 2.3.1. Pilot project “Polvdome”. Lausanne. Switzerland. 1991 This is the first rib shell structure o f this type executed. It was part o f a research project about wide span structures, funded by the Federal Technical Institute o f Lausanne (EPFL, Switzerland), and planned by IBOIS, under Professor Julius Natterer. The roof is a partial sphere, approximately 25 x 25 m2 in plan, with a height o f 7 m. The radius o f the sphere is 27.5 m. The wooden planks follow the great circle lines o f the sphere (Fig. 5 - Fig. 8) (Hoeft and Kaelin, 1992). Fig. 5: Rough structure, mounted Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Fig. 8: During mounting. The planks bend naturally in their weak axis o f inertia. Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2.3.2. Expo 2000. Hanover. Germany For the central fair area o f the EXPO 2000, a long span roof structure o f a total o f ten square umbrellas has been constructed. Each umbrella covers a basic surface area o f 40 m x 40 m and is approximately 25 m high. The umbrellas consist o f four anticlastic shell surfaces that cantilever approximately 26 m and are suspended at four cantilever masts. This is currently the largest timber rib shell structure. Below (Fig. 9) is a photograph o f a model. The construction is now finished. Further details can be seen on the World Wide Web (http://www.expodach.de). Fig. 9: Model o f the roof structure for the central fair o f EXPO 2000, Hanover, Germany AutoCAD Drawing/JL AutoCAD Drawing/JL Fig. 10: Drawings of the roof shape for the EXPO 2000 11 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2.3.3. Airport. Kloten. Switzerland. Competition This wave shaped shed is a proposal for a roof structure competition for the Kloten airport, in Zurich, Switzerland. The structure has a span o f 10 m x 10 m, a width o f 22 m, and is repeated over a length o f 400 m. It has not been built. BCN Natterer BCN Natterer BCN Natterer Fig. 11: Construction principal o f the wave shaped shed roof structure Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2.3.4. Temporary hall for galley construction. Morges. Switzerland. 1996 This hall is a temporary structure for the reconstruction o f a 55m long galley, o f the type the French had in the 17th century. The construction work was done by unemployed workers and supported by the state office o f the canton o f Vaud and the Federal O ffice for Industry, Arts, Craft, and Work o f Switzerland (OFIAMT). The structure had to be easy in order to be executed by unskilled workers and at low cost. The hall consists o f a barrel vault o f a 19 m span and a length o f 60 m. Outside trusses are the lateral stabilization system. Further details can be seen on the World Wide Web (http://www.galere.ch). BCN Natterer Fig. 12: Axonometric view from the outside of a part of the structure BCN Natterer Fig. 13: Plan view. Note that the plank lines are S-shaped in plan view. 13 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2.4. Choice of shapes These four examples show us that the applications are diversified, from very challenging projects like the main fair roof o f the EXPO 2000, to simple temporary structures like the construction hall for the galley. The structural system is competitive in cost and structural capacity with conventional structural systems. The actual inconvenience o f the system is the limited choice o f possible shapes. The examples shown have a cylindrical or spherical shape, which is relatively easy to design. When the shape is more difficult, like for the hyperbolic-paraboloid shaped roof o f the EXPO 2000, or for the wave shaped roof o f the Kloten airport, the planning effort actually necessary for the structure gets extensive and too expensive to fit in the budget o f most projects. 14 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 3. EXISTING DESIGN METHODS 3.1.1. H ow is the design o f the rib shell structures being done today? In the normal design or planning process, it is the architect who defines the overall shape o f a project. He/she decides which materials to use, what form the building will take, and its size. He/she represents the ideas in plans, mostly drawn in AutoCAD or other CAD system. T he structural engineer takes these plans and designs the structural load bearing structure, within the limits given by the architect’s first drawings. The calculations show sometimes that modifications are necessary in the architect’s design in order to execute a cost efficient project. If the structure meets with the overall design, both architect and engineer can proceed with the detail design. For conventional construction methods, this process is straightforward, because the architect and engineer know the usual dimensions and executable techniques. For unconventional construction like rib shell structures, the back and forth interaction between architect and engineer (until a satisfying solution is found) can cost considerable time and money. Each time the engineer has to thoroughly analyze the structure before he can give an answer to the architect, and the architect may then not be satisfied with the solution, because he/she has certain objectives that he and the client wish to achieve. Each optimization process implies changes, and the goal o f a good collaboration between different designers (architects and engineers) is to react quickly, to adopt these changes easily, and quickly come to a correct, satisfying resolution. Computers make this process possible and easier. It can take merely seconds to change a line in a drawing and to run a structural analysis on a structure. Only the manual part o f the work is time consuming^ for example, to input manually a structure in a structural analysis program, or 15 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. to draw a new structure form scratch. The goal o f a good optimization process is therefore to apply the computer to the slowest link in the process. For existing projects, one o f the following two planning methods had been applied: • For small projects with low budgets, the planner was limited in his choice o f shapes. The shape had to be a simple geometric form, i.e. a part o f a cylinder (barrel vault) or a part o f a sphere. This way the plank lines could be found graphically with a three-dimensional drawing program. The disadvantage o f this method is that not only the planner is limited in his choice o f the shape, but also the geometrically easy form is structurally not ideal; it is in areas of concentrated stresses it is too flat, which creates buckling problems. And last but not least, it is an enormous effort to find these lines graphically, because conventional drawing programs are not equipped to easily draw curves in a three-dimensional space. • For more complex structures, a mathematician was hired as a subcontractor. He used to calculate the lines for the particular shape (with geometrical equations). For the optimization process this is inconvenient and cost intensive. For each modification o f the shape, he had to be contacted again to recalculate the points. The actual planning process lacked a tool to be able to automate the work o f the mathematician. The tool needs to sim plify the planning process by computing the lines through which planks can run. The structural engineer must have a quick interface between the architectural drawing, (which gives the overall shape but not the structural elements) 16 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. and his structural analysis program, (which needs as input the load bearing structure). With this tool an optimization process becomes possible and easy, because there is only one simple step between the modification o f the shape and the input in the structural analysis program. The shape can therefore be adapted in function to the deformation stress output. 3.2. Existing Computer Tools Existing computer tools in this planning process are three-dimensional drawing programs, structural analysis programs, and form finding programs Both CAD programs and structural analysis programs are well developed today, relatively user friendly, and affordable even for small companies. Most planning offices are computerized and also have Internet access. This makes data exchange fast and simple between different offices. Data exchange between different software programs is fairly straightforward. The most common universally adapted graphical data exchange interface is the DXF-format. There are also several form finding tools available on the market. One software for example is ‘Tsimem / Cadisi” from Technet GmbH (http://www.technetgmbh.com) (Fig. 14). ^ O i k i i m ~ B i l A l g r e r Fig. 14: Examples o f membrane design by ’’Cadisi” and “Isimem” from Technet GmbH. 17 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Form-finding tools are helpful for the design o f membrane structures. They compute the minimal surface o f a tensile structure. This is not to be confused with the computer tool described in this paper. The plank line computer program is NOT a form finding tool; it is NOT supposed to FEND the form, but to find out certain lines on a GIVEN form (for instance given by Cadisi). Form-finding tools and the plank line program are therefore not competing, but complementary programs. Considerable work has already been done in the field o f fabric structures. A problem similar to finding the plank: line is the cutting o f fabrics for membrane structures. Easy, another software from Technet GmbH, has as one o f its options the computing o f cutting patterns (Fig. 15). The problem is similar to the plank lines. The fabric patterns have to be able to be flattened on a plane; the seams can be approached with semi-geodesic lines (Griindig, Ekert, and Moncrieff, 1996). However, in detail it is a different problem, a plank has other laws than fabric patterns. For example, a seam can easily have a curvature in the tangential plane, as it can b e seen in the pattern example below, which is not allowed for a plank line. Curvature in tangential plane! Fig. 15: Examples o f cutting pattern design by "Easy” from Technet GmbH. 18 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 3.3. Inter-Relationship of Existing Computer Tools The flowchart (Fig. 16) shows the existing computer tools and how they work together. Note that the design phase does not include the design o f structural elements. Defining the appropriate location o f the structural element can only be done manually, due to the lack o f an appropriate computer tool. Design-Phase: 3D CAD Program AutoCAD, FormZ, Cadisi etc Execution-Plans: 2D CAD Program AutoCAD, CADwork, etc Interface between the different tools: DXF-file form at Structural Elements: Defining manually the location o f the structural elements, with geometrical equations. Help tools: 3D CAD Program AutoCAD, CADwork it Structural Analysis: Finite Element Program SAP, RSTAB, etc ---------------- Fig. 16: Existing computer tools Legend: • AutoCAD (http://www3.autodesk.com/adsk): 2D and 3D CAD tool mainly used by architects for design and execution plans. • CADwork (http://www.cadwork.ch): 2D and 3D CAD tool specialized for wood structure. It is mainly used by wood structure engineers and carpenters, for design and execution plans. It is also compatible with CNC-cutting machines. • SAP, RSTAB (http://www.dlubal.de): Structural analysis tool. SAP and RSTAB figure as examples. Any three dimensional finite element tool can be used. It needs to be able to handle beam elements but no surface or plate elements are needed. It must be able to perform stability calculations in the second order. • Easy, Cadisi (http://www.technet-gmbh.com): Form finding tool. Easy and Cadisi figure as examples. For given border conditions and prestress they give the shape o f a 19 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. surface in pure tension. Easy also computes cutting pattern optimization for fabric tensile structures. • DXF: Most commonly used file format to transfer graphic data between AutoCAD, CADwork, and structural analysis tools. 3.4. Integration of the New Computer Tool The flowchart (Fig. 17) shows the ideal process with an optimal performance o f the new tool; in order achieve a smooth process for the optimization o f the design o f timber rib shell structures. Design-Phase: 3D CAD Program AutoCAD, FormZ, CADISI, etc Interface between the different tools: DXF-file Format Execution-Plans: 2D CAD Program AutoCAD, CADwork, etc New Tool; Structural Analysis Designs the Finite Element Program location o f the SAP. RSTAB structural elements (Plank Lines) Fig. 17: Integration of the new computer tool The architect determines the boundary conditions and surface o f the structure. He can use a form finding tool for finding the optimal shape o f a tensile or compression shape or use any other drawing program to design a needed shape. 20 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. The geometry o f the shape is imported into the new tool with an appropriate interface (DXF format). Through a user interface, the structural engineer is asked to input the maximum spacing distance and main direction o f the ribs, and thickness o f the planks. The new tool then calculates the geometry o f the plank lines and the intersection points. It also performs a check o f the relationship between the thickness of the plank and its curvature and twist. The geometry o f the ribs is then imported into the calculating tool. Static calculations have to be performed for verifying stability and stresses o f the structure. If the structure is not stable or stress limit is exceeded, wood quality and/or sections have to be increased, or the shape has to be modified. Once the structural requirements perform well, the geometry o f the shape and the ribs can be imported into AutoCAD or other drawing program. Execution plans can then be drawn and the structure can be built. The ideal configuration is that the new tool is able to handle any kind o f DXF-file and shape. This is not the case with this computer program in its current version. It handles only surfaces with four edges and consisting o f 3Dfaces (see section 5.1). 21 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 3.5. Integration o f RIPS The program developed in this thesis is called RIPS, which stands for "Rib structure Interactive Plank System lines ”. As it is developed so far, it is not able to satisfy all the criteria o f an ideal tool mentioned above. The most important limitation consists in the necessity that the original DXF-input file has to have a specific configuration, which is obtained by following a special series o f steps in AutoCAD. The input must therefore be an AutoCAD drawing and some other limitations have to be respected, which will be described later. The integration o f RIPS in the actual design process is shown below (Fig. 18). Design-Phase: AutoCAD only! Interface between the different tools: nXF-file Format Structural Analysis: ** SAP, RSTAB, etc Finite Element Program Execution-Plans: 2D CAD Program AutoCAD, CADwork, etc Fig. 18: Integration o f RIPS 22 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 4. PROGRAM OBJECTIVES Again, the goal o f this computer program is NOT finding a shape, but computing lines on a GIVEN shape. Specifically, that means, the lines have to lie in the given surface. The properties o f the line are defined by the natural properties o f a wooden plank. Wood is an organic material, anisotropic, and with an excellent elastic behavior. For the purpose o f the computer program, two characteristics are crucial: the ability o f wood to bend in its long direction and the width o f the plank has to be tangential to the surface. Wood can be bent to a radius r > d * 200 without deficiency in its structural characteristics (r = minimal radius o f the curvature, d = dimension the wooden section in the bend direction). For a typical plank o f 2.5 cm x 15 cm that means that r > 5 m in the weak axis o f inertia and r > 30 m in the other axis. Practically, it can be said therefore that curvature normal to the surface is allowed, but curvature tangential to the surface is not allowed. Also twist (torsion) is allowed to a small degree. It could be further analyzed how much twist is allowed and how much the efficiency o f strength o f the wood is decreased by a certain bending or/and twist o f a plank, but this is not the focus o f this thesis. Since in the program would be just a simple parameter being applied to perform a twist and bend check, no further analysis is done in this direction. It is simply assumed that curvature in the normal direction and twist is allowed (subject to the judgment by the designer), and curvature in the other plane is not allowed. Another parameter to be respected is that the width o f the plank has to be tangential to the surface. This becomes obvious in the construction by the layering o f the planks and also for covering them (Fig. 19). Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Not a Plank Line! Fig. 19: Sphere: indicated curve is not a valid plank line! The others (great circles) are valid It becomes obvious in the next picture (Fig. 20), that a plank line is not simply obtained by cutting a shape with a two-dimensional plane. The picture represents a cylinder cut with two-dimensional planes. The oblique band drawn around is only feasible with a plastic material like clay, but no wooden plank can be forced to take this track. The horizontal band is a plank line, but is not useful structurally. Fig. 20: Cylinder cut with two-dimensional planes. (The oblique line is not a valid plank line!) 24 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 4.1. Definitions Considering the lines’ characteristics, geodesic lines come to mind. In the literature the following definition o f a geodesic line can been found: Geodesic Line - The shortest line on a mathematically derived surface, between two points on the swface. Also called geodesic. A geodesic line on the spheroidal earth is called a geodetic line (Parker, 1970). Geodetic - 1. The circle on the spheroid midway between its poles o f revolution. The geodetic equator is the line o f 0 ° geodetic latitude 4 from which geodetic latitudes are reckoned, north and south, to 90 ° at the poles. The plane o f the geodetic equator cuts the celestial sphere in a line coinciding with the celestial equator, because the axis o f the spheroid o f reference is by definition parallel to the axis o f rotation o f the Earth. 2. For the geodesic line from A to B, the angle between the tangent to the median at A and the tangent to the geodesic line at A. In the United States Coast and Geodetic Survey, this angle is measured clockwise from south. This azimuth is called the forw ard azimuth for the line AB. The angle between the tangents to the meridian and to the geodesic line at B is called the back azimuth fo r the line AB. Because o f the convergence o f the meridians, the forw ard and backward azimuths o f a line do not differ exactly by 180 ° except where the two end points have the same geodetic longitude or where the geodetic latitudes o f both points are 0 ° . The geodesic line is not, except in special cases, a plane curve. For short lines o f the length commonly used in triangulation, the small difference between the geodesic line and the plane curve actually observed may be neglected (Meteorology Group, 1997). Some sources disagree: It is extremely common for geodesics to be defined as ‘The line o f shortest distance between two points on a surface, passing over that surface. ’ This definition is false, though it is certainly true that any line satisfying the condition will be geodesic. The problem with the definition is that in certain situations there may be more than one geodesic line between the two points. For example, consider the simple cylinder where there are an infinite number o f geodesics, only one o f which is shortest; or the poles o f a sphere, which are connected by an infinite number o f geodesics, all o f equal length. It is imfortunate that this incorrect definition has become so popular, in that it emphasizes the length aspect rather than the angular nature o f the geodesic property. It is the fa ct that a geodesic is straight which leads to its excellent suitability fo r seam generation in textile architectural applications (Griindig, Ekert, and Moncrieff, 1996, p.5). Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Geodesic lines are m ostly used to describe a sphere, i.e. earth, and then called a Geodetic. The popular w ay o f describing a geodesic line as the shortest distance between two points seems not to be the correct way. Either way, the definition is restricted to a mathematically derived surface, which is not the approach chosen in this thesis (see following section). In order to resolve the problem, it is not crucial to know the exact definition o f a geodesic line, as long as the properties o f the line are known (which they are). The term “geodesic line” will not be used for this thesis. The term “plank line” is used instead to describe the line with the properties o f a wooden plank. The plank line’s distinct properties are listed as follows: Imagine a local coordinate system following the direction o f the plank, with its x-axis in the direction o f the plank’s long dimension, its y-axis in the tangential plane o f the surface and its z-axis normal to the surface (Fig. 21). Rotation about Z (NOT ALLOWED!) Rotati Curvaturi Rotation about X , Torsion Fig. 21: Local Coordinate System 26 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. • Rotation around x is allowed (twist o f plank) • Rotation around y is allowed (curvature o f plank over the shape) • Rotation around z is forbidden (rotation in tangential plane, the plank would break!) • Displacement in x direction: is the direction the plank actually runs over the surface • Displacement in y direction is forbidden (this implies shear in the plank) • Displacement in z direction is allowed as long as it is due to the curvature o f plank over the shape. Simple displacement in z, which is not due to the curvature, implies shear and is not allowed. • An imaginary width o f the line, corresponding to the width o f the plank, or to the y-axis o f the line, must at all points be tangential to the surface. Note: These rotations and displacements are according to a local coordinate system, which changes its orientation in each single point o f the plank! Given these properties, it is possible to make a computer program that computes plank lines for a given shape. 27 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 4.2. Finite Element Approach The goal o f the program is to process the DXF-file o f an architectural drawing o f the shape, to compute the crossing points o f two perpendicular (or in a user defined angle to each other) series o f piank lines, and to export the result in DXF-format again, in order to view it in AutoCAD or to run structural analysis. The user has to be able to input, through a user interface, the number and/or distance o f the planks as well as the angle o f the plank to the board. RIPS will not perform structural analysis. The three above-mentioned parameters (number o f planks, distance between the planks, and angle) have to be optimized with the help o f a structural analysis program, or they are the judgment from an experienced user, familiar with this kind o f structures. The possible shapes o f rib shell structures can be divided into two different groups: geometrically definable shapes (spherical, cylindrical, anticlastic, hyperbolic-paraboloid shape, etc) and free form shapes, which cannot be described by geometric equations (Fig. 22). Cylindrical shape Wave shape Free form Spherical shape HP-shape Fig. 22: Two different groups o f shapes: geometrically definable shapes and free form shapes 28 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. There are also at least two different ways to approach the problem for finding the plank lines: mathematically by analyzing the geometric properties o f the shape or with a finite element approach. By resolving the geometric equations, the user has to know what kind o f shape the surface has. Also, for each different form, the problem is different and has to be resolved by different equations. Third, free forms that can’t be described by geometric equations (or the equations are not known) would not be possible to analyze. Because o f these reasons, the program is based on a finite element approach. For finite element programs the solution is approached by dividing the problem into many small problems (finite elements) o f the same kind. One o f these small problems is easy to resolve. Repeated calculations, as many times as there are finite elements, the whole problem gets resolved. In the case o f the plank line over the shape, the surface is divided in many parts (rectangular or triangular plane surfaces), and the plank line is found step by step, starting at the edge, where direction and starting point are known. The other edge o f this first finite element can be found, applying the plank line rules, without worrying about the rest. Once the other edge o f the finite element is reached, the process can be repeated for the next element, since the starting point and direction is now known for this next element as well, given by the previous element. The algorithm is repeated until the other edge o f the surface is reached. That establishes one o f the plank lines. The other lines are obtained in the same way (Fig. 23). 29 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Fig. 23: Schematic representation o f the finite element approach In conclusion, the finite element approach has the following advantages: • One and the same algorithm can be used for every kind o f shape -> simplicity, only one computer program for all different input shapes. • The grid o f the structure ' - already similar to the finite element grid. This means finding the solution in a way that is close to the initial design. • The initial shape will not have to be defined by mathematical forms; this gives more freedom in design, as architectural designs do not always want to follow mathematically definable lines. • The problem is broken down in many small, easier problems, which are all similar, but repeatedly applied, they solve the big problem. 30 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. However, the result obtained by finite element method, is not going to be the exact solution, but is a good approximation. The density o f the finite element grid (Fig. 24) defines the precision o f the result, but determines also the efficiency o f the program run time. The denser the grid, the closer the result to the exact solution, but also, the more time is needed for the execution o f the algorithms. Especially for large structures, this is an important factor. It has therefore to be decided where the reasonable medium is between the precision o f the result and the runtime efficiency. The user o f RIPS will have to be familiar with the use o f finite element meshes, because he sets up the original finite element grid himself. Fig. 24: Different finite element mesh densities 31 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 5. HOW TO RUN THE PROGRAM This section describes the preparation o f an AutoCAD drawing and how to run the program. At present, the program is not able to process all kinds o f input files. It is, therefore, necessary to proceed in a certain way to obtain a RIPS-compatible drawing. 5.1. AutoCAD drawing One goal o f the computer tool is to give the user maximum freedom about the shape o f the surface. However, RIPS needs a s input a specific type o f DXF-file. Specifically, the DXF-file has to contain a surface consisting o f 3Dfaces. This can be obtained by drawing the surface as described in the follow ing step-by-step example. 5.1.1. How to draw a surface in AutoCAD 1. Draw four lines that are connected together. Each o f the four lines can be a straight line, a curve, a polyline, or a combination o f the previous ones. The four lines can be situated anywhere in the three-dimensional space, as long as AutoCAD allows it. (The regular “polyline”-command allow s lines in a two-dimensional plane only. Use the “3dpoly”-command instead for lines outside a two-dimensional plane.) The endpoints o f the four lines must be connected to each other (Fig. 25). Fig. 25: Step one: draw four “polylines” 32 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 2. From the menu, choose: “draw - surface - Edge Surface” (equivalent to the command “edgesurf ’ ) , to approximate a mesh from these four polylines. The parameters “surf tab 1 ” and “sw ftab2” need to be set prior to the command to establish the density o f the mesh.. The mesh should be pretty dense. The mesh will be the finite element grid for the calculations o f the plank line. The denser the mesh, the more precise will be the result, but also, the more time consuming the calculations will be. A good density to start with are grids o f about 50 x 50 cm (Fig. 26). Fig. 26: Step two: draw an edge surface 3. Explode the mesh using the “explode” command. The RIPS program only works with 3Dfaces, which are being created with this command. 4 “Save as" (AutoCAD 2000) or “Export" (AutoCAD 14) the mesh in DXF-format, version AutoCAD 14. A DXF-file is then created, with the name given by the user, called here “ filename.cbtf". If multiple shapes or other elements are in the same drawing, only the surface that has to be processed by RIPS should be exported as a DXF-file. For this, delete all other elements and “purge” the drawing. If several surfaces have to be processed, the program has to run separately for each mesh. Selecting only the mesh in question (with “option”) whiie saving or exporting the file, will not create a correct DXF-file. 33 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 5.2. Running o f REPS 1. For the program to run, the following files have to be in the same folder on the hard drive o f a PC or Unix machine: • RIPS.exe • filename.dxf (file containing the shape, previously created in AutoCAD) Double click on RIPS.exe 2. The program w ill ask for the name o f the DXF-file, without extension. Type the file’s name (without extension) (Fig. 27). This command is not case sensitive, capital or lower case letters are considered being identical. B ■ B BB^B M R Hj B i n B ^ B l ^ B j n f l M f f l H B ^ B B ^ B ■1 B Fig. 27: RIPS - user prompt for file name 3. The program w ill ask for the number o f planks o f edge 1 and edge 2 (the number o f planks on one edge is the same as the number o f planks on the opposite edge) (Fig. 28). A higher number than the number o f finite elements on the particular edge is not allowed. The result would not be precise enough. The number to enter depends on the structure. A reasonable number is a plank distance o f about 1 m. (Defining the exact distance o f the planks is part o f the structural engineer’s task who has to run structural analyze on the system.) 34 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. i 1 A ■ | m B ■ H| H H i H M MBM BMBBMM MM MB MM Fig. 28: RIPS — user prompt for number o f ribs 4. The program w ill ask for two different starting angles (a l and a2) o f the lines (Fig. 29). The angles are defined as the deviation angle from one, respectively the other diagonal o f the shape, which connects two opposite comers (angle in degrees). An input o f 0° means that the plank lines are diagonal to the edges (Fig. 30). H i --------------------------------------------------------------------------------------- ------------------------------------------1 Fig. 29: RIPS — user prompt for start directions Second diagonal First diagonal al Fig. 30: Definition o f starting angles 35 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 5. Finally the program will ask on which edges the lines have to start (Fig. 31). From each edge it is possible to start with angle a l (FIRST series o f plank lines) and/or with angle a2 (SECOND series o f plank lines) (Fig. 32). ■ i ■ M B B | I 1 i b b b Fig. 31: RIPS — user prompt for plank line Second edge Fourth edge al Fig. 32: Definition o f Start Positions 36 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 6. The program will create a new DXF file, with the name “filename-OUT.dxf”. I f an identical file exists already, it will be overwritten. 7. The new DXF-file can now be opened in AutoCAD to view the results. The new points and lines are drawn in the default layer 0. For eventual modifications, the program has to run a second time. 5.3. Output example As example, a hyperbolic-paraboloid shape has been processed with RIPS (Fig. 33). Two different possible outputs are presented and discussed. Axonometric view Plan view Fig. 33: Original finite element mesh drawn in AutoCAD (surftabl = suftab2 = 24) 5.3.1. Output with plank lines diagonal to the edges Number o f planks on first and third edge: 15. Number o f planks on second and fourth edge: 17. a l = a2 = 0°. Plank lines with the start direction a l start at second and third edge, plank lines with start the direction a2 start at first and second edge. Which o f the edges is the first edge, has to be figured out by running a sample case (Fig. 34). Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 'ourth edge a . - > T ~ v k : ^ C J O ■ o u. * ! > ■ Second edge Fig. 34: Output with plank lines diagonal to the edges 5.3.2. Output with plank lines parallel to the edges Number o f planks on first and third edge: 10. Number o f planks on second and fourth edge: 10. a l = a2 = 45°. Plank lines with the start direction a l start at first edge, plank lines with start the direction a2 start at second edge (Fig. 35). Fourth edge •a < D C O Second edge Fig. 35: Output with plank lines parallel to the edges 38 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 5.3.3. Discussion o f results As can be seen, the program computes a series o f plank lines starting at a user-defined edge in a user-defined direction and spacing. Maximal two different directions are possible for each edge. (This makes sense structurally, because rib shell structures consist o f two directional series o f ribs.) The two directions are the same for the entire surface. In plan view, it appears that the direction is changing. This is due to the fact that the start direction is defined according to the world coordinate system. Applied to the finite element grids, which are each oriented differently, the resulting x-axis o f the plank system line comes out different. Maximal eight series o f plank lines could be calculated for a surface (two for each o f the four edges). However, this doesn’t make sense because the plank line from one edge to another is similar to the plank line from the endpoint back to the starting point. Ideally, these two lines should be exactly the same, but because the endpoint o f a line will most probably not end at the start point o f another plank line, and also because the start direction o f the new line is different form the ending direction o f the first line, these two lines will be different (Fig. 36). Fig. 36: Output wrth plank lines from two opposite edges 39 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. This leads us to the most important shortcoming o f the current version, which is that the user has only limited control over the ending point o f the plank line at the other edge o f the surface. Depending on the starting angle, the line finds its way over the surface independent o f where it will end. From a structural point o f view, the plank lines should meet all around the boundary lines. Another difficulty for structural implementation is that plank lines are supposed to be approximately parallel but occasionally happen to cross each other (Fig. 37). This is not an error o f the program. It is also due to the same fact that the line is not controlled by the endpoint, but by its starting direction according to the world coordinate system. Crossing lines are not a good structural solution however, and the input parameters will have to be changed (Larger spacing and/or different starting directions). Fig. 37: Output of crossing plank lines (Zoom) These points are further discussed in section 9 (program optimization). 40 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 6. PROGRAM The program code is written in C++, which is an object oriented programming language. A program written in C++ has the advantage that it is easily modifiable and extendable. Its structure consists o f independent objects, which can be modified, or others can be added, without knowing the details o f the rest o f objects. The following chapter describes the program and how it works. First the DXF-file structure is explained. Second, the specifications o f the program are presented, including a description o f the overall tasks. Then the specific program structure (design) is diagramed. For the complete code for the program, see the Appendix. 6.1. DXF Files The most common data exchange file format for data between different vector based drawing or structural analysis programs is the DXF-format. This was initially introduced by Autodesk, makers of AutoCAD (http://www3.autodesk.com/adsk). 6.1.1. Structure o f a DXF file In this section, the most important characteristics of an ASCII DXF-file are described. A complete example o f an ASCII DXF file is in the Appendix. Below is just a small section o f file (Fig. 38). 1 2 3 4 5 6 7 8 9 10 11 12 SE C T IOl HEADER Group code $ACAD' Associated value A C 1 0 1 A N S I 1 2 5 2 $ XNSBASE 41 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 13 10 14 0 . 0 15 20 16 0 . 0 17 9 18 $EXTMIN 19 10 20 - 9 4 9 .9 9 7 2 5 5 9 7 21 20 22 - 1 8 8 8 .7 7 4 3 4 9 9 5 etc... Fig. 38: Part of a DXF-flle This example shows the structure o f a DXF-file. It is a sequential file with one single information in each line. (Only bold signs are part o f the DXF-file, italic letters are added as reference) Every second line contains an integer. This integer is called “Group code”. The group code contains the information about what kind o f information is noted in the next following line, called the “Associated value”. The associated value o f the “0 ” in line / for example is the character string “ S E C T IO N ” . The “ 1 0 ” in line 19 has a floating double precision number as its associated value with the Y-coordinate (“9 4 9 . 9 9 7 2 5 5 9 7 ”) o f a point. A DXF-file is further more divided in different sections like “Header”, “Classes” “Tables”, “Entities” and “Objects”. The “Entities” section contains the graphical objects in the drawing, which is the information needed for the RIPS-program. The other sections don’t contain any pertinent information that has to be processed. There is no specific order on the sequence o f the sections. Depending on the AutoCAD drawing, a section can further more contain certain elements or omit certain elements. Also the subsections within one section don’t have any particular order. 42 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 6.1.2. Entities Section The Entities Section contains information about Lines, Arcs, Polylines, 3DFACEs and so on. The information to be processed in the following is the 3DFACE. When an AutoCAD drawing is processed like described earlier, using an exploded “edgesurface” mesh, the entity section w ill consist o f many 3DFACEs. Each 3DFACE represents a grid o f the mesh. It contains the x-, y-, and z-coordinates o f all four comer points o f one square grid (Fig. 39). 0 3DFACE Entity type 5 2B«* 330 2 Hexadecimal number 100 AcDbEntity 100 AcDbFace 10 -904.42279599 20 -1632.1431014 30 21.78023202 11 -904.90569353 21 -1686.41999287 31 30.82613067 12 -949.99725597 22 -1675.96816523 32 4.13168541 13 -949.99725597 23 -1624.21686967 33 -5.05985164 x-, y-, and z-coordinate of the fourth comer x-, y-, and z-coordinate of the third comer x-, y-, and z-coordinate of the second comer x-, y-, and z-coordinate of the first comer Fig. 39: Example of a 3DFACE in DXF-format 43 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Please note that these are the important data that will be extracted from the DXF-file for the RIPS program. Furthermore, each element o f the entity section has a number (in hexadecimal format) that is unique for each element. It is important for the DXF-file that none o f these hexadecimal numbers is used more than once. In particular this means, that the new points and lines, which will be added later to represent the plank lines, are not allowed to have a number already used before. In the Header section is a keyword called HANDSEED, followed by a number, which represents the highest hexadecimal number used. This number has also to be captured in order to know where to continue numbering the new elements. 6.2. Specification The program must be able to read in the DXF-file, to determine which data corresponds to the coordinates o f all the 3DFACEs (finite element mesh) and to store this data on a particular place. This data has then to be interpreted as points on a surface connected with each other through a line (each point needs to have the information which are the his neighbor points). The lines must have the information if it is a borderline or a line in the inside o f the shell. Now, additional points have to be found which satisfy the conditions o f the plank lines. This is possible with an algorithm, which is repeated for each single 3DFACE, that means, for each single grid element o f the finite element mesh. The steps o f the algorithm can simply be described as follows: 44 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 6.2.1. Principle o f Algorithm over the shape As discussed in “Program objectives”— “Finite element approach”, the benefits o f the finite element method are that one and the same algorithm can be applied for every kind o f shape, that the geometric equations o f the initial shape have not to be known, and that the problem is broken down in many small, relatively simple problems, which can be resolved isolated from the overall problem. Starting at an edge, the same step is repeated in each finite element grid, which the plank line encounters in its path over the shape. In the beginning it is not known, where this line will go through, only the starting point at the edge is known. This are the boundary conditions, defined by the user (Fig. 40). But with the starting point, the end point o f a part o f the plank line, called sub-line, can be found. It is the intersection point o f the plank line with one o f the edges o f the first finite element grid. The intersection point gives in the same time the starting point for the next (neighbor) element. Step by step the sub-lines are joined together until the entire plank line is established. Enter point o f neighbor element One finite element grid Enter point /C' -is the same as the end point o f theprevious element End point Sub-line Fig. 40: Visualization of a sub-line (part o f a plank line within one finite element grid) 45 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 6.2.2. Algorithm for one finite element grid At the 'enter1 point o f the line (point where the line 'enters' a finite element), a local coordinate system is defined (Fig. 42): • X-axis: is the longitudinal axis o f the plank’s sub-line. • Y-axis: perpendicular to the x-axis and lies in the PLANE o f the finite element. • Z-axis: normal to the PLANE o f the finite element. The PLANE o f a finite element grid is defined by the following three points: two comer points o f the finite element grid and the middle point o f the other 2 comers (Fig. 41). (The four points, o f which the SQUARE finite element grid is defined, are not necessarily lying in the same plane! (Fig. 42)) PLANE Middle Comer po Plan view Comer-ft Elevation Zoom Middle point Fig. 41: Definition o f local coordinate system 46 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Plan view: Elevation: _ _ _ _ _ _ _ ___________ - 7 — —— " " Fig. 42: Plan view and elevation o f a finite element grid So far is said how the local coordinate system is defined. For the program to set up a local coordinate system, the following steps are executed (each time the plank line encounters a new finite element grid) (Fig. 43 and following). Known are the four comer points o f the finite element, the enter point, and the X- orientation o f the X -axis. X-orientati< Fig. 43: X-orientation o f the X-axis The X-orientation is not to confuse with the X-axis itself. The X-orientation is not yet positioned in the PLANE o f the finite element; it only gives the orientation in the X- direction that the sub-line has to follow. (This is derived from the rule, that the plank line can only be bent in x-direction) The X-orientation is identical to the X-axis o f the previous element grid, respectively defined by the user for the first element grid at the edge (Fig. 47 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 43). The X-orientation can be rotated to the correct place by applying the right hand rules. Geometrically this means the following: The cross product o f tw o arbitrary vectors in the PLANE gives as result the Z-axis, the cross product o f the Z-axis with the actual orientation o f the X-axis gives the Y-axis, and finally the cross product o f the Y-axis with the Z-Axis gives the new, correct X-axis. Fig. 44: Cross product o f two vectors in the plane gives Z-axis (normal to the plane) X -orientation Fig. 45: Cross product o f Z-axis and X-orientation gives Z-axis (tangential to the plane) Fig. 46: Cross product o f Z-axis and Y-axis gives the X-axis (tangential to the plane) 48 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. The next step is to find the end point o f the sub-line within this finite element grid. Knowing the properties o f the plank line, which say that only rotation in x direction and twist are allowed (see also “Program Objectives”), it needs only one more step for finding the endpoint. The searched point is the intersection point o f the plane containing the X- and Z-axis o f previously defined local coordinate system and the edge line o f the finite element grid (Fig. 47). Searched endj)pint^ Fig. 47: Intersection o f the XZ-plane with the edge o f the finite element The end point is at the same time the starting point o f the next finite element. A new local coordinate system is defined and the same algorithm repeated. The sub-line finds its way step by step until the other edge o f the shape. The accumulation o f this series o f sub lines becomes a plank line, and the process is begins again for the next plank line. 49 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7. PROGRAM DESIGN This section describes the most important design decisions. For a complete documentation refer to the program code in the Appendix. The program contains classes for reading and storing information from the DXF-file. It also contains classes for the interpretation o f the DXF-file information and setting up a finite element mesh. It finally contains classes for computing the plank line algorithm. In addition to this it refers to a geometric library (“Geometry3D”, copyright by Richard Wagner, thesis advisor, used with permission), a queue class, and a linked list. In addition, it refers to standard library classes. There are two classes provided for reading the original DXF-file: DXFgroupCode and DXFassoc Value. The main reason o f these classes is to interpret the different types of DXF-file information. In a program, the type o f parameters and variables have to be defined before head as integers, doubles, floats or characters. If a different type than declared is encountered, the program fails. The DXFgroupCode-class below reads the group code o f the DXF-file, and can then communicate the type o f the associated value to the DXFassocValue-class (Fig. 48). 7.1. Classes needed for reading the DXF-file DXFassocValue DXF groupCode int _intInformation float floatlnformation char * charlnformation • int groupCode ■ DXFassocValue * assoc Value ■ double doublelnformation Fig. 48: Classes “DXFgroupCode” and “DXFassocValue” 50 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.1.1. DXFgroupCode • groupCode allows storing o f the group codes o f a DXF-source file; it is an integer value that defines the kind o f the associated value in the following line o f the DXF-source file. • _assocValue is a pointer to the DXFassocValue class. 7.1.2. DXFassocValue • charlnformation is for storing character strings, intlnformation for integers, doublelnformation for double precision numbers, and floatlnformation for floating point numbers. As DXF-files can contain some or all o f these types o f data, variables must be defined for each type. The original DXF file is read and sequentially stored in an Array (“Entity Array”) o f DXFgroupCodes (Fig. 49). Each o f the DXFgroupCodes has a pointer to a DXFassocValue that contains the necessary information. Two difficulties with this approach have been encountered: the original DXF-file can contain empty lines, that means, DXFassocValue with a blank entry, or, lines with two words separated by a blank space (Fig. 50). Special loops had to be created to avoid errors, because the regular input stream usually skips blanks and new line characters until the first non-blank character is encountered, and reads then only to the next blank or new line character. 51 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Entity Array (part): DXFgroupCode DXFassocValue 0 LINE 2F 100 GRID 100 AcDbLine 10 300.0 20 200.0 3 0 0.0 11 300.0 21 200.0 3 1 LINE C2 100 Fig. 49: Storing data in Entity Array Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. DXF Source File (part): 0 SECTION 2 HEADER 9 $ACADVER 1 AC1014 $ACAD"MAINTVER Blank Space! 70 Blank Line! SDWGCODE 3 ANSI_I252 0 ENDSEC 0 SECTION ENT IT . 0 LINE 5 2F 100 AcDbEntity 8 GRID 100 AcDbLine 10 300.0 etc Start storing information Fig. 50: Sample section of a DXF-source file showing two typical problems Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.2. Classes needed for the finite element mesh 7.2.1. Point The Point class (Fig. 51) contains _condition, an information, which tells if the Point is a CORNER, BORDER, INSIDE, or not defined, __lineNbr, which counts the Lines o f which the Point is part of, _nbr, a number which is explicit for each Point, _x, _y and _z, which are the coordinates of the Point, and _partOfLine, an array o f pointers to the Lines, o f which the Point is part of. 7.2.2. Point member functions A Point can logically be part o f a maximum o f four Lines. It is possible to add and remove Lines. If there is attempt to add more than four Lines, a message appears and will prompt the user to press any key to continue. The member function “same” returns true, if the _nbr (number) o f the source Point is identical with the _nbr o f the Point that called the function. This means only if they are both one and the same Point. The member function “equal” returns true, if two Points have the same coordinates. They don’t need to have the same _nbr (number), which means, they can be two different Points located at the same place. 7.2.3. Line The Line class (Fig. 52) contains _condition, an information, which tells if the Line is a BORDER, INSIDE, or not defined, _faceNbr, which counts the Faces o f which the Line is part of, _nbr, a number which is explicit for each Line, two pointers _pl and _p2, which point to the start and end points o f the Line, and _partOfFace, an array o f pointers to the 54 Point ■ Cond _condition ■ int _lineNbr ■ int _nbr ■ double _x « double _y ■ double _z ■ Line **_partOfLine Fig. 51: Point class Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Faces, o f which the Line is part of. Line ■ Cond _condition ■ int_faceNbr • int_nbr ■ Point *_pl ■ Point *_p2 ■ Face **_partOfFace Fig. 52: Line class 7.2.4. Line member functions A Line can logically be part o f a maximum o f two Faces. It is possible to add and remove Faces as well as Points. If there is attempt to add more than the max allowable two Faces, a message shows up and will prompt the user to press any key to continue. The member function “same” returns true, if the _nbr (number) o f the source Line is identical with the nbr (number) o f the Line that called the function. This means only if they are both one and the same Lines. The member function “equal” returns true, if both Points (_pl and _p2) of the Line have the same coordinates as the Points o f the source Line. They don’t need to have the same _nbr (number), which means, they can be two different Lines located at the same place. 7.2.5. Face The Face class (Fig. 53) contains _condition, an information, which tells if the Face is a CORNER, BORDER, INSIDE, or not defined, _nbr, a number which is explicit for each Face, four pointers 11, 12, 13, and _14, which point to the surrounding Lines o f the Face, and jpartOfShape, a pointer to the Shape, o f which the Face is part of. 55 Face Cond _condition ■ int_nbr ■ Line *_10 ■ Line *_ll ■ Line *_12 ■ Line *_13 • Shape *_partOJShape Fig. 53: Face class Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.2.6. Face member functions It is possible to add and remove Lines. The member function “same” returns true, if the _nbr (number) o f the source Face is identical with the _nbr (number) o f the Face that called the function. This means only if they are both one and the same Face. The member function “equal” returns true, if ail the Lines o f two Faces have Points with the same coordinates. They don’t need to have the same _nbr (number), whay means, they can be two different Faces located at the same place. 7.2.7. Shape The Shape class (Fig. 54) contains _faceCount, which counts the number o f Faces belonging to the Shape, geoPointCount, which counts the number o f PlankPoints (for class definition see section 7.4.1), and geoLineCount, which counts the number o f the plank lines’ sub-lines, belonging to the Shape. It also contains _face, and array o f Pointers to each o f the Faces o f the Shape, _geoPoint, an array o f pointers to each o f the PlankPoints that are calculated during the runtime o f the program, and _geoLine, an array o f pointers to each o f the sub -lines that are connecting the PlankPoints. It is possible to add and remove Faces, PlankPoints, and Lines. Below is represented how the classes are connected together. The white-gray thick arrow represents an array o f pointers, the dark, thin array represents a single pointer (Fig. 55). 56 Shape • int _faceCount ■ int _geoPointCount ■ int _geoLineCount ■ Face **_face • Line ** geoLine • Point ** s eoPoint Fig. 54: Shape class Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Point Cond _condition int _IineNbr int _nbr double _x double _y double _z Line **_partOJLine Line Cond _condition int _faceNbr int_nbr Point *_pl Point *_p2 Face **_partOfFace Face Cond _condition int _nbr Line *_10 Line *_ll Line *_12 Line *13 Shape *_partOfShape Shape int_faceCount int geoPointCount int _geoLineCount Face **_face Line **_geoLine Point ** seoPoint Fig_ 55: Finite element mesh classes Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.3. Inter-relationship of finite element classes Special care is needed for the distribution o f the points and the lines composing the finite element. One possibility for setting up a finite element mesh is presented below (Fig. 56). Derived from the DXF-file, each face has its own four lines and points. This results in a mesh with two superposed lines and four superposed points (except for boundary faces). (See also Fig. 67) Line Line Line Line Point Point Point Fig. 56: Organization of finite element mesh classes before redistribution o f Lines and Points Even though the design with double lines and points presented in figure 56 is a possible way to set up the mesh, the decision has been taken to delete the duplicated objects. For later programming steps it is easier without duplicated elements. The pointers 58 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. to the objects have to be redistributed, before deleting an object. This is achieved with the functions distributeLines and distributePoints (see section 7.5). The new representation looks more confusing than the previous one. A line points now to two different faces, a point to four different lines (Fig. 57). But the graphical representation o f the finite element mesh is more straightforward (Fig. 68). geoPoint geoPomt Point Point Point 3 Q U □ □ □ ! mam Fig. 57: Final organization of finite element classes, after redistribution of Lines and Points The shape has also pointers to geoLines and geoPoints (Fig. 57). GeoPoints are the points o f the new calculated plank line. GeoLines are the connection line between the geoPoints (see next section). 59 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.4. Classes needed for the algorithm of the plank line Only two classes are needed for computing the algorithm o f the plank lines, PlankPoint and LocalAxis. 7.4.1. PlankPoint The PlankPoint class (Fig. 58) contains the algorithm to compute the exit point o f the plank line, for a given finite element and the enter point o f the plank line within this element. _condition and _nbr are not used in the current version o f RIPS, but they can be used in the same way as described for the Point-, Line- and Face classes. _pointIn is a pointer to the intersection point o f entering plank line with one o f the edges o f the finite element and must be set with the constructor or with the member function “set_pointIn”. _pointOut is a pointer a the new calculated point o f plank line on another edge o f the finite element. It can be called with the constant member function “get_pointOut” after the member function “set_directionX” has been called. _xAxisIn is a pointer to a direction; the x-orientation o f the x-axis. It must be set with the member function “set_directionX”. The member function “set_directionX” will then modify the direction in order for it to lie in the plane o f the finite element When _xAxisIn will be called later, it will return the new x-axis (Fig. 60). _partOfLineIn is a pointer to the Line on which the enter point is situated. It must be set with the constructor or with a member function “set_partOfLineIn”. _partOfLineOut is a pointer to the edge o f the finite element on which the new calculated point o f plank line is situated. It can be called with the constant member function “get_partOfLineOut” after the member function “set_directionX” has been called. _partOfFace is a pointer to the finite element in which the plank sub-line has to be calculated. _partOfShape is a pointer to the Shape o f which the Face is part of. B oth partOfFace and _partOfShape must be set 60 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. with the constructor or with the member functions “jsetpartOfFace” and “jsetpartOfShape”. _p l to _p2 and _e!2 to _e41 are pointers to the four comers and edges o f the finite element according to (Fig. 59). PlankPoint ■ Cond _condition ■ int_nbr ■ Point3D* jpointln ■ Point 3D* _pointOut ■ Direction3D* _xAxisIn • Line* jpartOJLineln • Line* _partOfLineOut ■ Face* jpartOJFace ■ Shape* _partOJShape • Point3D* _p I • Point3D* _p2 ■ Point3D* _p3 • Point3D* _p4 ■ Edge3D* _e 12 • Edge3D*_e23 ■ Edge3D* _e34 • Edge3D* _e41 Fig. 58: PlankPoint class 7.4.2. Member function “set directionX” The member function “set_directionX” (Fig. 60) is actually the main part o f the program (where the secret o f the algorithm is hidden). It calls the class LocalAxis to place the local coordinates o f the enter point. All the necessary parameters for satisfying the precondition o f LocalAxis are known. The xz-plane can then be called (with the constant member function “getjzxPIane” o f the LocalAxis class) and the intersection o f the xz- plane with one o f the edge lines of the finite element gives the new plank point (_pointOut) (Fig. 61). This point can be called later when the enter point for the next finite element grid is needed. Important to know is also on which line the new plank point lies, because through the line pointing to the both o f its neighbor faces, it can be found out, which is the next finite element for repeating the algorithm. The line can be called with the member function “get_partOfLineOut”, which calls the private variable _partOfLineOut. 61 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.4.3. Geometrv3D library As can be seen, PlankPoint uses points o f the Point3D class, rather than the Point class from the finite element mesh. This is in order to obtain compatibility with functions used from the Geometry3D library, (copyright by Professor Richard Wagner, used with permission), in particular the “crossProduct” function used in the LocalAxis class and the “LinePlanelntersection” function that computes the intersection point o f a plane with a line. A plane is represented with the DirectedPoint3D class, which has a pointer to the Point3D class (representing a point in the plane), and a pointer to the Direction3D class (representing a unit vector normal to the plane). xAxisIn e41 e34 _P1 jpointln _partOfLine!n e!2 e23 Fig. 59: Precondition of PlankLine class 62 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Fig. 60: Member function “set_directionX” _pa rtOfLineOut pointO ut e4 e34 _p3 e!2 e23 xAxisIn Fig. 61: Postcondition o f PlankPoint class Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.4.4. LocalAxis The LocaLAxis class (Fig. 6 2 ) contains the algorithm necessary to position the local coordinate system o f a finite elem ent grid. It needs as input (precondition, Fig. 63) two vectors in the plane o f the finite elem ent grid (class Direction3D), the X-orientation o f the X-axis (class Direction3D), and th e origin for the local coordinate system (class Point3D). With the Direction3D class’ member function “crossProduct”, the local coordinate system is set up (see section 6.2.2, Fig. 44, Fig. 45, Fig. 46). Each axis as w e ll as the planes defined by the axis can be called (postcondition, F ig. 64). X-oriem i o q Fig. 63: Precondition of LocaLAxis class Fig. 64: Postcondition of LocaLAxis class 64 LocalAxis ■ Direction3D* _xAxis ■ Direction3D* _yAxis ■ Direction3D* _zAxis ■ Point3D* _origin Fig. 62: LocalAxis class Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 7.5. Structure of the main program The main program prompts the user to input the name o f the DXF-file. Then it reads in the DXF-file and stores the important information in an array (EntityArray). The part o f the DXF-file in front o f the place where the new, additional PlankPoints and lines will be added and the part afterwards, are stored in two different queues, (called “beginning” and “rest”) using a linked list. For the queue and the linked list there is an already existing library used from Main and Savitch (1997, p.372). A series o f functions is called now to read in the part o f the DXF-file with the important information, to set up the finite element mesh and to calculate the plank lines and its intersections. Afterwards a new output file is opened, the queue “beginning” with the first part o f the original DXF-file is added, then the new PlankPoints and lines are inserted, and finally the queue “rest” is added. The functions called by main to perform the calculations are the following: ■ fillEntityArray • fillFaceArray • readPoints (called by fillFaceArray) • distributeLines • distributePoints • verifyLines • verifyPoints • divideEdge • startAngle 65 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. The function fillEntityArray stores the information found in the Entity section o f the DXF file in an array called “entityArray” (Fig. 36). 0 3DFACE 5 27 (= 39) 2 too ' ''AcPbEntity 8 o too A c D b F a c e '''\ 10 -904.422799 \ 20 -1 6 3 2 .1 4 ^ 30 2 1 .7 8 0 2 3 2 0 2 '"\ 11 -904.905693 21 -1686.419997 31 30.82613067 12 -949.997257 22 -1675.968123 32 4.13168541 13 97-949.9975 23 -1624.216867 33 -5.05985164 0 3DFACE 5 28 (=40) 330 2 100 AcDb Entity 8 0 100 AcDbFace 10 -861.220377 20 -1804.577365 30 36.62653726 11 -861.808055 21 -1856.863338 31 19.72789837 12 -905.9569176 22 -1841.710209 32 -8.0467938 13 -905.690085 23 -1791.394496 33 10.692635 DXFgroupCode DXFassocValue Fig. 65: Graphic representation of entityArray 66 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. The function fillFaceArray takes the entityArray form previous function and fills a double array, called “arrayOfFaces” (Fig. 66). ArrayOfFaces: FaceArray: DXFgroupCode 1 ,— nJ 5 | 10 | 20 | 30 1 II <=> 3 c=>[ a a a a a a to O O 1 -0 oo O S I I O S to to V O to cs o o 00 21 a a a a a a , a , a U i O ) u O v 31 12 22 32 13 23 33 • U O v ■ u . O i DXFassocValue I 5 | 10 1 20 | 30 | 11 a , a . a a a a to 1 oo os oo Os I I o to to o to Cs 21 a a a a a a . a a oo u » ON o c oo S O o o .c * . O S •o so o u so And so on.. 31 12 22 32 13 23 33 o b s S O tO s 10 2? 30 11 21 31 12 22 | 32 13 23 33 a a a a a 3 . i t t I D a a a a a to V O I I Fig. 66: Graphic representation of arrayOfFaces The function readPoints sets up a finite element mesh with multiple lines and points: except for edge faces, each line exists twice, each point four times. It can be represented as follows (Fig. 56 and Fig. 67); the arrows represent pointers to and from the different elements: 67 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Line I Line I Line 1 Face 1 Face 2 Face 3 Line 3 Line 3 Line I Line 1 Face 4 Face 6 Line 3 Line 3 Line 3 Line 1 Line 1 Line 1 Face 7 Face 8 Face 9 Line 3 Line 3 Line 3 Line 1 Line 1 Line 1 Face 10 Face 11 Face 12 Line 3 Line 3 Line 3 Fig. 67: Finite element mesh before redistribution of Lines and Points The functions distributeLines and distributePoints set up the correct finite element mesh. The multiple lines and points are reduced to one single line respectively point. It has to be dealt with the different elements pointing to each other. A point or line cannot simply be deleted, the pointers to and form it have to be removed first or changed in order to point to the remaining point/line/face. After the functions are called, the finite element mesh appears as follows (Fig. 57 and Fig. 68): 68 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. L ne I ^ L ne 1 ^ ■ ^ r 1 - > <7c^> Face 1 4 ^ . i n e 3 Line I Face 4 Line 3 Line 1 Face 7 Line 3 Line 1 Face 10 Line 3 Face 2 Face 5 Line 1 Face 3 N J J n e 3 Line 3 Line 1 M ~ Face 6 Line 1 Face 8 Line 3 Line 1 Face 11 Line 3 Line 3 Line 1 Face 9 Line 3 Line 1 Face 12 Line 3 Fig. 68: Finite element mesh after redistribution of Lines and Points The functions verifyLines and verifyPoints are help functions to test the program. They are not necessary to be called for the normal runtime o f the program. The function divideEdge prompts the user to give the number o f planks in one direction and in the other, as well as the starting angle o f the plank at a particular edge. The angle is measured in z-projection (global coordinate system), from the diagonal o f two comer points. The program then divides each edge o f the shape in the given number o f equal length. For each o f these edge points the function startAngle is called. StartAngle finds the plank lines’ points. 69 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 8. PROGRAM VALIDATION The program has been tested on different surfaces. The free form (Fig. 69) is architecturally and structurally speaking not a useful form, but it shows clearly, that in points o f freedom for possible shapes, the program works correctly and has no limitations. Possible output for hyperbolic-paraboloid and spherical shapes are also shown below (Fig. 70 and following). The barrel vault is giving the expected S-shaped lines in plan view (Fig. 73). Plan View Elevation Axonometric Views Fig. 69: Free shape 70 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Plan View Elevation Axonometric Views Fig. 70: Hyperbolic-paraboloid Shape Plan View i Elevation Axonometric View Fig. 71: Hyperbolic-paraboloid shape with parallel lines Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Axonometric Views Fig. 72: Anticlastic shape (similar to roof EXPO 2000, see “examples of executed projects”) Axonometric View Plan View v AAAAaA / ■ r v l i f\ f\ t Xxxx Fig. 73: Barrel Vault (similar to hall for galley, see “examples of executed projects”) Plan View ' AAAA' -' - v Elevation A v n n o m e t T t r * V ipw «; Fig. 74: Spherical Shape (similar to Polydome, see “examples of executed projects”) Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Plan View Elevation Axonometric View Fig. 75: Spherical Shape, with sloping edge arc Plan View Axonometric View Fig. 76: Spherical Shape, with vertical edge arc So far, with this visual check o f the different test cases, the program seems to work correctly and with a satisfying precision. Further testing must be done by comparison o f mathematically calculated plank system lines with the program’s output for the same surface. As example figures the hyperbolic-paraboloid shape o f the fair’s main roof o f the World Exposition in Hanover, Germany (Fig. 9, Fig. 10 and Fig. 72). The structure has been designed with the help o f mathematically computed plank lines. The author o f this thesis plans to meet with the planners o f the project and to compare the result. 73 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. The original hypothesis stated that every double curved surface has a certain number o f lines that bend with one degree o f freedom only and that a computer tool can be developed to compute these lines. It appears through numerous examples that this is true. None o f the tested surfaces showed conflicts with the hypothesis. However, in its practical application, the use o f RIPS is not optimized yet and it has a certain number o f constraints, which will have to be eliminated. 74 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 9. PROGRAM OPTIMIZATION Even though the hypothesis has been proven, the computer program is not very useful at this point. T he main part (or heart) o f the program, which is the algorithm for finding the plank lines, is developed and works so far. But for having a useful computer tool, some changes need to be made. The types o f problems and solutions can be grouped into three categories: Problems with the use o f AutoCAD as the program is currently written, problems within the program coding itself, amd problems with the program’s logical design and the user interface issues. 9.1. Problems related to AutoCAD 9.1.1. Text strings longer than 255 characters Multiline-text in the AutoCAD drawing may be longer than the allowed space for character strings o f 255 characters o f a DXF-file. To avoid problems o f this kind there should be no text included in the drawing while saving in DXF-format. If text strings are deleted, before saving in DXF-format, their information may still be stored in a temporary place. To avoid this, PURGE the drawing before saving in DXF-format. Solution: It has to be added a loop in RIPS that checks for the length o f the character strings in the original DXF-file. If a string is longer than 255 characters, it ignores the exceeding characters 9.1.2. Saving in DXT-format If “option”* is chosen during the saving process and only a selected part o f the drawing is saved in DXZF-format, the program will not work correctly. RIPS will not recognize the 75 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. first comer point as it is; it will start calculating the algorithm in the middle o f an edge instead o f starting at a comer. The rest o f the program works correctly. Solution: It has to be found out, where exactly the problem occurs. 9.1.3. Conversion form AutoCAD 2000 to AutoCAD 14 A DXF-file saved in the AutoCAD 2000 version will not open in AutoCAD 14, even if the option “save as DXF, version Autocad R14” has been chosen. Solution: The problem may consist in a wrong setting, and not occur to all machines. 9.2. Problems related to the coding 9.2.1. Static arrays — dynamic arrays The actual version o f RIPS contains static arrays for setting up the finite element mesh. These arrays have a limited space for storing objects. For large shapes, the constants must be changed. (They figure on top o f the source code “PlankLine.h”) Solution: The static arrays can be replaced with dynamic arrays or linked lists. 9.2.2. Interactive user interface The actual version o f RIPS is not self-explanatory; the user needs to read and understand the step by step explications in section 5. Solution: The user friendliness can be increased by an interactive graphic user interface (for instance with Microsoft Visual C++). Graphical input and output interface would simplify the understanding o f the needed parameters, as well as allow immediate correction o f inappropriate parameters 76 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 9.3. Improvement of the logic design and user input 9.3.1. Connecting two edge points The most important modification, which has yet to be done concerns the input parameters given by the user. In the actual state the user can define the number o f planks and the starting direction o f the plank lines, but has only limited control over the endpoint o f the line. He can indirectly define the endpoint on changing the starting direction, but it is time-consuming, to find out the right angle, and this same angle is then applied to all lines together. It would better serve the user to input two points on the edges (start point and end point), which have to be connected through a plank line. This way the line is not finding somehow arbitrary its way over the surface, but in a controlled way to an endpoint. Solution: The modification can be made in form o f a search algorithm. For the programming design, this means the following: first, the line is calculated as it has been done before. Then, in function of the distance to the desired endpoint, the line is recalculated with an adjusted starting direction. The process is repeated until the endpoint coincides close enough with the desired endpoint. The search algorithm is repeated for all the lines. This method includes the possibility o f no solution. For the free form shape for instance (Fig. 77) the search method will most likely not converge in some cases, because there is not always a possible solution to connect two points with a plank line. 77 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Plan View Line Endpoint Fig. 77: The “Line” may not be able to connect to the “Endpoint” 9.3.2. Bending Check A check should be performed to verify that the curvature is no smaller than r > 200 * d. The same applies for twist with its respective delimitation. Solution: The plank line, actually consisting o f multiple small straight lines, has to be assimilated to a spline curve and its radius has to be tested at each point. 9.3.3. Intersection Points For the execution planning, the most useful parameters are the coordinates o f the intersection points o f the plank lines. In the actual version, these intersection points don’t exist as intersections, because two lines in the three-dimensional space will not necessarily cross each other. Solution: To find the intersection points, an algorithm has to be applied, which searches for the shortest distance in between two lines. 9.3.4. DXF-format A bigger freedom should be obtained for processing different DXF-files formats. Currently the program is limited to read SDfaces from the DXF-file and to process a shape with four edges, respectively four comers only. For other DXF-entities as well as for 78 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. shapes with different number o f edges and comers (for instance, a spherical shape with circular base, which has one circular edge, and zero comers), the program has to be modified accordingly. Solution: Other possible representations o f surfaces have to be analyzed and functions have to be added (similar to the functions “fillFaceArray” and “readPoints”, see section 7.5) that can interpret different entities (for instance triangular finite elements). The functions “divideEdge” and “StartAngle” have to be modified in order also to handle shapes with a different number o f edges than four. 9.3.5. Proposing meaningful solutions The current version o f the program implies a user who is experienced with ribbed shell structures. The necessary distance and the best orientation o f the ribs, and also the ideal form o f the surface have to be judgment o f the person using the program. If a bad input is given, the plank lines are given anyway. The program could be amplified with some features for narrowing down the scope o f possible solutions to a handful meaningful solutions, and not allowing insignificant solutions. Then, the user would not even be constraint to give an orientation o f the ribs anymore, he could choose form a handful possible proposed solutions (symmetrical, asymmetrical, equal distance o f the planks, or distance condensed towards the edges o f concentrated stress, and so on). A s a last step, the program could even be integrated with a structural analysis tool and also give answers regarding structural performance (stability, stress distribution, deflection). 79 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 10. CONCLUSIONS RIPS, which stand for “Rib structure Interactive Plank System lines" computer program, written in C++, solves for a set o f plank lines over a given surface. Plank lines are lines that are curved only in one direction (normal to the surface), and describe the system lines o f timber planks, lying over this surface. The program is supposed to help in the design o f timber rib shell structures, which’s structural system consists o f a grid o f curved timber planks, screwed together and forming the ribs. RIPS processes a DXF-file o f a surface drawn in AutoCAD and outputs a new DXF- file, including the plank lines, which can be viewed in AutoCAD. RIPS works fine for any kind o f shape, as long the shape has four edges and it has been drawn in a certain way in AutoCAD. Even though this program has limitations, it is a clear proof o f a conceptual computer tool being able to simplify the process o f finding the plank lines for a given surface. Applied at different scales and for different materials, the program could also be used in other fields than in the narrow scope o f rib shell structures. As example figure form work for double curved concrete structures, or to design moulds founding steel, glass, lightweight cement, composite materials (plastic), and so on. It can be used as a help tool for designing haute gammed furniture. In a small scale, it could find use in the field o f micro technique: for medical devices, artificial organs, robotic engines, which are mostly used in a dynamic way. The possibilities are endless. Wherever a one directional element has to be curved and has a width bigger than its height, the problem is the same. 80 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 11. BIBLIOGRAPHY 11.1.1. Books Deitel, H. M., & Deitel, P. J. (1994). C++ how to program (2n d ed.). New Jersey: Prentice-Hall Inc. Griindig, L., Ekert, L., & Moncrieff, E. (1996). Geodesic and semi-geodesic line algorithms for cutting pattern generation of architectural textile structures. In Lan, T. T., p roc: A sia-P acific Conference on Shell a n d Spatial Structures- Beijing, China: IASS. Main, M., & Savitch, W. (1997). D ata structures a n d other objects using C++- Massachusetts: Addison Wesley Longman. Natterer, J., Herzog, T., & Volz, M. (1998). Construire en bois 2 (2n d ed.). Lausanne: Presses Polytechniques et Universitaires Romandes. Otto, F. (Ed.). (1967). Zugbeanspruchte K onstruktionen. Cambridge, Massachusetts: M.I.T. Press Parker, S. P. (1993). Parker encyclopedia o f scientific a n d technical term s (5th ed.). New York: Me. Graw-Hill Inc. Roland, C. (1970). p rei Qtto: Tension structures (c - v - Amerongen, Trans.). New York: Praeger Publishers. 11.1.2. Journals Hoeft, M., & Kaelin, J. (1992, January 10). Austeliungspavillion in Brettstapelbauweise. Holzbau, Fachbeilage sum Schw eizer Baublatt, Nr. 2. 81 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Natterer, J. (1996, April). The use o f timber as a construction material - the only chance to save the forests o f the world, P ublication IBOIS, Lausanne, Switzerland. Schierle, G. G. (1977, September). Interdisciplinary design optimization: a search method. Journal o f O ptim ization T'heory and A pplications’ vo^ - 23, No 1. 11.1.3. From the World. Wide Web Meteorology Group. (1997, Junej. M eteorological Terms a n d Definitions• Document ->51-97, New Mexico: Range commanders council U.S. Army. Retrieved May 20, 2000 from the World Wide Web: http://tecnet0.jcte.jcs.mi1/RCC/manuaIs/meteor/g.htm 11.1.4. Companies, Institutes BCN. Bois Consult Natterer SA, Etoy, Switzerland, email: bois-consuIt-natterer-sa@bluewin.ch IBOIS. Chair de construction en bois, Swiss Federal Institute o f Technology (EPFL), Lausanne, Switzerland, http://iboiswww.epfl.ch IEZ. Internationales Entwicklungszentrum fur Holzkonstruktionen Natterer GmbH, Wiesenfelden, Germany, email: iez.natterer.gmbh@t-online.de 82 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 12. APPENDIX 12.1. DXF sample file 12.1.1. Picture of the original AutoCAD drawing 12.1.2. DXF source file 0 9 10 SECTION SEXTMIN 1000.0 2 10 20 HEADER -954.825406 1000.0 9 20 9 SACADVER -1856.863384 SORTHOMODE 1 30 70 AC1014 -35.594856 0 9 9 9 SACADMAINTVER SEXTMAX SREGENMODE 70 10 70 9 -859.686445 1 9 20 9 SDWGCODEPAGE -1675.968165 SFILLMODE 3 30 70 ANSI 1252 56.935404 1 9 9 9 SINSBASE SLIMMIN SQTEXTMODE 10 10 70 0.0 -2000.0 0 20 20 9 0.0 -2000.0 SMIRRTEXT 30 9 70 0.0 SLIMMAX 1 SDRAGMODE 70 2 9 SLTSCALE 40 1.0 9 SOSMODE 70 11 9 SATTMODE 70 1 9 STEXTSIZE 40 2.5 9 STRACEWID 40 1.0 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 9 1.25 1 $DIMBLK1 $TEXTSTYLE 9 1 7 $DIMTP 9 STANDARD 40 $DIMASO 9 9 0.0 70 $DIMBLK2 SCLAYER 9 1 1 8 $DIMTM 9 GRID 40 $DIMSHO 9 9 0.0 70 $dimstyl: $CELTYPE 9 1 2 6 $DIMTXT 9 STANDARD BYLAYER 40 $DIMPOST 9 9 2.5 1 5DIMCLRD SCECOLOR 9 70 62 $DIMCEN 9 0 256 40 5DIMAPOST 9 9 2.5 1 SDIMCLRE SCELTSCALE 9 70 40 $DIMTSZ 9 0 i.O 40 $DIMALT 9 9 0.0 70 $DIMCLRT $DELOBJ 9 0 70 70 5DIMTOL 9 0 1 70 SDIMALTD 9 9 0 70 $DIMTFAC $DISPSILH 9 4 40 70 $DIMLIM 9 1.0 0 70 SDIMALTF 9 9 0 40 SDIMGAP SDIMSCALE 9 0.0394 40 40 $DIMTIH 9 0.625 1.0 70 SDIMLFAC 9 9 0 40 $DIMJUST SDIMASZ 9 1.0 70 40 $DIMTOH 9 0 2.5 70 $DIMTOFL 9 9 0 70 SDIMSDl SDIMEXO 9 1 70 40 $DIMSE1 9 0 0.625 70 5DIMTVP 9 9 0 40 $DIMSD2 5DIMDLI 9 0.0 70 40 $DIMSE2 9 0 3.75 70 $DIMTIX 9 9 0 70 $DIMTOLJ 5DIMRND 9 0 70 40 $DIMTAD 9 1 0.0 70 $DIMSOXD 9 9 1 70 $DIMTZIN SDIMDLE 9 0 70 40 $DIMZIN q 0 0.0 70 SDIMSAH 9 9 8 70 $DIMALTZ SDIMEXE 9 0 70 40 $DIMBLK 9 0 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. $DIMALTTZ 70 0 9 5DIMFIT 70 3 9 SDIMUPT 70 0 9 $DIMONIT 70 8 9 SDIMDEC 70 4 9 $DIMTDEC 70 4 9 SDIMALTU 70 8 9 SDIMALTTD 70 4 9 SDIMTXSTY 7 STANDARD 9 $DIMAUNIT 70 0 9 SLUNITS 70 2 9 SLUPREC 70 2 9 SSKETCHINC 40 1.0 9 SFILLETRAD 40 100.0 9 $A0NITS 70 0 9 $AOPREC 70 2 9 SMENU $ELEVATION 40 0.0 9 SPELEVATION 40 0.0 9 STHICKNESS 40 0.0 9 $LIMCHECK 70 0 9 SBLIPMODE 70 0 9 SCHAMFERA 40 10.0 9 SCHAMFERB 40 10.0 9 SCHAMFERC 40 20.0 9 SCHAMFERD 40 0.0 9 SSKPOLY 70 0 9 STDCREATE 40 2451519.82300259 2 9 STDUPDATE 40 2451741.73268564 8 9 STDINDWG 40 0.2581053009 9 STDUSRTIMER 40 0.2581053009 9 SUSRTIMER 70 1 9 SANGBASE 50 0.0 9 SANGDIR 70 0 9 SPDMODE 70 34 9 $ PDSIZE 40 0.0 9 SPLINEWID 40 0. 0 9 $COORDS 70 1 9 SSPLFRAME 70 0 9 SSPLINETYPE 70 6 9 5SPLINESEGS 70 SATTDIA 70 0 9 SATTREQ 70 1 9 $HANDLING 70 4097 9 $HANDSEED 5 105E 9 SSURFTAB1 70 25 9 $SURFTAB2 70 25 9 SSURFTYPE 70 6 9 SSURFU 70 6 9 SSURFV 70 6 9 SUCSNAME 2 SDCSORG 10 0.0 20 0.0 30 0.0 9 SUCSXDIR 10 1.0 20 0.0 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 30 SUSERI5 9 STANDARD 0.0 70 $ PEXTMIN 9 9 0 10 $CMLJUST $UCSYDIR 9 1 .OOOO0OE+2O 70 10 $USERR1 20 0 0.0 40 1.000000E+20 9 20 0.0 30 SCMLSCALE 1.0 9 1.000000E+20 40 30 5USERR2 9 20.0 0.0 40 $ PEXTMAX 9 9 0.0 10 $ PROXYGRAPHICS 5PUCSNAME 9 -1.OOOOOOE+20 70 2 $USERR3 40 20 —1.OOOOOOE+20 1 9 9 0.0 30 $MEASUREMENT 5PUCSORG 9 -1.OOOOOOE+20 70 10 SUSERR4 9 1 0.0 40 $ PLIMMIN 0 20 0.0 10 ENDSEC 0.0 9 0.0 0 30 $USERR5 20 SECTION 0.0 40 0.0 2 9 0.0 9 CLASSES 5PUCSXDIR a 5PLIMMAX 0 10 $WORLDVIEW 10 CLASS 1.0 70 420.0 1 20 1 20 LWPOLYLINE 0.0 9 297 .0 2 30 SSHADEDGE 9 AcDbPolyline 0.0 70 5UNITMODE 3 9 3 70 AutoCAD 2000 5PUCSYDIR 9 0 90 10 5SHADEDIF 9 0 0.0 70 $VISRETAIN 280 20 70 70 0 1.0 9 1 281 30 $TILEMODE 9 1 0.0 70 SPLINEGEN 0 9 1 70 CLASS SUSERIl 9 0 1 70 5MAXACTVP 9 ACDBDICTIONARYWD 0 70 5PSLTSCALE FLT 9 48 70 2 5USERI2 9 1 AcDbDictionaryWi 70 SPINSBASE 9 thDefault 0 10 $TREEDEPTH 3 9 0.0 70 AutoCAD 2000 SUSERI3 20 3020 90 70 0.0 9 0 0 30 5PICKSTYLE 280 9 0.0 70 0 $USERI4 9 1 281 70 5PLIMCHECK 9 0 0 70 $CMLSTYLE 0 9 0 2 CLASS 86 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 1 1 AcDbSymbolTableR 50 ACDBPLACEHOLDER 0 ecord 0.0 2 CLASS 100 51 AcDbPlaceHolder 1 AcDbViewportTabl 0 . 0 3 HATCH eRecord 71 AutoCAD 2000 2 2 0 90 AcDbHatch *ACTIVE 72 0 3 70 100 280 AutoCAD 2000 0 73 0 90 10 1 281 0 0.0 74 0 280 20 1 0 0 0.0 75 CLASS 281 11 0 1 1 1.0 76 LAYOUT 0 21 0 2 CLASS 1.0 77 AcDbLayout 1 12 0 3 XRECORD 596.232922 78 AutoCAD 2000 2 22 0 90 AcDbXrecord -1087.165135 0 0 3 13 ENDTAB 280 AutoCAD 2000 0.0 0 0 90 23 TABLE 281 0 0.0 2 0 280 14 LTYPE 0 0 10.0 5 CLASS 281 24 5 1 0 10.0 330 LONG TRANSACTIO 0 15 0 N ENDSEC 50.0 100 2 0 25 AcDbSymbolTable AcDbLongTransac SECTION 50.0 70 tion 2 16 1 3 TABLES -1.0 0 AutoCAD 2000 0 26 LTYPE 90 TABLE -1.0 5 0 2 36 12 280 VPORT 1.0 330 0 5 17 5 281 8 0.0 100 0 330 27 AcDbSymbolTable! 0 0 0.0 ecord CLASS 100 37 100 1 AcDbSymbolTable 0.0 AcDbLinetypeTab! LWPOLYLINE 70 40 eRecord 2 2 193.126004 2 AcDbPolyline 0 41 BYBLOCK 3 VPORT 1.714286 70 AutoCAD 2000 5 42 0 90 1038 50.0 3 0 330 43 280 8 0.0 72 0 100 44 65 281 0.0 73 8 87 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 0 O STYLE 0 40 LAYER 5 TABLE 0.0 5 3 2 0 2 330 ucs LTYPE 330 0 5 5 0 100 7 13 100 AcDbSymbolTable 330 330 AcDbSymbolTable 70 0 5 70 1 100 100 2 0 AcDbSymbolTable AcDbSymbolTable 0 STYLE 70 Record LAYER 5 2 100 5 F 0 AcDbLinetypeTab E 330 UCS leRecord 330 3 5 2 2 100 F37 BYLAYER 100 AcDbSymbolTableR 330 70 AcDbSymbolTableR ecord 7 0 ecord 100 100 3 100 AcDbTextStyleTab AcDbSymbolTableR AcDbLayerTableRe leRecord ecord 72 cord 2 100 65 2 STANDARD AcDbUCSTableReco 73 0 70 rd 0 70 0 2 40 0 40 4 EDGE 0 . 0 62 0.0 70 0 7 41 0 LTYPE 6 1.0 10 5 CONTINUOUS 50 -354.7486013613 14 0 0.0 20 330 LAYER 71 -1106.010629514 5 5 0 30 100 21 42 18.90105273122 AcDbSymbolTable 330 2.5 11 Record 2 3 0.052431691828 100 100 txt 21 AcDbLinetypeTab AcDbSymbolTableR 4 0.998605996231 leRecord ecord 31 2 100 0 0.006081161365 CONTINUOUS AcDbLayerTableRe ENDTAB 12 70 cord 0 -0.000318857917 0 2 TABLE 22 3 GRID 2 -0.006072802815 Solid line 70 VIEW 32 72 0 5 0.999981509597 65 62 6 0 73 250 330 UCS 0 6 0 5 40 CONTINUOUS 100 F47 0.0 0 AcDbSymbolTable 330 0 ENDTAB 70 7 ENDTAB 0 0 100 0 TABLE 0 AcDbSymbolTableR TABLE 2 ENDTAB eccrd 88 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 100 10 41 0 AcDbUCSTableRec 330 0.18 174 ord g 42 0 2 100 0.0625 175 BARREL AcDbSymbolTableR 43 0 70 ecord 0.38 176 0 100 44 0 10 AcDbRegAppTableR 0.18 177 - ecord 45 0 83.702635831373 2 0.0 178 86 ACAD 46 0 20 70 0.0 270 - 0 47 2 1266.0667500978 0 0.0 271 55 ENDTAB 48 4 30 0 0.0 272 64 .523424060288 TABLE 140 4 35 2 0.18 273 11 DIMSTYLE 141 2 0.2092723394099 5 0.09 274 572 A 142 2 21 330 0.0 340 0.9774888511837 0 143 F 261 100 25.4 275 31 AcDbSymbolTable 144 0 0.0268446227278 70 1.0 280 986 1 145 0 12 0 0.0 281 - DIMSTYLE 146 0 0.0056198622950 105 1.0 282 596 ID 147 0 22 330 0.09 283 - A 71 1 0.0262497793740 100 0 284 781 AcDbSymbolTableR 72 0 32 ecord 0 285 0.9996396181777 100 73 0 694 AcDbDimStyleTabl 1 286 0 eRecord 74 0 ENDTAB 2 1 287 0 STANDARD 75 3 TABLE 70 0 288 2 0 76 0 APPID 3 0 0 5 77 ENDTAB 9 4 0 0 330 78 TABLE 0 5 0 2 100 170 BLOCK E AcDbSymbolTable 6 0 5 70 171 1 1 7 2 330 0 172 0 APPID 40 0 100 5 1.0 173 AcDbSyn Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. e 5 0.0 22 70 19 20 -1740.478589 0 330 0.0 32 0 18 30 28.864608 BLOCK RECORD 100 0.0 13 5 AcDbEntity 3 -904.905694 18 8 *PAPER SPACE 23 102 0 1 -1686.419993 {ACAD XDICTIONA 100 33 RY AcDbBlockBegin 0 30 . 826131 360 2 ENDBLK 0 105C *MODEL SPACE 5 3DFACE 102 70 17 5 } 0 330 F28 330 10 15 330 i 0.0 100 18 100 20 AcDbEntity 100 AcDbSymbolTable 0.0 67 AcDbEntity Record 30 1 8 100 0.0 8 GRID AcDbBlockTabieR 3 0 100 ecord *MODEL SPACE 100 AcDbFace 2 1 AcDbBlockEnd 10 *MODEL SPACE 0 -860.492304 0 0 ENDSEC 20 BLOCK RECORD ENDBLK 0 -1751.571355 5 5 SECTION 30 15 1A 2 52.688752 102 330 ENTITIES 11 {ACAD XDICTIONA 18 0 -861.220376 RY 100 3DFACE 21 360 AcDbEntity 5 -1804.577368 105A 8 F27 31 102 0 330 36.626537 } 100 18 12 330 AcDbBlockEnd 100 -905.690087 1 0 AcDbEntity 22 100 BLOCK 8 -1791.394468 AcDbSymbolTable 5 GRID 32 Record 16 100 10.692634 100 330 AcDbFace 13 AcDbBlockTabieR 15 10 -905.329424 ecord 100 -859.686445 23 2 AcDbEntity 20 -1740.478589 *PAPER SPACE 67 -1695.874529 33 0 1 30 28.864608 ENDTAB 8 56.935404 0 0 0 11 3DFACE ENDSEC 100 -860.492304 5 0 AcDbBlockBegin 21 F29 SECTION 2 -1751.571355 330 2 *PAPER SPACE 31 18 BLOCKS 70 52.688752 100 0 0 12 AcDbEntity BLOCK 10 -905.329424 8 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. GRID 32 AcDbFace 100 2.888682 10 AcDbFace 13 -905.690087 10 -949.997256 20 -861.220376 23 -1791.394468 20 -1675.968165 30 -1804.577368 33 10.692634 30 4.131685 11 36.626537 0 -905.956918 11 3DFACE 21 -861.80806 5 -1841.710239 21 F34 31 -1856.863384 330 -8.046794 31 18 12 19.727898 100 -949.997256 12 AcDbEntity 22 -905.956918 8 -1825.771021 22 GRID 32 -1841.710239 100 -35.594856 32 AcDbFace 13 -8.046794 10 -949.997256 13 -905.329424 23 -905.690087 20 -1776.94582 23 -1740.478589 33 -1791.394468 30 -16.132569 33 28.864608 0 10.692634 11 LINE 0 -905.690087 5 3DFACE 21 100B 5 -1791.394468 330 F33 31 18 330 10.692634 100 18 12 AcDbEntity 100 -949.997256 8 AcDbEntity 22 0 8 -1776.94582 100 GRID 32 AcDbLine 100 -16.132569 10 AcDbFace 13 -949.997256 10 -949.997256 20 -904.905694 23 -1701.964639 20 -1727.961113 30 -1686.419993 33 3.510184 30 2 .888682 11 30.826131 0 -905.509756 11 3DFACE 21 -905.329424 5 -1765.936529 21 F35 31 -1740.478589 330 19.778621 31 18 0 28.864608 100 POINT 12 AcDbEntity 5 -949.997256 8 100C 22 GRID 330 -1727.961113 100 18 100 AcDbEntity 8 0 100 AcDbPoint 10 -905.509756 20 -1765.936529 30 19.778621 0 POINT 5 100D 330 18 100 AcDbEntity 8 0 100 AcDbPoint 10 -949.997256 20 -1701.964639 30 3.510184 0 ENDSEC 0 SECTION 2 OBJECTS 0 DICTIONARY 5 C 330 0 100 AcDbDictionary 3 ACAD_GRO U P 350 D 3 ACAD_LAYOUT 350 1001 3 ACAD_MLINESTYLE 350 91 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. IB } FFF 103E 3 330 102 3 ACAD PLOTSETTIN C {ACAD REACTORS PLOTSETDICT GS 100 330 350 350 AcDbDictionary C 103F 1002 0 102 3 3 DICTIONARY } PLOTSTYLNAMDICT ACAD PLOTSTYLEN 5 330 350 AME 1001 C 1040 350 102 100 3 FFF (ACAD REACTORS AcDbDictionary LWETCUNION 3 330 281 350 ACDBHEADERROQND C 1 1041 TRIPXREC 102 3 3 350 } Normal INSUNITS 1039 330 350 350 0 C 1000 1042 DICTIONARY 100 100 3 5 AcDbDictionary AcDbDictionaryWi CEPSNTYPE 105C 0 thDefault 350 330 DICTIONARY 340 1043 18 5 1000 3 100 IB 0 FINGERPRINTGUID AcDbDictionary 102 DICTIONARY 350 280 {ACAD REACTORS 5 1044 1 330 1039 3 3 C 102 VERSIONGUID ACAD LAYOUTSELF 102 {ACAD REACTORS 350 REF } 330 1045 360 330 C 3 105D C 102 PSVPSCALE 0 100 } 350 DICTIONARY AcDbDictionary 330 1046 5 3 C 3 105A STANDARD 100 DIMSTYLEDATA 330 350 AcDbDictionary 350 15 1C 3 1047 100 0 TSTACKALIGN 3 AcDbDictionary DICTIONARY 350 PUCSORTHOREF 280 5 103A 350 1 1002 3 1048 3 102 TSTACKSIZE 3 ACAD LAYOUTSELF {ACAD REACTORS 350 PUCSORTHOVIEW REF 330 103B 350 360 C 3 1049 105B 102 HYPERLINKBASE 3 0 } 350 PUCSBASE DICTIONARY 330 103C 350 5 C T 104A D 100 STYLESHEET 3 102 AcDbDictionary 350 PUCSORGTOP {ACAD REACTORS 0 103D 350 330 ACDBDICTIONARYWD 3 104B C FLT LAYOUTDICT 3 102 5 350 PUCSORGBOTTOM 92 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 350 XRECORD 52 1039 104C 5 90.0 102 3 105D 71 } PUCSORGLEFT 102 2 330 350 {ACAD REACTORS 49 1039 104 D 330 0.5 100 3 105C 62 AcDbXrecord PUCSORGRIGHT 102 256 90 350 } 6 70 104E 330 BYLAYER 0 3 105C 49 XRECORD PCJCSORGFRONT 100 -0.5 5 350 AcDbXrecord 62 103C 104 F 340 256 102 3 18 6 {ACAD REACTORS PUCSORGBACK 0 BYLAYER 330 350 XRECORD 0 1039 1050 5 ACDBPLACEHOLDER 102 3 105B 5 } UCSORTHOREF 102 1000 330 350 {ACAD REACTORS 102 1039 1051 330 {ACAD REACTORS 100 3 105A 330 AcDbXrecord UCSORTHOVIEW 102 FFF 1 350 } 102 1052 330 } 0 3 105A 330 XRECORD UCSBASE 100 FFF 5 350 AcDbXrecord 100 103D 1053 340 AcDbPlaceHolder 102 3 15 280 {ACAD REACTORS UCSORGTOP 0 0 330 350 MLINESTYLE 0 1039 1054 5 XRECORD 102 3 1C 5 } UCSORGBOTTOM 102 103A 330 350 {ACAD REACTORS 102 1039 1055 330 {ACAD REACTORS 100 3 IB 330 AcDbXrecord UCSORGLEFT 102 1039 1 350 } 102 1056 330 } 0 3 IB 330 XRECORD UCSORGRIGHT 100 1039 5 350 AcDbMlineStyle 100 103E 1057 2 AcDbXrecord 102 3 STANDARD 90 {ACAD REACTORS OCSORGFRONT 70 1 330 350 0 0 1039 1058 3 XRECORD 102 3 5 } UCSORGBACK 62 103B 330 350 256 102 1039 1059 51 {ACAD REACTORS 100 0 90.0 330 AcDbXrecord Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 340 {ACAD REACTORS 330 1039 1001 330 1039 102 0 1039 100 } XRECORD 102 AcDbXrecord 330 5 } 1 1039 103F 330 {0277A29B—FA53— 100 102 1039 4BF0—83A9- AcDbXrecord {ACAD REACTORS 100 F6DC1F973000} 340 330 AcDbXrecord 0 0 1039 90 XRECORD 0 102 0 5 XRECORD } 0 1046 5 330 XRECORD 102 1049 1039 5 {ACAD REACTORS 102 100 1043 330 {ACAD REACTORS AcDbXrecord 102 1039 330 340 {ACAD REACTORS 102 1039 1002 330 } 102 0 1039 330 } XRECORD 102 1039 330 5 } 100 1039 1040 330 AcDbXrecord 100 102 1039 40 AcDbXrecord {ACAD REACTORS 100 0.0 70 330 AcDbXrecord 0 0 1039 90 XRECORD 0 102 0 5 XRECORD } 0 1047 5 330 XRECORD 102 104A 1039 5 {ACAD REACTORS 102 100 1044 330 {ACAD REACTORS AcDbXrecord 102 1039 330 340 {ACAD REACTORS 102 1039 FFF 330 } 102 0 1039 330 } XRECORD 102 1039 330 5 } 100 1039 1041 330 AcDbXrecord 100 102 1039 1000 AcDbXrecord {ACAD REACTORS 100 DSTYLE 340 330 AcDbXrecord 1002 0 1039 1 { 0 102 { 8 FA65E0F-8AA7- 1070 XRECORD } 4FAF-BF0C- 277 5 330 D217 05CDEF27} 70 104B 1039 0 6 102 100 XRECORD 1002 {ACAD REACTORS AcDbXrecord 5 } 330 90 1045 0 1039 14877 102 XRECORD 102 0 {ACAD REACTORS 5 } XRECORD 330 1048 330 5 1039 102 1039 1042 102 {ACAD REACTORS 100 102 } 330 AcDbXrecord Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 10 } 102 1039 0.0 330 {ACAD REACTORS 100 20 1039 330 AcDbXrecord 0.0 100 1039 10 30 AcDbXrecord 102 0.0 0.0 10 } 20 0 0.0 330 0.0 XRECORD 20 1039 30 5 0.0 100 0.0 104C 30 Ac DbXre cord 0 102 0.0 340 XRECORD {ACAD REACTORS 0 0 5 330 XRECORD 0 1055 1039 5 XRECORD 102 102 104F 5 {ACAD REACTORS } 102 1052 330 330 {ACAD REACTORS 102 1039 1039 330 {ACAD REACTORS 102 100 1039 330 } AcDbXrecord 102 1039 330 10 } 102 1039 0.0 330 } 100 20 1039 330 AcDbXrecord 0.0 100 1039 10 30 AcDbXrecord 100 0.0 0.0 10 AcDbXrecord 20 0 0.0 70 0.0 XRECORD 20 0 30 5 0.0 0 0.0 104 D 30 XRECORD 0 102 0.0 5 XRECORD {ACAD REACTORS 0 1053 5 330 XRECORD 102 1056 1039 5 {ACAD REACTORS 102 102 1050 330 {ACAD REACTORS } 102 1039 330 330 {ACAD REACTORS 102 1039 1039 330 ) 102 100 1039 330 } AcDbXrecord 102 1039 330 10 } 100 1039 0.0 330 AcDbXrecord 100 20 1039 340 AcDbXrecord 0.0 100 0 10 30 AcDbXrecord 0 0.0 0.0 10 XRECORD 20 0 0.0 5 0.0 XRECORD 20 1054 30 5 0.0 102 0.0 104E 30 {ACAD REACTORS 0 102 0.0 330 XRECORD {ACAD REACTORS 0 1039 5 330 XRECORD 102 1057 1039 5 } 102 102 1051 330 {ACAD REACTORS Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 330 XRECORD 1039 5 102 1058 } 102 330 {ACAD REACTORS 1039 330 100 1039 AcDbXrecord 102 10 } 0.0 330 20 1039 0.0 100 30 AcDbXrecord 0.0 10 0 0.0 20 1039 0.0 100 30 AcDbXrecord 0.0 10 0 0.0 XRECORD 20 5 0.0 1059 30 102 0.0 {ACAD REACTORS 0 330 ENDSEC 1039 0 102 EOF } 330 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 12.2. Program code 12.2.1. RIPS.cpp // 2/10/2000 last edited: 7/1/2000 // University of Southern California, School of Architecture, // Masters of Building Science // Copyright 2000 by the University of Southern California and // Judith Leuppi, all right reserved / / // Judith Leuppi email: leuppi@hotmail.com // RIPS"; // Rib structure Interactive Plank System lines / / // C++ code for Reading in, processing and outputting a DXF-file // structure of a three dimensional surface. The program computes // lines running over the surface, which are bent only in the normal // plane to the surface. For further comments see Thesis Report / / // source file: RIPS.cpp #include ciostream.h>// for printing on screen and reading from keyboard finclude <fstream.h>// for printing in a file, and reading from a file // for text stream processing // for mathematical standard functions #include <iomanip.h> finclude <math.h> #include <stdlib.h> finclude <string.h> finclude "PlankLine.h" // standard library // for character strings // contains classes for processing the DXF file of a surface with 3DFACES and // set up a finite element mesh for running the algorithm // to find the plank line over finite element mesh finclude "Geometry3D.h" // contains classes for geometrical purposes, // copyright by Rick Wagner, used and modified with permission finclude "Queue2.h" // Queue class ("first in, last out") //[Main & Savitch, 1997, p. 372] (see Bibliography) finclude "Link2.h" // Linked list toolkit [Main & Savitch, // 1997, p. 295] (see Bibliography) / / ____________________ / / // Global variables: / / ________ int handseed = 0; // last (highest) number of the DXF entities int entityCount =0; // used as array counter int p = 0, 1 = 0, f = 0; // used as array counters: point-, line- // and face count 97 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. char answer[2] ; // answer of user ('y' for "yes" or any key for "no") // several times, in different functions DXFgroupCode* entityArray [ENTITY_ARRAYMAX] ; // array of DXFgroupCodes, // stores all the information // of the Entity section from the DXF file Point* point [POINTMAX] , - // point-, line- and face array respectively, containing the Line* line[LINEMAX]; // elements of the finite element mesh Face* face[FACEMAX]; Shape* shape; // finite element mesh / / __________________________ / / // Function Prototypes: / / void fillEntityArray (DXFgroupCode**, ifstream) ; // fills an array // with the information of the // Entity section from the DXF file void fillFaceArray (DXFgroupCode**) ; // fills a double array with the // information of the 3DFACES. void readPoints(DXFgroupCode* arrayOfFaces [FACES_ARRAYMAX] [FACE_ARRAYMAX] , int, int) ; // reads all the information from the / / faceArray and sets up a // finite element mesh with all the points, // lines and faces void distributePoints(); // checks the finite element // mesh, if the same point exists // several times, it eliminates the others void distributeLines(); // checks the finite element // mesh, if the same line exists // several times, it eliminates the others void divideEdge () ; // divides the edges in equal // parts and starts the plank line // algorithm at each of these dividing // points void startAngle(GeoPoint*, Direction3D* startDirection) ; // runs // plank line algorithm until edge // line is encountered Queue<char*> getBegining(ifstream) ; // stores the beginning (until // where new points and lines // have to be added) of the DXF file in // an Queue Queue<char*> getRest(ifstream) ; // stores the rest of the DXF // file in an Queue void addPoints(ofstream); // adds the new calculated // plank points in a new file void addLines(ofstream); // adds the new calculated // plank lines in a new file void addPart(ofstream, Queue<char*>) ; // adds a Queue containing a // part of the DXF file in a new file void skipLine (ifstream); // while reading from a file, it skips // a line whether there are 98 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // characters in there or not void pause(); // program stops until user hits any key Type checkCode (int); // performs a check of an integer, // depending on the value of the // integer, it returns a different TYPE. // checkCode-function implementation is in // PlankLine.cpp ! ! ! / / _________________________________________________________________________________ / / // Main function / / __________________________________________________________________________________ int main() { char c; int groupCode; char* charlnfo = new char; Queue<char*> rest; Queue<char*> begining; char inExtention[] = ".dxf"; char outExtention[] = "-OUT.dxf"; char filename[25], inName[25], outName[25]; cout « "\n r cout « "\n RIPS"; cout « "\n Rib structure Interactive Plank System lines "; cout << "\n / cout << "\n\n Copyright 2000 by the University of Southern California"; cout << "\n and Judith Leuppi, all right reserved"; cout « "\n for questions or remarks, please email to leuppi0hotmail.com"; cout « "\n\n The program calculates the plank lines on a 3 dimensional surface."; cout << "\n The input file must be a DXF-file of a surface drawn in AutoCAD "; cout « "\n according to the step-by-step description in the thesis report." « endl « endl; do { cout « "\nGive the name of the DXF-file (no extension)\t"; cin » filename; strcpy(inName, filename); // copies the name given by the // user into inName strcpy(outName, filename); // copies the name given by the user // into outName strcat(inName, inExtention); // adds the extension ".dxf" to the // filename strcat(outName, outExtention);// adds the extension "-OUT.dxf" to // the filename 99 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. cout << endl << "You -entered: 1" << inName <<"' \n\n"« "Is this correct? (press 'y' for Yes, any key for No) \t"; cin » answer; } while (strcmp(answer, "y")); // repeats asking the user about the filename until the answer is "y" ifstream inData(inName, ios::in); // opens the DXF-file with the // filename given by the user // (the file must be in the same folder as // the executable (.exe) if ( !inData ) // performs a check if file could // be opened { cout « "File could not be opened." << endl; cerr ; exit (1); do { inData » groupCode; // reads an integer line of the DXF file if (groupCode == 9) //if condition to find "handseed" { c = inData.get(); // steps to new line (steps over '\n') if (inData .peek () != ' \n')// if there is something in the next line { inData.getline(charlnfo, 255); // reads next string (associated // value of group code) until // new line encountered if ( ! (strcmp (charlnfo, "SHANDSEED") ) ) { inData >> groupCode, inData.setf(ios::hes<} ; // transforms the hexadecimal value // in a decimal value inData » handseed; inData.unsetf(ios: : hex); } } else inData.ignore() ; // if there is an empty line, // ignorer it and go to next line } else if (groupCode == 2) // if condition to find // "ENTITIES" section { c = inData.get(); // steps to new line (steps over '\n') if (inData.peek() != '\n')// if there is something in next line { inData.getline(char3!nfo, 255); // reads next string 100 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. //(associated value of group code) // until new line encountered if (!(strcmp(charlnfo, "ENTITIES"))) { fillEntityArray(entityArray, inData); // function called to // fill an array with all the } // information in the ENTITIES } // section this function reads several else // lines of the DXF file, until // the end of the ENTITIES section is reached! inData.ignore() ; // if there is an empty line } else { skipLine (inData); // it the group code is whether // 2 nor 9, skip the next line } // containing the associate d value } while (inData && ! inData. eof ()) ; // until the end of the DXF // file is reached ifstream storeData(inName, ios::in); // opens the DXF-file with // the filename given by the user a second time if ( !storeData ) // performs a check if file could be opened { cout « "File could not be opened." « endl; cerr; exit (1) ; } begining = getBegining(storeData) ; // stores the beginning of the DXF file (until the ENTITIES // section starts) in a Queue called //"beginning" rest = getRest(storeData) ; // stores the rest of the DXF file // in a Queue called "rest" fillFaceArray(entityArray) ; // fills a double array with the // information of the 3DFACES. // in this function the function // "readPoints" is called, which // reads all the information from the // faceArray and sets up a // finite element mesh with all the points, lines and faces distributeLines(); // checks the finite element // mesh, if the same point exists // several times, it eliminates the others distributePoints(); // checks the finite element // mesh, if the same line exists // several times, it eliminates the others divideEdge () ; // divides the edges in equal parts // and starts the plank line // algorithm at each of these dividing 101 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // points ofstream outData(outName, ios::out); // opens a new, blank file // with the ending "-OUT.dxf" if { 'outData ) // performs a check if file // could be opened { cout « "File could not be opened." << endl; cerr; exit (1) ; } addPart(outData, begining) ; // adds the content of the Queue // "beginning" in the new file addPoints(outData); // adds the coordinates of the new // calculated points in the new file addLines(outData); // adds the coordinates of the new // calculated lines in the new file addPart(outData, rest); // adds the content of the Queue // "rest" in the new file cout «"\n\nProgram finished correctly" <<endl; pause (); return 0; } // end of main function / / _______________________________________________________________ // adds the points to the DXF-file according // addPoints to the DXF-file structure / / ____________________________________________________________ void addPoints(ofstream outData) // "handseed" and "shape" are // global variables { // the directly following number of // handseed is not handseed += 100; // working, therefore a // gap of 100 is created between // the existing DXF entities and the // new added elements for (int i = 0; i < shape->get_geoPointCount () ; i++) // for all the // geoPoints contained in the shape { outData « "0\n" « "P0INT\n" « "5\n"; outData.setf(ios::hex | ios::uppercase); outData « handseed« "\n"; outData.unsetf(ios::hex | ios::uppercase); outData « "330\n" « "2\n" « "100\n" « "AcDbEntity\n"; outData « "8\n" « "0\n" « "100\n" « "AcDbPoint\n";// the new // points are set in the default // layer 0 outData « "10\n" « shape->get_geoPoint(i)->get_pointIn()->getX () « "\n"; outData « "20\n" « shape->get_geoPoint(i)->get pointln()- 102 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. >getY() « "\n" ; outData « "30\n" « shape->get_geoPoint(i)->get_pointIn()->getZ () « " \ n " ; handseed++; } } / / ______________________________________________________________ // adds the lines to the DXF-file // addLines according to the DXF-file structure / / ______________________________________________________________ void addLines(ofstream outData) // "handseed" and "shape" are global // variables { for (int i = 0; i < shape->get_geoLineCount () ; i++) // for all the // geoLines contained in the shape { outData « "0\n" « "LINE\n" « "5\n"; outData.setf(ios::hex | ios::uppercase); outData << handseed<< "\n"; outData.unsetf(ios::hex | ios::uppercase); outData « "330\n" « "2\n" « "100\n" « "AcDbEntity\n"; outData « "8\n" « "0\n" « "100\n" « "AcDbLine\n"; // the new // points are set in the default // layer 0 outData << "10\n" << shape->get_geoLine(i)->get_pl()->get_x() « " \n"; outData << "20\n" << shape->get_geoLine(i)->get_pl()->get_y() « "\n"; outData << "30\n" « shape->get_geoLine(i)->get_pl()->get_z() << "\n"; outData << "ll\n" « shape->get_geoLine(i)->get_p2()->get_x{) << "\n" ; outData « "21\n" « shape->get_geoLine(i)->get_p2()->get_y() << " \ n " ; outData << "31\n" « shape->get_geoLine(i)->get_p2()->get_z() << "\n"; handseed++; } ) / / ___________________________________________________________ // stores the beginning (until where new points // getBegining and lines have to be added) of the DXF file //_________________ in a Queue, called "beginning", with a linked list Queue<char*> getBegining(ifstream data) { char* temp = NULL; Queue<char*> begining; do { 103 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. temp - new char [225]; data. get line (temp, 225) ; //reads till \n encountered // (default) [Deitel &Deitel, p. 324] begining. insert (temp) ; } while (strcmp(temp, "ENTITIES")); // reads each line until ENTITIES // is encountered // (ENTITIES- line is included) return begining; } / / ________________________________________________________________ // stores the rest of the DXF // getRest file in an Queue called "rest", //__________________________________ with a linked list Queue<char*> getRest (ifstream data) { char* temp; Queue<char*> rest; while (!data.eof () ) { temp - new char[225]; data. getline (temp, 225) ; //reads till \n encountered // (default) [Deitel & Deitel, p. 324] rest.insert(temp) ; } return rest; } / / _________ If // addPart //__________ void addPart(ofstream data, Queue<char*> part) { while (! part. is_empty () ) data « part. get_front () <<"\n"; } / / ___________ // // skipLine //___________ void skipLine (ifstream line) { char c; char temp[255]; c = line, get (); // steps to new line (steps over '\n') 104 while reading from a file, it skips a line whether there are characters in there or not adds a Queue containing a part of the DXF file in a file Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. if (line.peek() != '\n') // if there are some char in next line: { line.getline(temp, 255); // reads next string until new line // encountered } else line.ignore(); // if new line is empty, ignore the "\n" } / / ____________________________________________________________ // fills an array with the information // fillEntityArray of the Entity section //____________________________________ from the DXF file void fillEntityArray (DXFgroupCode** entityArray, ifstream inData) { DXFgroupCode* data = NULL; int groupCode, intInfo; double doublelnfo; float floatlnfo; char* charlnfo = NULL; char c; for (int i = 0; i < ENTITY_ARRAYMAX; i++) //init. of array { entityArray[i] = NULL; } do { inData » groupCode; // reads the group code data = new DXFgroupCode; data->set_groupCode(groupCode); // and puts it in the class // DXFgroupCode in groupCode switch (checkCode(groupCode)) // depending on the value of the // group groupCode, the associated // value of the next line is put in the // corresponding private { // variable of class DXFassocValue, case CHAR: // DXFgroupCode has a pointer to the // DXFassocValue charlnfo = new char; c = inData.get () ; // steps to new line (steps over '\n') inData.getline(charlnfo,255); data->get_assocValue()->set_charInfo(charlnfo); break; case INT: inData » intInfo; data->get_assocValue()->set_intInfo(intlnfo); break; case HEX: inData.setf(ios::hex); 105 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. inData » intInfo; inData.unsetf(ios::hex); data->get_assocValue()->set_intInfo(intlnfo); break; case DOUBLE: inData » doublelnfo; data->get_assocValue()->set_doubleInfo(doublelnfo); break; case FLOAT: inData » floatlnfo; data->get_assocValue()->set_floatlnfo(floatlnfo); break; case ERR: cout << " error in Input-DXF file "; break; } entityArray[entityCount] = data; // the DXFgroupCode with the // associated DXFassocValue // are put in an array entityCount++; // entityArray and entityCount are // global variables because they // are used in the next function to be // further processed if (entityCount >= ENTITY_ARRAYMAX) { cout « "\n\nERROR! ENTITY_ARRAYMAX constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; exit (1); } } while (inData && strcmp(data->get_assocValue()- >get_charInfo(),"ENDSEC")); // the loop is repeated } // until the end of ENTITIES section is reached / / _ _ _ _____________________________________________________ // fills a double array with the information o // fillFaceArray the3DFACES and calls the function "readPoints" //_________________________ _ to set up a finite element mesh void fillFaceArray (DXFgroupCode** entityArray) { int facesCount = 0; int faceCount = 0; DXFgroupCode* b = new DXFgroupCode; DXFgroupCode* arrayOfFaces[FACES_ARRAYMAX][FACE_ARRAYMAX]; for (int m = 0; m < FACES_ARRAYMAX; m++) { for (int n = 0; n < FACE_ARRAYMAX; n++) { arrayOfFaces[m][n] = NULL; // initialization of double array Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. } } for (int i = 0; i < entityCount; i++) { b = entityArray [i] ; if ( (b->get_giroupCode () == 0) && (! strcmp (b->get_assocValue () - >get_charInfo () , r -3DFACE" ) ) ) // searches the entityArray for 3DFACES { faceCount = 0 ; do { arrayOf Faces [facesCount] [f aceCount] = b; i++; faceCount+-(-; if (faceCount >= FACE_ARRAYMAX) { cout << " \n\nERR0RI FACE_ARRAYMAX constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; exit (1) ; } b = entityArray [i] ; } while (b->ge-t_groupCode () 1= 0); i — ; facesCount++ ; if (facesCount >= FACES_ARRAYMAX) { cout « "\ra.\nERRORl FACES_ARRAYMAX constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; exit (1); } } } readPoints (arrayOf Faces, facesCount, faceCount); // and calls the J / function readPoints to set up a } // finite element mesh / / ____________________________________________________________ // areads the x, y and z coordinates of the points from // readPoints the faceArray and sets up a finite element mesh //__________________________ with all the points, lines and faces void readPoints (DXFgroupCode* arrayOf Faces [FACES_ARRAYMAX] [FACE_ARRAYMAX] , int facesCount, int faceCount) 107 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { / / double xO, xl, x2, x3, yO, yl, y2, y3, zO, zl, z2, z3; int nbr; shape = new Shape; for (int il = 0; il < POINTMAX; il++) //initialization of array { point[il] = NULL; } for (int jl = 0; jl < LINEMAX; jl++) //initialization of array { line[j1] = NULL; for (int kl = 0; kl < FACEMAX; kl++) //initialization of array { face[kl] = NULL; for (int i = 0; i < facesCount; i++) // reads x, y and z of each of the 4 points of a 3DFACE { for (int j =0; j < faceCount; j++) { switch (arrayOfFaces[i][j]->get_groupCode()) { case 5: cout.setf(ios::hex); nbr = (arrayOfFaces[i] [j]->gst_assocValue ()->get_int!nfo()); cout.unsetf(ios::hex); case 10: xO = (arrayOfFaces[i] break; >get_doubleInfo() case 20: yO >get_doubleInfo() case 30: zO >get_doubleInfo() case 11: xi >get_doubleInfo() case 21: yl >get_doubleInfo() case 31: zl >get_doubleInfo() case 12: x2 >get_doubleInfo() case 22: y2 >get_doubleInfo() case 32: z2 >get_doubleInfo() case 13: x3 >get_doubleInfo() case 23: y3 >get_doubleInfo() case 33: z3 >get doublelnfo() ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; = (arrayOfFaces[i] ; break; ->get_assocValue( ->get_assocValue ( ->get_assocValue( ->get_assocValue( ->get_assocValue( ->get_assocValue( ->get_assocValue( ->get_assocValue( ->get_assocValue( ->get_assocValue( ->get_assocValue( ->get_assocValue( 108 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. default: break; } } point[p] point[p+1] point[p+2] point[p+3] = new Point (p, xO, yO, zO) ; // "pair" is associated = new Point(p+1,xl,yl,zl); // continuous number (p) = new Point(p+2,x2,y2,z2); = new Point (p+3, x3, y3, z3) ; // each x, y, z coordinate // to a point, with a line[l] = new Lined, point [p], point[p+l]); // 4 lines, with a // continuous number (1) are set up line[1+1] = new Line(1+1, point[p+1], point[p+2]); line[1+2] = new Line(1+2, point[p+2], point[p+3]); line[1+3] = new Line(1+3, point[p+3], point[p]); face[f] = new Face(nbr, line[1],line [1+1],line[1+2],line[1+3]); // a face, with a continuous number (f) // is set up shape->add_face(face[f]); // all the faces are added to // the shape (global variable) p= p+4; 1= 1+4; f++; // ATTENTION: because each single 3DFACE has its own // four points and four lines, //a line exists two times (except boundary lines), // a point to eight times (except boundary points)! if (p >= POINTMAX) { cout << "\n\nERROR! POINTMAX constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; exit (1) ; } if (1 >= LINEMAX) { cout « "\n\nERROR! LINEMAX constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; exit (1); } // the verification for the number of max faces is done } // in the Shape class implementation (add_face) } / / ____________________________________________________________ // checks the finite element mesh, // distributeLines if the same line exists several //_____________________________ times, it eliminates the others void distributeLines() { int fcount; 109 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. for (int i=0; i < 1-1 ; i++) { for (int j = (i+1); j < 1; j++) { if (line[i]->equal(line[j])) // equal means: the same coordinates { fcount = line[j]->get_faceNbr(); // _faceNbr here is always 1 - > only passing one time // through loop for (int f = 0; f < fcount; f++) { // pointer of face needs to be set to the remaining face line[j]->get_partOfFace(0)->unset_line(line[j]); // removes the pointer from the Face to // the Line j, does NOT remove the pointer // from the Line j to the Face! line[j]->get_partOfFace(0)->add_line(line[i]); // adds a pointer from the Face to the Line i, } // AND a pointer from Line i to the Face, line[j]->get_pl()->unset_partOfLine(line[j]); // the points // of the line need to be unset, but cannot be // erased! This will happen in the next function line[j j->get_p2()->unset_partOfLine(line[j ] ) ; delete line[j]; // sets _condition to "DEAD", Face-, // Line- and Point-pointers to NULL // and all the other private variables to 0. // Does NOT remove the pointers from // the Faces or from the Points TO the Line! for (int k = j; k < 1; k++) { line[k] = line[k+l]; // the open space in the line array is // replaced by the remaining lines } 1— ; } } } } / / ____________________________________________________________ // checks the finite element mesh, // distributePoints if the same point exists //________________________________ several times, it eliminates the others void distributePoints() { int lcount; for (int i = 0; i < p-1 ; i++) { for (int j = (i+1); j < p; j++) { if (point[i]->equal(point[j])) // equal means: the same 110 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // coordinates { Icount = point [j ]->get_lineNbr () ; // _lineNbr here is 1 or 2 for (int 1=0; 1 < Icount; 1++) { point[j]->get_partOfLine(1)->unset_point(point [j]); // removes the pointer from the Line 1 to // the Point j, does NOT remove the pointer // from the Point j to Line 1! point[j]->get_partOfLine(1)->add_point(point [i] ) ; // adds a pointer from the Line 1 to the } // Point i, AND a pointer from Point i to Line 1 delete point[j]; // removes the pointers from the // Point to the Lines, does NOT remove the // pointers from the Line to the Point j for (int k=j; k<p; k++) { point[k] = point[k+l]; // the open space in the array of } // lines is replaced by the retaining lines P — ; } } } } / / ______________________________________________________________ / J divides the edges in equal parts // divideEdge and starts the plank line algorithm // _ at each of these dividing points void divideEdge() { int k=0, i = 0, j = 0, b; int last_k[4]; // last_k counts the number of // finite elements at each edge bool controll = 0, control2 =0; double xl[4], x2[4], yl[4], y2[4], zl[4], z2[4]; double proportion, plankRest, length[4], plankDistance[4]; int plankNumberl = 0, plankNumber2 =0; float plankAnglel = 0, plankAngle2 = 0; Line* helpLinel; // helpLines and helpPoints are // necessary, in order not to Line* helpLine2; // mess up the finite element mesh // without it, the message: Line* helpLineS; // "too many lines are part of // point" would appear Line* restEdge; Point* helpPointi; // necessary, if not message: // too many lines are part of point Point* helpPoint2; // necessary, if not message: // too many lines are part of point Point* corner[4]; Point* newCorner[4]; // necessary, if not message: // too many lines are part of point 11 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Line* edge[4][MAXEDGEELEMENTS]; Point3D* geoEdgePoint[4][MAXEDGEELEMENTS]; GeoPoint* plankPoint; Direction3D* startDirectionl, *startDirection2; for (int m = 0; m < 4; m ++) // initialization { xl[m] =0; x2[m] =0; yl[m] = 0; y2[m] =0; zl[m] =0; z2[m] = 0; last_k [m] =0; length[m] = 0; corner[m] = new Point; plankDistance[m] = 0; for (int n = 0; n < MAXEDGEELEMENTS; n++) { edge [m] [n] = new Line; geoEdgePoint[m] [n] = new Point3D; } r J while (! point [i]->get_condition () == CORNER) // search for any // corner i++; corner[j] = point[i] ; edge[j][k] = corner[j]->get_partOfLine(1); // j = 0, k = 0 // get any of the two lines for (j =0; j <4; j++) // sets up a double array with / / the boundary lines for each { // edge of the finite element mesh k = 0; // "length[j]" contains the real total // length of each of the // four edges (not a // projection!) length[j] = length[j] + edge[j][k]->get_length(); if (edge[j] [k]->get_pl()->same(corner[j])) // for the first pass { if ((edge[j] [k]->get_p2()->get_partOfLine(0)->get_condition () == BORDER) && !(edge[j][k]—>get_p2()->get_partOfLine(0)— >same(edge[j][k]))) edge[j][k+1] = edge[j][k]->get_p2()->get_partOfLine(0); else if ((edge[j][k]->get_p2()->get_partOfLine(1)- >get_condition() == BORDER) && ! (edge [ j] [k]->get_p2()- >get_partOfLine(1)->same(edge[j ] [k]))) edge[j][k+l] = edge[j][k]->get_p2()->get_partOfLine(1); else if ((edge[j][k]->get_p2()->get_partOfLine(2)- >get_condition() == BORDER) && ! (edge [ j] [k]->get_p2()- >get_partOfLine(2)->same(edge[j][k]))) edge [ j ] [k-t-1] = edge [ j ] [k]->get_p2 ()->get_partOfLine (2) ; } else { 112 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. if ((edge[j] [k] ->get_pl () ->get_partOfLine (0) ->get_condi.tion () = BORDER) && !(edge[j][k]->get_pl()->get_partOfLine(0)- >same(edge[j] [k] ) ) ) edge[j][k+l] = edge[j][k]->get_pl(}->get_partOfLine(0); else if ((edge[j][k]->get_pl()->get_partOfLine(1)- >get_condition() == BORDER) && !(edge[j][k]->get_pl()- >get_partOfLine(1)->same(edge[j ] [k] ) ) ) edge[j][k+l] = edge[j][k]->get_pl()->get_partOfLine(1); else if ((edge[j][k]->get_pl()->get_partOfLine(2)- >get_condition() == BORDER) && ! (edge[j] [k]->get_pl()- >get_partOfLine(2)->same(edge[j ] [k]))) edge[j][k+l] = edge[j][k]->get_pl()->get_partOfLine(2); } do { // for all the following passes k++; last_k[j] = k; // last_k counts the number of // finite elements at each edge if (k >= MAXEDGEELEMENTS) { cout << "\n\nERROR! MAXEDGEELEMENTS constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; exit (1) ; } length[j] = length[j] + edge[j][k]->get_length(); if (edge[j][k]->get_pl()->same(edge[j][k-1]->get_pl()) || edge[j][k]->get_pl()->same(edge[j][k-1]->get_p2())) { if ((edge[j] [k]->get_p2()->get_partOfLine(0)->get_condition () == BORDER) && !(edge[j][k]->get_p2()->get_partOfLine(0)- >same(edge[j][k]))) edge[j][k+I] = edge[jj[k]->get_p2()->get_partOfLine(0); else if ((edge[j][k]->get_p2()->get_partOfLine(1)- >get_condition() == BORDER) && !(edge[j][k]->get_p2()- >get_partOfLine(1)->same(edge[j][k]))) edge[jj[k+l] = edge[j][k]->get_p2()->get_partOfLine(1); else if ((edge[j][k]->get_p2()->get_partOfLine(2)- >get_condition() == BORDER) && !(edge[j][k]->get_p2()- >get_partOfLine(2)->same(edge[j][k]))) edge[j][k+1] = edge[j][k]->get_p2()->get_partOfLine(2); } else { if ((edge [ j] [k]->get_pl()->get_partOfLine(0)->get_condition () == BORDER) && !(edge[j][k]->get_pl()->get_partOfLine(0)- >same(edge[j][k]))) edge[j][k+l] = edge[j][k]->get_pl()->get_partOfLine(0); else if ((edge[j][k]->get_pl()->get_partOfLine(1)- >get_condition() == BORDER) && !(edge[j][k]->get_pl()- 11 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. >get_partOfLine(1)->same(edge[j][k]))) edge[j][k+l] = edge [ j ] [k] ->get_pl () — >get_partOfLine (I) ; else if ( (edge [ j ] [k] ->get_pl () ->get_p artOfLine (2) - >get_condition() == BORDER) && !(edge[j][k] ->get_pl()- >get_partOfLine(2)->same(edge[j][k]))) edge[j][k+l] = edge [ j ] [k] ->get_pl () — >get_partOfLine (2) ; } } while ( (edge [ j 1 [k]->get_pl ()->get_condit ion() != CORNER) && (edge[j ] [k]->get_p2()->get_condition() != CORNER)); if (j < 3) // connection from last edge element to first // edge element on next edge { // special case for last edge: no continuation // needed edge[j+l] [03 = edge[j3 [k+1] ; if (edge[j] [k]->get_pl()->get_condition() == CORNER) corner[j+13 = edge[j][k]->get_pl(); else if (edge [ j 3 [k]->get_p2 ()->get_conc2ition () == CORNER) comer [j+1] = edge [ j ] [k] ->get_p2 () ; } } do // prompts the user for the number of planks on 2 edges { cout « "\n\n\nGive the number of ribs in first direction: (max " « last_k[03 « " = " « last_k[23 « ")\t"; cin » plankNumberl; cout << "\nGive the number of ribs in second direction: (max " « last_k[l] « " = " « last_k[3] « ")\t"; cin » plankNumber2; cout « endl « "You entered: ' " « plankNumberl « " and " << plankNumber2 <<"'\n\n"<< "Is this correct? (press 'y' for Yes, any key for No)\t"; cin >> answer; } while (strcmp(answer, "y")); plankDistance[03 = length[03 / plankNumberrl; // dividing the // total length of the plankDistance[1] = length[1] / plankNumberr2; // edge by the // number of planks (user choice). plankDistance [2] = length [2] / plankNumbed; // Result: distance between the planks plankDistance [3] = length [3] / plankNumber:2; do // prompts the user for the angle of planks on 2 edges { //(angle between diagonal and plank) cout « "\n\nGive the angle between the zribs and the first diagonal:\t"; // "0" means: direction equal to diagonal, // "45" means approx parallel to the edges cin » plankAnglel; 114 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. cout « "\nGive the angle between the ribs and the second diagonal:\t"; cin >> plankAngle2; cout << endl << "You entered: « plankAnglel « " and " « plankAngle2 <<"' \n\n"« "Is this correct? (press ’ y' for Yes, any key for No)\t"; cin » answer; } while (strcmp(answer, "y")); startDirectionl = new Direction3D(corner[0], corner [2],rad(plankAnglel)); // sets the // direction according to the first diagonal startDirection2 = new Direction3D(corner[1],corner [3],rad(plankAngle2)); // sets the // direction according to the second diagonal for (j =0; j < 4; j++) { b = 0; for (k =0; k < last_k[j]; k++) { if ((edge[j][k]->get_length() > plankDistance[j]) M (edge[j][last_k[j]]—>get_length() > plankDistance[j]) ) { cout « "\n\nMesh is not dense enough or plank distance to big. Invalid conditions\n"; cerr; // the mesh has to be denser than the distance exit(l); // between the planks (precision of result!) } else { plankRest = plankDistance[j ] ; while ((plankRest - edge[j ] [k]->get_length()) > EPSILON) // repeated until the start point of // the plank lies in between the two points of an { // edge element plankRest = plankRest - edge[jj [k]->get_length() ; k++; } proportion = plankRest / edge[j] [k]->get_length() ; // proportion to find out how far // apart the points lies from point 1 and point2 if (proportion > ONE) // ONE = 0.99 // to avoid having a point in a zone // outside the face which it is belonging to proportion = ONE; // ONE must be smaller than (1 - EPSILON) // but as close as possible to 1 xl[j] = edge[j][k]->get_pl()->get_x(); yl[j] = edge[j] [k]->get_pl()->get_y(); 115 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. zl[j] = edge[j][k]->get_pl()->get_z(); x2[j] = edge[j][k]->get_p2()->get_x(); y2[j] = edge[j][k]->get_p2()->get_y{); z2[j] = edge[j][k]->get_p2()->get_z(); newCorner[j] = new Point(corner[j]->get_x(),corner[j]- >get_y () , corner [j ] ->get_z () ) ; helpPointl = new Point(xl[j],yl[j], zl[j]); helpPoint2 = new Point(x2[j],y2[j], z2[j ]) ; helpLinel = new Line(helpPointl,newCorner[j]); helpLine2 = new Line(helpPoint2,newCorner[j]); // newCorner, helpPoint and helpLine are necessary, // if not message: too many lines are part of point if ( helpLinel->get_length() < helpLine2->get_length() ) // to find out, which point is closer { //to the corner where the loop started xl[j] = xl[j] + proportion * (x2[j] - xl[j]) yl[j] = yl[j] + proportion * (y2[j] - yl[j]) zl[j] = zl[j] + proportion * (z2[jj - zl[j]) geoEdgePoint[j] [b]->setX ( (float)xl[j ] ) geoEdgePoint[j] [b]->setY( (float)yl[j]) geoEdgePoint[j] [b]->setZ((float)zl[j 3) restEdge = new Line(Point_Point3D(geoEdgePoint[j][b]), helpPoint2); } // restEdge will be used later to continue else // the algorithm in the next pass of the loop { xl [j] = x2[j] + proportion * (xl[j] - x2[j]) yl[j] = y 2 [ j ] + proportion * (yl [ j ] - y2[j]) zl[j] = z2[j] + proportion * (zl[j] - z2[j]) geoEdgePoint[j] [b]->setX ( (float)xl[j ] ) geoEdgePoint[j) [b]->setY((float)yl[j ] ) geoEdgePoint[j] [b]->setZ((float)zl[j ] ) restEdge = new Line(Point_Point3D(geoEdgePoint[j][b]), helpPointl); } // restEdge will be used later to continue // the algorithm in the next pass of the loop //delete helpPointl; // program fails if delete helpPoint! //delete helpPoint2; // program fails if delete helpPoint! delete helpLinel; delete helpLine2; helpLine3 = new Line; // necessary, if not message: too many // lines are part of point helpLine3 = edge[j][k]; // the starting point of a plank on an edge is found, 116 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // and added to the shape plankPoint = new GeoPoint(geoEdgePoint[j][b], helpLine3, helpLine3->get_part0fFace(0), shape); shape->add_geoPoint(plankPoint); if (b == 0) { controll =0; control2 = 0; cout « "\n\nDo you want the FIRST series of plank lines on edge " « j+1 « "? \n(press 'y' for Yes, any key for No)\t"; cin » answer; if (!strcmp(answer, "y")) controll = 1; cout « "\nDo you want the SECOND series of plank lines on edge " « j+1 « ”? \n(press 'y' for Yes, any key for No)\t"; cin >> answer; if (!strcmp(answer, "y")) control2 = 1; } if (controll) startAngle(plankPoint, startDirectionl); // function is // called to compute the algorithm // for finding the plank points over the // shape in one direction if (control2) startAngle(plankPoint, startDirection2); // function is // called to compute the algorithm // for finding the plank points over the shape in // the other direction edge[j][k] = restEdge; k — ; b++; } } } / / / / // startAngle // runs -plank line algorithm until //_______________________________________________ edge line is encountered void startAngle(GeoPoint* plankPoint, Direction3D* startDirection) { GeoPoint* newPlankPoint; Point3D* point = new Point3D; Point* pi = NULL, *p2 = NULL; Line* line = new Line; Line* plankLine; 117 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. plankPoint->set_directionX(startDirection); point = plankPoint->get_pointOut(); line = plankPoint->get_partOfLineOut(); if (line->get_partOfFace(0)->same(plankPoint->get_partOf Face ())) { newPlankPoint = new GeoPoint(point, line, line->get_partOfFace(1) , shape); } else if (line->get_partOfFace(1)->same(plankPoint- >get_partOfFace())) { newPlankPoint = new GeoPoint(point, line, line->get_partOfFace(0) , shape); } else { cout << "error: Face not part of nothing"; pause(); } pi = Point_Point3D(plankPoint->get_pointIn()) ; p2 = Point_Point3D(plankPoint->get_pointOut()); plankLine = new Line(pi, p2); shape->add_geoPoint(newPlankPoint); shape->add_geoLine(plankLine); if (line->get_condition() == INSIDE) { startAngle(newPlankPoint, plankPoint->get_xAxisIn()); // recursive function call as long as the // line is not a boundary line } } / / _____________________________________________________________________________ / / // End / / _____ 118 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 12.2.2. PlankLine.h // 2/10/2000 last edited: 7/1/2000 // University of Southern California, School of Architecture, // Masters of Building Science // Copyright 2000 by the University of Southern California and // Judith Leuppi, all right reserved / / // Judith Leuppi email: leuppi@hotmail.com // RIPS"; // Rib structure Interactive Plank System lines / / // C++ code for Reading in, processing and outputting a DXF-file // structure of a three dimensional surface. The program computes // lines running over the surface, which are bent only in the normal // plane to the surface. For further comments see Thesis Report / / // Haederfile: PlankLine.h including: // DXFgroupCode, DXFassocValue, Point, Line, Face, Shape, GeoPoint, // LocalAxis (Implementation-file: see PlankLine.cpp) #ifndef DXFDATA_H #define DXFDATA_H // Predefinitions: class DXFassocValue; class Line; class Face; class Shape; class GeoPoint; class LocalAxis; class Point3D; // see Geometry3D.h class Edge3D; // see Geometry3D.h class Direction3D; // see Geometry3D.h class DirectedPoint3D; // see Geometry3D.h enum Cond { NOTDEF = 0, CORNER, BORDER, INSIDE, DEAD }; // for setting up a finite element mesh enum Type { CHAR = 1, INT, HEX, DOUBLE, FLOAT, ERR }; // for reading DXF file structure // Global constants: const float EPSILON = (float) 0.001; const float ONE = (float) 0.998; // ONE must be < than (I - EPSILON), but as close as poss. to 1 const ENTITY_ARRAYMAX = 100000; // must be > than number of group codes in the Entities section // of the original DXF file const FACES ARRAYMAX = 1000; Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // must be > than number of 3DFACES in the original DXF file const FACE_ARRAYMAX = 20; // must be > than the number of group codes in one 3DFACE const POINTMAX = (FACES_ARRAYMAX * 4 ) ; // must be > than the number of points and lines originally // built to form the finite element mesh const LINEMAX = (FACES_ARRAYMAX * 4); // They are in direct relationship with FACES_ARRAYMAX, because // each face creates four points and four lines, const FACEMAX = FACES_ARRAYMAX; // is equal to the number of 3DFACES const GEOPOINTMAX = 10000; // must be greater than the number of new // points created (a point is created whenever a // plankline intersects with a finite element grid line const GEOLINEMAX = GEOPOINTMAX; // is almost equal to number of // points; a line links two points const MAXEDGEELEMENTS = 100; // max grid-elements per edge / / ______________________________________________ // a class to store the Group Codes of a DXF file, // DXFgroupCode and it has a pointer to a DXFassocValue class, // for storing its Associated Values. class DXFgroupCode { public: // Default Constructor and Destructor DXFgroupCode(); -DXFgroupCode(); // Copy Constructor DXFgroupCode (const DXFgroupCode& source); // copies Group Code AND Associated Value // Assignment Operator void operator = (const DXFgroupCodeS source); // equals Group Code AND Associated Value // Bool Operator bool operator == (const DXFgroupCodes source); // checks Group Code AND Associated Value // Modification Member Functions void set_groupCode (const int& groupCode); // sets Group Code void set_assocValue (DXFassocValue *assocValue); // sets Associated Value // Constant Member Functions int get_groupCode() const {return _groupCode;} // gets Group Code DXFassocValue* get_assocValue() const {return _assocValue;} // gets Associated Value private: 120 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. irvt _groupCode ; DXFassocValue *_assocValue; }; / / ______________________________________________ // a class to store the Assoc Value to a Group Code of a DXF // DXFassocValue file. Depending on the type of the Assoc Value, //__________ it has to be stored in the corresponding private variable class DXFassocValue { public: // Default Constructor and Destructor DXFassocValue() ; 'DXFassocValue() ; // Copy Constructor DXFassocValue (const DXFassocValueS source); // Assignment Operator void operator = (const DXFassocValueS source); // Bool Operator bool operator == (const DXFassocValueS source); // Modification Member Functions void set_charInfo (const char* information); // sets charlnfo, // the other private variables are not affected or modified void set_intInfo (const int information); // sets intlnfo, the // other private variables are not affected or modified void set_floatInfo (const float information); // sets floatlnfo, // the other private variables are not affected or modified void set_doubleInfo (const double information);// sets doublelnfo, // the other private variables are not affected or modified // Constant Member Functions char* get_charlnfo() const {return _charInformation;} int get_intInfo() const {return _intInformation;} float get_floatlnfo() const {return _floatInformation;} double get_doubleInfo() const {return _doubleInformation;} private: char* _charInformation; int _intInformation; float _floatlnformation; double _doubleInformation; } ; / / ___________ // // Point //___________ class Point { public: 121 a Class for a Point of a finite element mesh. It has up to 4 pointers to Lines. Type condition tells, if the Point is a CORNER, BORDER or INSIDE Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // Constructors and Destructor Point(); // all Line-pointers are set to NULL, _condition // to NOTDEF, other private variables to 0. Point(int nbr, double x, double y, double z) ; // all Line-pointers // are set to NULL, _condition to NOTDEF, _lineNbr to 0. Point (double x, double y, double z) ; // all Line-pointers are set //to NULL, _condition to NOTDEF, _lineNbr and _nbr to 0. ~Point(); // sets _condition to "DEAD", the Line-pointers to NULL // and all the other private variables to 0. Does NOT // remove the pointers from the Lines TO the Point I // Copy Constructor Point (Point* source); // copies only x, y + z of the point. Line- // pointers are set to 0 NULL, _condition to NOTDEF, // other private variables to 0 // Assignment Operator void operator = (Point* source); // sets ALL private variables // equal to the source Point // Bool Function bool equal (Point* source); // returns true if the point's // coordinates are equal bool same (Point* source);// returns true it the "_nbr"s are equal // Modification Member Functions void unset_partOfLine (Line* partOfLine); // searches for Line, if // found, removes the pointer //from the Point to the Line and adjusts the // _condition and _linNbr. Does NOT remove // the pointer from the Line to the Point! void set_partOfLine (Line* partOfLine); // sets a pointer from the // Point to the Line, and adjusts // the _condition and _lineNbr. Does NOT set a // pointer from the Line // to the Point. A Point can point to max 4 Lines void set_nbr (const int nbr) ; // optional, can be used as a label, // to recognize a certain Point // (see "same"-bool function) void set_x (const double x) ; // sets the x coordinate of the Point void set_y (const double y) ; // sets the y coordinate of the Point void set_z (const double z) ; // sets the z coordinate of the Point // Constant Member Functions Cond get_condition() const (return _condition;} // returns the // condition: 0 = NOTDEF, 1 = CORNER, 2 = BORDER, 3 = INSIDE, // 4 = DEAD (is in direct relationship with "_lineNbr") Line* get_partOfLine(int i) const (return _partOfLine[i] ; } // returns one of the Lines, which the // Point points to. A Point can point to max 4 Lines int get_lineNbr() const (return _lineNbr;} // returns the number of pointers to Lines (max 4) int get_nbr() const (return _nbr;} // returns a int number of the Point which can be used // as a label of this Point double get_x() const (return x;}// returns x coordinate of Point 122 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. double get_y() const {return _y;} // returns y coordinate of Point double get_z() const {return _z;} // returns z coordinate of Point private: // Cond: 0 = NOTDEF, 1 = CORNER, 2 = BORDER, // 3 = INSIDE, 4 = DEAD, Cond _condition; // depending on the numbers of Lines, // which the Point points to // (is in direct relationship with "_lineNbr") Line** _partOfLine; // array of pointers to Lines, max. 4 Lines int _lineNbr; // keeps track of number of pointers to Lines (max 4) int _nbr; // optional, can be used as a label, to recognize a // certain Point (see "same"-bool function) double _x; double _y; double _z; }; / / _______________________________________________ // a Class for a Line of a finite element mesh. // Line It has 2 pointers to Points, up to 2 pointers to Faces //_______________ and a pointer to a Shape Type condition tells, if the // Line is a CORNER, BORDER or INSIDE class Line { public: // Constructors and. Destructor Line(); // all pointers are set to NULL, // _condition to NOTDEF, // all other private variables to 0. Line(int nbr, Point* pi, Point* p2); // Face- and Shape-pointers // are set to NULL, // _condition to NOTDEF, _faceNbr to 0. Line(Point* pi, Point* p2) ; // Face- and Shape-pointers are // set to NULL, _condition // to NOTDEF, _faceNbr and _nbr to 0 -Line(); // sets _condition to "DEAD", Face-, // Line- and Shape- pointers // to NULL and all the other private // variables to 0. // Does NOT remove the pointers from the // Shape, from the Faces // or from the Points TO the Line! // Copy Constructor Line (Line* source); // copies only the pointers to the Points. // All other pointers are set to NULL, _condition // to NOTDEF, other private variables to 0. // Assignment Operator void operator = (Line* source) ; // sets ALL private variables and pointers equal to the source Line // Bool Function bool equal (Line* source);//returns true if Line's Points are equal bool same (Line* source) ; / / returns true it the " nbr"s are equal 123 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // Modification Member Functions void set_partOfFace (Face* partOfFace) ; // sets a pointer from the // Line to the Face (max 2), and adjusts the //_condition and _faceNbr. Does NOT set a pointer // from the Face TO the Line. A Line can point // to max 2 Faces void set_partOfShape (Shape* partOfShape);// sets a pointer from the // Line to the Shape. Does NOT set a pointer from the // Shape TO the Line (optional, used for Planklines) void unset_partOfFace (Face* partOfFace);// searches for the Face, // if found, removes the pointer from the Line // to the Face and adjusts tne_ccndition and // _faceNbr. Does NOT remove the pointer from // the Face to the Line! void set_nbr (const int nbr); // optional, can be used as a label, // to recognize a certain Line // (see "same"-bool function) void set_pl (Point* pi); // sets a pointer from the Line to the // Point pi, sets ALSO a pointer // from the Point pi to the Line!! void set_p2 (Point* p2); // sets a pointer from the Line to the // Point p2, sets ALSO a pointer // from the Point p2 to the Line!! void unset_point(Point* p) ; // searches for the Point p, it found, // removes the pointer to the Point p. Does NOT // remove pointer from the Point p to the Line! void add_point(Point* p); // searches for a Point == 0. The // first found, it sets a pointer from the Line to // the Point p, sets ALSO a pointer from the Point //p to the Line!! void unset_points () ; // removes the pointers from the // Line to both Points void delete_points(); // deletes both Points // Constant Member Functions Cond get_condition() const {return _condition; } // returns the // condition: 0 = NOTDEF, 2 = BORDER, // 3 = INSIDE, 4 = DEAD (is in direct // relationship with ”_faceNbr") Face* get_partOfFace(int i) const {return _partOfFace[i];} // returns one of the Faces, which the // Line points to. A Line can point to max 2 Faces. Shape* get_partOfShape() const {return _partOfShape;} // returns the Shape, which the Line // points to (optional, used for Plank-lines) int get_faceNbr() const {return _faceNbr;} // returns the number // of pointers to Faces (max 2) int get_nbr () const {return _nbr; } // returns a int number of the // Line which can be used as a label of this Line float get_length() ; // returns the length of the Line Point* get_pl() const {return _pl;} // returns Point _pl Point* get_p2() const {return _p2;} // returns Point _p2 private: // Cond: 0 = NOTDEF, 2 = BORDER, 3 = INSIDE, 4 = DEAD, 124 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Cond _conditicn; J / depending on the numbers of Faces, which the // iine points to (is in direct relationship with // -'_faceNbr") Face** _partOfFace// array of pointers to Faces, max. 2 Lines Shape* _partOfShape; // pointer to a Shape (optional, used for /T Plank-lines) int _faceNbr; /f keeps track of the number of pointers to Faces int _nbr; /T (max 2) optional, can be used as a label, to /T recognize a certain Line (see "same"-bool /T function) Point* _pl; // pointer to Point pi Point* p2; // pointer to Point p2 } ; / / ______________________________________________ // a Class for a Face of a finite element mesh. // Face It h_as 4 pointers to Lines and a pointers to a Shape. //_______________ Typer condition tells, if the Face is a CORNER, BORDER // or INSIDE class Face { public: // Constructors and Destructor Face () ; J / all Line- and Shape-pointers are set to NULL, J/ _condition to NOTDEF, _nbr to 0. Face(int nbr, Line’* 10, Line* 11, Line* 12, Line* 13); // Shape-pointer is set to NULL, // _condition to NOTDEF, _nbr to 0. the Face points to each // of the 4Lines and the Lines are set to point to the Face Face(Line* 10, Line* 11, Line* 12, Line* 13); // Shape-pointer is // set to NULL, _condition to // NOTDEF. the Face points to each of the 4 Lines // and the Lines are set to point to the Face ~Face () ; // sets _condition to "DEAD", Shape-, and Line-pointers // to HULL and _nbr to 0. Does NOT remove the pointers // from the Shape and from the Lines TO the Face! // Copy Constructor: Face (Face* source)}; // copies only the pointers to the Lines. The // Shape pointer is set to NULL, _condition to NOTDEF, _nbr to 0. // Assignment Operator void operator = (Face* source); // sets ALL private variables and pointers equal to the source Line // Bool Operator bool equal (Face* source); // returns true if the Face's Lines are equal bool same (Face* source) ; // returns true it the "_nbr"s are equal // Modification Member Functions void set_nbr (const int nbr) ; // optional, cam be used as a label, to recognize a certain // Line (see "same"- bool function) 125 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. void unset_line (Line* 1); // searches for the Line 1, it found, removes the pointer to Line 1. // Does NOT remove the pointer from the Face to the Line! void add_line (Line* 1) ; // searches for a Line which is == 0, the // first found, it sets a pointer from the Face to this Line 1, // sets ALSO a pointer from the Line 1 to the Face!! void set_10 (Line* 10); // sets a pointer from the Face to the Line 10, sets ALSO a // pointer from the Line 10 to the Face!! void set_il (Line* 11); // sets a pointer from the Face to the Line 11, sets ALSO a pointer // from the Line 11 to the Face!1 void set_12 (Line* 12); // sets a pointer from the Face to Line 12, sets ALSO a pointer // from the Line 12 to the Face!! void set_13 (Line* 13); // sets a pointer from the Face to Line 13, sets ALSO a pointer e // from the Lin 13 to the Face!! void set_partOfShape (Shape* partOfShape); // sets a pointer from the Face to the Shape. Does NOT // set a pointer from the Shape TO the Line // Constant Member Functions Cond get_condition(); // returns the condition: 0 = NOTDEF, 1 = CORNER, // 2 = BORDER, 3 = INSIDE, 4 = DEAD int get_nbr() const (return _nbr;} // returns a int number of the Face which can be used // as a label of this Face Line* get_10() const (return _10; } // returns Line _10 Line* get_ll() const (return _11; } // returns Line _11 Line* get_12() const (return _12;} // returns Line _12 Line* get_13() const (return _13; } // returns Line _13 Shape* get_partOfShape () const (return _partOfShape;} // returns the Shape, which the Face points to private: // Cond: 0 = NOTDEF, 1 = CORNER, 2 = BORDER, 3 = INSIDE, 4 = DEAD, Cond _condition; // depending on the condition of the Lines, which the Face points to int _nbr; // optional, can be used as label, to recognize a Face, // see "same"-bool fct Line* _10; // pointer to Line _10 Line* _11; // pointer to Line _11 Line* _12; // pointer to Line _12 Line* _13; // pointer to Line _10 Shape* _partOfShape; // pointer to a Shape } ; / / // a Class for a Shape representing a finite element mesh. // Shape It has arrays of pointers to Lines, Faces and GeoPoints. //______________ The size of the arrays can be adjusted in the // global constants at the top of this file class Shape 126 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { public: // Constructors and Destructor Shape(); // array-counts are 0, pointer-arrays initialized to NULL ~Shape (); // array-counts are 0f pointers TO the Shape are removed, // arrays are deleted // Copy Constructor Shape (Shape* source); // Face-array and faceCount are // copied from the source Shape // Modification Member Functions void unset_face (Face* face); // searches for the Face, if found, // removes the pointer from the Face to the Shape // and removed the Face from the face-array. // faceCount++ void add_face (Face* face); // adds a pointer to a Face, // adds also a pointer from the Face to the Shape, // faceCount++ void add_geoPoint (GeoPoint* point); // adds a pointer to a GeoPoint, adds also a pointer // from the GeoPoint to the Shape, geoPointCount++ void add_geoLine (Line* geoLine); // adds a pointer to a Line, add // also a pointer from the Line to // the Shape, lineCount++ // Constant Member Functions Face* get_face(int i) {return _face[i];} // returns the Face i GeoPoint* get_geoPoint(int i) {return _geoPoint[i];} // returns the geoPoint i Line* get_geoLine(int i) {return _geoLine[i] ; } // returns the Line i int get_faceCount() {return _faceCount;} // returns the faceCount (number of Faces, which are // part of the Shape, resp. in the Face-array) int get_geoPointCount() {return _geoPointCount;} // returns the geoPointCount (number of GeoPoints, // which are part of the Shape, resp. in the GeoPoint- array) int get_geoLineCount() {return _geoLineCount;} // returns the geoLineCount (number of Lines, which // are part of the Shape, resp. in the Line-array) private: int _faceCount; // number of Faces, which are part of the Shape, // resp. in the Face-array int _geoPointCount; // number of GeoPoints, which are part // of the Shape, resp. in GeoPoint-array int _geoLineCount; // number of GeoLines, which are part of // the Shape, resp. in the Line-array Face** _face; // array of pointers to Faces GeoPoint** _geoPoint; // array of pointers to GeoPoints Line** _geoLine; // array of pointers to Lines }; 127 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. / / ________________________________________________ // a Class modeling a Plank point on an edge line // of a finite element grid // GeoPoint It has pointers to the Line and Face, of which // it is a part of. //_____________________________ It has member function to compute a Local // Coordinate system and to // compute a second Plank point on another edge. It // has pointers to both // of the Points a pointers to both of the Lines // where the points are on. class GeoPoint { public: // Constructors and Destructor GeoPoint() ; // all pointers are initialized with // "new", condition and _nbr // are set to NOTDEF, resp 0. GeoPoint(Point3D* point, Line* line, Face* face, Shape* shape); // The first (IN-) point has to be // given, as well the Line and Face and Shape // which it is part of. -GeoPoint (); // all pointers are deleted, _nbr and // condition are NOTDEF, resp 0 // Copy Constructor GeoPoint (GeoPoint* source, int nbr); // initial conditions are // copied, variables, which have to // be computed by an algorithm, initialized // as in Constructor // Assignment Operator void operator = (const GeoPoints source); // All private variables // are set equal to the source // Modification Member Functions void set_nbr (const int nbr) ; //a number representing a label //of the GeoPoint (optional) void set_pointIn (Point3D *pointIn); // the first (IN-) point is // set. The point represents a // known point of the plank line void set_directionX (Direction3D* xAxisIn); // the x-direction of // the first (IN-) point is set. The direction does not // need to be in the plane of the finite element grid // This function computes the algorithm for finding // the second (OUT-) Point of the finite element grid void set_partOfLineIn (Line* partOfLineln); // the Line on which the first (IN-) point lies, has to //be set, if not set with the constructor void set_partOfFace (Face* partOfFace); // the Face on which the // algorithm has to be calculated // has to be set, if not set with the constructor void set_partOfShape (Shape* partOfShape); // a pointer to the Shape is set 128 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // Constant Member Functions int get_nbr () const {return _nbr;} // returns number representing a label of GeoPoint (optional) Cond get_condition() const {return _condition; } // 0 NOTDEF, 1 CORNER, 2 BORDER, 3 INSIDE, 4 DEAD Point3D* get_pointIn{) const {return _pointIn; } // returns the first (IN-) point Point3D* get_pointOut() const {return _pointOut;} // returns the second (OUT-) point, which has been // calculated if the function set_directionX() has been called before Direction3D* get_xAxisIn() const {return _xAxisIn; } // returns the x Axis of the first (IN-) point. // (not to confuse with the inputted x-direction1) Line* get_partOfLineIn() const {return _partOfLineIn; } // returns Line on which lies the first (IN-) Point Line* get_partOfLineOut () const {return _partOfLineOut; } // returns Line on which lies the second (OUT-) Point Face* get_partOfFace() const {return _partOfFace; } // returns Face in which the algorithm is calculated Shape* get_partOfShape() const {return _partOfShape;} // returns Shape of which Geopoint is part of. float GeoPoint:: get_length (); // returns the length of the Geoline, which is the distance // between the first (IN-) and the second (OUT-) Point private: int _nbr; // optional, can be used as a label Cond _condition; // 0 NOTDEF, 1 CORNER, 2 BORDER, 3 INSIDE, 4 DEAD Point3D *_pointIn; // first (IN-) point, from here the algorithm // starts computing the plank line Point3D *_pointOut; // second (OUT-) point, this is the point where // the Plank line reaches the other end of the // finite element grid Direction3D *_xAxisIn; // x-Axis of the first (IN-) point. // Computed on calling the function // "set_directionX()" Line *_partOfLineIn; // Line, on which lies the first (IN-) point Line *_partOfLineOut; // Line, on which lies the second (OUT-) point Face *_partOfFace; // Face in which the algorithm is to be calculated Shape *_part Of Shape; // Shape or which the PlankLine is part of Point3D *_pl; // First corner point of finite element grid (or: Face) Point3D *_p2; // Second corner point of finite element grid (or: Face) Point3D *_p3; // Third corner point of finite element grid (or: Face) Point3D *_p4; // Forth corner point of finite element grid (or: Face) Edge3D * el2 ; // Edge which combines point -P1 with _p2 Edge3D * e23 ; // Edge which combines point _P2 with _p3 Edge3D * e34 ; // Edge which combines point _P3 with p4 Edge3D * e41; // Edge which combines point _p4 with pi }; 129 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. a Class modeling a Local Coordinate system of a // Plank Point (GeoPoint) It has a pointer to an origin Point and 3 // pointers to the x, y and z direction. An origin, two directions // defining a plane, and a Direction defining the x-direction must be given //______________ // / / LocalAxis //_______________ // class LocalAxis { public: // Constructor and Destructor LocalAxis(); // all pointers are initialized to "new" LocalAxis(Point3D* origin, Direction3D* planePl, Direction3D* planeP2, Direction3D* angle) ; // x-, y- and z-Axis are computed, origin is set ~LocalAxis(); // all pointers are deleted // Copy Constructor LocalAxis (LocalAxisJ source);// all pointers are copied from source // Assignment Operator void operator = (LocalAxis* source); // all pointers are set equal to the source // Modification Member Functions void set_origin (Point3D* origin); // sets origin void set_axis (Direction3D* planePl, Direction3D* planeP2, Direction3D* angle); // it determines local coordinate system for a given tang plane //(given by planePl and planeP2) and a x direction (angle) pointing // anywhere // Constant Member Functions Point3D* get_origin() const (return _origin;} //returns origin Direction3D* get_xAxis() const Direction3D* get_yAxis() const Direction3D* get_zAxis() const DirectedPoint3D* get_yzPlane () // (represented by (return _xAxis;} //returns x-Axis (return _yAxis; } //returns y-Axis (return _zAxis;} / returns z-Axis const; // returns a plane containing a point (origin) in the y- and z-Axis // the plane and direction normal to the plane (x-Axis)) DirectedPoint3D* get_zxPlane() const; // returns a plane containing the z- and x-Axis // (represented by a point (origin) in the plane // and direction normal to the plane (y-Axis)) DirectedPoint3D* get_xyPlane () const; // returns a plane containing the x- and y-Axis // (represented by a point (origin) in the plane // and direction normal to the plane (z-Axis)) private: Direction3D* _xAxis;//x-Axis of local coordinate system of a Point Direction3D* _yAxis;//y-Axis of local coordinate system of a Point Direction3D* _zAxis;//z-Axis of local coordinate system of a Point 130 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Point3D* _origin; //origin of local coordinate system of a Point } ; //____________________________________________________________ // // // General Helper Functions // // Point3D* Point3D_Point(Point* p) ; // transforms a point from Point-class to the Point3D-class Point* Point_Point3D(Point3D* p); // transforms a point from Point3D-class to the Point-class Direction3D* Direction3D_Point3D(Point3D* p); // transforms a point from Point3D-class to a Direction Point3D* Point3D_Direction3D(Direction3D* d); //transforms a Direction to a point of Point3D-class Line* Line_Edge3D(Edge3D* e) ; // transforms a Line to an Edge Edge3D* Edge3D_Line(Line* 1); // transforms an Edge to a Line void pause(); // stops running the program and prompts the user to //press any key to continue Type checkCode (int code); // Performs a check of a code, and returns its Type // (CHAR, INT, etc) according to the DXF file structure #endif Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 12.2.3. PlankLine.cpp // 2/10/2000 last edited: 7/1/2000 // University of Southern California, School of Architecture, // Masters of Building Science // Copyright 2000 by the University of Southern California and // Judith Leuppi, all right reserved // // Judith Leuppi email: leuppi@hotmail.com // f // RIPS"; // Rib structure Interactive Plank System lines // 'kie'ie-k'te-k'k'tr-ie'k'k-ir'k'k'k'k'ie'ie'ir'k-m ir'h'if'ie'ie'k'k'1r'k'te'k'k,'ir'k'ir'k'k'ir'ir'te'ic'ie'k'^'ie'te'ie, ie'k--k'k'k'if'k-ir'ie'ie-ie'k-'ie'ie'k'ie'te'ie^ • r // // C++ code for Reading in, processing and outputting a DXF-file // structure of a three dimensional surface. The program computes // lines running over the surface, which are bent only in the normal // plane to the surface. For further comments see Thesis Report // // Implementation file: PlankLine.cpp // Implementation for following Classes: // // DXFgroupCode, DXFassocValue // Point, Line, Face, Shape // GeoPoint, LocalAxis // // For comments, see Header file: "PlankLine.h" tinclude <stdlib.h> tinclude <string.h> #include ciomanip.h> #include <math.h> #include "PlankLine.h" #include "Geometry3D.h" //________________________________________________________________ // // // DXFgroupCode // // // Default Constructor DXFgroupCode::DXFgroupCode() { _groupCode = 0; _assocValue = new DXFassocValue; } // Destructor template <class Item> Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. DXFgroupCode::'DXFgroupCode() { _groupCode = 0; delete _assocValue; } // Copy Constructor DXFgroupCode::DXFgroupCode (const DXFgroupCode& source) { _groupCode = source._groupCode; _assocValue = source._assocValue; } // Assignment Operator void DXFgroupCode::operator = (const DXFgroupCodeS source) { _groupCode = source._groupCode; _assocValue = source ._assocValue; } // Bool Operator bool DXFgroupCode::operator = (const DXFgroupCodeS source) { (_groupCode == source._groupCode) && (_assocValue == source._assocValue); } // Modification Member Function void DXFgroupCode::set_groupCode(const int& groupCode) { _groupCode = groupCode; } void DXFgroupCode::set_assocValue (DXFassocValue *assocValue) { _assocValue = assccValue; } return // // // // DXFassocValue // _________ // // Default Constructor DXFassocValue::DXFassocValue() \ charlnformation = new char[]; intInformation = 0; floatlnformation =0; doublelnformation = 0; // Destructor DXFassocValue::'DXFassocValue() I ^ < * ■ » 133 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { delete [] _charInformation; _intInformation =0; _floatInformation = 0; _doubleInformation = 0; } // Copy Constructor DXFassocValue::DXFassocValue(const DXFassocValue& source) { _cnarInformation = new char[strlen{_charlnformation) +1]; strcpy (_charInformation, source ._charInformation) ; _intInformation = source._intInformation; _floatlnformation = source._floatlnformation ; _doubleInformation = source ._doubleInformation; } // Assignment Operator void DXFassocValue::operator = (const DXFassocValueS source) { _charInformation = new char[strlen(_charInformation) +1]; strcpy (_charInformation, source ._char Inf ormation) ; _intInformation = source._intInformation; _floatlnformation = source. floatlnformation ; doublelnformation = source, doublelnformation; // Bool Operator bool DXFassocValue::operator == (const DXFassocValue& source) { return ! (strcmp(_charInformation, source._charInformaticn)) && _intInformation == source ._intInformation && _floatInformation == source._floatlnformation && _doubleInformation == source._doubleInformation; } // Modification Member Functions void DXFassocValue: :set_charInfo (const char *information) { _charlnformation = new char [strlen (information) +1]; strcpy(_charInformation, information); } void DXFassocValue::set_intInfo(const int information) { _intInformation = information; } void DXFassocValue::set_floatlnfo(const float information) { _floatInformation = information; } 134 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. void DXFassocValue::set_doubleInfo (const double information) { _doubleInformation = information; } //________________________________________________________________// // // Point //________________________________________________________________// // Default Constructor Point::Point() { _conaition = NOTDEF; _partOfLine = new Line*[4]; for (int i = 0; i < 4; i++) _partOfLine[i] = NULL; _lineNbr = 0; _nbr = 0; _x = 0; _y = 0; _z = 0; } // Constructor Point::Point(int nbr, double x, double y, double z) { _condition = NOTDEF; _partOfLine = new Line*[4]; for (int i = 0; i<4; i++) _partOfLine[i] = NULL; _lineNbr = 0; _nbr = nbr; _x = x; _y = y; _z = z; } Point::Point(double x, double y, double z) { _condition = NOTDEF; _partOfLine = new Line*[4] ; for (int i=0; i<4; i++) _partOfLine[i] = NULL; _lineNbr = 0; _nbr = 0; _x = x; _y = y; _z = z; } // Destructor Point::~Point() { Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. _condition = DEAD; for (int i = 0; i < _lineNbr; i++) { // cout << "\n\nPoint destructor called, pointer " « i << " from and to the following line removed: line_nbr " « jpartOfLine[i]- >get_nbr() << endl; // pause(); // _partOfLine[i]->unset_point(this); //???? _partOfLine[i] = NULL; } _lineNbr = 0; _nbr =0; _x = 0; _Y = 0; _z = 0; } // Copy Constructor Point::Point (Point* source) { _condition = NOTDEF; _partOfLine = new Line* [4]; for (int i = 0; i<4; i++) _partOfLine[i] = NULL; _nbr = 0; _x = source->get_x () ; _y = source->get_y(); _z = source->get_z(); } // Assignment Operator void Point::operator = (Point* source) { _condition = source->get_condition(); _lineNbr = source->get_lineNbr(); for (int i = 0; i < _lineNbr; i++) _partOfLine[i] = source->get_partOfL±ne (i) ; _nbr = source->get_nbr(); _x = source->get_x(); _y = source->get_v(); _z = source->get_z(); } // Nonmember Function Bool Operator [MainSSavitch, p. 80] bool operator == (const Points pi, const Points p2) // Post condition: // returns true if the point's coordinates are equal { if ((fabs(pi.get_x() - p2.get_x()) <= EPSILON) ss (fabs(pi.get_y() - p2.get_y()) <= EPSILON) SS (fabs(pi.get_z() - p2.get_z()) <= EPSILON)) return true; else return false; } 136 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // Bool Function bool Point:requal (Point* source) { if ((fabs(_x - source->get_x ()) <= EPSILON) && (fabs(_y - source->get_y ()) <= EPSILON) && (fabs(_z - source->get_z ()) <= EPSILON)) return true; else return false; } // Bool Function bool Point::same (Point* source) { if (_nbr == source->get_nbr()) return true; else return false; } void Point::set_partOfLine (Line* partOfLine) { if (_lineNbr >= 4) { cout << "\n\nThis point is part of more Lines than max allowable (4)\n\n"; pause(); } else { _partOfLine[_lineNbr] = partOfLine; switch (_lineNbr) { case 0: _condition = NOTDEF; break; case 1: _condition = CORNER; break; case 2: _condition = BORDER; break; case 3: _condition = INSIDE; break; default: condition = NOTDEF; cout « "\n\nerror in Point Class\n\n"; pause() ; break; } _lineNbr++; } } void Point::unset_partOfLine (Line* partOfLine) { for (int i = 0; i < _lineNbr; i++) { if (_partOfLine[i]->same(partOfLine)) 137 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { //cout « "\n\nremoved pointer " « i « " to line: line number _partOfLine [i] ->get_nbr () «endl; //pause(); _partOfLine[i] = NULL; for (int k = i; k < _lineNbr; k++) { _partOfLine[k] = _partOfLine[k+1]; } _lineNbr— ; switch (_lineNbr) { case 0: case 1: _condition = NOTDEF; break; case 2: _condition = CORNER; break; case 3: _condition = BORDER; break; default: _condition = NOTDEF; cout « "\n\nerror in Point Class\n\n"; pause(); break; } } } void Point::set_nbr (const int nbr) { _nbr = nbr; } void Point::set_x (const double x) { _x = x ; } void Point::set_y (const double y) { _y = y; } void Point::set_z (const double z) { z = z; //________________________________________________________________ // // // Line // // Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. // Default Constructor Line::Line() { _condition = NOTDEF; _partOfFace = new Face*[2]; for (int i = 0; i < 2; i++) _partOfFace[i] = NULL; _partOfShape = NULL; _faceNbr =0; _nbr = 0; _pl = NULL; _p2 = NULL; } // Constructor Line::Line(int nbr. Point* pi, Point* p2) { _condition = NOTDEF; _partOfFace = new Face*[2]; for (int i = 0; i < 2; i++) _partOfFace[i] = NULL; _partOfShape = NULL; _faceNbr = 0; _nbr = nbr; _pl = pi; _pl->set_partOfLine(this); _p2 = p2; _p2->set_partOfLine(this); ) Line::Line(Point* pi, Point* p2) { _condition = NOTDEF; _partOfFace = new Face*[2]; for (int i = 0; i < 2; i++) _partOfFace[i] = NULL; _partOfShape = NULL; _faceNbr = 0; _nbr = 0; _pl = pi; _pl->set_partOfLine(this) ; _p2 = p2; _p2->set_partOfLine(this); ) // Destructor Line::~Line() { for (int i = 0; i < _faceNbr; i++) { // cout « "\n\nLine destructor called, pointer ” << i « " to the following face is removed: face_nbr" « _partOfFace[i]->get_nbr() « endl ; // pause () ; 139 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. _partOfFace[i] = NULL; } _partOfShape = NULL; _condition = DEAD; _f aceNbr = 0; _nbr = 0; _pl = NULL; //removes pointer to point _p2 = NULL; } // Copy Constructor Line::Line (Line* source) { _condition = NOTDEF; _partOfFace = new Face*[2]; for (int i = 0; i < 2; i++) _partOfFace[i] = NULL; _partOfShape = NULL; _nbr = 0; _pl = source->get_pl(); _p2 = source->get_p2(); } // Assignment Operator void Line::operator = (Line* source) { _condition = source->get_condition(); _faceNbr = source->get_faceNbr() ; for (int i = 0; i < _faceNbr; i++) _partOfFace[i] = source->get_partOfFace(i); _partOfShape = source->get_partOfShape(); _nbr = source->get_nbr() ; _pl = source->get_pl(); _p2 = source->get_p2(); } // Nonmember Function Bool Operator Main&Savitch, p. 80 bool operator == (const Lines 11,const Lines 12) { if ((11.get_pl() == 12.get_pl()) SS (ll.get_p2() == 12.get_p2())) return true; else if ((11.get_pl() == 12.get_p2()) SS (ll.get_p2() - 12.get_pl())) return true; else return false; } // Bool Function bool Line::equal (Line* source) { if ((_pl->equal(source->get_pl() ) ) SS (_p2->equal(source- >get_p2()))) return true; else if ( (_pl->equal (source->get_p2 () ) ) SS (_p2->equal (source- >get_pl()))) Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. return true; else return false; } // Bool Function bool Line::same (Line* source) { if (_nbr == source->get_nbr() ) return true; else return false; } void Line::set_partOfFace (Face* partOfFace) { if (_faceNbr >= 2) { cout « "\n\nThis line is part of more Faces than max allowable (2)\n\n"; pause(); } else { _partOfFace[_faceNbr] = partOfFace; switch (_faceNbr) { case 0: _condition = BORDER; break; case 1: _condition = INSIDE; break; default: _condition = NOTDEF; cout << "\n\nerror in Line Class\n\n"; pause(); break; ) _faceNbr++; } } void Line :: set_partOfShape (Shape* partOfShape) { _partOfShape = partOfShape; } void Line::unset_partOfFace (Face* partOfFace) { for (int i = 0; i < _faceNbr; i++) { if (_partOfFace [i] ->same (partOfFace) ) { //cout « "\n\nremoved pointer " « i « " to face: face number " • _partOfFace [i] ->get_nbr () «endl; //pause(); _partOfFace[i] = NULL; Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. for (int k = i; k < _faceNbr; k++) { _partOfFace [k] = _partOfFace[k+1]; } _f aceNbr— ; switch (_faceNbr) { case 0: _condition = NOTDEF; break; case 1: _condition = BORDER; break; default: _condition = NOTDEF; cout « "\n\nerror in Line Class\n\n"; pause(); break; } } } } void Line::set_nbr (const int nbr) { _nbr = nbr; } void Line::set_pl (Point* pi) { _pl = pi; _pl->set_partOfLine(this) ; } void Line::set_p2 (Point* p2) { _p2 = p2; _p2->set_part0fLine(this) ; } void Line::add_point (Point* o) { if (_pl == 0) /./ if _pl is empty, points to nothing { jpl = p; _pl->set_partOfLine(this); } else if (_p2 == 0) { _p2 = p; _p2->set_partOfLine(this); } void Line::unset_point (Point* p) 142 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { if (p->same(_pl)) _pl = NULL; if (p->same(_p2)) _p2 = NULL; } void Line::unset_points () { _pl = NULL; _p2 = NULL; } void Line: :delete_points () { delete _pl; delete _p2; } float Line::get_length () { float deltaX =0; float deltaY = 0; float deltaZ = 0; float distance = 0; deltaX = (float)get_pl()->get_x() - // Compute the orthogonal distances. deltaY = (float)get_pl ()->get_y() - deltaZ = (float)get_pl()->get z() ~ (float)get_p2()->get_x() ; (float)get_p2()->get_y() ; (float)get_p2()->get_z{); deltaX *= deltaX; distances. deltaY *= deltaY; deltaZ *= deltaZ; // Square the orthogonal distance = deltaX + deltaY + deltaZ; distance = (float) sqrt((float) distance); // Sum the squares. return distance; //_________________________________________________________________// // // Face // // // Default Constructor Face::Face() { _condition = NOTDEF; _nbr = 0; _partOfShape = NULL; Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 10 = new Line; // works also without, why??? 11 - new Line; 12 = new Line; 13 = new Line; 10 = NULL; 11 = NULL; 12 = NULL; 13 = NULL; // Constructor Face::Face(int nbr, Line* 10, Line* 11, Line* 12, Line* 13) { _condition = NOTDEF; _nbr = nbr; _partOfShape = NULL; _10 = new Line; _11 = new Line; _12 - new Line; _13 = new Line; _10 = 10; _11 = 11; _12 = 12; _13 = 13; _10->set_partOfFace(this); _ll->set_partOfFace(this); _12->set_partOfFace(this); _13->set_partOfFace(this); } Face::Face(Line* 10, Line* 11, Line* 12, Line* 13) { _condition = NOTDEF; _nbr = 0; _partOfShape = NULL; _10 = new Line; _11 = new Line; _12 = new Line; _13 = new Line; _10 = 10; _11 = 11; _12 = 12; _13 = 13; _10->set_partOfFace(this); _ll->set_partOfFace(this); _12->set_partOfFace(this); _13->set_partOfFace(this); } // Destructor Face::~Face() { cout « "\n\nFace destructor called, following lines removed: " << endl ; cout « _10->get_nbr() « endl; 144 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. cout << _ll->get_nbr() << endl; cout « _12->get_nbr () « endl; cout « _13->get_nbr () « endl; pause(); _condition = DEAD; _nbr = 0; _partOfShape = NULL; _10 = NULL *11 = NULL *12 = NULL "l3 = NULL //removes pointer to line // Copy Constructor Face::Face (Face* source) { _condition = NOTDEF; _nbr = 0; _partOfShape = NULL; _10 = source->get_10() ; _11 = source->get_ll() ; _12 - source->get_12() ; _13 = source->get_13() ; // Assignment Operator void Face::operator = (Face* source) { _condition = source->get_condition(); _nbr = source->get_nbr(); _partOfShape = source->get_partOfShape() ; _10 = source->get_10() ; _11 = source->get_ll() ; _12 1 source->get_12() ; _13 = source->get_13() ; // Bool Operator bool Face::equal(Face* source) { if (_10->equal(source->get_10()) && _ll->equal(source->get_ll()) _12->equal (source->get_12 () ) && _13->equal (source->get_13 () ) ) return true; else if (_10->equal(source->get_ll()) && _ll->equal(source- >get_12()) && _12->equal(source->get_13()) && _13->equal(source- >get_10())) return true; else if (_10—>equal(source->get_12()) && _ll->equal(source— >get_13()) && _12->equal(source->get_10()) && _13->equal(source- >get_ll())) return true; else if (_10->equal(source->get_13()) && _ll->equal(source- >get_10()) && _12->equal(source->get_ll()) && _13->equal(source- >get 12 0)) 145 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. return true; else return false; } // Bool Operator bool Face::same(Face* source) { if (_nbr == source->get_nbr () ) return true; else return false; } // Nonmember Function Bool Operator bool operator == (const Faces fl, const Faces f2) { if (fl.get_10() == f2.get_10() SS fl.get_ll() == f2.get_ll() SS f1.get_12() == f2.get_12() s s f1.get_13 () == f2.get_13()) return true; else if (f1.get_10() == f2.get_ll() SS fl.get_ll() == f2.get_12() SS f1.get_12() == f2.get_13() SS fl.get_13() == f2.get_10()) return true; else if (fl.get_10() == f2.get_12() SS fl.get_ll() == f2.get 13 () SS fl.get_12() == f2.get_10() SS fl.get_13() - f2.get_ll()) return true; else if (fl.get_10() == f2.get_13() SS fl.get_ll() == f2.get 10 () SS fl.get_12() == f2.get_ll() SS fl.get_13() == f2.get_12()) return true; else return false; } // Modification Member Functions void Face::set_nbr (const int nbr) { _nbr = nbr; } void Face::set_10 (Line* 10) { _10 = 10; _10->set_partOfFace(this) ; } void Face::set_ll (Line* 11) { _11 = 11; _ll->set_partOfFace(this) ; } void Face::set_12 (Line* 12) { _12 = 12; _12->set_partOfFace(this) ; 146 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. void Face::set_13 (Line* 13) { _13 = 13; _13->set_part0fFace(this) ; } void Face::add_line (Line* 1) { if ( 10 == 0) _10 = 1; 10->set_partOfFace(this) ; else if (_H == 0) _11 = 1; _ll->set_partOfFace(this) ; else if (_12 == 0) 12 = 1; 12->set_partOfFace(this) ; else if (_13 == 0) _13 = 1; _13->set_partOfFace(this) ; } void Face::unset_line (Line* 1) { if (1->same( 10)) _10 - NULL ; else if (l->same(_11) ) _11 = NULL; else if (l->same(_12) ) _ 1 2 - NULL ; else if (l->same(_13) ) 13 = NULL; } void Face::set_partOfShape (Shape* partOfShape) { _partOfShape = partOfShape; } // Constant Member Functions Cond Face::get_condition () { int count = 0; int add; 147 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. add = _10—>get_condition() ; count = count + add; add = _ll->get_condition(); count = count + add; add = _12->get_condition() ; count = count + add; add = _13->get_condition(); count = count + add; if (count = 16) _condition = INSIDE; else if (count == 15) _condition = BORDER; else if (count == 14) _condition = CORNER; else { cout « "\nerror in Line Class\t"; pause(); } return _condition; } //_________________________________________ // // Shape // // Default Constructor Shape::Shape() { _faceCount =0; _geoPointCount =0; _geoLineCount = 0; _face = new Face*[FACEMAX]; for (int i = 0; i < FACEMAX; i++) _face[i] = NULL; _geoPoint = new GeoPoint*[GEOPOINTMAX]; for (int j =0; j < GEOPOINTMAX; j++) _geoPoint[j] = NULL; _geoLine = new Line*[GEOLINEMAX] ; for (int k = 0; k < GEOLINEMAX; k++) _geoLine[k] = NULL; } // Destructor Shape::~Shape() { cout « "\n\nShape destructor called" « endl; pause(); Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. for (int i = 0; i < _faceCount; i++) _face[i]->set_partOfShape(NULL) ; for (int j = 0; j < _geoPointCount; j++) _geoPoint[j]->set_partOfShape(NULL) ; for (int k = 0; k < _geoLineCount; k++) _geoLine[k]->set_partOfSnape(NULL) ; delete [] _face; delete [] _geoPoint; delete [] _geoLine; _faceCount = 0; _geoPointCount = 0; _geoLineCount = 0; } // Copy Constructor Shape::Shape (Shape* source) { _faceCount = source->get_faceCcunt() ; for (int i = 0; i < _faceCount; i++) { _face[i] = source->get_face(i) ; } } void Shape::add_face (Face* face) { _f ace[_faceCount] = face; _f aceCount++ ; if (_faceCount >= FACEMAX) { cout << "\n\nERROR! FA.CEMAX constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; exit (1); } face->set_partOfShape(this) ; } void Shape::add_geoPoint (GeoPoint* point) { _geoPoint[_geoPointCount] = point; _geoPointCount++; if (_geoPointCount >= GEOPOINTMAX) { cout << "\n\nERROR! GEOPOINTMAX constant is too small. See PlanLine.h\n\nThe program will terminate"; pause(); cerr; 149 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. exit (1); } point->set_pa xtOfShape (this) ; } void Shape:: add_geoLine (Line* line) { _geoLine [_geoILineCount] = line; _geoLineCount -++; if (_geoLineCount >= GEOLINEMAX) { cout << "\n\nERROR! GEOLINEMAX constant is too small. See PlanLine.h\n\nfhe program will terminate"; pause(); cerr; exit (1); } line->set_par-tOfShape (this) ; } void Shape: :unset-_face (Face* face) { for (int i = C; i < _faceCount; i++) { if (face->same (_face [i] ) ) { _face [i] ->set_partOfShape (NULL) ; for (int j = i; j < _faceCount; j++) { _face[j] = _face[j+l]; ) _f aceCount ; } } } //________________________________________________________________// // // GeoPoint //________________________________________________________________// // Default Constructor GeoPoint: : GeoPoint () { _nbr = 0; _condition = ESTOTDEF; _pointIn = netw Point3D; _pointOut = new Point3D; _xAxisIn = netw Direction3D; _partOfLineIn = new Line; _partOfLineOut = new Line; 150 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. partOfFace = new Face; partOfShape = NULL; pi = new Point3D; p2 = new Point3D; p3 = new Point3D; p4 = new Point3D; // Constructor GeoPoint::GeoPoint(Point3D* point, Line* line, Face* face. Shape* shape) { _nbr = 0; _condition = NOTDEF; _pointIn = new Point3D; _pointOut = new Point3D; _xAxis!n = new Direction3D; _partOfLineIn = new Line; _partOfLineOut = new Line; _partOfFace = new Face; _partOfShape = new Shape; _pl = new Point3D; _p2 = new Point3D; _p3 = new Point3D; _p4 = new Point3D; _pointIn = point; _partOfLineIn = line; _partOfFace = face; _partOfShape = shape; } // Destructor GeoPoint::-GeoPoint() { _nbr = 0; _condition = NOTDEF; delete _pointIn; //???? delete _pointOut; //???? delete _xAxisIn; delete _partOfLineIn; delete _partOfLineOut; delete _partOfFace; delete _partOfShape; delete _pl; delete _p2; delete _p3; delete _p4; delete _el2; delete _e23; delete _e34; delete _e41; } // Copy Constructor GeoPoint::GeoPoint (GeoPoint* source, int nbr) Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { _nbr = nbr; _condition = NOTDEF; _pointIn = source->get_pointIn() ; _pointOut = source->get_pointOut(); _xAxisIn = new Direction3D; _partOfLineIn = new Line; _partOfLineOut = new Line; _partOfFace = new Face; _partOfShape = NULL; } // Assignment Operator void GeoPoint::operator = (const GeoPointS source) { _nbr = NULL; _condition = NOTDEF; _pointIn = source.get_pointIn() ; _pointOut = source.get_pointOut(); _xAxisIn = source.get_xAxisIn(); _partOfLineIn = source. get_partOfLineIn () ; _partOfLineOut = source.get_partOfLineOut(); _partOfFace = source.get_partOfFace(); _partOfShape = source.get_partOfShape () ; } void GeoPoint::set_nbr (const int nbr) { _nbr - nbr; } void GeoPoint::set_pointIn (Point3D* point) { _pointIn = point; } void GeoPoint::set_directionX (Direction3D* xAxisIn) { float x, y, z; Point* point1 = new Point; Point* point2 = new Point; Point3D* pm; Point3D* crossP23 = new Point3D; Point3D* crossP34 = new Point3D; Point3D* crossP41 = new Point3D; Direction3D* dl2; Direction3D* d23; Direction3D* d34; Direction3D* d41; Direction3D* dOm; DirectedPoint3D* d23p2; DirectedPoint3D* d34p3; DirectedPoint3D* d41p4; DirectedPoint3D* dOmpO; DirectedPoint3D* vertPlane = new DirectedPoint3D; 152 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. LocalAxis* locAx; pointl = _partOfLineIn->get_pl(); point2 = _partOfLineIn->get_p2(); _pl = Point3D_Point((_partOfLineIn—>get_pl () )) _p2 = Point3D_Point((_part0fLine!n->get_p2())) // setting up a "square" with pi to p4 in a consecutive order: if (pointl->same(_partOfFace->get_10()->get_pl()) && ' (point2- >same (_partOf Face->get_10 () ->get_p2 () ) ) ) _p4 = Point3D_Point((_partOfFace->get_10()->get_p2())); else if (pointl->same(_partOfFace->get_10()->get_p2()) && I (point2- >same (_partOf Face->get_10 (} ->get_pl () ) ) ) _p4 = Point3D_Point((_partOfFace->get_10()->get_pl())); else if (pointl->same(_partOfFace->get_ll()->get_pl()) && ! (point2- >same (_partOf Face->get_ll () ->get_p2 () ) } ) _p4 = Point3D_Point((_partOfFace->get_ll()->get_p2())); else if (pointl->same(_partOfFace->get_ll()->get_p2()) && i(point2- >same (_partOf Face->get_ll () ->get_pl () ) ) ) _p4 = Point3D_Point((_partOfFace->get_ll()->get_pl())); else if (pointl->same(_partOfFace->get_12()->get_pl()) && ' (point2- >same (_partOf Face->get_12 () ->get_p2 () ) ) ) _p4 = Point3D_Point((_partOfFace->get_12()->get_p2())); else if (pointl->same (_partOf Face->get_12 () ->get_p2 () ) && ' (point2- >same (_partOf Face->get_12 () ->get_pl () ) ) ) _p4 = Point3D_Point((_partOfFace->get_12()->get_pl())); else if (pointl->same (_partOf Face->get_13 ()->get_pl () ) && ' (point2- >same (_partOf Face->get_13 () ->get_p2 () ) ) ) _p4 = Point3D_Point((_partOfFace->get_13()->get_p2())); else if (pointl->same (_partOfFace->get_13()->get_p2()) && ' (point2- >same (_partOf Face->get_13 () ->get_pl () ) ) ) _p4 = Point3D_Point((_partOfFace->get_13()->get_pl())); else { cout << pause(), "errorOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"; if (point2->same(_partOfFace->get_ >same (_partOf Face->get_10 () ->get_p2 _p3 = Point3D_Point ( (_partOf Face else if (point2->same(_partOfFace- >sarae (_partOf Face->get_10 () ->get_pl _p3 = Point3D_Point((_partOfFace else if (point2->same(_partOfFace- >same (_partOf Face->get_ll () ->get_p2 _p3 = Point3D_Point((_partOfFace else if (point2->same(_partOfFace- >same (_partOf Face->get_ll () ->get_pl _p3 = Point3D_Point((_partOfFace else if (point2->same(_partOfFace- >same (_partOf Face->get_12 () ->get_p2 _p3 = Point3D_Point((_partOfFace else if (point2—>same(_partOfFace- >same (_partOf Face->get_12 () ->get_pl 10() () > ) ) ->get ->get_ () ) ) ) ->get >get_ () ) ) ) ->get ■>get_ () ) ) ) ->get >get_ () ) ) ) ->get >get_ () ) ) ) ->get_pl() ) && I (pointl- _10() 10 () - _10 () 110- JL1() 11 () - _11() 12 () - _12 () 12 0 - ->get_p2())); ->get_p2()) && I (pointl- >get_pl())); ->get_pl()) && 1 (pointl- ->get_p2())); ->get_p2()) && ! (pointl- ->get_pl())); ->get_pl()) && I (pointl- ->get_p2())); ->get_p2()) && ! (pointl- 153 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. _p3 = Point3D_Point ( (_partOfFace->get_12()->get_pl() ) ) ; else if (point2->same (_partOfFace->get_13 () ->get_pl () ) && I (pointl >same (_partOf Face->get_13 () ->get_p2 () ) ) ) _p3 = Point3D_Point ( (_partOfFace->get_13 () ->get_p2 () ) ) ; else if (point2->same (_part0fFace->get_13 () ->get_p2 () ) && ! (pointl >same (_partOf Face->get_13 () ->get_pl () ) ) ) _p3 = Point3D_Point ( (_partOf Face->get_13 () ->get_pl () ) ) ; else { cout « "errorlll11II11111111111111111111111"; pause(); } _el2 = new Edge3D(*_pl, *_p2) ; _e23 = new Edge3D(*_p2, *_p3) ; _e34 - new Edge3D(*_p3, *_p4); _e41 = new Edge3D(*_p4, *_pl) ; // computing the mid-point between p3 and p4: x = _p3->getX() + (( _p4->getX() - _p3->getX() ) / 2 ); y = _p3->getY() + (( _p4->getY() - _p3->getY() ) / 2 ); z = _p3->getZ() + (( _p4->getZ() - _p3->getZ() ) / 2 ); pm = new Point3D(x, y, z); dl2 = new Direction3D(_pl, _p2) ; d23 = new Direction3D(_p2, _p3) ; d34 = new Direction3D(_p3, _p4); d41 = new Direction3D (_p4, _pl) ; dOm = new Direction3D(_pointIn, pm); d23p2 = new DirectedPoint3D(*d23, *_p2); d34p3 = new DirectedPoint3D(*d34, *_p3); d41p4 = new DirectedPoint3D(*d41, *_p4); dOmpO = new DirectedPoint3D(*dOm, *_pointIn); locAx = new LocalAxis (_pointIn, dl2, dOm, xAxisIn) ; _xAxisIn = locAx->get_xAxis() ; vertPlane = locAx->get_zxPlane() ; crossP23 = LinePlanelntersection(*d23p2, *vertPlane) ; crossP34 = LinePlanelntersection(*d34p3, *vertPlane); crossP41 = LinePlanelntersection(*d4lp4, *vertPlane); if (crossP23->between(*_p2, *_p3)) { _pointOut = crossP23; if ((Line_Edge3D(_e23))->equal(_partOfFace->get_10() ) ) _partOfLineOut = _partOf Face->get_10 () ; else if ( (Line_Edge3D (_e23) ) ->egual (_partOfFace->get_ll () ) ) _partOf LineOut = _partOf Face->get_ll () ; else if ( (Line_Edge3D (_e23) )->equal (_partOf Face->get_12 () ) ) _partOf LineOut = _partOf Face->get_12 () ; else if ( (Line_Edge3D (_e23) )->equal (_partOf Face->get_13 () ) ) _partOfLineOut = _part0fFace->get_13 () ; 154 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { cout « "error2222222222222222222222222222222222222222"; } } else if (crossP34->between(*_p3, *_p4)) { _pointOut = crossP34; if (Line_Edge3D(_e34)->equal(_partOfFace->get_10())) _partOfLineOut = _partOfFace->get_10(); else if (Line_Edge3D(_e34)->equal(_partOfFace->get_ll())) _partOfLineOut = _partOfFace->get_ll(); else if (Line_Edge3D(_e34)->equal(_partOfFace->get_12())) _partOfLineOut = _partOfFace->get_12(); else if (Line_Edge3D(_e34)->equal(_partOfFace->get_13())) _partOfLineOut = _partOfFace->get_13() ; else { cout « "error3333333333333333333333333333333333333333333" pause(); } } else if (crossP41->between(*_p4, *_pl)) { _pointOut = crossP41; if (Line_Edge3D(_e41)->equal(_partOfFace->get_10())) _partOfLineOut = _partOfFace->get_10() ; else if (Line_Edge3D(_e41)->equal (_partOfFace->get_ll())) _partOfLineOut = _partOfFace->get_ll() ; else if (Line_Edge3D(_e41)->equal(_partOfFace->get_12())) _partOfLineOut = _partOfFace->get_12() ; else if (Line_Edge3D(_e41)->equal(_partOfFace->get_13{))) _partOfLineOut = _partOfFace->get_13() ; else { cout << "error44444444444444444444444444444444444444"; pause(); } } else { cout << "error2 3 4 * pause(); } } void GeoPoint::set_partOfLineln (Line* partOfLineln) { _partOfLineIn = partOfLineln; } Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. void GeoPoint::set_partOfFace (Face* partOfFace) { _partOfFace = partOfFace; void GeoPoint::set_partOfShape (Shape* partOfShape) { _partOfShape = partOfShape; float GeoPoint::get_length () { float deltaX = 0; float deltaY = 0; float deltaZ = 0; float distance =0; deltaX = _pointOut->getX() orthogonal distances. deltaY = _pointOut->getY() orthogonal distances. deltaZ = _pointOut->getZ() orthogonal distances. deltaX *= deltaX; distances. deltaY *= deltaY; deltaZ *= deltaZ; distance = deltaX + deltaY + deltaZ; // Sum the squares, distance = (float) sqrt((float) distance); return distance; } // ; ; // // // Local Axis // // // Default Constructor LocalAxis::LocalAxis() { _xAxis = new Direction3D; _yAxis = new Direction3D; _zAxis = new Direction3D; _origin = new Point3D; ) // Constructor LocalAxis::LocalAxis(Point3D* origin, Direction3D* planePl, Direction3D* planeP2, Direction3D* angle) { xAxis = new Direction3D; - _pointIn->getX(); // Compute the - _pointIn->getY(); // Compute the - _pointIn->getZ(); // Compute the // Square the orthogonal Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. _vAxis = new Direction3D; _zAxis = new Direction3D; _origin = new Point3D; _zAxis = planePl->crossProduct(*planeP2); _yAxis = _zAxis->crossProduct(*angle); _xAxis = _yAxis->crossProduct(*_zAxis); _origin = origin; } // Destructor LocalAxis::-LocalAxis() { delete _xAxis; delete _yAxis; delete _zAxis; delete _origin; } // Copy Constructor LocalAxis::LocalAxis (LocalAxis* source) { _xAxis = source->get_xAxis(); _yAxis = source—>get_yAxis(); _zAxis = source->get_zAxis(); _origin = source->get_origin(); } // Assignment Operator void LocalAxis::operator = (LocalAxis* source) { _xAxis = source->get_xAxis(); _yAxis = source->get_yAxis(); _zAxis = source->get_zAxis(); _origin = source->get_origin(); } void LocalAxis::set_axis (Direction3D* planePl, Direction3D* planeP2 Direction3D* angle) { _xAxis = new Direction3D; _yAxis = new Direction3D; _zAxis = new Direction3D; _zAxis = planePl->crossProduct(*planeP2); _yAxis = _zAxis->crossProduct(*angle) ; _xAxis = _yAxis->crossProduct(*_zAxis); void LocalAxis::set_origin (Point3D* origin) { _origin = new Point3D; _origin = origin; } Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. DirectedPoint3D* LocalAxis::get_yzPlane() const { DirectedPoint3D* plane = new DirectedPoint3D; plane->setDirection(*(this)->get_xAxis()); plane->setPoint(*(this)->get_origin()); return plane; } DirectedPoint3D* LocalAxis::get_zxPlane() const { DirectedPoint3D* plane = new DirectedPoint3D; plane->setDirection(*(this)->get_yAxis()); plane->setPoint(*(this)—>get_origin()); return plane; } DirectedPoint3D* LocalAxis::get_xyPlane() const { DirectedPoint3D* plane = new DirectedPoint3D; plane->setDirection(*(this)->get_zAxis()); plane->setPoint(*(this)->get_origin()); return plane; } //_____________________________________________________________ // // // General Helper Functions // // void pause() { char c; cout « "\nPress 'enter' to continue" cin.get(c); } Type checkCode (int code) { if ((code >=0) && (code <= 4) I[ maximum; less for Unicode strings) (code >= 6) && (code <= 9) II maximum; less for Unicode strings) (code >= 1000)&&(code <= 1009)| maximum; less for Unicode strings) (code == 100) ||(code == 102) | // String (255 characters // String (255 characters // String (255 characters // String (255 characters Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. maximum; less for (code == 999) I (code >= 300)&& return CHAR; else if ((code >=60) & (code >=90) && (code >= 170)&& (code >= 280)&& (code >= 1060)& (code == 1071)) return INT; else if ((code >= 310)& hexadecimal (hex) (code >= value (code >= IDs (code == (code == Unicode strings) I (code <= 309)) & (code <= 79) || (code <= 99) || (code <= 175) II (code <= 28 9) || & (code <= 1070) I // Comment (string) // Arbitrary text string // 16-bit integer value // 32-bit integer value // 16-bit integer value // 8-bit integer value // 16-bit integer value // 32-bit integer value &(code <= 319) || // String representing value of binary chunk (code <= 329) || // String representing hex handle 320)&& 330)&&(code <= 369) // String representing hex object 105) 5) ) I // String representing hexadecimal handle value // String representing hexadecimal handle value return HEX; else if ((code >=10) & (code >= 140) & (code == 210) I return DOUBLE; else if ((code >= 1010) return FLOAT; else return ERR; & (code <= 5 9) & (code <= 14 7) // double precision 3D point I// double precision scalar // floating-point value (code == 220) || (code == 230)) // x, y, z // values of the extrusion direction && (code <= 1059)) // Floating-point value Point3D* Point3D_Point(Point* p) { Point3D* point = new Point3D; point->setX((float)p->get_x() ) point->setY((float)p->get_y() ) point->setZ((float)p->get_z() ) return point; } Point* Point_Point3D(Point3D* p) { Point* point = new Point; point->set_x(p->getX()); point->set_y(p->getY()); point->set_z(p->getZ()); return point; > 159 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. Direction3D* Direction3D_Point3D(Point3D* p) { Direction3D* direction = new Direction3D; direction->setXYZ(p->getX(),p->getY(),p->getZ()); return direction; } Point3D* Point3D_Direction3D(Direction3D* d) { Point3D* point = new Point3D; point->setX(d->getX()); point->setY(d->getY()); point->setZ(d->getZ()); return point; } Line* Line_Edge3D(Edge3D* e) { Line* line = new Line; line->set_pl(Point_Point3D(e->getPl())); line->set_p2(Point_Point3D(e->getP2())); return line; } Edge3D* Edge3D_Line(Line* 1) { Edge3D* edge = new Edge3D; edge->setPl(*Point3D_Point(l->get_pl())); edge->setP2(*Point3D_Point (l->get_p2())); return edae; } Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 12.2.4. Geometry3D.h // Geometry3D. h // Header file for the 3D geometry classes. // Copyright 1999 by the University of Southern California and // Rick Wagner, // all rights reserved. // // Code use permission granted for educational purposes at USC only. // No use without attribution. // // Version 1.12. // Created September 10, 1999, last edited October 3, 1999. // Used and modified with permission by Judith Leuppi, // last edited July 4, 2000 // #ifndef POINT3D_H tdefine P0INT3D_H #include <math.h> // Global constants: const float gsfPi = (float) (atan(l.O) * 4.0); const float gsfEpsilon = (float) 0.0000000001; nine balls one. class Point; class Point3D; // Classes are listed below in referenced order. + // Direction3D: a class to model a unit direction vector in 3D: class Direction3D { public: Direction3D(float x, float y, float z) ; // default Constructor for 3 entries. Direction3D(float a, float b) ; Direction3D(Point* pi, Point* p2, float azimuth); // constructor for a direction given by two Points, and an angle, which is the direction in a z-projection Direction3D(Point3D* pi, Point3D* p2); // constructor for a direction given by two Point3D Direction3D(} ; Direction3D (const Direction3D& d) ; // Copy constructor. float getX() const; float getY() const; // Accessors. 161 // Compute pi. // Tiny number, Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. float getZ() const; float getAzimuth() const; float getElevation() const; void setXYZ(float x, float y, float z); // Mutator, void setAzimElev (float a, float b) ; // Mutator, (sets Azimuth and Elevation) void setPoints(Point* pi. Point* p2, float azimuth); // sets a direction given by two Points, and an angle, in a z-projection which is the direction void setPoints3D(Point3D* pi, Point3D* p2); direction given by two Point3D // sets a float dotProduct(const Direction3D& d); dot product of two directions. // Return the float angleBetween(const Direction3D& d); angle between two directions. // Return the Direction3D* crossProduct(const Direction3D& d); cross product of two directions. private: // Return the float x; of the vector. // X component float _y; of the vector. // Y component float z; // Z component of the vector. }; // End of Direction3D class declaration. // Non-member functions for the Direction3D class: bool operator ==(const Direction3D& dl, const Direction3D& d2) ; // Point3D: a class to model a point in three dimensional Cartesian space: class Point3D { public: Point3D(float x = 0, float y = 0, float z = 0); Constructor. Point3D(const Point3D& p) ; constructor. // // Copy ~Point3D() ; float getX() const; float getY() const; float getZ() const; // Destructor. // Accessors. void setX(float x); // Mutators. 162 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. void setY (float y); void setZ(float z) ; void setXYZ (float x, float y, float z) ; void operator = (const Point3D& source); // Overloaded assignment operator. float distance(const Point3D& p); // Return the distance to another point. bool between(const Point3D& pi, const Point3D& p2) ; // Returns true if the point is in between pi and p2 bool equals(const Point3D& p); // Test for equality with another point. private: float _x; // X coordinate of the point, float _y; // Y coordinate of the point, float _z; // Z coordinate of the point. }; // End of Point3D class declaration. // Nonmember functions for the Point3D class: // Return the distance between two points: float distance(const Point3D& pi, const Point3D& p2) ; /'/ Operator overloading: bool operator ==(const Point3D& pi, const Point3D& p2); • i e // Edge3D: a class to model an edge (line segment) in three dimensional Cartesian space: class Edge3D { public: Edge3D(); // Default constructor. Edge3D(const Point3D& pi, const Point3D& p2);//Two point constructor. Edge3D(const Edge3D& e); // Copy constructor, void operator =(const Edge3D& source);//Overloaded assignment operator. ~Edcre3D(); //Destructor. Point3D* getPl() const; Point3D* getP2() const; //Accessors. void setPl(const Point3D& p); void setP2(const Point3D& p); // Mutators, 163 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. bool equals(const Edge3D& e);//Test for: equality with another edge. private: Point3D *_pl; // Point one of the edge. Point3D *_p2; f / Point two of the edge. }; // End of Edge3D class declaration. // DirectedPoint3D: a class to model a point with direction in three dimensional Cartesian space. // Can be used to model a plane, a line, or a unit wrench, class DirectedPoint3D { public: DirectedPoint3D(); // Default constructor. DirectedPoint3D(const Direction3D& d, const Point3D& p); // General constructor. DirectedPoint3D(const DirectedPoint3D& dp); // Copy constructor, void operator =(const DirectedPoint3D& dp); // Overloaded assignment operator. // Destructor. // // ~DirectedPoint3D(); // Accessors: Direction3D* getDirection() const; Returns a pointer to a copy of the direction. Point3D* getPoint() const; Returns a pointer to a copy of the point. // Mutators: void setDirection(const Direction3D& d) ; void setPoint(const Point3D& p) ; private: Direction3D *_d; Point3D *_p; }; // End of DirectedPoint3D class declaration. // Non-member functions for the DirectedPoint3D class: // Return the intersection point with a plane: Point3D* LinePlanelntersection(DirectedPo int3D line, DirectedPoint3D plane); // Return the line of intersection of two planes: DirectedPoint3D* GetPlaneIntersection(DirectedPoint3D planel, DirectedPoint3D plane2); 164 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. J J i e ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ // General helper functions: float arcCos(float CosineTheta); // Return the arc cosine (theta) of // the cosine of theta. // Global functions to convert rad to degrees and degrees to rad float rad(float degree); float degree(float rad); tendif 165 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. 12.2.5. Geometry3D-cpp // Geometry3D.cpp // Implementation file for the 3D geometry classes. // Copyright 1999 by Rick Wagner, all rights reserved. // // Version 1.12. // Created September 10, 1999, last edited October 3, 1999. // Used and modified with permission by Judith Leuppi, // last edited July 4, 2000 // tfinclude <math.h> "include <string.h> #include ciostream.h> ^include "Geometry3D.h" #include "PlankLine.h" // Classes are given below in alphabetic order. // Member functions for the DirectedPoint3D class: // Default constructor: DirectedPoint3D::DirectedPoint3D() { _d = new Direction3D(); _p = new Point3D; } // General constructor: DirectedPoint3D::DirectedPoint3D(const Direction3D& d, const Point3D& P) { _d = new Direction3D(d); _p = new Point3D(p); } // Copy constructor: DirectedPoint3D::DirectedPoint3D(const DirectedPoint3D& dp) r \ _d = new Direction3D(*(dp._d)); _p = new Point3D(*(dp._p)); > // Overloaded assignment operator: void DirectedPoint3D::operator =(const DirectedPoint3D& dp) { Direction3D *d = new Direction3D(*(dp._d) ) ; Point3D *p = new Point3D(*(dp._p)) ; delete _d; ., Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. delete _p; _d = d; _P = p; // Destructor: DirectedPoint3D::~DirectedPoint3D() { delete _d; delete _p; // Accessors: Direction3D* DirectedPoint3D::getDirection() const { return new Direction3D(*_d); } Point3D* DirectedPoint3D::getPoint() const { return new Point3D(*_p); } // Mutators: void DirectedPoint3D::setDirection(const Direction3D& d) { delete _d; _d = new Direction3D(d); } void DirectedPoint3D::setPoint(const Point3D& p) { delete _p; _p = new Point3D(p); } // Non-member functions for the DirectedPoint3D class: Point3D* LinePlanelntersection (DirectedPoint3D line, DirectedPoint3D plane) { // Returns the point of intersection with the plane. // Assumes the line and plane are not parallel. Point3D *p; float t = 0; float sfNumerator = 0; float sfDenominator = 0; // Return point pointer. // Parameter t of p along the input line. float xO = line.getPoint()->getX(); float yO = line.getPoint()->getY(); float zO = line.getPoint()->getZ() ; float dx = line.getDirection()->getX() float dy = line.getDirection()->getY() 167 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. float dz = line.getDirection()->getZ(); float Qx = plane.getPoint()->getX(); float Qy = plane.getPoint()->getY(); float Qz - plane.getPoint()->getZ(); float Vx - plane.getDirection()->getX(); float Vy = plane.getDirection()->getY(); float Vz plane.getDirection()->getZ() ; // Solve the plane and line equations for parameter t: sfNumerator = Vx * (Qx - xO) + Vy * (Qy - yO) + Vz * (Qz - zO) ; sfDenominator = Vx * dx + Vy * dy + Vz * dz; if (sfDenominator == 0) { cout « "Error in LinePlanelntersection: Attempted division by zero." << endl; t = 1 / gsfEpsilon; // Ten billion is close enough to infinity. } else { t = sfNumerator / sfDenominator; } // cout « "LinePlanelntersection () sfNumerator = " << sfNumerator << endl; // cout « "LinePlanelntersection() sfDenominator = " « sfDenominator << endl; // cout << "LinePlanelntersection() t = " « t << endl; //xO *= t //yO *= t //zO *= t xO += dx * t; yO += dy * t; zO += dz * t; p = new Point3D(xO, yO, zO); return p; } DirectedPoint3D* GetPlanelntersection(DirectedPoint3D planel, DirectedPointSD plane2) { // Finds the line of intersection of two planes; assumes planes are not parallel. // Input planes are represented as applied vectors; so is the returned line. DirectedPoint3D *Line; pointer. float dx, dy, dz, xO, yO, zO; variables for compiler // Pull out the components of planel: 168 // Return line // Pre-define line Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. float xl float yl float zl float A1 float B1 float Cl planel. planel. planel. planel. planel. planel. getPoint()—>getX(); getPoint()—>getY(); getPoint()—>getZ(); getDirection()->getX() getDirection()—>getY() getDirection()->getZ() // Pull out the components of plane2: float x2 float y2 float z2 float A2 float B2 float C2 float D1 - float D2 = plane2.getPoint() —>getX(); plane2.getPoint()—>getY(); plane2.getPoint()->getZ (); plane2.getDirection()->getX() plane2.getDirection()->getY() plane2.getDirection()->getZ () -fAl - (A2 xl + B1 x2 + B2 yl + Cl y2 + C2 zl) ; z2) ; if { ( (B2 A1 B1 A2) 1 = 0 ) // The line is not parallel to the X-Y plane dx = (Bl * C2 - B2 * Cl) / (B2 * Al - Bl * A2) xO = (Bl * D2 - B2 * Dl) / (B2 * Al - Bl * A2) dy = (Al * C2 - A2 * Cl) / (A2 * Bl - A1 * B2) yO = (A1 * D2 - A2 * Dl) / (A2 * Bl - A1 * B2) dz = 1; zO = 0; ) else { // Line of intersection is parallel to X-Y plane, if ((C2 * A1 - Cl * A2) 1= 0) { parallel to the X-Z plane // The line is dx = xO = dy = yO = dz = zO = (Cl (Cl 1; 0; (Al (A1 B2 D2 B2 D2 not C2 C2 A2 A2 Bl) Dl) Bl) Dl) / / (C2 (C2 (A2 (A2 A1 A1 - Cl - Cl A2) ; A2) ; Cl - A1 Cl - A1 C2) ; C2) ; } else ( // The line is not parallel to the Y-Z plane dx = 1; xO if { } = 0; ( (C2 Bl - Cl B2) 0) dy = (Cl i l r A2 - C2 ■ k Al) / (C2 k Bl - Cl * B2) ; yO = (Cl • k D2 - C2 k Dl) / (C2 k Bl - Cl * B2) ; dz = (Bl ■ k A2 - B2 k Al) / (B2 k Cl - Bl * C2) ; zO = (Bl k D2 - B2 k Dl) / (B2 k Cl - Bl * C2) ; else { 169 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. cout << "Error in GetPlanelntersection: trying to divide by zero." << endl; } } } // Construct the return value: Point3D TempPoint(xO, yO, zO) ; Direction3D TempDirection (dx, dy, dz) ; Line = new DirectedPoint3D (TempDirection, TempPoint); return Line; } / f * * -k * * * * * * * * * * * * * * * * * * // Member functions for the Directxon3D class: // Constructor: Direction3D:: Direction3D (float x, float y, float z) // Precondition: 3 input parametres must be given. // Postcondition: vector components are normalized and initialized. { float length = 0; length = x * x + y*y+z* z; if (length == 0) ( x = 1; > else { length = (float) x /= length; y /= length; z /= length; } _x = x ; _y = y; z = z; Direction3D::Direction3D(Point* pi, Point* p2, float azimuth) // Precondition: 2 points (class Point) must be given. // Postcondition: vector components between the two points are normalized and initialized. ( float length = 0; float 1=0; float init_azi =0, final_azi = 0; float elevation = 0; float x = 0, y = 0, z = 0; x = (float)p2->get_x() - (float)pl->get_x(); 170 // Let it be a default direction vector sqrt((double) length); Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. y z (float)p2->get_y() - (float)pl->get_y(); (float)p2->get_z() - (float)pl->get_z (); length = x * x + y * y + z * z ; if (length == 0) x = 1; else 1; // Let it be a default direction vector { length = (float) sqrt((double) length); x /= length; y /= length; z /= length; if (azimuth == 0) // simplifing to avoid rounding errors { _x = x; _y = y; z = z; { 1 = (float) (sqrt(x*x+y*y)); init_azi = (float) atan2 (y,x); elevation = (float) atan2 (z,l); final_azi = init_azi + azimuth; _x = (float) cos (elevation) * (float) cos (final_azi) ; _y = (float) cos (elevation) * (float) sin (final_azi); z = (float) sin (elevation); Direction3D::Direction3D(Point3D* pi, Point3D* p2) // Precondition: 2 points (class Point) must be given. // Postcondition: vector components between the two points are normalized and initialized. { float length = 0; float x = 0, y=0, z = 0; x = p2->getX() - pl->getX(); y = p2->getY() - pl->getY{); z = p2->getZ() - pl->getZ(); length = x * x + y * y + z * z ; if (length == 0) x = 1; // Let it be a default direction vector else else length = (float) sqrt((double) length); x /= length; 171 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. y /= length; z /= length; } _x = x; _y = y; _z = z; } Direction3D::Direction3D(float a, float b) // Precondition: 2 input parameters must be given and be in Radian. // Postcondition: vector components are normalized and initialized. { float length = 0; float x = 0.0; float y = 0.0; float z = 0.0; x = (float) cos (b) * (float) cos (a); y = (float) cos (b) * (float) sin (a); z = (float) sin (b) ; length = x * x + y * y + z * z ; if (length — 0) { x — 1; } else { length = (float) x /= length; y /= length; z /= length; } _x = x; _y = y; z = z; } Direction3D::Direction3D() // Postcondition: default vector, length 1, direction x. { x = 1; _y - 0; z = 0; // Copy constructor Direction3D::Direction3D(const Direction3D& p) // Postcondition: vector components are initialized to p._x, p._y, and p._z. 172 // Let it be a default direction vector sqrt((double) length); Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { _x = p . x ; _y = p-_y; _z = p. z; } // Accessors: float: Direction3D: :getX () const // Postcondition: vector x component is returned. r I return _x; } float Direction3D::getY{) const // Postcondition: vector y component is returned. { return _y; } float Direction3D::getZ() const // Postcondition: vector z component is returned. { return _z; } float Direction3D::getAzimuth() const // Postcondition: Azimuth is returned. { float 1 = 0; float azimuth = 0; azimuth = (float) atan2 (_y^_x); return azimuth; } float Direction3D::getElevation() const // Postcondition: Elevation is returned. { float 1=0; float elevation = 0; 1 = (float) (sqrt (_x*_x+_y*_y) ) ; elevation = (float) atan2 (_z,1); return elevation; > // Mutator: void Direction3D::setXYZ(float x, float y, float z) // Postcondition: vector components are changed to normalized input values. { float length = 0; float 1=0; 173 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. length = x * x + y * y + z * z; if (length — 0) { x = 1; // Let it be a default direction vector } else { length = (float) sqrt((double) length); x /= length; y /= length; z /= length; } _x = x ; _y = y; z = z; } void Direction3D::setPoints(Point* pi, Point* p2, float azimuth) // Postcondition: vector components are changed to normalized input values. { float length =0; float 1=0; float init_azi = 0, final_azi = 0; float elevation =0; float x = 0, y=0, z = 0; x = (float)p2->get_x() - (float)pl->get_x() y = (float)p2->get_y() - (float)pl->get_y() z = (float)p2->get_z() - (float)pl->get_z() length = x * x + y * y + z * z ; if (length == 0) x = 1; // Let it be a default direction vector else { length = (float) sqrt((double) length); x /= length; y /= length; z /= length; } if (azimuth == 0) // simplifing to avoid rounding errors { _x = x; _ v = v; _z = z; } else { 1 = (float) (sqrt(x*x+y*y)); 174 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. init_azi = (float) atan2 (y,x); elevation = (float) atan2 (z,l); final_azi = init_azi + azimuth; _x = (float) cos (elevation) * (float) cos (final_azi); _y = (float) cos (elevation) * (float) sin (final_azi); _z = (float) sin (elevation); } } void Direction3D::setPoints3D(Point3D* pi, Point3D* p2) // Postcondition: vector components are changed to normalized input values. { float length = 0; float x = 0, y = 0, z = 0; x = p2->getX() - pl->getX(); y = p2->getY() - pl->getY(); z = p2->getZ() - pl->getZ(); length = x * x + y * y + z * z; if (length - - 0) { x = 1; } else { length = (float) x /= length; y /= length; z /= length; } _x = x ; _y = y; z = z; void Direction3D::setAzimElev(float a, float b) // Precondition: a and b are Azimuth and Elevation in RADIAN) /'/ Postcondition: carthesial vector components are changed to normalized input values (transformed from // the spherical input values. The spherical values are in in RAD. { float length = 0; float x = 0; float y = 0; float z = 0; x = (float) cos (b) * (float) cos (a) ; y = (float) cos (b) * (float) sin (a) ; z = (float) sin (b); 175 // Let it be a default direction vector sqrt((double) length); Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. length = x * x + y * y + z*z; if (length. == 0) { x = 1; // Let it be a default direction vector } else { length = (float) sqrt((double) length); x /= length; y /= length; z /= length; } _x = x; // carthesial coordonates _y = y; z = z; float Direction3D::dotProduct(const Direction3D& d) { return _x * d._x + _y * d._y + _z * d._z; } float Direction3D::angleBetween(const Direction3D& d) // Postcondition: the angle between the directions is returned. { return arcCos(dotProduct (d) ) ; } Direction3D* Direction3D::crossPrcduct(const Direction3D& a) { // Return the cross product of two directions. Direction3D *rd = NULL; // The return object pointer, float dx = 0; float dy = 0; float dz = 0; dx = _y * d._z - _z * d._y; // From Protter-Morrey, p 253. dy = _z * d._x - _x * d._z; dz = _x * d._y - _y * d._x; rd = new Direction3D(dx, dy, dz) ; return rd; } bool operator =(const Direction3D& dl, const Direction3D& d2) // Postcondition: returns true if the input directions are parallel. { return fabs(dl.getX() - d2.getX()) < gsfEpsilon && fabs(dl.getY() - d2.getY()) < gsfEpsilon && fabs(dl.getZ() - d2.getZ()) < gsfEpsilon; 176 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. } // Member functions for the Edge3D class: // Default constructor: Edge3D::Edge3D() { _pl = new Point3D; _p2 = new Point3D; } // Two-point constructor: Edge3D::Edge3D(const Point3D& pi, const Point3D& p2) { _pl = new Point3D(pl); _p2 = new Point3D(p2); } // Copy constructor: Edge3D::Edge3D(const Edge3D& e) { _pl = new Point3D(*(e._pl)) ; _p2 = new Point3D(*(e._p2) ) ; } // Destructor: Edge3D::~Edge3D() { delete _pl; delete _p2; } // Overloaded assignment operator: void Edge3D::operator =(const Edge3D& source) { // Handles the degenerate case p = p Point3D *pl = new Point3D(*(source._pl)); Point3D *p2 = new Point3D(*(source._p2)); delete _pl; delete _p2; _pl = pi; _p2 = p2; Point3D* Edge3D::getPl() const { return new Point3D(*(_pl)) ; Point3D* Edge3D::getP2() const { return new Point3D(*(_p2)) ; } 177 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. void Edge3D::setPl(const Point3D& p) { delete _pl; _pl = new Point3D(p); } void Edge3D::setP2(const Point3D& p) { delete _pl; _pl = new Point3D(p); } bool Edge3D::equals(const Edge3D& e) { return _pl->equals(*(e-_pl)) && _p2->equals(*(e._p2)); } // Member functions for the Point3D class: // Constructor: Point3D::Point3D(float x, float y, float z) // Postcondition: point coordinates are initialized to x, y, and z, and the label. { _x = x; _y = y; _z = z ; } // Copy constructor Point3D::Point3D(const Point3D& p) // Postcondition: point coordinates are initialized to p._x, p._y, and p._z, the label is too. { x = p._x; _y = p-_y; z = p._z; } // Destructor Point3D::~Point3D() { _x = 0; _y - 0; _z = 0 ; } // Accessors: float Point3D::getX() const // Postcondition: point x coordinate is returned. 17S Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. { return _x; } float Point3D::getY() const // Postcondition: Doint y coordinate is returned. { return _y; } float Point3D::getZ() const // Postcondition: point z coordinate is returned. { return _z; } // Mutators: void Point3D::setX(float x) // Postcondition: point x coordinate is changed to x. { _x = x ; } void Point3D::setY(float y) // Postcondition: point y coordinate is changed to y. { _y = y; } void Point3D::setZ(float z) // Postcondition: point z coordinate is changed to z. { z = z; } void Point3D::setXYZ(float x, float y, float z) // Postcondition: point z coordinate is changed to z. { _x = x; _y = y; _z = z ; } void Point3D::operator = (const Point3D& source) // Postcondition: the point is an exact copy of the source point. { _x = source._x; // Copy the coordinates. y = source._y; _z = source._z; } // Other public member functions: float Point3D::distance(const Point3D& p) // Postcondition: The scalar distance between the points is returned. { 179 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. float deltaX = 0 float deltaY = 0 float deltaZ = 0; float distance =0; deltaX = p._x - _x; // Compute the orthogonal distances. deltaY = p._y - _y; deltaZ = p._z - _z; deltaX *= deltaX; // Square the orthogonal distances. deltaY *= deltaY; deltaZ *= deltaZ; distance = deltaX + deltaY + deltaZ; // Sum the squares, distance = (float) sqrt((float) distance); return distance; } bool Point3D::between(const Point3D& pi, const Point3D& p2) //Postcondition: Returns true if the point is in between pi and p2. { bool checkX =0; bool checkY = 0; bool checkZ = 0; if ( ( (_x >= pl.getXO ) && (_x <= p2 .getX () ) ) || ( (_x >= p2 .getX () ) && (_x <= pl.getXO))) checkX = 1; if ( ( (_y >= pl.getYO ) && (_y <= p2. getY () ) ) || ( (_y >= p2 . getY () ) && (_y <= pl.getYO))) checkY = 1; if ( ((_z >= pi.getZ()) && (_z <= p2.getZ())) | | ((_z >= p2.getZ ()) && (_z <= pl.getZO))) checkZ = 1; if (checkX && checkY && checkZ) return true; else return false; } bool Point3D::equals(const Point3D& p) // Postcondition: The return valus is true if the input point has nearly the same coordinates. { return fabs(_x - p._x) < gsfEpsilon && fabs(_y - p._y) < gsfEpsilon && fabs(_z - p._z) < gsfEpsilon; } // Nonmember functions for the Point3D class: float distance(const Point3D& pi, const Point3D& p2) // Postcondition: The scalar distance to the input point is returned. r i float deltaX =0; 180 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. float deltaY = 0; float deltaZ = 0; float distance = 0; deltaX = p2.getX() - pl.getXO; // Compute the orthogonal distances. deltaY = p2.getY() - pl.getYO; deltaZ = p2.getZ() - pi.getZO; deltaX *= deltaX; // Square the orthogonal distances. deltaY *= deltaY; deltaZ *= deltaZ; distance = deltaX + deltaY + deltaZ; // Sum the squares, distance = (float) sqrt((float) distance); return distance; } bool operator ==(const Point3D& pi, const Point3D& p2) // Postcondition: The return valus is true if the points have nearly the same coordinates. { return fabs (pi.getX() - p2.getX()) < gsfEpsilon && fabs(pi.getY() - p2.getY()) < gsfEpsilon && fabs(pi.getZ() - p2.getZ()) < gsfEpsilon; } // General geometric helper functions: float arcCos(float CosineTheta) // Postcondition: The arccosine of the input parameter is returned. { float arcCos = 0; if (CosineTheta > 1 || CosineTheta < -1) { arcCos = 0; // Input is out of bounds. } else { if (CosineTheta = 0) { arcCos = gsfPi / 2; // 90 degrees. } else { if (CosineTheta == 1) { arcCos =0; // 0 degrees. } else { 181 Reproduced with permission of the copyright owner. Further reproduction prohibited without permission. if (CosineTheta == -1) { arcCos = gsfPi; } else { arcCos = (float) atan2(sqrt(l CosineTheta); } } > return arcCos; } //Global functions: float rad(float degree) { return (degree * gsfPi / 180) ; } float degree(float rad) { return (rad * 180/gsfPi) ; } // 180 degrees. CosineTheta * CosineTheta) Reproduced with permission of the copyright owner. Further reproduction prohibited without permission.
Linked assets
University of Southern California Dissertations and Theses
Conceptually similar
PDF
Determine the optimum block type for use in Saudi Arabia
PDF
Hebel design analysis program
PDF
A proposed wood frame system for the Philippines
PDF
Computer aided design and manufacture of membrane structures Fab-CAD
PDF
A method for glare analysis
PDF
Guidelines for building bamboo-reinforced masonry in earthquake-prone areas in India
PDF
Catalyst: A computer-aided teaching tool for stayed and suspended systems
PDF
Eccentric braced frames: A new approach in steel and concrete
PDF
Comparison of lateral performance: Residential light wood framing versus cold-formed steel framing
PDF
Bracing systems for tall buildings: A comparative study
PDF
Acoustics of the Bing Theater, USC: Computer simulation for acoustical improvements
PDF
Statistical analysis of the damage to residential buildings in the Northridge earthquake
PDF
Computer aided form-finding for cable net structures
PDF
A case study comparing measured and simulated acoustical environments: Acoustical improvements of Verle Annis Gallery
PDF
Energy performance and daylighting illumination levels of tensile structures in an extreme climate
PDF
Shading mask: a computer-based teaching tool for sun shading devices
PDF
A passive cooling system for residential buildings in the Eastern Province desert in Saudi Arabia
PDF
Investigation of sloshing water damper for earthquake mitigation
PDF
Emergency shelter study and prototype design
PDF
The Indian Himalayan building energy code as a step towards energy conservation
Asset Metadata
Creator
Leuppi, Judith
(author)
Core Title
Interactive C++ program to generate plank system lines for timber rib shell structures
School
School of Architecture
Degree
Master of Building Science / Master in Biomedical Sciences
Degree Program
Building Science
Publisher
University of Southern California
(original),
University of Southern California. Libraries
(digital)
Tag
Computer Science,engineering, civil,OAI-PMH Harvest
Language
English
Contributor
Digitized by ProQuest
(provenance)
Advisor
Schierle, G. Goetz (
committee chair
), Kensek, Karen (
committee member
), Schiler, Marc E. (
committee member
), Wagner, Richard (
committee member
)
Permanent Link (DOI)
https://doi.org/10.25549/usctheses-c16-36094
Unique identifier
UC11336649
Identifier
1405245.pdf (filename),usctheses-c16-36094 (legacy record id)
Legacy Identifier
1405245.pdf
Dmrecord
36094
Document Type
Thesis
Rights
Leuppi, Judith
Type
texts
Source
University of Southern California
(contributing entity),
University of Southern California Dissertations and Theses
(collection)
Access Conditions
The author retains rights to his/her dissertation, thesis or other graduate work according to U.S. copyright law. Electronic access is being provided by the USC Libraries in agreement with the au...
Repository Name
University of Southern California Digital Library
Repository Location
USC Digital Library, University of Southern California, University Park Campus, Los Angeles, California 90089, USA
Tags
engineering, civil