diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-12-11 03:25:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-12-11 03:27:00 +0300 |
commit | becc85c5d487b0df834bbeb6b21f3f122bdedd10 (patch) | |
tree | fb0e9938eac021a20bc19430ce2773383afa64a6 /source/blender/blenlib | |
parent | 6e4802d71297993041f7e393d17bf2508585747b (diff) |
Math Lib: 2d ray-segment intersection function
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 5 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 45 |
2 files changed, 50 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index bf483386752..b0421c39707 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -244,6 +244,11 @@ bool isect_ray_tri_watertight_v3_simple( const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2]); +bool isect_ray_seg_v2( + const float p1[3], const float d[3], + const float v0[3], const float v1[3], + float *r_lambda, float *r_u); + /* point in polygon */ bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr, const bool use_holes); bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr, const bool use_holes); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 0ff12ebcaa9..5b809ab26cc 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1495,6 +1495,51 @@ bool isect_ray_tri_threshold_v3( } #endif + +bool isect_ray_seg_v2( + const float p1[3], const float d[3], + const float v0[3], const float v1[3], + float *r_lambda, float *r_u) +{ + float v0_local[2], v1_local[2]; + sub_v2_v2v2(v0_local, v0, p1); + sub_v2_v2v2(v1_local, v1, p1); + + float s10[2]; + float det; + + sub_v2_v2v2(s10, v1_local, v0_local); + + det = cross_v2v2(d, s10); + if (det != 0.0f) { + const float v = cross_v2v2(v0_local, v1_local); + float p[2] = {(d[0] * v) / det, (d[1] * v) / det}; + + const float t = (dot_v2v2(p, d) / dot_v2v2(d, d)); + if ((t >= 0.0f) == 0) { + return false; + } + + float h[2]; + sub_v2_v2v2(h, v1_local, p); + const float u = (dot_v2v2(s10, h) / dot_v2v2(s10, s10)); + if ((u >= 0.0f && u <= 1.0f) == 0) { + return false; + } + + if (r_lambda) { + *r_lambda = t; + } + if (r_u) { + *r_u = u; + } + + return true; + } + + return false; +} + /** * Check if a point is behind all planes. */ |