dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.28k stars 4.74k forks source link

[API Proposal]: Vector2.PerpDot #80739

Open PavielKraskouski opened 1 year ago

PavielKraskouski commented 1 year ago

Background and motivation

The Perp Dot Product can be used to check the winding order of triangle vertices, check if a point is inside a triangle, calculate barycentric coordinates of a point inside a triangle, triangulate polygons by ear clipping method, etc.

API Proposal

namespace System.Numerics;

public struct Vector2
{
    public static float PerpDot(Vector2 value1, Vector2 value2)
    {
        return value1.X * value2.Y - value1.Y * value2.X;
    }
}

Alternative design:

namespace System.Numerics;

public struct Vector2
{
    public static float PerpDot(Vector2 value1, Vector2 value2)
    {
        return Dot(new Vector2(-value1.Y, value1.X), value2);
    }
}

API Usage

using System.Numerics;

public bool ClockwiseTriangle(Vector2 a, Vector2 b, Vector2 c)
{
    return Vector2.PerpDot(b - a, c - a) < 0;
}

public bool PointInTriangle(Vector2 p, Vector2 a, Vector2 b, Vector2 c)
{
    float u = Vector2.PerpDot(b - p, c - p);
    float v = Vector2.PerpDot(c - p, a - p);
    float w = Vector2.PerpDot(a - p, b - p);
    return (u >= 0 && v >= 0 && w >= 0) ||
           (u <= 0 && v <= 0 && w <= 0);
}

public (float, float, float) Barycentric(Vector2 p, Vector2 a, Vector2 b, Vector2 c)
{
    float denom = 1f / PerpDot(b - a, c - a);
    float u = Vector2.PerpDot(b - p, c - p) * denom;
    float v = Vector2.PerpDot(c - p, a - p) * denom;
    return (u, v, 1 - u - v);
}

Alternative Designs

No response

Risks

No response

ghost commented 1 year ago

Tagging subscribers to this area: @dotnet/area-system-numerics See info in area-owners.md if you want to be subscribed.

Issue Details
### Background and motivation The [Perp Dot Product](https://mathworld.wolfram.com/PerpDotProduct.html) can be used to check the winding order of triangle vertices, check if a point is inside a triangle, calculate [barycentric coordinates](https://en.wikipedia.org/wiki/Barycentric_coordinate_system) of a point inside a triangle, triangulate polygons by [ear clipping method](https://en.wikipedia.org/wiki/Polygon_triangulation#Ear_clipping_method), etc. ### API Proposal ```csharp namespace System.Numerics; public struct Vector2 { public static float PerpDot(Vector2 value1, Vector2 value2) { return value1.X * value2.Y - value1.Y * value2.X; } } ``` Alternative design: ```csharp namespace System.Numerics; public struct Vector2 { public static float PerpDot(Vector2 value1, Vector2 value2) { return Dot(new Vector2(-value1.Y, value1.X), value2); } } ``` ### API Usage ```csharp using System.Numerics; public bool ClockwiseTriangle(Vector2 a, Vector2 b, Vector2 c) { return Vector2.PerpDot(b - a, c - a) < 0; } public bool PointInTriangle(Vector2 p, Vector2 a, Vector2 b, Vector2 c) { float u = Vector2.PerpDot(b - p, c - p); float v = Vector2.PerpDot(c - p, a - p); return (u >= 0 && v >= 0 && u + v <= 1) || (u <= 0 && v <= 0 && u + v >= -1); } public (float, float, float) Barycentric(Vector2 p, Vector2 a, Vector2 b, Vector2 c) { float denom = 1f / PerpDot(b - a, c - a); float u = Vector2.PerpDot(b - p, c - p) * denom; float v = Vector2.PerpDot(c - p, a - p) * denom; return (u, v, 1 - u - v); } ``` ### Alternative Designs _No response_ ### Risks _No response_
Author: PavielKraskouski
Assignees: -
Labels: `api-suggestion`, `area-System.Numerics`
Milestone: -