PyGeo: a dynamic geometry toolkit

PyGeo, an Overview

What is PyGeo?

PyGeo is most fundamentally a framework for the creation of dynamic geometric constructions - i.e. constructions which embody defined and persistent geometric relationships responsive to real time on-screen interactivity.

PyGeo is, further, an implementation of this underlying abstract framework - exposing a range of geometric objects as the building blocks for virtual, dynamic geometric constructions.

The focus is away from Euclidian geometry and metrics, and toward later geometric and mathematical developments - particularly those connected with projective geometry of real space, and the geometry of complex numbers on the plane and on the unit (Riemann) sphere.

return to Contents

Programming based geometric construction

PyGeo is implemented in the Python programming language, making extensive use of its object oriented characteristics - and PyGeo constructions themselves can only be Python scripts processed directly by the Python interpreter.

In creating the simplest geometric construction in PyGeo one is therefore also programming. Typing is unavoidable, and spelling counts.

Sorry. No point and click. Until after the construction is created and on the screen.

The possibility of allowing it to be otherwise not only exists, but has been impressively realized in a number of other efforts.

One can visit

for a look at the myriad of options, free and otherwise, more appropriate for those who find the requirement of an ability to create constructions by mouse clicks on screen as essential to their own purposes or on behalf of their students.

But it cannot sensibly be thought that there are not trade-offs being made in settling upon such an approach.

And those trade-offs seem to be assessed differently by different sensibilities.

PyGeo takes a position on the matter.

There is, however, substantial (and ongoing) efforts made in the design of PyGeo to mitigate the complexity connected to the underlying fact of its programming based approach - by means thought not to compromise the cognitive focus which the approach encourages or narrow the range and depth of possibilities which the approach enables. Hopefully some of what follows helps make that case.

return to Contents

Python as the choice of programming language

No, Python is not easy. It is a full-featured, cross-platform. general purpose, professional, and quite literate programming language. A potential subject of extensive study unto itself.

However -

  • the language takes pride in its effort to make itself accessible as a tool to those whose core interests are outside the areas of computer science and/or technology
  • it is interpreted - no separate compile cycle, and therefore instant feedback when running code
  • it is multi-paradigm - i.e. objected oriented and functional and mixed and matched programming styles are accommodated
  • it is dynamically typed - one needs not spend one's time stating the near obvious for the benefit of the compiler.
  • such technical matters as memory management are undertaken behind the scenes, as its problem, not ours.
  • it encourages, by design, an aesthetic of code as readable text, in particular by making the use of code indentation meaningful - in fact as its primary mechanism for specifying code blocks.

Yet -

  • no babysitting. One can work oneself into any level of trouble to which one might aspire.

It can be, many seem to agree, simply fun.

In the framework provided by PyGeo, interesting things can be achieved with a quite small and particularly accessible subset of the language's full range of possibilities. More, of course, with more

All of the above serves PyGeo's purposes, to a tee.

return to Contents

PyGeo as an introduction to programming

With no citable evidence to offer in support of the claim, it is nonetheless reasonable to believe that PyGeo might serve well as an environment in which to approach the introduction of programming concepts synergistically with the exploration of geometric ones. Certainly, the core idea of such an approach - the concept that there may indeed be some cognitive resonance at play which makes working these streets together a good way to go - is far from new. The question as to what extent PyGeo may offer a good framework in which to motor this well-traveled (since Logo? before?) road is an aside, and should it turn out that PyGeo, in practice, is found particularly well suited for such an assignment, it is happenstance - as indeed its focus, and its love, is the geometry. Which - who knows - might be just the right configuration. Accidents happen.

However, PyGeo also tries to offer a different, or supplemental, approach to one that focuses on interactivity - geometric or otherwise - in introducing programming concepts. As is reiterated throughout this document, PyGeo is sold (for free) , with the postion that it's application code is its accompanying text. Efforts are made (see Anatomy of PyGeo code) to provide an entry point to that text for those without significant prior programming experience. The belief is that approaching a working application from a satellite view, and down, can have certain advantages over the approach of working from the table-setting view, and up.

return to Contents

Editing environment

While requiring programming for the creation of geometric constructions, PyGeo aspires to be accessible to folks with little prior programming experience.

Question One of such a someone might appropriately be "In what environment might a programmer using a language such as Python choose to work?"

Thinking that the question deserves an answer in the concrete, a programmers' editor, customized to a reasonable extent to serve as an environment suitable for the creation and running of PyGeo scripts, is made available with, or along side of, the PyGeo distribution.

See the download http:// section.

What is provided is a version of Neil Hodgon's SciTE programmers' text editor customized to provide:

  • Syntax highlighting of Python keywords and PyGeo classes, functions, keyword options and constants
  • Autoword completion for PyGeo's exposed geometric classes and functions
  • Calltips for PyGeo's exposed geometric classes and functions
  • Access to Python and PyGeo documentation from the menu system.

Options under the 'Tools" menu item provide for calling the Python interpreter to either check the syntax of the current script, feed back, and exit; or to run the script in full.

return to Contents

Built-in geometric objects and their classification

PyGeo is ambitious (overreaching?) in the range of geometric objects it makes available as built-ins:

In terms of the geometric "space" that the objects might be designed to inhabit

  • objects identifiable with classical Euclidian space together with those more closely connected to concepts of real projective space and the real projective plane.

  • objects connected to the geometry of complex numbers, and within this:
    • objects visible on the projective complex plane
    • objects visible on the origin centered (Riemann) unit sphere.

In terms of the definition of what, in fact, "an object" can be

  • simple objects, i.e. the point, the line, the plane, etc.
  • compound objects, e.g. an object representing the collection of lines passing through a given point of a given plane
  • transformations as objects, e.g. the "object" created by projecting objects on a given plane from a given point in space to a second plane

All these objects - simple, compound, transformed - retain "first class" characteristics. That is, they are objects that can be passed on to other objects as arguments - allowing, for example, for the exploration of such phenomena as the iterative transformation.

In terms of defined default behaviors of objects

  • objects (i.e. points) that can be interactively picked and moved either freely within a domain (e.g. 3d space, the complex plane) or constrained to a particular object of that domain (e.g. a particular circle, a particular line)
  • objects that are animated, i.e. which move along a defined course, e.g. the circumference of a circle, at each update cycle
  • objects that are fixed, e.g. a point with a defined coordinate location
  • objects that are dependent, i.e. which change location but based only on a change in the position of an object in its dependency graph.

There are in total over 40 factory functions, each representing a category of geometric object in what may be thought of as a classification matrix consisting of the 3 axes described above, and which may summarized as:

  1. the geometric space the object is designed to inhabit
  2. fundamental geometric characteristics connected to the object
  3. the default behavior of the object

A bit daunting without a roadmap.

What suffices as that roadmap?

Probably no one thing, sufficiently.

But see:

return to Contents

Built-in geometric intelligence

Creating a visible geometric object in PyGeo is in essence creating an object that is an instance of a predefined class, in the object-oriented programming sense of these words. By in turn instantiating another class with a previously created object as a constructor, a link of dependency is created between the objects - one that persists during an on-screen interactive session .

Which sounds perhaps more complicated than it is, and therefore should.

The following is a complete PyGeo construction that will work either entered line by line to the interactive Python prompt, or saved as text and run as a script by the Python interpreter.

>>> from pygeo import *
>>> display=display()
>>> point1= FreePoint(1,4,7)
>>> point2=FreePoint(6,11,9)
>>> line=Line(point1,point2)
>>> display.pickloop()

A quick analysis of these lines of code:

The first line makes the PyGeo classes available to what follows, and the second instantiates the environment for display of the geometric objects that follow it.

We then create 2 point objects with initial positions at the given coordinates, which - because their class definition arranges it to be so - can be picked and moved freely in virtual space.

And then a line through those points. This line is now dependant on those points referenced in its construction, and in a interactive session, therefore, any movement of those points will impact the position of the line.

The last line of the script simply puts the display in interactive mode, allowing the display to respond to mouse events - for the picking and movement of the points, for the rotation of the scene as a whole, and for zooming in and out on the scene.

But can it be concluded from the above example that a "Line" in PyGeo is limited to that which contains 2 points given as its constructors? Sounds kind of basic, and a little dull.

The answer is no.

We are working in space and one of the concepts we may be exploring, or already comfortable with, is the projective Principle of Duality. The dual, in space, of a point is a plane. And indeed had we created 2 planes (and assigned to them the names 'plane1' and 'plane2') the creation of a line as

>>> Line(plane1,plane2)

will return the unique line common to the given planes

just as

>>> Line(point1,point2)

returned, in the above example, the unique line common to the given points.

The mechanism employed is that of the 'class factory' function. "Line", in PyGeo is in fact not itself a class definition. It is in fact a function that analyzes the arguments it is given, identifying the class under its hierarchy that can be constructed with the category of geometric objects to which the given objects belong, and then instantiating and returning an object that is an instance of that class with the given objects as its constructing arguments. Or returning an error if no such beast is found to exist.

The general principle underlying the taxonomy is one of uniqueness. Generally speaking, a factory function is defined within a given a category of geometric object, and the classes that it can call are ones representing geometric objects of that category that are uniquely determined by a certain set of geometric objects as its constructing arguments.

So that, for example, there is a category of points defined generally as intersections of given objects - with

>>> Intersect(plane,line)

thereby becoming the unique point of intersection of the plane and the line, and

>>> Intersect(plane1,plane2,plane3)

becoming the unique point of intersection of the 3 planes.

And so forth.

And, following the logic of duality in space, and assuming that we have created 3 points in space and assigned to them the names point1,point2, and point3 we find that indeed

>>> Plane(point1,point2,point3)

returns the unique plane containing the 3 points, just as the Intersect constructor above gave us the unique point containing 3 planes. As we might expect, as a matter of geometry.

The concept behind the factory functions is to allow one, to a reasonable extent, to rely on geometric reasoning, rather than memorization or the reasoning of that of a programmer. Given a informed geometric expectation, PyGeo tries to respond in conformity with it.

Worth mentioning as well is the fact that one is not constrained to the use of the factory function mechanism. One can just as well instantiate a class directly, if one knows - or looks up - what it is called.

So that, from the above, example,:

>>> PlaneLineIntersect(plane,line)

is fully equivalent to

>>> Intersect(plane,line)

Either will become exactly the same object.

Which instantiation method is preferable is a matter of taste and circumstance.

Pointing out, however, that use of the class factory function provides another level of intelligence that the construction directly by class does not provide, and that is in relation to argument ordering.

The ordering of "plane" and "line", in thinking about their intersection geometrically, has no relevance. However, in calling a class directly, by arguments of the form (plane,line), as above, those arguments are, by language design, processed by position, so that order is crucial.

But again, we wish to allow geometric thinking to prevail over thinking as a programmer (while allowing ourselves to be succinct, ruling out some other possible ways this issue might have been addressed) So that if, geometrically, the positioning of arguments would not be expected to be relevant, they will not be when provided to class factory function, so that:

>>> Intersect(line, plane)

gets us exactly where

>>> Intersect(plane, line)



>>> PlaneLineIntersect(line,plane)

is something else again compared to

>>> PlaneLineIntersect(plane,line)

and will not be understood as intended by the PyGeo code, generating errors and an interruption of processing.

See Anatomy of a function section in the Anatomy of PyGeo code document for a more complete discussion of this functionality and its implementation.

Degenerate cases - in the above Intersect examples, the line is on the plane, or two of the given planes are parallel - generally pass quietly. Infinity exists in projective space equally with all other locations. Except for the fact one cannot draw to it.Nonetheless an object that finds its way there may find its way back to someplace that can be virtually represented in a split second of an interactive session. So the design, in general, is to have corner cases pass without interruption of processing, but usually with a message written simply noting the occurrence that a particular object is undrawable during a particular. update cycle. Normally if an object is considered to be undrawable at a particular update cycle, the objects dependant on it, if any, will be considered to be undrawable as well.

return to Contents

PyGeo - as text

PyGeo is open source , as is the code on which it depends - that of Python , VPython , and Numeric.

This fact serves the purposes of PyGeo in a number of indirect ways, and fulfills an obligation accrued in its development, as PyGeo could not have been developed had not others made their applications available freely, and with source code that could be inspected, and from which ideas could be gleaned.

But because of what PyGeo in particular is, open source serves its purposes in a quite direct way as well.

Code as readable text has been a foundation of the Python programming language's design goals from its inception. And the intent of PyGeo is to take full advantage of that effort.

Because - the code is the text, and more to the point for PyGeo, the code is the algebra, and

Geometry without algebra is dumb!
Algebra without geometry is blind!
David Hestenes and Garret Sobczyk

Embedded in the code is the analytic geometry that drives the synthetic geometry with which we are interacting. Connections that were perhaps before merely understood, are now convincingly understood. That difference is potentially qualitative, rather of degree.

An insistence that, for PyGeo, the code is the application - in the same sense as is the response to mouse clicks when interacting with a construction - is, perhaps, a bit Quixotic.

Nonetheless...the case is being stated therefore the effort to provide an entry point should at least be made.

And so we have proceeded in the direction of the windmills, unperturbed...

See the document Anatomy of PyGeo code

return to Contents

The documentation

The effort to create PyGeo has been undertaken without direct or indirect compensation, and is made available for free.

And under those circumstances it seems not unreasonable to expect those who might be interested in working with it to themselves expect to need to dig on their own a bit in discovering its functionality.

That being said...

PyGeo does in fact come with hundreds of illustrated pages of .html documentation.

But that documentation does not stray far from a point of view that the code is the text - by virtue of the fact this documentation is computer generated directly from the source code itself.

That being said...

The effort has been made so that the generated documentation is not redundant to a direct reading of the source code:

  1. by providing a manner to navigate the code taking advantage of hyperlink technology
  2. by including information supplemental to what is found in the code itself, most importantly, for a geometric application, visual information.

More specifically, the generated documentation provides:

  • "bread-crumb" links in the heading section of all documentation pages, allowing one to reference where in the code structure one is at any given point and a mechanism to jump between sections conveniently
  • links to html versions of the source code itself, in which Python keywords and words and name significant to PyGeo's functionality are highlighted and color coded.
  • those links to source code at a granular level, linking, for example, references to a particular method in a particular PyGeo class directly to that code of that method within the module in which it resides.
  • for all documentation pages that relate directly to a geometric object, a rendered illustration of that object, as a visual reference to its geometric meaning.
  • hyperlinked to all illustrations of geometric objects, an html version of the actual script used to create the illustration.

Hopefully, all-in-all, sufficient.

The documentation root , geometry of space and geometry of complex numbers can serve as appropriate entry points into the documentation.

return to Contents

Examples and test scripts

Perhaps the best starting point in approaching PyGeo, after some time with this document but before an attempt to approach in earnest the auto-generated documentation or source code itself, is the viewing and running the provided example and test scripts.

And to get the broadest view of PyGeo's functionality perhaps begin with the scripts in the "examples" directory. The examples are organized in sub-directories based on whether they happen to work within the domain of real 3d space or that of complex numbers. Those in the "real" directory are more extensive, intending to provide examples that include a range of PyGeo's functionality. The few in the complex directories are intended to be illustrative of some of the possibilities particular to working with PyGeo in that domain.

The examples range from ones with classical and identifiable geometric significance, to those undertaking no more than play and geometric design. But taken as a whole they should give one a feel for the possibilities of PyGeo, such as animated constructions, tracing of loci, iterative projections, multi-window display, layering of constructions by 'level', supplementing the built-in objects with one's own, and etc.

In most cases the construction code is annotated in an effort to explain its intentions and the approach undertaken.

A few specifics about the mechanics of interactivity should be made clear to anyone first approaching a PyGeo construction:

  1. by clicking with the left mouse button anywhere within a construction window the points that are pickable will identify themselves by blinking momentarily.
  2. a pickable point will enlarge when picked directly with the button, but movement itself is accomplished by keeping the left mouse pressed during the movement activity. Releasing the left mouse button releases the point.
  3. rotation of the full scene is accomplished by mouse movement of the mouse with the right button held.
  4. zooming in and out on a scene is accomplished by mouse movement with the middle button (or left and right button on a two-button mouse) pressed.
  5. constructions can be made as layered, by assigning visibility levels to objects on their construction. Only 'level 1' (the default level) objects are visible when first viewing a scene. Some of the examples are multi-layered, and visibility beyond the first layer is only gained by selecting additional levels in the control panel. The code itself will reveal whether more than the default level is being constructed.



In addition to the constructions in the 'examples' directory are those in the test_scripts directory, again organized in real and complex sub-directories, and within each these, "classes" and 'factories".

In the 'classes' directory is a construction of all of the PyGeo built-in geometric objects, as a separate construction file for each.

In the "factories" directory are scripts for groups of objects called in this case by their factory function and argument signature, rather than directly by their class name. See Built-in geometric intelligence to understand the significance of this feature.

The test scripts are intended for two practical purposes:

  • testing of functionality in code development
  • the 'classes' scripts were used to create Pov-ray rendering of all built-in objects used in the illustrations for the auto-generated documentation.

These scripts should also provide pertinent information to a user, at a more granular then that provided in the examples, so that if one wants to understand better what a particular object is designed to represent, geometrically, or to see its dynamic possibilities in action, looking at and running the scripts in this directory would be a sensible approach.

In running the scripts under the 'factories' directory, experiment with the "Detail levels" on the control panel, as most of these script's constructions are highly layered.

return to Contents

Pov-Ray rendering and geometric illustration

Their exist two empty directories in a fresh installation of Pygeo, whose purpose has not yet been addressed.

  • "povout"
  • "images"

Both are related to PyGeo's ability to work with the POV-RAY raytracer.

All of the illustrations on the PyGeo website and within the documentation were created by the export of PyGeo construction to POV-RAY scene definition language, and then by POV-RAY rendering.

Interesting possibilities for geometric illustration are presented, as PyGeo's dynamic nature allows one to "pose" a geometric construction exactly as wished before taking a high resolution snapshot of it by way of the POV-RAY interface.

The export to POV-RAY is triggered via the control panel menu that appears, by default, with a construction..

By default, PyGeo attempts, after exporting a POV-RAY scene file, to call the POV-RAY rendering engine, accomplish the rendering and display the result.

The intent is to create an efficient workflow when doing a series of rendering, perhaps working toward achieving a particular effect in a geometric illustration.

Note that POV-RAY default options themselves may need adjustment to allow the default workflow to in fact flow as designed. On Windows, it is necessary to remove script I/O restrictions by adjusting the default setting on the OptionsScript IO Restictions menu item of the POV_RAY editing environment to No Restrictions.

Also note that the toolkit being used to display the rendered image and POV-RAY's image output options have only the .ppm format in common. However, the freely available Python Imaging Library ("PIL") can automatically convert the full range of POV-RAY output format options for display. by the toolkit handling the display. PyGeo checks for an installation of PIL and, if found, will display the image rendered by POV-RAY in whatever format, otherwise limiting itself to the display of .ppm format files.

See Setting Options for information as to the setting of image output and workflow options related to the POV-RAY interface.

return to Contents

Setting Options

The are a limited number of global options setting significant to the functioning of PyGeo. Adjustments to the default options are accomplished by editing the "" file found in the directory.

Those options, briefly explained:

  • EPS

    PyGeo relies on the underlying floating point mathematics of Python and the operating system on which it is run. The EPS constant option is the tolerance to consider two floating point numbers as equal.

    The default setting is in scientific notation "1e-4", or .0001


    PyGeo code can test for certain sanity conditions throughout the course of its processing flow, and branch to a sane processing option it they are not met. For example, if a point is defined as the intersection of two lines, are those lines in fact coplanar. The intention is to treat the circumstance where expected conditions are not as an exceptional, and avoid the possibilities of viewing unintended and/or undefined behavior. However, the tests can be processing intensive.

    The default setting to DO_TESTS = True but should be set to False if the goal is to optimize responsiveness in interactive mode.


    Display aberrations can occur under certain circumstances when attempts are made to draw objects outside of certain ranges.

    For certain objects the issue is inherent.

    Lines in PyGeo are by default intended to represent "breathless length". For display purposes, however, a bounding limit to the representation needs be established.

    For other objects the issue arises circumstantially:

    A point may be defined as the intersection of two coplanar lines which may, either in construction or in the course of interactivity, approach parallel. At what distance from the origin should we cease attempting to represent that point?

    TEST_MAX is an option to turn on and off the functionality to bound such a point, and by default is set to False - avoiding the performance penalty that occurs with it functioning.

    MAX is an option which in all cases controls the range of the representation of a line representation in real space, and when TEST_MAX is set to True, the bound, as distance from the origin, for the drawing of point objects.

    If is set by default at 1,000

    COMPLEX_MAX is there in acknowledgement of the fact that when working with complex number geometry we are generally working at a smaller scale than we do when working in 3d space. It provides the same functionality for working within the complex domain as MAX provides in 3d space.

    If is set by default at 100


    See Pov-Ray rendering and geometric illustration for some background.

    • POV_RENDER controls whether exported POV RAY files will be rendered immediately upon export, by a call to the POV_RAY engine.

      Default is True

    • POV_DISPLAY controls whether images rendered on export are then automatically displayed upon completion.

      Default is True

    • POV_FILES controls the default location for exported POV_RAY *.pov scene definition files.


      • Windows: '..pygeopovout' under 'site-directories' for the Python directory recognized by os.environ['PYTHONPATH']
      • Other: '../pygeo/povout' under the directory recognized by os.environ['HOME']
    • IMAGE_FILES controls the default location for images rendered by POV_RAY


      • Windows:'..pygeoimages' under 'site-directories' for the Python directory recognized by os.environ['PYTHONPATH']
      • Other: '../pygeo/images' under the directory recognized by os.environ['HOME']
    • POV_IMAGE controls the image format POV_RAY will produce on automatic rendering


      • Windows: .bmp
      • Other: .ppm

return to Contents

"One of my foreign colleagues gives classes on the esthetics of programming. I advised him to throw away the overhead projector and return to the blackboard. It made him find again the joy of teaching".

Edsger Dijkstra