Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #2341 > unrolled thread
| Started by | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| First post | 2015-09-06 07:50 -0700 |
| Last post | 2016-06-09 01:20 -0700 |
| Articles | 6 — 3 participants |
Back to article view | Back to comp.lang.postscript
On the path luser- -droog <mijoryx@yahoo.com> - 2015-09-06 07:50 -0700
Re: On the path jdaw1 <jdawiseman@gmail.com> - 2015-09-07 01:43 -0700
Re: On the path luser- -droog <mijoryx@yahoo.com> - 2015-09-07 16:48 -0700
Re: On the path jdaw1 <jdawiseman@gmail.com> - 2015-09-08 02:02 -0700
Re: On the path luser- -droog <mijoryx@yahoo.com> - 2015-09-08 13:47 -0700
Re: On the path Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-09 01:20 -0700
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2015-09-06 07:50 -0700 |
| Subject | On the path |
| Message-ID | <549740ac-3620-4dad-b437-7c08d7bdd7b3@googlegroups.com> |
Inspired by Ken's insightful response to my question about
organizing a high-level device interface, and browsing
ghostscript's devices: http://ghostscript.com/doc/current/Drivers.htm ,
I want to go back and simplify everything.
Browsing my old threads
https://groups.google.com/d/topic/xpost-discuss/KJCesIt-AGw/discussion
I looked again at the Path Stack idea.
https://groups.google.com/d/topic/comp.lang.postscript/dAwAN5x5goU/discussion
And I think it can be made still simpler. It can be an array (or stack) of
just coordinate-pairs or sextuples. A path must start with a pair (not a
sextuple) and this is the initial moveto element. Subsequent lineto or
curveto elements are pairs or sextuples respectively. And a closed path
contains a duplicated (shared) copy of the moveto element, which will
compare equal "pointerwise" as 'the same pair'.
[0 0]
[1`1]
[2 2 3 3 4 4]
2 index % eg.
The process of iterating through the path with pathforall needs to use
a local variable to hold the moveto and compare each element (or just
pairs) against it to detect when to emit a /close call and reset to
moveto after the next pair (which must be a pair, as stipulated above).
This provides a direct translation from a flat-stack layout to a flat-array
layout, so I can use a stack for the "current path" and export arrays as
necessary for gsave/grestore.
This should be significantly less overhead than the dictionary-record
implementation of elements and dictionary-array implementations of
subpaths, paths, and path-stacks.
And it should reduce conversions for internal algorithms like clipping:
https://github.com/luser-dr00g/xpost/blob/master/data/clip.ps#L200
%clip the current path by the clipregion
% convert the path to an array of polygons (arrays of points)
% convert clipregion to array of polygons
% traverse the clipregion
% convert line to [A B C] form
% feed polygon and line to hodgman-sutherland,
% receiving new polygon.
% convert polygon array back to path structure
/doclip {
Producing a "polygon" becomes a getinterval.
[toc] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2015-09-07 01:43 -0700 |
| Message-ID | <bc7ada31-6c4a-4a0a-ae7f-de3a7e27aace@googlegroups.com> |
| In reply to | #2341 |
The following is meant to be a crossed square, but the pointer-equivalence rule causes a problem on the first re-use of PointA. /PointA [0 0] def /PointB [0 1] def /PointC [1 1] def /PointD [1 0] def PointA PointB PointC PointD PointA PointC PointB PointD Consider making an empty array, [], imply closepath.
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2015-09-07 16:48 -0700 |
| Message-ID | <05803aff-0b4d-4cbd-86e1-c57972520919@googlegroups.com> |
| In reply to | #2342 |
On Monday, September 7, 2015 at 3:43:23 AM UTC-5, jdaw1 wrote:
> The following is meant to be a crossed square, but the pointer-equivalence rule causes a problem on the first re-use of PointA.
>
> /PointA [0 0] def /PointB [0 1] def /PointC [1 1] def /PointD [1 0] def
> PointA PointB PointC PointD PointA PointC PointB PointD
>
> Consider making an empty array, [], imply closepath.
Excellent idea. I don't quite follow the problem you
describe, but it makes algorithms like coalescing
consecutive movetos much easier.
/last-was-moveto-p { 1 index length 0 eq } def
[toc] | [prev] | [next] | [standalone]
| From | jdaw1 <jdawiseman@gmail.com> |
|---|---|
| Date | 2015-09-08 02:02 -0700 |
| Message-ID | <e8fdb408-8a41-4bbd-bdc0-e5bf0adad362@googlegroups.com> |
| In reply to | #2343 |
> I don't quite follow the problem you describe Paths can have points visited more than once. [0 0] [0 1] [1 1] [1 0] [0 0] [2 2] Your old data setup would work with that. But if the repeated point had been def'd: /SpecialPoint [0 0] def Then SpecialPoint [0 1] [1 1] [1 0] SpecialPoint [2 2] would contain an array equivalence that doesn't mean 'closepath'. Error!
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2015-09-08 13:47 -0700 |
| Message-ID | <20d9b0b1-e5ca-498d-9b4a-3d1c5b2ca0ca@googlegroups.com> |
| In reply to | #2344 |
On Tuesday, September 8, 2015 at 4:02:07 AM UTC-5, jdaw1 wrote: > > I don't quite follow the problem you describe > > Paths can have points visited more than once. > [0 0] [0 1] [1 1] [1 0] [0 0] [2 2] > Your old data setup would work with that. > > But if the repeated point had been def'd: > /SpecialPoint [0 0] def > Then > SpecialPoint [0 1] [1 1] [1 0] SpecialPoint [2 2] > would contain an array equivalence that doesn't mean 'closepath'. Error! Ok. I see. This would all be for "internals", so the user interaction is still with the normal operators (moveto, lineto, curveto, closepath). But yes, the idea does look very fragile and prone to mistakes like you describe. A further refinement might be to use a 1-element array which contains a reference back to the moveto element. With the linear layout, this might more conveniently be an integer index instead of a pointer.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <lawrencedo99@gmail.com> |
|---|---|
| Date | 2016-06-09 01:20 -0700 |
| Message-ID | <06014966-3a71-4c03-8418-6960192d375a@googlegroups.com> |
| In reply to | #2341 |
On Monday, September 7, 2015 at 2:50:13 AM UTC+12, luser- -droog wrote: > It can be an array (or stack) of just coordinate-pairs or sextuples. A > path must start with a pair (not a sextuple) and this is the initial moveto > element. Subsequent lineto or curveto elements are pairs or sextuples > respectively. And a closed path contains a duplicated (shared) copy of the > moveto element, which will compare equal "pointerwise" as 'the same pair'. For a path structure that you can perform useful manipulations on, this is just too fiddly. That was my verdict, after trying to do something similar for Qahirah <https://github.com/ldo/qahirah>. In the end, I implemented my “Path” class in terms of one or more “Segment” objects. Each contains one or more “Point” objects, together with a “closed” flag. Each Point has a Vector (2D coordinate), together with an on-curve/off-curve flag. Two successive on-curve points define a straight line; one off-curve point in-between make a quadratic Bézier, and two successive in-between off-curve points a cubic Bézier. This structure is 1) easy to construct, and 2) easy to convert to moveto/lineto/curveto/closepath calls.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.postscript
csiph-web