I have a polyline (white) with coordinates {x1, y1, x2, y2, x3, y3 ...}
polyline = {100,300,160,257,220,242,280,250,340,271,400,300,460,329,520,350,580,358,640,343,700,300}
How can I get the curvature of it? The result must be same as the curvature of Bezier (red curve on the calculated heights):
I can understand, that the ends of polyline must have the zero curvature.
The result must be something like:
Here was the solution: Determining curvature of polylines
-- function to calculate the curvature of a polyline segment using three points
local function calculatePolylineCurvature(p1x, p1y, p2x, p2y, p3x, p3y)
-- https://gis.stackexchange.com/questions/195370/determining-curvature-of-polylines
-- compute the determinant (signed area of the triangle)
local numerator = 2 * ((p2x - p1x) * (p3y - p2y) - (p2y - p1y) * (p3x - p2x))
-- compute the product of the three segment lengths
local len1 = (p2x - p1x)^2 + (p2y - p1y)^2
local len2 = (p3x - p2x)^2 + (p3y - p2y)^2
local len3 = (p1x - p3x)^2 + (p1y - p3y)^2
local denominator = math.sqrt(len1 * len2 * len3)
-- prevent division by zero
if denominator == 0 then
return nil
end
return -8.1*numerator / denominator -- just to set the same scale as Bezier curvature
end
-- function to calculate the normal vector to the polyline segment
local function calculatePolylineNormal(p1x, p1y, p2x, p2y, p3x, p3y)
return p1y - p3y, p3x - p1x
end
The main function:
polyline = {100,300,160,257,220,242,280,250,340,271,400,300,460,329,520,350,580,358,640,343,700,300}
local length = 20
polylineCurvatureLines = {}
polylineCurvatureHeightLine = {}
table.insert (polylineCurvatureHeightLine, polyline[1])
table.insert (polylineCurvatureHeightLine, polyline[2])
for i = 3, #polyline - 3, 2 do
local p1x, p1y = polyline[i-2], polyline[i-1]
local p2x, p2y = polyline[i], polyline[i+1]
local p3x, p3y = polyline[i+2], polyline[i+3]
local k = calculatePolylineCurvature(p1x, p1y, p2x, p2y, p3x, p3y)
local nx, ny = calculatePolylineNormal (p1x, p1y, p2x, p2y, p3x, p3y)
nx = nx * k * length
ny = ny * k * length
table.insert (polylineCurvatureLines, {p2x, p2y, p2x + nx, p2y + ny})
table.insert (polylineCurvatureHeightLine, p2x + nx)
table.insert (polylineCurvatureHeightLine, p2y + ny)
end
table.insert (polylineCurvatureHeightLine, polyline[#polyline-1])
table.insert (polylineCurvatureHeightLine, polyline[#polyline])
The result:
Update:
It has a mistake! The curvature will be lower for more curve divisions!
factor = 20 for 40 crossings
factor = 40 for 80 crossings