22 views

Skip to first unread message

Oct 19, 2022, 12:27:56 PM10/19/22

to

Pursuant to Julian's parallel curve threads and my "snipping the ears"

thread, I dug into a few articles and found one with code that I could

mostly implement in PostScript.

Using this, one could define separate heuristics for each class of

curve and maybe convert loops into cusps. Thus identifying and

snipping all the ears.

But it calls for 3 functions (H0, H1, H2) which I don't know how to

implement. It's supposed to determine the position of the Origin

in the "hodograph associated with the implicit Bezier curve".

So presumably, I have to ... I don't know what .... do some crazy

stuff with resultant matrices and Sylvester matrices? Then take

the derivatives of the implicit equation wrt u and v, I suppose.

But I don't know how to do step 2.

$ cat bez.ps

% https://www.researchgate.net/profile/Abdelouahad-Bayar/publication/317351174_A_Practical_Way_to_Characterize_Non-degenerate_Cubic_BEZIER_Curves/links/5b43ee210f7e9bb59b1b0c0f/A-Practical-Way-to-Characterize-Non-degenerate-Cubic-BEZIER-Curves.pdf?origin=publication_detail

/bzGeoChz {

1 dict begin {y3 x3 y2 x2 y1 x1 y0 x0}{exch def}forall

/gx x3 x0 sub def

/gy y3 y0 sub def

/flt

3 x1 x0 sub mul 3 y1 y0 sub mul

3 x2 x1 sub mul 3 y2 y1 sub mul

3 x3 x2 sub mul 3 y3 y2 sub mul

0 0 linearFlag

3 x1 x0 sub mul 3 y1 y0 sub mul

3 x2 x1 sub mul 3 y2 y1 sub mul

3 x3 x2 sub mul 3 y3 y2 sub mul

gx gy linearFlag

xor

def

flt 0 eq {

/flt 7

x0 y0 x1 y1 x2 y2 x3 y3 0 0 quadLocationFlag

add def

} if

flt 1 eq { 1 }{

flt 6 eq { 2 }{

flt 10 eq { 3 }{

flt 2 eq

flt 4 eq or { 4 }{

flt 3 eq

flt 5 eq or { 5 }{

flt 9 eq { 6 }{

flt 7 eq { 7 }{

8

}ifelse }ifelse }ifelse }ifelse }ifelse }ifelse }ifelse

end

} def

/quadLocationFlag {

1 dict begin {y x y3 x3 y2 x2 y1 x2 y0 x0}{exch def}forall

/flag

x0 y0 x1 y1 x2 y2 x y H0

dup 0 gt { pop 2 }{

0 lt { 1 }{ 0 } ifelse

} ifelse

def

x0 y0 x1 y1 x2 y2 x y H1 0 lt

x0 y0 x1 y1 x2 y2 x y H2 0 lt or {

/flag flag 2 add def

} if

flag

end

} def

/linearFlag {

1 dict begin {y x hy2 hx2 hy1 hx1 hy0 hx0}{exch def}forall

/flag 0 def

/gx hx0 hx1 hx2 add add 3 div def

/gy hy0 hy1 hy2 add add 3 div def

hx1 hx0 sub gy hy0 sub mul

hy1 hy0 sub gx hx0 sub mul sub

0 gt {

hx1 hx0 sub y hy0 sub mul

hy1 hy0 sub x hx0 sub mul sub

0 ge {

/flag flag 4 add def

} if

hx2 hx1 sub y hy1 sub mul

hy2 hy1 sub x hx1 sub mul sub

0 ge {

/flag flag 2 add def

} if

hx0 hx2 sub y hy2 sub mul

hy0 hy2 sub x hx2 sub mul sub

0 ge {

/flag flag 1 add def

} if

}{

hx1 hx0 sub y hy0 sub mul

hy1 hy0 sub x hx0 sub mul sub

0 gt {

/flag flag 4 add def

} if

hx2 hx1 sub y hy1 sub mul

hy2 hy1 sub x hx1 sub mul sub

0 gt {

/flag flag 2 add def

} if

hx0 hx2 sub y hy2 sub mul

hy0 hy2 sub x hx2 sub mul sub

0 gt {

/flag flag 1 add def

} if

} ifelse

end

} def

/H0 {

} def

/H1 {

} def

/H2 {

} def

thread, I dug into a few articles and found one with code that I could

mostly implement in PostScript.

Using this, one could define separate heuristics for each class of

curve and maybe convert loops into cusps. Thus identifying and

snipping all the ears.

But it calls for 3 functions (H0, H1, H2) which I don't know how to

implement. It's supposed to determine the position of the Origin

in the "hodograph associated with the implicit Bezier curve".

So presumably, I have to ... I don't know what .... do some crazy

stuff with resultant matrices and Sylvester matrices? Then take

the derivatives of the implicit equation wrt u and v, I suppose.

But I don't know how to do step 2.

$ cat bez.ps

% https://www.researchgate.net/profile/Abdelouahad-Bayar/publication/317351174_A_Practical_Way_to_Characterize_Non-degenerate_Cubic_BEZIER_Curves/links/5b43ee210f7e9bb59b1b0c0f/A-Practical-Way-to-Characterize-Non-degenerate-Cubic-BEZIER-Curves.pdf?origin=publication_detail

/bzGeoChz {

1 dict begin {y3 x3 y2 x2 y1 x1 y0 x0}{exch def}forall

/gx x3 x0 sub def

/gy y3 y0 sub def

/flt

3 x1 x0 sub mul 3 y1 y0 sub mul

3 x2 x1 sub mul 3 y2 y1 sub mul

3 x3 x2 sub mul 3 y3 y2 sub mul

0 0 linearFlag

3 x1 x0 sub mul 3 y1 y0 sub mul

3 x2 x1 sub mul 3 y2 y1 sub mul

3 x3 x2 sub mul 3 y3 y2 sub mul

gx gy linearFlag

xor

def

flt 0 eq {

/flt 7

x0 y0 x1 y1 x2 y2 x3 y3 0 0 quadLocationFlag

add def

} if

flt 1 eq { 1 }{

flt 6 eq { 2 }{

flt 10 eq { 3 }{

flt 2 eq

flt 4 eq or { 4 }{

flt 3 eq

flt 5 eq or { 5 }{

flt 9 eq { 6 }{

flt 7 eq { 7 }{

8

}ifelse }ifelse }ifelse }ifelse }ifelse }ifelse }ifelse

end

} def

/quadLocationFlag {

1 dict begin {y x y3 x3 y2 x2 y1 x2 y0 x0}{exch def}forall

/flag

x0 y0 x1 y1 x2 y2 x y H0

dup 0 gt { pop 2 }{

0 lt { 1 }{ 0 } ifelse

} ifelse

def

x0 y0 x1 y1 x2 y2 x y H1 0 lt

x0 y0 x1 y1 x2 y2 x y H2 0 lt or {

/flag flag 2 add def

} if

flag

end

} def

/linearFlag {

1 dict begin {y x hy2 hx2 hy1 hx1 hy0 hx0}{exch def}forall

/flag 0 def

/gx hx0 hx1 hx2 add add 3 div def

/gy hy0 hy1 hy2 add add 3 div def

hx1 hx0 sub gy hy0 sub mul

hy1 hy0 sub gx hx0 sub mul sub

0 gt {

hx1 hx0 sub y hy0 sub mul

hy1 hy0 sub x hx0 sub mul sub

0 ge {

/flag flag 4 add def

} if

hx2 hx1 sub y hy1 sub mul

hy2 hy1 sub x hx1 sub mul sub

0 ge {

/flag flag 2 add def

} if

hx0 hx2 sub y hy2 sub mul

hy0 hy2 sub x hx2 sub mul sub

0 ge {

/flag flag 1 add def

} if

}{

hx1 hx0 sub y hy0 sub mul

hy1 hy0 sub x hx0 sub mul sub

0 gt {

/flag flag 4 add def

} if

hx2 hx1 sub y hy1 sub mul

hy2 hy1 sub x hx1 sub mul sub

0 gt {

/flag flag 2 add def

} if

hx0 hx2 sub y hy2 sub mul

hy0 hy2 sub x hx2 sub mul sub

0 gt {

/flag flag 1 add def

} if

} ifelse

end

} def

/H0 {

} def

/H1 {

} def

/H2 {

} def

Jul 4, 2023, 6:03:04 PMJul 4

to

> Using this, one could define separate heuristics for each class of

> curve

What are the classes of curve?
> curve

Jul 4, 2023, 6:06:05 PMJul 4

to

Relevant links:

http://groups.google.com/g/comp.lang.postscript/c/OTpiW7feg_c/m/7S733-mkey4J

http://groups.google.com/g/comp.lang.postscript/c/bFWXCkT2R-A

http://groups.google.com/g/comp.lang.postscript/c/UJKMKfAoqDY/m/Ba9OAtLdCAAJ

(indeed, I’d welcome an explanation of the term “Snipping the ears”.)

https://github.com/jdaw1/placemat/issues/18

http://groups.google.com/g/comp.lang.postscript/c/OTpiW7feg_c/m/7S733-mkey4J

http://groups.google.com/g/comp.lang.postscript/c/bFWXCkT2R-A

http://groups.google.com/g/comp.lang.postscript/c/UJKMKfAoqDY/m/Ba9OAtLdCAAJ

(indeed, I’d welcome an explanation of the term “Snipping the ears”.)

https://github.com/jdaw1/placemat/issues/18

Jul 6, 2023, 11:56:41 AMJul 6

to

paper by D.S. Kim from the 80s that I didn't want to pay Springer's crazy

price for.

The classes themselves are in figure 2 of the paper by Bayar. He shows

6 stereotypical forms of curve and any given bezier curve is supposed

to be (or boil down to) one of these. And he gives some Pascal code

for everything except H0(), H1(), and H2() for which he refers you to Kim.

I tried asking ChatGPT for help implementing H0, H1, and H2. But none

of the formulas it gave me really made any sense, and they didn't produce

the desired results. But if you can track down the Deok Soo Kim paper

and then do your Mathematica magic on it, I bet we'd get there.

Jul 6, 2023, 12:25:31 PMJul 6

to

On Tuesday, July 4, 2023 at 5:06:05 PM UTC-5, jdaw1 wrote:

> (indeed, I’d welcome an explanation of the term “Snipping the ears”.)

>

> https://github.com/jdaw1/placemat/issues/18

That was my nickname for the artifact happening when the corners
> (indeed, I’d welcome an explanation of the term “Snipping the ears”.)

>

> https://github.com/jdaw1/placemat/issues/18

were too tight. My algorithm produces a little "trapeze" or "dog ear"

instead of smoothing over the problem spots. It showed up in the

little corners of the (9) charpath when offset and got worse and worse

with repeated offsetting.

Reply all

Reply to author

Forward

0 new messages

Search

Clear search

Close search

Google apps

Main menu