#Circles
1 messages · Page 1 of 1 (latest)
@surreal mural this fails in negative direction for some reason
{
var dir = line.c1 - line.c0;
var centerToOrigin = line.c0 - circle.xy;
var radiusSq = circle.z * circle.z;
if (math.lengthsq(math.cross(new float3(dir, 0), new float3(centerToOrigin, 0))) > radiusSq) return false;
var a = math.dot(dir, dir);
var b = 2 * math.dot(dir, centerToOrigin);
var c = math.dot(centerToOrigin, centerToOrigin) - radiusSq;
var discriminant = b * b - 4 * a * c;
return !(discriminant < 0);
}
(ignore the ! instead of >= thats just rider auto cleaning it up)
so according to this image, all you need is to find distance between point and a line segment, that is it
need to check where exactly it fails
nope never mind it fails in positive as well
basically it works on some segments but not others
segments around top left fail, segments on bottom right are fine
this one?
yes
this from enzi and slightly modified is working as expected
public static bool SegmentCircle(float2 p1, float2 p2, float2 center, float radius)
{
if (IsPointInsideCircle(p1, center, radius) ||
IsPointInsideCircle(p2, center, radius))
{
return true;
}
p1 -= center;
p2 -= center;
var a = math.lengthsq(p2 - p1);
var b = 2 * (math.dot(p1.x, p2.x - p1.x) + math.dot(p1.y, p2.y - p1.y));
var c = math.lengthsq(p1.x) + math.lengthsq(p1.y) - math.lengthsq(radius);
var disc = math.lengthsq(b) - (4 * a * c);
if (disc <= 0)
{
return false;
}
// var sqrtDisc = math.sqrt(disc);
// var t1 = (-b + sqrtDisc) / (2 * a);
// var t2 = (-b - sqrtDisc) / (2 * a);
var t1 = (-b + (disc / b)) / (2 * a);
var t2 = (-b - (disc / b)) / (2 * a);
return t1 is > 0 and < 1 || t2 is > 0 and < 1;
}```
let's try to reduce it
would be cool if this can get even more optimized. i already got rid of the sqrt because the pointInsideCircle check catches where it would fail
if burst can't handle it automatically (i suspect not) i'm going to redo it with 2x float4
public static bool SegmentCircle(float2 p1, float2 p2, float2 center, float radius)
{
var dir = p2 - p1;
var toCenter = center - p1;
var r2 = radius * radius;
var projectedPoint = p1 + math.dot(toCenter, dir) * math.normalize(dir);
var distanceToProjectionSq = math.distancesq(projectedPoint, center);
return r2 <= distanceToProjectionSq;
}
same issue
do you not have a test setup? ^^
circle center, radius 10
collection of failing segments clearly further than 10 away
it returns true no matter where i put the line or circle
now it's false everytime ^^
this code only works when p1 is inside the circle. had to normalize math.dot(toCenter, dir) toCenter and dir though, otherwise it's pointing to the end of the map
yeah, I see where it comes from, it projects point on the ray as well
Get closest point on line segment, compare to radius?
/// Find for a given point the closest point on a line segments
/// </summary>
public static float2 GetClosestPointOnLineSegment(float2 pointA, float2 pointB, float2 P)
{
float2 AP = P - pointA; //Vector from A to P
float2 edgeA = pointB - pointA; //Vector from A to B
float dot = math.dot(edgeA, AP);
float edgeLengthSquared = math.lengthsq(edgeA);
dot = math.max(dot, 0.0f); //Check if P projection is over vectorAB
dot = math.min(dot, edgeLengthSquared); //Check if P projection is over vectorAB
float invEdgeLengthSquared = 1.0f / edgeLengthSquared;
float frac = dot * invEdgeLengthSquared; //The normalized "distance" from a to your closest point
return pointA + edgeA * frac;
}```
the use it like float2 closestAB = GetClosestPointOnLineSegment(A, B, circleCenter); return math.distance(closestAB, circleCenter) < radius
so basically need to clamp math.dot(toCenter, dir) from 0 to dir length squared
it was close, nice catch @swift plover 😄
public static bool SegmentCircle(float2 p1, float2 p2, float2 center, float radius)
{
var dir = p2 - p1;
var toCenter = center - p1;
var r2 = radius * radius;
var dot = math.dot(toCenter, dir);
var lenSq = math.dot(dir, dir);
var projectedPoint = p1 + math.clamp(dot, 0, lenSq) / lenSq * dir;
var distanceToProjectionSq = math.distancesq(projectedPoint, center);
return r2 >= distanceToProjectionSq;
}
this works nicely
beautiful math 😄
now just vectorize it and get some free juice 😄
yep
7 hours of circles discussion
but successful!
I mean it was almost solved right there #1064581837055348857 message
determinant + b and determinant - b represent a fraction of the line segment that lead to the projection point. for some reason I wasn't able to wrap my head around clamping it at that moment, happens sometimes 😅
I see I missed the fun