mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +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 *
|
||||
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 *
|
||||
|
|
|
@ -230,5 +230,16 @@ main (void)
|
|||
s.scalar, s.bvec);
|
||||
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 :)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue