Thursday, October 22, 2009

KDE 4.3.2 ..... awsome !!!!

yestarday, i have shifted from ubuntu to kubuntu. I love KDE4.3.2. I heard KDE team fixed 10,000 bugs from 4.2 release to stabilize 4.3. It's a lot of work and now the KDE is awsome smooth. And it also consumes lot less RAM than Radmond OSes. It's working more smoother for me than ubuntu.

Here's a look of my desktop:




 

Tuesday, October 20, 2009

MacPaint source ....... where ?



yesterday, i was reading Coders at work in which donald knuth pointed out that MacPaint is the one of the best code ever written and it's source code is donated to Computer History Museum (CHM). So, today i am searching for it's source code. But after 4 hours i still can't find it anywhere on the net. CHM website has a page for this, but  no link for downloading source code. It turns out that it is due to legal issues. Apple still didn't provide rights to CHM for MacPaint. So, i have to wait ..............................

link at CHM:

Tuesday, October 13, 2009

Computer Science Education: Where Are the Software Engineers of Tomorrow?

It is our view that Computer Science (CS) education is neglecting basic skills, in particular in the areas of programming and formal methods. We consider that the general adoption of Java as a first programming language is in part responsible for this decline. We examine briefly the set of programming skills that should be part of every software professional’s repertoire.
It is all about programming! Over the last few years we have noticed worrisome trends in CS education. The following represents a summary of those trends:

  1. Mathematics requirements in CS programs are shrinking.
  2. The development of programming skills in several languages is giving way to cookbook approaches using large libraries and special-purpose packages.
  3. The resulting set of skills is insufficient for today’s software industry (in particular for safety and security purposes) and, unfortunately, matches well what the outsourcing industry can offer. We are training easily replaceable professionals.
These trends are visible in the latest curriculum recommendations from the Association for Computing Machinery (ACM). Curriculum 2005 does not mention mathematical prerequisites at all, and it mentions only one course in the theory of programming languages [1].
We have seen these developments from both sides: As faculty members at New York University for decades, we have regretted the introduction of Java as a first language of instruction for most computer science majors. We have seen how this choice has weakened the formation of our students, as reflected in their performance in systems and architecture courses. As founders of a company that specializes in Ada programming tools for mission-critical systems, we find it harder to recruit qualified applicants who have the right foundational skills. We want to advocate a more rigorous formation, in which formal methods are introduced early on, and programming languages play a central role in CS education.
Formal Methods and Software Construction
Formal techniques for proving the correctness of programs were an extremely active subject of research 20 years ago. However, the methods (and the hardware) of the time prevented these techniques from becoming widespread, and as a result they are more or less ignored by most CS programs. This is unfortunate because the techniques have evolved to the point that they can be used in large-scale systems and can contribute substantially to the reliability of these systems. A case in point is the use of SPARK in the re-engineering of the ground-based air traffic control system in the United Kingdom (see a description of iFACTS – Interim Future Area Control Tools Support, at ). SPARK is a subset of Ada augmented with assertions that allow the designer to prove important properties of a program: termination, absence of run-time exceptions, finite memory usage, etc. [2]. It is obvious that this kind of design and analysis methodology (dubbed Correctness by Construction) will add substantially to the reliability of a system whose design has involved SPARK from the beginning. However, PRAXIS, the company that developed SPARK and which is designing iFACTS, finds it hard to recruit people with the required mathematical competence (and this is present even in the United Kingdom, where formal methods are more widely taught and used than in the United States).
Another formal approach to which CS students need exposure is model checking and linear temporal logic for the design of concurrent systems. For a modern discussion of the topic, which is central to mission-critical software, see [3].
Another area of computer science which we find neglected is the study of floating-point computations. At New York University, a course in numerical methods and floating-point computing used to be required, but this requirement was dropped many years ago, and now very few students take this course. The topic is vital to all scientific and engineering software and is semantically delicate. One would imagine that it would be a required part of all courses in scientific computing, but these often take MatLab to be the universal programming tool and ignore the topic altogether.
The Pitfalls of Java as a First Programming Language
Because of its popularity in the context of Web applications and the ease with which beginners can produce graphical programs, Java has become the most widely used language in introductory programming courses. We consider this to be a misguided attempt to make programming more fun, perhaps in reaction to the drop in CS enrollments that followed the dot-com bust. What we observed at New York University is that the Java programming courses did not prepare our students for the first course in systems, much less for more advanced ones. Students found it hard to write programs that did not have a graphic interface, had no feeling for the relationship between the source program and what the hardware would actually do, and (most damaging) did not understand the semantics of pointers at all, which made the use of C in systems programming very challenging.
Let us propose the following principle: The irresistible beauty of programming consists in the reduction of complex formal processes to a very small set of primitive operations. Java, instead of exposing this beauty, encourages the programmer to approach problem-solving like a plumber in a hardware store: by rummaging through a multitude of drawers (i.e. packages) we will end up finding some gadget (i.e. class) that does roughly what we want. How it does it is not interesting! The result is a student who knows how to put a simple program together, but does not know how to program. A further pitfall of the early use of Java libraries and frameworks is that it is impossible for the student to develop a sense of the run-time cost of what is written because it is extremely hard to know what any method call will eventually execute. A lucid analysis of the problem is presented in [4].
We are seeing some backlash to this approach. For example, Bjarne Stroustrup reports from Texas A & M University that the industry is showing increasing unhappiness with the results of this approach. Specifically, he notes the following:

I have had a lot of complaints about that [the use of Java as a first programming language] from industry, specifically from AT&T, IBM, Intel, Bloomberg, NI, Microsoft, Lockheed-Martin, and more. [5]
He noted in a private discussion on this topic, reporting the following:

It [Texas A&M] did [teach Java as the first language]. Then I started teaching C++ to the electrical engineers and when the EE students started to out-program the CS students, the CS department switched to C++. [5]
It will be interesting to see how many departments follow this trend. At AdaCore, we are certainly aware of many universities that have adopted Ada as a first language because of similar concerns.
A Real Programmer Can Write in Any Language (C, Java, Lisp, Ada)
Software professionals of a certain age will remember the slogan of old-timers from two generations ago when structured programming became the rage: Real programmers can write Fortran in any language. The slogan is a reminder of how thinking habits of programmers are influenced by the first language they learn and how hard it is to shake these habits if you do all your programming in a single language. Conversely, we want to say that a competent programmer is comfortable with a number of different languages and that the programmer must be able to use the mental tools favored by one of them, even when programming in another. For example, the user of an imperative language such as Ada or C++ must be able to write in a functional style, acquired through practice with Lisp and ML1, when manipulating recursive structures. This is one indication of the importance of learning in-depth a number of different programming languages. What follows summarizes what we think are the critical contributions that well-established languages make to the mental tool-set of real programmers. For example, a real programmer should be able to program inheritance and dynamic dispatching in C, information hiding in Lisp, tree manipulation libraries in Ada, and garbage collection in anything but Java. The study of a wide variety of languages is, thus, indispensable to the well-rounded programmer.
Why C Matters
C is the low-level language that everyone must know. It can be seen as a portable assembly language, and as such it exposes the underlying machine and forces the student to understand clearly the relationship between software and hardware. Performance analysis is more straightforward, because the cost of every software statement is clear. Finally, compilers (GCC for example) make it easy to examine the generated assembly code, which is an excellent tool for understanding machine language and architecture.
Why C++ Matters
C++ brings to C the fundamental concepts of modern software engineering: encapsulation with classes and namespaces, information hiding through protected and private data and operations, programming by extension through virtual methods and derived classes, etc. C++ also pushes storage management as far as it can go without full-blown garbage collection, with constructors and destructors.
Why Lisp Matters
Every programmer must be comfortable with functional programming and with the important notion of referential transparency. Even though most programmers find imperative programming more intuitive, they must recognize that in many contexts that a functional, stateless style is clear, natural, easy to understand, and efficient to boot.
An additional benefit of the practice of Lisp is that the program is written in what amounts to abstract syntax, namely the internal representation that most compilers use between parsing and code generation. Knowing Lisp is thus an excellent preparation for any software work that involves language processing.
Finally, Lisp (at least in its lean Scheme incarnation) is amenable to a very compact self-definition. Seeing a complete Lisp interpreter written in Lisp is an intellectual revelation that all computer scientists should experience.
Why Java Matters
Despite our comments on Java as a first or only language, we think that Java has an important role to play in CS instruction. We will mention only two aspects of the language that must be part of the real programmer’s skill set:

  1. An understanding of concurrent programming (for which threads provide a basic low-level model).
  2. Reflection, namely the understanding that a program can be instrumented to examine its own state and to determine its own behavior in a dynamically changing environment.
Why Ada Matters
Ada is the language of software engineering par excellence. Even when it is not the language of instruction in programming courses, it is the language chosen to teach courses in software engineering. This is because the notions of strong typing, encapsulation, information hiding, concurrency, generic programming, inheritance, and so on, are embodied in specific features of the language. From our experience and that of our customers, we can say that a real programmer writes Ada in any language. For example, an Ada programmer accustomed to Ada’s package model, which strongly separates specification from implementation, will tend to write C in a style where well-commented header files act in somewhat the same way as package specs in Ada. The programmer will include bounds checking and consistency checks when passing mutable structures between subprograms to mimic the strong-typing checks that Ada mandates [6]. She will organize concurrent programs into tasks and protected objects, with well-defined synchronization and communication mechanisms.
The concurrency features of Ada are particularly important in our age of multi-core architectures. We find it surprising that these architectures should be presented as a novel challenge to software design when Ada had well-designed mechanisms for writing safe, concurrent software 30 years ago.
Programming Languages Are Not the Whole Story
A well-rounded CS curriculum will include an advanced course in programming languages that covers a wide variety of languages, chosen to broaden the understanding of the programming process, rather than to build a résumé in perceived hot languages. We are somewhat dismayed to see the popularity of scripting languages in introductory programming courses. Such languages (Javascript, PHP, Atlas) are indeed popular tools of today for Web applications. Such languages have all the pedagogical defaults that we ascribe to Java and provide no opportunity to learn algorithms and performance analysis. Their absence of strong typing leads to a trial-and-error programming style and prevents students from acquiring the discipline of separating design of interfaces from specifications.
However, teaching the right languages alone is not enough. Students need to be exposed to the tools to construct large-scale reliable programs, as we discussed at the start of this article. Topics of relevance are studying formal specification methods and formal proof methodologies, as well as gaining an understanding of how high-reliability code is certified in the real world. When you step into a plane, you are putting your life in the hands of software which had better be totally reliable. As a computer scientist, you should have some knowledge of how this level of reliability is achieved. In this day and age, the fear of terrorist cyber attacks have given a new urgency to the building of software that is not only bug free, but is also immune from malicious attack. Such high-security software relies even more extensively on formal methodologies, and our students need to be prepared for this new world.
References

  1. Joint Taskforce for Computing Curricula. “Computing Curricula 2005: The Overview Report.” ACM/AIS/ IEEE, 2005 .
  2. Barnes, John. High Integrity Ada: The Spark Approach. Addison-Wesley, 2003.
  3. Ben-Ari, M. Principles of Concurrent and Distributed Programming. 2nd ed. Addison-Wesley, 2006.
  4. Mitchell, Nick, Gary Sevitsky, and Harini Srinivasan. “The Diary of a Datum: An Approach to Analyzing Runtime Complexity in Framework-Based Applications.” Workshop on Library-Centric Software Design, Object-Oriented Programming, Systems, Languages, and Applications, San Diego, CA, 2005.
  5. Stroustrup, Bjarne. Private communication. Aug. 2007.
  6. Holzmann Gerard J. “The Power of Ten – Rules for Developing Safety Critical Code.” IEEE Computer June 2006: 93-95.
Note

  1. Several programming language and system names have evolved from acronyms whose formal spellings are no longer considered applicable to the current names for which they are readily known. ML, Lisp, GCC, PHP, and SPARK fall under this category.

About the Authors
Dr. Robert B.K. Dewar Robert B.K. Dewar, Ph.D., is president of AdaCore and a professor emeritus of computer science at New York University. He has been involved in the design and implementation of Ada since 1980 as a distinguished reviewer, a member of the Ada Rapporteur group, and the chief architect of Gnu Ada Translator. He was a member of the Algol68 committee and is the designer and implementor of Spitbol. Dewar lectures widely on programming languages, software methodologies, safety and security, and on intellectual property rights. He has a doctorate in chemistry from the University of Chicago.

AdaCore
104 Fifth AVE 15th FL
New York, NY 10011
Phone: (212) 620-7300 ext. 100
Fax: (212) 807-0162
E-mail: dewar@adacore.com


Dr. Edmond Schonberg Edmond Schonberg, Ph.D., is vice-president of AdaCore and a professor emeritus of computer science at New York University. He has been involved in the implementation of Ada since 1981. With Robert Dewar and other collaborators, he created the first validated implementation of Ada83, the first prototype compiler for Ada9X, and the first full implementation of Ada2005. Schonberg has a doctorate in physics from the University of Chicago.

AdaCore
104 Fifth AVE 15th FL
New York, NY 10011
E-mail: schonberg@adacore.com

Thursday, October 8, 2009

An inteview with Brian Kernighan (october 6, 2009)

You maintain you had no part in the birth of C, but do you think the language would have been as successful as it has been without the book?
Brian Kernighan: The word is not ‘maintained’; it's ‘stated accurately’. C is entirely Dennis Ritchie's work. C would have done just fine on its own, since as a language it achieved a perfect balance among efficiency, expressiveness, and power. The book probably helped, though I think more in spreading the language early on than in its ultimate acceptance. Of course, it helped enormously to have Dennis as co-author, for his expertise and his writing.
In the ten years since you launched The Practice of Programming, a separate book written with Rob Pike, has the way programmers operate changed enough for you to consider amending any parts of the publication?
Programming today depends more and more on combining large building blocks and less on detailed logic of little things, though there's certainly enough of that as well. A typical programmer today spends a lot of time just trying to figure out what methods to call from some giant package and probably needs some kind of IDE like Eclipse or XCode to fill in the gaps. There are more languages in regular use and programs are often distributed combinations of multiple languages. All of these facts complicate life, though it's possible to build quite amazing systems quickly when everything goes right. I think that the advice on detailed topics in The Practice of Programming is sound and will always be — one has to find the right algorithms and data structures, one has to test and debug and worry about performance, and there are general issues like good notation that will always make life much better. But it's not clear to me or to Rob that we have enough new good ideas for a new book, at least at the moment.
What advice do you have for young programmers starting out? Would you recommend a grounding in Cobol like you had, for example?
Every language teaches you something, so learning a language is never wasted, especially if it's different in more than just syntactic trivia. One of Alan Perlis's many wise and witty epigrams says, "A language that doesn't affect the way you think about programming is not worth knowing". On the other hand, I would not suggest Cobol as a primary focus for most people today — I learned it as part of a summer job and long ago, not because it taught me something new (though it did that as well). No matter what, the way to learn to program is to write code, and rewrite it, and see it used, and rewrite again. Reading other people's code is invaluable as well. Of course all of these assume that the code is good; I don't see a lot of benefit in reading a lot of bad code, other than to learn what to avoid, and one should, of course, not write bad code oneself. That's easier said than done, which is why I stress rewriting.
Who would you consider to be the icons of the programming world?
For purely parochial reasons, I think of people who I know or whose work I know well. Ken Thompson and Dennis Ritchie changed my life and yours; we would not be having this conversation without them. People who created major languages would also fall into that camp, for instance we all regularly use languages created by Bjarne Stroustrup, James Gosling, Larry Wall, and Guido von Rossum. And of course there are super-icons like Don Knuth and Fred Brooks. But this is a personal list; there are many others whose work has been influential, and your list would surely differ.
Bell Labs has produced some of the most influential figures in the world as far as IT goes — does it still maintain its relevance in your view? What could it do to better its acclaimed past?
Bell Labs was an astonishing place for many decades, though it fell on somewhat hard times during the telecom meltdown some years ago, as its corporate owner had to cope with shrinking markets. There are great people at Bell Labs but the operation is much smaller than it used to be, which reduces the chance of a big impact, though certainly it can still happen — all it takes is one or two people with a good idea.
What are you working on at the moment? Can we expect any new books or work on languages?
I seem to get totally wrapped up in teaching and working with students during the school year. During the summer I try to spend time in the real world, writing code for therapy and perhaps for some useful purpose. This is fun but so far it hasn't led to any book, though ideas are percolating. I'm still very interested in domain-specific languages and, more generally, in tools that make it easier to write code. And it sometimes seems like some of the old Unix command line languages for special purposes might have a second life in web pages. So I play with these from time to time, or entice some student into exploring a half-baked idea for a semester.
You've been around the development of some of the formative influences on the Internet such as UNIX, what do you see as the driving influences of contemporary computing and the way the world connects?
For better or worse, the driving influence today seems to be to get something up and running and used via the Internet, as quickly as possible. A good idea, however simple in retrospect, can give one fame and fortune (witness Google, Facebook, Twitter, and any number of others). But this only works because there is infrastructure: open source software like Unix/Linux and GNU tools and web libraries, dirt-cheap hardware, and essentially free communications. We're seeing an increase in scalable systems as well, like Amazon's web services, where one can start very small and grow rapidly and without real limits as the need arises. It's starting to look like the Multics idea of an information utility.
AWK and AMPL languages are two you have been involved in developing. Are there any languages you would have liked to have helped develop?
Well, it's always nice to have been part of a successful project, so naturally I would like to have helped with everything good. But I've been quite lucky in the handful that I was involved in. Most of that comes from having first-rate collaborators (Al Aho and Peter Weinberger for AWK and Bob Fourer and Dave Gay for AMPL).
Which companies/individuals would you point to as doing great things for the society at present through computer sciences?
I might single out Bill and Melinda Gates for their foundation, made possible by the great success of Microsoft. Their charitable work is aimed at tough but potentially solvable problems and operates on a scale that few others can approach. After that, one might name Google, which has made so much information so readily accessible; that access has changed the world greatly and is likely to continue to do so.
What are you views on the following languages: Perl, Java, and Ruby?
I use Java some; it's the standard language for introductory computing at Princeton and lots of other places. I find it bulky and verbose but it flows pretty smoothly once I get going. I don't use Perl much at this point — it's been replaced by Python in my personal working set — but no other language matches the amount of computation that can be packed into so few characters. I have not written much Ruby; it clearly has a lot of appeal and some intriguing ideas, but so far when I have to write a program quickly some other more familiar language gets used just to get the job done. But one of these days, I'll add Ruby to the list.

Tuesday, October 6, 2009

wheel rotating on a plane (sunanda madam's assignment)



FILE : rrc.cpp
/*
 *      rrc.cpp
 *
 *      Copyright 2009 Rooparam Choudhary <rooparambhakar@gmail.com>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#include <graphics.h>
#include <math.h>

typedef  float   matrix3x3[3][3];
typedef  float   vector[3];


/* -------- Public Interface ------------ */
static int _WIDTH = 640;     static int _HEIGHT = 480;
static int _CX = 320;        static int _CY = 240;         // CENTER OF COORDINATES
static int _COLOR = BLACK;
static vector    _DOT;
static matrix3x3    _M;
static int _TRANS = 0;                    // whether to use transformation matrix in pixel drawing
                                          // 0: false   1: true

static void SetToIdentity(matrix3x3 X);                // Converts X to indentity matrix
static void Transform(matrix3x3 X, vector P);          // P = X.P
static void mul(matrix3x3 Left, matrix3x3 right);      // [right] = [Left].[right]
static void Translate(matrix3x3 X, int tx, int ty);    // X = [Tranlation matrix].X
static void Rotate(matrix3x3 X, float theta);          // X = [Rotation Matrix].X

static void setPixel(int x, int y);                // (x, y) are in screen coordinates
// to optimize, shift transformation operations from setPixel to line_r.
static void line_r(int x0, int y0, int x1, int y1, const int color = -1);      
static void circle_r(int xc, int yc, const int radius, const int color = -1);
static void ellipse_r(int xc, int yc, int rx, int ry, const int color = -1);

/* -------------------------------------- */

static void Transform(matrix3x3 X, vector P) {
       vector T;
       for(int i=0; i<3; ++i) {
               T[i] = 0.0f;
               for(int j = 0; j<3; ++j) {
                       T[i] += X[i][j]*P[j];
               }
       }
       P[0] = T[0];
       P[1] = T[1];
       P[2] = T[2];
}

static void SetToIdentity(matrix3x3 X) {
       for(int i=0; i<3; ++i) {
             for(int j=0; j<3; ++j) {
                     X[i][j] = (float)(i==j);
             }
       }
}


static void mul(matrix3x3 Left, matrix3x3 right) {      // right's content will be changed
       matrix3x3 T;        // new matrix
       for(int i=0; i<3; ++i) {
               for(int j=0; j<3; ++j) {
                       T[i][j] = 0.0f;
                       for(int k=0; k<3; ++k)
                               T[i][j] += Left[i][k] * right[k][j];
               }
       }
     
       // copy T to right
       for(int i=0; i < 3; ++i)
        for(int j=0; j < 3; ++j)
                right[i][j] = T[i][j];
}

/* [Tranlation matrix].X */
static void Translate(matrix3x3 X, int tx, int ty) {
       matrix3x3 A1;
       SetToIdentity(A1);
     
       A1[0][2] = tx;
       A1[1][2] = ty;
     
       mul(A1, X);
}

/* [Rotation Matrix].X */
static void Rotate(matrix3x3 X, float theta) {
       matrix3x3 A1;          // rotation matrix
       SetToIdentity(A1);
     
       A1[0][0] = A1[1][1] = cos(theta);
       A1[0][1] = -sin(theta);
       A1[1][0] = sin(theta);
     
       mul(A1, X);  
}

static void setPixel(int x, int y) {
       if(_TRANS) {
              _DOT[0] = (float)(x - _CX);
              _DOT[1] = (float)(-y + _CY);
              _DOT[2] = 1.0f;
 
              Transform(_M, _DOT);
              x = int(_DOT[0] + _CX);   y = int(_CY - _DOT[1]);
       }
       putpixel(x, y, _COLOR);
}

/*
 * line drawing function on the screen
 * implements : Bresenhem's Line Drawing Algorithm
 * parameters :
 *              x0, y0      -   one end of the line
 *              x1, y1      -   another end of the line
 *              color   -   color of line, default value -1 indicates
 *                          we will use last defined color
 */

static void line_r(int x0, int y0, int x1, int y1, const int color)
{
    if(color != -1)
        _COLOR = color;
       
    int isTRANS = 0;
    if(_TRANS) {
              _DOT[0] = (float)x0;
              _DOT[1] = (float)y0;
              _DOT[2] = 1.0f;
 
              Transform(_M, _DOT);
              x0 = (int)_DOT[0];   y0 = (int)_DOT[1];
             
              _DOT[0] = (float)x1;
              _DOT[1] = (float)y1;
              _DOT[2] = 1.0f;
 
              Transform(_M, _DOT);
              x1 = (int)_DOT[0];   y1 = (int)_DOT[1];
             
              isTRANS = 1;
              _TRANS = 0;
    }

    int inverse =    0; // 0 : false      1 : true
    int sign = 0;       // 0 : y = x        1 : y = -x

    /* ---------------------------------------------------- */
    inverse = 0;
    sign = 0;
   float m = 0;
   int t;
   int infinity = (x1 == x0);

   if(!infinity)
      m = (y1-y0) / (float)(x1-x0);
    if(m < 0)
        sign = 1;

   if(infinity || fabs(m) > 1) {
      inverse = 1;

        if(sign)
            { t = -x0;  x0 = -y0;   y0 = t;
              t = -x1;  x1 = -y1;   y1 = t; }
        else
            { t = x0;   x0 = y0;    y0 = t;
              t = x1;   x1 = y1;    y1 = t; }
   }

   if(x1<x0)
    {
        t = x1;   x1 = x0;    x0 = t;
        t = y1;   y1 = y0;    y0 = t;
    }
    /* ---------------------------------------------------- */

    /* ---------------------------------------------------- */
    int twoDY = 2*(y1-y0), twoDX = 2*(x1-x0),   DX = x1-x0;
   int incY = ((twoDY < 0) ? -1 : 1);
   twoDY = abs(twoDY);
   int p = twoDY - DX;  int x = x0, y = y0;

   /* put a pixel at (x, y) */
   if(inverse){
            if(sign)
              setPixel(_CX - y, _CY + x);
            else
                setPixel(_CX + y, _CY - x);
   } else
      setPixel(_CX + x, _CY - y);
   /* --------------------- */

   while(x < x1) {
      ++x;
      if(!(p<0)) {
         y += incY;
         p -= twoDX;
      }
      p += twoDY;
        /* put a pixel at (x, y) */
        if(inverse){
            if(sign)
              setPixel(_CX - y, _CY + x);
            else
                setPixel(_CX + y, _CY - x);
        } else
            setPixel(_CX + x, _CY - y);
        /* --------------------- */
   }
    /* ---------------------------------------------------- */
    if(isTRANS)
        _TRANS = 1;
}

/*
 * helper for 'circle' function
 * it uses the symmetry of Circle to draw points in other octants
 */

 static inline void _draw(int xc, int yc, int x, int y) {
     setPixel(_CX + xc+x, _CY - (yc+y) );      // Ist      Octant
     setPixel(_CX + xc+y, _CY - (yc+x) );      // IInd     Octant
     setPixel(_CX + xc-y, _CY - (yc+x) );      // IIIrd    Octant
     setPixel(_CX + xc-x, _CY - (yc+y) );      // IVth     Octant
     setPixel(_CX + xc-x, _CY - (yc-y) );      // Vth      Octant
     setPixel(_CX + xc-y, _CY - (yc-x) );      // VIth     Octant
     setPixel(_CX + xc+y, _CY - (yc-x) );      // VIIth    Octant
     setPixel(_CX + xc+x, _CY - (yc-y) );      // VIIIth   Octant
}


/*
 * circle drawing function on the screen
 * implements : Midpoint Circle Algorithm
 * parameters :
 *              xc, yc  -   center of the circle
 *              radius  -   radius of the circle
 *              color   -   color of line, default value -1 indicates
 *                          we will use last defined color
 */

static void circle_r(int xc, int yc, const int radius, const int color)
{
    if(color != -1)
        _COLOR = color;

    int p = 1 - radius;
     int x = 0,       y = radius;
     do{
           _draw(xc, yc, x, y);
           ++x;
           if (p < 0)
              p += 1 + (x<<1);
           else{
                --y;
                p += 1 - ((y-x) << 1) ;
           }
     }while(y >= x);
}

/*
 * helper for 'ellipse' function
 * it uses the symmetry of Ellipse to draw points in other quadrants
 */

static inline void draw_E(int xc, int yc, int x, int y)
{
     setPixel(_CX + xc+x, _CY - (yc+y));      // Ist      Quadrant
     setPixel(_CX + xc-x, _CY - (yc+y));      // IInd     Quadrant
     setPixel(_CX + xc-x, _CY - (yc-y));      // IIIrd    Quadrant
     setPixel(_CX + xc+x, _CY - (yc-y));      // IVth     Quadrant
}
/*
 * ellipse drawing function on the screen
 * implements : Midpoint Ellipse Algorithm
 * parameters :
 *              xc, yc  -   center of the ellipse
 *              rx, ry  -   axes of the ellipse
 *              color   -   color of line, default value -1 indicates
 *                          we will use last defined color
 */

static void ellipse_r(int xc, int yc, int rx, int ry, const int color)
{
       if(color != -1)
        _COLOR = color;
       
     long long int rx_2 = rx*rx,   ry_2 = ry*ry;
     long long int p = ry_2 - rx_2*ry + (ry_2>>2);
     int x = 0,       y = ry;
     long long int two_ry_2_x = 0, two_rx_2_y = (rx_2<<1)*y;
     draw_E(xc, yc, x, y);
     while(two_rx_2_y >= two_ry_2_x){
           ++x;
           two_ry_2_x += (ry_2<<1);
         
           p +=  two_ry_2_x + ry_2;
             
           if(p >= 0){
                --y;
                two_rx_2_y -= (rx_2<<1);
               
                p -= two_rx_2_y ;
           }
           draw_E(xc, yc, x, y);
     }
   
     p = (long long int)(ry_2*(x+1/2.0)*(x+1/2.0) + rx_2*(y-1)*(y-1) - rx_2*ry_2);
     while (y>=0) {
           p += rx_2;
           --y;
           two_rx_2_y -= (rx_2<<1);
           p -= two_rx_2_y;
         
           if(p <= 0) {
                ++x;
                two_ry_2_x += (ry_2<<1);
                p += two_ry_2_x;
           }
           draw_E(xc, yc, x, y);
     }
}



FILE : wheel.cpp
/*
 *      wheel.cpp
 *
 *      Copyright 2009 Rooparam Choudhary <rooparambhakar@gmail.com>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

 #include <iostream>
 #include <stdio.h>
 #include <math.h>
 #include "rrc.cpp"

 #define PI        3.14159f
 #define ee        0.85f     // collision constant
 #define CLOCK     0.2f     // tick increment
 // #define _PEL_DO
 
 static void draw_wheel(int xc, int yc, const int radius, const float theta)
 {
        int temp = _TRANS;
        _TRANS = 1;
     SetToIdentity(_M);
     Rotate(_M, theta);
     //     Translate(_M, xc, yc);
     _M[0][2] = xc;       _M[1][2] = yc;
     
     int x0, y0, x1, y1;    
     float rim = 4.0f/5.0f;  
     
     // first spike of wheel
     x0 = int(-radius*rim);  y0 = 0;
     x1 = int(radius*rim);   y1 = 0;
     line_r(x0, y0, x1, y1, RED);
     _M[1][2] -= 1;
     line_r(x0+1, y0, x1-1, y1, RED);
     _M[1][2] += 2;
     line_r(x0+1, y0, x1-1, y1, RED);
     _M[1][2] -= 1;
     
     // second spike of wheel
     x0 = int(-0.5f*radius*rim);     y0 = int(-0.866f*radius*rim);
     x1 = int(0.5f*radius*rim);      y1 = int(0.866f*radius*rim);
     line_r(x0, y0, x1, y1, GREEN);
     _M[0][2] += 1;
     line_r(x0, y0, x1-1, y1-1, GREEN);
     _M[0][2] -= 2;
     line_r(x0-1, y0-1, x1, y1, GREEN);
     _M[0][2] += 1;
     
     // third spike of wheel
     x0 = int(-0.5f*radius*rim);       y0 = int(0.866f*radius*rim);
     x1 = int(0.5f*radius*rim);        y1 = int(-0.866f*radius*rim);
     line_r(x0, y0, x1, y1, BLUE);
     _M[0][2] += 1;
     line_r(x0, y0, x1-1, y1+1, BLUE);
     _M[0][2] -= 2;
     line_r(x0+1, y0-1, x1, y1, BLUE);
     _M[0][2] += 1;
     
     // drawing tyre
     _TRANS = 0;
     circle_r(xc, yc, int(radius*rim), BLACK);
     circle_r(xc, yc, int(radius*rim-1), BLACK);
     int my_r = (int)(radius*rim+4.0f);
     do{
         circle_r(xc, yc, my_r, BLACK);
         my_r += 4;
     } while(my_r < (radius-5));
     circle_r(xc, yc, radius, BLACK);
     circle_r(xc, yc, radius-1, BLACK);
     circle_r(xc, yc, radius-2, BLACK);
     
     _TRANS = temp;
 }

 static void simulate(float angle, float radius, float g)
 {
     char *author = "Coder:- Rooparam Choudhary";

     float ix, iy;     // (ix, iy) : upper end of wedge

     setbkcolor(WHITE);

     if(tan(angle) <= (float)_CY/(_WIDTH - _CX) ) {
         ix = (float)(_WIDTH - _CX);
         iy = ix * tan(angle);
     } else {
         iy = (float)_CY;
         ix = iy / tan(angle);
     }

     // (x, y) : wheel center
     float x = ix - radius*(cos(angle) + sin(angle));
     float y = iy + radius*(cos(angle) - sin(angle));
     
     float C1 = g*sin(angle)/4.0f;
     float C2 = C1/radius;
     float tick;     // discrete time, increment on every iteration of while loop
     float twoT;

     float h, h1, t, t1, energy, speed, MAX;
     h = y-radius/cos(angle);
     energy = g*h;
     MAX = energy;
     
     float theta = 0.0f;        // rotation angle of wheel (in radians)
     while(energy > 0.01f*MAX)
     {
                  // rotating down the slope from upper right.
        t = 2.0f/sin(angle)*sqrtf(h/g);
        tick = 0.0f;
         do
         {
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#ifdef _PEL_DO
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#endif            
            twoT = (CLOCK + 2*tick)*CLOCK;
            theta += C2*twoT;
            while(theta >= 2.0f*PI) { theta -= 2.0f*PI; }
            x -= C1*cos(angle)*twoT;
            y -= C1*sin(angle)*twoT;
            tick += CLOCK;
         } while(tick <= t);
         
                      // climbing up the slope from center towards upper left.
           h1 = ee*ee*h;
           t1 = 2.0f/sin(angle)*sqrtf(h1/g);
           tick = 0.0f;
           x = 0.0f;   y = radius/cos(angle);
           speed = sqrtf(g*h1);
         do
         {
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#ifdef _PEL_DO            
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#endif            
            twoT = (CLOCK+2*tick)*CLOCK;
            theta += speed/radius*CLOCK - C2*twoT;
            while(theta >= 2.0f*PI) { theta -= 2.0f*PI; }
            x -= (speed*CLOCK - C1*twoT)*cos(angle);
            y += (speed*CLOCK - C1*twoT)*sin(angle);
            tick += CLOCK;
         } while(tick <= t1);
         
                      // rotating down the slope from upper left
           tick = 0.0f;
           float br, kr;
           kr = h1+radius/cos(angle) - radius*(cos(angle) - sin(angle));
           br = kr/tan(angle);
           x = -br + radius*(cos(angle) + sin(angle));     y = h1+radius/cos(angle);
           speed = 0;
         do
         {
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#ifdef _PEL_DO            
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#endif            
            twoT = (CLOCK+2*tick)*CLOCK;
            theta -= C2*twoT;
            while(theta <= -2.0f*PI) { theta += 2.0f*PI; }
            x += C1*twoT*cos(angle);
            y -= C1*twoT*sin(angle);
            tick += CLOCK;
         } while(tick <= t1);
         
                         // climbing up the slope towards upper right
           h = ee*ee*h1;
           t = 2.0f/sin(angle)*sqrtf(h/g);
           tick = 0.0f;
           x = 0.0f;   y = radius/cos(angle);
           speed = sqrtf(g*h);
         do
         {
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#ifdef _PEL_DO            
            cleardevice();
            setcolor(WHITE);
            setbkcolor(GREEN);
            outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
            setbkcolor(WHITE);
   
            // draw wedge
            line_r(0, 0, (int)ix, (int)iy, MAGENTA);
            /*
            line_r(1, 0, (int)ix+1, (int)iy, MAGENTA);
            line_r(2, 0, (int)ix+2, (int)iy, MAGENTA);
            line_r(3, 0, (int)ix+3, (int)iy, MAGENTA);
            line_r(4, 0, (int)ix+4, (int)iy, MAGENTA);
            */

            line_r(5, 0, (int)ix+5, (int)iy, MAGENTA);
            line_r(0, 0, (int)-ix, (int)iy, MAGENTA);
            /*
            line_r(-1, 0, (int)-ix-1, (int)iy, MAGENTA);
            line_r(-2, 0, (int)-ix-2, (int)iy, MAGENTA);
            line_r(-3, 0, (int)-ix-3, (int)iy, MAGENTA);
            line_r(-4, 0, (int)-ix-4, (int)iy, MAGENTA);
            */

            line_r(-5, 0, (int)-ix-5, (int)iy, MAGENTA);
           
            draw_wheel((int)x, (int)y, (int)radius, theta);
            swapbuffers();
#endif            
            twoT = (CLOCK+2*tick)*CLOCK;
            theta -= speed/radius*CLOCK - C2*twoT;
            while(theta <= -2.0f*PI) { theta += 2.0f*PI; }
            x += (speed*CLOCK - C1*twoT)*cos(angle);
            y += (speed*CLOCK - C1*twoT)*sin(angle);
            tick += CLOCK;
         } while(tick <= t);
         
           energy = g*h;
           kr = h+radius/cos(angle) - radius*(cos(angle) - sin(angle));
           br = kr / tan(angle);
           x = br - radius*(cos(angle) + sin(angle));    y = h+radius/cos(angle);
           speed = 0.0f;
     }
 }
#define _WHEEL
int main(void)
{
    std::cout << "Enter Screen Size [Width, Height] : ";
    std::cin >> _WIDTH >> _HEIGHT;
    std::cout << "Enter Center Coordinates [CX, CY] : ";
    std::cin >> _CX >> _CY;
    initwindow(_WIDTH, _HEIGHT, ".:: WHEEL ROLLING ON AN INCLINED PLANE ::.", 100, 100, true);
    setbkcolor(WHITE);
    cleardevice();
    swapbuffers();
    cleardevice();
    swapbuffers();
   
#ifdef _TEST_TRANSLATE
       int x0, y0, x1, y1, tx, ty;
       
       line_r(-_CX, 0, _WIDTH-_CX, 0, MAGENTA);
       line_r(0, _CY, 0, -_HEIGHT+_CY, MAGENTA);
       swapbuffers();
       line_r(-_CX, 0, _WIDTH-_CX, 0, MAGENTA);
       line_r(0, _CY, 0, -_HEIGHT+_CY, MAGENTA);
       swapbuffers();
       _TRANS = 1;
       std::cout << "Enter (x0, y0, x1, y1, tx, ty) [5000 to exit]: ";
       std::cin >> x0;
       while(x0 != 5000) {
                std::cin >> y0 >> x1 >> y1 >> tx >> ty;
                SetToIdentity(_M);
                Translate(_M, tx, ty);
                line_r(x0, y0, x1, y1, BLACK);
                swapbuffers();
                line_r(x0, y0, x1, y1, BLACK);
                swapbuffers();
                std::cout << "Enter (x0, y0, x1, y1, tx, ty) [5000 to exit]: ";
                std::cin >> x0;
       }
#endif          // _TEST_TRANSLATE
   
#ifdef _TEST_WHEEL
       int xc, yc, r; float theta, radian;
       
       line_r(-_CX, 0, _WIDTH-_CX, 0, MAGENTA);
       line_r(0, _CY, 0, -_HEIGHT+_CY, MAGENTA);
       swapbuffers();
       line_r(-_CX, 0, _WIDTH-_CX, 0, MAGENTA);
       line_r(0, _CY, 0, -_HEIGHT+_CY, MAGENTA);
       swapbuffers();
       
       std::cout << "Enter (xc, yc, r, theta)[5000 to exit]: ";
       std::cin >> xc;
       while(xc != 5000) {
                std::cin  >> yc >> r >> theta;
                radian = theta / 180.0f * 3.14159f;
                draw_wheel(xc, yc, r, radian);
                swapbuffers();
                draw_wheel(xc, yc, r, radian);
                swapbuffers();
                std::cout << "Enter (xc, yc, r, theta)[5000 to exit]: ";
                std::cin >> xc;
       }
       
#endif          // _TEST_WHEEL
   
#ifdef _WHEEL
    float theta, gravity;
    int radius;
   
    std::cout << "Enter radius of wheel [5000 to exit]: ";
    std::cin >> radius;
    while(radius != 5000) {
                 std::cout << "Enter inclination angle of plane: ";
                 std::cin >> theta;
                 std::cout << "Enter gravity constant of planet (980 for earth)[unit is cm/s2]: ";
                 std::cin >> gravity;
   
                 simulate(theta / 180.0f * 3.14159f, radius, gravity);
                 
                 std::cout << "Enter radius of wheel [5000 to exit]: ";
                 std::cin >> radius;
    }
#endif          // _WHEEL  

    closegraph();
    restorecrtmode();
}