1

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):

curve and bezier curvature

I can understand, that the ends of polyline must have the zero curvature.

The result must be something like:

curve and bezier curvature and polyline curvature

1 Answer 1

1

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:

good polyline curvature

Update:

It has a mistake! The curvature will be lower for more curve divisions!

  • factor = 20 for 40 crossings

    factor = 40 for 80 crossings

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.