Trace a curve which pass through all of the points.
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Trace a curve which pass through all of the points.
Hi ! I'm currently coding a game where the player swing using a rope, using love.physics as the physics engine, the rope is made with rectangles jointed together thanks to RevoluteJoint , to render the rope graphically, I wanted to use Bezier Curved, to have a smooth rope , instead of rectangles, so I give all the anchor points to the bezier curve and render it, but I noticed that it doesn't use all the points, it takes some shortcut.
Re: Trace a curve which pass through all of the points.
That's how bezier curves work, yes. It doesn't look far off to me so you can just keep it that way.
Re: Trace a curve which pass through all of the points.
Whatever my girlfriend's svg editing software used for it's curves ( which it did call bezier) does pass through all the points, so I was also surprised by this.
I spent some time looking for this, and I didn't find anything. I think you'll need to come up with it yourself. I was thinking of doing it myself but haven't gotten around to it and probably won't for a while.
I expect it'd be some pretty tough math though, and if it's just for rendering then raidho is right  it still looks pretty good.
I spent some time looking for this, and I didn't find anything. I think you'll need to come up with it yourself. I was thinking of doing it myself but haven't gotten around to it and probably won't for a while.
I expect it'd be some pretty tough math though, and if it's just for rendering then raidho is right  it still looks pretty good.
Re: Trace a curve which pass through all of the points.
The problem is, it can sometime pass through walls because of that.
Last edited by Pordrack on Sat Jul 20, 2019 11:04 am, edited 2 times in total.
Re: Trace a curve which pass through all of the points.
Use CatmullRom instead of Bezier splines.
Re: Trace a curve which pass through all of the points.
You can try using centers of bodies as end points and joints as control points.
Re: Trace a curve which pass through all of the points.
I did that, and yes, it's better, not perfect, but good enough for me.
Re: Trace a curve which pass through all of the points.
Not sure if this is any use, but a while back i was trying to understand the use of moving an object along a bezier curve (typically a rocket/missile), this example that someone fixed for me may be useful in plotting the points along the curve:
https://love2d.org/forums/viewtopic.php ... 10#p211910
May be some other relevant info in that thread also.
https://love2d.org/forums/viewtopic.php ... 10#p211910
May be some other relevant info in that thread also.
Re: Trace a curve which pass through all of the points.
One method to do what the OP wants with LÖVE is the KochanekBartels method. It works by drawing one Hermite curve between each pair of points.
While the method generates Hermite curves, these can easily be converted to Bézier for them to be drawn with LÖVE. You can adjust tension to the desired value, and leave continuity and bias set to 0. In my experience, a bit of negative tension works better than zero tension (which would produce a CatmullRom spline).
To convert a start Hermite vector to the first control point of a cubic Bézier, divide it by 3 and add the start point. To convert an end Hermite vector to the second point of a cubic Bézier, divide it by 3 and add the end point.
For example, if the Hermite curve is given by start and end points p0 and p1, and tangents d0 and d1, the corresponding Bézier control points P0, P1, P2, P3 (where P0 and P3 are the starting and ending point, and P1 and P2 are the control points) are:
P0 = p0
P1 = p0 + d0 / 3
P2 = p1  d1 / 3
P3 = p1
Edit: Sorry, I previously said "multiply by 3". I misremembered, it should have been "divide by 3".
Edit 2: Simple example follows:
Snapshot:
While the method generates Hermite curves, these can easily be converted to Bézier for them to be drawn with LÖVE. You can adjust tension to the desired value, and leave continuity and bias set to 0. In my experience, a bit of negative tension works better than zero tension (which would produce a CatmullRom spline).
To convert a start Hermite vector to the first control point of a cubic Bézier, divide it by 3 and add the start point. To convert an end Hermite vector to the second point of a cubic Bézier, divide it by 3 and add the end point.
For example, if the Hermite curve is given by start and end points p0 and p1, and tangents d0 and d1, the corresponding Bézier control points P0, P1, P2, P3 (where P0 and P3 are the starting and ending point, and P1 and P2 are the control points) are:
P0 = p0
P1 = p0 + d0 / 3
P2 = p1  d1 / 3
P3 = p1
Edit: Sorry, I previously said "multiply by 3". I misremembered, it should have been "divide by 3".
Edit 2: Simple example follows:
Code: Select all
local bez = love.math.newBezierCurve(0,0, 0,0, 0,0, 0,0)
local function Kochanek_Bartels(t, c, b,
p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y)
local P0x = p1x
local P0y = p1y
local P1x = p1x + ( (1t)*(1+b)*(1+c) * (p1x  p0x)
+ (1t)*(1b)*(1c) * (p2x  p1x) ) / 6
local P1y = p1y + ( (1t)*(1+b)*(1+c) * (p1y  p0y)
+ (1t)*(1b)*(1c) * (p2y  p1y) ) / 6
local P2x = p2x  ( (1t)*(1+b)*(1c) * (p2x  p1x)
+ (1t)*(1b)*(1+c) * (p3x  p2x) ) / 6
local P2y = p2y  ( (1t)*(1+b)*(1c) * (p2y  p1y)
+ (1t)*(1b)*(1+c) * (p3y  p2y) ) / 6
local P3x = p2x
local P3y = p2y
bez:setControlPoint(1, P0x, P0y)
bez:setControlPoint(2, P1x, P1y)
bez:setControlPoint(3, P2x, P2y)
bez:setControlPoint(4, P3x, P3y)
love.graphics.line(bez:render())
end
local points = {0, 0, 200, 0, 200, 150, 250, 120, 300, 250}
local tension = 0.6
local continuity = 0
local bias = 0
function love.draw()
love.graphics.translate(love.graphics.getWidth()/2, love.graphics.getHeight()/2)
 Draw dots
love.graphics.setColor(1, 1, 1, 1)
for i = 1, #points, 2 do
love.graphics.circle("fill", points[i], points[i + 1], 5)
end
love.graphics.setColor(0, 0.3, 1, 1)
local len = #points
local npoints = len / 2
if npoints >= 3 then
 do first segment by repeating first point
Kochanek_Bartels(tension, continuity, bias,
points[1], points[2], points[1], points[2],
points[3], points[4], points[5], points[6])
 do middle segments
for i = 2, npoints  2 do
local base = i * 2  1
Kochanek_Bartels(tension, continuity, bias,
points[base  2], points[base  1],
points[base], points[base + 1],
points[base + 2], points[base + 3],
points[base + 4], points[base + 5])
end
 do last segment by repeating last point
Kochanek_Bartels(tension, continuity, bias,
points[len  5], points[len  4], points[len  3], points[len  2],
points[len  1], points[len], points[len  1], points[len])
elseif npoints == 2 then
 just draw a line between the points
love.graphics.line(points)
end
end
function love.keypressed(k) return k == "escape" and love.event.quit() end
 Attachments

 KochanekBartels.png (12.06 KiB) Viewed 2123 times
Who is online
Users browsing this forum: No registered users and 37 guests