SVG Graphical Programming

SVG Tool
The vector between the two blue dots on the circle was created via 2 point and click, ese

SVG Tool now allows the user to point-and-click on 2 points along the circumference of a circle, and automatically creates lines between them.

Doing so repeatedly allows the end user to quickly sketch, say, a basic pattern.

The points along the circumference are also dynamically created by the designer, using the two input boxes (Radii and Angle) provided for this purpose.

Clicking on the Mark button automatically populates the endpoints of the lines along the circle.

Hovering over any of these graphical objects produces a tooltip with an object identifier.

Next step will be to come up with an algorithm — there is math stuff out there on the subject the one can Google — that calculates where a line intersects with other lines in the interior of a circle.

This would allow an end user to erase sections of a given vector simply by clicking.  Deleting sections of a line is of course not possible in standard or native SVG, but I have demoed in a prior post how to do it with paths.

Implementing in JS a coordinate geometry algorithm that can quickly and accurately figure out the intersection points of any 2 lines inside a circle is non trivial.

If I can devise one that actually works, then SVG Tool will genuinely allow designers to create basic Islamic Design patterns without having to resort to tedious calculations and SVG coding.  Such an approach would of course be light years ahead of using traditional means such as rulers and compasses and protractors.

Meanwhile, I still have some grunt work error checking to bake in regarding the automated line drawing you see above.

I also will be implementing a “delete line” capability, which the user can invoke via a double mouse click on a line already drawn.

I will be putting up this new version of SVG Tool on Git after I complete these enhancements.

If you are interested in the details on how I did this, you will have to wait to read the code, but in the meantime I will summarize at a high level how it works.

What I have done in the SVG tool so far is write what is essentially an old school C-style procedural program.

The drawing algorithm I use relies on two global arrays:  one contains the starting and terminal coordinates of each line that originates from the center of the circle; the other one contains the x y coordinates of the vertices that the user sequentially clicks on.

The algorithm is based on indexed based lookups between these two arrays, with a naive global semaphore to coordinate the order of the vertices clicked on (ie, no async time delimited wait times for paired inputs).

I have avoided almost all of the fancy mandarin-like constructs that ECMA-262 supports, relying instead on straightforward, script-like code where everything that happens is explicit, easily debugged, and as fast as possible within the constraints of DOM programming.

I developed this habit a long time ago, when I worked as a system guy on Wall Street, and did not relish having to figure out, when I got a maintenance call at 2am, what, say, an overloaded function was doing wrong, much as I personally admired Bjarne at the time.

However, I am not immune to the charms of elegant programming, and may, for example eventually migrate the SVG Tool  codebase to a functional paradigm.

That will come later, probably after I re-implement this somewhat clunky HTML/SVG interface under CSS grid.

Meanwhile, you can now come up with new patterns on the fly with the current iteration of SVG Tool.

Here’s a little doodle that took a few seconds to produce.

svg
After I made this, I immediately wish I could click inside the various sections to color them in various ways.

A user might want to save such a doodle to a text file on their local machine.

To support that I have to supply a button that when clicked fires a function that traverses root <svg>, serializes the output, and presents a SaveFile popup.

svg
The DOM’s root svg, as seen in Chrome’s console

I’ve already written a little side function snippet that does some of this.