the function bezier draws a spike on the inside of the curve when it creates an infinitesimally small loop.

note: this spike is also on the outside of the loop if lineJoin(MITER) but this is expected.

the function bezier draws a spike on the inside of the curve when it creates an infinitesimally small loop.

note: this spike is also on the outside of the loop if lineJoin(MITER) but this is expected.

@Amber Welcome to the forum. Itâ€™s good to have more users finding things wrong in the new version so they can be corrected.

1 Like

Thought Iâ€™d try the bezier function. I was able to get the spike inside and outside just using the bezier function, no lineJoin. Not sure what lineJoin does.

Hmmm, interesting. This is probably due to some kind of precision issue / singularity with this specific edge case. What does the code look like for this?

@John Hereâ€™s the code I used for mine. Just touch a circle to move it.

```
viewer.mode=FULLSCREEN
function setup()
tab={100,100,100,200,200,100,200,200}
end
function draw()
background(0)
style.noFill()
style.stroke(255)
style.strokeWidth(4)
bezier(tab[1],tab[2],tab[3],tab[4],tab[5],tab[6],tab[7],tab[8])
for z=1,8,2 do
ellipse(tab[z],tab[z+1],20)
end
end
function touched(t)
for z=1,8,2 do
if t.x>tab[z]-20 and t.x<tab[z]+20 and t.y>tab[z+1]-20 and t.y<tab[z+1]+20 then
tab[z]=t.x
tab[z+1]=t.y
end
end
end
```

1 Like

my code is similar, just more complicated hahah

lineJoin() is a new style setting that sets how polylines corners look.

it seems MITER is the default setting for it.

1 Like

It would be nice to have a version that compute instead of just drawing it. It will allow us to make something follow the path.

I did something that do it by compute and cache the segments (like Godot).

Path.zip (2.3 KB)

While weâ€™re on the subject of bezier, I just put this together. It draws a BĂ©zier curve using any number of points that you want to enter in the tables px and py. Tap on a point to move it. If you want the point values that make up the curve, theyâ€™re in the table tab. This is for the Legacy 3.x code.

PS. I modified the code to calculate 12 pairs of random points. You get a different curve each time itâ€™s run. You can change the 12 in the for loop to whatever number you want to try.

```
viewer.mode=FULLSCREEN
function setup()
px,py={},{}
for z=1,12 do
table.insert(px,math.random(WIDTH))
table.insert(py,math.random(HEIGHT))
end
step=.01
n=#px-1
bez()
end
function bez()
tab={}
for r=0,1,step do
pX,pY=0,0
for i=0,n do
pX=pX+calc1(n,i,px[i+1],r)
pY=pY+calc1(n,i,py[i+1],r)
end
table.insert(tab,vec2(pX,pY))
end
table.insert(tab,vec2(px[#px],py[#py]))
end
function draw()
background(31, 59, 60)
stroke(255)
strokeWidth(4)
fill(255)
for z=2,#tab do
line(tab[z-1].x,tab[z-1].y,tab[z].x,tab[z].y)
end
stroke(0,255,0)
fill(0,255,0)
for z=2,#px-1 do
ellipse(px[z],py[z],15)
end
stroke(0,0,255)
fill(0,0,255)
ellipse(px[1],py[1],15)
ellipse(px[#px],py[#py],15)
stroke(255,0,0)
strokeWidth(1)
for z=2,#px do
line(px[z-1],py[z-1],px[z],py[z])
end
end
function calc1(n,i,p,t)
return(fac(n)/(fac(i)*fac(n-i))*(1-t)^(n-i)*t^i*p)
end
function fac(n)
return n > 0 and n * fac(n-1) or 1
end
function touched(t)
if t.state==BEGAN then
offset=0
for z=1,#px do
if math.abs(t.x-px[z])<30 and math.abs(t.y-py[z])<30 then
offset=z
end
end
elseif t.state==CHANGED then
px[offset]=t.x
py[offset]=t.y
bez()
end
end
```

Hereâ€™s my bĂ©zier code (for Codea 3) which includes evaluation routines (and tangent, and splitting, amongst others). It uses a mesh to render the curve, which provides for a smoother render than line segments.

(Incidentally, @dave1707, there are much more efficient ways to compute the coefficients of Pascalâ€™s triangle than using factorials)

@LoopSpace Thanks. When I wrote the code, I didnâ€™t realize that part was calculating the coefficients of Pascalâ€™s triangle. I was just using a Bezier formula I found on the internet and converted it to run in Codea. I originally wrote code long ago that used 4 points for the BĂ©zier curve, but I wanted to use a varying number of points.

I found this site that gave a formula and explained it a little.

https://www.freecodecamp.org/news/nerding-out-with-bezier-curves-6e3c0bc48e2f/

Apart from the initial bit about â€śmath anxietyâ€ť, thatâ€™s actually not a bad article.

@sim Looks like an interesting video. Watched a few minutes. Will watch more of it when I have time.

1 Like

A slightly different approach using Catmull-Rom splines so that the curve passes through known control points. You can move the control points and then save the required path data for use in other programs.

Spline.zip (2.5 KB)

2 Likes

Thereâ€™s also a nice algorithm due to someone called John Hobby (who worked with Don Knuth on font design, I believe) that produces a sequence of cubic bĂ©zier curves passing through a sequence of points that is designed to be â€śniceâ€ť at the joins. Thereâ€™s an implementation of it in my bĂ©zier code (core function starts on line 371). I also modified it to something I call a â€śQuick Hobbyâ€ť algorithm which is also in that library.

2 Likes