Subv's picture

Vector comparison

Project:The Open Toolkit library
Version:1.0.0-rc1
Component:Code
Category:support request
Priority:normal
Assigned:Unassigned
Status:open
Description

Hello,
I just recently started with OpenTK and 3D graphics in general, so I tried a simple program that interpolates a 2D vector from a vector v1 to a vector v2, as I understand, this is given by the equation V = (1 - t)V1 + tV2 where t is in the range [0, 1], that means that I have stop to the interpolation when t = 1 (V = V2).

My code is as follows

public class Game : GameWindow
    {
        int i = 0;
        float t = 0;
        Vector2 lin = Vector2.Zero;
// ... Some other methods
 
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            Matrix4 modelview = Matrix4.LookAt(new Vector3(0, 0, 5), new Vector3(1, 1, 0), Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref modelview);
 
            Vector2 v1 = new Vector2(1, 1);
            v1.Normalize();
            Vector2 v2 = new Vector2(1, 0);
            // Some draw code of the v1 and v2 vectors
 
            GL.Begin(BeginMode.Lines);
            GL.Color3(Color.Red);
            GL.Vertex2(Vector2.Zero);
            GL.Vertex2(lin);
// I only recalculate this vector once every 10 redraws, to simulate a "smooth" animation
            if (lin != v2 && (i % 10) == 0)
            {
                lin = ((1 - t) * v1 + t * v2);
                if (lin != Vector2.Zero)
                    lin.Normalize();
                t += 0.05f;
            }
            ++i;
            GL.End();
            SwapBuffers();
        }
    }

The problem is that the as t increases, the coordinates of lin (V) are not exact representations of their V1/V2 counterparts, so the lin != v2 condition fails when t = 1 because (values taken from the debugger) lin.X = V2.X = 1 and V2.Y = 0 but lin.Y = ~0.00000000004 (note the precision loss).
Taking a deeper look into the code, I found that the method used to compare Vector2 structures is

/// <summary>Indicates whether the current vector is equal to another vector.</summary>
        /// <param name="other">A vector to compare with this vector.</param>
        /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
        public bool Equals(Vector2 other)
        {
            return
                X == other.X &&
                Y == other.Y;
        }

Where X and Y are both floats, this is not a safe way of comparing floats and may cause unexpected behavior (As seen in the above example), is there any reason why an Epsilon wasn't used? Is this behavior intended?

Once again, I'm pretty new to OpenTK and 3D graphics in general (Just started 2 days ago), and any insight is greatly appreciated.

Thanks,
Subv


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
nythrix's picture

#1

Don't do that. Assuming t runs between [0 1] check that instead (using "<" and ">" only).

I'm afraid there's no "magically safe" float comparison mostly because what you see is NOT what you get.