#### Design and Trajectory

The development goal is to get some sort of end-to-end system doing something as quickly as possible.

To that end, we should likely start with only points, planes, and incidence constraints. That will let us make some simple polyhedra; not sure if there are any challenging problems with just those elements/constraints. If not, it's probably good, because we could get away with just rational numbers as our underlying mathematical space and a toy handwritten solver. It will also be a good start on gluing different components together to make a working system.

Speaking of components, here are some different pieces we need to consider:

##### Language

Top candidates include C++, likely with a syntactic sugar preprocessor to make coding in it bearable, compiled into WASM via Emscripten, and Lobster, a significant-whitespace language with an interesting type system that appears on the Awesome WASM Languages list (link should go here).

Other candidates include Civet (as it's already very comfortable to code in, but it mires us in the JavaScript-family morass), and Python (also very comfortable for coding, speed might not be an issue if we're mostly using other optimized components, but not sure how mature WASM compilation is).

##### Display and Interaction

Possibilities include three.js, D3.js, writing `<x3d>` elements to the DOM and then using either x3DOM or X_ITE, or direct WebGL programming. See also possibly ganja.js, mentioned in the coordinate representation as well.

##### User Interface

The goal is to take the best parts of the UIs of GeoGebra, Geometry Expressions, LibreCAD, and FreeCAD. Some lessons therefrom:

* Multi-selection should be effortless, probably click to toggle whether something is in the current selection -- but if so, need a really easy gesture to unselect everything.

* Modality: Should tools reset themselves after one use, or persist until the tool is canceled? One option is have the idiom that "select operands, then select tool" is a one-shot use of the tool, whereas selecting a tool when there are no operands selected "activates" that tool until it is "deactivated" by selecting another tool or deselecting that tool.

* Parallelism: Every operation should be equally invocable either by a menu item, toolbar button (if it is configured to be on one), keystroke (ditto), or textual "command" (e.g., in some functional notation). The menu layout should be fixed and comprehensive; the textual commands should be internationalized and comprehensive; and the program should offer a default toolbar layout and keyboard shortcuts that need not be comprehensive and which should be easily configurable.

##### Solver

SolveSpace could well provide a general numeric solver that would work for us. There is a new Julia-based computer algebra system OSCAR that could be of interest. Sage may have pieces we can use. There may be generic Gröbner basis implementations out there we can use.

A closely related question is the representation of numbers that appear in coordinates. We can start with exact rationals, which should be implemented or easy to implement in whatever language we choose. But as soon as we have any quadratic constraints (like equal distances) we will need at least quadratic algebraic numbers if not arbitrary algebraic numbers, and a package to represent/manipulate those will be needed.

##### Coordinate Representation

Besides just the representation of numbers, we have to decide how to coordinatize various geometric entities. The default starting place is just triples of numbers for points in $\mathbb{R}^3$, but we may quickly decide to use more elaborate coordinates that allow more operations or entities to be easily coordinatized. For example, many systems use homogeneous coordinates with one extra dimension so that all rigid motions and scalings can be represented as (in our case) 4×4 matrices. Systems that have been suggested are inversive coordinates (Alex Kontorovich, see [inversive.md](inversive.md)) and various Geometric Algebras (like Clifford Algebras and many variants). Related to this last operation, see ganja.js, which could also bear on the the display/interaction item above as well.

###### Representing lines

In general it seems in 3D it's more comfortable to represent planes and points than lines. There are appear to be numerous options, not clear if any are really perfect or canonical:

* [Equivalence classes of] pairs of points

* [Equivalence classes of] pairs of planes

* A bag of arbitrarily many collinear points [of course this is still equivalence classes, but the practical computational aspect is that when there's another point of interest that turns out to be on the line, you just throw it in the bag.]

* Plücker coordinates

* A plane through the origin and a point on it. The line is perpendicular to that plane and goes through that point. This representation at least seems to be 1-1. Easy to tell if lines are parallel. Maybe not as easy to tell if they intersect, but not particularly worse than pairs of points, for example.

* The unit normal vector of the plane from the last option, but projected to the xy-plane, and that point of intersection, but projected to the xy-plane, so that there are just four numbers corresponding to the four-dimensionality of the space of lines. This representation has some discontinuities: very close lines might be represented by faraway coordinates, and (partly as a result) it might be tricky to compute with in general.

###### Choice of coordinatization

Note that ultimately the choice of coordinates for entities serves solely to facilitate (a) display and manipulation of geometric objects, and (b) expressing and solving the constraints that are put on those entities. So we want to steer toward the choices that make those tasks the easiest. We won't necessarily have direct coordinates for every type of entity that Dyna3 allows to be created. Some may be "derived entities" that serve only as "front ends" for the actual items that Dyna3's internals are processing. For example, suppose we choose a system that provides direct parametrizations of spheres and planes (see e.g. [inversive.md](inversive.md)). Perhaps then when the user creates a circle, Dyna3 will actually create an auxiliary sphere and plane, and the auxiliary constraint that the plane contains the center of the circle. These auxiliaries would be marked so that only their intersection would be displayed, producing an arbitrary circle.

The sort of scheme outlined in the previous paragraph works particularly well when it is easy to express the sorts of constraints one wants on the derived entity in terms of the supported constraints on the auxiliary entities. So for example, we want to be able to constrain a circle to contain a given point -- that translates just to both the plane and the sphere contain that point, so that works well. We also want to be able to say that a line and circle are tangent. This translates to the line being in the associated plane (easily expressed) and then (as one possibility) that there is a second plane containing the line and perpendicular to the first plane and tangent to the sphere. So at least for those two examples, these underlying entities to represent circles seem to work fairly well.
