Created
March 28, 2023 18:30
-
-
Save juj/0623fc6fe4bc0aeb04b4ad551c11aefd to your computer and use it in GitHub Desktop.
Rough sketch of sphere vs arc sector intersection test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Sphere | |
{ | |
float2 pos; | |
float radius; | |
}; | |
struct ArcSector | |
{ | |
float2 pos; | |
float radius; | |
float2 dir; // center line direction from pos towards dir vector, normalized. | |
float angle; // radians, assume symmetricly spreading out angle +/- away from direction vector. | |
} | |
bool sphere_sphere_intersect(Sphere s1, Sphere s2); // exercise for reader | |
// Intersects a sphere with a half-plane that passes through the origin. | |
bool sphere_intersects_halfplane(Sphere s, float planeNormal) | |
{ | |
return dot2(s.pos, planeNormal.xy) - s.radius <= 0; | |
} | |
void intersect_sphere_arc(Sphere s, ArcSector a) | |
{ | |
if (!sphere_sphere_intersect(s, Sphere(a.pos, a.radius))) return false; | |
Sphere sphereLocal(s.pos - a.pos, s.radius); | |
float dirAngle = atan2(a.dir.y, a.dir.x); | |
float2 edge1 = float2(cos(dirAngle+angle), sin(dirAngle+a.angle)); | |
float2 edge2 = float2(cos(dirAngle-angle), sin(dirAngle-a.angle)); | |
float2 normal1 = float2(-edge1.y, edge1.x); // rotate 90 deg CCW | |
float2 normal2 = float2(edge2.y, -edge1.x); // rotate 90 deg CW | |
if (a.angle <= pi/2) // convex arc sector | |
{ | |
if (!sphere_intersects_halfplane(sphereLocal, normal1)) return false; | |
if (!sphere_intersects_halfplane(sphereLocal, normal2)) return false; | |
} | |
else if (!sphere_intersects_halfplane(sphereLocal, normal1) // concave arc sector | |
&& !sphere_intersects_halfplane(sphereLocal, normal2)) return false; | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment