Tutorial

Using Visualization to Debug Visualization Software Robert S. Laramee ■ Swansea University

E

xperienced software engineers know that developing visualization software can be difficult. One of the first challenges lies simply in understanding the visualization algorithm itself. The implementation of visualization software poses special challenges due to both algorithm complexity and the large size of the data sets processed. Often, a bug will arise while you’re developing an algorithm. Finding and resolving it can be especially difficult if it appears only when you’re investigating large data sets or the computation involves many iterations. Because visualization software usually involves a large number of loops—for example, thousands, millions, or billions of computations for gigabytesized data sets—traditional methods for finding bugs become much less useful. For example, attempting to print out (and read) the state of millions of visualization primitives isn’t feasible. More advanced integrated development environments (IDEs) offer better debugging support, such as setting break points and reporting the state of userspecified variables at runtime. But again, these tools might not be useful when the computation involves iterations numbering in the thousands, millions, or more. Programmers would like to see precisely where and when in the space-time domain errors occur—a capability that IDEs can’t offer. To my knowledge, no one has developed general guidelines for debugging visualization software (the sidebar offers examples of more specific research). So, I offer here a set of such guidelines that I developed with my colleagues in Swansea University’s Visual and Interactive Computing Group. These guidelines are based on several years’ experience implementing scientific (volume and flow) visualization software and helping others Published by the IEEE Computer Society

resolve their bugs. The key to debugging visualization software is to exploit the strengths of computer graphics and visualization. In other words, you take advantage of visualization’s key value1— the ability to quickly summarize and convey large amounts of information to the viewer—to find and fix problems arising as you implement visualization techniques. In tandem, you also employ traditional good development practices.

Visualize Tests and Comparisons

The guidelines in this article Most visualization algorithms in- come from experience in volve tests and comparisons be- developing applications for tween two or more visualization both industry and research. primitives. By visualization prim- The key is to exploit the itives, I mean the basic elements strengths of computer to which data is mapped—for graphics and visualization, example, points, lines, polygons, while still using good software voxels, texels, and tetrahedrons. A general technique for finding development practices. errors in visualization software is to visualize a test or comparison between two or more primitive objects at runtime. This often involves highlighting a given object oa (the current primitive) in one color and another object ob, against which you compare oa, in another color (in an iterative process). This strategy tells the developer ■■

■■

whether oa and ob actually are the expected primitives to test and compare and whether the test yields the correct result.

For example, we implemented a streamlinetracing algorithm on boundary meshes from computational fluid dynamics2 (see Figure 1). Such an algorithm poses challenges because the meshes

0272-1716/10/$26.00 © 2010 IEEE

IEEE Computer Graphics and Applications

67

Tutorial

In our implementation, some streamlines terminated too early, at what appeared to be random times. So, we implemented a debugging feature that highlighted ■■

■■

Figure 1. Visualizing tests and comparisons: streamlines traced on an unstructured, adaptiveresolution grid. The colors indicate velocity.3 This article describes a way to debug streamline-tracing (and other) algorithms. (Source: Zhenmin Peng; used with permission.)

An efficient line segment intersection test will first test whether the line segments are parallel (in which case they don’t intersect).4 As soon as we added the highlighting, it became clear that the test for parallelism wasn’t stringent enough. In other words, when sa and sb were close to (but not quite) parallel, some streamlines terminated too early (because the test found no intersection).

Visualize Data Structure Traversal and Evolution Almost all visualization techniques use at least one data structure. When debugging visualization software, you can visualize both the traversal and evolution of the data structure as it’s being built. The visualization of the traversal can also show and identify neighbors, either implicit or explicit. For example, we implemented a vector-field clustering algorithm that builds a binary-tree hierarchy from the bottom up. Each leaf represents a cluster, which at the finest resolution maps to a single pixel in image space. To debug the algorithm, we added a feature that visualizes the clustering algorithm as it evolves at runtime. The visualization highlights ■■

Figure 2. Visualizing data structure traversal and evolution. The current cluster (the middle of the image) is bright green, whereas current neighbors are a shade of red. The image also shows previously processed clusters. Visualizing data structure evolution is a key debugging technique. (Source: Zhenmin Peng; used with permission.)

are unstructured and have adaptive resolution. Streamline tracing involves three basic computations: point location, interpolation, and integration, evaluated for each point along the curve. The most difficult step is point location because the meshes are unstructured and streamlines can intersect vertices in the mesh. During point location, it’s useful to track where a streamline exits one polygon and enters the next. This involves a line segment intersection test. 68

November/December 2010

the newly computed (current) streamline segment sa and the triangle segment sb, which we tested to see whether it intersected s a.

■■ ■■ ■■

the the the the

current cluster, ca; north, south, east, and west neighbors of ca; neighbor chosen to merge with ca; and previous clusters formed.

Figure 2 shows a snapshot of the visualization. Such visualizations help verify that the algorithm behaves as expected—for example, that it traverses the data structure in the correct order, it properly locates and compares neighbors, and new clusters form as expected. Another example in Figure 3 visualizes a quadtree that stores adaptive-resolution data from a height field, together with a coastal land map.

Classify and Color-Map You can also classify and color-map visualization primitives. Data objects fall into different categories and have different values and attributes. Color-

mapping their characteristics can provide useful debugging information. We used this strategy while implementing an integral surface-construction algorithm (see Figure 4).5 The surfaces consist of dynamic quad meshes. During surface construction, quads can split owing to divergent flow, merge in convergent flow, and warp in shear flow. So, we color-coded the quads according to divergence, convergence, and shear. This proved not only a useful debugging tool but also a nice visualization of surface characteristics. Patricia Crossno and Edward Angel used this strategy to debug a particle visualization system.6 Their debugging options include mapping particle color to energy level, type, amount of repulsion, number of neighboring links, and age. (For more on their research and other research in debugging visualization software, see the sidebar.)

Figure 3. Another example of visualizing data structure traversal and evolution: a quadtree that stores adaptive-resolution data from a height field, together with a coastal land map. Rendering the quadtree data structure aids in verifying its correctness. (Source: Edward Grundy; used with permission.)

Incorporate Algorithm Parameters into the User Interface Any new algorithm inevitably introduces new parameters—for example, threshold values, alpha values, special distances, and minimum and maximum values. Identifying, discussing, and visualizing these parameters is an effective debugging strategy. In addition, illustrating the effect of setting these parameters to a range of different values is instructive and helps the user understand the presented algorithm or method. During any implementation, the best value of any new parameter is generally unknown. So, it’s best to implement new parameters as user options because their value might change depending on the data set being evaluated. After thoroughly testing the new parameter, the user might give it an optimal default value. Bruno Jobard and Wilfrid Lefer introduced two parameters:7 ■■

■■

dsep is the separating distance between streamlines. dtest is the distance determining when a streamline is terminated.

They presented both as user options and illustrated each one’s effects. Jobard and his colleagues7,8 and Jarke van Wijk9 provided further good discussions of algorithm parameters and their effects.

Run Simple Error Checks Don’t forget to run simple sanity checks on your visualization primitives and data structures. A sim

Divergence Convergence Left rotation Right rotation Laminar flow

Figure 4. Classifying and color-mapping. Each quad in the stream surface mesh is classified and color-mapped to reflect the flow-field characteristics. This helps visualize the individual mesh elements’ behavior. (Source: Tony McLoughlin; used with permission.)

ple, generic error-checking procedure (for example, checkState()) can check your data objects for basic properties (for example, point locations; edge lengths; minimum, average, and maximum data values; and boundary conditions), testing whether an object’s attributes are all within reasonable, expected bounds. You can then invoke a general error-checking function at any time through the visualization pipeline to catch updates causing unexpected changes. For example, while developing an isosurfacing algorithm for adaptive-resolution data,10 we IEEE Computer Graphics and Applications

69

Tutorial

Related Work in Debugging Visualization Software

A

llan Wong and his colleagues presented a tool that uses visualization to debug mobile object-based distributed programs.1 Chris Laffra and Ashok Malhotra described a generic visual approach to debugging C++ programs that uses bar charts.2 Randi Rost also gave guidelines on debugging vertex and fragment shaders in Chapter 8.3 of OpenGL Shading Language.3 Patricia Crossno and Edward Angel described debugging tools incorporated in their particle visualization system.4 Although previous papers cover algorithm visualization and animation, Crossno and Angel’s paper is the only one I found that specifically covered debugging visualization. They explained how they map different properties of dynamic particles to color. However, their explanation was system specific, and they didn’t provide general guidelines. For more on their approach, see the “Classify and Color-Map” section in the main article. The main article, together with my two “How to Write a Visu­ alization Research Paper” articles,5,6 “How to Read a Visualization Research Paper,”7 and “Bob’s Concise Coding Conventions,”8 form what I call “Bob’s PhD in Visualization Starter Kit.” I’ve intended them to be useful tools for visualization PhD students and visualization scientists in general.

References 1. A. Wong et al., “A Generic Visualization Framework to Help Debug Mobile-Object-Based Distributed Programs Running on Large Networks,” Proc. 6th Int’l Workshop Object-Oriented Real-Time Dependable Systems (Words 01), IEEE CS Press, 2001 pp. 240–247. 2. C. Laffra and A. Malhotra, “HotWire: A Visual Debugger for C++,” Proc. 6th Usenix C++ Tech. Conf. (CTEC 94), Usenix Assoc., 1994, pp. 109–122. 3. R.J. Rost, OpenGL Shading Language, 2nd ed., Addison-Wesley, 2006. 4. P. Crossno and E. Angel, “Visual Debugging of Visualization Software: A Case Study for Particle Systems,” Proc. IEEE Visualization ’99, IEEE Press, 1999, pp. 417–420. 5. R.S. Laramee, “How to Write a Visualization Research Paper: A Starting Point,” to be published in Computer Graphics Forum, 2010; www. cs.swan.ac.uk/~csbob/research/how2write/laramee09how2write.pdf. 6. R.S. Laramee, “How to Write a Visualization Research Paper: The Art and Mechanics,” Eurographics Education Papers 2009, Eurographics, 2009, pp. 59–66. 7. R.S. Laramee, How to Read a Visualization Research Paper: Extracting the Essentials, tech. report, Computer Science Dept., Swansea Univ., 2007. 8. R.S. Laramee, “Bob’s Concise Coding Conventions (C3),” Advances in Computer Science and Eng., vol. 4, no. 1, 2010, pp. 23–36.

encountered a bug that caused cracks in the surfaces. The algorithm uses an adaptive-resolution space-partitioning octree in which internal nodes store their children’s minimum and maximum data values. This error was difficult to pin down 70

November/December 2010

because it occurred only at data resolutions of 1283 or greater (not at 643 or smaller). To track down the error, we implemented a simple, generic error-checking procedure that examined ■■

■■

the locations of triangle vertices, testing to see whether they fell outside their associated cube, and the maximum and minimum data values of each octree node to ensure that all child values fell within this range.

We then recomputed the values and compared them to stored values. This function traversed the entire octree and could be called at any time. By invoking the function at every stage of our visualization algorithm, we could quickly track down the procedures causing surface discontinuities. Another common example involves surface shading. Many programmers run into simple bugs involving polygon shading (for example, see Figure 5). A standard user option for fixing shading bugs is to render the normal vectors of each polygon or surface vertex as a small glyph. The glyphs depict the orientation of each normal vector at the surface. We regularly resolve bugs this way.

Introduce a Step Function Most visualization algorithms involve computation that iterates, perhaps over each data item and over each pass through the data or data structure. Incorporate a pause button in the user interface that lets the user interrupt the execution between each iteration. The user can then examine the current scene in more detail. Pressing the pause button again then executes exactly one loop of the algorithm. With this feature, the user can step through program execution at runtime, one iteration (or loop) at a time. For example, while developing a streak-surface algorithm, we introduced a step function that can stop program execution after each time step. When the user hits the space bar, the simulation data’s next time step is visualized and the processing stops again. This lets the user examine the surface’s properties after each pass through the mesh data structure representing it. This helped us quickly identify operations on the mesh that reduced its quality.

Use Still-Image-Driven Animation Some types of bugs occur infrequently—for example, only after several time steps of data have been processed and visualized. You might be watching an animation of your visualization—for example,

as a data structure is traversed—and notice a bug only after several seconds (or even minutes) of observation. The point in time when you recognized the error might be too late for you to slow down or interrupt the algorithm, say, by invoking a step function. Stopping the process and starting all over is painful and time-consuming. In this case, it’s useful to employ a feature that saves still images of the visualization at each frame buffer update. We recommend adding a user option to your software or system that automatically ■■

■■

resizes the viewer to 5122 pixels (old MPEG players can only handle movie resolutions that are a power of two) and saves each frame as a still image in JPEG (or PNG) format.

The still images become input to an application that can play them back. We use Adobe Premiere (www.adobe.com/products/premiere) because of its rich feature set. It’s expensive, but there are free alternatives, such as VideoMach (http:// gromada.com/videomach/videomach.php). However, VideoMach isn’t so feature-rich. Most builtin file browsers of modern OSs support scrolling through still images. You can then replay, pause, and rewind the still images as needed to study when and under which circumstances the bug occurred. You can skip or delete uninteresting frames. Saving and replaying still images can save considerable time and help you track down infrequent bugs or study an algorithm’s behavior. You can supplement the images with useful metadata, such as time steps, that help locate and reproduce the error. This approach is also good for showing the error to others. We consider this a standard feature for visualization applications. We also use it to generate supplementary movie material for research paper submissions. I discuss this topic in more detail elsewhere.11

Test Algorithms on a Variety of Data Sets Use these guidelines for choosing test data sets: ■■

■■

■■



When first developing a visualization algorithm, test it on simpler data sets with which you’re very familiar. This way, you’ll know what to expect. If possible, create your own data generator for small synthetic data sets with known characteristics. When debugging, find the smallest data set that produces the problem. After the visualization exhibits the expected behavior on the smaller,

Figure 5. Running simple error checks. A shading bug appears around the edges of this surface. In this case, the bug was caused by reversing the calls to glNormal() and glVertex(). Rendering the surface normals makes this bug immediately apparent. (Source: Matthew Edmunds; used with permission.)

■■

more familiar data sets, test it on larger, more complex, and less familiar ones. Test your algorithm on a variety of data sets.

Believing that an algorithm works after testing only a few small, simple data sets is a common mistake.

Exploit and Compare with Previous Research Chances are you’re not the first person to visualize a given data set. Compare your visualizations with their predecessors. This guideline seems simple and obvious, but we regularly see colleagues overlook it. Also, don’t hesitate to communicate with those who have already worked with a given data set. Normally, colleagues will be happy to share their experiences and important unpublished information.

Exclusively Use Accessor Methods All class variables are accessed through accessor methods—that is, Get() and Set() methods such as GetClassVariable() and SetClassVariable(int newValue). We advocate no exceptions to this rule. Using accessor methods enforces encapsulation. (Rebecca Wirfs-Brock and her colleagues provided more on this topic.12) Accessing member variables with methods makes changing the implementation easy—for example, a float to an int. This IEEE Computer Graphics and Applications

71

Tutorial

methodology also prevents unwieldy (or even impossible) search-and-replace operations.13 Another advantage of accessor methods concerns object state. If you perform class variable assignment exclusively through Set() methods, you can ensure that your objects’ state is always valid. This is because Set() methods perform error and bounds checking on the parameters passed to the procedure. Following this convention leads to robust code.

Follow Coding Conventions Following coding conventions helps pave the way to a successful software application. Why? Because legible software is better. It has fewer bugs, is more stable, and makes developers happier. Legible software’s other two key ingredients are code comment conventions (for example, Doxygen; www. doxygen.org) and good design,12 which coding conventions can help facilitate. Coding conventions enable software reuse. Big projects require multiple, coordinated developers over several years. Also, you generally shouldn’t start applications from scratch.14 Even so, software developers frequently start projects from scratch— repeatedly reinventing the wheel. A major problem stems from source code that doesn’t follow any conventions and isn’t legible. Illegible code is untouchable, or nonmodifiable. As such, it quickly turns into legacy code. Writing illegible code is easy and is generally the default. We’ve encountered numerous instances of programmers who can’t even read their own code. I’ve presented coding conventions15 influenced by coding standards and guidelines from other sources, including the Visualization Toolkit (VTK),16 Sun Microsystems,13 Scott Meyers,17,18 and Michael Dickheiser.19 These conventions are concise, so print them out and hang them up for ease of use. The basic philosophy behind them is that you should maximize code legibility, which in turn helps maximize code reuse, good design, and flexibility.

Describe the Problem to Others If you run into an implementation error, describe the problem to someone in enough detail that the listener actually understands it. Often, you’ll realize the problem’s possible sources as you describe it. Every programmer has experienced this phenomenon at least once. This tactic might be effective because it encourages the speaker to describe the algorithm step-by-step to an audience. Breaking the process down into smaller steps might help identify missteps. 72

November/December 2010

T

his article provides useful strategies for debugging visualization software; I hope that visualization students and developers will use them. They are, however, just one piece of a larger PhD in visualization starter kit (PVSK) that I hope to develop further. Future work includes incorporating some of these guidelines directly into an IDE.

Acknowledgments I especially thank Eugene Zhang of Oregon State University for asking me to write down these debugging guidelines. Jarke van Wijk of the Eindhoven University of Technology provided feedback that improved the content. Min Chen of Swansea University, Amitabh Varshney of the University of Maryland, College Park, and Hamish Carr of the University of Leeds also provided valuable discussion on the topic. Dan Lipsa of Armstrong Atlantic State University contributed valuable feedback and proofreading. Zhenmin Peng, Edward Grundy, Tony McLoughlin, and Matthew Edmunds of Swansea University provided images. EPSRC Grant EP/F002335/1 partly supported this research. I encourage you to send your questions, comments, and feedback concerning these guidelines to me at [email protected].

References 1. J.J. van Wijk, “Views on Visualization,” IEEE Trans. Visualization and Computer Graphics, vol. 12, no. 4, 2006, pp. 421–432. 2. R. Laramee et al., “Investigating Swirl and Tumble Flow with a Comparison of Visualization Tech­ niques,” Proc. IEEE Visualization 2004, IEEE Press, 2004, pp. 51–58. 3. Z. Peng et al., “Glyph and Streamline Placement Algorithms for CFD Simulation Data,” NAFEMS World Congress Conf. Proc. (NWC), NAFEMS, 2009, p. 66. 4. T. Möller and E. Haines, Real-Time Rendering, 2nd ed., A.K. Peters, 2002. 5. T. McLoughlin, R.S. Laramee, and E. Zhang, “Easy Integral Surfaces: A Fast, Quad-Based Stream and Path Surface Algorithm,” Proc. Computer Graphics Int’l (CGI 09), Springer, 2009, pp. 67–76. 6. P. Crossno and E. Angel, “Visual Debugging of Visualization Software: A Case Study for Particle Systems,” Proc. IEEE Visualization ’99, IEEE Press, 1999, pp. 417–420. 7. B. Jobard and W. Lefer, “Creating Evenly Spaced Streamlines of Arbitrary Density,” Proc. Eurographics Workshop Visualization in Scientific Computing ’97, vol. 7, Eurographics, 1997, pp. 45–55. 8. B. Jobard, G. Erlebacher, and Y. Hussaini, “Lagrangian-

Eulerian Advection of Noise and Dye Textures for Unsteady Flow Visualization,” IEEE Trans. Visualization and Computer Graphics, vol. 8, no. 3, 2002, pp. 211–222. 9. J.J. van Wijk, “Image Based Flow Visualization,” ACM Trans. Graphics, vol. 21, no. 3, 2002, pp. 745–754. 10. R.S. Laramee and R.D. Bergeron, “An Isosurface Continuity Algorithm for Super Adaptive Resolution Data,” Advances in Modelling, Animation, and Rendering: Computer Graphics International (CGI 02), Springer, 2002, pp. 215–237. 11. R.S. Laramee, “How to Write a Visualization Research Paper: A Starting Point,” to be published in Computer Graphics Forum, 2010; www.cs.swan.ac.uk/~csbob/ research/how2write/laramee09how2write.pdf. 12. R. Wirfs-Brock, B. Wilkerson, and L. Wiener, Designing Object-Oriented Software, Prentice-Hall, 1990. 13. Code Conventions for the Java Programming Language, Sun Microsystems, Apr. 1999. 14. R.S. Laramee, “Comparing and Evaluating Computer Graphics and Visualization Software,” Software: Practice and Experience, vol. 38, no. 7, 2008, pp. 735–760. 15. R.S. Laramee, “Bob’s Concise Coding Conventions

(C3),” Advances in Computer Science and Eng., vol. 4, no. 1, 2010, pp. 23–36. 16. W.J. Schroeder, K.M. Martin, and W.E. Lorensen, The Visualization Toolkit: An Object-Oriented Approach to 3D Graphics, 2nd ed., Prentice-Hall, 1998. 17. S. Meyers, More Effective C++: 35 New Ways to Improve Your Programs and Design, Addison-Wesley, 1996. 18. S. Meyers, Effective C++: 55 Specific Ways to Improve Your Programs and Designs, Addison-Wesley, 2005. 19. M.J. Dickheiser, C++ for Game Programmers, 2nd ed., Charles River Media, 2007.

Robert S. Laramee is a lecturer at Swansea University’s Department of Computer Science. His research interests are scientific visualization, computer graphics, and human-computer interaction. Laramee has a PhD from the Vienna University of Technology’s Institute of Computer Graphics and Algorithms. Contact him at [email protected]; http:// cs.swan.ac.uk/~csbob. Selected CS articles and columns are also available for free at http://ComputingNow.computer.org.

EXECUTIVE STAFF PURPOSE: The IEEE Computer Society is the world’s largest association of computing professionals and is the leading provider of technical information in the field. MEMBERSHIP: Members receive the monthly magazine Computer, discounts, and opportunities to serve (all activities are led by volunteer members). Membership is open to all IEEE members, affiliate society members, and others interested in the computer field. COMPUTER SOCIETY WEBSITE: www.computer.org Next Board Meeting: 15–16 Nov. 2010, New Brunswick, NJ, USA

EXECUTIVE COMMITTEE President: James D. Isaak* President-Elect: Sorel Reisman;* Past President: Susan K. (Kathy) Land, CSDP;* VP, Standards Activities: Roger U. Fujii (1st VP);* Secretary: Jeffrey M. Voas (2nd VP);* VP, Educational Activities: Elizabeth L. Burd;* VP, Member & Geographic Activities: Sattupathu V. Sankaran;† VP, Publications: David Alan Grier;* VP, Professional Activities: James W. Moore;* VP, Technical & Conference Activities: John W. Walz;* Treasurer: Frank E. Ferrante;* 2010–2011 IEEE Division V Director: Michael R. Williams;† 2009–2010 IEEE Division VIII Director: Stephen L. Diamond;† 2010 IEEE Division VIII DirectorElect: Susan K. (Kathy) Land, CSDP;* Computer Editor in Chief: Carl K. Chang†

Executive Director: Angela R. Burgess; Associate Executive Director, Director, Governance: Anne Marie Kelly; Director, Finance & Accounting: John Miller; Director, Information Technology & Services: Ray Kahn; Director, Membership Development: Violet S. Doan; Director, Products & Services: Evan Butterfield; Director, Sales & Marketing: Dick Price

COMPUTER SOCIETY OFFICES Washington, D.C.: 2001 L St., Ste. 700, Washington, D.C. 20036 Phone: +1 202 371 0101 • Fax: +1 202 728 9614 Email: [email protected] Los Alamitos: 10662 Los Vaqueros Circle, Los Alamitos, CA 90720-1314 Phone: +1 714 821 8380 • Email: [email protected] MEMBERSHIP & PUBLICATION ORDERS Phone: +1 800 272 6657 • Fax: +1 714 821 4641 • Email: [email protected] Asia/Pacific: Watanabe Building, 1-4-2 Minami-Aoyama, Minato-ku, Tokyo 107-0062, Japan Phone: +81 3 3408 3118 • Fax: +81 3 3408 3553 Email: [email protected]

IEEE OFFICERS

President: Pedro A. Ray; President-Elect: Moshe Kam; Past President: John R. Vig; Secretary: David G. Green; Treasurer: Peter W. Staecker; President, Standards Association Board of Governors: W. Charlston *voting member of the Board of Governors †nonvoting member of the Board of Governors Adams; VP, Educational Activities: Tariq S. Durrani; VP, Membership & Geographic Activities: Barry L. Shoop; VP, Publication Services & BOARD OF GOVERNORS Products: Jon G. Rokne; VP, Technical Activities: Roger D. Pollard; IEEE Term Expiring 2010: Piere Bourque; André Ivanov; Phillip A. Laplante; Itaru Division V Director: Michael R. Williams; IEEE Division VIII Director: Mimura; Jon G. Rokne; Christina M. Schober; Ann E.K. Sobel Stephen L. Diamond; President, IEEE-USA: Evelyn H. Hirt Term Expiring 2011: Elisa Bertino, George V. Cybenko, Ann DeMarle, David S. Ebert, David A. Grier, Hironori Kasahara, Steven L. Tanimoto Term Expiring 2012: Elizabeth L. Burd, Thomas M. Conte, Frank E. revised 10 Sept. 2010 Ferrante, Jean-Luc Gaudiot, Luis Kun, James W. Moore, John W. Walz



IEEE Computer Graphics and Applications

73

Using visualization to debug visualization software.

Using visualization to debug visualization software. - PDF Download Free
5MB Sizes 4 Downloads 3 Views