evil-mad / axidraw

Software for the AxiDraw drawing machine
GNU General Public License v2.0
439 stars 131 forks source link

Start drawing from current position / from specified point of drawing #141

Open James-Mat opened 1 year ago

James-Mat commented 1 year ago

I looked through the issues and found Setting the home position option? #54, which, if I'm reading the poster correctly, is about the same case. The workaround does work, but is quite cumbersome.

To rephrase the case: I often find myself trying to write text or draw shapes at a specific postion on the medium. If that's not a regular format like DIN A4, in which case one could align the top right corner with the home corner, aligning is either ticklish measurement or guesswork. The way it is now with f.e. text, the first movement is always from the position of the pen at the beginning of the plot / the home-corner to the left, to the first letter.

It would be a lot easier to put the pen to where the drawing should start manually with the motors turned off, and then start from there, i.e. have the axidraw start the drawing without any corrective movement right at the first node of the first curve. This would already be fairly optimal behaviour for text. For shapes etc., like @patakk pointed out, being able to specify a start-point within the drawing, which corresponds to the position of the pen where it is when plotting starts, would be advantageous. As an exmaple: You want to draw a star in the middle of a medium. You'd place the start-point in the middle of the shape. Then, you'd only need to move the pen before starting the plot to the middle of the medium and press plot: The result is a star as perfectly in the middle as you were able to align the pen.

As it is now, you'd need to measure the size of the shape, or a kind of bounding box if it is irregular, align that theoretical box to the home corner, and then move the middle of the star in the drawing by half of x and y of the box. For many differently sized media, like leather, this is really cumbersome, whereas with the approach above it would only mean moving the pen to where the star should be.

Placing a dot, which fulfills the same function as the mentioned starting-point, on another layer, then having a pause layer, and only then adding the pen and starting the plot of the actual layer as mentioned in #54 does work as a workaround, but is also tedious for many plots.

I hope I made the usecase understandable. I'm actually kind of surprised that this is not possible without workaround already, since it's exactly where the axidraw shines: Drawing on irregular shapes and unusual materials, which a normal printer couldn't handle.

oskay commented 1 year ago

It would be a lot easier to put the pen to where the drawing should start manually with the motors turned off, and then start from there, i.e. have the axidraw start the drawing without any corrective movement right at the first node of the first curve. This would already be fairly optimal behaviour for text.

I am not following how this would be helpful. Since the location of the first node of the first curve is rarely obvious -- especially for text -- this seems like it would make things extremely difficult to use.

I also don't follow how you would want to define the SVG file for a case like this. An SVG file defines the origin (0, 0) to be at the corner of the document. If you instead wanted to construct a virtual origin at the center of the document, at the first node of your curve, or at the center of your artwork within the document, you would need some way to encode that in the file itself or make it selectable within the software.

The workaround suggested in #54 isn't something that we regularly recommend. I think that more than anything else, it merely reflects that it's been a long time since someone asked about something like this.

As it is now, you'd need to measure the size of the shape, or a kind of bounding box if it is irregular, align that theoretical box to the home corner, and then move the middle of the star in the drawing by half of x and y of the box. For many differently sized media, like leather, this is really cumbersome, whereas with the approach above it would only mean moving the pen to where the star should be.

Yes, that would be really cumbersome. The usual way to draw on a strange shape is to draw a locator for it in Inkscape, draw that locator on the workbench (or on a big piece of cardboard or paper) and then put the object up against the locator to ensure that it's properly located for drawing on. (The locator can be an exact shape -- if known -- or a traced photo, or two lines at right angles.)

I'm actually kind of surprised that this is not possible

Suppose that we wanted to implement this right away. Is there a way to do so that would make sense?

How would you recommend that it be implemented? What would the user do to represent where the starting point of the pen was? And, how would they configure the machine physically to ensure that the travel bounds were still respected? Would the software do an automatic move to the starting point (like it does in the #54 example), or something else?

James-Mat commented 1 year ago

Hi oskay, thank you for your swift reply!

I am not following how this would be helpful. Since the location of the first node of the first curve is rarely obvious -- especially for text -- this seems like it would make things extremely difficult to use.

Hmm, when working with the Hershey Text extension in Inkscape, the first curve drawn is always one of the ones of the textually first letter; in that case, you'd just put the pen where you want the first letter to be, which I thought might be an intuitive method to arrange text. If you need more precise control than 'somewhere within the first letter', inspecting the paths within the letter would of course become necessary.
For custom handwritten script, the direction of movement must already be considered when designing the drawing, so direction and order should already be known.
Such an option would be really just a shorthand for the described start-point-behaviour, so I think you're right in omitting that and focus on a possible home-node instead (I think home-node following the nomination home corner is a better term compared to what I've used before).

I also don't follow how you would want to define the SVG file for a case like this. An SVG file defines the origin (0, 0) to be at the corner of the document. If you instead wanted to construct a virtual origin at the center of the document, at the first node of your curve, or at the center of your artwork within the document, you would need some way to encode that in the file itself or make it selectable within the software.

I'm not sure if there are considerations of which I'm unaware, but a possibility would be using the ID of the SVG path. A potential home-node would need to be unique, so I think the ID field would be a through both, Inkscape and direct management of an SVG, accessible option.
Another one would be to use an additional layer with a specific inkscape:label, which is how I guess the pause-functionality is handled right now. That layer would then only contain a single node, which is to be understood as the home-node. For applying that onto the actual drawing: I think the coordinates in an SVG can be absolute or relative; in case of absolute coordinates, the home-node position would simply be subtracted from the movement the AxiDraw would perform with a home-node of (0, 0). For relative coordinates, I'd need to look up on how they work in an SVG first.
My first try was actually to just construct the drawing around the home-corner, but unfortunately the software detects that the drawing would be out of bounds, since the pen is assumed to be at the home-corner. Being able to disable this check, would actually solve the problem and would only make for some unsightlier SVGs, since 3/4ths of the drawing would be outside the layer boundaries.

Yes, that would be really cumbersome. The usual way to draw on a strange shape is to draw a locator for it in Inkscape, draw that locator on the workbench (or on a big piece of cardboard or paper) and then put the object up against the locator to ensure that it's properly located for drawing on. (The locator can be an exact shape -- if known -- or a traced photo, or two lines at right angles.)

I understand that approach. It makes measuring the medium necessary though, or, in case of the right-angled-lines, measuring from that reference point, whereas simply putting the pen to where you'd want it to start (in case of known path-order) or simply where a certain node of the drawing is supposed to end up does seem like an intuitive option to me.
This would only make it necessary to keep an eye on the size of the drawing, as to not exceed the bounds of the AxiDraw, but this should be done anyhow if the size of the drawing is relevant to the medium. If one is not working at the limits of the range, a judgmenent by eye should also be pretty easy.

Suppose that we wanted to implement this right away. Is there a way to do so that would make sense?

How would you recommend that it be implemented? What would the user do to represent where the starting point of the pen was? And, how would they configure the machine physically to ensure that the travel bounds were still respected? Would the software do an automatic move to the starting point (like it does in the https://github.com/evil-mad/axidraw/issues/54 example), or something else?

Apart from what I've mentioned above, which might be a bit vague because I'm not used to work with SVGs directly, I would expect a behaviour like this:

Sorry for the long text, it's gotten a bit out of hand.
I think this would make for an intuitive way to use the AxiDraw. I can't tell if my kind of thinking is just really unusual; I've been using the AxiDraw since 2017 and only now thought of actually requesting that feature, so maybe the feature is not too extra and more users would benefit from it. An easy solve for me specifically would be the possibility to disable the check for whether the drawing is inside the layer / travel bounds, so it could be arranged around the home-corner, with the warning that the AxiDraw can't verify anymore that the drawing won't lead it outof travel bounds.

oskay commented 1 year ago

OK, that's helpful. However, I'm still not following what the possible application for this feature would be, nor any real-world situations where it could actually save a user (yourself included) effort or time.

Is there any specific method that you would propose for a user to "place a node"? I can't immediately think of any good user-interface model for this in Inkscape.

For text in particular, determining where the first node is can be quite difficult. Finding the first letter in text laid out with Hershey Text is easy, but within that, it won't be obvious to a user which path or subpath is first, nor which direction it starts in-- to tell which node on that path is first. This sounds like a really, really hard way to get things aligned to any extent.

If you're already able to the pen starting position to the upper left corner of a text block, it sounds like it would be easier to use the AxiDraw in the normal way -- that you put the position where you want to align the upper-left corner of the text block up against the pen. In the example of the ruled lines, that would be to put the ruled lines under the pen.

Unfortunately, working within Inkscape, there's no facility at present to give a dialog box to ask a user a question before proceeding.

I would note that your request is somewhat related to a couple of more frequent (though still very infrequent) feature requests that would both be more straightforward to implement, and for which I can see some possible use cases.

Occasional feature request 1: Plot bounding box With this feature implemented, the AxiDraw could draw a rectangle around the artwork in the document, helping to ensure that the physical workpiece is correctly positioned, when plotted with or without a pen depending on preference.

Occasional feature request 2: Centered plotting With this feature implemented, the AxiDraw would plot the artwork in the document centered on the document (or on the full travel area, when working with a document larger than the travel). We could add to that a feature "move to center" that moves the pen to the center position, and such that (if started there), each plot would begin and end at that center position. That would make it possible to physically position items under the pen that have an easy-to-identify center position.

James-Mat commented 1 year ago

Is there any specific method that you would propose for a user to "place a node"? I can't immediately think of any good user-interface model for this in Inkscape.

I think this should be conveniently achievable within an Inkscape extension, from what I remember when I wrote some myself. Unfortunately, a lot of my projects need to be finished within Q1 of 2023, so I think I can only start tinkering myself when that's done. I just wanted to pitch the feature request and see where it leads first, but it seems that it's more of a me-problem. When I find the time, I'll try to create a rough UI and see whether things work as I'd intend them to.

For text in particular, determining where the first node is can be quite difficult. Finding the first letter in text laid out with Hershey Text is easy, but within that, it won't be obvious to a user which path or subpath is first, nor which direction it starts in-- to tell which node on that path is first. This sounds like a really, really hard way to get things aligned to any extent.

I think what I'm using for that right now works well, though it could be faster if Inkscape had an option to visualize these from the Edit Paths tool. I'm using Extensions -> Visualize Path -> Number Nodes -> Live Preview, this shows the exact order that the AxiDraw will use. So, by selecting the bottom-most path and visualizing the nodes like that, you can see whith which node AxiDraw will start when pressing plot. At some point, I also wrote an Extension which adds points to the start and end of each path to see whether my drawing had any overlapping path ends, on which the AxiDraw would raise and lower the pen instead of moving over fluently, but that was before the addition of plot optimization.

If you're already able to the pen starting position to the upper left corner of a text block, it sounds like it would be easier to use the AxiDraw in the normal way -- that you put the position where you want to align the upper-left corner of the text block up against the pen. In the example of the ruled lines, that would be to put the ruled lines under the pen.

I think it really just boils down to my way of thinking - I'd rather fix the medium first and the position the pen to where it's supposed to start drawing than positioning the medium under the pen, either with the !pause workaround or by measuring where it's supposed to end up relative to the home corner. It seems natural to me, since it's the way you'd start drawing or writing by hand as well. This might just be an unusual way of thinking though, in which case I think your resources are better spend elsewhere!

Unfortunately, working within Inkscape, there's no facility at present to give a dialog box to ask a user a question before proceeding.

Oh, I thought there was. Then there's only the informational pop-up which can only be closed without a choice, is there?

I would note that your request is somewhat related to a couple of more frequent (though still very infrequent) feature requests that would both be more straightforward to implement, and for which I can see some possible use cases.

I definitely see the advantages of Occassional Request 1.
The second one is a bit elusive to me - wouldn't it yield the same result to simply center the drawing by Inkscape means? The move-to-center-variant goes in a similar direction though, but wouldn't that create the same problem I described above where the AxiDraw assumes this center-position to be the home corner and therefore doesn't allow travel in negative x or negative y direction?
That's what I meant in my last reply with arranging around the home corner: If it is possible to remove the checks for travel bounds, I could just, to use the example from above, move my determined first node or the baseline of the first line to the home corner. This would look a bit weird, since the whole text is then outside the layer in Inkscape, but should yield my desired behaviour. I don't know if it really would just be disabling the check to make that work, or if the then possibly negative coordinates would pose problems to the AxiDraw API.
If this could be made possible, I would be really happy; otherwise, I'll see what I can achieve myself when I find the time and could possibly reopen the issue once I made progress!

Also Merry Christmas!

oskay commented 1 year ago

I think this should be conveniently achievable within an Inkscape extension

Maybe, but IMO it's better user experience to do everything with Inkscape tools and then to use the AxiDraw extension to plot. If you need the user run an extension to place or label a start point like that, then we're somewhat failing at making the feature user friendly.

Also, to me it just seems unnecessarily complicated to approach it this way. A document already has a (0, 0) defined. If you're placing artwork on your document with respect to some origin, placing the artwork on the document with respect to a different origin requires (at least) as much effort.

I just wanted to pitch the feature request and see where it leads first

If I understand what is being requested here, it's "Set the first vertex encountered to be at position (0,0) and turn off all travel limit checking".

If so, that sounds like a trivial modification to make in terms of programming, but not one that we immediately see any application for outside of your individual needs. If you can propose a reasonable UX model for some way of doing something similar that would still allow the AxiDraw to know its travel bounds, that might be different, especially if you could suggest a use case where someone else might find it useful.

At some point, I also wrote an Extension which adds points to the start and end of each path to see whether my drawing had any overlapping path ends, on which the AxiDraw would raise and lower the pen instead of moving over fluently, but that was before the addition of plot optimization.

The path joining optimization to reduce pen lifts travel has actually been there since the first AxiDraw software in 2016.

I think it really just boils down to my way of thinking - I'd rather fix the medium first and the position the pen to where it's supposed to start drawing than positioning the medium under the pen [...]. It seems natural to me, since it's the way you'd start drawing or writing by hand as well.

If that were your main issue, you wouldn't be making a feature request. You would just pick up the AxiDraw and put the pen exactly where you want to start the drawing. That's a common workflow.

The AxiDraw is a printer, or maybe a simple "robot", but in either case, it's an output device. There is no facility for measuring where you place its carriage by hand. Any process that begins by positioning the carriage with the motors off that isn't against a hard stop leads to an undefined initial case from which we cannot guarantee that it won't run into the ends of travel. It wouldn't be something that we would want as a standard supported feature.

This would look a bit weird, since the whole text is then outside the layer in Inkscape, but should yield my desired behaviour.

One possible approach that might get where you want would be to use a series of 'walk' type commands to move the carriage from the Home corner, under power, to where you need it to start. And, you could define that position as (0,0) with respect to your SVG document -- making it so that you could draw things off the page, so long as they still fit within the travel area of the AxiDraw.

The big problem with this approach is that items outside of the SVG document bounds should be clipped. The actual thing in an SVG file that the document size represents -- the only reason that it is there at all -- is specifically to say "Hey, stuff outside this rectangle shouldn't be drawn." If you open up an SVG file in a web browser, and the file includes paths that go outside the page, those paths are clipped at the page boundaries.

The move-to-center-variant goes in a similar direction though, but wouldn't that create the same problem I described above where the AxiDraw assumes this center-position to be the home corner and therefore doesn't allow travel in negative x or negative y direction?

No; It would allow travel over the full range of travel allowed by the AxiDraw, clipping travel at the machine (or document) travel bounds, whichever is smaller.

James-Mat commented 1 year ago

The path joining optimization to reduce pen lifts travel has actually been there since the first AxiDraw software in 2016.

Ah, now I remember: The nodes I got from the .ttf-texts didn't align by some μm, which is why the path joining didn't work. What my extension did, apart from visualizing the ends, was to move path-ends which are off by some lenience to the identical coordinates and join the path. I got confused since the option to choose the different plot optimizations is newer.

If you can propose a reasonable UX model for some way of doing something similar that would still allow the AxiDraw to know its travel bounds, that might be different

Any process that begins by positioning the carriage with the motors off that isn't against a hard stop leads to an undefined initial case from which we cannot guarantee that it won't run into the ends of travel. It wouldn't be something that we would want as a standard supported feature.

Unfortunately, I'm pretty sure that's not possible. What I'd call the convenience of moving the pen freely before starting the plot would always mean that the AxiDraw is unaware of its current position, and there would be no way to make sure travel bounds are not exceeded. I understand, why something like this would be discouraged as a standard feature.

No; It would allow travel over the full range of travel allowed by the AxiDraw, clipping travel at the machine (or document) travel bounds, whichever is smaller.

Oh, I thought of this in terms of the current capabilities, because currently the AxiDraw is not 'aware' of its new position when walking the carriage with motors turned on and assumes the pen to be at the home corner when starting the plot.
So the idea would be to give the middle as another home-point, alongside the home-corner. I see why this could mean an improvement for some use-cases, since, with the drawing centered as well, one would know that the drawing is formed around the pen.

One possible approach that might get where you want would be to use a series of 'walk' type commands to move the carriage from the Home corner, under power, to where you need it to start. And, you could define that position as (0,0) with respect to your SVG document -- making it so that you could draw things off the page, so long as they still fit within the travel area of the AxiDraw.

This would indeed be an alternative, which trades the safety of awareness of the travel bounds for the ease that would be to move the pen with motors turned off.
Maybe this would be realisable as a generalization of the move-to-center-approach, where it's possible to specify arbitrary coordinates within travel bounds. UX would be something like a tab within the extension where you'd put in the coords; on apply, the pen would be moved to the coordinates and the AxiDraw uses this as home-point, subtracting the new coordinates from how it would have moved with a home-point of (0, 0). This would give me the desired control to move the pen to where it actually starts drawing, simply by looking up the first node as described above and using this as starting coordinates.
I can see why the motors-off-variant is nothing to have as a standard feature, so this would make a good alternative for easier alignment of documents, since it isn't a specific amount of x and y from (0,0) which would need to be measured or tested beforehand but instead could be a point-of-interest within the drawing, which is, after specifying the coordinates accordingly, simply directly below the pen.
If progress in this direction could be made with the possibility to use arbitrary coordinates as home-point, I would be really happy!

oskay commented 1 year ago

Maybe this would be realisable as a generalization of the move-to-center-approach, where it's possible to specify arbitrary coordinates within travel bounds. UX would be something like a tab within the extension where you'd put in the coords; on apply, the pen would be moved to the coordinates and the AxiDraw uses this as home-point, subtracting the new coordinates from how it would have moved with a home-point of (0, 0).

I would imagine that the "moving" extension could use absolute, relative, or "first vertex of SVG" as options.

James-Mat commented 1 year ago

I would imagine that the "moving" extension could use absolute, relative, or "first vertex of SVG" as options.

This sounds great, thanks for taking consideration!