How to find the intersection between a line and a mathematical function?

Asked

Viewed 116 times

5

I have a problem where I need to find the intersection of two mathematical functions. I have the formula of the first function and two coordinates, where ab and cd are my points. To pass these coordinates to a function, I use the line equation by two points, and this is my problem.

The first function is represented by f(x) = |x| - cos(3x), who create this drawing:

inserir a descrição da imagem aqui

Since the formula is already ready, I wrote it in C# with:

static Vector2 CossineFormula(int x)
{
     double y = Math.Sqrt(Math.Pow(Math.Abs(x), 2)) - Math.Cos(x * 3);
     return new Vector2(x, y);
}

So far, so good. Now, I have two points that I mentioned, and I can’t go on with the two-point line equation because I can’t define a function dynamically, or at least I can’t find how.

The intersection is given by the continuation of the points ab and cd until you create the interception Ef:

inserir a descrição da imagem aqui

I can’t find that intersection because I can’t pass the two points to mathematical function.

I tried to use the formula of the ramp (Slope) as it is in the above mentioned tutorial, but I stopped in this part (in the tutorial is Step 2):

static Vector2 CossineIntersection(Vector2 a, Vector2 b)
{
    double distance = Math.Sqrt(Math.Pow(b.X - a.X, 2) + Math.Pow(b.Y - a.Y, 2));
    double slope = (b.Y - a.Y) / (b.X - a.X);
    double intercept = (2 * slope); // onde continuo com b?
}

Slope was calculated, but at this stage:

Substitute the Slope for’m' in the Slope Intercept form of the Equation y = mx + b

I went to y = (2 * slope) but I didn’t have to continue b.

I also asked about how to find this intersection in Mathematics.

All the ways of doing intersection, I can’t perform in programming. I know it’s possible, but I can’t find anywhere anything like.

Note: is not an intersection between two lines, but between a line and a function.

1 answer

5


You can use the bisection method. You’re basically trying to find the root of this equation:

y = |x| - cos(3x) - (mx + b)

The root of this equation is where its two lines meet.

Like Vector2 works with floats, so let’s treat all the numbers as floats.

First, the linear function:

static float LinearFormula(float x, Vector2 a, Vector2 b)
{
     float slope = (b.Y - a.Y) / (b.X - a.X);
     float dx = x - a.X;
     float dy = slope * dx; 
     return dy + a.Y;
}

Its function with cosine:

static float CossineFormula(float x)
{
     return Math.Abs(x) - (float) Math.Cos(x * 3);
}

Note that I simplified the Math.Sqrt(Math.Pow(Math.Abs(x), 2)) for Math.Abs(x). There is no reason to square just to take out the square root later, even more that you are already applying the Abs.

Its function:

static float MyFormula(float x, Vector2 a, Vector2 b)
{
     return CossineFormula(x) - LinearFormula(x, a, b);
}

And then we look for the root for consecutive bisections:

static Vector2 FindIntersection(Vector2 a, Vector2 b)
{
    float x1 = 2;
    float x2 = 3;

    for (int i = 0; i < 100; i++)
    {
        float d = (x2 + x1) / 2;
        if (d == x1 || d == x2) break;
        float v3 = MyFormula(d, a, b);
        if (v3 > 0)
        {
            x2 = d;
        }
        else
        {
            x1 = d;
        }
    }
    return new Vector2(x1, CossineFormula(x1));
}

In this function, 2 and 3 are the initial values of the interval where we will look for the root of the function. The choice of these values is arbitrary, but I did it knowing that (a) for 2 we have a negative value, (b) for 3 a positive and (c) in this interval there is only one single root for the function. Therefore, by dividing this interval into smaller and smaller parts, we can find where the root is.

The for should rotate the number of times enough to find the root, and could even be a while (true). But I put a counter to limit the number of iterations, in case something goes wrong.

Finally, to test:

public static void Main()
{
    Console.WriteLine(FindIntersection(new Vector2(0, 4), new Vector2(1, 3)));
}

The result is this:

<2.354912, 1.645088>

See here working on ideone.

  • Thanks for your help. I tested your code using the dots 0, 4 and 1, 3 and the intersection gave X = 3,033 and Y = 3.051. In this function calculator, these same points give an intersection of approximately X = 2.35 and Y = 1.66. What is wrong?

  • @Cypherpotato Fixed. Sorry I had made a mess initially.

  • Victor, I think you got confused in the condition to define bisection. Do not just check the sign of d, which is the midpoint, but rather compares it to the values of v1 and v2 current. In this example, you updated v1 when d > 0. This would work if the curve were increasing, but it is decreasing. If d > 0 you will need to update the point that is also positive, be it v1 or v2.

  • 1

    Considering the above comment, I think it only worked by "luck" because the curve is decreasing and you update v2 when v3 > 0. This same condition will not work if the curve is increasing (or I’m wrong?).

  • 1

    @Andersoncarloswoss It is based on the fact that the x1 always produces a v1 negative and that the x2 always produces a v2 positive. This is not something very general, but to make it into something more general, I would also have to embrace the choice of x1 and of x2 initial and parameterize the function to be bisected, which would leave a little more complicated than the author of the question needs.

  • Ah, truth, there’s this premise xD I was already thinking of something for when it was v1 positive and v2 negative also haha

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.