123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- float vDistPointLine2(Vector2 p, Line2 ls) {
- Vector2 pa = vSub2(p, ls.start);
- Vector2 ba = vSub2(ls.end, ls.start);
-
- float t = vDot2(pa, ba) / sqrtf(vDot2(ba, ba));
- fclamp(t, 0.0, 1.0);
-
-
-
-
-
- Vector2 pi = vSub2(pa, vScale2(ba, t));
- return vMag2(pi);
- }
- float vDistPointLine3(Vector3 p, Line3 ls) {
- Vector3 pa = vSub3(p, ls.start);
- Vector3 ba = vSub3(ls.end, ls.start);
-
- float t = fclamp(vDot3(pa, ba) / vDot3(ba, ba), 0.0, 1.0);
- return vMag3(vSub3(pa, vScale3(ba, t)));
- }
- float vDistTPointLine2(Vector2 p, Line2 ls, float* T) {
- Vector2 pa = vSub2(p, ls.start);
- Vector2 ba = vSub2(ls.end, ls.start);
-
- float t = fclamp(vDot2(pa, ba) / vDot2(ba, ba), 0.0, 1.0);
- if(T) *T = t;
- return vMag2(vSub2(pa, vScale2(ba, t)));
- }
- float vDistTPointLine3(Vector3 p, Line3 ls, float* T) {
- Vector3 pa = vSub3(p, ls.start);
- Vector3 ba = vSub3(ls.end, ls.start);
-
- float t = fclamp(vDot3(pa, ba) / vDot3(ba, ba), 0.0, 1.0);
- if(T) *T = t;
- return vMag3(vSub3(pa, vScale3(ba, t)));
- }
- float projPointLine2(Vector2 p, Line2 ls) {
- Vector2 pa = vSub2(p, ls.start);
- Vector2 ba = vSub2(ls.end, ls.start);
-
- return vDot2(pa, ba) / vDot2(ba, ba);
- }
- float distLineLine3(Line3* a, Line3* b) {
-
- Vector3 ea = vSub3(a->end, a->start);
- Vector3 eb = vSub3(b->end, b->start);
- Vector3 q = vSub(b->start, a->start);
-
-
- float vaa = vLenSq3(ea);
- float vbb = vLenSq3(eb);
- float vba = vDot3(ea, eb);
- float vba_a = vDot3(q, ea);
-
- float den = vba * vba - vbb * vaa;
-
- float ta, tb;
- if(fabs(den) < 1e-6) {
- ta = 0;
- tb = -vba_a / vba;
- }
- else {
- float vba_b = vDot3(q, eb);
-
- ta = (vba_b * vba - vbb * vba_a) / den;
- tb = (-vba_a * vba + vaa * vba_b) / den;
- }
-
- ta = fclamp(0, 1, ta);
- tb = fclamp(0, 1, tb);
-
- Vector3 pa = vAdd(a->start, vScale(ea, ta));
- Vector3 pb = vAdd(b->start, vScale(eb, tb));
- return vDist(pa, pb);
- }
- Line2 shortestLineFromLineToLine2(Line2* a, Line2* b) {
-
- float s, t;
- vec2 da = vSub(a->end, a->start);
- vec2 db = vSub(b->end, b->start);
-
-
- float det = vCross2(da, db);
- if(fabsf(det) > 1e-5f) {
-
- float invdet = 1.f / det;
-
- float x02 = a->start.x - b->start.x;
- float y02 = a->start.y - b->start.y;
-
- s = (da.x * y02 - da.y * x02) * invdet;
- if(s >= 0.f && s <= 1.f) {
- t = (db.x * y02 - db.y * x02) * invdet;
- if(t >= 0.f && t <= 1.f) {
- vec2 pa = vAdd(a->start, vScale(da, t));
-
- return (Line2){pa, pa};
- }
- }
- }
-
-
-
- vec2 ab = vSub(b->start, a->start);
-
- float d_abda = vDot(ab, da);
- float d_abdb = vDot(ab, db);
- float d_dadb = vDot(da, db);
- float l2_da = vLenSq(da);
- float l2_db = vLenSq(db);
- float invl2_da = 1.f / l2_da;
-
- float den = l2_da * l2_db - d_dadb * d_dadb;
-
- if(den < 1e-6f * l2_db * l2_da) {
- s = fclamp(d_abda * invl2_da, 0, 1);
- t = 0;
- }
- else {
- float invden = 1.f / den;
- s = fclamp((d_abda * l2_db - d_abdb * d_dadb) * invden, 0, 1);
- t = fclamp((d_abda * d_dadb - d_abdb * l2_da) * invden, 0, 1);
- }
-
- return (Line2){
- vAdd(a->start, vScale(da, fclamp((t * d_dadb + d_abda) * invl2_da, 0, 1))),
- vAdd(b->start, vScale(db, fclamp((s * d_dadb - d_abdb) / l2_db, 0, 1)))
- };
- }
- Line3 shortestLineFromLineToLine(Line3* a, Line3* b) {
-
- Vector3 ea = vSub3(a->end, a->start);
- Vector3 eb = vSub3(b->end, b->start);
- Vector3 q = vSub(b->start, a->start);
-
- float vaa = vLenSq3(ea);
- float vbb = vLenSq3(eb);
-
- float vba = vDot3(ea, eb);
- float vba_a = vDot3(q, ea);
-
- float den = vba * vba - vbb * vaa;
-
- float ta, tb;
- if(fabs(den) < 1e-6) {
- ta = 0;
- tb = -vba_a / vba;
- }
- else {
- float vba_b = vDot3(q, eb);
-
- ta = (vba_b * vba - vbb * vba_a) / den;
- tb = (-vba_a * vba + vaa * vba_b) / den;
- }
-
- ta = fclamp(ta, 0, 1);
- tb = fclamp(tb, 0, 1);
-
- Vector3 pa = vAdd(a->start, vScale(ea, ta));
- Vector3 pb = vAdd(b->start, vScale(eb, tb));
- return (Line3){pa, pb};
- }
- int linePlaneClip3p(
- Vector3* la,
- Vector3* lb,
- Plane* pl,
- Vector3* aboveOut,
- Vector3* belowOut,
- int* aboveCnt,
- int* belowCnt
- ) {
- Vector3 ldir, c;
- float da, db;
-
- vSub3p(lb, la, &ldir);
-
- da = vDot3p(la, &pl->n) - pl->d;
-
-
- if(fabs(vDot3p(&pl->n, &ldir)) < FLT_CMP_EPSILON) {
- *aboveCnt = 0;
- *belowCnt = 0;
-
-
- if(fabs(da) < FLT_CMP_EPSILON) {
- return C3DLAS_COPLANAR;
- }
-
- return C3DLAS_PARALLEL;
- }
-
- db = vDot3p(lb, &pl->n) - pl->d;
-
-
- if(fabs(da) < FLT_CMP_EPSILON) {
- if(db > 0) {
- aboveOut[0] = *la;
- aboveOut[1] = *lb;
- *aboveCnt = 1;
- *belowCnt = 0;
- }
- else {
- belowOut[0] = *la;
- belowOut[1] = *lb;
- *aboveCnt = 0;
- *belowCnt = 1;
- }
-
- return C3DLAS_INTERSECT;
- }
- if(fabs(db) < FLT_CMP_EPSILON) {
- if(da > 0) {
- aboveOut[0] = *la;
- aboveOut[1] = *lb;
- *aboveCnt = 1;
- *belowCnt = 0;
- }
- else {
- belowOut[0] = *la;
- belowOut[1] = *lb;
- *aboveCnt = 0;
- *belowCnt = 1;
- }
-
- return C3DLAS_INTERSECT;
- }
-
-
- Vector3 p0, g, j;
- vScale3p(&pl->n, pl->d, &p0);
- vSub3p(&p0, la, &g);
- float h = vDot3p(&g, &pl->n);
- float i = vDot3p(&ldir, &pl->n);
- float d = i != 0 ? h / i : 0;
-
-
- if(d < 0 || d > vDist3p(la, lb)) {
- if(da > 0) {
- aboveOut[0] = *la;
- aboveOut[1] = *lb;
- *aboveCnt = 1;
- *belowCnt = 0;
- }
- else {
- belowOut[0] = *la;
- belowOut[1] = *lb;
- *aboveCnt = 0;
- *belowCnt = 1;
- }
-
- return C3DLAS_DISJOINT;
- }
-
- vScale3p(&ldir, d, &j);
- vAdd3p(la, &j, &c);
-
- if(da > 0) {
- aboveOut[0] = *la;
- aboveOut[1] = c;
- belowOut[0] = c;
- belowOut[1] = *lb;
- }
- else {
- belowOut[0] = *la;
- belowOut[1] = c;
- aboveOut[0] = c;
- aboveOut[1] = *lb;
- }
-
- *aboveCnt = 1;
- *belowCnt = 1;
-
- return C3DLAS_INTERSECT;
- }
|