Last active
September 2, 2024 07:31
-
-
Save unitycoder/10241239e080720376830f84511ccd3c to your computer and use it in GitHub Desktop.
Math Algorithms c# Calculate - 2D Line Intersection
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
// https://forum.unity.com/threads/line-intersection.17384/#post-4442284 | |
bool FasterLineSegmentIntersection (Vector2 line1point1, Vector2 line1point2, Vector2 line2point1, Vector2 line2point2) { | |
Vector2 a = line1point2 - line1point1; | |
Vector2 b = line2point1 - line2point2; | |
Vector2 c = line1point1 - line2point1; | |
float alphaNumerator = b.y * c.x - b.x * c.y; | |
float betaNumerator = a.x * c.y - a.y * c.x; | |
float denominator = a.y * b.x - a.x * b.y; | |
if (denominator == 0) { | |
return false; | |
} else if (denominator > 0) { | |
if (alphaNumerator < 0 || alphaNumerator > denominator || betaNumerator < 0 || betaNumerator > denominator) { | |
return false; | |
} | |
} else if (alphaNumerator > 0 || alphaNumerator < denominator || betaNumerator > 0 || betaNumerator < denominator) { | |
return false; | |
} | |
return true; | |
} |
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
// https://stackoverflow.com/questions/481144/equation-for-testing-if-a-point-is-inside-a-circle | |
//test if coordinate (x, y) is within a radius from coordinate (center_x, center_y) | |
public bool IsPointInCircle(float centerX, float centerY, float radius, float x, float y) | |
{ | |
if (IsInRectangle(centerX, centerY, radius, x, y)) | |
{ | |
float dx = centerX - x; | |
float dy = centerY - y; | |
dx *= dx; | |
dy *= dy; | |
float distanceSquared = dx + dy; | |
float radiusSquared = radius * radius; | |
return distanceSquared <= radiusSquared; | |
} | |
return false; | |
} | |
bool IsInRectangle(float centerX, float centerY, float radius, float x, float y) | |
{ | |
return x >= centerX - radius && x <= centerX + radius && y >= centerY - radius && y <= centerY + radius; | |
} |
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
// https://github.com/chengkehan/Line-Triangle-Intersection/blob/master/Assets/LineTriangleIntersection.cs | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class LineTriangleIntersection : MonoBehaviour | |
{ | |
public Transform tri0 = null; | |
public Transform tri1 = null; | |
public Transform tri2 = null; | |
public Transform line0 = null; | |
public Transform line1 = null; | |
// UE4:kDOP.h appLineCheckTriangleSOA | |
private void OnDrawGizmos() | |
{ | |
Vector3 trip0 = tri0.position; | |
Vector3 trip1 = tri1.position; | |
Vector3 trip2 = tri2.position; | |
Vector3 linep0 = line0.position; | |
Vector3 linep1 = line1.position; | |
Gizmos.matrix = Matrix4x4.identity; | |
// Draw triangle | |
Gizmos.color = Color.yellow; | |
Gizmos.DrawLine(trip0, trip1); | |
Gizmos.DrawLine(trip1, trip2); | |
Gizmos.DrawLine(trip2, trip0); | |
// Draw line | |
Gizmos.color = Color.red; | |
Gizmos.DrawLine(linep0, linep1); | |
// Line is on the same side of triangle-plane | |
Vector3 triNormal = Vector3.Cross(trip1 - trip0, trip2 - trip0); | |
triNormal.Normalize(); | |
float triPlaneD = Vector3.Dot(trip0, triNormal); | |
Vector4 triPlane = new Vector4(triNormal.x, triNormal.y, triNormal.z, triPlaneD); | |
float line0D = Vector3.Dot(linep0, triNormal) - triPlaneD; | |
float line1D = Vector3.Dot(linep1, triNormal) - triPlaneD; | |
if (line0D * line1D > 0) | |
{ | |
return; | |
} | |
// Figure out the hit point(intersection) | |
float hitTime = line0D / (line0D - line1D); | |
Vector3 lineDir = linep1 - linep0; | |
Vector3 hitP = linep0 + lineDir * hitTime; | |
// Check if the point point is inside the triangle | |
Vector3[] trips = new Vector3[] { trip0, trip1, trip2 }; | |
for(int sideIndex = 0; sideIndex < 3; ++sideIndex) | |
{ | |
Vector3 edge = trips[(sideIndex + 1) % 3] - trips[sideIndex]; | |
Vector3 sideDir = Vector3.Cross(triNormal, edge); | |
Vector3 hitDir = hitP - trips[sideIndex]; | |
float side = Vector3.Dot(hitDir, sideDir); | |
if(side < 0) | |
{ | |
// Hit point is outside the triangle. | |
return; | |
} | |
} | |
// Draw intersection | |
Gizmos.color = Color.green; | |
Gizmos.DrawCube(hitP, Vector3.one * 0.5f); | |
} | |
} |
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
// get fraction part | |
float frac = 123.1234f % 1; | |
// average of two ints in a single instruction | |
(a>>1)+(b>>1)+(a&b&1) | |
(a&b) + ((a^b) >> 1) | |
// convert small integer to float https://youtu.be/BpwvXkoFcp8?t=1379 | |
ushort x = ...; | |
uint y = x | 0x4b000000; | |
float f = as_float(y)-8388608.0f; | |
// generate mask from sign of float data | |
float x = ...; | |
uint mask = as_int(x) >> 31; | |
// compare if two lines are identical | |
https://twitter.com/schneckerstein/status/1191813789408256002 |
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
// SLAB : Intersection of Line Segment and Cube | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class SlabTest : MonoBehaviour | |
{ | |
public Transform startT = null; | |
public Transform endT = null; | |
public Vector3 boundsSize = Vector3.one * 3; | |
private Bounds bounds = new Bounds(Vector3.zero, Vector3.one * 3); | |
private void OnDrawGizmos() | |
{ | |
// Resize bounds | |
bounds.size = boundsSize; | |
// Transform line segment from world space to local space | |
Matrix4x4 w2l = transform.worldToLocalMatrix; | |
Vector3 startP = w2l.MultiplyPoint(startT.position); | |
Vector3 endP = w2l.MultiplyPoint(endT.position); | |
// Draw bounds | |
Gizmos.color = Color.yellow; | |
Gizmos.matrix = transform.localToWorldMatrix; | |
Gizmos.DrawWireCube(bounds.center, bounds.size); | |
// Draw line segment | |
Gizmos.color = Color.cyan; | |
Gizmos.DrawCube(startP, Vector3.one * 0.3f); | |
Gizmos.DrawCube(endP, Vector3.one * 0.3f); | |
Gizmos.DrawLine(startP, endP); | |
Vector3 min = bounds.min; | |
Vector3 max = bounds.max; | |
Vector3 dir = endP - startP; | |
Vector3 oneOverDir = new Vector3(1.0f / dir.x, 1.0f / dir.y, 1.0f / dir.z); | |
// Slabs | |
float _minSlabX = (min.x - startP.x) * oneOverDir.x; | |
float _minSlabY = (min.y - startP.y) * oneOverDir.y; | |
float _minSlabZ = (min.z - startP.z) * oneOverDir.z; | |
float _maxSlabX = (max.x - startP.x) * oneOverDir.x; | |
float _maxSlabY = (max.y - startP.y) * oneOverDir.y; | |
float _maxSlabZ = (max.z - startP.z) * oneOverDir.z; | |
// Min/Max Slabs | |
float minSlabX = Mathf.Min(_minSlabX, _maxSlabX); | |
float minSlabY = Mathf.Min(_minSlabY, _maxSlabY); | |
float minSlabZ = Mathf.Min(_minSlabZ, _maxSlabZ); | |
float maxSlabX = Mathf.Max(_minSlabX, _maxSlabX); | |
float maxSlabY = Mathf.Max(_minSlabY, _maxSlabY); | |
float maxSlabZ = Mathf.Max(_minSlabZ, _maxSlabZ); | |
float minSlab = Mathf.Max(minSlabX, minSlabY, minSlabZ); | |
float maxSlab = Mathf.Min(maxSlabX, maxSlabY, maxSlabZ); | |
// Check hit | |
bool bHit = maxSlab >= 0.0f && maxSlab >= minSlab && minSlab <= 1.0f; | |
if(bHit) | |
{ | |
Gizmos.color = Color.red; | |
int hitSurface = 0; | |
if (minSlab >= 0 && minSlab <= 1) | |
{ | |
// Draw first hit point | |
++hitSurface; | |
Gizmos.DrawSphere(startP + new Vector3(minSlab * dir.x, minSlab * dir.y, minSlab * dir.z), 0.4f); | |
} | |
if (maxSlab >= 0 && maxSlab <= 1) | |
{ | |
// Draw second hit point | |
++hitSurface; | |
Gizmos.DrawSphere(startP + new Vector3(maxSlab * dir.x, maxSlab * dir.y, maxSlab * dir.z), 0.4f); | |
} | |
if (hitSurface == 0) | |
{ | |
// line segment inside bounds | |
Debug.LogError("inside"); | |
} | |
else | |
{ | |
// line segment hit surface | |
Debug.LogError("hit"); | |
} | |
} | |
else | |
{ | |
// line segment hit nothing | |
Debug.LogError("nohit"); | |
} | |
} | |
private float CompareGE(float a, float b) | |
{ | |
return a >= b ? 0xFFFFFFFF : 0; | |
} | |
private float CompareGT(float a, float b) | |
{ | |
return a > b ? 0xFFFFFFFF : 0; | |
} | |
private float BitwiseAnd(float a, float b) | |
{ | |
int ia = System.BitConverter.ToInt32(System.BitConverter.GetBytes(a), 0); | |
int ib = System.BitConverter.ToInt32(System.BitConverter.GetBytes(b), 0); | |
int r = ia & ib; | |
return System.BitConverter.ToSingle(System.BitConverter.GetBytes(r), 0); | |
} | |
} |
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
// https://forum.unity.com/threads/all-intersection-point-in-single-collider.453956/#post-2942175 | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
[ExecuteInEditMode] | |
public class ClippingScript : MonoBehaviour | |
{ | |
public Vector2 LineStart; | |
public Vector2 LineEnd; | |
public float crossScale = 0.05f; | |
Vector2[] polygonPoints; | |
PolygonCollider2D polygon; | |
List<Vector2> clipPoints = new List<Vector2> (); | |
// Use this for initialization | |
void Start () | |
{ | |
// Start the body rotating. | |
GetComponent<Rigidbody2D> ().angularVelocity = 45.0f; | |
polygon = GetComponent<PolygonCollider2D> (); | |
} | |
// Update is called once per frame | |
void Update () | |
{ | |
// Fetch the polygon points in world-space (not the most efficient way of doing things)! | |
polygonPoints = polygon.points; | |
for (var i = 0; i < polygonPoints.Length; ++i) | |
polygonPoints[i] = transform.TransformPoint (polygonPoints[i]); | |
// Perform clipping against the polygon. | |
clipPoints.Clear (); | |
var pointCount = polygonPoints.Length; | |
for (int i = 0, j = pointCount - 1; i < pointCount; j = i++) | |
{ | |
var edgeStart = polygonPoints[i]; | |
var edgeEnd = polygonPoints[j]; | |
Vector2 clipPoint; | |
if (LineSegmentIntersection (LineStart, LineEnd, edgeStart, edgeEnd, out clipPoint)) | |
clipPoints.Add (clipPoint); | |
} | |
// Draw the clipping line. | |
Debug.DrawLine (LineStart, LineEnd, Color.red); | |
// Draw the clip points. | |
foreach (var v in clipPoints) | |
{ | |
var clipPoint = (Vector3)v; | |
Debug.DrawLine (clipPoint + (Vector3.left * crossScale), clipPoint + (Vector3.right * crossScale), Color.white); | |
Debug.DrawLine (clipPoint + (Vector3.up * crossScale), clipPoint + (Vector3.down * crossScale), Color.white); | |
} | |
} | |
bool LineSegmentIntersection (Vector2 a, Vector2 b, Vector2 c, Vector2 d, out Vector2 point) | |
{ | |
// Sign of areas correspond to which side of ab points c and d are. | |
float area1 = SignedTriangleArea (a, b, d); | |
float area2 = SignedTriangleArea (a, b, c); | |
// If c and d are on different sides of ab, areas have different signs. | |
if (area1 * area2 < 0.0f) | |
{ | |
// Compute signs for a and b with respect to segment cd. | |
float area3 = SignedTriangleArea (c, d, a); | |
float area4 = area3 + area2 - area1; | |
// Points a and b on different sides of cd if areas have different signs. | |
if (area3 * area4 < 0.0f) | |
{ | |
float time = area3 / (area3 - area4); | |
point = a + time * (b - a); | |
return true; | |
} | |
} | |
// Segments are not intersecting or collinear. | |
point = Vector2.zero; | |
return false; | |
} | |
float SignedTriangleArea (Vector2 a, Vector2 b, Vector2 c) | |
{ | |
return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
COS
https://github.com/ifduyue/musl/blob/master/src/math/__cos.c