/ipe-lassotool

Ipelet implementing a lasso selection tool for the Ipe editor

Primary LanguageLuaGNU General Public License v3.0GPL-3.0

Lasso Tool Ipelet

This Ipelet implements a Lasso Tool in Ipe.

The main difference to the normal, rectangular selection tool is that arbitrary selection polygons can be drawn. Furthermore, for the selection not the bounding boxes of objects are considered, but their actual geometry.

Usage

Select Ipelets -> Lasso Select or use the configured shortcut (line 13) to enter the selection mode.

You can also use a mouse binding to start the tool. For example, if you want to bind it to CTRL+Left Mouse, you can write the following:

mouse.left_control = function (model, modifiers)
    tool = LASSOTOOL:new(model)
    tool:mouseButton(1, modifiers, true)
end

Start dragging the mouse to draw a selection polygon. If you release the mouse, the objects inside the polygon are selected. Additive selection can be performed by holding the shift key.

Selection that cannot be performed by rectangular selection

Select multiple objects

Correctly select different types of objects

Select different objects

Select many objects at once

Select many objects

Installation

Copy lassotool.lua to a location found by IPE.

(Normally this is ~/.ipe/ipelets for Linux and %userprofile%\ipelets for Windows (see Help->Show configuration))

Technical Details & Lessons Learned

  • The selection path of the Lasso is implemented as a closed polygon consisting of line segments
  • To detect that a point lies within the polygon, a very simple ray casting algorithm is used
  • To detect that other objects (paths, arcs, ...) lie within the polygon, a search for intersections with the Lasso is performed. If there are no intersections AND one point of the object lies within the Lasso, the object is completely inside.
  • To simplify the Lasso polygon, the very straightforward recursive Ramer-Douglas-Peucker algorithm is used
  • The complexity of identifying whether an object is inside could be reduced by a sweep-line algorithm, for example. However, the currently implemented bruteforce method was "good enough" for me (detection of over 30,000 objects takes less than 500ms on my computer)
  • For speed up, only objects that are visible, not locked and whose bounding box lies completely within the bounding box of the lasso polygon (Ipe>=7.2.29) are taken into account.
  • For nested groups of objects, the transformation matrices have to be applied recursively
  • The outline of an image object is not directly accessible. One option is to apply the inverse transformation matrix, get the bounding box and again apply the forward transformation.
  • The outline of a text object is not directly accessible. One option is to calculate the outline based on the position, dimensions, alignment and transformation matrix