mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
[qfcc] Implement mutli-vector division
But only for scalar divisors. The simple method of AB†/(BB†) works only if B is a versor and there's also the problem of left and right division. Thanks to sudgy for making me stop and think before I actually implemented anything (though he mentioned only that it doesn't work for general mutli-vector divisors).
This commit is contained in:
parent
41e0483102
commit
6b1684b711
2 changed files with 42 additions and 1 deletions
|
@ -1374,7 +1374,37 @@ commutator_product (expr_t *e1, expr_t *e2)
|
||||||
static expr_t *
|
static expr_t *
|
||||||
multivector_divide (expr_t *e1, expr_t *e2)
|
multivector_divide (expr_t *e1, expr_t *e2)
|
||||||
{
|
{
|
||||||
internal_error (e1, "not implemented");
|
if (is_algebra (get_type (e2))) {
|
||||||
|
return error (e2, "Division is left-right ambiguous (and works only"
|
||||||
|
" for versors anyway). Use explicit reversion and divide"
|
||||||
|
" by square magnitude instead.");
|
||||||
|
}
|
||||||
|
if (!is_algebra (get_type (e1))) {
|
||||||
|
internal_error (e1, "wtw?");
|
||||||
|
}
|
||||||
|
auto t1 = get_type (e1);
|
||||||
|
auto algebra = algebra_get (t1);
|
||||||
|
auto layout = &algebra->layout;
|
||||||
|
auto stype = algebra->type;
|
||||||
|
expr_t *a[layout->count] = {};
|
||||||
|
e1 = mvec_expr (e1, algebra);
|
||||||
|
e2 = promote_scalar (algebra->type, e2);
|
||||||
|
mvec_scatter (a, e1, algebra);
|
||||||
|
|
||||||
|
for (int i = 0; i < layout->count; i++) {
|
||||||
|
if (!a[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto den = e2;
|
||||||
|
auto ct = get_type (a[i]);
|
||||||
|
int width = type_width (ct);
|
||||||
|
if (width > 1) {
|
||||||
|
den = new_extend_expr (den, vector_type (stype, width), 2, false);
|
||||||
|
}
|
||||||
|
a[i] = new_binary_expr ('/', a[i], den);
|
||||||
|
a[i]->e.expr.type = ct;
|
||||||
|
}
|
||||||
|
return mvec_gather (a, algebra);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
|
|
|
@ -230,5 +230,16 @@ main (void)
|
||||||
s.scalar, s.bvec);
|
s.scalar, s.bvec);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
e.mvec = e.mvec / 2; // odd
|
||||||
|
if ((dvec3)e.vec != '2 3 0.5'd || (scalar_t)e.tvec != -10) {
|
||||||
|
printf ("odd† != '2 3 0.5' + -10: %lv %g\n", e.vec, e.tvec);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
s.mvec = s.mvec / 2; // even
|
||||||
|
if (s.scalar != -4.5 || (dvec3)s.bvec != '-7 -22 -23'd) {
|
||||||
|
printf ("even† != -4.5, '-7 -22 -23': %g %lv\n",
|
||||||
|
s.scalar, s.bvec);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0; // to survive and prevail :)
|
return 0; // to survive and prevail :)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue