3

What I am trying to do get the X coordinates at which a certain bezier curve crosses a horizontal line (a y coordinate). For the moment, I have this code:

function self.getX(y)
    if y > maxY or y < minY then
        return
    end
    local a = y1 - y
    if a == 0 then
        return
    end
    local b = 2*(y2 - y1)
    local c = (y3 - 2*y2 + y1)

    local discriminant = (b^2 - 4*a*c )

    if discriminant < 0 then
        return
    else
        local aByTwo = 2*a
        if discriminant == 0 then
            local index1 = -b/aByTwo
            if 0 < index1 and index1 < 1 then
                return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
            end
        else
            local theSQRT = math.sqrt(discriminant)
            local index1, index2 = (-b -theSQRT)/aByTwo, (-b +theSQRT)/aByTwo
            if 0 < index1 and index1 < 1 then
                if 0 < index2 and index2 < 1 then
                    return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3, (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
                else
                    return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
                end
            elseif 0 < index2 and index2 < 1 then
                return (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
            end
        end
    end     
end

A few specifications:

  • This is Lua code.
  • local means the variable is local to the chunk of code, so it does not affect the code's functionality.
  • y1, y2, and y3 are the y coordinate of the 3 points. The same applies to x1, x2, x3.
  • y is the y coordinate of the horizontal line I am computing.
  • maxY is the biggest of the 3 y's.
  • minY is the smallest.

For the moment this code gives me this:

enter image description here

  • There are 8 bezier curves
  • The green ones are generated using the normal method: (1-t)^2*x1+2*(1-t)*t*x2+t^2*x3
  • The red dots are the control points.
  • The white lines are what is generated using the method described with the code above.
  • The straight lines are lines, ignore them.
  • There should be 8 curves, but only 4 are rendered.

Thanks in advance,

Creator!

Creator
  • 151
  • 1
  • 9
  • How comes no o e has responded? Is something wrong with the post? – Creator Jan 17 '16 at 00:07
  • Nope, since it would then return the same result for any y. – Creator Jan 17 '16 at 00:18
  • 4
    The Bézier has `y(t)=(1-t)^2*y1+2(1-t)*t*y2+t^2*y3`, which expands to `(y1-2 *y2+y3)*t^2+2(y2-y1)*t+y1`. So you seem to have swapped `a` and `c`. – lhf Jan 17 '16 at 00:21
  • The first expression is equal to y, which is then moved inside to make it = 0 – Creator Jan 17 '16 at 00:23
  • Rather than the picture, can you give a specific set of input values (x1, x2, x3, y1, y2, y3, x) that result in an incorrect answer? That way somebody could actually step through the code and try to see where it goes wrong. (Have you done that yet?) – Nate Eldredge Jan 17 '16 at 00:23
  • I iterate from 0 to 600, which is the input to the function. – Creator Jan 17 '16 at 00:24
  • Can you post a **complete** example, including the code that calls this function, that somebody could actually run? – Nate Eldredge Jan 17 '16 at 00:25
  • OK, I'll do it tomorrow since it is 2 am here. Gnight. – Creator Jan 17 '16 at 00:25
  • 3
    (Also, regarding "how come no one has responded": keep in mind Stack Overflow is not your personal support hotline. You posted a fairly complex chunk of code that would take a person some time to read through. Any time that people spend here is time they could instead be earning money and/or doing something else they enjoy. It would be more respectful to have some patience.) – Nate Eldredge Jan 17 '16 at 00:28
  • OK, sorry. I assumed there a quite a lot of people here since the site is popular. – Creator Jan 17 '16 at 07:40
  • 1
    @lhf has the solution: You have mixed up the quadratic and constant terms in your quadratic equation. Swap the values for `a` and `c` and you should get good results. – M Oehm Jan 17 '16 at 08:17
  • Thanks, solved my problem. If you want an upvote post it as answer and I'll mark it too. – Creator Jan 17 '16 at 09:55

1 Answers1

2

The Bézier curve has

y(t)=(1-t)^2*y1+2(1-t)*t*y2+t^2*y

which expands to

(y1-2*y2+y3)*t^2+2(y2-y1)*t+y1

You have swapped a and c in the quadratic equation a*t^2+b*t+c=0 required for solving y(t)=y.

lhf
  • 70,581
  • 9
  • 108
  • 149