View on
MetaCPAN is shutting down
For details read Perl NOC. After June 25th this page will redirect to
Lutz Gehlen > Math-Geometry-Construction-0.024 > Math::Geometry::Construction



Annotate this POD

View/Report Bugs
Module Version: 0.024   Source  


Math::Geometry::Construction - intersecting lines and circles


Version 0.024


  use Math::Geometry::Construction;

  my $construction = Math::Geometry::Construction->new
      (background => 'white');
  my $p1 = $construction->add_point('x' => 100, 'y' => 150, hidden => 1);
  my $p2 = $construction->add_point('x' => 120, 'y' => 150, hidden => 1);
  my $p3 = $construction->add_point('x' => 200, 'y' => 50);
  my $p4 = $construction->add_point('x' => 200, 'y' => 250);

  my $l1 = $construction->add_line(extend         => 10,
                                   label          => 'g',
                                   label_offset_y => 13,
                                   support        => [$p1, $p2]);
  my $l2 = $construction->add_line(support => [$p3, $p4]);

  my $i1 = $construction->add_derivate('IntersectionLineLine',
                                       input => [$l1, $l2]);
  my $p5 = $i1->create_derived_point(label          => 'S',
                                     label_offset_x => 5,
                                     label_offset_y => -5);

  my $c1 = $construction->add_circle(center => $p5, radius => 20);

  # an intersection point can also be generated in one go
  my $p6 = $construction->add_derived_point
       {input => [$l1, $c1]},
       {position_selector => ['extreme_position', [[1, 0]]]});

  print $construction->as_svg(width => 800, height => 300)->xmlify;


This is alpha software. The API is stabilizing and the test suite at least deserves that name by now, but input checks and documentation are still sparse. However, release early, release often, so here we go.


This distribution serves two purposes:


Problems of these kinds can be solved using several pieces of geometry software. However, I have not found any with sufficiently powerful automization features. This problem has two aspects:

Output Formats

The current output formats are SVG and TikZ. Especially the latter one is experimental and the interface might change in future versions. Other output engines could be written by subclassing Math::Geometry::Construction::Draw. However, documentation of the interface is not available, yet.

Intersection Concept

Intersecting two objects consists of two steps. First, you create a Math::Geometry::Construction::Derivate object that holds the intersecting partners and "knows" how to calculate the intersection points. Second, you create a Math::Geometry::Construction::DerivedPoint from the Derivate. The DerivedPoint object holds information about which of the intersection points to use. This can be based on distance to a given point, being the extreme point with respect to a given direction etc..

The DerivedPoint object only holds information about how to select the right point. Only when you ask for the position of the point it is actually calculated. The purpose of this approach is that you will always get the desired point based on the current situation, even if you move your start configuration and the arrangement of points changes.

The classes are called Derivate and DerivedPoint because this concept is applicable beyond the case of intersections. It could, for example, be used to calculate the center of a circle given by three points. Whenever some operation based on given objects results in a finite number of points, it fits into this concept.

Current Status

At the moment, you can define points, lines, and circles. You can intersect circles and lines with each other. The objects can have labels, but the automatic positioning of the labels is very primitive and unsatisfactory withouth polishing by the user.

Next Steps




  $construction = Math::Geometry::Construction->new(%args)

Creates a new Math::Geometry::Construction object and initializes attributes. This is the default Moose constructor.

Public Attributes


By default the background is transparent. This attribute can hold a color to be used instead. Possible values depend on the output type. For SVG, it can hold any valid SVG color specifier, e.g. white or rgb(255, 255, 255). TikZ currently ignores the background attribute.


A construction holds a hash of the objects it contains. The hash itself is inaccessible. However, you can call the following accessors:

As more specific accessors there are

The points list contains both user defined points and derived points.


Holds the default point size that is used if no explict size is given to Point objects. Defaults to 6. Changing it will only affect Point objects created afterwards.




Returns a new Math::Geometry::Construction::FixedPoint object. All parameters are handed over to the constructor after adding the construction and order_index arguments.


  $construction->add_point(position => [10, 20]);
  $construction->add_point('x' => 50, 'y' => 30,
                           style => {stroke => 'red'});

  # requires 'use Math::Vector::Real' in this package
  $construction->add_point(position => V(-15, 23),
                           hidden   => 1);

  # NB: use of Math::VectorReal is still supported, but discouraged
  # in favor of Math::Vector::Real
  # requires 'use Math::VectorReal' in this package
  $construction->add_point(position => vector(-1.3, 2.7, 0),
                           size     => 10);



Returns a new Math::Geometry::Construction::Line object. All parameters are handed over to the constructor after adding the construction and order_index arguments.


  $construction->add_line(support => [$point1, $point2],
                          extend  => 10);



Returns a new Math::Geometry::Construction::Circle object. All parameters are handed over to the constructor after adding the construction and order_index arguments.

The "standard" circle requires the center and a "support" point on its perimeter. However, you can provide a radius instead of the support point, and the constructor of Math::Geometry::Construction::Circle will create a support point under the hood. Even if you move the center later on, the radius of the circle will stay constant.


  $construction->add_circle(center  => $point1,
                            support => $point2);
  $construction->add_circle(center  => $point1,
                            radius  => 50);


  $construction->add_derived_point($class, $derivate_args, $point_args)

Combines the creation of a Derivate object and a DerivedPoint object in one step.

The method expects three parameters:

1. the derivate class
2. a hash reference with arguments for the constructor of Math::Geometry::Construction::Derivate
3. a hash reference with arguments for the constructor of Math::Geometry::Construction::DerivedPoint; this argument is optional, if not defined it is replaced by an empty hash reference

Returns the DerivedPoint object.


  $derived_point = $construction->add_derived_point
       {input => [$line1, $line2]},
       {position_selector => ['indexed_point', [0]]});

In this example, the last hash reference can be omitted:

  $derived_point = $construction->add_derived_point
      ('IntersectionLineLine', {input => [$line1, $line2]});

The missing hash reference is replaced by an empty hash reference, and the constructor of the DerivedPoint object uses the default position selector ['indexed_point', [0]].

If multiple derived points based on the same derivative are desired then the third argument for add_derived_point can be replaced by the reference to an array of hash references each of which holds the parameters for one of the points. A list of DerivedPoint objects is returned.


  @derived_points = $construction->add_derived_point
       {input => [$circle, $line]},
       [{position_selector => ['extreme_point', [[0, -1]]]},
        {position_selector => ['extreme_point', [[0,  1]]]}]);

In this case, we ask for the two intersection points between a circle and a line. The extreme_point position selector will give us the most extreme of the intersection points in the given direction. Therefore, in SVG coordinates, $derived_points[0] will hold the "northern", $derived_points[1] the "southern" intersection point.


  $construction->add_derivate($class, %args)

Creates and returns a Math::Geometry::Construction::Derivate subclass instance. This can be used to create DerivedPoint objects. In most cases, it is convenient to perform these two steps in one go, see add_derived_point.

This method is a convenience shortcut for add_object. The only difference is that $class is prepended with Math::Geometry::Construction::Derivate::. Therefore you can call

  $construction->add_derivate('IntersectionCircleLine', %args)

instead of

      ('Math::Geometry::Construction::Derivate::IntersectionCircleLine', %args)


  $derivate = $construction->add_derivate('TranslatedPoint',
                                          input      => [$point],
                                          translator => [10, -20]);
  $point    = $derivate->create_derived_point;


  $construction->add_object($class, %args)

Returns a new instance of the given class. All parameters are handed over to the constructor after adding the construction and order_index arguments. In fact, the methods above just call this one with the appropriate class.


  $construction->draw('SVG', %args)

Shortcut for draw. Returns an SVG object representing the construction. All parameters are handed over to the SVG constructor. At least width and height should be provided.

If a background color is specified then a rectangle of that color is drawn as background. The size is taken from the viewBox attribute if specified, from width and height otherwise. If none is given, no background is drawn.


  my $svg = $construction->as_svg(width  => 800,
                                    height => 300);
  print $svg->xmlify;

  # or if SVG::Rasterize is installed...
  my $rasterize = SVG::Rasterize->new();
  $rasterize->rasterize(svg    => $svg,
                          width  => $width,
                          height => $height);
  $rasterize->write(type      => 'png',
                    file_name => 'construction.png');


  $construction->draw('TikZ', %args)

Shortcut for draw. Returns an LaTeX::TikZ sequence object representing the construction. See Math::Geometry::Construction::Draw and Math::Geometry::Construction::Draw::TikZ for supported parameters. At least width and height should be provided.


  my $tikz = $construction->as_tikz(width  => 8,
                                    height => 3);

  my (undef, undef, $body) = TikZ->formatter->render($tikz);
  printff("%s\n", join("\n", @$body));


  $construction->draw('SVG', %args)

Draws the construction. The return value depends on the output type and might be an object or a stringified version. Currently, the only output types are SVG and TikZ. See as_svg and as_tikz.

If the type does not contain a :: then it is prepended by Math::Geometry::Construction::Draw:: before requiring the module.

Calls the draw method first on all non-point objects, then on all Point and DerivedPoint objects. This is because I think that points should be drawn on top of lines, circles etc..

List of Derivates

Partial Drawing

Each line or similar object holds a number of "points of interest". These are - in case of the line - the two points that define the line and all intersection points the line is involved in. At drawing time, the object determines the most extreme points and they define the end points of the drawn line segment. The extend attribute allows to extend the line for a given length beyond these points because this often looks better. A similar concept exist for circles.

Reusing Objects




Currently, Math::Geometry::Construction does not use any advanced exception framework, it just croaks if it is unhappy. The error messages are listed below in alphabetical order.



Please report any bugs or feature requests to bug-math-geometry-construction at, or through the web interface at I will be notified, and then you will automatically be notified of progress on your bug as I make changes.


Lutz Gehlen, <perl at>


Copyright 2011-2013 Lutz Gehlen.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See for more information.

syntax highlighting: