Live Geometry

Live Geometry is an interactive geometry designer built using Silverlight. It can be used to visualize and solve geometry problems, and help make geometry lessons more fun and interactive for teachers and students. It's built on top of an open-source .NET dynamic geometry engine, which can power interactive designers in the same way that physics engines can power games.

The Interactive Geometry Designer

This online application allows you to create interactive geometry drawings and explore them right in the browser. Here's what it looks like (Click for the live demo—requires Silverlight):

clip_image002

The UI essentially consists of two parts: the toolbar with all available tools (above) and the drawing canvas (below). Click on the Samples button clip_image004 to load the tutorial start page. You can start interacting with this drawing right away—just select the Drag tool clip_image006, and drag any of the three yellow points. You can also drag any of the squares, the arrow or the text labels. Live Geometry allows you to drag just about anything, and if you're creating a new kind of a tool or figure, you can easily add dragging support to it, too.

Just like regular webpages, drawings can contain hyperlinks to other drawings. Click on any of the links to jump to another sample drawing. The drawings from this tutorial are stored online as XML files. The tutorial start page that you see in the screenshot above is stored at http://livegeometry.com/demo/demo.xml.

You can save any drawing to disk as a file with the .lgf (Live Geometry file) extension, which is essentially just XML, and open it back later.

To create a new drawing, click the New drawing button clip_image008. To draw a couple of points, select the Point tool and click anywhere in the drawing a couple of times. To draw a segment or a line, select the corresponding tool in the toolbar, and then click two points that you wish to connect. When you select a tool, it displays help on how to use it in the bottom left corner.

For more details on how to use the tools and to get a better idea of what you can do with the existing tools, you can watch a short 5-min video here. You can also browse the Samples tutorial to view the sample drawings.

Embedding a geometry drawing in your own website

You can embed the Live Geometry Silverlight application in your own website. For an example on how to do this, you can go to http://livegeometry.com and click View Source in your browser. Embedding Silverlight boils down to the object tag:

HTML

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
  <param name="source" value="http://livegeometry.com/LiveGeometry.xap"/>
  <param name="onError" value="onSilverlightError" />
  <param name="background" value="white" />
  <param name="minRuntimeVersion" value="3.0.40624.0" />
  <param name="autoUpgrade" value="true" />
  <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none">
          <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
  </a>
</object>

When you build a Silverlight project, the output is compressed to a .xap file. The most up-to-date .xap file for Live Geometry is always published to http://livegeometry.com/LiveGeometry.xap, so you can just reference this one, or place the .xap file on any other webserver.

To tell Live Geometry to open a drawing instead of showing up empty, you can pass the parameters using initParams:

HTML

<object data="data:application/x-silverlight-2," 
type="application/x-silverlight-2" width="800" height="600">
  <param name="source" value="LiveGeometry.xap"/>
  <param name="initParams" 
         value="LoadFile=http://livegeometry.com/demo/demo.xml,ShowToolbar=false" />

Note how ShowToolbar=false is used to hide the toolbar.

If you publish your own drawing on your own webserver, there is a catch. For Live Geometry to be able to download it, the root of your webserver has to contain the crossdomain.xml at its root. For more details on how to embed your own drawings into webpages, read more here: Bezier Curves and Car Manufacturers

Source Code

Live Geometry is written using Silverlight 3 and C# 3.0 (Visual Studio 2008). There are also project versions for Visual Studio 2010 available. Additionally, you can build a WPF desktop version of the app from the same source code.

When you download the source code from CodePlex at http://livegeometry.codeplex.com/SourceControl/list/changesets, you will see the following folder structure:

  1. Main
    1. DynamicGeometryLibrary
    2. Samples
    3. SilverlightClient
    4. WPFClient
  2. Reference – previous versions (obsolete code)

The core dynamic geometry library is a flexible and extensible framework that allows you to add new figure types and features easily. Live Geometry currently has two front-ends, WPF and Silverlight, which share the common DynamicGeometry library.

To open the Silverlight solution, use Main\SilverlightClient\SilverlightClient.sln.

To open the WPF solution, use Main\WPFClient\WPFClient.sln.

Regardless of which solution you open, it will contain two projects: one for the UI and one for the dynamic geometry library.

To build and run the application in Visual Studio, set the corresponding client project as startup (right-click the project in Solution Explorer and choose Set As Startup) and hit F5.

Implementation of the Dynamic Geometry Engine

The dynamic geometry library provides the implementation for all the tools and figures that you see in the toolbar, as well as a set of common services, such as loading/saving, undo engine, property browser, styles, expression evaluation, and so on:

clip_image010

However, the main class of the library is the class Drawing, defined in Drawing.cs. This represents a single document—a geometry drawing that can be displayed in the canvas at any time.

Defining figures

As an example, let's imagine that the Segment tool clip_image012 hasn't been implemented yet and that we have to add support for it. All the figure implementations are under Figures folder, so we'll go under \Figures\Lines\ and add a file called Segment.cs with this content:

C#

namespace DynamicGeometry
{
    public class Segment : LineBase, ILine
    {
        [PropertyGridVisible]
        public double Length
        {
            get
            {
                return Coordinates.Length;
            }
        }

        public override double GetNearestParameterFromPoint(System.Windows.Point point)
        {
              //  ...
        }

        public override IFigure HitTest(System.Windows.Point point)
        {
            var boundingRect = 
        Coordinates.GetBoundingRect().Inflate(CursorTolerance);
            return boundingRect.Contains(point) ? base.HitTest(point) : null;
        }

        public override Tuple<double, double> GetParameterDomain()
        {
            return Tuple.Create(0.0, 1.0);
        }
    }
}

The library already provides several convenient base classes for lines (LineBase), circles (CircleBase), points (PointBase) and shapes (ShapeBase<T>). Here's the inheritance tree diagram for these classes:

clip_image014

We'll inherit from LineBase and override a couple of methods.

HitTest determines whether a point (say a mouse cursor) is actually over the figure. The base class LineBase already defines the logic to determine if the cursor is over a line, but in our case, we need to add an additional constraint and test whether the point is also between the two segment endpoints.

ParameterDomain is used when a point is placed on the segment, but we can ignore it for the purposes of this article.

Finally, we declare the Length property and mark it as [PropertyGridVisible].

Property Grid

When you select a figure with the mouse and the Drag tool is selected, Live Geometry displays a property grid control that allows you to view and edit the properties of the selected figure:

clip_image016

You can see that the value of the Length property is now displayed on the very top of the list. Since we defined the Length property as read-only, the user can't change the value. All this is achieved by just marking the property with [PropertyGridVisible]. All other properties in the screenshot were declared exactly the same way (and inherited from LineBase and its base classes). For instance, Locked is a Boolean property on FigureBase, the base class for all figures. The Delete, Edit style and Create new style buttons map directly to methods, just like the property editors are mapped to properties of the figure.

The property grid control can display and edit properties and call methods on any .NET object, not only figures. To read more about the property grid, its implementation and various editor controls, read here: UI without code or XAML: PropertyGrid, DataForm, etc.

Behaviors

Just declaring the Segment class in the project is not enough for it to show up in the toolbar and become active. Toolbar buttons in Live Geometry set the canvas into a special mode, called a Behavior. When you click the Segment button, the canvas is brought into the segment creation mode. This mode will be described by a class called SegmentCreator (sample code in \Figures\Lines\SegmentCreator.cs):

C#

using System.Windows;
using System.Windows.Media;

namespace DynamicGeometry
{
    public class SegmentCreator : FigureCreator
    {
        protected override DependencyList InitExpectedDependencies()
        {
            return DependencyList.PointPoint;
        }

        protected override IFigure CreateFigure()
        {
            return Factory.CreateSegment(Drawing, FoundDependencies);
        }

        public override string Name
        {
            get { return "Segment"; }
        }

        public override string HintText
        {
            get
            {
                return "Click (and release) twice to connect two points with a segment.";
            }
        }

        public override Color ToolButtonColor
        {
            get
            {
                return Color.FromArgb(255, 205, 255, 128);
            }
        }

        public override FrameworkElement CreateIcon()
        {
            return IconBuilder.BuildIcon()
                .Line(0.25, 0.75, 0.75, 0.25)
                .Point(0.25, 0.75)
                .Point(0.75, 0.25)
                .Canvas;
        }
    }
}

That's it! Now that this class is present in the project, the new tool will show up in the toolbar and work as expected. One minor detail, though: the new tool will show up at the end of the toolbar by default, but editing the file \Behaviors\BehaviorOrderer.cs specifies the order in which the tools are added to the toolbar:

C#

private static List<Type> orders = new List<Type>()
{
    typeof(Dragger),
    typeof(FreePointCreator),
    typeof(MidpointCreator),
    typeof(ReflectionCreator),
    typeof(SegmentCreator),
    typeof(RayCreator),
    ...


Live Geometry uses reflection to scan the assembly for all types that inherit from Behavior, and automatically adds them to the toolbar.

So to add a new figure, you typically just need to define the class for the figure itself, e.g. Bezier.cs, as well as its corresponding behavior and a toolbar button (e.g. BezierCreator.cs). Most tools inherit from the common base class FigureCreator, which provides most of the functionality.

Actions

Most of the time the dynamic geometry library takes care of Undo/Redo, so your new figure will automatically support unlimited undo and redo. Live Geometry uses another one of my .NET open-source projects called the Undo Framework, which can be downloaded at http://undo.codeplex.com. For more details about the Undo Framework, read more here: Undo Framework

The Actions folder provides the classes for common undoable operations:

clip_image018

Controls

The Controls folder stores user controls used in the project. Right-now this is just the ColorPicker from http://silverlightcontrib.codeplex.com. You can read more about the color picker here: ColorPicker Control for WPF/Silverlight

Expressions

The Expressions folder contains support for parsing arithmetic expressions and equations, such as sin(x). This functionality is used by the function plot and line plot tools: clip_image020. You can read more about mathematical expression evaluation here.

Macros

The Macros folder contains support to let users define their own kinds of figures at runtime, without even closing the application. Tools defined by user are added to the end of the toolbar and persisted across application lifetime using Silverlight Isolated Storage.

Serialization

The Serialization folder contains support for writing the figures to XML and reading them back. Usually your figures will be serialized automatically, so you don't have to provide any serialization code for most of custom figures. However, it's possible to override the methods.

C#

void WriteXml(XmlWriter writer);
void ReadXml(XElement element);

This allows you to provide additional custom serialization logic for your figure.

Styles

clip_image022You can define a style for a kind of figure (e.g. line style, point style, shape style or text style) by either creating a new style or selecting from an existing one:

Then you can assign this style to several figures and change the style so that all figures will update their appearance automatically—similar to CSS stylesheets.

Conclusion

Live Geometry is free and open source. You can examine the code; add your own features; or build your own designer, vector graphics software, a CAD application or even a game using the Live Geometry dynamic geometry engine. Since it's written in .NET, you can use any language, such as C#, VB, F#, IronPython or IronRuby. Silverlight support makes it easy to make your software available online.

For more details about the Live Geometry implementation, you can read the documentation wiki on the project's CodePlex website: http://livegeometry.codeplex.com/documentation

You're welcome to discuss Live Geometry on the forum, open bugs and suggestions, and otherwise let me know your feedback! Thanks!

About The Author

Kirill Osenkov is a tester on the Microsoft Visual Studio team. He tests many of the C# IDE features (IntelliSense, Refactorings, Navigation, Call Hierarchy, Highlighting, Formatting etc). In his free time, Kirill is working on his .NET open-source projects on CodePlex: http://livegeometry.codeplex.com, http://undo.codeplex.com, http://structurededitor.codeplex.com and others.

Kirill's blog is at http://blogs.msdn.com/kirillosenkov and Twitter is at http://twitter.com/kirillosenkov.

Tag:

Follow the Discussion

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.