mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-28 23:22:43 +00:00
[qfcc] Implement the rest of 3d VGA
With tests.
This commit is contained in:
parent
a299cda463
commit
be4405485d
5 changed files with 573 additions and 16 deletions
|
@ -322,6 +322,21 @@ algebra_init (algebra_t *a)
|
|||
basis_group_init (&a->groups[4], 1, pga_blades + 11, a, 4);
|
||||
basis_group_init (&a->groups[5], 4, pga_blades + 12, a, 5);
|
||||
basis_layout_init (&a->layout, 6, a->groups);
|
||||
} else if (p == 3 && m == 0 && z == 0) {
|
||||
// 3d VGA (x y z square to +1):
|
||||
// : x y z xyz
|
||||
// : yz zx xy 1
|
||||
basis_blade_t pga_blades[8] = {
|
||||
blades[1], blades[2], blades[3], blades[7],
|
||||
blades[6], blades[5], blades[4], blades[0],
|
||||
};
|
||||
a->groups = malloc (sizeof (basis_group_t[4]));
|
||||
a->mvec_types = alloc_mvec_types (4);
|
||||
basis_group_init (&a->groups[0], 3, pga_blades + 0, a, 0);
|
||||
basis_group_init (&a->groups[1], 1, pga_blades + 3, a, 1);
|
||||
basis_group_init (&a->groups[2], 3, pga_blades + 4, a, 2);
|
||||
basis_group_init (&a->groups[3], 1, pga_blades + 7, a, 3);
|
||||
basis_layout_init (&a->layout, 4, a->groups);
|
||||
} else if (p == 2 && m == 0 && z == 1) {
|
||||
// 2d PGA (w squares to 0, x y square to +1):
|
||||
// : yw xw xy 1
|
||||
|
@ -533,12 +548,16 @@ static int pga_swaps_3d[16] = {
|
|||
[0xa] = 1, // e31
|
||||
[0xd] = 1, // e032
|
||||
};
|
||||
static int vga_swaps_3d[8] = {
|
||||
[0x5] = 1, // e31
|
||||
};
|
||||
|
||||
int
|
||||
algebra_count_flips (const algebra_t *alg, pr_uint_t a, pr_uint_t b)
|
||||
{
|
||||
bool pga_2d = (alg->plus == 2 && alg->minus == 0 && alg->zero == 1);
|
||||
bool pga_3d = (alg->plus == 3 && alg->minus == 0 && alg->zero == 1);
|
||||
bool vga_3d = (alg->plus == 3 && alg->minus == 0 && alg->zero == 0);
|
||||
int swaps = count_flips (a, b);
|
||||
if (pga_2d) {
|
||||
swaps += pga_swaps_2d[a];
|
||||
|
@ -548,6 +567,10 @@ algebra_count_flips (const algebra_t *alg, pr_uint_t a, pr_uint_t b)
|
|||
swaps += pga_swaps_3d[a];
|
||||
swaps += pga_swaps_3d[b];
|
||||
}
|
||||
if (vga_3d) {
|
||||
swaps += vga_swaps_3d[a];
|
||||
swaps += vga_swaps_3d[b];
|
||||
}
|
||||
return swaps;
|
||||
}
|
||||
|
||||
|
@ -557,6 +580,7 @@ algebra_blade_value (algebra_t *alg, const char *name)
|
|||
uint32_t dimension = alg->plus + alg->minus + alg->zero;
|
||||
bool pga_2d = (alg->plus == 2 && alg->minus == 0 && alg->zero == 1);
|
||||
bool pga_3d = (alg->plus == 3 && alg->minus == 0 && alg->zero == 1);
|
||||
bool vga_3d = (alg->plus == 3 && alg->minus == 0 && alg->zero == 0);
|
||||
|
||||
//FIXME supports only 0-9 (ie, up to 10d)
|
||||
if (name[0] == 'e' && isdigit(name[1])) {
|
||||
|
@ -593,6 +617,9 @@ algebra_blade_value (algebra_t *alg, const char *name)
|
|||
if (pga_3d) {
|
||||
swaps += pga_swaps_3d[blade];
|
||||
}
|
||||
if (vga_3d) {
|
||||
swaps += vga_swaps_3d[blade];
|
||||
}
|
||||
int sign = 1 - 2 * (swaps & 1);
|
||||
auto g = alg->layout.group_map[alg->layout.mask_map[blade]];
|
||||
auto group = &alg->layout.groups[g[0]];
|
||||
|
|
|
@ -258,6 +258,10 @@ evaluate_constexpr (expr_t *e)
|
|||
auto opb = get_def (s->opb);
|
||||
auto opc = get_def (s->opc);
|
||||
auto inst = opcode_find (s->opcode, s->opa, s->opb, s->opc);
|
||||
if (!inst) {
|
||||
print_statement (s);
|
||||
internal_error (e, "no such instruction");
|
||||
}
|
||||
auto ds = codespace_newstatement (&value_codespace);
|
||||
*ds = (dstatement_t) {
|
||||
.op = opcode_get (inst),
|
||||
|
|
|
@ -930,6 +930,88 @@ static pga_func pga2_dot_funcs[4][4] = {
|
|||
},
|
||||
};
|
||||
|
||||
static void
|
||||
vga3_x_y_z_dot_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_x_y_z_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = cross_expr (algebra_mvec_type (alg, 0x01), b, a);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_x_y_z_dot_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[2] = scale_expr (algebra_mvec_type (alg, 0x04), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_yz_zx_xy_dot_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = cross_expr (algebra_mvec_type (alg, 0x01), b, a);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_yz_zx_xy_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = neg_expr (dot_expr (algebra_mvec_type (alg, 0x08), a, b));
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_yz_zx_xy_dot_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = neg_expr (scale_expr (algebra_mvec_type (alg, 0x01), a, b));
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_xyz_dot_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[2] = scale_expr (algebra_mvec_type (alg, 0x04), b, a);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_xyz_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = neg_expr (scale_expr (algebra_mvec_type (alg, 0x01), b, a));
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_xyz_dot_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = neg_expr (scale_expr (algebra_mvec_type (alg, 0x08), b, a));
|
||||
}
|
||||
|
||||
|
||||
static pga_func vga3_dot_funcs[4][4] = {
|
||||
[0] = {
|
||||
[0] = vga3_x_y_z_dot_x_y_z,
|
||||
[1] = vga3_x_y_z_dot_xyz,
|
||||
[2] = vga3_x_y_z_dot_yz_zx_xy,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[1] = {
|
||||
[0] = vga3_xyz_dot_x_y_z,
|
||||
[1] = vga3_xyz_dot_xyz,
|
||||
[2] = vga3_xyz_dot_yz_zx_xy,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[2] = {
|
||||
[0] = vga3_yz_zx_xy_dot_x_y_z,
|
||||
[1] = vga3_yz_zx_xy_dot_xyz,
|
||||
[2] = vga3_yz_zx_xy_dot_yz_zx_xy,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[3] = {
|
||||
[0] = scale_component,
|
||||
[1] = scale_component,
|
||||
[2] = scale_component,
|
||||
[3] = scale_component,
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
component_dot (expr_t **c, expr_t *a, expr_t *b, algebra_t *algebra)
|
||||
{
|
||||
|
@ -949,6 +1031,12 @@ component_dot (expr_t **c, expr_t *a, expr_t *b, algebra_t *algebra)
|
|||
if (pga2_dot_funcs[ga][gb]) {
|
||||
pga2_dot_funcs[ga][gb] (c, a, b, algebra);
|
||||
}
|
||||
} else if (p == 3 && m == 0 && z == 0) {
|
||||
int ga = get_group (get_type (a), algebra);
|
||||
int gb = get_group (get_type (b), algebra);
|
||||
if (vga3_dot_funcs[ga][gb]) {
|
||||
vga3_dot_funcs[ga][gb] (c, a, b, algebra);
|
||||
}
|
||||
} else {
|
||||
internal_error (a, "not implemented");
|
||||
}
|
||||
|
@ -1148,41 +1236,42 @@ static pga_func pga2_wedge_funcs[4][4] = {
|
|||
};
|
||||
|
||||
static void
|
||||
vga2_x_y_z_wedge_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
vga3_x_y_z_wedge_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[2] = cross_expr (algebra_mvec_type (alg, 0x04), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga2_x_y_w_wedge_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
vga3_x_y_z_wedge_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b);
|
||||
c[1] = dot_expr (algebra_mvec_type (alg, 0x02), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga2_yz_zx_xy_wedge_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
vga3_yz_zx_xy_wedge_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b);
|
||||
c[1] = dot_expr (algebra_mvec_type (alg, 0x02), a, b);
|
||||
}
|
||||
|
||||
static pga_func vga3_wedge_funcs[4][4] = {
|
||||
[0] = {
|
||||
[0] = vga3_x_y_z_wedge_x_y_z,
|
||||
[2] = vga3_x_y_z_wedge_yz_zx_xy,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[1] = {
|
||||
[3] = scale_component,
|
||||
},
|
||||
[2] = {
|
||||
[0] = vga3_yz_zx_xy_wedge_x_y_z,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[3] = {
|
||||
[0] = scale_component,
|
||||
[1] = scale_component,
|
||||
[2] = scale_component,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[1] = {
|
||||
[0] = scale_component,
|
||||
[1] = vga2_x_y_z_wedge_x_y_w,
|
||||
[2] = vga2_x_y_w_wedge_yz_zx_xy,
|
||||
},
|
||||
[2] = {
|
||||
[0] = scale_component,
|
||||
[1] = vga2_yz_zx_xy_wedge_x_y_w,
|
||||
},
|
||||
[3] = {
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -1692,6 +1781,90 @@ static pga_func pga2_geometric_funcs[6][6] = {
|
|||
},
|
||||
};
|
||||
|
||||
static void
|
||||
vga3_x_y_z_geom_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b);
|
||||
c[2] = cross_expr (algebra_mvec_type (alg, 0x04), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_x_y_z_geom_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = cross_expr (algebra_mvec_type (alg, 0x01), b, a);
|
||||
c[1] = dot_expr (algebra_mvec_type (alg, 0x02), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_x_y_z_geom_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[2] = scale_expr (algebra_mvec_type (alg, 0x04), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_yz_zx_xy_geom_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = cross_expr (algebra_mvec_type (alg, 0x01), b, a);
|
||||
c[1] = dot_expr (algebra_mvec_type (alg, 0x02), a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_yz_zx_xy_geom_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = neg_expr (dot_expr (algebra_mvec_type (alg, 0x08), a, b));
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_yz_zx_xy_geom_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = neg_expr (scale_expr (algebra_mvec_type (alg, 0x01), a, b));
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_xyz_geom_x_y_z (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[2] = scale_expr (algebra_mvec_type (alg, 0x04), b, a);
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_xyz_geom_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[0] = neg_expr (scale_expr (algebra_mvec_type (alg, 0x01), b, a));
|
||||
}
|
||||
|
||||
static void
|
||||
vga3_xyz_geom_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
c[3] = neg_expr (scale_expr (algebra_mvec_type (alg, 0x08), b, a));
|
||||
}
|
||||
|
||||
static pga_func vga3_geometric_funcs[6][6] = {
|
||||
[0] = {
|
||||
[0] = vga3_x_y_z_geom_x_y_z,
|
||||
[1] = vga3_x_y_z_geom_xyz,
|
||||
[2] = vga3_x_y_z_geom_yz_zx_xy,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[1] = {
|
||||
[0] = vga3_xyz_geom_x_y_z,
|
||||
[1] = vga3_xyz_geom_xyz,
|
||||
[2] = vga3_xyz_geom_yz_zx_xy,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[2] = {
|
||||
[0] = vga3_yz_zx_xy_geom_x_y_z,
|
||||
[1] = vga3_yz_zx_xy_geom_xyz,
|
||||
[2] = vga3_yz_zx_xy_geom_yz_zx_xy,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[3] = {
|
||||
[0] = scale_component,
|
||||
[1] = scale_component,
|
||||
[2] = scale_component,
|
||||
[3] = scale_component,
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
component_geometric (expr_t **c, expr_t *a, expr_t *b, algebra_t *algebra)
|
||||
{
|
||||
|
@ -1711,6 +1884,12 @@ component_geometric (expr_t **c, expr_t *a, expr_t *b, algebra_t *algebra)
|
|||
if (pga2_geometric_funcs[ga][gb]) {
|
||||
pga2_geometric_funcs[ga][gb] (c, a, b, algebra);
|
||||
}
|
||||
} else if (p == 3 && m == 0 && z == 0) {
|
||||
int ga = get_group (get_type (a), algebra);
|
||||
int gb = get_group (get_type (b), algebra);
|
||||
if (vga3_geometric_funcs[ga][gb]) {
|
||||
vga3_geometric_funcs[ga][gb] (c, a, b, algebra);
|
||||
}
|
||||
} else {
|
||||
internal_error (a, "not implemented");
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ test_progs_dat=\
|
|||
tools/qfcc/test/vecconst.dat \
|
||||
tools/qfcc/test/vecinit.dat \
|
||||
tools/qfcc/test/vecops.dat \
|
||||
tools/qfcc/test/vga3d.dat \
|
||||
tools/qfcc/test/voidfor.dat \
|
||||
tools/qfcc/test/while.dat \
|
||||
tools/qfcc/test/zerolinker.dat
|
||||
|
@ -845,6 +846,16 @@ tools/qfcc/test/vecops.run: $(qfcc_test_run_deps)
|
|||
include $(vecops_dep) # am--include-marker
|
||||
r_depfiles_remade += $(vecops_dep)
|
||||
|
||||
tools_qfcc_test_vga3d_dat_SOURCES=tools/qfcc/test/vga3d.r
|
||||
vga3d_obj=$(tools_qfcc_test_vga3d_dat_SOURCES:.r=.o)
|
||||
vga3d_dep=$(call qcautodep,$(tools_qfcc_test_vga3d_dat_SOURCES))
|
||||
tools/qfcc/test/vga3d.dat$(EXEEXT): $(vga3d_obj) $(QFCC_DEP)
|
||||
$(V_QFCCLD)$(QLINK) -o $@ $(vga3d_obj)
|
||||
tools/qfcc/test/vga3d.run: $(qfcc_test_run_deps)
|
||||
@$(top_srcdir)/tools/qfcc/test/build-run $@
|
||||
include $(vga3d_dep) # am--include-marker
|
||||
r_depfiles_remade += $(vga3d_dep)
|
||||
|
||||
tools_qfcc_test_voidfor_dat_SOURCES=tools/qfcc/test/voidfor.r
|
||||
voidfor_obj=$(tools_qfcc_test_voidfor_dat_SOURCES:.r=.o)
|
||||
voidfor_dep=$(call qcautodep,$(tools_qfcc_test_voidfor_dat_SOURCES))
|
||||
|
|
336
tools/qfcc/test/vga3d.r
Normal file
336
tools/qfcc/test/vga3d.r
Normal file
|
@ -0,0 +1,336 @@
|
|||
#include "test-harness.h"
|
||||
#pragma warn no-vararg-integer
|
||||
typedef @algebra(float(3,0,0)) VGA;
|
||||
typedef VGA.group_mask(0x08) scalar_t;
|
||||
typedef VGA.group_mask(0x01) vector_t;
|
||||
typedef VGA.group_mask(0x04) bivector_t;
|
||||
typedef VGA.group_mask(0x02) trivector_t;
|
||||
typedef union {
|
||||
VGA.group_mask(0x0c) mvec;
|
||||
struct {
|
||||
bivector_t bvec;
|
||||
scalar_t scalar;
|
||||
};
|
||||
} evengrades_t;
|
||||
typedef union {
|
||||
VGA.group_mask(0x3) mvec;
|
||||
struct {
|
||||
vector_t vec;
|
||||
trivector_t tvec;
|
||||
};
|
||||
} oddgrades_t;
|
||||
|
||||
static int
|
||||
test_wedge (void)
|
||||
{
|
||||
scalar_t scalar;
|
||||
vector_t vec, vecb, vecc, vecd;
|
||||
bivector_t bvec, bvecb;
|
||||
trivector_t tvec, tvecb;
|
||||
@algebra (VGA) {
|
||||
scalar = 42;
|
||||
vec = 3*e1 - 2*e2 + 4*e3;
|
||||
bvec = 11*e23 - 4*e31 + 2*e12;
|
||||
tvec = 2*e123;
|
||||
|
||||
vecb = 5*e1 + 12*e2;
|
||||
bvecb = 1*e12;
|
||||
tvecb = 1*e123;
|
||||
|
||||
vecc = 5*e1 + 4*e2 - 3*e3;
|
||||
vecd = e1 + e2 + e3;
|
||||
}
|
||||
|
||||
if (scalar != 42) {
|
||||
printf ("scalar != 42: %g\n", scalar);
|
||||
return 1;
|
||||
}
|
||||
if ((vec3)vec != '3 -2 4') {
|
||||
printf ("vec != '3 -2 4': %v\n", vec);
|
||||
return 1;
|
||||
}
|
||||
if ((vec3)bvec != '11 -4 2') {
|
||||
printf ("bvec != '11 -4 2': %v\n", bvec);
|
||||
return 1;
|
||||
}
|
||||
if ((scalar_t)tvec != 2) {
|
||||
printf ("tvec != 2: %g\n", (scalar_t)tvec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bivector_t a = vec ∧ vecb;
|
||||
if ((vec3)a != '-48 20 46') {
|
||||
printf ("vec ∧ vecb != '-48 20 46': %v\n", a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto b = a ∧ vecc;
|
||||
if ((scalar_t)b != -298) {
|
||||
printf ("a ∧ vecc != -298: %g\n", (scalar_t)b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto c = b ∧ vecd;
|
||||
if ((scalar_t)c != 0) {
|
||||
printf ("b ∧ vecd != 0': %g\n", (scalar_t) c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
a = vecb ∧ vec;
|
||||
if ((vec3)a != '48 -20 -46') {
|
||||
printf ("vecb ∧ vec != '48 -20 -46': %v\n", a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
b = vecc ∧ a;
|
||||
if ((scalar_t)b != 298) {
|
||||
printf ("vecc ∧ a != 298: %g\n", (scalar_t)b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c = vecd ∧ b;
|
||||
if ((scalar_t)c != 0) {
|
||||
printf ("vecd ^ b != 0': %g\n", (scalar_t) c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c = a ∧ (vecc ∧ vecd);
|
||||
if ((scalar_t)c != 0) {
|
||||
printf ("a ∧ (vecc ∧ vecd) != 0': %g\n", (scalar_t) c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c = (vecd ∧ vecc) ∧ a;
|
||||
if ((scalar_t)c != 0) {
|
||||
printf ("(vecd ∧ vecc) ∧ a != 0': %g\n", (scalar_t) c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_dot (void)
|
||||
{
|
||||
scalar_t scalar;
|
||||
vector_t vec, vecb, vecc, vecd;
|
||||
bivector_t bvec, bvecb;
|
||||
trivector_t tvec, tvecb;
|
||||
@algebra (VGA) {
|
||||
scalar = 42;
|
||||
vec = 3*e1 - 2*e2 + 4*e3;
|
||||
bvec = 11*e23 - 4*e31 + 2*e12;
|
||||
tvec = 8*e123;
|
||||
|
||||
vecb = 5*e1 + 12*e2;
|
||||
bvecb = 1*e12;
|
||||
tvecb = 1*e123;
|
||||
|
||||
vecc = 5*e1 + 4*e2 - 3*e3;
|
||||
vecd = e1 + e2 + e3;
|
||||
}
|
||||
|
||||
auto a = bvec • tvec;
|
||||
if ((vec3)a != '-88 32 -16') {
|
||||
printf ("bvec • tvec != '-88 32 -16': %v\n", a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto b = vec • tvec;
|
||||
if ((vec3)b != '24 -16 32') {
|
||||
printf ("vec • tvec != '24 -16 32': %v\n", b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (bvec • bvec != -141) {
|
||||
printf ("(bvec • bvec) != -141': %g\n", bvec • bvec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
a = vec • bvec;
|
||||
if ((vec3)a != '-12 -38 -10') {
|
||||
printf ("vec • bvec != '-12 -38 -10': %v\n", a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vec • vecb != -9) {
|
||||
printf ("(vec • vecb) != -9': %g\n", vec • vecb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto d = tvec • tvec;
|
||||
if (d != -64) {
|
||||
printf ("tvec • tvec != -64: %g\n", a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
a = tvec • bvec;
|
||||
if ((vec3)a != '-88 32 -16') {
|
||||
printf ("tvec • vec != '-88 32 -16': %v\n", a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
b = tvec • vec;
|
||||
if ((vec3)b != '24 -16 32') {
|
||||
printf ("tvec • vec != '24 -16 32': %v\n", b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
a = bvec • vec;
|
||||
if ((vec3)a != '12 38 10') {
|
||||
printf ("bvec • vec != '12 38 10': %v\n", a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_geom (void)
|
||||
{
|
||||
scalar_t scalar;
|
||||
vector_t vec, vecb, vecc, vecd;
|
||||
bivector_t bvec, bvecb;
|
||||
trivector_t tvec, tvecb;
|
||||
@algebra (VGA) {
|
||||
scalar = 42;
|
||||
vec = 3*e1 - 2*e2 + 4*e3;
|
||||
bvec = 11*e23 - 4*e31 + 2*e12;
|
||||
tvec = 8*e123;
|
||||
|
||||
vecb = 5*e1 + 12*e2;
|
||||
bvecb = 1*e12;
|
||||
tvecb = 1*e123;
|
||||
|
||||
vecc = 5*e1 + 4*e2 - 3*e3;
|
||||
vecd = e1 + e2 + e3;
|
||||
}
|
||||
|
||||
if (tvec * tvecb != -8) {
|
||||
printf ("(tvec * tvecb) != -8': %g\n", tvec * tvecb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto d = bvec * tvec;
|
||||
if ((vec3)d != '-88 32 -16') {
|
||||
printf ("bvec * tvec != '-88 32 -16': %v\n", d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto e = vec * tvec;
|
||||
if ((vec3)e != '24 -16 32') {
|
||||
printf ("vec * tvec != 0 '24 -16 32': %v\n", e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto f = bvec * bvec;
|
||||
if (f != -141) {
|
||||
printf ("bvec * bvec != -141: %g\n", f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
oddgrades_t odd = { .mvec = vec * bvec };
|
||||
if ((vec3)odd.vec != '-12 -38 -10' || (scalar_t)odd.tvec != 49) {
|
||||
printf ("vec * bvec != '-12 -38 -10' 49: %v %g\n",
|
||||
odd.vec, (scalar_t)odd.tvec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
evengrades_t even = { .mvec = vec * vecb };
|
||||
if (even.scalar != -9 || (vec3)even.bvec != '-48 20 46') {
|
||||
printf ("(vec * vecb) != -9 '-48 20 46': %g %v\n",
|
||||
even.scalar, even.bvec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto b = tvec * bvec;
|
||||
if ((vec3)b != '-88 32 -16') {
|
||||
printf ("tvec * bvec != '-88 32 -16': %v\n", b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
e = tvec * vec;
|
||||
if ((vec3)e != '24 -16 32') {
|
||||
printf ("tvec * vec != '24 -16 32': %v\n", e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
odd.mvec = bvec * vec;
|
||||
if ((vec3)odd.vec != '12 38 10' || (scalar_t)odd.tvec != 49) {
|
||||
printf ("vec * bvec != '12 38 10' 49: %v %g\n",
|
||||
odd.vec, (scalar_t)odd.tvec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_basics (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
if (sizeof (scalar_t) != sizeof (float)) {
|
||||
printf ("scalar has wrong size: %d\n", sizeof (scalar_t));
|
||||
return 1;
|
||||
}
|
||||
if (sizeof (vector_t) != 4 * sizeof (scalar_t)) {
|
||||
printf ("vector has wrong size: %d\n", sizeof (vector_t));
|
||||
return 1;
|
||||
}
|
||||
if (sizeof (bivector_t) != 4 * sizeof (scalar_t)) {
|
||||
printf ("bivector has wrong size: %d\n", sizeof (bivector_t));
|
||||
return 1;
|
||||
}
|
||||
if (sizeof (trivector_t) != sizeof (scalar_t)) {
|
||||
printf ("trivector has wrong size: %d\n", sizeof (trivector_t));
|
||||
return 1;
|
||||
}
|
||||
if (sizeof (evengrades_t) != 4) {
|
||||
evengrades_t e;
|
||||
#define offsetof(s,f) ((int)(&((s*)0).f))
|
||||
printf ("evengrades has wrong size: %d\n", sizeof (evengrades_t));
|
||||
printf ("mvec: %d, bvec: %d, scalar: %d\n",
|
||||
sizeof (e.mvec), sizeof (e.bvec), sizeof (e.scalar));
|
||||
printf ("mvec: %d, bvec: %d, scalar: %d\n",
|
||||
offsetof (evengrades_t, mvec), offsetof (evengrades_t, bvec),
|
||||
offsetof (evengrades_t, scalar));
|
||||
return 1;
|
||||
}
|
||||
if (sizeof (oddgrades_t) != 4) {
|
||||
oddgrades_t o;
|
||||
#define offsetof(s,f) ((int)(&((s*)0).f))
|
||||
printf ("oddgrades has wrong size: %d\n", sizeof (oddgrades_t));
|
||||
printf ("mvec: %d, vec: %d, tvec: %d\n",
|
||||
sizeof (o.mvec), sizeof (o.vec), sizeof (o.tvec));
|
||||
printf ("mvec: %d, vec: %d, tvec: %d\n",
|
||||
offsetof (oddgrades_t, mvec), offsetof (oddgrades_t, vec),
|
||||
offsetof (oddgrades_t, tvec));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_wedge ()) {
|
||||
printf ("wedge products failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_dot ()) {
|
||||
printf ("dot products failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_geom ()) {
|
||||
printf ("geometric products failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_basics ()) {
|
||||
printf ("basics failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0; // to survive and prevail :)
|
||||
}
|
Loading…
Reference in a new issue