# Classifying bezier curves

22 views

### luser droog

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

/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
} 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

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

### jdaw1

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?

### jdaw1

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

### luser droog

Jul 6, 2023, 11:56:41 AMJul 6
to
I wasn't able to fully understand it. All the literature I found cites back to a
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.

### luser droog

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
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.