Algorithms for Visual Design Using the Processing Language

385 Pages • 70,630 Words • PDF • 20.8 MB
Uploaded at 2021-09-24 07:00

This document was submitted by our user and they confirm that they have the consent to share it. Assuming that you are writer or own the copyright of this document, report to us by using this DMCA report button.


Algorithms for Visual Design Using the Processing Language

Algorithms for Visual Design Using the Processing Language Kostas Terzidis

Algorithms for Visual Design Using the Processing Language Published by Wiley Publishing, Inc. 10475 Crosspoint Boulevard Indianapolis, IN 46256 lll#l^aZn#Xdb Copyright © 2009 by Kostas Terzidis Published by Wiley Publishing, Inc., Indianapolis, Indiana Published simultaneously in Canada ISBN: 978-0-470-37548-8 Manufactured in the United States of America 10 9 8 7 6 5 4 3 2 1 Library of Congress Cataloging-in-Publication Data is available from the publisher. No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be addressed to the Permissions Department, John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030, (201) 748-6011, fax (201) 748-6008, or online at ]iie/$$lll#l^aZn#Xdb$\d$eZgb^hh^dch. Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifically disclaim all warranties, including without limitation warranties of fitness for a particular purpose. No warranty may be created or extended by sales or promotional materials. The advice and strategies contained herein may not be suitable for every situation. This work is sold with the understanding that the publisher is not engaged in rendering legal, accounting, or other professional services. If professional assistance is required, the services of a competent professional person should be sought. Neither the publisher nor the author shall be liable for damages arising herefrom. The fact that an organization or Web site is referred to in this work as a citation and/or a potential source of further information does not mean that the author or the publisher endorses the information the organization or Web site may provide or recommendations it may make. Further, readers should be aware that Internet Web sites listed in this work may have changed or disappeared between when this work was written and when it is read. For general information on our other products and services please contact our Customer Care Department within the United States at (877) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002. Trademarks: Wiley and the Wiley logo are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries, and may not be used without written permission. All other trademarks are the property of their respective owners. Wiley Publishing, Inc. is not associated with any product or vendor mentioned in this book. Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be available in electronic books.

To my father, George

About the Author

Kostas Terzidis is an associate professor at the Harvard Graduate School of Design. His current GSD courses are Kinetic Architecture, Algorithmic Architecture, Digital Media I & II, Cinematic Architecture, and Design Research Methods. He holds a PhD in Architecture from the University of Michigan (1994), a Masters of Architecture from Ohio State University (1989) and a Diploma of Engineering from the Aristotle University in Greece (1986). He is a registered architect in Europe where he has designed and built several commercial and residential buildings. His research work focuses on creative experimentation within the threshold between arts, architecture, and computer science. As a professional computer programmer, he is the author of many computer applications on form making, morphing, virtual reality, and self-organization. His most recent work is in the development of theories and techniques for algorithmic architecture. His book Expressive Form: A Conceptual Approach to Computational Design, published by London-based Spon Press (2003), offers a unique perspective on the use of computation as it relates to aesthetics, specifically in architecture and design. His latest book, Algorithmic Architecture, (Architectural Press/Elsevier, 2006), provides an ontological investigation into the terms, concepts, and processes of algorithmic architecture and provides a theoretical framework for design implementations.

vii

Credits

Executive Editor Carol Long

Associate Publisher Jim Minatel

Senior Development Editor Tom Dinse

Project Coordinator, Cover Lynsey Stanford

Production Editor Angela Smith

Compositor Craig Johnson, Happenstance Type-O-Rama

Copy Editor Foxxe Editorial Services Editorial Manager Mary Beth Wakefield Production Manager Tim Tate Vice President and Executive Group Publisher Richard Swadley

Proofreader Publication Services, Inc. Indexer Robert Swanson Cover Designer Michael Trent Cover Image © Kostas Terzidis

Vice President and Executive Publisher Barry Pruett

ix

Acknowledgments

This book was conceived as a first step towards open source development. I would like to thank the person who introduced me to the world of computer graphics back in 1986 at Ohio State University, Professor Chris Yessios. He gave me the knowledge and taught me the means of making my own tools to design and showed me how to share it with my colleagues. Also, I would like to thank my doctoral student at Harvard University Taro Narahara for his help in formatting the text and images of this book. Tom Dinse, Angela Smith, and Carol Long also deserve thanks for their patience and helpfulness during the preparation of this book.

xi

Contents

Introduction Chapter 1

xix Elements of the Language 1.1 Operands and Operations 1.1.1 Variable Types 1.1.2 Name Conventions 1.1.3 Arithmetic Operations 1.1.4 Logical and Relational Operations/Statements 1.1.5 Loops 1.1.6 Patterns of Numbers

1.2 Graphics Elements 1.2.1 Code Structure 1.2.2 Draw Commands 1.2.3 Geometrical Objects 1.2.4 Attributes 1.2.5 Fonts and Images 1.2.6 Examples

1.3 Interactivity 1.3.1 Drawing on the Screen 1.3.2 Mouse and Keyboard Events

1.4 Grouping of Code 1.4.1 Arrays 1.4.2 Procedures and Functions 1.4.4 Recursion 1.4.5 Importing Processing Classes

Summary Exercises

1 2 2 4 5 7 8 10

12 12 13 13 17 20 21

24 24 26

28 28 30 33 34

35 35

xiii

xiv

Contents Chapter 2

Points, Lines, and Shapes 2.1 Sine and Cosine Curves 2.2 Bezier Curve 2.3 Pointillist Images 2.4 Polygons 2.5 Equilateral Polygons 2.6 Responsive Polygons 2.7 Responsive Curve Summary Exercises

41 42 47 48 51 53 54 56 57 57

Chapter 3

The Structure of Shapes 3.1 Introduction to Class Structures

63 63

3.1.1 Defining a Class Called MyPoint 3.1.2 Adding Methods to a Class

64 66

3.2 Organization of Classes

68

3.2.1 Class MyPoint 3.2.2 Class MySegment 3.2.3 Class MyShape

70 70 71

3.3 Standard Transformations (move, rotate, scale) 3.4 Implementing Transformations 3.5 Creating Grids of Shapes 3.6 Class MyGroup 3.7 Selecting Objects Summary Exercises

74 76 80 83 85 90 91

Chapter 4

Basics of Graphical User Interfaces 4.1 Basic GUI (Buttons) 4.2 Choice, Label, and TextField 4.3 Arranging GUI Objects on the Screen 4.4 Selecting Points, Segments, Shapes, or Groups 4.5 Color Setup 4.6 Putting the GUI Elements in Their Own Window 4.7 Mouse Wheel Control Summary Exercises

93 94 98 99 102 104 106 107 107 108

Chapter 5

Image Processing 5.1 Displaying Images 5.2 Preset Image Filters 5.3 Bit Manipulation on Pixels 5.4 A Paint Brush Tool 5.5 Edge Detection Summary Exercises

109 110 111 115 118 121 123 123

Contents Chapter 6

Motion 6.1 Animation Basics 6.2 Erratic Motion 6.3 Line Traces 6.4 Interactive Transformations 6.5 Double Buffering 6.6 Motion and Friction 6.7 Collision 6.8 Elastic Motion Summary Exercises Notes

127 127 131 133 135 138 140 143 145 149 149 152

Chapter 7

Advanced Graphics Algorithms 7.1 Voronoi Tessellation 7.2 Stochastic Search 7.3 Fractals 7.4 Interpolation/Extrapolation 7.5 Cellular Automata 7.6 Evolutionary Algorithm Summary Exercises Notes

153 154 158 162 165 168 172 177 178 180

Chapter 8

3-D Space 8.1 The Third Dimension 8.2 Defining 3D Objects 8.3 Projecting on the Screen 8.4 Perspective Projection 8.5 Three-Dimensional Graphics in Processing 8.6 3D Point Formations

181 182 183 187 190 192 199

8.6.1 Cubical Formations 8.6.2 Spherical Formations 8.6.3 Superquadrics

Chapter 9

199 201 203

Summary Exercises

205 206

Solid Geometry 9.1 Class MyPoint

209 209

9.1.1 Class MyFace 9.1.2 Sets of Faces 9.1.3 Class MySolid 9.1.4 Face Visibility

9.2 Shading 9.2.1 Vectors 9.2.2 Normalization 9.2.3 Cross Product

211 214 215 220

223 225 226 227

xv

xvi

Contents 9.2.4 Dot Product 9.2.5 MyVector Class 9.2.6 Color Tables 9.2.7 Array of Shades 9.2.8 Shade Calculation 9.2.9 Class MyGroup 9.2.10 Sorting Solids (Painter’s Algorithm)

9.3 3D User Interaction 9.3.1 Picking Objects in the Scene 9.3.2 Simulating Menu Bars

Summary Exercises Notes Chapter 10 File Read/Write 10.1 File Formats 10.2 Basic Write/Read in Processing 10.2.1 Exporting PDF and DXF File Formats Using Processing Libraries 10.2.2 Native File Write 10.2.3 Native File Read 10.2.4 The DXF File Format 10.2.5 Writing DXF Files 10.2.6 Reading DXF Files 10.2.7 The VRML File Format 10.2.8 Writing VRML Files 10.2.9 Reading VRML Files

Chapter 11

228 228 229 230 231 234 238

240 241 244

246 246 247 249 250 250 253 255 256 258 259 261 263 265 266

10.3 Client/Server Data Transfer Summary Exercises

268 272 272

Physical Computing 11.1 Basics of Electrical Circuits 11.2 Arduino Microcontroller Board 11.3 Arduino Language 11.4 LED 11.5 Photocell 11.6 Pushbutton 11.7 Servo Motor 11.8 Sound 11.9 Differential Values 11.10 Responsive System: Photo-Sound 11.11 A Feedback System: Photo-Motor Summary Exercises

275 276 278 279 282 284 287 288 290 292 292 294 296 296

Contents Appendix A Equations of Lines and Planes

301

Appendix B Answers to Exercises

307

Appendix C Further Readings

335

Index

339

xvii

Introduction

How has design changed through the use of computers? Is it still valid to assume that a designer is in control of a design concept? What if there is a lack of predictability over what was intended by the designer and what came out on the computer’s screen? Is computer programming necessary in design today? This book is about computer programming. Programming is a way of conceiving and embracing the unknown. At its best, programming goes beyond developing commercial applications. It becomes a way of exploring and mapping other ways of thinking. It is the means by which one can simulate, extend, and experiment with principles, rules, and methods of traditionally humandefined theories. In developing computer programs, the programmer has to question how people think and how mental processes develop and to map them into different dimensions through the aid of computers. Computers should be acknowledged not only as machines for imitating and appropriating what is understood but also as vehicles for exploring and visualizing what is not (yet) understood. The entire sequence of specifying computer operations is similar (albeit not equal) to that of human thinking. When designing software, one is actually codifying processes of human thinking to a machine. The computer becomes a mirror of the human mind, and as such, reflects to a certain level our own way of thinking. However, there is an unraveling relationship between the needs of a designer and the ability of a specific computer application to address these needs. Designers rarely know what the computer is capable of providing them intellectually and often designers overestimate the computer’s capabilities. This can be attributed to at least two factors. First, designers are never really taught how to program (one should to look no further than the classic question/answer “What does computer programming have to do with design?”). In fact, in design xix

xx

Introduction

schools today students are taught how to use CAD tools and how to experiment within the limits of the applications, but they are never taught how to channel their creativity through the language, structure, and philosophy of programming. Second, CAD developers rarely release source code. They may ask the users what they want, they may offer interfaces for customization, but they will never give access to their source code. For good reasons, code is proprietary information, and information is power. So, if a designer wants to experiment with the computational design, then he or she will need to write his or her own application, including the modeling, interface, display, optimization, and debugging modules, all on their own. How many people either have the time or the know-how to do this out there? When are we going to see a Linux-like CAD system? When are we going to see a community of designers-architectsprogrammers sharing common source code, for their own advancement? It is possible to claim that a designer’s creativity is limited by the very programs that are supposed to free their imagination. The motto “form follows software” is indeed a contemporary Whorfian hypothesis that still applies not only to language as a tool but also to computer tools. The reason for that is that there is a finite amount of ideas that a brain can imagine or produce by using a CAD application. If designers don’t find the tool/icon that they want, then they are simply stuck. And, conversely, whenever they use a new tool provided for them by programmers, they think that they are now able to do something new and “cool.” But are they really doing anything new? Or are they simply replicating a process already conceived by the programmer who provided the tool? Of course, if designers knew the processes, principles, and methods of the program behind the tool, then they would be empowered to always keep expanding their knowledge and scholarship by always devising solutions not tackled by anybody else. By using a conventional program, and always relying on its design possibilities, the designer/architect’s work is sooner or later at risk of being imitated, controlled, or manipulated by CAD solutions. By cluttering the field with imitations of a type of particular software, one runs the risk of being associated not with cutting-edge research but with a mannerism of style. In this context, there are many designers claiming to use the computer to design. But are they really creating a new design? Or are they just rearranging existing information within a domain set by the programmers? If it is the programmer who is considering all possible solutions to a design environment beforehand, who is really setting the parameters and the outcome of a design solution? We saw already the I-Generation (Internet-Generation) risen out of the information age. When are we going to see the C-Generation (CodeGeneration) — the generation of truly creative designers who can take their fate into their own hands?

Introduction

In the world of design today, computer programs have taken over many traditionally human intellectual tasks, leaving less and less tasks for traditional designers to do. From Photoshop filters to modeling applications, and from simulation programs to virtual reality animation, and even more mundane tasks that used to need a certain talent to take on, such as rendering, paper cutting, or sculpting, the list of tasks diminishes day by day only to be replaced by their computational counterparts. What used to be a basis to judge somebody as a talent or a genius is no longer applicable. Dexterity, adeptness, memorization, fast calculation, and aptitude are no longer skills to seek for, nor are they reasons to admire a designer as a “genius.” The focus has shifted far away from what it used to be toward new territories. Computational tools allow not only manual, tedious, and repetitive tasks to be done quicker, cheaper, and more efficiently but also intellectual tasks that require intelligence, thought, and decision making. In the process, many take advantage of the ephemeral awe that the new computational tools bring to design, either manual or intellectual, by using them as means to establish a new concept, style, or form — only to have it revealed later that their power was based on the tool they used and not on their own intellectual ability. Of course, the tool that was used was indeed developed by somebody else, that is, a programmer, who discovered the tool’s concept, mechanism, and implementation, and should, perhaps, be considered instead as the true innovator. As a result of the use, misuse, and, often, abuse of computational design tools, many have started to worry about the direction that design may take in the next few years. As, one by one, all design tasks are becoming computational, some regard this as a danger, misfortune, or misappropriation of what design should be and yet, others regard it as a liberation, freedom, and power towards what design should be: conceptualization. According to the latter, the designer does not need to worry anymore about the mundane, tedious, or redundant tasks in the design process, such as construction documents, schedules, databases, modeling, rendering, animation, and so forth and can now concentrate on what is most important: the concept. But what if that is also replaced? What if one day a new piece of software appears that allows one to input the building program and then produces valid designs, that is, a plan, elevation, and sections that work? And, worse, what if they are better than the designer would have ever done by himself or herself? (Even though most designers would never admit publicly that something is better than what they would have designed, yet what if deep inside they would admit it?) What then? Are we still going to continue demonizing the computer and seeking to promote geniuses when they probably don’t exist? If that ever happens, then obviously the focus of design will not be in the process itself, since that can be replaced, but rather in the replacement operation

xxi

xxii

Introduction

itself. The new designer will construct the tool that will enable one to design in an indirect meta-design way. As the current condition indicates, the original design is laid out in the computer program that addresses the issues, not in the mind of the user. If the tool maker and the tool user is the same person, then intention and randomness can coexist within the same system and the gap can be bridged. Maybe, then, the solution to this paradox may not be found inside or outside the designer’s mind but perhaps in the link that connects the two.

Overview of the Book and Technology This book offers students, programmers, and researchers the technical, theoretical, and design means to develop computer code that will allow them to experiment with design problems for which a solution is possible or for those for which it is not. The first type of problem is straightforward, where the methodology is to create an algorithm that will solve the problem in a series of steps. It is about the codification of ideas that are preconceived in the mind of the designer and await a way to manifest them in a physical form. Sample cases are given that address various problems such as geometrical, topological, representational, numerical, and so forth. In contrast, there is another set of problems, in which a solution is not preconceived, or even known. This book offers a series of procedures that can function as building blocks for designers to experiment, explore, or channel their thoughts, ideas, and principles into potential solutions. The computer language used in this book is a new, fascinating, and easy-to-use language called Processing, and it has been used quite extensively in the visual arts over the last few years. Although this book offers a quick and concise introduction to the language itself, the core of the book focuses on the development of algorithms that can enhance the structure and strategy of the design process. These algorithms and techniques are quite advanced and not only offer the means to construct new design tools but also function as a way of understanding the complexity involved in today’s design problems. Such algorithms include Voronoi tessellation, stochastic search, morphing, cellular automata, and evolutionary algorithms.

How This Book Is Organized This book is divided into 11 chapters. It is assumed that the reader of the book has no previous knowledge of programming. Nevertheless, the topics of each chapter are organized so that successive chapters contain progressively more complex topics that are based on the previous chapters. Each chapter covers a

Introduction

discrete topic that allows you to build your knowledge not only by reading the chapters but also by applying the knowledge through relevant exercises. This book introduces basic structures and processes of programming in Processing in order to clarify and illustrate some of the mechanisms, relationships, and connections behind the forms generated. This is not intended to be an exhaustive introduction to programming but rather an indication of the potential and a point of reference for assessing the value of algorithms. N

N

N

N

N

Chapter 1 is a general introduction to the elements, operands, and operations of the Processing language. It covers basic concepts such as variables, arithmetic and logical operations, loops, arrays, and procedures. It also shows how to create basic geometry, how to affect their attributes, and how to interact with them. A series of exercises allows the reader to explore and test more possibilities. Chapter 2 shows how to use points in order to construct curves or images, and how to use lines to construct shapes. It uses trigonometric functions as well as polynomials to determine the positions of points along a curve. Shapes are constructed by using trigonometric functions to place points along a circumference establishing equilateral polygons. Chapter 3 introduces the concept of class and how classes can be used to organize code in hierarchical entities. This chapter introduces the classes of a point, a segment, a shape, and then a group. Each class contains methods that allow it to interact with other classes in a complementary, hierarchical, and object-oriented way. The advantage of this methodology is speed, organization, and interaction that allows objects or their subparts to be selected, modified, or deleted. Chapter 4 introduces basic elements of a graphic user interface (GUI) such as buttons, choice menus, labels, and text fields. The objective is first to arrange them in the screen to provide an interactive environment, but more importantly to connect them with the classes introduced in Chapter 3. In such a way, the graphical user interface elements can determine the position, orientation, and size of geometrical entities such as vertices, edges, faces, or groups as well as their color. Chapter 5 shows you how to process images. An image is a collection of colored pixels and can be changed by the application of certain functions that affect the color of specific pixels or their neighboring pixels. Grayscale, threshold, inversion, blur, or poster are some of the many image processing filters. However, you will look further into the structure of a pixel and see how it is represented in the computer’s memory and then use this information to speed up the process so as to produce any possible filter. You will also look into interactive paint brushes and edge detection.

xxiii

xxiv

Introduction N

N

N

N

N

Chapter 6 is about motion. Motion is simply a visual phenomenon based on the speedy redraw of the screen. You will see how to produce motion using images or geometrical objects, how to constrain the motion within boundaries, and how to affect the direction or position of motion. You are introduced to the use of transformation operations and how they can be used to produce repetitive, recursive, or random patterns. Finally, you look into physics-based motion showing how to use friction, collision, and elasticity. Chapter 7 is a collection of advanced graphics algorithms that can be used as techniques for design projects. These algorithms include Voronoi tessellation, stochastic search, fractals, hybridization, cellular automata, and evolutionary algorithms. Voronoi tessellation is shown as a method of subdividing the screen into multiple areas using pixels as finite elements. Stochastic search is a method of random search in space until a given or an optimum condition is met. Fractals are recursive patterns that subdivide an initial base shape into subelements and then repeat the process infinitely. Hybridization is a procedure in which an object changes its shape in order to obtain another form. Cellular automata are discrete elements that are affected by their neighboring elements’ changes. Finally, evolutionary algorithms use biological Darwinian selection to optimize or solve a problem. Even though they are abstract, these algorithms have been used quite extensively to address or solve design problems and can function as metaphors or inspiration for similar design projects. Chapter 8 introduces you to the concept of 3D space in the context of geometry. This is done through projections and transformation of threedimensional points into two-dimensional viewing screens. Single or multiple objects can be viewed either statically or dynamically by rotating the scene. Formations of multiple objects are being studied as grids in space, spheres, or superquadrics. Chapter 9 introduces basic concepts of solid geometry using the class structures introduced earlier in Chapter 3. Here you are introduced to classes for a point, a face, a solid, and a group. Each class contains the appropriate methods that allow it to interact with the other classes. Specifically, faces are arranged to form extruded polygons and then checked for visibility. Shading of faces is also introduced using vector geometry. Finally, objects or subelements can be selected and transformed in a user interactive environment. Chapter 10 shows you the structure of files and how they can be used to save information or to input new information to a design project. You will cover basic file read and write operations and then look into the structure of universal file formats such as PDF, MOV, DXF, and VRML.

Introduction

These will be used to interchange information between Processing and other applications, such as Acrobat, AutoCAD, Rhino, QuickTime, and so forth. The purpose is to take advantage of each application’s tools and use them to enhance the initial processing form, or conversely, to input an application’s file into Processing for further enhancements. You will also be introduced to client-server data transfer as a means of connecting to remote servers. N

Chapter 11 shows you how to use Processing to produce physical motion in the environment. This will be done through electrical circuits and devices, such as photocells, motors, buttons, speakers, LEDs, and the like. You see how to process information coming in the computer and how to output information to the external physical world. You will be using a microcontroller called Arduino, which uses a computer language based on Processing. You will also see how input and output information can be connected in responsive and feedback systems and how this can be useful in a design or installation context.

Each chapter, apart from its theoretical and technical dimension, also contains a series of exercises that are meant to help the reader understand and explore possibilities beyond the chapter’s content. For each exercise a solution is given in Appendix B so that the reader can try and then compare solutions.

Who Should Read This Book This book is aimed mainly at students (design, art, computation, architecture, etc.) and professionals (web developers, software developers, designers, architects, computer scientists). Since it addresses both a computer language and advanced algorithms, it can be seen as a textbook or a manual as well as a reference book. From my experience as a professor and a software developer, there are many students, instructors, developers, and regular folks that cannot find a book that will teach them graphics software development in a simple, no-prerequisite, hands-on manner. Most of these people are ready to start writing software, and they are waiting for the chance. This book does it in a great and efficient way taking you much further than any other book.

Tools You Will Need The language used in the book is Processing, an open source, free-of-charge, powerful, and yet simple computer language that can be downloaded from the Internet. The version of Processing used in this book is the latest at this time,

xxv

xxvi

Introduction

that is, version 1. You should also know that Processing is based on another language called Java, which is also available free of charge from the Internet. In the last chapter of this book, a physical device is introduced called Arduino that also uses a version of the Processing language called, appropriately enough, Arduino. The version used in this book is Arduino 0012.

What’s on the Web Site All code shown in this book together with the exercises can be found at the book’s web site at lll#l^aZn#Xdb.

From Here One of the main objectives of this book, compared to other computer graphics books, is to take away the fear of complexity or the assumption of prerequisites that most books have. There is a large audience of computer graphics–thirsty readers that simply cannot understand existing books because either they are full of mathematical formulas or assume that the reader already knows the basics. As a computer scientist and designer-architect, I have developed this book with this in mind. In addition, my experience with teaching computer graphics programming to design-oriented students with no programming experience guided me as well. The book is a bridge between the creative designer and the computer savvy.

Algorithms for Visual Design Using the Processing Language

CHAPTER

1

Elements of the Language

Processing is a computer language originally conceived by Ben Fry and Casey Reas, students at the time (2001) at MIT. Their objective was to develop a simple language for use by designers and artists so that they could experiment without needing an extensive knowledge of computer programming. They began with Java, a popular computer language at that time, yet quite complicated for noncomputer-science programmers, and developed a set of simpler commands and scripts. They also developed an editor so that typing, compiling, and executing code could be integrated. Specifically, the compiler used (called jikes) is for the Java language, so any statement in Java can also be included within the Processing language and will be consequently compiled. Some of the characteristics of Processing (and Java) language are: N N

N

N

N

Multi-platform: Any program runs on Windows, Mac OS, or Linux. Secure: Allows high-level cryptography for the exchange of important private information. Network-centric: Applications can be built around the internet protocols. Dynamic: Allows dynamic memory allocation and memory garbage collection. International: Supports international characters.

1

2

Chapter 1 N

N

N

Elements of the Language

Performance: Provides high performance with just-in-time compiles and optimizers. Simplicity: Processing is easier to learn than other languages such as a C, C++, or even Java.

The basic linguistic elements used in Processing are constants, variables, procedures, classes, and libraries, and the basic operations are arithmetical, logical, combinatorial, relational, and classificatory arranged under specific grammatical and syntactical rules. These elements and operations are designed to address the numerical nature of computers, while at the same time providing the means to compose logical patterns. Thus, it can be claimed that the Processing language assumes that a design can be generated through the manipulation of arithmetic and logical patterns and yet may have meaning attributed to it as a result of these manipulations. The following sections examine basic structures and processes in Processing as they relate to graphics in two dimensions (2D) and three dimensions (3D). This is not intended to be an exhaustive introduction to Processing but rather an introduction to the elements and processes used in the context of 2D and 3D graphics. We will start with basic elements and processes, give examples, and then move into more complex topics.

1.1 Operands and Operations The basic structure of a computer language involves operations performed with elements called operands. The operands are basic elements of the language, such as variables, names, or numbers and the operations involve basic arithmetic and logical ones such as addition, multiplication, equality, or inequality. The next section introduces the basic operands and operations used in Processing and their corresponding syntax.

1.1.1 Variable Types Variables are used to hold data values. Variables can be of different types: if they hold whole numbers, they are called integer variables; if they hold true/false data, they are called booleans; if they hold fractional numbers they are called float, etc. In Processing, as well as in most computer languages, the syntax for declaring a variable is: ineZcVbZ

For instance: ^cibn6\Z2(*

Chapter 1

N

Elements of the Language

declares an integer variable called bn6\Z. Depending on the type of data you want to store, you might use different variable types: N

WddaZVc, which is 1-bit long and can take values of either igjZ or [VahZ: WddaZVc^h>ch^YZ2[VahZ0

N

X]Vg, which is 16-bit long and therefore can store 216 (= 65,536) different

characters (assuming that each character corresponds to one number, which is its ASCII code): X]Vg[^ghiAZiiZg2»6¼0 N

WniZ, which is an 8-bit element and therefore can store 28 (= 256) different

binary patterns: WniZW2'%0 N

^ci, which is 32 bits long, can define integer (whole) numbers: ^cicjbWZgTd[ThfjVgZh2'*0

N

[adVi, which is 32 bits long, can define real numbers: YdjWaZe^2(#&)&*.0

N

Xdadg, which is a group of three numbers that defines a color using red,

green, and blue. Each number is between 0 and 255: XdadgX2Xdadg'**!%!%0 N

Hig^c\, which is a collection of characters used for words and phrases: Hig^c\bnCVbZ2¹Idcnº0

Be aware that a string is defined as characters within double quotation marks. It is different from X]Vg where we use single quotation marks. Table 1-1 lists the variable types and their characteristics. Table 1-1: Variable Types TYPE

SIZE

DESCRIPTION

boolean

1 bit

True or false

char

16-bits

Keyboard characters

byte

8 bits or 1 byte

0–255 numbers

int

32 bits

Integer numbers

float

32 bits

Real fractional numbers

color

4 bytes or 32 bytes

Red, Green, Blue, and Transparency

String

64 bits

Set of characters that form words

3

4

Chapter 1

N

Elements of the Language

1.1.1.1 Cast A variable of one type can be cast (i.e., converted) to another type. For example: [adViY^hi2(#*0 ^cim2^ciY^hi0

Here the value of the float variable Y^hi can be cast to an integer m. After the casting, m will be ( (i.e., the fractional or decimal part is omitted). The following command allows casting between different types: WddaZVc!^ci![adVi!hig!WniZ#

For example: [adViY^hi2(#*0 Hig^c\h2higY^hi0

will create the string value “3.5” (not the float number 3.5).

1.1.2 Name Conventions When you declare a variable (which is a made up name) you also need to tell what type it is and (if necessary) to give it an initial value. You use the following format: ineZcVbZ2kVajZ0

For example: ^cibn6\Z2(*0

declares an integer variable called bn6\Z and assigns to it the data value (*, which is a whole number. All data types, if no initial value is given, default to 0. Booleans default to [VahZ and strings to ¹º (empty). You choose a variable’s name and, for the sake of readable code, it should make sense in the context of a problem. If you declare a variable that holds names, you should call it cVbZh or cZlCVbZh, or something that makes sense given the context. Variables usually start with lower case, and when you want to composite more than one word, you use upper case for the next word. This is also referred to as intercapping. For example: cVbZhdgcZlCVbZhdgcZlEZdeaZCVbZh

WA R NI NG A name cannot start with a number, contain an empty space or contain any special characters except the underscore. For example, 1thing, x-y, and the plan are invalid names, but thing1, x_y, and the_plan are valid names.

Chapter 1

N

Elements of the Language

Booleans usually start with the prefix “is” For example: ^hA^\]iDcdg^h>iGV^c^c\

As an example of initializing variables and data, let’s define information about a circle. The following types, variables, and initializations can be used: Hig^c\cVbZ2¹Bn8^gXaZº0 ^ciadXVi^dcTm2''0 ^ciadXVi^dcTn2*+0 [adVigVY^jh2)#*0 WddaZVc^hCjgWh2[VahZ0

In this case, we define information about a circle, that is, its name, its x and y pixel location on the screen (integer numbers), its radius, and an indication of its method of construction.

1.1.3 Arithmetic Operations All the basic arithmetic operations, such as addition, subtraction, multiplication, and division are available in Processing using the symbols shown in Table 1-2. Table 1-2: Arithmetic Operations OPERATOR

USE

DESCRIPTION

+

op1 + op2

Adds op1 and op2

-

op1 - op2

Subtracts op2 from op1

*

op1 * op2

Multiplies op1 by op2

/

op1 / op2

Divides op1 by op2

%

op1 % op2

Computes the remainder of dividing op1 by op2

For example, to get the sum of two numbers, you can write: ^cihjb0$$cdi^c^i^Va^oZYWZXVjhZlZYdcdi`cdl]dlbjX] hjb2* +0$$cdlhjb^h&&

Note that the addition operation occurs on the right side of the equal sign, and the result is assigned to the variable on the left side of the equal sign. This is always the case for operations, and it may seem odd, as it uses the opposite syntax to the statement 1 + 1 = 2. Note also the two slashes. They represent comments. Anything after $$ is ignored by Processing until the end of the line.

5

6

Chapter 1

N

Elements of the Language

Therefore, $$ is for one-line comments. If you want to write multiline comments, use $ to start and $ to end. For example: $i]^hhiViZbZci^h^\cdgZY WnegdXZhh^c\ZkZci]dj\]>X]Vc\Z a^cZh $ $$i]^h^h^\cdgZYjci^ai]ZZcYd[i]Za^cZ

The multiplication symbol is , and the division is $. For example: [adVigZhjai0 gZhjai2%#* (*#'$'.#&0$$i]^hbVnWZVbW^\jdjh

Since the result of this operation may seem ambiguous, you can use parentheses to define the parts of the formula to be executed first: gZhjai2%#* (*#'$'.#&0

This is obviously different from: gZhjai2%#* (*#'$'.#&0

However, there is a priority to the various symbols — if you can remember it, then you do not need to use parentheses. The sequence in which the operations will be executed follows this order: !!!$!! !", as shown in Table 1-3. Table 1-3: Precedence Operations Execution TYPE

SYMBOL

postfix operators

()

multiplicative

*/%

additive

+-

Finally, one useful operation is the remainder  operation. It is the remainder of the division of two numbers. Note that a remainder is always less than the divisor: ^cibdYjadGZhjai0 bdYjadGZhjai2&%'0$$i]ZgZhjai^h% bdYjadGZhjai2.'0$$i]ZgZhjai^h&

Processing provides convenient shortcuts for all of the arithmetic operations. For instance, x+=1 is equivalent to x = x + 1 or y/=z is equivalent to y = y / z. These shortcuts are summarized in Table 1-4.

Chapter 1

N

Elements of the Language

Table 1-4: Equivalent Operations OPERATOR

USE

EQUIVALENT TO

+=

op1 += op2

op1 = op1 + op2

-=

op1 - = op2

op1 = op1 - op2

*=

op1 *= op2

op1 = op1 * op2

/=

op1 /= op2

op1 = op1 / op2

%=

op1 % = op2

op1 = op1 % op2

1.1.4 Logical and Relational Operations/Statements Logical operations define the truthfulness of a conditional statement. Logical operations are tested with the word ^[, which represents a guess needed to be tested. In Processing, ^[ statements have the following format: ^[XdcY^i^dc °0 ZahZ °0

The conditions can be one of the following: equal, not equal, greater, or smaller. These conditions are represented by the following symbols: ^[V22W$$^[V^hZfjVaidW ^[V2W$$^[V^hcdiZfjVaidW ^[V3W$$^[V^h\gZViZgi]VcidW ^[V32W$$^[V^h\gZViZgi]VcdgZfjVaidW ^[V1W$$^[V^haZhhi]VcW ^[V12W$$^[V^haZhhi]VcdgZfjVaidW

To combine conditions, we use the AND and OR operators represented by  and qq symbols. For example ^[V3WV3X$$^[V^h\gZViZgi]VcWVcYV^h\gZViZgi]VcX ^[V3WqqV3X$$^[V^h\gZViZgi]VcWdgV^h\gZViZgi]VcX

Here is an example of a conditional statement: Hig^c\jhZgCVbZ2¹@dhiVhº0 WddaZVc^ihBZ0 ^[jhZgcVbZ22¹@dhiVhºp ^ihBZ2igjZ0 r

7

8

Chapter 1

N

Elements of the Language

ZahZp ^ihBZ2[VahZ0 r

Note that the left and right curly brackets (p) and (r) are used to group sets of statements. If there is only one statement, we can omit the curly brackets, as in: ^[jhZgcVbZ22¹@dhiVhº ^ihBZ2igjZ0 ZahZ ^ihBZ2[VahZ0

Also, note that the semicolon (0) at the end of each statement indicates the end of the statement. Table 1-5 lists and describes the basic logical and relational operations. Table 1-5: Logical Operators OPERATOR

USE

RETURNS TRUE IF

>

op1 > op2

op1 is greater than op2

>=

op1 > = op2

op1 is greater than or equal to op2

<

op1 < op2

op1 is less than op2

bV\Z will load and display an existing image. It takes the location of the image and returns a E>bV\Z object that can be displayed using the

image command. For example, E>bV\Zbn>bV\Z2adVY>bV\Z¹X/$YViV$^bV\Z#_e\º0 ^bV\Zbn>bV\Z!%!%0

will display an image at location 0,0 (i.e. the origin). Figure 1-20 shows an example.

Figure 1-20: An image placed at the upper left corner of the window

If a directory is not mentioned, then Processing will look for the image within the same directory that the code is (or inside the sub-directory “data”). The image will be drawn on the default 100 t100 screen. If it is larger it will be cropped and if smaller it will be left with an empty margin (as in Figure 1-20).

1.2.6 Examples This section introduced the basic graphics commands for geometrical objects, text, and images. These graphical objects are assumed to be static as paintings. The next section introduces motion and interactivity using the YgVl command and by redrawing the screen to create an illusion of motion. The follow code demonstrates most of the graphics commands introduced so far. Figure 1-21 shows an example. h^oZ(%%!'%%0$$h^oZd[i]ZY^heaVn WVX`\gdjcY&*%0$$hZiVYVg`WVX`\gdjcY E>bV\Zbn>bV\Z2adVY>bV\Z¹X/$YViV$^bV\Z#_e\º0$$\ZiVc^bV\Z ^bV\Zbn>bV\Z!&%%!*%0$$Y^heaVn^iVii]ZXZciZgd[i]ZhXgZZc cd;^aa0$$[dgVcZbeingZXiVc\aZ higd`ZLZ^\]i)0$$bV`ZVi]^c`a^cZ gZXi.%!)%!bn>bV\Z#l^Yi] '%!bn>bV\Z#]Z^\]i '%0$$bV`ZVgZXiVc\aZ [gVbZ

21

22

Chapter 1

N

Elements of the Language

E;dcibn;dci2XgZViZ;dci¹I^bZhº!('0$$XgZViZV[dci iZmi;dcibn;dci0$$adVYi]Z[dci [^aa'*%0$$X]Vc\Zi]ZXdadgd[i]ZiZmiidVabdhil]^iZ iZmi¹L]Vi^hi]^h4º!*%!&%%0$$Y^heaVni]ZiZmi

Figure 1-21: A combination of images, text, and a rectangle

The following code and figures provide examples of loops using graphics elements. [dg^ci^2%0^1*%0^ p a^cZ^'!&%!^'!.%0 r

[dg^ci^2%0^1&%%0^2^ 'p a^cZ^!^!^!*%0 r

[dg^ci^2%0^1&%%0^2^ 'p a^cZ^!&%!gVcYdb&%%!.%0 r

Chapter 1

[dg^ci^2&%%0^3%0^2^"'p gZXi%!%!^!^0 r

[dg^ci^2%0^1&%%0^2^ *p gZXi^!%!(!..0 r

[dg^ci^2%0^1,%%0^2^ 'p a^cZ^!*%!^!h^cgVY^Vch^((% *%0 r

[dg^ci^2,%0^3%0^2^")p Zaa^ehZ*%!*%!^!^0 r

[dg^ci^2,%0^3%0^2^")p Zaa^ehZ^!*%!^!^0 r

N

Elements of the Language

23

24

Chapter 1

N

Elements of the Language

1.3 Interactivity So far, we have seen graphics elements displayed on the window as static entities. They appear to be stationary even though, as we will see, they are redrawn continuously on the computer screen. In this section, we will show how to take graphical elements and redraw them fast enough to produce the illusion of motion. This subject will be expanded further in Chapter 6.

1.3.1 Drawing on the Screen As discussed earlier in this chapter, the structure of Processing code is divided in two main sections: the setup and draw section. The setup section is used to define initial environment properties (e.g. screen size, background color, loading images/fonts, etc.) and the draw section for executing the drawing commands (e.g. point, line, ellipse, image, etc.). The structure of the code is as follows: kd^YhZijep r kd^YYgVlp r

By default, in Processing the draw area is executed repeatedly in a loop. The speed of this loop can be controlled by using the [gVbZGViZ command to set the number of frames per second. For example, if we want to draw a vertical line that moves horizontally (as illustrated in Figure 1-22) then the following code can be used: &kd^YhZijep 'h^oZ(%%!&%%0 (r ) *^ci^2%0 +kd^YYgVlp ,a^cZ^!%!^!&%%0 -^ 0 .r

Figure 1-22: A moving line leaving a trace

Chapter 1

N

Elements of the Language

The first three lines are used to set the size of the display. In line 5 an integer variable ^ is initialized to %. It will be used as a counter. It is defined outside of the draw area. Line 8 increases the counter by 1 every time the screen redraws itself. So, then the line is being redrawn in increments of one pixel in the horizontal direction. In the resulting effect, the black line leaves a trace as it is redrawn that over time creates an increasingly black area. The next example redraws the background every time the draw command is executed, creating an animating effect. This produces a line that seems to move from left to right one pixel at a time, illustrated in Figure 1-23. &kd^YhZijep 'h^oZ(%%!&%%0 (r ) *^ci^2%0 +kd^YYgVlp ,WVX`\gdjcY'%%0 -a^cZ^(%%!%!^(%%!&%%0 .^ 0 &%r

Figure 1-23: A moving line leaving no trace

Note that in line 8 we modulate the counter ^ by (%% so that when it reaches 300 it sets itself back to zero. Finally, in the last example, we replace the counter ^ with the mouse coordinates that are defined in Processing by bdjhZM and bdjhZN. In that way, we can get an interactive effect where the line is redrawn every time the mouse is moved, as illustrated in Figure 1-24. &kd^YhZijep 'h^oZ(%%!&%%0 (r ) *kd^YYgVlp +WVX`\gdjcY'%%0 ,a^cZbdjhZM!%!bdjhZM!&%%0 -r

25

26

Chapter 1

N

Elements of the Language

Figure 1-24: A line moved to follow the mouse’s location

1.3.2 Mouse and Keyboard Events A mouse’s or keyboard’s activity can be captured by using the bdjhZ9gV\\ZY, bdjhZBdkZY, bdjhZEgZhhZY, bdjhZGZaZVhZY, or `ZnEgZhhZY events. In each case, a series of commands can be activated every time the corresponding event is triggered. The structure of the code is: kd^YhZijep r kd^YYgVlp r kd^YbdjhZEgZhhZYp r kd^Y`ZnEgZhhZYp r

In specific, these events are used in the following way: N

b d j h Z E g Z h h Z Y   is called when a mouse button is pressed. For

example, &kd^YYgVlp 'r ( )kd^YbdjhZEgZhhZYp *gZXibdjhZM!bdjhZN!&%!&%0 +r

produces the result shown in Figure 1-25.

Figure 1-25: Randomly located rectangles by the press of the mouse button

Chapter 1 N

N

Elements of the Language

bdjhZ9gV\\ZY is called when a mouse is dragged. For example, &kd^YYgVlp 'r ( )kd^YbdjhZ9gV\\ZYp *gZXibdjhZM!bdjhZN!&%!&%0 +r

will result in Figure 1-26.

Figure 1-26: Rectangles following the location of the mouse

N

`ZnEgZhhZY is called when a mouse is pressed. For example, &kd^YYgVlp 'r ( )kd^Y`ZnEgZhhZYp *^cim2^cigVcYdb%!&%%0 +^cin2^cigVcYdb%!&%%0 ,gZXim!n!&%!&%0 -r

will result in Figure 1-27.

Figure 1-27: Randomly located rectangles by the press of any keyboard key

The example above uses a random generator to produce x and y coordinates. This is done by calling the gVcYdb function; we pass two numbers that correspond to the lower and upper limit (i.e. 0,100). Then we cast the resulting random numbers to integers. This is done because the random function always returns float numbers.

27

28

Chapter 1

N

Elements of the Language

1.4 Grouping of Code Computer code can be seen as language statements that convey a process to be executed by a computer. As a linguistic structure, code can be grouped into sentences, paragraphs, sections, etc. In the following sections we will examine basic structures of code that can store information (arrays), be referred to (procedures) and be self-referential (recursion).

1.4.1 Arrays An array is an ordered set of data. It appears as a variable that can hold multiple values at the same time, but essentially it is a pointer to the memory addresses of where that data are held. We assign or extract the data values of an array by pointing at the index of the array, i.e., a number indicating the sequential order of the element of the array. For example, we may refer to the fifth or sixth element in an array. We can have arrays of any type, i.e., booleans, integers, strings, etc. We define an array by using the PR symbol. For example: Hig^c\PRcVbZh2p¹@dhiVhº!¹>kVcº!¹?Z[[º!¹?^Z:jcºr0 [adViPRiZbeZgVijgZh2p--#.!-.#&!-.#%!.(#)!.*#'!&%&#'r0 ^ciPRcjbTd[TigVchVXi^dch2cZl^ciP*%R0 WddaZVcPR^hD[[0

The above arrays define 4, 6, 50, or no elements, respectively, either populated or not. The word cZl is used to create and initialize the array (or, in technical terms, allocate memory for it). The term edejaViZ means that we are assigning specific values to the array, i.e. populating its content. In this case, we initialized the array cjbTd[TigVchVXi^dch to 50 integer values. While creating an array we can fill it with data and then have access to them by pointing to an index number. For example, the following code: [dg^ci^2%0^1)^ p eg^ciaccVbZhP^R0 r

will produce the following output: @dhiVh >kVc ?Z[[ ?^Z:jc

This will extract the data from the array. Note that arrays start at 0. So, in order to access the second element of the array, we use the expression: Hig^c\eZghdc2cVbZhP&R0$$VggVnhhiVgiVi%hd&^hi]ZhZXdcY ZaZbZci#>ci]^hXVhZ^i^h>kVc

Chapter 1

N

Elements of the Language

The above statement will return the second element (which should be the name >kVc). If we have a two-dimensional array we initialize it as: ^ciild96ggVnPRPR2cZl^ciP*RP&%%R0

It will initialize an array of 5 rows and 100 columns and we access its elements in the following way: ^cihdbZ:aZbZci2ild96ggVnP'RP&-R0

The above statement will return the element at the third row and the nineteenth column. Arrays are very useful for storing a set of data under the same name. For example, float XddgYhPRPR can hold all the values of data residing at x and y coordinates of a grid. While arrays may start with a specific number of positions, it is possible that they need to be expanded in order to receive new data values. Also, it is possible that they need to be shortened as the data values are much less than the positions. Consider the problem of a butterfly hunter who starts the day with a set of jars. What if she finds more butterflies than the available jars? What if she finds fewer and carries around empty jars? Processing (as well as Java) has dynamic memory allocation, i.e. memory allocated whenever it is necessary. So, in the case of the butterfly hunter, there is no need to pre-estimate the number of jars. She goes out with no jars, and every time a butterfly is caught, a jar is fetched from the camp. So, for convenience, there are, at least, five important methods associated with arrays: N

VggVn#aZc\i]: returns the number of elements of an array

N

hdgiVggVn: sorts the elements of an array in alphabetic order

N

VeeZcYVggVn!YViV: expands an array by one element and adds data

value N

hjWhZiVggVn!d[[hZi!aZc\i]): creates a subset of an array at offset for

a specified length N

ZmeVcYVggVn!h^oZ: expands an array by a total size position retaining

the existing data values The following code shows how an array can be created, populated, sorted, and then shortened and expanded: &Hig^c\PRh2cZlHig^c\P%R0$$cZlZbeinVggVn 'h2VeeZcYh!º@dhiVhº0 (h2VeeZcYh!ºCVh]^Yº0 )h2VeeZcYh!º?^Z:jcº0 *eg^cih#aZc\i]0$$h]djaYWZ( +[dg^ci^2%0^1h#aZc\i]0^  ,eg^cihP^R ¹!¹0 -$$h]djaYWZ/@dhiVh!CVh]^Y!?^Z:jc!

29

30

Chapter 1

N

Elements of the Language

.h2hdgih0 &%[dg^ci^2%0^1h#aZc\i]0^  &&eg^cihP^R ¹!¹0 &'$$h]djaYWZ/?^Z:jc!@dhiVh!CVh]^Y! &(h2hjWhZih!&!'0 &)eg^cih#aZc\i]0$$h]djaYWZ' &*[dg^ci^2%0^1h#aZc\i]0^  &+eg^cihP^R ¹!¹0 &,$$h]djaYWZ/@dhiVh!CVh]^Y! &-h2ZmeVcYh!*0 &.eg^cih#aZc\i]0$$h]djaYWZ* '%[dg^ci^2%0^1h#aZc\i]0^  '&eg^cihP^R ¹!¹0 ''$$h]djaYWZ/@dhiVh!CVh]^Y!cjaa!cjaa!cjaa!

In the first line of code, we declare an empty array of strings called h. Note that we are allocating 0 positions for this array so that we can expand it. In other words, it is not sufficient to just declare it without using the cZl command for memory allocation. Once, the array h is defined, we can printout its size and its members (line 7), sort it in ascending order (line 9), get a subset of the first two elements of the sorted array (line 13), and expand it to contain 3 more elements (i.e. a total of 5). Note that since we did not assign values to the expanded position, they will printout as null.

1.4.2 Procedures and Functions When we write code in Processing, we occasionally may want to group a series of statements that do something useful. Then we can use these statements to perform repetitive tasks by making reference to that group of statements. For example the following lines of code produce a series of 15 lined up long rectangles that start at location 10,10. &h^oZ*%%!)%%0 ' (^cim2&%0 )^cin2&%0 *^cicgZXih2&*0 +[dg^ci^2%0^1cgZXih0^  ,gZXim ^&%!n!&%!*%0

If we want to make more of these rectangle groups, we will have to use the same code again, changing only the number of rectangles and their starting location, as shown in the code and Figure 1-28. -m2&%%0 .n2'%%0 &%^cicgZXih'2&'0

Chapter 1

N

Elements of the Language

&&[dg^ci^2%0^1cgZXih'0^  &'gZXim ^&%!n!&%!*%0 &( &)m2(%%0 &*n2'%%0 &+^cicgZXih(2&-0 &,[dg^ci^2%0^1cgZXih(0^  &-gZXim ^&%!n!&%!*%0

Figure 1-28: Three groups of rectangles

A simple observation of the code above shows a repetitive pattern where each group of rectangles is produced through the same code structure by altering only the number of rectangles and their starting location. The problem with this method of copying and pasting code is that it is specific, redundant, and repetitive. Further, it is limited to small repetitions. What if we need to produce the same pattern 1,000 times? The solution to this problem is the development of generic code that follows the same steps given different parameters (i.e. location and number of rectangles). The following code illustrates this point: &kd^YhiV^gh^cim!^cin!^cichiZehp '[dg^ci^2%0^1chiZeh0^  (gZXim ^&%!n!&%!*%0 )r

In line 1 we define a process (also called a procedure) which we call here hiV^gh. This name can be anything we want and should express the nature of procedure or its result. We then define the three parameters that are needed for the procedure (i.e. in this case the x and y starting location and the numbers of steps). These are enclosed in parentheses and are separated by commas. Note the word kd^Y at the

31

32

Chapter 1

N

Elements of the Language

beginning of the procedure’s name; this means that the procedure does not return anything, i.e. it returns “void.” The next paragraph covers this in more detail. Finally, we enclose the actual set of code lines that perform the procedure within curly brackets. The code itself is simply a generic version of the previous code and it uses the parameters that are passed through the procedure in line 1. Once we define a procedure, then we can call it by using the following code: &kd^YhZijep 'h^oZ*%%!)%%0 (hiV^gh&%!&%!&*0 )hiV^gh&%%!'%%!&(0 *hiV^gh(%%!'%%!&%0 +r

Lines 3, 4, and 5 make calls to the procedure defined earlier in lines 1 through 4. These calls are placed within the hZije section which is also a procedure and evident from the word kd^Y. In this way, the procedure hiV^gh and the procedure hZije are groups of code that reside within the same program. The result of this program is exactly the same as in Figure 1-28. Similarly, we can define a procedure that can perform a task and then returns a value. This type of procedure is also referred to as a function. For example, let’s say we want to create a method that can calculate the area of a rectangle given its two sides and return the result as a float. Here is how it can be done: [adVi\Zi6gZV[adVil![adVi]p ^cibnGZhjai2l]0 gZijgcbnGZhjai0 r

In the above example, we have declared a method called \Zi6gZV and we use two float numbers l and ] as parameters for the width and height of the rectangle. Within the method we define a variable called bnGZhjai, and we assign to it the result of the multiplication of the two parameters l and ]. The procedure then returns the result. To invoke the method from another part of the code we write: [adViV2\Zi6gZV(#*!'#+0

The method \Zi6gZV will do the calculation. This can be very useful in organizing code through statements and commands that call one another. For example, if you want the surface area of a sphere you can call: [adVihV2\ZiHjg[VXZ6gZV[adVig0

The method \ZiHjg[VXZ6gZV will do the math with or without your knowledge or supervision. Sometimes methods can be very complex such as bdge]dW_ZXi V!dW_ZXiW or very simple such as \Zi6gZV[adVil![adVi]).

Chapter 1

N

Elements of the Language

1.4.4 Recursion A recursion is a repetitive procedure in which part of the repetition involves a call to the procedure itself. In other words, the procedure is not only a group of code that serves an external-to-itself purpose, but it also involves its own existence in the grouping of the code. Let’s examine a simple case of recursion used to calculate a factorial of a number. Please recall that a factorial of a number is the product of all the positive integer numbers less or equal to itself. For example, the factorial of 5 is 120 which is the product 1*2*3*4*5. In the following two columns we show two procedures that calculate the factorial of a number using iteration (left) and recursion (right). &kd^YhZijep 'eg^ciac[VXidg^Va*0 (r )^ci[VXidg^Va^cicp *^ci[VXi2&0 +[dg^ci^2c0^32&0^""  ,[VXi2^0 -gZijgc[VXi0 .r

&kd^YhZijep 'eg^ci[VXidg^Va*0 (r )^ci[VXidg^Va^cicp *^[c12& +gZijgc&0 ,ZahZ -gZijgcc[VXidg^Vac"&0 .r

In the right column, we define a procedure called factorial which takes as a parameter an integer c. Then it examines c: if n is less or equal to 1 then it return 1; otherwise it returns the product of c with the result of the procedure itself passing the parameter c"&. This process is shown below for [VXidg^Va(: the first call to [VXidg^Va breaks into the product of 3 times [VXidg^Va'; then [VXidg^Va' breaks into 2 times [VXidg^Va&; then [VXidg^Va& returns &, which is then multiplied by 2, which is then multiplied by 3, resulting 6. 6=3*2

factorial(3){ return(3 * factorial(2)) }

2=2*1

factorial(2){ return(2 * factorial(1)) }

1

factorial(1) { return(1) }

Figure 1-29: The deployment of the recursive procedure factorial()

33

34

Chapter 1

N

Elements of the Language

Recursion can be used to produce graphical objects, as in the case of a series of nested circles constructed through the code shown below: &kd^YhZijep 'GZX8^gXaZ-%0 (r )^ciGZX8^gXaZ^cigp *Zaa^ehZ*%!*%!g!g0 +^[g12&% ,gZijgc&%0 -ZahZ .gZijgcgGZX8^gXaZg"&%0 &%r

This algorithm will produce the following result:

Figure 1-30: Recursion used to place nested concentric circles

1.4.5 Importing Processing Classes A number of sets of procedures (also known as classes) have already been developed within the Processing language or are provided by software development companies. These classes are inside compressed files called packages. For example, egdXZhh^c\#cZi# is a package that includes classes related to network communication (the  stands for “all files under the directory processing/net”). In Processing, these packages are located in the directory where Processing exists, that is, wherever its language was installed. To use those packages, we need to include them in the code and that is done through the statement ^bedgiegdXZhh^c\#cZi#0

which should always be the first line of the Processing file. So when we import, for example, egdXZhh^c\#cZi# we can include any class that exists in that package (i.e. Server) or the methods under those packages (i.e. gZVY, lg^iZ, etc.).

Chapter 1

N

Elements of the Language

Summary This chapter introduced you to data types, arithmetic and logical operations, loops, arrays, methods, and classes. At this point you should know how constants and variables are declared, how conditional statements are made, how to loop with a counter and use it within the loop, what arrays are and how we declare, fill, and access their members, what are procedures and how they are called, and finally how recursions are formed. We also used these concepts to draw simple shapes on the screen and then explained the mechanisms of generating simple drawings in Processing.

Exercises NOTE Answers to the exercises are provided in Appendix B. 1. Memorize the symbols/types and their meaning: boolean

for

>=

%

int

(

$&-%#m0 +^ci\gZZc2^ci'**#h^cE>$&-%#n0 ,^ciWajZ2%0 .gZY2VWhgZY'**0 &%\gZZc2VWh\gZZc'**0 &&WajZ2VWhWajZ'**0 &' &(higd`ZgZY!\gZZc!WajZ0 &)gZXim!n!&!&0 &*r &+r

Figure 2-10: A color scheme as an output of an algorithm

The image shows the color behavior of the combinations of sine and cosine of the x and y coordinates. Blue is absent from the image, since we always assign it 0. Now, if we involve blue in the picture by multiplying red and green, as in the following code, we get the interesting result shown in Figure 2-11. ^cigZY2^ci'**#XdhE>$&-%#m0 ^ci\gZZc2^ci'**#h^cE>$&-%#n0 ^ciWajZ2gZY\gZZc0

Figure 2-11: A color scheme as an output of a constraint-based algorithm

We can “carve out” the preceding pattern, as shown in Figure 2-12, by setting conditions in the code: for instance, any value above a certain color level could be omitted (thus, setting a threshold): h^oZ(+%!&-%0 [dg^cim2%0m1(+%0m

p

Chapter 2 [dg^cin2%0n1(+%0n

N

Points, Lines, and Shapes

p

^cigZY2^ci'**#XdhE>$&-%#m0 ^ci\gZZc2^ci'**#h^cE>$&-%#n0 ^ciWajZ2gZY\gZZc0 gZY2VWhgZY'**0 \gZZc2VWh\gZZc'**0 WajZ2VWhWajZ'**0 ^[WajZ1&'- gZY2\gZZc2WajZ2%0 higd`ZgZY!\gZZc!WajZ0 gZXin!m!&!&0 r r

Figure 2-12: A color scheme as an output of a constraint-based algorithm

2.4 Polygons A polygon as defined in the Processing language is a series of vertices that are connected with lines. The series of vertices are initiated by using the WZ\^cH]VeZEDANcejiHZ\bZcih and an array in which to store the input segments ^cejiHZ\bZcih. These variables then assign their values to the class’s variables called cjbHZ\bZcih and hZ\h. In particular, the array hZ\h needs to be initialized, to allocate memory for it, through the statement: hZ\h2cZlBnHZ\bZciPcjbHZ\bZcihR0

The bdkZ and eadi methods simply invoke the methods of their constituent class’s one level below, that is, hZ\hP^R#bdkZmd[[!nd[[0. Specifically, the hierarchical structure of these three newly introduced classes works as follows: when a method is called at the top, that method calls its corresponding method of the class one level below, and so on, all the way to the bottom classes. For example, a call to h]VeZ#bdkZm!n will call the BnHZ\bZci’s method bdkZ, which, in turn, will call the BnEd^ci’s method bdkZ, which will do the actual movement. Following is the main code (MyProject): &BnEd^cie&!e'!e(!e)0$$YZ[^cZ[djged^cih 'BnHZ\bZciPRhZ\bZci2cZlBnHZ\bZciP'R0$$YZ[^cZildhZ\bZcih (BnH]VeZh]VeZ0$$YZ[^cZVh]VeZ ) *$$^c^i^Va^oZkVg^VWaZh +kd^YhZijep , -e&2cZlBnEd^ci&%#!&%#0$$bV`ZVed^ci .e'2cZlBnEd^ci'%#!'%#0$$bV`ZVed^ci &%e(2cZlBnEd^ci'%#!'%#0$$bV`ZVed^ci &&e)2cZlBnEd^ci(%#!&%#0$$bV`ZVed^ci &' &(hZ\bZciP%R2cZlBnHZ\bZcie&!e'0$$bV`ZVhZ\bZci &)hZ\bZciP&R2cZlBnHZ\bZcie(!e)0$$bV`ZVhZ\bZci &*

Chapter 3

N

The Structure of Shapes

&+h]VeZ2cZlBnH]VeZ'!hZ\bZci0$$bV`ZVh]VeZ &, &-h]VeZ#bdkZ(%#!(*#0$$bdkZi]Zh]VeZVi(%#%!(*#% &.h]VeZ#eadi0$$YgVli]Zh]VeZ '% '&r

First, we declare four points e&, e', e(, and e); a two-segment segment (actually, one array with two positions); and a shape. In the hZije method, we create all the objects: first, we create four points with fixed (a.k.a. “hard-coded”) values, then we fill the two array positions, creating two segments, and finally we create a shape that needs the number of segments, that is, 2, and the array containing the segments. Once these objects are created, we call the bdkZ and eadi methods of the BnH]VeZ class to move and plot. Indeed, in the eadi method, all we do is to make one reference the shape class. Here is what is happening: h]VeZ#bdkZ(%#!(*#0

calls the bdkZ method of BnH]VeZ. That invokes the method: kd^YbdkZ[adVimd[[![adVind[[p

which, in turn, loops and invokes the bdkZ method of the BnHZ\bZci class, [dg^ci^2%0^1cjbHZ\bZcih0^ hZ\hP^R#bdkZmd[[!nd[[0



which, in turn, invokes twice the bdkZ method of the BnEd^ci class, kd^YbdkZ[adVimd[[![adVind[[p hiVgi#bdkZmd[[!nd[[0 ZcY#bdkZmd[[!nd[[0 r

which in turn assigns the moved offsets to the m and n members of the BnEd^ci class: kd^YbdkZ[adVimd[[![adVind[[p m2m md[[0 n2n nd[[0 r

The propagation of action from the shape’s moving methods to the segments’ moving methods down to the points’ moving methods is illustrated in Figure 3-5 with a sequence of arrows.

73

74

Chapter 3

N

The Structure of Shapes

shape.move(30.; 35.); //********** Move (in MyShape) void move(float xoff, float yoff){ for (int i=0; i$cjbHZ\bZcih0 $$XgZViZilded^cihidhidgZi]ZhZ\bZcied^cih BnEd^cie2cZlBnEd^ci%#!%#0 BnEd^ciecZmi2cZlBnEd^ci%#!%#0 $$addeidVhh^\ckVajZhidi]Zed^cih [dg^ci^2%0^1cjbHZ\bZcih0^ p e#m2md[[ gVY^jhh^cVc\aZ^0 e#n2nd[[ gVY^jhXdhVc\aZ^0 ecZmi#m2md[[ gVY^jhh^cVc\aZ^ &0 ecZmi#n2nd[[ gVY^jhXdhVc\aZ^ &0 hZ\hP^R2cZlBnHZ\bZcie!ecZmi0 r r

This constructor can coexist in the same class BnH]VeZ . It will be distinguished because of the different number and/or sequence of its parameters;

81

82

Chapter 3

N

The Structure of Shapes

the older constructor had only two parameters; this one has four. In this new constructor, the first thing we need to do is to assign the number of sides and to allocate memory for the hZ\hPR array: cjbHZ\bZcih2cjbH^YZh0 hZ\h2cZlBnHZ\bZciPcjbHZ\bZcihR0

Then, we divide the full circle into sections: [adViVc\aZ2'BVi]#E>$cjbHZ\bZcih0

Then we create two points, e and ecZmi, where we will put the two points necessary to create each segment. We initialize them to 0. Then we loop and compute the points around the circle and for each one we compute the one ahead; we need them in order to create the segments. [dg^ci^2%0^1cjbHZ\bZcih0^ p e#m2md[[ gVY^jhh^cVc\aZ^0 e#n2nd[[ gVY^jhXdhVc\aZ^0 ecZmi#m2md[[ gVY^jhh^cVc\aZ^ &0 ecZmi#n2nd[[ gVY^jhXdhVc\aZ^ &0 hZ\hP^R2cZlBnHZ\bZcie!ecZmi0 r

Once we compute the two points, e and ecZmi, we pass them to the BnHZ\bZci, which constructs a segment, which is then assigned to the array hZ\hPR, one at a time: hZ\hP^R2cZlBnHZ\bZcie!ecZmi0

All we need to do now is to call the creation of a 20t20 grid of pentagons in the main code: &BnH]VeZPRh]VeZ2cZlBnH]VeZP&'&'R0 ' ( )kd^YhZijep *h^oZ(*%!(*%0$$bV`Zi]ZhXgZZcW^\Zcdj\]idhZZ +[dg^cin2%0n1&'0n p$$[dg&'hiZeh^cn ,[dg^cim2%0m1&'0m p$$[dg&'hiZeh^cm -$$bV`ZVh]VeZXVaa^c\i]Zedan\dcXdchigjXidg .h]VeZPn&' mR2cZlBnH]VeZ*!&%#!m'%#!n'%#0 &%h]VeZPn&' mR#bdkZ&%#m!&%#n0 &&r &'r &( &)r &* &+

Chapter 3

N

The Structure of Shapes

&,kd^YYgVlp &&.[dg^cin2%0n1&'0n p$$[dg&'hiZeh^cn '%[dg^cim2%0m1&'0m p$$[dg&'hiZeh^cm '&h]VeZPn&' mR#eadi0$$eadii]Zh]VeZh ''r '(r ') '*r

Take a note that the expression n&' m is a way of counting from 0 to 144 (i.e., 12*12), using the two counters m and n. The result is shown in Figure 3-8.

Figure 3-8: A grid of shapes

Once we have an array of shapes, we can then create a group-type class, which we will call BniZbA^hiZcZgcZl>iZbA^hiZcZgp (+ejWa^Xkd^Y^iZbHiViZ8]Vc\ZY>iZb:kZciZp (,hiVijh2igVch[dgb#\Zi>iZbigVch[dgb#\ZiHZaZXiZY>cYZm0 (-Xdcigda#^ceji#hZiIZmihiVijh0rr0 (.WZm^i#VYY6Xi^dcA^hiZcZgcZl6Xi^dcA^hiZcZgp )%ejWa^Xkd^YVXi^dcEZg[dgbZY6Xi^dc:kZciZp )&Zm^i0 )'rr0 )(^ceji#VYY6Xi^dcA^hiZcZgcZl6Xi^dcA^hiZcZgp ))ejWa^Xkd^YVXi^dcEZg[dgbZY6Xi^dc:kZciZp )*eg^ciac¹iZmi[^ZaY2¹ ^ceji#\ZiIZmi0 )+rr0 ),r )-r

Chapter 4

N

Basics of Graphical User Interfaces

).Bn8dcigdaXdcigda0 *%kd^YhZijep *&h^oZ)%%!(%%0 *'WVX`\gdjcY'%%0 *(Xdcigda2cZlBn8dcigda0 *)r **kd^YYgVlp *+Xdcigda#XddgYh9^heaVn#hZiIZmi¹m2¹ bdjhZM  ¹n2¹ bdjhZN0 *,r

First, we define four objects: a 7jiidc, a 8]d^XZ, a AVWZa, and a IZmi;^ZaY. Each one is initialized using its corresponding constructor and then we set a location and a size to be displayed. This is done by canceling the automatic placement of objects in the scene with command hZiAVndjicjaa in line 29. The 8]d^XZ object can invoke its selection by using the \Zi>iZb, which returns the string label of the selected choice, using \ZiHZaZXiZY>cYZm, which returns the number of the choice. The button “Exit” will execute the Zm^i command, which will terminate the session (line 41). The IZmi;^ZaY object will return any text typed by the user (after a return carriage is typed). Finally, within YgVl in line 56 there is a method connected with the Bn8dcigda object XddgYh9h^eaVn, and it is used here to display the location of the mouse: Xdcigda#XddgYh9^heaVn#hZiIZmi¹m2¹ bdjhZM ¹n2¹ bdjhZN0

The resulting GUI is shown Figure 4-4.

Figure 4-4: A Button, two Labels, a TextField, and a Choice object

If the new Bn8dcigda class is replaced in the main code in section 4.2, we are faced with a new (and functional) interface that will look like Figure 4-5.

101

102

Chapter 4

N

Basics of Graphical User Interfaces

Figure 4-5: The new GUI in the old code

4.4 Selecting Points, Segments, Shapes, or Groups In the code introduced in the previous chapter, we have been able to select shapes and move, rotate, or scale them. As a reminder, here is the part of the code that selects shapes: kd^YbdjhZEgZhhZYp m[^ghi2bdjhZM0$$gZbZbWZgi]^hed^ci n[^ghi2bdjhZN0 $$E^X`Vh]VeZ [dg^ci^2%0^1\gdje#cjbH]VeZh0^  ^[\gdje#h]VeZhP^R#hZaZXi[adVim![adVin!&%#22igjZ Xdcigda#^ceji#hZiIZmi¹HZaZXiZY2¹ ^0 r

Since we have written our whole project in a point-segment-shape-group class hierarchy, it should be easy for us now to select any object at any level of that hierarchy. All we need to do is go through the levels and extract the classes that we want. So, for example, if we wanted to select a segment in the preceding code, we need to write: $$E^X`VHZ\bZci [dg^ci^2%0^1\gdje#cjbH]VeZh0^



Chapter 4

N

Basics of Graphical User Interfaces

[dg^ci_2%0_1\gdje#h]VeZhP^R#cjbHZ\bZcih0_  ^[\gdje#h]VeZhP^R#hZ\hP_R#hZaZXi[adVibdjhZM! [adVibdjhZN!&%#22igjZ Xdcigda#^ceji#hZiIZmi¹Ndj\diHZ\bZci2º _ ¹d[h]VeZ2º ^0

As you see, we use the dot operator to point to a subclass of a class. For example, \gdje#h]VeZhP^R#hZ\hP_R#hZaZXi will address the select method of the hZ\h object under the h]VeZh object under the \gdje object. So, to select a point we use the following code: $$E^X`VEd^ci [dg^ci^2%0^1\gdje#cjbH]VeZh0^  [dg^ci_2%0_1\gdje#h]VeZhP^R#cjbHZ\bZcih0_  ^[\gdje#h]VeZhP^R#hZ\hP_R#hiVgi#hZaZXi[adVibdjhZM! [adVibdjhZN!&%#22igjZ Xdcigda#^ceji#hZiIZmi¹Ndj\diEd^ci2º _ ¹d[h]VeZ2º ^0

The same applies to moving or rotating a point or a segment. By arranging the graphical user interface, we can break down all the possible combinations of move/rotate/scale operations for any group/shape/segment/point to allow the user to interact in all possible ways. The GUI for this would be: $$8]d^XZhZije igVch[dgb2cZl8]d^XZ0 igVch[dgb#VYY>iZb¹BdkZº0 igVch[dgb#VYY>iZb¹GdiViZº0 igVch[dgb#VYY>iZb¹HXVaZº0 l]ViEVgi2cZl8]d^XZ0 l]ViEVgi#VYY>iZb¹HZaZXiEd^ciº0 l]ViEVgi#VYY>iZb¹HZaZXiHZ\bZciº0 l]ViEVgi#VYY>iZb¹HZaZXiH]VeZº0 l]ViEVgi#VYY>iZb¹HZaZXibV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0

where the only parameter needed is the path location of the image. If the image is called memorial.jpg and it is in the data directory of the Processing Sketch folder, then you would type it in the form of a string, that is, ¹bZbdg^Va#_e\º. Otherwise, you would give the full path, that is, ¹8/$^bV\Zh$bZbdg^Va#_e\º (use forward slashes). The following code demonstrates how to read an image and then display it: &E>bV\Zbn>bV\Z0$$YZ[^cZVE>bV\ZdW_ZXi 'bn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVYVc^bV\Z (h^oZbn>bV\Z#l^Yi]!bn>bV\Z#]Z^\]i0$$h^oZi]Zl^cYdlidi]ZlVcY]  $$dgi]Z^bV\Z )^bV\Zbn>bV\Z!%!%0$$Y^heaVni]Z^bV\ZVi%!%d[[hZi[gdb $$i]Zl^cYdl¼hjeeZgaZ[iXdgcZg *hVkZ¹Xdend[bZbdg^Va#_e\º0$$hVkZi]Z^bV\ZVhV[^aZXden[dgcdl

The output is shown in Figure 5-1.

Figure 5-1: An image

Chapter 5

N

Image Processing

5.2 Preset Image Filters Processing offers a series of preset filters that can be applied to any image. The command [^aiZg applies a filter to an image using the following syntax: [^aiZgBD9:0or[^aiZgBD9:!aZkZa0

where BD9: is one of the following: N

I=G:H=DA9: Converts the image to black or white pixels, depending on whether they are above or below the threshold defined by the aZkZa parameter. The level must be between %#% (black) and &#% (white). If no level is specified, %#* is used.

N

CK:GI: Sets each pixel to its inverse value.

N

EDHI:G>O: : Limits each channel of the image to the number of colors

specified as the level parameter. N

N

7AJG: Executes a Gaussian blur with the aZkZa parameter specifying the extent of the blurring. If no aZkZa parameter is used, the blur is equivalent to Gaussian blur of radius 1. DE6FJ:: Sets the alpha channel to entirely opaque.

The following code demonstrates how to display images to which filters are applied: &E>bV\Zbn>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi 'bn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVY^i (h^oZbn>bV\Z#l^Yi]!bn>bV\Z#]Z^\]i0$$h^oZ^iid[^ii]Zl^cYdl )^bV\Zbn>bV\Z!%!%0$$Y^heaVni]Z^bV\Z * +^ci[^aiZg2&0$$X]ddhZV[^aiZg , -hl^iX][^aiZgp .XVhZ&/ &%[^aiZgI=G:H=DA9!#+0$$ZkZgne^mZaWZadl#+WZXdbZhWaVX` &&WgZV`0 &'XVhZ'/ &([^aiZgCK:GI0$$Vaae^mZah\Zii]Zdeedh^iZkVajZd[i]Z^gg\W &,WgZV`0$$^#Z#'**"g &-XVhZ)/ &.[^aiZgEDHI:G>O:!'0$$a^b^ihZVX]X]VccZad[i]Z^bV\Zid' '%WgZV`0$$Xdadgh '&XVhZ*/ ''[^aiZg7AJG!&0$$ZmZXjiZhVbV\Zbn>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi 'bn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVY^i (h^oZbn>bV\Z#l^Yi]!bn>bV\Z#]Z^\]i0$$h^oZ^iid[^ii]Zl^cYdl )^bV\Zbn>bV\Z!%!%0$$Y^heaVni]Z^bV\Z * +[dg^cin2%0n1bn>bV\Z#]Z^\]i0n $$[dgVaae^mZah^cn ,[dg^cim2%0m1bn>bV\Z#l^Yi]0m p$$[dgVaae^mZah^cm -XdadgbnE^mZa2\Zim!n0$$\ZiVe^mZa¼hXdadg .^ciV2^ciVae]VbnE^mZa0$$ZmigVXii]ZVae]VkVajZ &%^cig2^cigZYbnE^mZa0$$ZmigVXii]ZgZYkVajZ &&^ci\2^ci\gZZcbnE^mZa0$$ZmigVXii]Z\gZZckVajZ &'^ciW2^ciWajZbnE^mZa0$$ZmigVXii]ZWajZkVajZ &(Xdadg^ckZghZ2Xdadg'**"V!'**"g!'**"\!'**"W0 $$bV`ZVXdadgWn^ckZgi^c\'**"kVajZ &)hZim!n!^ckZghZ0$$hZii]Ze^mZa¼hXdadg^ci]Z^bV\Z &*r &+hVkZ¹bZbdg^VaT^ckZgiZY#_e\º0$$hVkZi]Z^bV\ZVhV[^aZ

Lines 6 and 7 loop through all pixels in the image in both y and x directions to extract the color value of every pixel (line 8). We use the \Zi method, which takes the x and y coordinate of a pixel and returns its color. Next, in lines 9 through 12, we extract the alpha, red, green, and blue values of the pixel’s color. Then we compose a new color by adding four channels using the hZi command for alpha, red, green, and blue, except that we reverse their values by subtracting them from the maximum value of a byte, that is, 255. The result can be seen to the left in Figure 5-3. While the filters provided by Processing are adequate for simple, basic image processing, this does not allow experimentation beyond that simple level. In contrast, the \Zi and hZi operations can be used to produce interesting filters that can be used in many creative ways. For example, the following code builds upon the existing grayscale filter provided by Processing and further extracts edges by marking the difference between consecutive neighboring pixels: &E>bV\Zbn>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi 'bn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVY^i (h^oZbn>bV\Z#l^Yi]!bn>bV\Z#]Z^\]i0$$h^oZ^iid[^ii]Zl^cYdl )^bV\Zbn>bV\Z!%!%0$$Y^heaVni]Z^bV\Z * +$$XdckZgii]Z^bV\Zid\gVnhXVaZ ,[^aiZgbV\Z#]Z^\]i"&0n $$[dgVaae^mZah^cn &([dg^cim2%0m1bn>bV\Z#l^Yi]"&0m p$$[dgVaae^mZah^cm &)Xdadgi]^hE^mZa2\Zim!n0$$\ZiVe^mZa¼hXdadg &*XdadgcZmiE^mZa2\Zim &!n0$$\Zii]ZcZmie^mZa¼hXdadg &+^cigV2^cigZYi]^hE^mZa0$$ZmigVXii]ZgZYkVajZ &,^cigW2^cigZYcZmiE^mZa0$$ZmigVXii]ZgZYd[i]ZcZmi &-^[VWhgV"gW3+$$^[i]ZnVgZY^[[ZgZci &.hZim!n!WaVX`0$$hZii]Ze^mZa¼hXdadgWaVX` '%ZahZ '&hZim!n!l]^iZ0$$ZahZidl]^iZ ''r '(hVkZ¹bZbdg^VaTZY\Z#_e\º0$$hVkZi]Z^bV\ZVhV[^aZ

After loading the image, we filter it so that it becomes gray by using Processing’s filter. Then we extract every pixel’s color from the image, using \Zim!n, and also the next pixel, using \Zim &!n . We then extract the red part of both neighboring pixels and compare their values. If the difference is more than 6, then we set the current pixel to black; otherwise, to white. The result can be seen to the right in Figure 5-3.

Figure 5-3: An inverted image (left) and an image that contains only the high differential points in the x direction (right)

Instead of changing the color value of a pixel, it may be possible to change its location within an image. This can be done by coloring one pixel with the color of another pixel. The following code demonstrates this displacement operation, which results in a fairly interesting impression: &E>bV\ZBn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0 'h^oZBn>bV\Z#l^Yi]!Bn>bV\Z#]Z^\]i0 (^bV\ZBn>bV\Z!%!%0 )

Chapter 5

N

Image Processing

*[dg^cim2'0m1l^Yi]"'0m $$[dgVaagdlh +[dg^cin2'0n1]Z^\]i"'0n p$$[dgVaaXdajbch ,XdadgX2\Zim!n0 -$$bV`ZhjgZi]ZkVajZh[VaaWZilZZc%"'** .^cimm2m ^cigVcYdb"(!(0 &%^cinn2n ^cigVcYdb"(!(0 &&hZimm!nn!X0$$Xdadgi]Ze^mZa &'[^aaX0 &(cdHigd`Z0 &)gZXimm"*!nn"*!)!)0 &*r

After extracting the color of a pixel (line 7), we create two random numbers and add them the values x and y. This displaced location is then used to draw a 4 × 4 rectangle at that location. The result of this operation is shown in Figure 5-4.

Original image

Displaced image

Figure 5-4: The original image (left) and a displaced pixel image (right)

While the preceding code is still quite simple and straightforward, it is also slow in execution. This is because the hZi, \Zi, ^ci, Vae]V, gZY, \gZZc, and WajZ methods add an extra overhead to the overall number of computations for all pixels in the image. In order to optimize the \Zi, hZi, and color extractions for every pixel, we will use bit-level manipulations, which are demonstrated in the following section.

5.3 Bit Manipulation on Pixels The value of a pixel is represented in Processing (and Java) as an integer. In that sense, an image is an array of integers. An integer is composed of 32 bits or 4 bytes. So Processing uses those 4 bytes to store information about the pixel’s

115

116

Chapter 5

N

Image Processing

color. Specifically, the first byte (i.e., eight bits) are for the degree of transparency (also known as alpha channel), the second byte for red, the third byte for green, and the fourth byte for blue. Schematically, the bits of an integer, representing a pixel, look like Figure 5-5.

Figure 5-5: The bits of an integer representing a pixel.

To get access to a color, we need to do manipulation at the bit level to extract the proper 8 bits. This is done through bit-manipulation methods provided by Processing. In brief, the process is shown below. Suppose that we have a pixel called myPixel. ^cibnE^mZa0 ^ciVae]V2bnE^mZa%m[[%%%%%%33')0 ^cigZY2bnE^mZa%m[[%%%%33&+0 ^ci\gZZc2bnE^mZa%m[[%%33-0 ^ciWajZ2bnE^mZa%m[[0

The variables alpha, red, green, and blue contain the corresponding values for that pixel. To get the value of red, we AND (using the symbol ) with the hexadecimal number dm[[%%%%, and then we shift the bits (using the symbol 33) by 16 positions. This will return only the second group of 8 bits that holds the value of red. So, for example, the color red is represented as: %%%%%%%%&&&&&&&&%%%%%%%%%%%%%%%%

In this bit sequence above, the first 8 bits are the alpha channel (i.e., transparency), the next 8 bits are the color red, and the rest of the bits are for green and blue. Now, we want to determine which bits are set to 1 in order to determine what color this sequence of bits represents. We are not interested in what decimal integer this is (which happens to be 16,711,680 or 223+222+221+220+219+218+217+216). To extract the value of a byte, we use the bit-wise operations 33 and 11 to shift bits right or left, respectively. For example, to extract the value of red from the above set of bits, we shift the bits by 16 positions right and then add the binary set: %%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&

or, in hexadecimal format %m;;, to clean up any 1’s that may exist in the first 24 to 8 bit range. So, for example, if we are given the color represented as: %%&&%&&%%%&%&&&%&%%&%&%%%%&%&&&&

Chapter 5

N

Image Processing

and we want to find the amount of red, we first shift the bits by 16 positions: %%%%%%%%%%%%%%%%%%&&%&&%%%&%&&&%

and then we add %m;;: %%%%%%%%%%%%%%%%%%&&%&&%%%&%&&&% %%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&& %%%%%%%%%%%%%%%%%%%%%%%%%%&%&&&%

Notice that in the  operator &&2&, &%2%, %&2%, and %%2%. So, the alpha byte becomes zero, and the red byte remains as is. The result of the operation yields an integer that is the value of red (i.e., in this case, it is 46). In the following example, a filter is applied to an image using bit-wise operations: &E>bV\Zbn>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi 'bn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVY^i (h^oZbn>bV\Z#l^Yi]!bn>bV\Z#]Z^\]i0$$h^oZ^iid[^ii]Zl^cYdl )^bV\Zbn>bV\Z!%!%0$$Y^heaVni]Z^bV\Z * +adVYE^mZah0$$\ZiVXXZhhidi]ZVggVnd[e^mZahPR , -[dg^ci^cYZm2%0^cYZm1l^Yi]]Z^\]i0^cYZm  .p &%^cibnE^mZa2e^mZahP^cYZmR0$$\ZiVe^mZakVajZ &&^cig2bnE^mZa33&+%m;;0$$\ZigZYbnE^mZa &'^ci\2bnE^mZa33-%m;;0$$\Zi\gZZcbnE^mZa &(^ciW2bnE^mZa%m;;0$$\ZiWajZbnE^mZa &)^ciVk2\ W$'0$$VkZgV\Zdcan\gZZcVcYWajZ &*^[Vk3&'-p$$Z#\#^[Vk^h%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&& &+g2Vk11&+0$$7^cVgn/%%%%%%%%&&&&&&&&%%%%%%%%%%%%%%%% &,\2Vk11-0$$7^cVgn/%%%%%%%%%%%%%%%%&&&&&&&&%%%%%%%% &-W2Vk0 $$7^cVgn/%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&& &.e^mZahP^cYZmR2gq\qW0$$XdbedhZVXdadgjh^c\W^il^hZDG '%r '&r '' '(jeYViZE^mZah0$$hZZi]ZgZhjai ') '*hVkZ¹bZbdg^VaTVaiZgZY#_e\º0$$hVkZi]Z^bV\ZVhV[^aZ

In line 6, the command adVYE^mZah loads the pixels in an array called e^mZahPR. Each pixel is then extracted by looping sequentially (line 10) through the number of pixels of the image (i.e., width*height). Each pixel is an integer called bnE^mZa. In lines 11, 12, and 13 the red, green, and blue values of each pixel is extracted using the right shift bit operation (see the previous paragraphs). Once the RGB values are extracted, they are manipulated as integers (in this case, we average the green and blue values). Then, based on whether the average

117

118

Chapter 5

N

Image Processing

is above 128 or not, we compose an integer out of the RGB values: using Vk we shift its last 8 bits by 16 positions left to populate the red byte. Then we shift its last 8 bits by 8 positions left to populate the green byte. The blue byte occupies the last part of the integer, so it is left intact. Then we use the bit operation OR to compose the color that we put back into the e^mZahPR array. After completing these operations for all pixels, we update the screen with the new values placed in the e^mZahPR array. The result of this process is shown in Figure 5-6.

Figure 5-6: A custom-made “average-green-and-blue-over-128” filter

Image manipulation is a powerful tool. It allows us, as humans, to see and interpret the images further. However, for the computer, an image is simply a long array of numbers. So we, as human beings, need to create algorithms that take advantage of the computational power of the machine and allow us to explore images beyond what we can see with our eyes.

5.4 A Paint Brush Tool One common problem with images is that even though they are viewed by human beings as two-dimensional grids, for a computer the pixel information is stored in a one-dimensional array. In other words, Processing provides us with a one-dimensional array (i.e., e^mZahPR) that corresponds to a two-dimensional image. So we need to go from two to one and from one to two dimensions (see Figure 5-7). To address this problem, we use the following technique that allows us to extract the index of the one-dimensional array e^mZahPR from two counters m and n: [dg^cin2%0n1]Z^\]i0n  [dg^cim2%0m1l^Yi]0m  ^cibnE^mZa2e^mZahPnl^Yi] mR0

Chapter 5

N

Image Processing

Figure 5-7: Mapping of a two-dimensional array to a one-dimensional one

In the next section, we will create a mouse-based user interaction with the pixels in the screen in the form of a simple paint brush. Here, the paint brush is a 20 × 20 pixel square that will be updated as the mouse is dragged around the image and the one-dimensional array e^mZahPR is also updated. To add interaction to an image, we incorporate the image filtering in the bdjhZ9gV\\ZY method: &E>bV\Zbn>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi ' (kd^YhZijep )bn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVY^i *h^oZbn>bV\Z#l^Yi]!bn>bV\Z#]Z^\]i0$$h^oZ^iid[^ii]Zl^cYdl +^bV\Zbn>bV\Z!%!%0$$Y^heaVni]Z^bV\Z ,adVYE^mZah0$$adVYi]Ze^mZah -r .$$ &%kd^YYgVlp &&r &'$$YgV\idh^bjaViZVeV^ciWgjh] &(kd^YbdjhZ9gV\\ZYp &)[dg^cin2bdjhZN"&%0n1bdjhZN &%0n $$[dgV'%m'%Wgjh]VgZV &*[dg^cim2bdjhZM"&%0m1bdjhZM &%0m p &+^cimm2XdchigV^cm!%!l^Yi]"&0$$YdcdiZmXZZYi]ZhXgZZc &,^cinn2XdchigV^cn!%!]Z^\]i"&0 &-e^mZahPnnl^Yi] mmR2e^mZahPnnl^Yi] mmRS%m%%%%;;0 &.r$$^ckZgiWajZ '%jeYViZE^mZah0 $$jeYViZidhZZi]ZX]Vc\Zh '&r ''$$HVkZ_jhi^cXVhZ^i^hcZZYZY '(kd^Y`ZnEgZhhZYp ')hVkZ¹bZbdg^VaT^ckZgiZY#_e\º0 '*r

After defining, loading, and displaying an image, we use the adVYE^mZah command to populate the e^mZahPR array. The e^mZahPR array is the default system array that holds the colors of all pixels of an image. In the bdjhZ9gV\\ZY

119

120

Chapter 5

N

Image Processing

section, we loop within a 20 × 20 area (i.e., the area of the virtual paint brush). This is done by using the bdjhZM and bdjhZN coordinates and looping 10 pixels around it. The XdchigV^c command makes sure that the mouse does not try to draw outside the canvas window. Next, we use the 2D to 1D conversion formula discussed earlier to extract the value of each pixel. This value is inverted at the blue byte and then assigned back to the image (line 18). After updating the image, we can see the effect of a brush that inverts the pixels in a 20 × 20 area. The result is shown to the left in Figure 5.8. The “pixelating” effect occurs because we are reversing the pixels over and over within the same area. As the mouse is dragged, the 20 × 20 area is inverted, but as the mouse moves by one pixel the same pixel is inverted back to its original color. To avoid this situation, we need to make a copy of the original image and use it to extract colors but not write to it. In the following code this problem is addressed: &E>bV\Zbn>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi 'E>bV\ZXe>bV\Z0$$YZ[^cZVXden^bV\Z ( )kd^YhZijep *bn>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVY^i +Xe>bV\Z2adVY>bV\Z¹bZbdg^Va#_e\º0$$adVYi]ZXden ,h^oZbn>bV\Z#l^Yi]!bn>bV\Z#]Z^\]i0$$h^oZ^iid[^ii]Zl^cYdl -^bV\Zbn>bV\Z!%!%0$$Y^heaVni]Z^bV\Z .adVYE^mZah0$$adVYi]Ze^mZah &%r &&$$ &'kd^YYgVlp &(r &)$$YgV\idh^bjaViZVeV^ciWgjh] &*kd^YbdjhZ9gV\\ZYp &+[dg^cin2bdjhZN"&%0n1bdjhZN &%0n $$[dgV&%m&%Wgjh]VgZV &,[dg^cim2bdjhZM"&%0m1bdjhZM &%0m p &-^cimm2XdchigV^cm!%!l^Yi]"&0$$YdcdiZmXZZYi]ZhXgZZc &.^cinn2XdchigV^cn!%!]Z^\]i"&0 '%$$gZVY[gdbi]ZXdenVcYjeYViZi]Z^bV\Z '&e^mZahPnnl^Yi] mmR2Xe>bV\Z#e^mZahPnnl^Yi] mmRS%m%%%%;;0 $$^ckZgiWajZ ''r '($$Xdeni]Zild^bV\Zh ')bn>bV\Z#XdenXe>bV\Z!%!%!l^Yi]!]Z^\]i!%!%!l^Yi]!]Z^\]i0 '*jeYViZE^mZah0$$jeYViZidhZZi]ZX]Vc\Zh '+r

In line 2 we define an image (Xe>bV\Z) that will be the copy of the original image (bn>bV\Z). This is loaded in the same way as the original. The difference

Chapter 5

N

Image Processing

from the previous paint brush code is in line 21; we read the pixel value of the copy image but update the original: e^mZahPnnl^Yi] mmR2Xe>bV\Z#e^mZahPnnl^Yi] mmRS%m%%%%;;0 $$^ckZgiWajZ

When finished with the 20 × 20 pixels, we copy one image into the other in order to update the changes: bn>bV\Z#XdenXe>bV\Z!%!%!l^Yi]!]Z^\]i!%!%!l^Yi]!]Z^\]i0

The code that demonstrates this technique is shown above, and the effect is captured to the right in Figure 5-8.

Figure 5-8: Inverting the pixels, using a 20 × 20 paint brush

5.5 Edge Detection An important part of image processing is the quantitative measurement of pixels to determine certain characteristics of the depicted object. In satellite image analysis, counting pixels can help determine amounts, ratios, or comparisons between various areas within an image or across images. One of them is edge detection. Edge detection is a method of finding pixels that have a high differential value in brightness value compared to their neighboring pixels. In other words, we compare neighboring pixels one by one and mark only the ones that have a subtraction difference that exceeds a certain threshold. The following code demonstrates how to detect edges in an image: &^ciPRmY2p%!&!&!&!%!"&!"&!"&!%r0$$cZ^\]Wdgh¼m^cYZmXlide '^ciPRnY2p&!&!%!"&!"&!"&!%!&!&r0$$cZ^\]Wdgh¼n^cYZmXlide (E>bV\ZBn>bV\Z2adVY>bV\Z¹hidX`]dab#_e\º0$$adVYVc^bV\Z

121

122

Chapter 5

N

Image Processing

)h^oZBn>bV\Z#l^Yi]!Bn>bV\Z#]Z^\]i0$$h^oZidbViX]i]Z^bV\Z *^bV\ZBn>bV\Z!%!%0$$Y^heaVni]Z^bV\Z +^ciPRPRBn8den2cZl^ciPl^Yi]RP]Z^\]iR0$$VggVnZfjVaid^bV\Z ,[dg^cim2&0m1l^Yi]"&0m $$[dgVaae^mZahZmXZeiWdgYZg -[dg^cin2&0n1]Z^\]i"&0n p .^ciW2%0 &%^ciV2%0 &&[dg^ci^2%0^1-0^ p &'^[Wg^\]icZhh\Zim mYP^R!n nYP^R1&'-$$XVhZ& &(W 0 &)^[Wg^\]icZhh\Zim mYP^R!n nYP^R1&'- &*Wg^\]icZhh\Zim mYP^ &R!n nYP^ &R3&'-$$XVhZ' &+V 0 &,r &-^[W32'W12+qqV22& &.Bn8denPmRPnR2&0$$bVg`i]ZhZdcZhVhZY\Zh '%ZahZ '&Bn8denPmRPnR2%0 ''r '( ')[dg^cim2&0m1l^Yi]"&0m $$\di]gdj\]Vaae^mZah '*[dg^cin2&0n1]Z^\]i"&0n p '+^[Bn8denPmRPnR22&$$^[i]ZnVgZbVg`ZY ',hZim!n!Xdadg%!%!%0$$eV^cii]ZbWaVX` '-ZahZ '.hZim!n!Xdadg'**!'**!'**0$$ZahZl]^iZ (%r (&hVkZ¹Bn>bV\Z#_e\º0$$hVkZ_jhi^cXVhZ

The first two lines of code define the x and y offset for every pixel P1 in order to determine their eight neighbors in a clockwise fashion, starting from the top (as shown in Figure 5-9 (a)). Lines 3, 4, and 5 are simply the loading and displaying of an image (in this case Stockholm.jpg). In line 6 memory is allocated for a copy of all the pixels in the image. This will be used later to mark the edge pixels. Then we go through all pixels and we consider two cases: In the second case we use a counter W to count the number of dark neighboring pixels (that is, pixels below a threshold of 128). In the first case, we use a counter V to count the number of consecutive dark pixels). So in the examples shown in Figure 5-9 (b), (c), and (d) the left pattern (b) would amount to W2' and V2%, the middle pattern (c) to W2' and V2%, and the right pattern (d) to W2( and V2%.

Figure 5-9: An eight-neighbor arrangement for a center pixel (a) and three cases (b), (c), and (d) where some neighboring pixels form patterns of gray and white

Chapter 5

N

Image Processing

In line 18, we mark the pixels that have W between ' and + and V as &. These are edge pixels, which we later mark in the image in lines 24 to 30. This algorithm is one of many used in image processing. The result of this algorithm can be seen in Figure 5-10.

Figure 5-10: Original (left) and after edge detection (right)

Summary In this chapter, you were introduced to image reading, displaying, processing, and interaction. You are now able to display an image, filter its colors, and use the mouse to affect certain areas of the image. These operations are important for graphics because images are very strong visual elements. Any alteration to their content can affect their interpretation.

Exercises NOTE Answers to the exercises are provided in Appendix B. 1. Consider a two-dimensional integer array, which is a 4 × 3 and named “a.” The data is VP%RP%R2%VP%RP&R2'VP%RP'R2)VP%RP(R2+ VP&RP%R2-VP&RP&R2&%VP&RP'R2&'VP&RP(R2&) VP'RP%R2&+VP'RP&R2&-VP'RP'R2'%VP'RP(R2''

123

124

Chapter 5

N

Image Processing

We want to make a new one-dimensional array named “b” in which to store a’s data. In other words, the data of “b” should be: WP%R2%WP&R2'WP(R2)###WP&&R2''

Which is the correct program? ^ciPRW2cZl^ciP&'R0 [dg^ci^2%0^1(0^ p [dg^ci_2%0_1)0_ p $$8]ddhZdcZ[gdb6!7!8!VcY9# r r

A. WP^R2VP^RP_R0 B. WP_) ^R2VP^RP_R0 C. WP^) _R2VP_RP^R0 D. WP^) _R2VP^RP_R0 2. Modify the code at section 5.4 so that when the mouse gets close or beyond the boundaries of the image the inversion of pixels stops. 3. Write the code that will take an image and create a perforated pattern of circles based on each pixel’s brightness, as shown in the following image:

4. You are given a 100 × 100 image called “spill.gif” (see the image at the left of the following figure; the background is in white and foreground is black). Write the code that would convert it so that the background becomes red and the foreground white, as it appears to the left in the

Chapter 5

N

Image Processing

following figure. (Note that the figures in this book are black and white, but the original shows a red background.)

E>bV\ZBn>bV\Z2adVY>bV\Z¹he^aa#\^[º0 ^bV\ZBn>bV\Z!%!%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n r

p

5. Write the code that would produce an effect of pixel shrinking that will lead toward a skeleton, as shown in the following figure.

125

CHAPTER

6

Motion

Motion is the act or process of changing position or place. While the perception of motion is based on the assumption that time is continuous, human vision per se is not continuous. Instead, as the distance between “before” and “after” diminishes, it reaches a point where both appear to blend in a continuous succession. The impression of motion is, therefore, only a reconstruction in the mind of a sequential display of static impressions. Animation is the sequential display of images. While the connotations associated with animation points to films, movies, or cartoons, the root of the word “animation” stems from the Greek word “anemos,” which means wind, as in the wind that blows life into lifeless forms. Animation is about the alive, lively, vibrant, vigorous, dynamic, and energetic. In its primordial sense, animation is a sign of life, an indication of a living organism. In this chapter, we will show how to create single and multiple animated objects as well as ways to simulate dynamic behavior.

6.1 Animation Basics In our previous examples, we have created animation by repainting the graphics on every mouse movement. As you may have noticed, that was a controlled animation. Eventually, we may want to set an object in motion independently of the mouse’s movement. To make things even more complicated, we may 127

128

Chapter 6

N

Motion

want to set a series of objects in motion and control their behavior through a common clock. This involves understanding of the basics of a computer clock. As you already know, computers have internal clocks that tick extremely fast, that is, for example, 1 GHz, which means a billion ticks per second. When we do animation, we need to use that clock as a guide of time. Sometimes we also need to keep track of two or more animations as they are deployed in parallel in the scene. For example, in a car race video game, there may be one car moving, and at the same time other cars that need to bypassed, not to mention moving obstacles on the road. It seems that these animations are happening in parallel. But practically that cannot happen because then we would need parallel processors, each taking care of one moving object. Instead, what we do is to divide the processor time in small time sections, called threads, each keeping track of an animated object in the scene. This is not too hard to do for the processor, since theoretically it can take care of 1 billion things every second! In the following example, a maple leaf is drawn on a brown background and then redrawn after moving it by a random offset to produce the effect of trembling. The process is quite simple: &E>bV\ZaZV[>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi 'E>bV\Zbn7VX`>bV\Z0$$YZ[^cZVc^bV\ZdW_ZXi ( )kd^YhZijep *aZV[>bV\Z2adVY>bV\Z¹bVeaZTaZV[#\^[º0$$adVY^i +bn7VX`>bV\Z2adVY>bV\Z¹\gdjcY#_e\º0$$adVY^i ,h^oZbn7VX`>bV\Z#l^Yi]!bn7VX`>bV\Z#]Z^\]i0 -r . &%^cim!n0$$i]ZadXVi^dcd[i]ZXjghdg &&kd^YYgVlp &'^bV\Zbn7VX`>bV\Z!%!%0$$YgVli]Z\gdjcY &(^bV\ZaZV[>bV\Z!m!n0$$i]Zci]ZaZV[ &)m 2^cigVcYdb"*!*0$$gVcYdbigZbWa^c\h &*n 2^cigVcYdb"*!*0 &+r &, &-kd^YbdjhZ9gV\\ZYp &.m2bdjhZM"aZV[>bV\Z#l^Yi]$'0$$bdkZi]ZXjghdg '%n2bdjhZN"aZV[>bV\Z#]Z^\]i$'0 '&r

In the first two lines of the preceding code we define two images that are loaded in lines 5 and 6. The size of the screen is then set to the background image’s size. Before we draw we define two integer variables m and n to hold the coordinate location of where to draw the leaf image1 (line 13). These two coordinates are randomly moved by five units every time the frame is refreshed. The leaf image can be moved to any location in the screen simply by dragging it. A screen capture of the process is shown in Figure 6-1.

Chapter 6

N

Motion

Figure 6-1: A leaf trembling on top of the ground

Suppose now that we want to draw multiple leaves that tremble at different speeds to produce an autumn scene. This process involves two modifications of the previous code. First, we need to create an object (i.e., a class) that would hold information about each leaf. Then we need to use the speed of the clock and draw each leaf one at a time. However, while those leaves that are redrawn at the speed of the clock will be the fastest, the ones that are redrawn at the same position twice or more will appear to be moving at half-speed and so on. For example, if the rate of redrawing an image is 4, that is, it is drawn at a new position only every four clock ticks that will make it appear to move at a quarter of the speed of another leaf with speed 1. So, in the definition of the class, we will use that principle to control the speed of each leaf. We define therefore a class called AZV[: &XaVhhAZV[p '^cim!n0$$i]ZaZV[¼hedh^i^dc (E>bV\Ze^XijgZ0$$Vc^bV\ZdW_ZXi )^cigViZ0$$gViZd[lV^i^c\idWZgZYgVlc * +AZV[p$$XdchigjXidg ,m2^cigVcYdbl^Yi]0$$\ZiVc^c^i^VaadXVi^dc -n2^cigVcYdb]Z^\]i0 .e^XijgZ2adVY>bV\Z¹bVeaZTaZV[#\^[º0$$\Zii]Z^bV\Z &%r && &'^ci`2%0$$VXdjciZg &(kd^YYgVlp

129

130

Chapter 6

N

Motion

&)^[`22gViZp$$^[i]ZXdjciZg^hVhi]ZgViZi]ZcYgVl &*m 2^cigVcYdb"*!*0$$gVcYdbigZbWa^c\h &+n 2^cigVcYdb"*!*0 &,`2%0$$gZhZii]ZXdjciZg &-r &.` 0$$^cXgZViZi]ZXdjciZg0Yjg^c\ZkZgn^cXgZbZcii]ZgZ^hcdYgVl '%^bV\Ze^XijgZ!m!n0$$cdlYgVli]Z^bV\Z '&r ''r

The class AZV[ contains the following variables: two coordinates, an image, and a rate. The rate is an integer number that indicates the number of times to wait before redrawing the image. Line 6 contains the constructor information about the leaf, that is, defining a random initial location and loading the image (maple_leaf.gif). Before drawing the image we define a counter `. This is used to skip drawing the image until the counter is equal to the rate (line 14). If they are equal, we draw the image at a randomly offset location; otherwise, we increase the counter `. This technique allows an image to be drawn at a variable rate resulting in a variable speed of trembling motion. In the main code we define a number of leaves to be created that we put into an array bnAZV[PR. Then, we loop through the number of leaves and create a AZV[ object and assign it a random rate between 2 and 20 (line 10). Next, we draw all the leaves, but since each one has a different rate the overall result is a variable speed motion. We assume here that the frame rate is at a default 60 frames per second (fps). So, if the rate is 6 that means that a leaf will not be redrawn for six times, giving it a perceived frame rate of 10 fps (i.e., six times slower movement). &^cicjbAZVkZh2)%%0$$cjbWZgd[aZVkZhidYgVl 'E>bV\Zbn7VX`>bV\Z0$$YZ[^cZVWVX`\djcY^bV\Z (AZV[PRbnAZV[2cZlAZV[PcjbAZVkZhR0$$YZ[^cZVAZV[dW_ZXi ) *kd^YhZijep +bn7VX`>bV\Z2adVY>bV\Z¹\gdjcY#_e\º0$$adVY^i ,h^oZbn7VX`>bV\Z#l^Yi]!bn7VX`>bV\Z#]Z^\]i0$$h^oZhXgZZcidi]Z^bV\Z -[dg^ci^2%0^1cjbAZVkZh0^ p$$[dgVaai]ZcjbWZgd[aZVkZh .bnAZV[P^R2cZlAZV[0$$XgZViZVAZV[dW_ZXi &%bnAZV[P^R#gViZ2^cigVcYdb'!'%0 &&r &'r &( &)kd^YYgVlp &*^bV\Zbn7VX`>bV\Z!%!%0$$YgVl[^ghii]ZWVX`\djcY &+[dg^ci^2%0^1cjbAZVkZh0^  &,bnAZV[P^R#YgVl0$$YgVlVaai]ZaZVkZh &-r

Chapter 6

N

Motion

The result of this process can be seen in Figure 6-2:

Figure 6-2: Multiple leaves of variable trembling speed

6.2 Erratic Motion In the previous section, you saw how an image can be used to produce the impression of animation simply by altering its position and redrawing the screen. If the process of redrawing the screen is fast enough (or less than a tenth of a second), then the image appears to move relative to its previous position. The same effect can be accomplished with geometrical entities by simply drawing to the screen and redrawing the background. For instance, in the following code we will redraw a small circle after moving it by a slight random location away from its previous position: &kd^YhZijep 'h^oZ(%%!(%%0 ([gVbZGViZ(%0 )r *[adVim!n0 +kd^YYgVlp ,WVX`\gdjcY'**0 -m2m gVcYdb"(!(0 .n2n gVcYdb"(!(0

131

132

Chapter 6

N

Motion

&%Zaa^ehZm!n!&%!&%0 &&r &'kd^YbdjhZEgZhhZYp &(m2bdjhZM0 &)n2bdjhZN0 &*r

In line 3 we set the frame rate, that is, the number of pictures to display per second. Each picture is displayed every time the screen is redrawn using the WVX`\gdjcY command. Then in the YgVl section of the code we draw an ellipse at location m, n plus a random offset. The result of this random offset is a jittering erratic motion of a circle, as shown in Figures 6-3 and 6-4. Please note that in Figure 6.3 the background in not redrawn, so the circle leaves a visible trace. In the bdjhZEgZhhZY section, we assign m and n with the mouse’s position in case the jittering circle starts to move off the borders of the window.

Figure 6-3: Jittering motion of a circle

An alternative way to ensure that the jittering circle does not move out of the visible screen is to insert the following lines of code before drawing the ellipse, that is, between lines 9 and 10: m2XdchigV^cm!%!l^Yi]0 n2XdchigV^cn!%!]Z^\]i0

or, if we want to constrain the motion within a 100 × 100 area at the center of the window, we can use the following code: m2XdchigV^cm!l^Yi]$'"*%!l^Yi]$' *%0 n2XdchigV^cn!]Z^\]i$'"*%!]Z^\]i$' *%0

The result of this constraining motion is shown in Figure 6-4.

Chapter 6

N

Motion

Figure 6-4: Constraint motion of circles within a 100 × 100 pixel area

6.3 Line Traces In the following code, we will show how to create a series of lines that connect a set of random points: &kd^YhZijep 'h^oZ(%%!(%%0 ([gVbZGViZ+%0 )r *[adVim2&*%!n2&*%!mc2&*%!nc2&*%0 +kd^YYgVlp ,$$WVX`\gdjcY'**0 -m2m gVcYdb"*!*0 .n2n gVcYdb"*!*0 &%m2XdchigV^cm!%!l^Yi]0 &&n2XdchigV^cn!%!]Z^\]i0 &'a^cZm!n!mc!nc0 &(mc2m0 &)nc2n0 &*r

In line 3, we set the frame rate to 60 frames per second. Next, in line 8 and 9, we generate points that are placed from their previous position by a random offset in a 10 × 10 pixel area (that is, 5 pixels in each direction), then we draw a line from the previous point to the next one. In lines 13 and 14, we preserve the values of m and n by assigning them to mc and nc, respectively. The result of this erratic line traces can be seen in Figure 6-5.

133

134

Chapter 6

N

Motion

Figure 6-5: Random line traces

If we want to constrain the traces only in horizontal or vertical direction, that is, in orthogonal directions, then we need to replace the following lines of code instead of lines 8 and 9 of the preceding code: &&^[gVcYdb&#3%#* &'m2m gVcYdb"&%!&%0 &(ZahZ &)n2n gVcYdb"&%!&%0

Line 11 produces a 50% chance by generating a random number between 0 and 1 and then selecting the numbers that are less than 0.5. So, in either case we increase the x or the y coordinate by a random offset (see lines 12 and 14. The result is shown in Figure 6-6 (left).

Figure 6-6: An orthogonal motion (left) with a snap every 10 pixels (right)

Further, if we want to snap the traces on a 10 × 10 grid, then we need to insert the following code between lines 9 and 10 of the preceding code: &&m2gdjcYm$&%#&%0$$hcVe &'n2gdjcYn$&%#&%0

Chapter 6

N

Motion

The gdjcY command returns an integer number that is closest to the inputted float number. So, by dividing x or y by 10, we obtain a float number that is rounded to its closest integer which, in turn, is multiplied by 10. The result of this process is shown in Figure 6-6 (right).

6.4 Interactive Transformations So far, you have seen how to move geometrical elements or images in order to produce an impression of motion. This is done by placing the element in a new position and then redrawing the screen in a sequential manner. In the following code, we will use the igVchaViZ and gdiViZ commands to rotate two rectangles around points 20,20 and 50,50, respectively. Consider the following code: &kd^YYgVlp 'igVchaViZ'%!'%0 (gdiViZgVY^VchbdjhZM(#+0 )gZXi%!%!'%!&%0 *igVchaViZ*%!*%0 +gdiViZgVY^VchbdjhZM(#+0 ,gZXi%!%!'%!&%0 -r

In line 2, we use the igVchaViZ command, which takes as parameter the coordinates of the location to move at. In line 3, we use the gdiViZ command, which takes as parameter an angle to be rotated (in radians). So, we use the mouse’s position multiplied by 3.6 and then convert it into radians. The reason that we use 3.6 is that the maximum dimension of the screen is 100, so the maximum angle will be 100 × 3.6 = 360. Then we use the gZXi command to draw a rectangle at the new translated and rotated position. The result can be seen in Figure 6.7 (left): the first rectangle rotates around point 20,20 as expected, but the second rectangle rotates also about 20,20 and not point 50,50. The reason is that the whole scene is never reset to the origin. So, the second translation occurs as the addition of the previous two. This problem is explained in more detail in Chapter 8 in section 8.5. To solve this problem, we use the edeBVig^m and ejh]BVig^m commands before and after each transformation. So, the preceding code will be as follows: &kd^YYgVlp 'ejh]BVig^m0 (igVchaViZ'%!'%0 )gdiViZgVY^VchbdjhZM(#+0 *gZXi%!%!'%!&%0 +edeBVig^m0 ,ejh]BVig^m0

135

136

Chapter 6

N

Motion

-igVchaViZ*%!*%0 .gdiViZgVY^VchbdjhZM(#+0 &%gZXi%!%!'%!&%0 &&edeBVig^m0 &'r

The result of this code is shown in Figure 6-7 on the right.

Figure 6-7: Transformation without matrices’ reset (left) and with (right)

In the next code sample, we will use multiple instances of transformations in a loop: &kd^YYgVlp 'WVX`\gdjcY'**0 ([dg[adVi^2%0^1(%0^ p )ejh]BVig^m0 *gZXiBdYZ8:CI:G0 +cd;^aa0 ,igVchaViZ*%!*%0 -hXVaZ&$^$bdjhZM!&$^$bdjhZM0 .gdiViZgVY^Vch^bdjhZN0 &%gZXi%!%!*%!*%0 &&edeBVig^m0 &'r &(r

Within the loop, we use the ejh]BVig^m and edeBVig^m to reset the scene and then draw a square after transforming it in three ways: first, we translate it to the center of the screen (at point 50,50), then we scale it by a fraction of the mouse’s position, and finally we rotate it by the mouse’s position, treating it as an angle degree. The result of this interactive transformation can be seen in Figure 6-8.

Figure 6-8: Interactive transformation of a square

Chapter 6

N

Motion

Suppose now that we have a series of rectangles that are translated in random positions, and we want to rotate them around their center just by sliding the mouse right or left. Since each rectangle will be rotated around its center, we need to keep track of each rectangle’s center, and its angle of rotation. So, we will use three arrays to hold this information. The code is shown here: &[adViemPR2cZl[adViP(%%R0 '[adVienPR2cZl[adViP(%%R0 ([adViegPR2cZl[adViP(+%R0 )kd^YhZijep *h^oZ(%%!(%%0 +r ,kd^YYgVlp -r .kd^YbdjhZEgZhhZYp &%[dg^ci^2%0^1bdjhZN0^ p &&emP^R2gVcYdbl^Yi]0 &'enP^R2gVcYdb]Z^\]i0 &(egP^R2gVcYdb(+%0 &)r &*r &+kd^YbdjhZ9gV\\ZYp &,WVX`\gdjcY'**0 &-[dg^ci^2%0^1bdjhZN0^ p &.ejh]BVig^m0 '%gZXiBdYZ8:CI:G0 '&igVchaViZemP^R!enP^R0 ''gdiViZgVY^VchegP^R bdjhZM0 '(gZXi%!%!*!*%%0 ')edeBVig^m0 '*r '+r

In the first three lines, we define three arrays that will hold the x and y coordinates and rotation angles for each rectangle. We define the maximum number of rectangles as 300, then in the bdjhZEgZhhZY section of the code we create random numbers that we use to populate the arrays. Please note that we are not using the maximum number of rectangles, that is, 300, but only a number equal to bdjhZN. This means that the number of rectangles increases or decreases, depending on the vertical motion of the mouse. Next, in the bdjhZ9gV\\ZY section of the code, we go through all the rectangles in the scene and perform the transformations: we translate each rectangle to its center, which is stored in the arrays emPR and enPR and then rotate by an angle, which is the addition of the

137

138

Chapter 6

N

Motion

mouse’s x direction and its previous rotation angle stored in the egPR array. The result of this algorithm can be seen in Figure 6-9.

Figure 6-9: Interactive rotation of multiple rectangles

6.5 Double Buffering When we draw on the screen we use the YgVl method. Every time we call a graphics object, such as a a^cZ or an ^bV\Z, we are actually writing to the screen sequentially. Suppose that we have 1,000 lines to draw on the screen and use the following code: [dg^ci^2%0^1&%%%0^  a^cZm&!n&!m'!n'0

We are actually sending line commands to the screen 1,000 times. This turns out to be an inefficient way of drawing that causes the whole system to slow down and the screen to, eventually, flicker. To avoid such a problem we do not draw straight to the screen but instead we draw to an off-screen image and then when done, we send the off-screen image to the screen as one action. This image is also referred to as an off-screen graphics or a buffer. Internally, a buffer is a memory area where we store temporary information. The method of indirect drawing is called double buffering. In the following code we will demonstrate a case of double buffering. First, we create an object of type EbV\Z that will be used to show the colored Voronoi areas; that is, we will paint each area with a random color using the image as a canvas. This image is created in line 8. In the YgVl section, we draw the image and then draw all the marks.

155

156

Chapter 7

N

Advanced Graphics Algorithms

However, in the bdjhZEgZhhZY section, we acquire the marks by saving the mouse’s location. This is done in lines 18 and 19. Lines 20 and 21 expand the arrays Y^hiVcXZPR and ^YmPR by one element set to 0. Next, we loop through all pixels in the image and through all already marked points and calculate the distance between the new mouseX and mouseY point with all other marks. Also, we set the ^cYZmPR array in ascending order. Then we sort the Y^hiVcXZPR array in the order of their distance from the new mark (sorting also at the same time the index numbers). So, at the end we have the Y^hiVcXZPR and ^YmPR arrays sorted, which we use to color each area with a random color (lines 38–39). The mapping process can be seen in Figure 7-2, and the result of this process can be seen in Figure 7-3. dist

id

25 3 12 21 20 56 33

1 2 3 4 5 6 7

dist 3 12 20 21 25 33 56

id 2 3 5 4 1 7 6

Figure 7-2: The distribution of distances in correlation with the identity number of a color is being redistributed based on the distance.

Figure 7-3: The Voronoi tessellation for 2 to 9 points

Notice that the preceding code will paint areas with a different color in order to differentiate them. If we extract the edges of each area, a visually clearer effect can be created. The following code will extract the edges of each area by

Chapter 7

N

Advanced Graphics Algorithms

simply going through every pixel on the image and checking the difference of color between adjacent pixels. If they are different, we paint them black (i.e., the edge); otherwise, we paint the pixel white (i.e., interior). The following code should be added at the end of line 40: )%[dg^cim2&0m1l^Yi]"&0m  )&[dg^cin2&0n1]Z^\]i"&0n $$X]ZX`i]ZY^[[ZgZcXZWZilZZcVY_VXZci e^mZah )'^[VWhgZY\Zim!n"gZY\Zim &!n3%qq )(VWhgZY\Zim!n"gZY\Zim!n &3% ))hZim!n!Xdadg%0$$WaVX` )*ZahZ )+hZim!n!Xdadg'**0$$l]^iZ

In the preceding code, we extract the edges of the colored regions and eliminate the colors. So, we start by going through all the pixels in the screen and checking the difference in color between each pixel and the ones next to it (the neighbor immediately below or the one on its right). If the difference is greater than 0, that is, there is a color difference, then we set that pixel to black. If the difference is 0, that is, they are the same color, we set the pixel to white. The result is shown in Figure 7-4.

Figure 7-4: The Voronoi tessellation for 2 to 11 points

While the problem of a Voronoi tessellation is the main focus here, the methodology used to solve the problem is worth mentioning. In the field of computer graphics, geometrical problems are dealt with by using numerical methods. These methods involve usually analytical geometry as the main method of mapping the set of numbers to the set of computer elements (i.e., registers, memory locations, pixels, etc.). However, because of physical limitations, computer

157

158

Chapter 7

N

Advanced Graphics Algorithms

elements are finite in size, yet the analytical mapping assumes infinite resolution. While the advantage of analytical methods lies in their precision, efficiency, and universality, discrete methods offer a more simple, specific, and realistic approach to the same problem. In this case, the code used to address the Voronoi tessellation problem is simple, as it explicitly describes the solution to the Voronoi classification problem, and thus it is closer to the realistic material representation. Further, such methods can easily combine multiple parameters for each discrete element, resulting in far more complex effects. This complexity is a typical characteristic of materials and material behavior. Analytical methods, while precise and efficient, offer only an idealized version of a non-ideal world.

7.2 Stochastic Search A stochastic search is defined here as a random search in space until a given condition is met. For instance, the placement of toys in a playpen so that each toy does not overlap any other and they all fit within the limits of the playpen can be addressed with a stochastic search. This algorithm can be represented as follows: l]^aZcdbdgZidnhVgZaZ[iideaVXZp X]ddhZgVcYdbanVedh^i^dcgm!gnl^i]^ci]ZeaVneZc XdbeVgZ^il^i]VaaegZk^djhidnadXVi^dch ^hi]ZgZVcdkZgaVe4 ^[cdi]ZceaVXZi]ZidnVigm!gn r

This algorithm can be used to place objects within a site so that that there is no overlap (or some other criterion is satisfied). In the following code, a series of 10 × 10 rectangles are placed within an area of the screen (300 × 300 here): &[adViPRme2cZl[adViP%R0$$jhZYidhidgZi]ZVaadXViZYZaZbZcih '[adViPRne2cZl[adViP%R0 (^cicjbDW_ZXih2%0$$jhZYidXdjcii]ZcjbWZgd[VaadXViZYZaZbZcih )kd^YhZijep *h^oZ(%%!(%%0 +r ,kd^YYgVlp -WVX`\gdjcY'**0 .[dg^ci^2%0^1me#aZc\i]0^ $$YgVlVcni]^c\i]Vi]VhWZZcVaadXViZY &%gZXimeP^R!neP^R!&%!&%0 &&r &'kd^Y`ZnEgZhhZYp &(^ci`2%0

Chapter 7

N

Advanced Graphics Algorithms

&)l]^aZigjZp$$jci^andj[^cYVhjXXZhh[jaadXVi^dc^#Z#l^i]djiVc dkZgaVe &*WddaZVcdkZgaVe2[VahZ0$$jhZ^iidbVg`dkZgaVeh &+[adVimgVcY2gVcYdb&%!l^Yi]"&%0$$egdYjXZVgVcYdbedhh^WaZadXVi^dc &,[adVingVcY2gVcYdb&%!]Z^\]i"&%0 &-[dg^ci_2%0_1me#aZc\i]0_ p$$\di]gdj\]Vaai]ZgZbV^c^c\ZaZbZcih &.[adViY^hiVcXZ2Y^himgVcY!ngVcY!meP_R!neP_R0$$[^cYY^hiVcXZ '%^[Y^hiVcXZ1&%dkZgaVe2igjZ0$$^[iddh]dgii]Zc^il^aadkZgaVe '&r ''^[dkZgaVe22[VahZp$$^[cddkZgaVei]Zci]^h^hVhjXXZhh[jaadXVi^dc '(me2VeeZcYme!mgVcY0$$VYY^iidbZbdgn ')ne2VeeZcYne!ngVcY0 '*WgZV`0 '+r ',` 0 '-^[`3&%%%%p$$l^aaZm^i^[V[iZg&%!%%%ViiZbeihcdheVXZ^h[djcY '.eg^ciacme#aZc\i] ¹^beVhhº0$$lVgci]ZjhZg (%WgZV`0 (&r ('r ((eg^ciaccjbDW_ZXih 0 ()r

First, we define two arrays, me and ne , that will hold the positions of the newly placed objects. We also need a variable called cjbDW_ZXih, which will hold to the number of objects. In the hZije section, we define the size of the window (300 × 300) and in the YgVl section we draw rectangles (representing the objects to be allocated) at the locations defined by the coordinates mePR and nePR. These coordinates are calculated in the `ZnEgZhhZY section so that each time a key is pressed an object is allocated. This section is composed basically of two loops: one for suggesting a random position and one for checking for the validity of the potential position (i.e., whether it overlaps the other objects already placed in the scene). We start with a “while” loop (line 14) that repeatedly creates random locations that are input into the variables mgVcY and ngVcY. We also define a boolean variable called dkZgaVe that we set to [VahZ. Next, we loop through all the already existing objects in the scene, and that is done by looping from 0 to the length of the existing objects (m#aZc\i] or n#aZc\i]). Then we calculate the distance between the suggested locations mgVcY and ngVcY from each already defined object. If it is less than a tolerance value (in this case 10), we consider this to be an overlap and set the variable dkZgaVe to igjZ. If not, we create a new random location and try again. If we have no overlaps, we assign the mgVcY value as a valid new location and exit the loop (line 25). However, it is possible that there is no more space, so there will always be an overlap (in which case we will run into an infinite loop). So, we use lines 28 to

159

160

Chapter 7

N

Advanced Graphics Algorithms

31 as a way of forcing an exit from the loop if 10,000 attempts have been made and there is always an overlap. At each successful allocation of a new object we add one to the number of objects (line 33). The result of this algorithm is shown in Figure 7-5.

Figure 7-5: Stochastic search allocating 1 to 15 and then 541 squares

An alternative approach to the problem of stochastic allocation is to search for space availability that is adjacent to the last successful allocation. In other words, after allocating an object, then look around it for available space to allocate the next one. This can be interpreted as an attempt to fill the local region before searching further out. The effect of such a search mechanism is the creation of snake-like blobs of objects that move along the empty space populating it with new objects. The code is shown here: &[adViPRme2cZl[adViP%R0 '[adViPRne2cZl[adViP%R0

Chapter 7

N

Advanced Graphics Algorithms

(^cicjbDW_ZXih2%0 )kd^YhZijep *h^oZ(%%!(%%0 +me2VeeZcYme!gVcYdb&%!l^Yi]"&%0 ,ne2VeeZcYne!gVcYdb&%!]Z^\]i"&%0 -r .kd^YYgVlp &%WVX`\gdjcY'**0 &&[dg^ci^2%0^1me#aZc\i]0^  &'gZXimeP^R!neP^R!&%!&%0 &(r &)kd^Y`ZnEgZhhZYp &*^ci`2%0 &+l]^aZigjZp &,WddaZVcdkZgaVe2[VahZ0 &-[adVimgVcY2gVcYdbmePme#aZc\i]"&R"'%!mePme#aZc\i]"&R '%0 &.[adVingVcY2gVcYdbnePne#aZc\i]"&R"'%!nePne#aZc\i]"&R '%0 '%[dg^ci_2%0_1me#aZc\i]0_ p '&[adViY^hiVcXZ2Y^himgVcY!ngVcY!meP_R!neP_R0 ''^[Y^hiVcXZ1&%qqmgVcY3l^Yi]"'%qqmgVcY1'%qq '(ngVcY3]Z^\]i"'%qqngVcY1'%dkZgaVe2igjZ0 ')r '*^[dkZgaVe22[VahZp '+me2VeeZcYme!mgVcY0 ',ne2VeeZcYne!ngVcY0 '-WgZV`0 '.r (%` 0 (&^[`3&%%%%p ('eg^ciacme#aZc\i] ¹^beVhhº0 ((WgZV`0 ()r (*r (+eg^ciaccjbDW_ZXih 0 (,r

This code is similar to that shown previously, except for three parts (shown in bold font): First, we start with a random initial location (lines 6 and 7). Second, we calculate a random new location, and we give it a range within which it can generate possible coordinates. This range is within 40 points of the previous (last) position. Finally, we change the condition for overlap by assuming that if the distance is greater than the minimum tolerance (i.e., 10), or the new location is out of the greater region (i.e., the screen), then the overlap is true. The result of this algorithm is shown in Figure 7-6.

161

162

Chapter 7

N

Advanced Graphics Algorithms

Figure 7-6: Stochastic search allocating 1 to 15 and then 227 squares

7.3 Fractals A fractal is a geometric object generated by a repeating pattern, in a typically recursive or iterative process. Some of the best examples can be divided into parts, each of which is similar to the original object. Fractals are said to possess infinite detail, and some of them have a self-similar structure that occurs at different levels of magnification. The term fractal was coined in 1975 by Benoît Mandelbrot, from the Latin fractus or “fractured.” In a fractal, there are at least two shapes: a base and a generator. In each iteration, the generator replaces each segment of the base shape. Theoretically, this process can continue infinitely. The algorithm to create fractals consists of a basic procedure that fits a shape between two points. The process of fitting involves scaling, rotation, and translation of the generator to fit between two points of a segment of the base. The following code shows the procedure: &[adViPRem2cZl[adViP%R0$$iZbeVggVn '[adViPRen2cZl[adViP%R0 ([adViPR\m2p"&%!&%!'%!(%!)%r0$$\ZcZgVidgYViV )[adViPR\n2p%!%!"&%!%!%r0 *[adViPRWm2p%!&%%!'%%!(%%!)%%r0$$WVhZYViV

Chapter 7

N

Advanced Graphics Algorithms

+[adViPRWn2p'%%!'%%!&%%!'%%!'%%r0 , -kd^YhZijep .h^oZ)%%!)%%0 &%r && &'kd^YYgVlp &(WVX`\gdjcY'%%0 &)[dg^ci^2&0^1Wm#aZc\i]0^  &*^[WmP^R2...WmP^"&R2...$$h`^e &+a^cZWmP^"&R!WnP^"&R!WmP^R!WnP^R0 &,r &&.kd^YbdjhZEgZhhZYp '%em2ZmeVcYem!%0$$Zbeinem '&en2ZmeVcYen!%0 ''[dg^ci_2%0_1Wm#aZc\i]"&0_ p$$[dgVaaWVhZa^cZh '(^[WmP_R2...WmP_ &R2...$$h`^e^[bVg`ZY ')[dg^ci^2%0^1\m#aZc\i]0^ p$$[dgVaa\ZcZgVidga^cZh '*[adViYW2Y^hiWmP_R!WnP_R!WmP_ &R!WnP_ &R0$$\ZiY^hid[ZVX] WVhZhZ\bZci '+[adViY\2Y^hi%!%!\mP\m#aZc\i]"&R!\nP\n#aZc\i]"&R0$$\Zii]Z Y^hiVcXZd[i]Z\ZcZgVidg ',[adVim2\mP^RYW$Y\0$$Y^k^YZid\Zii]ZhXVaZ[VXidg '-[adVin2\nP^RYW$Y\0 '.[adViVc\aZ2ViVc'WnP_ &R"WnP_R!WmP_ &R"WmP_R0$$Vc\aZWZilZZc i]Zdg^\^cVcYZVX]ed^ci (%[adViiZbem2mXdhVc\aZ"nh^cVc\aZ0$$gdiViZ (&n2nXdhVc\aZ mh^cVc\aZ0 ('m2iZbem0 ((m 2WmP_R0$$igVchaViZ ()n 2WnP_R0 (*em2VeeZcYem!m0$$VYYi]ZcZlanigVch[dgbZYed^ci (+en2VeeZcYen!n0 (,r (-em2VeeZcYem!...0$$bVg`i]ZZcYd[Vedana^cZhZfjZcXZl^i]... (.en2VeeZcYen!...0 )%r )&$$Xdeneidi]ZWVhZVggVn )'Wm2ZmeVcYWm!%0 )(Wn2ZmeVcYWn!%0 ))[dg^ci^2%0^1em#aZc\i]0^ p )*Wm2VeeZcYWm!emP^R0 )+Wn2VeeZcYWn!enP^R0 ),r )-r

In the first six lines of code we define the coordinates of the generator shape (\mPR and \nPR), the base shape (WmPR and WnPR) as well as a temporary array to hold the points of the resulting fractal shape (emPR and enPR). In the YgVl section, we just draw the lines that describe the base as it is being replaced with the generator. The number 999 is simply a mark to indicate the end of a

163

164

Chapter 7

N

Advanced Graphics Algorithms

polyline and the beginning of a new polyline. It is assumed that there will not be no more than 999 replacement polylines to construct. In the bdjhZEgZhhZY section, we perform the replacement operation. First, we set the resulting fractal shape array to 0. We do this every time we produce a new fractal shape. The Processing command used is XdcigVXi, which essentially shrinks the array to 0, that is, it empties it. Then we go for all the base array points (stored in the WmPR and WnPR arrays), skipping the end points (marked with the 999 number), and then loop for all the generator points and adjust them through the following three transformations: 1. Calculate the distance between two sequential base points and the distance between the first and last point of the generator array, then divide the distances to get the scaling factor (which we multiply by each generator point). 2. Find the angle between the base and the generator, using the VXdh function that returns the angle between two vectors (i.e., two lines whose first points are at the origin 0,0), then rotate the base by that angle (line 30). 3. Translate the base back to its location within their original location. Finally, we add the newly transformed base points to the temporary array emPR and enPR, adding a mark (999) at the end of each polyline to separate them

later on when we draw them. When we are done with all the parts of the base, we empty WmPR and WnPR and populate them with the emPR and enPR arrays. The result of this process is shown in Figure 7-7.

Figure 7-7: Fractal process of 1 to 6 replacements of Polyline

Chapter 7

N

Advanced Graphics Algorithms

7.4 Interpolation/Extrapolation Hybridization (a.k.a. morphing) is a procedure in which an object changes its form gradually in order to obtain another form. Morphing is a gradual transition that results in a marked change in the form’s appearance, character, condition, or function. The operation of morphing consists basically of the selection of two objects and the assignment of a number of in-between transitional steps. The first object then transforms into the second in steps. The essence of such a transformation is not so much in the destination form but rather in the intermediate phases this type of transformation passes through, as well as, in the extrapolations, which go beyond the final form. It is the transitional continuity of a form that progresses through a series of evolutionary stages. Morphing can be seen as either an image or a geometrical transformation. Geometrical morphing preserves the structural integrity of the objects involved, that is, an object changes into another object as a single entity. A cube, for instance, may be gradually transformed into a pyramid. From the viewer’s point of view, there are always two objects: the original (or source), to which transformation is applied, and the destination object (or target), which is the object one will get at the final step of the transformation. However, theoretically, there is only one object, which is transformed from one state (original) into another (destination). This object combines characteristics of both parent objects, which are involved in the transformation, and is called a hybrid object. This object is actually composed of the topology of the one object and the geometry of the other. It is an object in disguise. Although it is topologically identical to one parent, it resembles the geometry of the other parent. Interpolation is a method for estimating values that lie between two known values.1 The hybrid object derives its structure from its parents through formal interpolations. While it is easy to derive hybrid children from isomorphic parents, a challenge arises for heteromorphic parents. In an isomorphic transformation, a one-to-one correspondence applies between the elements of the two parent sets, such that the result of an operation on elements of one set corresponds to the result of the analogous operation on their images in the other set. In the case of heteromorphism, the lack of homogeneity between the parents leads necessarily to a selective process of omission and inclusion of elements between the two sets. The guiding principle in this mapping process is the preservation of the topological and geometrical properties of the hybrid object. For instance, in the case of a square mapped to a triangle, the addition of a fourth point to the triangle preserves the topology of the square, and yet its disguised location preserves the geometrical appearance of the triangle. In the following example, a square is mapped to a triangle: the hybrid child is a four-sided polygon in which two of the vertices overlap and these vertices are ordered to form a triangle. The problem here is to map two counters so that,

165

166

Chapter 7

N

Advanced Graphics Algorithms

when the one is counting points from one object to another, counter kc should skip points from the other object. For example, if the counter k1 increments as 01234 the counter k2 should increment as 00123 (or 01123 or 01223 or 01233). To obtain such behavior, we use the formula kc = k/(p1/p2) or kc = k/(p2/p1). &[adViPRm&2p'%%!&%%!&%%!'%%!'%%r0$$eVgZci& '[adViPRn&2p'%%!'%%!(%%!(%%!'%%r0 ([adViPRm'2p(*%!(%%!)%%!(*%r0$$eVgZci' )[adViPRn'2p'%%!(%%!(%%!'%%r0 *[adViPRmX!nX0$$X]^aY +[adVigVi^d2%#*0$$eZgXZciV\Zd[^ciZgedaVi^dc ,^ci`&!`'!bVmed^cih0$$cjbWZgd[ed^cih[dgi]ZVggVnh -kd^YhZijep .h^oZ*%%!)%%0 &%hbddi]0$$[dgk^hjVaZ[[ZXi &&bVmed^cih2bVmm&#aZc\i]!m'#aZc\i]0$$i]ZbVmcjbWZgd[ Z^i]ZgVggVn &'mX2cZl[adViPbVmed^cihR0$$XgZViZVX]^aYl^i]ed^cihVhi]Z aVg\ZhieVgZci &(nX2cZl[adViPbVmed^cihR0 &)r &*kd^YYgVlp &+WVX`\gdjcY'**0 &,higd`Z%0 &-[dg^ci^2&0^1mX#aZc\i]0^ $$YgVli]ZX]^aY¼ha^cZh &.a^cZmXP^R!nXP^R!mXP^"&R!nXP^"&R0 '%[dg^ci^2%0^1mX#aZc\i]0^ $$YgVli]ZX]^aY¼hkZgi^XZh '&gZXimXP^R"&!nXP^R"&!(!(0 ''higd`Z'**!%!%0 '([dg^ci^2&0^1m&#aZc\i]0^ $$YgVleVgZci& ')a^cZm&P^R!n&P^R!m&P^"&R!n&P^"&R0 '*[dg^ci^2&0^1m'#aZc\i]0^ $$YgVleVgZci' '+a^cZm'P^R!n'P^R!m'P^"&R!n'P^"&R0 ',r ''.kd^YbdjhZ9gV\\ZYp (%[dg^ci`2%0`1bVmed^cih0` p (&^[m&#aZc\i]32m'#aZc\i]p$$^[e&^h\gZViZgi]Vce' ('`&2`0$$XdjciZg&gZbV^chVh^h ((`'2^ci`$m&#aZc\i]&#$m'#aZc\i]&#0 ()r$$XdjciZg'bjhiWZVY_jhiZY (*ZahZp$$^[e'^h\gZViZgi]Vce& (+`&2^ci`$m'#aZc\i]&#$m&#aZc\i]&#0 (,`'2`0 (-r (.mXP`R2m&P`&R bdjhZM&#$l^Yi]&#m'P`'R"m&P`&R0 )%nXP`R2n&P`&R bdjhZM&#$l^Yi]&#n'P`'R"n&P`&R0 )&r )'r

Chapter 7

N

Advanced Graphics Algorithms

In the first five lines of the code, we declare six arrays to hold the coordinates of two parents and the child. We define a ratio of interpolation as 0.5 (that is half the distance of the path). Then we define three variables to hold the number of points of the parents and the child. In the hZije section, we increase the array mXPR and nXPR that will hold the child’s points to the length of the largest (in number of points) parent. This is done because we know that the child will hold the number of the largest parent but the coordinate locations of the smallest parent. In the YgVl section, we simply draw the child’s lines (stored in arrays mXPR and nXPR) and also the vertices as little rectangles (for visual purposes). Then we draw the two parents. In the bdjhZ9gV\\ZY section, we loop through all points of the child and distinguish two possibilities: 1. If parent 1 is greater than parent 2 (i.e., has more points than parent 2), then the counter k1 remains as is, but the counter k2 (which will collect points for the smaller parent) is modified according to the formula described earlier. 2. If parent 2 is greater than parent 1 (i.e., has more points than parent 1), then the counter k2 remains as is, but the counter k1 (which will collect points for the smaller parent) is modified according to the formula described earlier. The result of this algorithm is shown in Figure 7-8 and 7-9.

Figure 7-8: Interpolation of a square into a triangle in six steps

167

168

Chapter 7

N

Advanced Graphics Algorithms

Figure 7-9: Interpolation of a square to a triangle, halfway (above), and multiple steps of interpolation and extrapolation of a square into a triangle and beyond (below)

7.5 Cellular Automata A cellular automaton (plural: cellular automata) is a discrete model that consists of a finite, regular grid of cells, each in one of a finite number of states. Time is also discrete, and the state of a cell at a time slice is a function of the state of a finite number of cells called the neighborhood at the previous time slice. Every cell exhibits a local behavior based on the rules applied, which in turn are based on values in their neighborhood. Each time the rules are applied to the whole grid, a new generation is produced. See Figure 7-10. While cellular automata (a.k.a. CA) were developed originally to describe organic self-replicating systems, their structure and behavior were also useful in addressing architectural, landscape, and urban design problems. From vernacular settlements and social interaction to material behavior and air circulation, CA may provide interesting interpretations of urban and architectural phenomena. The basic idea behind CA is not to describe a complex system with complex equations but to let the complexity emerge by interaction of simple individuals following simple rules. Typical features of CA include: absence of external control (autonomy), symmetry breaking (loss of freedom/heterogeneity), global order (emergence from local interactions), self-maintenance (repair/ reproduction metabolisms), adaptation (functionality/tracking of external variations), complexity (multiple concurrent values or objectives), and hierarchies (multiple nested self-organized levels).

Chapter 7

N

Advanced Graphics Algorithms

Figure 7-10: An 8-neighborhood for the black square in the center

The following algorithm was developed as a kernel to implement cellular automata for architectural purposes. It produces sets of lines and paths that, when seen from a distance, form a maze: &E>bV\ZBn>bV\Z0$$YZ[^cZVc^bV\Z '^ciPRPRbZbdgn0$$jhZ^iVhVXdend[i]Z^bV\Z¼hYViV (kd^YhZijep )h^oZ)%%!)%%0 *Bn>bV\Z2XgZViZ>bV\Zl^Yi]!]Z^\]i!G$&-%#!dg^\^c0 &,[VXZ#YgVl0 &-m[2bdjhZM0 &.n[2bdjhZN0 '%r

The result is shown in Figure 9-1.

Figure 9-1: A planar polygon in 3D space

213

214

Chapter 9

N

Solid Geometry

9.1.2 Sets of Faces With the same rationale you can construct more than one face and draw them together. The source code below modifies the previous Bn;VXZ class to accommodate two faces that you put into an array called [VXZPR. First, you create a face out of the points array and then you create another face with the same array and move it 100 units in the z direction. Bn;VXZPR[VXZh0 kd^YhZijep h^oZ'%%!'%%!E(90 cd;^aa0 XVbZgV,%#%!(*#%!&'%#%!%#%!%#%!%#%!%#%!&#%!%#%0 [VXZh2cZlBn;VXZP'R0 [VXZhP%R2cZlBn;VXZ0 [VXZhP%R#VYYEd^ci*%!*%!%0 [VXZhP%R#VYYEd^ci"*%!*%!%0 [VXZhP%R#VYYEd^ci"*%!"*%!%0 [VXZhP%R#VYYEd^ci*%!"*%!%0 [VXZhP&R2cZlBn;VXZ0 [VXZhP&R#VYYEd^ci*%!*%!%0 [VXZhP&R#VYYEd^ci"*%!*%!%0 [VXZhP&R#VYYEd^ci"*%!"*%!%0 [VXZhP&R#VYYEd^ci*%!"*%!%0 [VXZhP&R#bdkZ%#!%#!'%#0 r kd^YYgVlp WVX`\gdjcY'**0 [VXZhP%R#YgVl0 [VXZhP&R#YgVl0 r

The result is shown in Figure 9-2.

Figure 9-2: Two parallel planar polygons in 3D space

Chapter 9

N

Solid Geometry

9.1.3 Class MySolid The previous example makes it apparent that you can create as many faces as you want by populating the [VXZPR array with more faces. However, since certain arrangements of faces form known solid objects, such as a cube, a pyramid, or a sphere, you can construct a new class, called BnHda^Y, in which you create an arrangement of faces that will form known solids. Begin with a formation process for solids called extrusion. In extrusion, you construct solids out of a base polygon and a height of extrusion, as shown in Figure 9-3.

+ Base

h

Height of extrusion

= Extruded solid

Figure 9-3: Extrusion of a polygon into a solid

To create a class that represents a solid object, the constructor should accept a set of points that forms the base and a number representing the height of extrusion. The following code shows how an extruded solid can be created (one of the many ways): XaVhhBnHda^Yp Bn;VXZPR[VXZh0 ^cic[VXZh0 XdadgX0 $$ BnHda^YBnEd^ciPR^cEd^cih![adVi]Z^\]ip c[VXZh2%0 [VXZh2cZlBn;VXZP^cEd^cih#aZc\i] 'R0 $$Wdiidb [VXZhP%R2cZlBn;VXZ^cEd^cih0 c[VXZh 0 $$ide [VXZhPc[VXZhR2cZlBn;VXZ^cEd^cih0 [VXZhPc[VXZhR#bdkZ%#!%#!]Z^\]i0 c[VXZh 0

215

216

Chapter 9

N

Solid Geometry

BnEd^ciPRh^YZ0 h^YZ2cZlBnEd^ciP)R0 [dg^ci^2%0^1^cEd^cih#aZc\i]"&0^ p h^YZP%R2cZlBnEd^ci[VXZhP%R#ed^cihP^R#m![VXZhP%R#ed^cihP^R#n! [VXZhP%R#ed^cihP^R#o0 h^YZP&R2cZlBnEd^ci[VXZhP%R#ed^cihP^ &R#m! [VXZhP%R#ed^cihP^ &R#n![VXZhP%R#ed^cihP^ &R#o0 h^YZP'R2cZlBnEd^ci[VXZhP&R#ed^cihP^ &R#m! [VXZhP&R#ed^cihP^ &R#n![VXZhP&R#ed^cihP^ &R#o0 h^YZP(R2cZlBnEd^ci[VXZhP&R#ed^cihP^R#m![VXZhP&R#ed^cihP^R#n! [VXZhP&R#ed^cihP^R#o0 [VXZhPc[VXZhR2cZlBn;VXZh^YZ0 c[VXZh 0 r $$aVhih^YZ[VXZ ^ciaVhi2^cEd^cih#aZc\i]"&0 h^YZP%R2cZlBnEd^ci[VXZhP%R#ed^cihPaVhiR#m! [VXZhP%R#ed^cihPaVhiR#n![VXZhP%R#ed^cihPaVhiR#o0 h^YZP&R2cZlBnEd^ci[VXZhP%R#ed^cihP%R#m![VXZhP%R#ed^cihP%R#n! [VXZhP%R#ed^cihP%R#o0 h^YZP'R2cZlBnEd^ci[VXZhP&R#ed^cihP%R#m![VXZhP&R#ed^cihP%R#n! [VXZhP&R#ed^cihP%R#o0 h^YZP(R2cZlBnEd^ci[VXZhP&R#ed^cihPaVhiR#m! [VXZhP&R#ed^cihPaVhiR#n![VXZhP&R#ed^cihPaVhiR#o0 [VXZhPc[VXZhR2cZlBn;VXZh^YZ0 c[VXZh 0 $$gZkZghZi]ZdgYZgd[i]ZWdiidb[VXZ BnEd^ciPRgZkEd^cih0 gZkEd^cih2cZlBnEd^ciP^cEd^cih#aZc\i]R0 [dg^ci^2%0^1^cEd^cih#aZc\i]0^ p gZkEd^cihP^R2cZlBnEd^ci^cEd^cihP^cEd^cih#aZc\i]"&"^R#m! ^cEd^cihP^cEd^cih#aZc\i]"&"^R#n! ^cEd^cihP^cEd^cih#aZc\i]"&"^R#o0 r [VXZhP%R2cZlBn;VXZgZkEd^cih0 r r

Let’s take a closer look at the constructor. The class BnHda^Y has two data members: Bn;VXZPR[VXZh0 ^cicjb;VXZh0

Those members are: a set of points (that form the base) and the number of faces (cjb;VXZh). The constructor takes two arguments, a set of input points (^cEd^cih) and the height of extrusion. The first thing to do is allocate memory for the faces. That is easy, because you know in advance how many faces you

Chapter 9

N

Solid Geometry

will need; that is, the number of points of the base plus 2 (an extruded object has a bottom face, a top face and, as side faces, as many as the number of points). [VXZh2cZlBn;VXZP^cEd^cih#aZc\i] 'R0

Next, you create the bottom face, which is formed by whatever points are in the input base: [VXZhP%R2cZlBn;VXZ^cEd^cih0

Then you do the same thing for the top, except you move it by height units in the z direction: [VXZhP&R2cZlBn;VXZ^cEd^cih0 [VXZhP&R#hZiBdkZ%#!%#!]Z^\]i0

You also increment the cjb;VXZh as you add more faces: cjb;VXZh

0

Finally, you need to construct the side faces. Thus, you loop for the number of incoming point minus one, and for each loop you collect: 1. The current point of the bottom face 2. The next point of the bottom face 3. The next point of the top face 4. The current point of the top face Put these four points in a BnEd^ciPR array called h^YZPR, which you use to construct the side face. BnEd^ciPRh^YZ0 h^YZ2cZlBnEd^ciP)R0 [dg^ci^2%0^1^cEd^cih#aZc\i]"&0^ p h^YZP%R2cZlBnEd^ci[VXZhP%R#ed^cihP^R#m![VXZhP%R#ed^cihP^R#n! [VXZhP%R#ed^cihP^R#o0 h^YZP&R2cZlBnEd^ci[VXZhP%R#ed^cihP^ &R#m![VXZhP%R#ed^cihP^ &R#n! [VXZhP%R#ed^cihP^ &R#o0 h^YZP'R2cZlBnEd^ci[VXZhP&R#ed^cihP^ &R#m![VXZhP&R#ed^cihP^ &R#n! [VXZhP&R#ed^cihP^ &R#o0 h^YZP(R2cZlBnEd^ci[VXZhP&R#ed^cihP^R#m![VXZhP&R#ed^cihP^R#n! [VXZhP&R#ed^cihP^R#o0 [VXZhPcjb;VXZhR2cZlBn;VXZh^YZ0 cjb;VXZh 0 r

217

218

Chapter 9

N

Solid Geometry

Figure 9-4 illustrates the position of the points and faces for a hexagon: If i = 1

If i = 2

3

4

3

4

i+1 2 i+1 2 1 1

0

1 1

0

faces[1] 5

1

5

1 2

i+1 3

4

i+1 3

4

faces[0]

1

0

1

0

faces[1] 5 5 faces[0]

Figure 9-4: Sequence of point in an extruded solid

These loops take care of the ^cEd^cih#aZc\i]"& sides, that is, n – 1, where n is the number of points. You cannot construct the last face because i + 1 will take you out of the boundaries of the array when i = ^cEd^cih#aZc\i]. So, you construct the first n – 1 side-face and, then, construct the last side face, which is: ^ciaVhi2^cEd^cih#aZc\i]"&0 h^YZP%R2cZlBnEd^ci[VXZhP%R#ed^cihPaVhiR#m![VXZhP%R# ed^cihPaVhiR#n! [VXZhP%R#ed^cihPaVhiR#o0 h^YZP&R2cZlBnEd^ci[VXZhP%R#ed^cihP%R#m![VXZhP%R#ed^cihP%R#n! [VXZhP%R#ed^cihP%R#o0 h^YZP'R2cZlBnEd^ci[VXZhP&R#ed^cihP%R#m![VXZhP&R#ed^cihP%R#n! [VXZhP&R#ed^cihP%R#o0 h^YZP(R2cZlBnEd^ci[VXZhP&R#ed^cihPaVhiR#m![VXZhP&R# ed^cihPaVhiR#n! [VXZhP&R#ed^cihPaVhiR#o0 [VXZhPcjb;VXZhR2cZlBn;VXZh^YZ0 cjb;VXZh 0

kd^YYgVl$&-%#!dg^\^c0 hda^Y#YgVl0 m[2bdjhZM0 n[2bdjhZN0 r

219

220

Chapter 9

N

Solid Geometry

The output is shown in Figure 9-5.

Figure 9-5: Six planar polygon in the formation of a cube (wireframe)

You may notice that the faces do not appear in the right order. In fact, when eV^ci draws the faces, it fills a polygon in the index order 0, 1, 2, 3, 4, 5, and so forth. But [VXZhP%R is the bottom, [VXZhP&R is the top and the rest are side faces. This order from the furthest away to the closest is not the order they should be painted. The solution to this problem is to either paint them in the right order or find a way to omit the faces that are hidden, that is, the faces in the back. This is discussed in the following section.

9.1.4 Face Visibility Imagine a cube in 3D: the cube is composed of six faces, and each face is constructed in a clockwise fashion. However, the projection of each face is not all clockwise. It seems that the faces that are in the back of the object are counterclockwise. These faces are shown in light grey in Figure 9-6.

height Direction of faces

Figure 9-6: Direction of polygon creation in an extruded solid

height Direction of faces

Chapter 9

N

Solid Geometry

If you choose not to display the counterclockwise faces, you will end up with only the faces that are visible, as shown in Figure 9-7.

height Direction of faces

Figure 9-7: Direction of faces can determine a polygon (face) visibility

The algorithm to determine whether a 2D polygon is clockwise or counterclockwise is based on a simple algorithm that uses the cross product of vectors. The method belongs to the Bn;VXZ class and is shown here (cross products of vectors are covered in Chapter 10): WddaZVc^hK^h^WaZp [adVim&!n&!m'!n'!cdgb2%0 ^ciV]ZVY&!V]ZVY'0 [dg^ci^2%0^1ced^cih0^ p V]ZVY&2^ &0 V]ZVY'2^ '0 ^[^22ced^cih"'V]ZVY'2%0 ^[^22ced^cih"&p V]ZVY'2&0 V]ZVY&2%0 r $$bV`ZkZXidg& m&2ed^cihPV]ZVY&R#mhXgZZc"ed^cihP^R#mhXgZZc0 n&2ed^cihPV]ZVY&R#nhXgZZc"ed^cihP^R#nhXgZZc0 $$bV`ZkZXidg' m'2ed^cihPV]ZVY&R#mhXgZZc"ed^cihPV]ZVY'R#mhXgZZc0 n'2ed^cihPV]ZVY&R#nhXgZZc"ed^cihPV]ZVY'R#nhXgZZc0 $$XgdhhegdYjXi cdgb 2m&n'"n&m'0 r ^[cdgb3%#%gZijgc[VahZ0$$^[XadX`l^hZ ZahZgZijgcigjZ0$$ZahZXXl r

221

222

Chapter 9

N

Solid Geometry

In the preceding code, you take each point and construct two vectors: the previous and the next one. Then you take their cross product. If the value is positive you have a clockwise sequence. Otherwise, you have a counterclockwise sequence (see Figure 9-8). Please note that vector operations such as a cross product will be discussed in section 9.2.1. i+1

v2

i+2

Cross product of v1 and v2 if(positive) then clockwise

v1

+



if(negative) then counter-clockwise i

Figure 9-8: If the cross-product is positive, the sequence of points is clockwise, and vice-versa.

However, the points that you use are not the actual xyz points of BnEd^ci. Instead, you get their projections on the screen. To do that you constructed two methods that are added to the BnEd^ci class that return the screen projection: [adVimhXgZZcp [adVihm2hXgZZcMm!n!o0 gZijgchm0 r [adVinhXgZZcp gZijgchXgZZcNm!n!o0 r

This hidden-line method is then used in the YgVl method in the bnHda^Y class in the following way: kd^YYgVlp [dg^ci^2%0^1c[VXZh0^  ^[[VXZhP^R#^hK^h^WaZ[VXZhP^R#YgVl0 r

However, in the solid object you created, you did not reverse the order of the bottom face. You constructed all the faces in a clockwise direction, except the bottom face, as shown in Figure 9-9. To correct this problem, you do the following in the end of the BnHda^Y constructor: $$gZkZghZi]ZdgYZgd[i]ZWdiidb[VXZ BnEd^ciPRgZkEd^cih0 gZkEd^cih2cZlBnEd^ciP^cEd^cih#aZc\i]R0 [dg^ci^2%0^1^cEd^cih#aZc\i]0^ p gZkEd^cihP^R2cZlBnEd^ci^cEd^cihP^cEd^cih#aZc\i]"&"^R#m! ^cEd^cihP^cEd^cih#aZc\i]"&"^R#n! ^cEd^cihP^cEd^cih#aZc\i]"&"^R#o0 r [VXZhP%R2cZlBn;VXZgZkEd^cih0

Chapter 9

N

Solid Geometry

Figure 9-9: Direction of point on all faces of an extruded solid

The result is shown in Figure 9-10.

Figure 9-10: An extruded solid (cube) with back-face elimination

9.2 Shading Often reality is considered as the ultimate objective for the representation of architectural scenes.1 While the computer-graphical search for a representation of reality that is indistinguishable is, in essence, a search for completeness, its value as a means of architectural communication is debatable. Reality is about actuality, perfection, completeness, and objectivity. Nonetheless, the notions of incompleteness, imperfection, and subjectivity have a complementary value that often surpasses that of an explicit presentation. Tacit, suggestive, connotative, implicit, subtle, and evocative are qualities that invite the viewer to participate in the visual composition. Sketching, drawing, and painting are means of visual expression aimed not at representing reality as it is but rather at implying, suggesting, and inviting the viewer to explore and participate in how reality may be. Consistency is a phenomenon that ties together seemingly disparate entities. Traditionally, projection systems were constructed to simulate reality either

223

224

Chapter 9

N

Solid Geometry

subjective or objective using the principles of optics. In that context, movement in a simulated three-dimensional space under the rules of perspective projection should be consistent with one’s own experience of physical movement. Any distortion to the rules of optics should, in turn, distort the simulated environment. The distortion may not be recognized by reference to previous experience, but it is consistent within the new rules. More than ever now, through the use of applied physics and computation, design space can become a dynamic simulation environment for the exploration of visual behaviors far beyond experience or prediction. This section presents techniques for depicting solid objects in a realistic manner, incorporating shades and colors. Sets of objects will be sorted to convey the impression of depth. Shading is the process of determining the color of a face based on the direction of light. Observe the faces of the cube shown in Figure 9-11. You can see that, as a projection on the screen, we have three polygons (1, 2, and 3). By using the [^aa and higd`Z routines we can color the pixels of each polygon with a different shade of red (although the color is not visible in this book). The direction of the incoming light will determine the amount of red to be used to fill the polygon. So, you need two things: N N

A table of shades of red to pick from. A way of determining the direction of the surface of each polygon (in world space) in order to find the angle with the light direction (the lighter colored arrow). The larger the angle between the surface and the light, the more increased the shade is.

1

3

2

Figure 9-11: Shading of a face is determined by the direction of lighting

Chapter 9

Solid Geometry

N

Processing provides a method to automatically calculate the shading and to apply it to each surface on the scene using the a^\]ih command. So, in the code the addition of a^\]ih will render all surfaces that are created using the WZ\^cH]VeZFJ69H method when drawing the faces: WVX`\gdjcY'**0 a^\]ih0 hda^Y#YgVl0

However, in the next few sections you see how to create shades on solid faces in order to cover the theory behind these rendering operations. You will be using vectors that will allow you to detect light angles in 3D space and show how to produce a series of shades. The first step is to learn about vectors and their attributes.

9.2.1 Vectors Vectors are three-dimensional entities that show direction in space. Think of yourself as being at point (0,0,0) and looking at direction x, y, z. Practically, as shown in Figure 9-12, a vector is a set of three numbers that tell us where to look, assuming that we are standing at the origin (0,0,0). +z

+y (x, y, z) –x (0, 0, 0) z y x

–y

–z

Figure 9-12: A vector

+x

225

226

Chapter 9

N

Solid Geometry

So, we define a vector as a class with three components: BnKZXidg[adVim^c![adVin^c![adVio^cp m2m^c0 n2n^c0 o2o^c0 r

Notice that we use the u, v, w letters instead of x, y, z because a vector is different from a point even though it is defined in the same way. A vector shows a direction being looked at from the origin. A point shows a location. Given two points in space you can create a vector by positioning it back to the (0,0,0) reference point: BnKZXidgWj^aYKZXidgBnEd^cikZgi'!BnEd^cikZgi&p m2kZgi'#m"kZgi&#m0 n2kZgi'#n"kZgi&#n0 o2kZgi'#o"kZgi&#o0 gZijgci]^h0 r

9.2.2 Normalization A normalized vector is a vector where each of its components is divided by its length, that is, a vector that has unit length. The length of a vector is the square root of the addition of the squares of its components. hfgimm nn oo0

Normalization serves a purpose. As mentioned earlier, vectors show direction. Their length should be insignificant, since their purpose is to show a direction. For example, if you are told to look one foot ahead, then a foot right, and then another foot up it is the same as being told to look three feet ahead, three feet right, and three feet up. We are still looking in the same direction. In the following example, after normalization, the two normalized vectors are the same length (see Figure 9-13). When you normalize, you actually equalize the length of the two vectors. The normalization operation is: kd^Ycdgbp [adVii2hfgimm nn oo0 m2m$i0 n2n$i0 o2o$i0 r

Chapter 9

N

+z

Solid Geometry

+z

+y

+y

–x

–x (1, 1, 1)

(0, 0, 0)

(3, 3, 3)

(0, 0, 0) +x

–y

–z

+x –y

–z

Figure 9-13: Vector normalization

9.2.3 Cross Product The cross product of two vectors is an operation that results in a vector perpendicular to the two vectors (see Figure 9-14): kd^YXgdhhBnKZXidgVp BnKZXidgiZbe2cZlBnKZXidg0 iZbe#m2V#no"V#on0 iZbe#n2mV#o"oV#m0 iZbe#o2V#mn"V#nm0 m2iZbe#m0 n2iZbe#n0 o2iZbe#o0 r +z

(temp.x, temp.y, temp.z) +y

–x

–y

(x, y, z)

+x (a.x, a.y, a.z)

–z

Figure 9-14: Cross product of two vectors

227

228

Chapter 9

N

Solid Geometry

The direction of the cross product can be determined by the order in which we select the operands. The “corkscrew rule” shows the direction of the cross product. In Figure 9-14, if we choose the dashed and then the dotted vector, the resulting vector will be facing upwards. If we choose the dotted first and then the dashed one, the vector would be facing downwards.

9.2.4 Dot Product The dot product gives us the cosine of the angle between two vectors (in radians), as shown in Figure 9-15. [adViYdiBnKZXidgk&p gZijgck&#mm k&#nn k&#oo0 r

+z

+y –x angle

+x –y

(v.x, v.y, v.z)

(x, y, z) –z

Figure 9-15: Dot product of two vectors

9.2.5 MyVector Class The following class BnKZXidg defines a vector and its related operations: &XaVhhBnKZXidgp '[adVim!n!o0 ( )BnKZXidgp *m2n2o2%#0 +r

Chapter 9

N

Solid Geometry

,BnKZXidg[adVim^c![adVin^c![adVio^cp -m2m^c0 .n2n^c0 &%o2o^c0 &&r &'BnKZXidgWj^aYKZXidgBnEd^cikZgi'!BnEd^cikZgi&p &(m2kZgi'#m"kZgi&#m0 &)n2kZgi'#n"kZgi&#n0 &*o2kZgi'#o"kZgi&#o0 &+gZijgci]^h0 &,r &-[adViYdiBnKZXidgk&p &.gZijgck&#mm k&#nn k&#oo0 '%r '&kd^YXgdhhBnKZXidgVp ''BnKZXidgiZbe2cZlBnKZXidg%#!%#!%#0 '(iZbe#m2V#no"V#on0 ')iZbe#n2mV#o"oV#m0 '*iZbe#o2V#mn"V#nm0 '+m2iZbe#m0 ',n2iZbe#n0 '-o2iZbe#o0 '.r (%kd^Ycdgbp (&[adVii2hfgimm nn oo0 ('m2m$i0 ((n2n$i0 ()o2o$i0 (*r (+r

For the purposes of this book: N

N

Two vectors determine a plane in space. The cross product is a vector perpendicular to that plane. The cross product is a vector that shows the direction of a plane. The light is a vector that shows the direction of the incoming light. The dot product gives us the angle between the two vectors and, as a consequence, the amount of light that falls on that plane.

9.2.6 Color Tables In Processing, a color is defined with three numbers: Xdadgbn8dadg2Xdadg^cigZY!^ci\gZZc!^ciWajZ0

229

230

Chapter 9

N

Solid Geometry

Each number declares the amount of red, green, and blue that contributes to that color. The following are different color declarations: XdadgWaVX`2Xdadg%!%!%$$^hWaVX` Xdadgl]^iZ2Xdadg'**!'**!'**$$^hl]^iZ XdadggZY2Xdadg'**!%!%$$^hgZY Xdadg\gZZc2Xdadg%!'**!%$$^h\gZZc XdadgWajZ2Xdadg%!%!'**$$^hWajZ

9.2.7 Array of Shades To paint the faces of a solid you need a palette of colors, or shades of a color. To get that you need an algorithm that will create an array of colors that are alterations of one basic color (i.e., red). The algorithm is: XdadgPRh]VYZIVWaZ0$$YZ[^cZViVWaZVggVn kd^YhZiH]VYZhXdadgXp [adVig!\!W0 g2gZYX0$$ZmigVXii]ZXdadg \2\gZZcX0 W2WajZX0 g$2'**#0$$\ZiVjc^i \$2'**#0 W$2'**#0 h]VYZIVWaZ2cZlXdadgP'*+R0$$VaadXViZbZbdgn [dg^ci^2%0^1'**0^  h]VYZIVWaZP^R2Xdadg^cig^!^ci\^!^ciW^0 $$YgVli]Zh]VYZ r

This algorithm will take a basic color and create 256 shades of that color and then fill the h]VYZIVWaZPR array of colors. To draw them, you simply use the following code: kd^YhZijep h^oZ&%%!'**0 hZiH]VYZhXdadg'**!%!%0 [dg^ci^2%0^1'**0^ [^aah]VYZIVWaZP^R0 cdHigd`Z0 gZXi%!^!&%%!&0 r r

p

Notice that each basic color is associated with 256 other colors called shades (see Figure 9-16). So, when you define 10 colors to use to paint objects in a scene, you actually allocate 10 × 256 = 2,560 colors. This used to be a problem because

Chapter 9

N

Solid Geometry

different monitors could support only a limited amount of colors at the same time. However, it’s important to keep in mind that the shades of colors increase significantly, depending on the number of colors and the number of shades.

Figure 9-16: A range of shades

9.2.8 Shade Calculation At this point, you know how to create an array of color shades and how to represent the direction of planes in 3D using vectors. Now you need to determine which shade to choose from the XdadgH]VYZPR array: Figure 9-17 shows a red surface (although the color is not evident in this book); you will determine the shade of red depending on the direction of the light.

Figure 9-17: Shading of a face is determined by the direction of lighting

First, declare a light vector: BnKZXidgka^\]i2cZlBnKZXidg"&!&!'0

Since you have three points in a face, you can build two vectors out of points [0],[1] and [1],[2]. Then take the cross product, normalize it, and find the dot product with the light vector (see Figure 9-18).

231

232

Chapter 9

N

Solid Geometry

1 0

2

Figure 9-18: Building two vector on two edges to determine the angle of the face with the light.

The code for calculating the shade and returning an integer between 0 and 255 (which is the index of the shade array) is as follows: BnKZXidgka^\]i2cZlBnKZXidg&#!&#!&#0 ^ci\ZiH]VYZp ^cih]VYZ0 BnKZXidgk&2cZlBnKZXidg0 BnKZXidgk'2cZlBnKZXidg0 ka^\]i#cdgb0 $$[^ghih^YZd[ig^Vc\aZ k&#Wj^aYKZXidged^cihP&R!ed^cihP%R#cdgb0 $$hZXdcYh^YZd[ig^Vc\aZ k'#Wj^aYKZXidged^cihP&R!ed^cihP'R#cdgb0 k&#Xgdhhk'0$$\ZicdgbVaidig^Vc\aZ h]VYZ2^ci&%%# &**#k&#Ydika^\]i0$$[^cYVc\aZl^i]hjc ^[h]VYZ12%h]VYZ2%0 gZijgch]VYZ0 r

First, you build two vectors k& and k', one from points P%R and P&R and the other from points P&R and P'R. You then calculate the cross product to define the perpendicular vector k&, then normalize k&& to give it a unit length. Next, you calculate the dot product k& with the light vector ka^\]i. The dot product will be a number between -1 and 1 since it is a cosine. You multiply that number by 255 in order to scale it between -255 and 255. If it is negative, that means that the ka^\]i vector is under the surface and is not visible. If it is positive, you return an integer number between 0 and 255, which is the array index for the h]VYZIVWaZPR.

Chapter 9

N

Solid Geometry

Line 10 uses the expression: h]VYZ2^ci&%% &**iZbe&#Ydika^\]i0

This will ensure that if the angle is 90, the shade table will still be at least 100. The variable shade will oscillate now between 100 and 255. That will create a more realistic shading effect. Next, in the Bn;VXZ class you need to create a method hZi8dadg that will set the color for each face: kd^YhZi8dadgXdadgX^cp X2X^c0 hZiH]VYZhX0 X2h]VYZIVWaZP\ZiH]VYZR0 r

which, of course, will assign a color in the YgVl method of the Bn;VXZ class, using the [^aaX method. The hZi8dadg method can be also added to the BnHda^Y class and then be called from the main code, using the line: hda^Y#hZi8dadgXdadg'**#!%#!%#0 The output is shown in Figure 9-19.

Figure 9-19: A shaded cube

In this way, it is possible to paint each face in a different color, maintaining of course the shades. So, you can make a five sided object and color it in random colors, as shown in Figure 9-20. kd^YhZijep h^oZ*%%!*%%!E(90 XVbZgV,%#%!(*#%!&'%#%!%#%!%#%!%#%!%#%!&#%!%#%0 ^cich^YZh2+0 ed^cih2cZlBnEd^ciPch^YZhR0 [dg^ci^2%0^1ch^YZh0^  ed^cihP^R2cZlBnEd^ci)%#h^c(+%#$ch^YZh^E>$&-%#! )%#Xdh(+%#$ch^YZh^E>$&-%#!%#0 hda^Y2cZlBnHda^Yed^cih!'%#0

233

234

Chapter 9

N

Solid Geometry

[dg^ci^2%0^1hda^Y#c[VXZh0^  hda^Y#[VXZhP^R#hZi8dadgXdadggVcYdb'**!gVcYdb'**!gVcYdb'**0 r

Figure 9-20: A randomly colored solid

9.2.9 Class MyGroup So far, you have created a hierarchical structure of points, faces, and solids. The rationale was that solids contain faces, and faces contain points or, reversibly, points compose faces, and faces compose solids. With the same rationale, we can say that solids compose groups and groups contain solids. This simple hierarchy looks like Figure 9-21. Group

Object

Face

p

p

p

Face

p

p

p

p

Face

p

p

p

p

Face

p

p

p

Figure 9-21: The hierarchical structure of a 3D group of solids

p

Face

p

p

p

p

p

Chapter 9

N

Solid Geometry

The implementation of this hierarchy will be as follows: you make a copy of the class BnHda^Y and change Bn;VXZPR faces and ^cicjb;VXZh to BnHda^YPR solids and ^cicjbHda^Yh. The code would look like this: XaVhhBnI>:Hº0

259

260

Chapter 10

N

File Read/Write

,[dg^ci^2%0^1chda^Yh0^  -$$[dgh]VeZh .[dg^ci^^2%0^^1hda^YhP^R#c[VXZh0^^  &%$$[dged^cih &&[dg^ci^^^2%0^^^1hda^YhP^R#[VXZhP^^R#ced^cih"'0^^^ p &'dji#eg^ciac¹%¹0 &(dji#eg^ciac¹(9;68:º0$$ig^Vc\jaVi^dcd[[VXZ &)dji#eg^ciac¹&%Qcº hda^YhP^R#[VXZhP^^R#ed^cihP%R#m0 &*dji#eg^ciac¹'%Qcº hda^YhP^R#[VXZhP^^R#ed^cihP%R#n0 &+dji#eg^ciac¹(%Qcº hda^YhP^R#[VXZhP^^R#ed^cihP%R#o0 &,dji#eg^ciac¹&&Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ &R#m0 &-dji#eg^ciac¹'&Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ &R#n0 &.dji#eg^ciac¹(&Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ &R#o0 '%dji#eg^ciac¹&'Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ 'R#m0 '&dji#eg^ciac¹''Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ 'R#n0 ''dji#eg^ciac¹('Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ 'R#o0 '(dji#eg^ciac¹&(Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ 'R#m0 ')dji#eg^ciac¹'(Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ 'R#n0 '*dji#eg^ciac¹((Qcº hda^YhP^R#[VXZhP^^R#ed^cihP^^^ 'R#o0 '+r ',dji#eg^ciac¹%Qc:C9H:8º0 '-dji#eg^ciac¹%Qc:D;º0 '.$$;^c^h] (%dji#[ajh]0 (&dji#XadhZ0 ('r

In line 5 and 6, you write the code names of a section and an entity. Then you loop for all the objects and faces in the data structure as indicated in lines 7 and 9. Next, you go through all the coordinates and select them in groups of three. This is accomplished by starting with the first point of every face and then selecting sequentially the points that correspond to the counter + 1 and the counter + 2, as shown in Figure 10-7. Please note that because 3DFACE specifications require four points, we duplicate the last point.

Figure 10-7: A triangulated pentagon (left) and collection of points based on a counter (right).

Chapter 10

N

File Read/Write

10.2.6 Reading DXF Files Reading a DXF file is more complicated than writing because you do not know in advance how many points-shapes-solids you will encounter in order to preallocate the appropriate memory for the arrays. This problem is similar to that of a butterfly hunter discussed in Chapter 1 section 1.4.1: The hunter does not know how many jars to have in advance because it is unknown how many butterflies will be caught. So the hunter starts with a number of jars, and if she runs out of jars, she gets more. The case is similar here with points. You do know in advanced how many points or faces the file contains. Processing and Java recognize the difficulty of predicting this and, therefore, provide a solution: allocating memory one element at a time. An array can be expanded in order to add or remove elements on the fly. You use commands VeeZcY and ZmeVcY whenever you want to add an element or clear out the array. For example: Bn;VXZPR[2cZlBn;VXZP%R0 [2Bn;VXZPRVeeZcY[!cZlBn;VXZe0 [2BnEd^ciPRZmeVcY[!%0

The first line of the preceding code defines an array, called [, of Bn;VXZ elements and initializes it to %. In the next line of code, you allocate memory for just one Bn;VXZ element, using the VeeZcY command. Specifically, you create a new Bn;VXZ element in the second part of the VeeZcY command and then you cast the whole array into a Bn;VXZPR type. In the last line of code, you clear the array by expanding it to contain % elements. In the following code, you will use these commands to read data from a DXF file: &kd^YdeZc9M;T(9;68:Hig^c\[^aZcVbZp ' (Hig^c\a^cZhPR2adVYHig^c\h[^aZcVbZ0 )^[a^cZh#aZc\i]22%gZijgc0 *^ci`2%0 +Bn;VXZPR[2cZlBn;VXZP%R0 ,BnEd^ciPRe2cZlBnEd^ciP%R0 -[adViim2%#!in2%#0 .WddaZVc[VXZT[djcY2[VahZ0 &% &&[dg^ci^^2%0^^1a^cZh#aZc\i]0^^ p &'Hig^c\XdYZ2ig^ba^cZhP^^R0 &(^[XdYZ#ZfjVah¹6X9W;VXZº[VXZT[djcY2igjZ0 &)^[[VXZT[djcYXdYZ#ZfjVah¹&%ºqqXdYZ#ZfjVah¹&&ºqq XdYZ#ZfjVah¹&'ºqqXdYZ#ZfjVah¹&(º &*im2[adVia^cZhP^^ &R0 &+^[[VXZT[djcYXdYZ#ZfjVah¹'%ºqqXdYZ#ZfjVah¹'&ºqq XdYZ#ZfjVah¹''ºqqXdYZ#ZfjVah¹'(º

261

262

Chapter 10

N

File Read/Write

&,in2[adVia^cZhP^^ &R0 &-^[[VXZT[djcYXdYZ#ZfjVah¹(%ºqqXdYZ#ZfjVah¹(&ºqq XdYZ#ZfjVah¹('ºqqXdYZ#ZfjVah¹((º &.e2BnEd^ciPRVeeZcYe!cZlBnEd^ciim!in![adVia^cZhP^^ &R0 '%^[e#aZc\i]22)p '&[VXZT[djcY2[VahZ0 ''[2Bn;VXZPRVeeZcY[!cZlBn;VXZe0 '(hda^Yh2BnHda^YPRVeeZcYhda^Yh!cZlBnHda^Y[0 ')chda^Yh 0 '*e2BnEd^ciPRZmeVcYe!%0 '+[2Bn;VXZPRZmeVcY[!%0 ',r '-r '.r

Figure 10-8 illustrates reading a DFX file.

Figure 10-8: Reading a DXF file as 3D faces and rendered as wireframe (left) and as shaded (right)

First, you define a method called deZc9M;T(9;68: and pass the name of the file to read from. Using the adVYHig^c\h command, you load all the lines of the file as text in an array called a^cZhPR. Then, you define two arrays, [ and e, of Bn;VXZ and BnEd^ci, respectively, to hold the point coordinates and the face connections. These two arrays are initialized to %. Next, you define two float variables to hold the x and y coordinates of a point and a boolean variable [VXZT[djcY to denote the beginning and end of information about a face. In lines 11 till 29, you loop through all the lines of the file looking for keywords: if the word 6X9W;VXZ is encountered, you set the [VXZT[djcY flag to

Chapter 10

N

File Read/Write

igjZ. This flag will be used as a beginning mark for reading information about a face. If the number &%, &&, or &' is found, you read the next line and assign its value in the variable im (after casting it to a float). Similarly, if the number '%, '&, or '' is found, you read the next line and assign its value in the variable in (after casting it to a float). Finally, if the number (%, (&, or (' is found, you read the next line and assign it together with the previous two im and in variables

to construct a point (see line 19). This process will be repeated by collecting coordinates and then constructing new points. Once four points are read, there is enough information to construct a face (see line 22). You then create a solid out of the face, increase the counter chda^Yh (line 24), and clear out the ePR and [PR arrays. This process will be repeated until all lines are read. Please note that the 3DFACE DXF representation does not distinguish between faces and objects, so each face is also an object. Different keywords of DXF files provide more elaborate information that distinguishes a face from an object. For example, the keywords “VERTEX,” “POLYLINE,” and “ENTITY” distinguish between points, faces, and solids. For more information on DXF file formats, please see lll#VjidYZh`#Xdb.

10.2.7 The VRML File Format Another file format that has been used extensively in CAD systems is VRML. In this section you will be introduced briefly to this file format because it has, like DXF, become a common file format for the exchange of solid objects with CAD applications. The initials VRML stand for Virtual Reality Markup (or Modeling) Language and was developed in the mid-1990s as a means to represent three-dimensional objects using a web browser. The idea was to incorporate graphics libraries (such as openGL or direct3D) that would take advantage of the hardware graphics cards that the mid-1990s computers used. The idea was that a web browser (such as Netscape or IE) would run a plug-in that would process solid objects in a 3D-navigated environment in real-time motion. This technology was initiated in the first version of VRML in 1993 and completed in the second version in 1997. Later on, VRML was extended by another standard called X3D. The file extension of a VRML file is #lga, and most browsers recognize it and run the corresponding plug-in within a browser. Such plug-ins (such as cosmo, or cortona) together with information on the history, specifications, and techniques can be found on the wed 3D consortium at lll#lZW(Y#dg\. A VRML file is an ASCII text file. The syntax of the text represents the geometry of a 3D object but also abides by the rules of a language. Simple geometrical objects can be defined through vertices and faces. Other attributes such as color, shininess, or transparency can also be incorporated as separate entities

263

264

Chapter 10

N

File Read/Write

that link to the object. In the following VRML code you see a simple example of a face representation. &KGBAK&#%VhX^^ ' (9:;8dadgT&BViZg^Vap )VbW^Zci8dadg%#*%#*%#* *Y^[[jhZ8dadg%#*%#*%#* +igVcheVgZcXn% ,r .9:;dW_ZXiT&HZeVgVidgp &%8ddgY^cViZ(p &&ed^ciP &'%%&%! &(&%%&%! &)&%%%! &*%%%! &+R &,r &-JH:8dadgT& &.>cYZmZY;VXZHZip '%XddgY>cYZmP '&%!(!'!&!"&! ''R '(r ')r

Figure 10-9 shows the results.

Figure 10-9: File (left), schematic (upper right), and 3D view (lower right) of a VRML file using the Cortona plug-in.

Chapter 10

N

File Read/Write

As shown in the code above, the syntax makes a distinction between objects (the object is called dW_ZXiT& but there can be dW_ZXiT'!dW_ZXiT(! etc.). You can also see the coordinates of all points and the connections of the points. For example the line 0, 3, 2, 1, -1, refers to a sequence of points that start at point index 0 then go (or draw) to 3, then go to 2, then go to 1, and stop when you encounter a –1. So to read the geometry of an object you need to collect the x,y,z coordinates and then connect them in the given order. You can use the keywords ed^ci and XddgY>cYZm to find the beginning and end of these sections. You see how to export or import text files containing simple geometrical objects in the VRML format in the next two sections.

10.2.8 Writing VRML Files Writing a VRML file is a matter of taking the internal representation of the BnEd^ci-Bn;VXZ-BnHda^Y-BncYZmZY;VXZHZip¹0 (%dji#eg^ciac¹XddgY>cYZmP¹0 (&[dg^ci_2%0_1hda^YhP`R#c[VXZh0_ p ('dji#eg^ci¹¹0 (([dg^ci^2%0^1hda^YhP`R#[VXZhP_R#ced^cih0^ p ()dji#eg^ci_hda^YhP`R#[VXZhP_R#ced^cih ^ ¹!¹0 (*r (+dji#eg^ciac¹"&!º0 (,r (-dji#eg^ciac¹Rº0 (.dji#eg^ciac¹rº0 )%dji#eg^ciac¹rº0 )&r )'dji#[ajh]0 )(dji#XadhZ0 ))r

First, you define the procedure in line 1 and pass the name of the file you want to export. Then you create a Eg^ciLg^iZg to write out the VRML code. In lines 4 through 9, you write out information about the file (i.e., the version, creator, date, and user). In line 10, you define an object called 8dadgT& of a BViZg^Va type. This contains the ambient color, diffused color, and transparency values of a material that will be used later to color the geometrical objects. In this case, you are hard-coding (i.e., predetermining) the material information but that can be extracted from the color of the solid as in line 11. Once the material information is defined, you loop through all solids, all faces, and all points, and print out the coordinates. Note that coordinates are defined in the sequence as x, z, and y, and not in the standard x, y, and z. Then, for every face you print the sequence of points that define a face followed by a -1 to indicate the end of a face sequence (according to the VRML specification).

10.2.9 Reading VRML Files Reading the geometry of an object in a VRML file requires two steps. First, you read the coordinates and then the point connections. &kd^YgZVYKGBAHig^c\[^aZcVbZp 'Hig^c\a^cZhPR2adVYHig^c\h[^aZcVbZ0 (^[a^cZh#aZc\i]22%gZijgc0

Chapter 10

N

File Read/Write

)BnHda^YPRh2cZlBnHda^YP%R0 *Bn;VXZPR[2cZlBn;VXZP%R0 +BnEd^ciPRe2cZlBnEd^ciP%R0 ,BnEd^ciPReiZbe2cZlBnEd^ciP%R0 -WddaZVced^ciT[aV\2[VahZ0 .WddaZVcXddgY^cYZmT[aV\2[VahZ0 &%[dg^ci^2%0^1a^cZh#aZc\i]0^ p &&^[bViX]a^cZhP^R!ºed^ciº2cjaaped^ciT[aV\2igjZ0Xdci^cjZ0r &'^[bViX]a^cZhP^R!ºXddgY>cYZmº2cjaap &(XddgY^cYZmT[aV\2igjZ0Xdci^cjZ0 &)r &*^[ed^ciT[aV\bViX]a^cZhP^R!ºRº2cjaap &+ed^ciT[aV\2[VahZ0Xdci^cjZ0 &,r &-^[XddgY^cYZmT[aV\bViX]a^cZhP^R!ºRº2cjaap &.XddgY^cYZmT[aV\2[VahZ0 '%hda^Yh2BnHda^YPRVeeZcYhda^Yh!cZlBnHda^Y[0 '&chda^Yh 0 ''[2Bn;VXZPRZmeVcY[!%0 '(eiZbe2BnEd^ciPRZmeVcYeiZbe!%0 ')e2BnEd^ciPRZmeVcYe!%0 '*Xdci^cjZ0 '+r ', '-Hig^c\PRXdYZ2hea^iId`Zcha^cZhP^R!º!¹0 '.^[ed^ciT[aV\ (%e2BnEd^ciPRVeeZcYe!cZlBnEd^ci[adViXdYZP%R! [adViXdYZP&R![adViXdYZP'R0 (&^[XddgY^cYZmT[aV\p ('[dg^ci^^2%0^^1XdYZ#aZc\i]"&0^^  ((eiZbe2BnEd^ciPRVeeZcYeiZbe!cZlBnEd^ci eP^ciXdYZP^^RR#m! eP^ciXdYZP^^RR#n! eP^ciXdYZP^^RR#o0 ()[2Bn;VXZPRVeeZcY[!cZlBn;VXZeiZbe0 (*r (+r (,r

First, you load the file using the adVYHig^c\h command. This will populate the a^cZhPR array with all the lines of the file as text. Then, you initiate all arrays that will be used to store the points, faces, and solids. You also define an array eiZbePR that will be used to store the points of a solid temporarily until they are used to create faces. Also, you define two boolean variables: ed^ciT[aV\ and XddgY>cYZmT[aV\ that will be used to denote the presence of points or connections within a VRML file. In line 10, you loop through all the lines of the file and you look for keywords. If the word ed^cih is encountered, you set the ed^cihT[aV\ flag to igjZ . If the word XddgY>cYZm is encountered, you set

267

268

Chapter 10

N

File Read/Write

the XddgY>cYZmT[aV\ flag to igjZ. This will be used to filter the type of data to be read, that is, whether there will be triads of coordinates or pointers to points (see lines 12–15 and 21 in the VRML file displayed in section 10.9). Next, you set the ending condition for reading data. If the ed^ch_[aV\ flag is set and a “R” symbol is found, the reading of coordinates should stop. Similarly, when the XddgY>cYZm_[aV\ flag is set and a “R” symbol is found, there is enough information to create a face and a solid. This is accomplished in lines 20 to 24. Specifically, in line 20 you create a new solid out of a series of faces, then in the next line you increase the counter that counts the solids, that is, chda^Yh. Then, you empty the arrays [, eiZbe, and e (see lines 22, 23, and 24). This is accomplished by expanding each array to 0. At this point, you have enough information to read the data from the file. First, you split each line into words separated by white spaces, making sure that no commas are included in any word. This is accomplished by using the hea^i" Id`Zch command, where you include a white space and a comma as separators. You then distinguish two cases: if the ed^cih_[aV\ is set, you read triads of coordinate points that are used to construct BnEd^ci objects. Specifically, in line 33 you expand the ePR array by one element (note the cast BnEd^ciPR) and then create a new BnEd^ci by passing three numbers read from the file. Even though the data is read as strings, you cast them to floats in order to feed them to the BnEd^ci constructor. Also, note that the coordinate numbers are arranged in VRML as x, z, and y (not the usual x, y, and z). In the second case, that is, if the XddgY>cYZmT[aV\ flag is set, you construct faces out of points. These points are first added to a temporary array called eiZbePR and then passed to the face constructor to construct a face. So, line 33 is similar to line 30 discussed in the previous paragraph, and in line 34 you append a new face to the [PR array.

10.3 Client/Server Data Transfer Processing is a programming language built upon yet another language called Java, which was developed primarily to be a network-oriented language. It was developed to work over the Internet and is, therefore, a good medium for transferring data or invoking graphics on remote computers. So far, all the graphics examples you’ve seen demonstrated were designed to work on a local machine. But what if you want to run something on a remote machine? For example, moving the mouse on one computer and seeing its movement on the screen of another computer. The process of communication in Processing or Java is based on the clientserver protocol: one computer plays the role of the client who asks for information and another computer plays the role of the server, which provides information in response to the client’s request. The roles can be reversed, that is, both can send/receive information, but normally the server holds the information and

Chapter 10

N

File Read/Write

has the capacity to serve it to multiple clients through an identifiable address. Specific to the World Wide Web, a web server is the computer program that serves requested HTML pages or files. A web client is the program that requests information from the server. A web browser is a client that requests HTML files from web servers. Every computer that is connected to the Internet has an address, in order to be identified. This address is called an IP (Internet Protocol) address and is a 32-bit number. The IP address is usually expressed as four decimal numbers, each representing 8 bits, separated by periods. The format is “network.network. network.local”. The number version of the IP address is represented by a name or series of names called the domain name. Here’s an example: &(%#*#*#'*

Each number must be between 0 and 255 (i.e., a byte). The IP address 127.0.0.1 is the address of the local machine itself. Each of the decimal numbers represents a string of four binary digits. Thus, the above IP address really is this string of 0s and 1s: &%%%%%&%#%%%%%&%&#%%%%%&%&#%%%&&%%&

As you can see, periods are inserted between each 8-bit sequence just as was done for the decimal version of the IP address. To establish a server in Processing is simple: you construct a server through the following statement: HZgkZgBnHZgkZg2cZlHZgkZgi]^h!*'%%0

A HZgkZg is a Processing class that waits for request over a network. The number *'%% is the port where the server is listening. Following is the code for establishing a server. The purpose of this server is to send to the client its mouse’s x and y coordinates. &^bedgiegdXZhh^c\#cZi#0$$\Zii]ZcZia^WgVgn ' (HZgkZgBnHZgkZg0$$YZ[^cZVhZgkZg )kd^YhZijep *h^oZ(%%!(%%0 +BnHZgkZg2cZlHZgkZgi]^h!*'%%0 ,r -kd^YYgVlp .ed^cibdjhZM!bdjhZN0$$YgVlVed^ci &%BnHZgkZg#lg^iZbdjhZM0$$hZcYm &&BnHZgkZg#lg^iZbdjhZN0$$hZcYn &'r

In the first line of code, you import all the commands included in the net library of processing. Then you define a Server object called BnHZgkZg, which creates a server in line 6. You then draw points on the screen and use the server to send data out to the Internet (i.e., to whomever is receiving it), using the lg^iZ methods seen in lines 10 and 11.

269

270

Chapter 10

N

File Read/Write

To establish a client in Processing is also simple construct a server through the following statement: 8a^ZciBn8a^Zci2cZl8a^Zcii]^h!¹&',#%#%#&º!*'%%0

A 8a^Zci is a Processing class that sends requests over a network. To establish a client, you need to pass the address and port of the server to connect to. (Note that if you do not know the IP address’s number you can use the ^e method of the client’s class. It returns the IP address of the client as a string. As default value, we pass the address “127.0.0.1,” which refers to the local computer itself). The number *'%% is the port where the server is listening. If you know the IP address of the server, you can type it here instead of the local number. To find the address of a machine you go to the command line prompt (in Windows), and type the command ^eXdc[^\:

Figure 10-10: The ipconfig command

Following is the code for establishing a server. The purpose of this client is to receive the mouse’s x and y coordinates of the server. &^bedgiegdXZhh^c\#cZi#0$$\Zii]ZcZia^WgVgn ' (8a^ZciBn8a^Zci0$$YZ[^cZVXa^Zci )kd^YhZijep *h^oZ(%%!(%%0 +Bn8a^Zci2cZl8a^Zcii]^h!¹&',#%#%#&º!*'%%0 ,r -kd^YYgVlp .^[Bn8a^Zci#VkV^aVWaZ3%p$$^[YViVVgZVkV^aVWaZ &%^cim2Bn8a^Zci#gZVY0$$\Zii]Zm"XddgY^cViZ &&^cin2Bn8a^Zci#gZVY0$$\Zii]Zn"XddgY^cViZ &'gZXim!n!*!*0$$YgVlVgZXiVimn &(eg^ciacm º!¹ n0$$eg^cidjiXddgY^cViZh &)r &*r

Chapter 10

N

File Read/Write

In principle, the client code is almost the opposite of the server code. Here, you receive data from a connected server. To do that, first you create a client using the 8a^Zci command that takes as parameters the parent object (indicated by the “this” expression), the server’s IP address, and the specific port. In this case, you are using the IP address 127.0.0.1, which is the computer you are working on. In line 9 of the code you use the VkV^aVWaZ command to detect whether or not the server is sending data. If it is true (i.e., if it is not 0), then start to read the data values as they come in. In this case, you know that data comes in pairs, so you sequentially assign the odd data as x and the even as y. In more complicated cases, you may want to export an indicator on the server side to be used by the client as an identifier of what or how many data values are read in. For example, the server could be sending the string “x = 10” so the client would split the string based on the = symbol to determine that 10 is indeed the x coordinate. To run a client/server program, you need to first run the server code to make sure that the server is up and waiting for clients. Then you run the client. As the server is waiting for connections, a client sends a request that is received by the server and the communication process begins. Once the first connection is established from a new client, a continuous communication stream is established by repeatedly sending/receiving information, allowing data to flow back and forth. In the example, the server is sending x and y mouse coordinates, and the client is seeing drawn on the screen small 5 × 5 rectangles that show the coordinates sent by the server. The number 5000 stands for the port where the data will be sent or received. You can have multiple ports at the same time, since you can have multiple communications with other servers at the same time. In this case, you are using only one port, that is, the one numbered 5000. Once you establish the connection with the server, you create an input stream and receive the data, that is, the bdjhZM and bdjhZN mouse coordinates. Remember that in the server’s code, we used the lg^iZ method, which uses the output stream to send out data: BnHZgkZg#lg^iZbdjhZM0 BnHZgkZg#lg^iZbdjhZN0

On the client’s side a similar process is going on, except there you loop continuously, receiving data. The client needs to be in a constant state of waiting because it does not know when a request may come in. This is done through the line: ^[Bn8a^Zci#VkV^aVWaZ3%

271

272

Chapter 10

N

File Read/Write

which becomes true only if the server sends positive data values. Once an input stream is established, you read the data through the statements: ^cim2Bn8a^Zci#gZVY0 ^cin2Bn8a^Zci#gZVY0

Input integers are assigned to the x and y variables that are used in the gZXi method to draw a rectangle. The result of this process is shown in

Figure 10-11.

Figure 10-11: A client-server real-time interaction using graphics

For more information on the Java network objects and methods, look at the official Java site at ]iie/$$_VkV#hjc#Xdb.

Summary You have been introduced to the process of writing out and reading in files. Specifically, you have learned about the basic structure of two common graphics file formats called DXF and VRML. So, now you are able to import and export DXF and VRML files. This is an important task, because it allows you to interact with many computer graphics applications in their file format.

Exercises 1. Find information about a file format called RIB. Write the import/export methods that would handle #g^W files.

Chapter 10

N

File Read/Write

2. Without the ZmeVcY and VeeZcY array methods, how would you modify the deZc9M;T(9;68: method to read DXF files? (The problem you are faced with is that you do not know in advance the amount of data you will find in the DXF file.) 3. Find more information about the STL (Stereo Lithography) file format. Write the method that would allow to import and STL files. 4. Following are the contents of a text file called “positions.txt”:

Write the code that will open the text file and draw on the screen a series of 10 × 10 rectangles each located at the file’s data coordinates. 5. Write code that will open a text file and shuffle its contents as shown in the following figure:

273

CHAPTER

11

Physical Computing

Physical computing is a term used to denote the use of physical devices to carry out computational processes. In its simplest form, it involves circuits with sensors and actuators driven by microcontroller boards. Sensors are devices that sense information from the immediate environment, such as photocells that sense light intensity, thermistors that sense temperature, microphones that sense sound variations, and many more. One general classification of sensors is as either analog or digital, that is, whether they return a spectrum of variations or an on/off status. For example, a pushbutton is an on/ off sensor that can sense whether it is being pressed or not. In contrast, a dial can reflect a spectrum of variations, depending on the rotation of the dial. Actuators are devices that produce an action in their immediate environment, such as an LED (light emitting diode) a device that emits light, a motor that produces motion, or a speaker that vibrates sound. As in the case of sensors, one general categorization is as either analog or digital. For instance, an LED is a device that can either be on or off, whereas a motor can turn with variable degrees of speed or power output. A microcontroller board is a computing device that allows, apart from arithmetic and logical operations, the input or output of information coming from sensors or actuators. In this chapter, we will examine the Arduino microcontroller, which runs a language similar to Processing. The objective is to mix Processing code with Arduino commands in order to extend the possibilities into physical computing. In this chapter, we will introduce the basics of electrical circuits and 275

276

Chapter 11

N

Physical Computing

then introduce the Arduino microcontroller and its programming language. The purpose is to show how to use, connect, and control devices in terms of responses, feedback, and multiple feedback systems.

11.1 Basics of Electrical Circuits Electricity is the flow of electrons in a medium (i.e., copper wires). Electrons flow in one direction, which by convention, is defined from the positive to the negative pole of an electricity generator (i.e., a battery). The negative pole is also referred to as ground, for which we use the symbol GND. In some ways, the flow of electrons in a wire resembles the flow of water in a channel, and that analogy may be used occasionally in this chapter. The number of electrons that pass through a medium per second is defined as current. Its conventional symbol is I and it is measured in amperes. One ampere is equal to 6.28 × 1018 electrons per second. This unit is quite large for 9V battery-based electrical circuits, so we will mostly use mA or milliamperes (i.e., 1/1,000 amp). The potential to move electrons is defined as voltage. It is the ability of an electric source to send electrons through the medium and should remain constant. Its conventional symbol is V, and it is measured in volts. A device that slows down the flow of electrons is referred to as a resistor. Its conventional symbol is R, and it is measured in ohms. The symbol for an ohm is the Greek omega letter 7. This unit is quite small for battery-based electrical circuits, so we will occasionally use K7 or kilo-ohms (i.e., 1,000 ohms) or M7 or mega-ohms (i.e., 1,000,000 ohms). Practically, resistors can be identified from the colors of the three strips on their body (see Figure 11-1). To identify the resistance, we use a code system: position the resistor so that the gold strip (or band) is on the right side, and then identify the code.

First Strip

Golden Strip

Second Strip

Third Strip

Figure 11-1: Color strips that indicate the value of resistance (in this case brown-blackorange, that is, 10KΩ)

Chapter 11

N

Physical Computing

The system of colors can be used to calculate the exact resistance value, using the following table. COLOR

FIRST STRIP

SECOND STRIP

THIRD STRIP

Black

0

0

x1

Brown

1

1

x10

Red

2

2

x100

Orange

3

3

x1,000

Yellow

4

4

x10,000

Green

5

5

x100,000

Blue

6

6

x1,000,000

Purple

7

7

Gray

8

8

White

9

9

So, for instance, the resistance of the resistor in the figure above should be 1 (brown), then 0 (black), then t100 (red), that is, 1,000 8 or 1 K8. The relationship between current, voltage, and resistance is referred to as Ohm’s law and can be described in the following way: as the voltage remains constant, currency and resistance balance each other out to keep the voltage constant. This relationship is defined quantitatively as: V = I * R (or I = V/R or R = V/I) That is, the product of current and resistance is equal to the voltage. So, as the resistance increases (or decreases) the current decreases (or increases) correspondingly. For example, on a 5V voltage the following values of resistance and current will compensate for each other:11-KOhm resistor will allow 5/11,000 = 0.00045 or 0.4-mA current on a 5V voltage N

N

16-KOhm resistor will allow 5/16,000 = 0.00031 or 0.3-mA current on a 5V voltage 21-KOhm resistor will allow 5/21,000 = 0.00023 or 0.2-mA current on a 5V voltage

A capacitor is a device that stores electrons that flow in a circuit. It functions similar to a tank of electrons, and its usefulness is in the fact that it can slow down temporarily until it is full and then stabilize the flow or count the time that it takes to fill up. This last feature is described quantitatively by the relationship: Time = Capacity * Resistance

277

278

Chapter 11

N

Physical Computing

The unit of capacity is a farad, and its symbol is F. This unit is quite large for 9V battery-based electrical circuits, so we will mostly use µF, that is, microfarads (i.e., 1/1,000,000 F) or pF, that is, picofarads (i.e., 1/1,000,000,000,000 F). So, for example, a capacitor of 1 µF together with a resistance of 1 M8 will take 1 second because time = 1/1,000,000 F * 1,000,000 8 = 1 sec. Electrical circuits are usually created out of copper wires mounted on silicon boards. For practical purposes, there are temporary boards, called breadboards, where wires can be stuck in or pulled out to experiment with different circuit configurations. Figure 11-2 shows a typical breadboard on the left and on the right it shows the internal wiring underneath the holes.

Figure 11-2: A typical breadboard (left) and the wiring underneath the holes (right).

11.2 Arduino Microcontroller Board A microcontroller board is a computer hardware device that contains a microcontroller that can perform logico-arithmetic operations and a series of connections that allows the controller access to external input/output devices. They are all welded as a circuit on a flat silicon plate, hence the term “board.” Typically, they are small (hence the term “micro”) and much less expensive than laptop computers. Their purpose is to allow the development of circuits using one or many microcontrollers that can sense and/or act within the physical environment. In addition, many boards contain communication hardware for serial, Ethernet, or wireless networks. Arduino is the name of a microcontroller board based on the Atmel AVR microcontroller. It contains a USB communication port, 8 analog i/o ports, 16 digital i/o ports, and a TX/RX serial port (see Figure 11-3). It can be connected to a computer’s USB port and then establish communication between the computer and itself, also drawing power from the computer (there is a switch next to the Arduino’s power plug that allows one to toggle between external and USB power).

Chapter 11

N

Physical Computing

Once hardware communication is established between the computer and the Arduino board through the USB wire, software can be used to create programs. This software is also called Arduino, and it will be discussed in the next section. RX and TX LEDs Pin 13 LED

Digital Pins Power LED

USB jack

Reset Button

Power Selection Jumper

ICSP Header Microcontroller

Power Jack Power Pins Analog Input Pins

Figure 11-3: Components of the Arduino microcontroller (left) and its connection to a computer via a USB cable (right)

11.3 Arduino Language Arduino is a language designed to run on the Arduino microcontroller. Its structure is similar to Processing with a few minor differences. Arduino can be downloaded from the Processing web site (or directly from lll#VgYj^cd#XX) and installed. In the next few paragraphs, we will introduce the basic elements, structure, and commands of Arduino, and then show how to use them in context of a circuit. The main types of data variables are the following: N

WddaZVc, which is 1 bit long and can take values of either igjZ or [VahZ: WddaZVcgjcc^c\2[VahZ0

N

X]Vg, which is 1 byte (i.e., 8 bits) long and represents an ASCII character. Because of its size, 8 bits (compared to Processing’s 16 bits), it can only hold 256 different characters. Each character is defined as an alphanumeric symbol enclosed within single quotation marks and that symbol corresponds to its ASCII index number. For example, X]Vg[^ghi260$$XdggZhedcYhid+*

279

280

Chapter 11 N

N

Physical Computing

hig^c\, which is an array of characters. (There is no data type Hig^c\ as in Processing). So, the string ¹VgYj^cdº would be: X]VgcVbZPR2¹VgYj^cdº0

N

WniZ, which is an 8-bit element and, therefore, can store 28 (= 256) different

binary patterns. We use it to define integer numbers between 0 and 255. WniZW2'%0 N

^ci, which is 16 bits long and holds integer numbers. Those would range from –32,768 to 32,767 (or –215 to 215). ^ciVcVad\Te^c2(0

N

adc\, which is 32 bits long, can hold integer (whole) numbers. The range

is between 2,147,483,648 and 2,147,483,647 or –231 to 231.

adc\b^aa^hZXdcYh2+%%%%0 N

[adVi, which is 32 bits long, can define real numbers (i.e., fractional numbers). The range is between 3.4028235 * 1038 and –3.4028235 * 1038. [adVie^2(#&)&*.',0$$-cjbWZgedh^i^dch

N

YdjWaZ, which is 64 bits long, can define real numbers with higher (i.e.,

double) precision: YdjWaZe^2(#&)&*.'+*(*-.,.(0$$&+cjbWZgedh^i^dch

There are two more data types: unsigned integer and unsigned long, which correspond to only positive integers of longs. The basic variable data types can be seen in the following table. TYPE

SIZE

DESCRIPTION

WddaZVc

1 bit

True or false

X]Vg

8 bits

256 ASCII Codes

WniZ

8 bits or 1 byte

Numbers between 0 to 255

^ci

16 bits

Integer numbers

adc\

32 bits

Double-length integer numbers

[adVi

32 bits or 4 bytes

Floating numbers

YdjWaZ

64 bits or 8 bytes

Double-precision floating numbers

The structure of Arduino is similar to Processing code, as it is divided into two main processes: hZije and adde. The hZije process is used to define initial environment properties (mainly the pin mode and the serial initiation)

Chapter 11

N

Physical Computing

and the adde process for executing the input/output commands (e.g., read/ write, delay, etc.). The structure of the code is as follows: kd^YhZijep$$VgZVidhZijei]ZkVg^VWaZhdgegdXZYjgZhidWZjhZY ^ci]ZaddeWZadl r kd^Yaddep$$^cXdchiVciaddelV^i^c\idgZXZ^kZdgidhZcY ^c[dgbVi^dc r

The word kd^Y means that the process does not return any value, that is, it returns void. The term hZije is the name of the default “setup” process, and the parentheses are there in case one needs to insert parameters for processing; here they contain nothing, that is, . The curly brackets p and r denote the beginning and end of the process and normally should include the commands to be executed. Comments are represented by either double slash ($$), where everything after $$ is ignored by Processing until the end of the line, or by $ and $ where multiline comments use the $ to start and the $ to end. In brief, all of the casting, logical, and arithmetic operations as well as loops, arrays, methods, procedures, and library imports are essentially the same and can be reviewed in Chapter 1, sections 1.1 to 1.8. Also, all mathematical, trigonometric, and random commands are exactly the same. The main commands used to control the Arduino board are grouped in the categories of digital, analog, time, and serial communication. The first group includes three commands: N

N

N

e^cBdYZ^cie^c!WddaZVcbdYZ: This command defines the mode of a digital pin (0–13) to be either INPUT or OUTPUT. Note that INPUT is a constant equal to 0 or false, and OUTPUT is equal to 1 or true. Y^\^iVaLg^iZ^cie^c!WddaZVckVajZ: This command defines the value to be sent out from a digital pin (0–13) to be either HIGH or LOW. Note that HIGH is a constant equal to 1 or true, and LOW is equal to 0 or false. HIGH also corresponds to a +5V signal, whereas LOW corresponds to an almost 0V signal. ^ci Y^\^iVaGZVY ^ci e^c : This command receives a signal from a

digital pin (0–13) that is either HIGH or LOW. The next set of commands relate to the analog capabilities of the board. Those are: N

VcVad\Lg^iZ^cie^c!WniZkVajZ: This command defines the value to

be sent out to the digital pins (3, 5, 6, 9, 10, and 11), which can vary between 0 and 255. While this appears as an analog output (i.e., set the speed of a motor), in reality it is the frequency for sending out digital signals that

281

282

Chapter 11

N

Physical Computing

varies from none all the way to the highest frequency of 490 Hz. This is also referred to as PWM (Pulse Wave Modulation) wave: N

^ci VcVad\GZVY ^ci e^c : This command receives a signal from an

analog pin (0–5) that would vary between 0 and 1024 (corresponding from to 0V to +5V). The next set of commands relates to the control of time. Those are: N

adc\b^aa^hZXdcYh: This defines the number of milliseconds as a long (32-bit)

integer. The maximum value can be about 9 hours and 32 minutes. N

YZaVn adc\ bh : This defines the number of milliseconds to halt the

Arduino’s loop. The next set of commands relates to the serial communication capabilities of the board. Those are: N

N

HZg^Va#WZ\^c^ciheZZY: This starts the serial communication at the specified speed, in data bytes per second. These rates can be 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200. ^ciHZg^Va#VkV^aVWaZ: This returns 0 if a serial communication is not

established. Otherwise, it will return the number of bytes available to read from the serial buffer (1–128). N

^ciHZg^Va#gZVY: This reads data bytes coming in through the serial

port. If none is coming through, it will return -1. N N

HZg^Va#[ajh]: This clears the serial buffer of data. HZg^Va#eg^ciYViV: This sends data to the serial port. The data can be of type byte, binary, decimal, hex, or string. You can use eg^ciac instead

to include a carriage return. There are more specialized commands available for the Arduino board, which can be viewed on Arduino’s web site at lll#VgYj^cd#XX. However, for the purposes of this book, we will use only the ones outlined above. The next sections demonstrate the use of these commands in the context of circuits and as used as a reference for more complex electronic explorations.

11.4 LED An LED is a light-emitting device. It consists of semiconductor material that, when electricity passes through it in a specific direction, emits light (or infrared/ ultraviolet radiation). The word LED is an acronym for light emitting diode. The schematic symbol for an LED is shown on the left in Figure 11-4. For practical applications, we use the typical LED shown to the right in the figure.

Chapter 11

N

Physical Computing

+ –

Figure 11-4: Schematic symbol for an LED (left) and a typical LED (right)

In order to use the 13th digital pin of the Arduino to turn an LED on and off continuously every second, we employ the following code: &kd^YhZijep 'e^cBdYZ&(!DJIEJI0$$hZii]Ze^cVhdjieji (r ) *kd^Yaddep +Y^\^iVaLg^iZ&(!=>ciZ\Zg#eVghZ>ciWj[[$)0$$EVghZi]ZHig^c\id^ci ')eg^ciackVa0 '*Wj[[2¹º0$$8aZVgi]ZkVajZd[¹Wj[[º '+r ',r

As we discussed earlier, HZg^Va#eg^ciac sends out characters (i.e., bytes) over the serial line, so the main task of this code is to extract integer numbers out of 2 bytes plus a carriage return ASCII character (which is equal to 10). So, we first define a string that will hold the incoming bytes (called buff). Next, we define an integer called var that will hold the parsed integers, and then we define the word NEWLINE as 10 (since 10 is the ASCII number that corresponds to a new line). In line 9 of the code, we open serial communication with the serial port. At this point, the Arduino code is still running sending the photocell values (see line 7 in the previous code). Next, in the YgVl section we read the serial data using the edgi#gZVY command provided that it is available (see lines 13 and 14). Then we parse the incoming data, using the procedure hZg^Va:kZci. In this procedure, we read characters as they come in, concatenating them in the buff string. If the incoming byte is a new line (i.e., ASCII code 10), we take the concatenated buff string minus the last byte (which is the new line) and cast it into an integer (see lines 22 and 23). This is the value of the light intensity that was sent out through the serial stream. The reason we divide by four is that the Arduino sends values between 0 and 1024, but we can only pass values from 0 to 256 to the WVX`\gdjcY procedure, so we need to divide by 4. If the procedure was successful, the window should be changing color as the light intensities through the photocell change, as shown in Figure 11-9.

Chapter 11

N

Physical Computing

Figure 11-9: The Processing code that shows the changes in the window’s background based on the serial input

11.6 Pushbutton A pushbutton is a device that allows electricity to flow when it is pressed. In that sense, it can be viewed as a control switch. The schematic symbol for a pushbutton is shown to the left in Figure 11-10. The direction of electricity flow does not matter. For practical applications, we typically use a pushbutton with four legs, as shown in the image to the right.

Figure 11-10: Schematic symbol for a pushbutton (left) and a typical pushbutton with four legs (right)

287

288

Chapter 11

N

Physical Computing

In order to have a pushbutton notify us whether it was pressed or not, we employ the following code: &kd^YhZijep 'HZg^Va#WZ\^c.+%%0$$hiVgii]ZhZg^Vaedgi^cdgYZgidlg^iZ (e^cBdYZ'!>CEJI0$$hZii]Ze^c'id^ceji )r * +kd^Yaddep ,^cikVa2Y^\^iVaGZVY'0$$gZVY[gdbi]Ze^c' -^[kVa22ADL$$^[i]ZXjggZci^hadl^#Z#egZhhZYi]Zc .HZg^Va#eg^ciac¹ADLº0$$aZibZ`cdl &%r

First, we establish a serial connection with the computer, and then we set the pushbutton’s pin to input mode. Using the Y^\^iVaGZVY command within the main loop, the button’s activity is monitored. If the button is pushed, an interruption in the flow occurs, which results in a low signal value (i.e., an interruption). Then we send a signal back to the computer to notify it of the event. The circuit (shown in Figure 11-11) requires a 10-KOhm resistor on the 5V power supply (VCC) and two connections to the pin (2 in this case) and the ground. VCC +5V

10K

Pin 2

Button

GND

Figure 11-11: Schematic diagram of circuit (left) and actual appearance (right)

11.7 Servo Motor A servo motor is a motor that pulses at a certain rate moving its gear at a certain angle. It has three connections: the black (ground), the red (connected to 5V), and the white or yellow wire here, which is set to the digital pin (5 in our case).

Chapter 11

N

Physical Computing

A servo moves on the basis of vibrations. These vibrations range between 500 and 2,500. So, every degree corresponds to 2,000/180 = 11. So to move to 20 degrees we need to send a vibration of 500 + 11 * 20. The following code demonstrates the full range of motion for nine divisions of 180 degrees: &kd^YhZijep 'e^cBdYZ*!DJIEJI0$$hZii]Ze^ciddjieji (HZg^Va#WZ\^c.+%%0$$deZci]ZhZg^Vaideg^ci )HZg^Va#eg^ci¹GZVYnº0$$lg^iZVbZhhV\Z *r +kd^Yaddep ,^cikVa2HZg^Va#gZVY0$$gZVYi]ZhZg^VaidhZZ -^[kVa3¼%¼kVa12».¼p$$l]^X]`ZnlVhegZhhZY .kVa2kVa"»%¼0$$XdckZgii]ZX]VgVXiZgidVc^ciZ\Zg &%kVa2kVa&-%$.0$$.Y^k^h^dchd[&-%YZ\gZZh &&HZg^Va#eg^ci¹bdk^c\hZgkdid¹0 &'HZg^Va#eg^cikVa!9:80 &(HZg^Va#eg^ciac0 &)[dg^ciV2%0V1*%0V p &*^ciejahZL^Yi]2kVa&& *%%0$$HZZi]Z[dgbjaVVWdkZ &+Y^\^iVaLg^iZ*!=>ciZ\Zg#eVghZ>ciWj[[$)0 eg^ciackVa0 $$8aZVgi]ZkVajZd[¹Wj[[º Wj[[2¹º0 r r

Modify the Processing code so that you can open a file called “data.txt” to write the serial input data to that file. 3. Write the code using an Arduino that will snap to increments of 5 as the counter changes: VALUE

ROUNDIT

0

0

1

0

2

0

3

0

4

0

5

5

6

5

7

5

Chapter 11 VALUE

ROUNDIT

8

5

9

5

10

10

11

10

12

10

13

10





245

245

246

245

247

245

248

245

249

245

250

250

251

250

252

250

253

250

255

255

256

260

257

260

258

260





kd^YhZijep e^cBdYZ&&!DJIEJI0 HZg^Va#WZ\^c.+%%0 r kd^Yaddep ^cikVajZ2VcVad\GZVY%0 ^cigdjcY^i2 0 HZg^Va#eg^ciacgdjcY^i0 r 6chlZg/

N

Physical Computing

299

300

Chapter 11

N

Physical Computing

4. Consider the circuit shown in the following figure. A button is connected to digital pin 3 and an LED is on digital pin 13. Write code such that when you press the button, the LED light goes on. (Otherwise, it goes off.)

5. Project: Passage A passage is a movement from one place to another (as by going by, through, over, or across). While a passage signifies a process of flow, transition, and movement, it also implies the existence of a barrier, an obstruction, or an impediment. A passage is about the notion of a path, road, channel, trench, alley, or route, yet it is also about a cut, gash, incision, slash, slice, or slit on a barrier. In architecture, passages are typically addressed through doors that connect rooms. A door is a movable structure used to close off an entrance, typically consisting of a panel that swings on hinges or that slides or rotates. Site: Two spaces separated by a wall Program: A passage that disconnects the two spaces Satisfying the above requirements, create a contraption(s) that will address the notion of a passage. The mechanism that operates the access to the passage must be responsive to someone or something.

APPENDIX

A

Equations of Lines and Planes

Equation of Lines Given two points (x1, y1) and (x2, y2) the equation of the line they define is Ax + By + C where 62n'"n&$m'"m& 72"& 82n&"6m&

The slope of the line is given by m = –A/B = A. For example, assume points (110, 20) and (30, 70). Then 62,%"'%$(%"&&%2*%$"-%2"+#'* 72"&0 82'%"6&&%2'%""+#'*&%%2--#,*

The equation of the line is A * x + B * y + C = 0 or –6.25*x – y + 88.75 Note that for x = 0, y = C, the value of C represents the point where the line intersects the y-axis. Note also that for y = 0, x = –C/A The value of the ratio –C/A represents the point where the line intersects the x-axis.

301

302

Appendix A

N

Equations of Lines and Planes

Intersection of Lines Assume that we also have the line defined by points (x 3, y 3) = (30, 30) and (x4, y4) = (100, 80). The equation of the line is 7.5*x – y + 5 = 0. Its intersection with the previous line (the equation of which was –6.75*x – y + 88.75 = 0) is given by: m¼28'"8&$6&"6'2--#,*·*$,#* +#'*2+%#.& n¼26&m 8&2,#*+%#.& *2*%#+-

One should always watch for parallel lines, which do not intersect (or intersect at infinity). Two lines are parallel when A = 1/A2. Two lines are perpendicular to each other when A1 = 1/A2. One should also watch for vertical lines (lines parallel to the y-axis) since their slope is infinite. The following code shows a simple case of line creation, intersection, and perpendicularity: $$hjeedhZi]Vi\^kZced^cihlZ]VkZilda^cZh [adVim&2&&%0 [adVin&2'%0 [adVim'2(%0 [adVin'2,%0 [adVim(2'%0 [adVin(2'%0 [adVim)2&%%0 [adVin)2-%0 $$a^cZ&ZfjVi^dch [adVi6&2n'"n&$m'"m&0 [adVi7&2"&0 [adVi8&2n&"6&m&0 $$a^cZ'ZfjVi^dch [adVi6'2n)"n($m)"m(0 [adVi7'2"&0 [adVi8'2n("6'm(0 $$i]Z^ciZghZXi^dced^ci^h [adVim^ci28'"8&$6&"6'0 [adVin^ci26&m^ci 8&0 cd;^aa0 Zaa^ehZgdjcYm^ci!gdjcYn^ci!+!+0

Appendix A

N

Equations of Lines and Planes

eg^ciacm^ci ¹¹ n^ci0 $$ilda^cZhVgZeZgeZcY^XjaVgl]Zc6&2"&$6'#Hd!hjeedhZlZ]VkZV X^gXaZ/ [adVigVY^jh2)%0 [adVimX2'%0 [adVinX2'%0 Zaa^ehZmX!nX!gVY^jh'!gVY^jh'0$$gVY^jh^hi]ZWdjcY^c\Wdm Y^bZch^dch $$i]ZX^gXaZ¼hZfjVi^dc^h/edlmX!' edlnX!'2edlgVY^jh!' $$iV`ZVed^cidci]ZX^gXaZ¼heZg^e]Zgn [adVime2&*0$$h]djaYWZWZilZZc")%VcY)% [adVine2hfgiedlgVY^jh!'"edlme!'0 Zaa^ehZgdjcYme mX!gdjcYne nX!+!+0 $$HdVa^cZ[gdbi]ZXZciZgidme!nel^aaWZ higd`Z'**!%!%0 m&2mX0 n&2nX0 m'2me mX0 n'2ne nX0 a^cZm&!n&!m'!n'0 $$d[XdjghZi]ZZfjVi^dc^hhZZVWdkZ $$a^cZ&ZfjVi^dch 6&2n'"n&$m'"m&0 7&2"&0 8&2n&"6&m&0 $$6eZgeZcY^XjaVga^cZldjaYWZl]Zc6'2"&$6& $$Hda^cZ'h]djaYWZ 6'2"&$6&0 7'2"&0 8'2n'"6'm'0 $$hd[dg m(2&%%0$$VgW^igVgn n(28' 6'm(0 a^cZm'!n'!m(!n(0

303

304

Appendix A

N

Equations of Lines and Planes

Equation of Planes A plane is defined when given three points P1 = (x1, y1, z1), P2 = (x2, y2, z2) and P3 = (x3, y3, z3). The equation of a plane is Ax + By + Cz –D = 0, where the coefficients A, B, and C are calculated as follows: 1. Find the coefficients of the lines defined by pairs of points on the plane: 6&2m'·m&07&2n'·n&VcY8&2o'·o& 6'2m(·m&07'2n(·n&VcY8'2o(·o&#

2. Find the coefficients of the plane based on the coefficients of the lines: 62W&X'·X&W'072X&V'·V&X'082V&W'·W&V'VcY926m& 7n& 8o&

For example, assume that P1 = (4, 10, –2), P2 = (10, 5, 0) and P3 = (–2, 6, 10). Then a1 = 6, b1 = –5, c1 = 2, a2 = –6, b2 = –4, c2 = 12 A = –5 * 12 – 2 * (–4) = –6 –+8 = –52 B = 2 * (–6) – 6 * 12 = –12 – 72 = –84 C = 6 * (–4) – (–5) * (–6) = –24 – 30 = –54 D = –52*4 + (–84) * 10 + (–54) * (–2) = –208 – 840 + 108 = –940 The equation of the plane is –52x – 84y – 54z + 940 = 0 or 52x + 84y + 54z – 940 = 0 or 26x + 42y + 27z – 470 = 0

Intersection of Planes Suppose that you also have a second plane defined by points P4 = (–1, 12, 4), P5 = (3, 2, –2), and P6 = (5, –2, 8). Its equation is 31x + 13y – z – 121 = 0. The simplest way to find the intersection of the two planes is by assigning arbitrary values to any of the unknowns (the 0 value simplifies the calculations) and calculating the values of the others. In this way, we can find two points, which suffice for the definition of the intersection line.

Appendix A

N

Equations of Lines and Planes

Example: For x = 0, we have 42y + 27z – 470 = 0 (for plane P4, P5, P6) and 13y – z – 121 = 0 (for plane P1, P2, P3). Solving the equations, we have y = 9.509 and z = 2.617. So, the first point of the intersection line is P’1 = (0, 9.509, 2.617). Similarly, for y = 0, we find that x = 4.330 and z = 13.230, or P’2 = (4.330, 0, 13.230)

305

APPENDIX

B

Answers to Exercises

Chapter 1 NOTE Question 1 is a memorization exercise and does not have an answer. 2. Variable names cannot start with a number and cannot contain any arithmetic operation (+, -, *, /). The correct answer is D. 3. One bit that can be turned either on (true) or off (false). The correct answer is B. 4. For all the integer numbers between 0 and 99, there are only 10 numbers that, when divided, have a remainder of 0. These numbers are 0, 10, 20, 30, 40, 50, 60, 70, 80, and 90. The correct answer is C. 5. The correct answer is D because all the others either affect the values of x and y or do not assign anything to x and y. 6. The algorithm is: [dg^ci^2%0^1&*0^ p ^cim2^*'%0 ^cin2^$*'%0 gZXim!n!&%!&%0 r

307

308

Appendix B

N

Answers to Exercises

7. The algorithm is: [dg^ci^2%0^1(+%0^ 2&%p [adVim&2h^cgVY^Vch^(%0 [adVin&2XdhgVY^Vch^(%0 [adVim'2h^cgVY^Vch^)%0 [adVin'2XdhgVY^Vch^)%0 a^cZm& *%!n& *%!m' *%!n' *%0 r

8. The answer is: gZXi'%!'%!& hfgi*$')%!)%0

9. The algorithm is: [dg^ci^2%0^1'%0^ p ^cim2^)$("& &0 eg^cim0 r0

10. The answer is: [adVim2gdjcYbdjhZM$&%#&%#0

11. The answer is: ^cim2^cigVcYdb"*%!*%'0

12. A staircase. 13. Pattern 1. The algorithm is: h^oZ*%%!&%%0 [adVim2%0 [dg^ci^2%0^1*%%%0^ 2&%p m 2VWhh^cgVY^Vch^&%0 a^cZm!%!m!&%%0 r

Pattern 2. The algorithm is: h^oZ(%%!(%%0 [adVim2%0 [adVin2%0 [dg^ci^2%0^1*%%%0^ 2&%p m 2VWhh^cgVY^Vch^&%#0 [dg^ci_2%0_1*%%%0_ 2&%p n 2VWhXdhgVY^Vch_&%#0 a^cZ%!n!*%%!n0

Appendix B r a^cZm!%!m!*%%0 r

Pattern 3. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n ^[n'22%Xdci^cjZ0 gZXim&%!n&%!-!-0 r

p

Pattern 4. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n ^[m'22%Xdci^cjZ0 gZXim&%!n&%!-!-0 r

p

Pattern 5. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n gZXiBdYZ8:CI:G0 ^[n'22%Xdci^cjZ0 ^[m'22% gZXim&%!n&%!-!-0 ZahZ gZXim&%!n&%!)!)0 r

p

Pattern 6. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n p gZXiBdYZ8:CI:G0 ^[n'22%Xdci^cjZ0 ^[m'22% gZXim&%!n&%!&%!&%0 ZahZ gZXim&%!n&%!)!&%0 r

Pattern 7. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n gZXiBdYZ8:CI:G0 ^[n'22%Xdci^cjZ0

p

N

Answers to Exercises

309

310

Appendix B

N

Answers to Exercises

^[m(22% gZXim&%!n&%!&%!&%0 ZahZ gZXim&%!n&%!)!&%0 r

Pattern 8. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n  gZXimgVcYdb"&%#!&%#!ngVcYdb" &%#!&%#!gVcYdb'%#!gVcYdb'%#0

Pattern 9. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n  gZXimgVcYdb"&%#!&%#!n&%!&%!&%0

Pattern 10. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m  [dg^cin2%0n1]Z^\]i0n  gZXim&%!n&%!gVcYdb"&%#!&%#!&%0

Pattern 11. The algorithm is: h^oZ'%%!'%%0 [dg^cim2%0m1l^Yi]0m 2&% [dg^cin2%0n1]Z^\]i0n 2&%p WZ\^cH]VeZ0 kZgiZmm gVcYdb"&%#!&%#!n gVcYdb"&%#!&%#0 kZgiZmm gVcYdb"&%#!&%# &%!n gVcYdb"&%#!&%#0 kZgiZmm gVcYdb"&%#!&%# &%!n gVcYdb"&%#!&%# &%0 kZgiZmm gVcYdb"&%#!&%#!n gVcYdb"&%#!&%# &%0 ZcYH]VeZ8ADH:0 r

Pattern 12. The algorithm is: kd^YhZijep h^oZ'%%!'%%0 r kd^YYgVlp WVX`\gdjcY'**0 cd;^aa0 [adVimm2%!nn2%0

Appendix B

N

Answers to Exercises

[dg^cim2%0m1l^Yi]0m 2(% [dg^cin2%0n1]Z^\]i0n 2(% Zaa^ehZm!n!bdjhZM!bdjhZN0 r

Pattern 13. The algorithm is: kd^YhZijep h^oZ'%%!'%%0 r kd^YYgVlp cd;^aa0 WVX`\gdjcY'**0 [dg^cin2%0n1]Z^\]i0n 2&%p WZ\^cH]VeZ0 [dg^cim2%0m1(%0m p [adVimm2bdjhZM0 [adVimedh2m$'%#mm0 [adVinedh2n m'bdjhZN0 kZgiZmmedh!nedh0 r ZcYH]VeZ0 r r

Pattern 14. The algorithm is: kd^YhZijep h^oZ'%%!'%%0 r kd^YYgVlp cd;^aa0 WVX`\gdjcY'**0 [dg^cin2%0n1]Z^\]i0n 2&%p WZ\^cH]VeZ0 [dg^cim2%0m1(%0m p [adVimm2bdjhZM0 [adVimedh2m$'%#mm0 [adVinedh2n n'%'"&%$&%m'bdjhZN0 kZgiZmmedh!nedh0 r ZcYH]VeZ0 r r

311

312

Appendix B

N

Answers to Exercises

Chapter 2 N O TE Questions 9, 10, and 11 do not have answers as such. 1. The algorithm is: WZ\^cH]VeZ0 [dg^ci^2%0^1'%0^ p [adVim2^ ($)^ &$'''"&&%0 [adVin2^ '$)^$'''"&&%0 kZgiZmm *%!n *%0 r ZcYH]VeZ0

2. The algorithm is: [adViPRem2cZl[adViP%R0 [adViPRen2cZl[adViP%R0 kd^YhZijep h^oZ&%%!&%%0 r kd^YYgVlp WVX`\gdjcY'**0 higd`Z%!'**!%0 WZ\^cH]VeZ0 [dg^ci^2&0^1em#aZc\i]0^  [dg^ci_2%0_1em#aZc\i]"&0_ kZgiZmemP^R!enP^R0 kZgiZmemP_R!enP_R0 r ZcYH]VeZ0 higd`Z%0 [dg^ci^2%0^1em#aZc\i]0^  gZXiemP^R!enP^R!(!(0 r kd^YbdjhZEgZhhZYp gZXibdjhZM!bdjhZN!(!(0 em2VeeZcYem!bdjhZM0 en2VeeZcYen!bdjhZN0 r

3. The algorithm is: [adViPRme2cZl[adViP%R0 [adViPRne2cZl[adViP%R0 kd^YhZijep h^oZ'%%!'%%0 r

p

Appendix B

N

Answers to Exercises

kd^YYgVlp [dg^ci^2&0^1me#aZc\i]0^  ^[meP^R3%meP^"&R3%$$h`^e a^cZmeP^"&R!neP^"&R!meP^R!neP^R0 [dg^ci^2%0^1me#aZc\i]0^  ^[meP^R3%Zaa^ehZmeP^R!neP^R!)!)0 r kd^YbdjhZEgZhhZYp me2VeeZcYme!bdjhZM0 ne2VeeZcYne!bdjhZN0 r kd^Y`ZnEgZhhZYp me2VeeZcYme!"&0$$bVg`ZcYd[a^cZ ne2VeeZcYne!"&0 r

4. The algorithm is: [dg^cim2%0m1l^Yi]0m 2'% [dg^cin2%0n1]Z^\]i0n 2&%p ^[n'%2%m22%gZXim!n!-!-0 ^[n'%2%m3l^Yi]"'&gZXim &%!n!-!-0 ZahZ gZXim n'%!n!&-!-0 r

5. The algorithm is: h^oZ'%%!&%%0 ^cihiZeT]Z^\]i2-0 ^cihiZeTl^Yi]2&%0 ^cicThiZeh2]Z^\]i$hiZeT]Z^\]i0 [dg^ci^2%0^1cThiZeh0^ p [adVim2^hiZeTl^Yi]0 [adVin2"^hiZeT]Z^\]i0 gZXim!n ]Z^\]i!hiZeTl^Yi]!(0 r

6. The algorithm is: h^oZ'%%!)%%0 ^cihiZeT]Z^\]i2-0 ^cihiZeTl^Yi]2&%0 ^ciY^g2&0 ^cicThiZeh2]Z^\]i$hiZeT]Z^\]i0 ^ci`2%0 [adVim2'%!n2%0 [dg^ci^2%0^1cThiZeh0^ p m 2hiZeTl^Yi]Y^g0

313

314

Appendix B

N

Answers to Exercises

n2"^hiZeT]Z^\]i0 gZXim '%!n ]Z^\]i!hiZeTl^Yi]!(0 ^[m3&%%pgZXim '%!n ]Z^\]i!)%!(0 Y^g2"&0r ^[m1'%pgZXim"&%!n ]Z^\]i!)%!(0 Y^g2"&0r r

7. The algorithm is: h^oZ''%!''%0 cd;^aa0 WZ\^cH]VeZ0 [dg^ci^2'%%%0^3%0^"2&%p [adVim2h^cgVY^Vch^^$'%0 [adVin2XdhgVY^Vch^^$'%0 kZgiZmm &&%!n &&%0 r ZcYH]VeZ0

8. The algorithm is: h^oZ''%!))%0 cd;^aa0 WZ\^cH]VeZ0 [dg^ci^2'%%%0^3&%0^"2&%p [adVim2h^cgVY^Vch^"'%^$'%0 [adVin2XdhgVY^Vch^"'%^$'%0 kZgiZmm &&%!n ((%0 r [dg^ci^2&%0^1'%%%0^ 2&%p [adVim2h^cgVY^Vch^"'%^$'% &%0 [adVin2XdhgVY^Vch^"'%^$'% &%0 kZgiZmm &&%!n ((%0 r [dg^ci^2'%%%0^3&%0^"2&%p [adVim2h^cgVY^Vch^"'&%^$'%0 [adVin2XdhgVY^Vch^"'&%^$'%0 kZgiZmm &'%!n &'%0 r [dg^ci^2&%0^1'%%%0^ 2&%p [adVim2h^cgVY^Vch^"'&%^$'% &%0 [adVin2XdhgVY^Vch^"'&%^$'% &%0 kZgiZmm &'%!n &'%0 r ZcYH]VeZ8ADH:0

Appendix B

N

Answers to Exercises

Chapter 3 1. The class called BnE^mZa will contain information about a pixel (i.e., its location and color): &XaVhhBnE^mZap '^cim!n0 (XdadgX2Xdadg'**0 ) *kd^Yeadip +higd`ZX0 ,ed^cim!n0 -r .r

The class called BnHXgZZc will contain information about the screen (i.e., its pixels’ values). Note that the generation of a BnHXgZZc requires first the allocation of memory (line 7) and then the generation of x and y coordinates from the counter p (lines 8 and 9). &XaVhhBnHXgZZcp 'BnE^mZaPRe^mZabV\ZBn>bV\Z0 cdHigd`Z0 Bn>bV\Z2adVY>bV\Z¹[VXZ#_e\º0 h^oZBn>bV\Z#l^Yi]!Bn>bV\Z#]Z^\]i!E(90 ^bV\ZBn>bV\Z!%!%0 WZ\^cGVl9M;!¹dji#Ym[º0 [dg^cim2%0m1l^Yi]0m 2* [dg^cin2%0n1]Z^\]i0n 2*p [adViW2Wg^\]icZhh\Zim!n$*%0 [^aa%0 Zaa^ehZm!n!*"W!*"W0 r ZcYGVl0

Appendix B

N

Answers to Exercises

4. The algorithm is: XdadgX2\Zim!n0 ^[gZYX22% hZim!n!Xdadg'**!'**!'**0 ZahZ hZim!n!Xdadg'**!%!%0

5. The algorithm is: &^ciPRmY2p%!&!&!&!%!"&!"&!"&!%r0 '^ciPRnY2p&!&!%!"&!"&!"&!%!&!&r0 (E>bV\ZBn>bV\Z0 )^ciPRPRBn8den0 *kd^YhZijep +Bn>bV\Z2adVY>bV\Z¹hidX`]dabl]^iZ#_e\º0 ,h^oZBn>bV\Z#l^Yi]!Bn>bV\Z#]Z^\]i0 -Bn8den2cZl^ciPl^Yi]RP]Z^\]iR0 .^bV\ZBn>bV\Z!%!%0 &%[^aiZgI=G:H=DA90 &&[dg^cim2%0m1l^Yi]0m 

319

320

Appendix B

N

Answers to Exercises

&'[dg^cin2%0n1]Z^\]i0n  &(Bn8denPmRPnR2\Zi7^cVgnm!n0 &)[dg^ci\2%0\1(0\ h`ZaZidc^oZ0 &*r &+ &,kd^Yh`ZaZidc^oZp &-[dg^cim2&0m1l^Yi]"'0m  &.[dg^cin2'0n1]Z^\]i"&0n p '%^ciW2%0 '&^ciV2%0 ''[dg^ci^2%0^1-0^ p '(^[\Zi7^cVgnm mYP^R!n nYP^R22&W 0 ')^[\Zi7^cVgnm mYP^R!n nYP^R22% '*\Zi7^cVgnm mYP^ &R!n nYP^ &R22&V 0 '+r ',^ciV'2%0 ',[dg^ci^2%0^1-0^  '.^[\Zi7^cVgnm mYP^R!n & nYP^R22% (%\Zi7^cVgnm mYP^ &R!n & nYP^ &R22&V' 0 (&^ciX'2\Zi7^cVgnm!n &\Zi7^cVgnm &!n\Zi7^cVgnm"&!n0 ('^ciV(2%0 (([dg^ci^2%0^1-0^  ()^[\Zi7^cVgnm & mYP^R!n nYP^R22% (*\Zi7^cVgnm & mYP^ &R!n nYP^ &R22&V( 0 (+^ciX(2\Zi7^cVgnm!n &\Zi7^cVgnm &!n \Zi7^cVgnm!n"&0 (,^['12WW12+V22& (-X'22%qqV'2&X(22%qqV(2& (.^[\Zi7^cVgnm!n22&Bn8denPmRPnR2%0 )%r )&[dg^cim2&0m1l^Yi]"&0m  )'[dg^cin2&0n1]Z^\]i"&0n  )(^[Bn8denPmRPnR22& ))hZim!n!Xdadg%!%!%0$$WaVX` )*ZahZ )+hZim!n!Xdadg'**!'**!'**0$$l]^iZ ),r )).^ci\Zi7^cVgn^cim!^cinp *%gZijgcWg^\]icZhh\Zim!n3&'-4%/&0 *&r

The preceding algorithm is also referred to as Hilditch’s algorithm. It is a skeletonization process that progresses in steps. In each step, every pixel in the image is evaluated based on its neighboring pixels for the satisfaction of certain conditions. There are two neighboring conditions for a pixel e&:

Appendix B

N N

N

Answers to Exercises

7e& which is the number of non-zero neighbors 6e& which is the number of 0,1 patterns in a clockwise sequence starting at the top neighbor pixel (i.e., p2, p3, p4, p5, p6, p7, p8, p9, and p2).

The conditions that should be satisfied are: '127e&12+ 6e&2& e'e)e-2%dg6e'2& e'e)e+2%dg6e)2&

These conditions are also illustrated in the following chart:

The algorithm above addresses all these conditions in lines 20 through 39.

321

322

Appendix B

N

Answers to Exercises

Chapter 6 1. The code is: kd^YhZijep h^oZ(%%!(%%0 r kd^YYgVlp cd;^aa0 WVX`\gdjcY'**0 [adVimc2%!nc2%0 [dg^ci^2%0^1(%0^ p [adVim2^$'%#bdjhZM0 [adVin2*% ^'bdjhZN0 a^cZm!n!mc!nc0 mc2m0 nc2n0 r r

2. Pattern 2.1 can be produced through the following algorithm: cd;^aa0 h^oZ(%%!(%%0 [dg^ci^2&0^1'%0^ p ejh]BVig^m0 igVchaViZl^Yi]$'!]Z^\]i$'0 gdiViZgVY^Vch^)*0 hXVaZ&#$^!&#$^0 gZXi%!%!&%%!&%%0 edeBVig^m0 r

Pattern 2.2 can be produced through the following algorithm: cd;^aa0 h^oZ(%%!(%%0 WVX`\gdjcY'**0 gZXiBdYZ8:CI:G0 [dg^ci^2&0^1'%0^ p ejh]BVig^m0 igVchaViZl^Yi]$'!]Z^\]i$'0 gdiViZgVY^Vch^)*0 hXVaZ&#$^!&#$^0 gZXi%!%!&%%!&%%0 edeBVig^m0 r

Appendix B

N

Answers to Exercises

Pattern 2.3 can be produced through the following algorithm: cd;^aa0 h^oZ*%%!*%%0 WVX`\gdjcY'**0 [dg^ci^2%0^1'%0^ p ejh]BVig^m0 igVchaViZl^Yi]$'!]Z^\]i$'0 gdiViZgVY^Vch^.%0 hXVaZ&#$edl'!^!&#$edl'!^0 gZXi%!%!'%%!&%%0 a^cZ%!%!'%%!&%%0 edeBVig^m0 r

3. Pattern 3.1 can be produced through the following algorithm: kd^YhZijep cd;^aa0 h^oZ*%%!*%%0 r kd^YYgVlp WVX`\gdjcY'**0 [dg[adVi^2&0^1'%0^ p ejh]BVig^m0 igVchaViZl^Yi]$'!]Z^\]i$'0 hXVaZ&$^$bdjhZN.%!&$^$bdjhZN.%0 gdiViZgVY^Vch^bdjhZM0 gZXi%!%!'%%!&%%0 edeBVig^m0 r r

Pattern 3.2 can be produced through the following algorithm: kd^YhZijep cd;^aa0 h^oZ*%%!*%%0 r kd^YYgVlp WVX`\gdjcY'**0 [dg[adVi^2&0^1'%0^ p ejh]BVig^m0 igVchaViZl^Yi]$'!]Z^\]i$'0 hXVaZ&$^$bdjhZN.%!&$^$bdjhZN.%0 gdiViZgVY^Vch^bdjhZM0 Zaa^ehZ%!%!'%%!&%%0 edeBVig^m0 r r

323

324

Appendix B

N

Answers to Exercises

Pattern 3.3 can be produced through the following algorithm: kd^YhZijep cd;^aa0 $$gZXiBdYZ8:CI:G0 h^oZ*%%!*%%0 r kd^YYgVlp WVX`\gdjcY'**0 [dg[adVi^2&0^1'%0^ p ejh]BVig^m0 igVchaViZl^Yi]$'!]Z^\]i$'0 hXVaZ&$^$bdjhZN.%!&$^$bdjhZN.%0 gdiViZgVY^Vch^bdjhZM0 a^cZ'*%!%!'*%!*%%0 edeBVig^m0 r r

Chapter 7 1. Use the code provided in section 7.3 and replace the generator and base with the following data: [adViPR\m2p%!%!'%!'%!&%!&%!'%r0$$\ZcZgVidgYViV [adViPR\n2p%!"'%!"'%!"&%!"&%!%!%r0 [adViPRWm2p''*!''*!',*!',*!''*r0$$WVhZYViV [adViPRWn2p',*!''*!''*!',*!',*r0

2. The problem here is to use two generators: all even segments will be replaced with generator 1 and all odd segments with generator 2. This algorithm uses the existing code in section 7.3, except that you define two generator arrays: [adViPR\m&2p%!%!&%!&%!'%r0$$\ZcZgVidg&YViV [adViPR\n&2p%!&%!&%!%!%r0 [adViPR\m'2p%!&%!&%!'%!'%r0$$\ZcZgVidg'YViV [adViPR\n'2p%!%!"&%!"&%!%r0 [adViPRWm2p&%%!'%%!(%%r0$$WVhZYViV [adViPRWn2p'%%!(%%!'%%r0

Then you replace lines 26, 27, and 28 with the following code: [adViY\2%!m2%!n2%0 ^[_'22%p Y\2Y^hi%!%!\m&P\m&#aZc\i]"&R!\n&P\n&#aZc\i]"&R0

Appendix B

N

Answers to Exercises

m2\m&P^RYW$Y\0$$Y^k^YZid\Zii]ZhXVaZ[VXidg n2\n&P^RYW$Y\0 r ZahZp Y\2Y^hi%!%!\m'P\m'#aZc\i]"&R!\n'P\n'#aZc\i]"&R0 m2\m'P^RYW$Y\0$$Y^k^YZid\Zii]ZhXVaZ[VXidg n2\n'P^RYW$Y\0 r

3. The algorithm is: Hig^c\PRXjWZ2cZlHig^c\P(*R0 ^ci^cYZm2%0 ^ciheVXZPR2p,!'!)!+!+!*!*r0$$XdkZgV\Zd[ZVX]gddb ^ciheVXZTcVbZPR2p)!*!&!'!(!+!,r0 XdadgPRXdadgh2cZlXdadgPheVXZ#aZc\i]R0 kd^YhZijep h^oZ*(%!)%%0 WVX`\gdjcY'**0 [dg^ci^2%0^1Xdadgh#aZc\i]0^  XdadghP^R2XdadggVcYdb'**!gVcYdb'**!gVcYdb'**0 r kd^YYgVlp r kd^YbdjhZEgZhhZYp ^cYZm2%0 r kd^Y`ZnEgZhhZYp ^[^cYZm22(*gZijgc0 ^ciYdcZ2%0 WVX`\gdjcY'**0 ^cYZm2%0 $$6aaheVXZhl^i]XdchigV^cih ^cimg2^cigVcYdb,0$$\ZiVgVcYdb^ciZ\Zg%id*[dgmid hiVgi ^cing2^cigVcYdb*0$$\ZiVgVcYdb^ciZ\Zg%id,[dgn ^cime2mg0^cine2ng0 [dg^ci^2%0^1heVXZ#aZc\i]0^ p ^cicjb8jWZh2%0 ^ci`2%0 l]^aZcjb8jWZh1heVXZP^Rp me2mg0 ne2ng0 ^[gVcYdb&1#* mg2mg ^cigVcYdb"'!'0$$\ZiVgVcYdb^ciZ\Zg ^cXgZbZcid[&^cm ZahZ ng2ng ^cigVcYdb"'!'0$$\ZiVgVcYdb^ciZ\Zg ^cXgZbZcid[&^cn mg2XdchigV^cmg!%!+0

325

326

Appendix B

N

Answers to Exercises

ng2XdchigV^cng!%!)0 WddaZVcZm^hih2[VahZ0 [dg^ci_2%0_1^cYZm0_  ^[XjWZP_R#ZfjVah¹Bn8jWZº mg ¹mº ng Zm^hih2igjZ0 ^[Zm^hih22[VahZp$$^[i]ZgZ^hcdi]^c\i]ZgZ XjWZP^cYZmR2¹Bn8jWZº mg ¹mº ng0 $$h]dli]ZcZlanXgZViZYXjWZ [^aaXdadghPheVXZTcVbZP^R"&R0 gZXi,% mg*%!]Z^\]i"&%% ng*%!*%!*%0 cjb8jWZh 0 ^cYZm 0 r$$^[ ZahZp mg2me0ng2ne0 r ^[` 3&%%pYdcZ2&0WgZV`0r$$hV[ZinkVakZ r$$l]^aZ ^[YdcZ22&WgZV`0 r$$[dg r

Chapter 8 N O TE The answer to question 2 is not provided. 1. The algorithm is: h^oZ*%%!*%%!E(90 XVbZgV"'%!'%!"'%!%!%!%!%!%!&0 [dg[adVim2"&%0m1&%0m 2%#( [dg[adVin2"&%0n1&%0n 2%#( [dg[adVio2"&%0o1&%0o 2%#( ^[mm nn oo3&%%mm nn oo1&&% ed^cim!n!o0

3. The algorithm is: h^oZ*%%!*%%!E(90 XVbZgV"*!*!"'%!%!%!%!%!%!&0 [dg^cie]^2%0e]^1(+%0e]^ 2&%p [adVim2&%XdhgVY^Vche]^0 [adVin2&%h^cgVY^Vche]^0 ejh]BVig^m0

Appendix B igVchaViZm!n!%0 [adViVc\aZY2ViVc'n!m0 gdiViZOVc\aZY0 Wdm&0 edeBVig^m0 r

4. The algorithm is: h^oZ*%%!*%%!E(90 XVbZgV"'%!'%!"(%!%!%!%!%!%!&0 [dg^ci^2"(+0^1(+0^ p ejh]BVig^m0 gdiViZOgVY^Vch^&%0 igVchaViZ%!*!^$'#0 Wdm&!*!#'0 edeBVig^m0 r

5. The algorithm is: h^oZ*%%!*%%!E(90 XVbZgV"&%!&%!"'%!%!%!%!%!%!&0 WZ\^cH]VeZ0 [dg^ci^2%0^1)%0^ p [adVim2^$'''"&0 [adVin2^ &$'''"&0 [adVio2(%"^0 XjgkZKZgiZmm!n!o0 r ZcYH]VeZ0

6. The projection algorithm is: ^cimE[adViZnZp [adVii2&#%$&#% [adVio$ZnZ0 ^ciem2^cimh^ci nXdhi0 gZijgcem0 r ^cinE[adViZnZp [adVii2&#%$&#% [adVio$ZnZ0 ^cien2^cinh^ci"mXdhi0 gZijgcen0 r

N

Answers to Exercises

327

328

Appendix B

N

Answers to Exercises

The resulting project for a cubical line arrangement is shown here.

Chapter 9 1. First, create a class called Bn
Algorithms for Visual Design Using the Processing Language

Related documents

385 Pages • 70,630 Words • PDF • 20.8 MB

67 Pages • 23,079 Words • PDF • 4.5 MB

394 Pages • 151,941 Words • PDF • 46.5 MB

27 Pages • 1,560 Words • PDF • 625.7 KB

268 Pages • 98,143 Words • PDF • 3.5 MB

237 Pages • 65,623 Words • PDF • 7.4 MB

180 Pages • PDF • 26.1 MB