Files
2025-05-13 01:04:37 +03:00

83 lines
2.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static OpticalSurface2D;
public class RaycastMath
{
public struct RaycastResult2D {
public Vector2 Point;
public Vector2 Normal;
}
public static bool RaycastCircle(Ray2D ray, float radius, ref RaycastResult2D result) {
var vToCircleCenter = Vector2.zero - ray.origin;
bool isInsideCircle = vToCircleCenter.magnitude < radius;
var d = Vector2.Dot(vToCircleCenter, ray.direction.normalized);
if(d < 0 && ray.origin.magnitude > radius) {
return false;
}
var p = ray.origin + ray.direction.normalized * d;
var v = Vector2.zero - p;
var rayCenterDistance = v.magnitude;
if (rayCenterDistance > radius) {
return false;
} else if (rayCenterDistance == radius) {
result.Point = p;
result.Normal = p.normalized;
} else {
float m = Mathf.Sqrt(radius * radius - rayCenterDistance * rayCenterDistance);
if (isInsideCircle) {
result.Point = p + ray.direction.normalized * m;
result.Normal = result.Point.normalized;
} else {
result.Point = p - ray.direction.normalized * m;
result.Normal = result.Point.normalized;
}
}
return true;
}
public static bool RayLineIntersection(Vector2 rayOrigin, Vector2 rayDirection, Vector2 lineOrigin, Vector2 lineDirection, ref Vector2 hitPoint) {
Vector2 rayTangent = new Vector2(-rayDirection.y, rayDirection.x);
float distanceToLine = Vector2.Dot(lineOrigin - rayOrigin, rayTangent);
float origin2ExtensionDistance = distanceToLine / Vector2.Dot(-rayTangent, lineDirection);
hitPoint = origin2ExtensionDistance * lineDirection + lineOrigin;
return Vector2.Dot(hitPoint - rayOrigin, rayDirection) > 0.0f;
}
public static bool RayLineSegmentIntersection(Vector2 rayOrigin, Vector2 rayDirection, Vector2 lineOrigin, Vector2 lineP2, ref Vector2 hitPoint) {
Vector2 rayTangent = new Vector2(-rayDirection.y, rayDirection.x);
Vector2 lineDirection = lineP2 - lineOrigin;
float distanceToLine = Vector2.Dot(lineOrigin - rayOrigin, rayTangent);
float origin2ExtensionDistance = distanceToLine / Vector2.Dot(-rayTangent, lineDirection);
hitPoint = origin2ExtensionDistance * lineDirection + lineOrigin;
if (Vector2.Dot(hitPoint - rayOrigin, rayDirection) < 0.0f) {
return false;
}
var d = Vector2.Dot(hitPoint - lineOrigin, lineDirection.normalized);
if (d < 0.0f || d > lineDirection.magnitude) {
return false;
}
return true;
}
}