Sierpinski ish thing working

This commit is contained in:
Chris Hodapp
2020-10-02 11:38:53 -04:00
parent 35daf01b8a
commit 8146d4fea8
4 changed files with 174 additions and 30 deletions

View File

@@ -166,36 +166,52 @@ pub fn barbs(random: bool) -> Rule<()> {
pub fn pyramid() -> Rule<()> {
// base_verts are for a triangle in the XY plane, centered at
// (0,0,0), with unit sidelength:
let (b0, bn);
let rt3 = (3.0).sqrt();
let rt6 = (6.0).sqrt();
let base_verts: Vec<VertexUnion> = vec_indexed![
@b0 VertexUnion::Vertex(vertex( rt3/3.0, 0.0, 0.0)),
VertexUnion::Vertex(vertex( -rt3/6.0, -1.0/2.0, 0.0)),
VertexUnion::Vertex(vertex( -rt3/6.0, 1.0/2.0, 0.0)),
VertexUnion::Vertex(vertex( 0.0, 0.0, rt6/3.0)),
@bn,
];
// base_verts are for a unit-sidelength tetrahedron and its midpoints.
// Its *base* sits in the XY plane, centered at (0,0,0).
// Indices:
// b0,b1,b2 = base vertices; t = 'top' vertex.
// m01, m12, m20 = midpoints of (b0,b1), (b1,b2), (b2,b0).
// bm0, bm1, bm2 = midpoints of (b0,t), (b1,t), (b2,t).
let (b0, b1, b2, t, m01, m12, m20, bm0, bm1, bm2);
let base_verts: Vec<VertexUnion> = {
let v0 = vertex(rt3/3.0, 0.0, 0.0);
let v1 = vertex(-rt3/6.0, -1.0/2.0, 0.0);
let v2 = vertex(-rt3/6.0, 1.0/2.0, 0.0);
let vt = vertex(0.0, 0.0, rt6/3.0);
vec_indexed![
@b0 VertexUnion::Vertex(v0),
@b1 VertexUnion::Vertex(v1),
@b2 VertexUnion::Vertex(v2),
@t VertexUnion::Vertex(vt),
@m01 VertexUnion::Vertex((v0+v1)/2.0),
@m12 VertexUnion::Vertex((v1+v2)/2.0),
@m20 VertexUnion::Vertex((v2+v0)/2.0),
@bm0 VertexUnion::Vertex((v0+vt)/2.0),
@bm1 VertexUnion::Vertex((v1+vt)/2.0),
@bm2 VertexUnion::Vertex((v2+vt)/2.0),
]
};
let test = rule_fn!(() => |_s, base_verts| {
let rt3 = (3.0).sqrt();
let (a0, a1, a2);
let next_verts: Vec<VertexUnion> = vec_indexed![
VertexUnion::Vertex(vertex( rt3/12.0, -1.0/4.0, 0.0)),
VertexUnion::Vertex(vertex( rt3/12.0, 1.0/4.0, 0.0)),
VertexUnion::Vertex(vertex(-rt3/6.0, 0.0, 0.0)),
@a0 VertexUnion::Arg(0),
@a1 VertexUnion::Arg(1),
@a2 VertexUnion::Arg(2),
// TODO: Why do I have index-out-of-range crashes if I move
// the ::Vertex(...) to the end?
];
// Mnemonics for args:
let b0 = 0; // Base
let b1 = 1; // Adjacent base
let t = 2; // 'Top'
let m01 = 3; // Midpoint between b0 & b1
let bm0 = 4; // Midpoint between b0 & t
let bm1 = 5; // Midpoint between b1 & t
RuleEval {
geom: Rc::new(MeshFunc {
verts: next_verts,
faces: vec![ a0, 0, 2, a1, 1, 0, a2, 2, 1, 0, 1, 2 ],
verts: vert_args(0..6),
faces: vec![
b0, m01, bm0,
b1, bm1, m01,
t, bm0, bm1,
m01, bm1, bm0, // middle
],
}),
final_geom: Rc::new(MeshFunc {
verts: vec![],
@@ -224,16 +240,137 @@ pub fn pyramid() -> Rule<()> {
RuleEval {
geom: Rc::new(MeshFunc {
verts: base_verts,
faces: vec![ 0, 1, 2 ],
faces: vec![
b0, m01, m20,
b1, m12, m01,
b2, m20, m12,
m12, m20, m01,
],
}),
final_geom: Rc::new(MeshFunc {
verts: vec![],
faces: vec![],
}),
children: vec![
child!(rule!(test, ()), base_to_side(0), 1, 0, 3),
child!(rule!(test, ()), base_to_side(1), 0, 2, 3),
child!(rule!(test, ()), base_to_side(2), 2, 1, 3),
child!(rule!(test, ()), base_to_side(0), b1, b0, t, m01, bm1, bm0),
child!(rule!(test, ()), base_to_side(1), b0, b2, t, m20, bm0, bm2),
child!(rule!(test, ()), base_to_side(2), b2, b1, t, m12, bm2, bm1),
],
}
});
Rule { eval: base, ctxt: () }
}
pub fn pyramid2() -> Rule<()> {
let rt3 = (3.0).sqrt();
let dz = 0.05;
// Indices:
// b+0,b+1,b+2 = base vertices
// t+0,t+1,t+2 = 'top' vertices above base
// bm01, bm12, bm20 = midpoints of (b0,b1), (b1,b2), (b2,b0).
// tm01, tm12, tm20 = midpoints of (t0,t1), (t1,t2), (t2,t0).
let (b, t, tm01, tm12, tm20);
let base_verts: Vec<VertexUnion> = {
let v0 = vertex(rt3/3.0, 0.0, 0.0);
let v1 = vertex(-rt3/6.0, 1.0/2.0, 0.0);
let v2 = vertex(-rt3/6.0, -1.0/2.0, 0.0);
let v0b = v0 + vertex(0.0, 0.0, dz);
let v1b = v1 + vertex(0.0, 0.0, dz);
let v2b = v2 + vertex(0.0, 0.0, dz);
vec_indexed![
@b VertexUnion::Vertex(v0),
VertexUnion::Vertex(v1),
VertexUnion::Vertex(v2),
@t VertexUnion::Vertex(v0b),
VertexUnion::Vertex(v1b),
VertexUnion::Vertex(v2b),
@tm01 VertexUnion::Vertex((v0b+v1b)/2.0),
@tm12 VertexUnion::Vertex((v1b+v2b)/2.0),
@tm20 VertexUnion::Vertex((v2b+v0b)/2.0),
]
};
let tri_split = move |i| {
let rt3 = (3.0).sqrt();
let angle = 2.0 * FRAC_PI_3 * (i as f32);
id().
rotate(&Vector3::z_axis(), angle).
translate(rt3/12.0, 0.0, 0.0).
scale(0.5).
translate(0.0, 0.0, dz)
};
let test = rule_fn!(() => |_s, base_verts| {
let mut next_verts = base_verts;
let (a0, a1) = next_verts.append_indexed(vert_args(0..3));
RuleEval {
geom: Rc::new(MeshFunc {
verts: next_verts,
faces: vec![
//a0, a0+1, a0+2,
// Outer:
tm01, a0+1, t+1,
tm01, t+0, a0+0,
tm01, a0+0, a0+1,
tm12, a0+2, t+2,
tm12, t+1, a0+1,
tm12, a0+1, a0+2,
tm20, a0+0, t+0,
tm20, t+2, a0+2,
tm20, a0+2, a0+0,
// Inner:
tm01, tm12, tm20,
// Bottom:
//b+2, b+1, b+0,
],
}),
final_geom: Rc::new(MeshFunc {
verts: vec![],
faces: vec![],
}),
children: vec![
child!(_s, tri_split(0), t+0, tm01, tm20),
child!(_s, tri_split(1), t+1, tm12, tm01),
child!(_s, tri_split(2), t+2, tm20, tm12),
],
}
});
let base = rule_fn!(() => |_s, base_verts| {
RuleEval {
geom: Rc::new(MeshFunc {
verts: base_verts,
faces: vec![
// Outer:
tm01, b+1, t+1,
tm01, t+0, b+0,
tm01, b+0, b+1,
tm12, b+2, t+2,
tm12, t+1, b+1,
tm12, b+1, b+2,
tm20, b+0, t+0,
tm20, t+2, b+2,
tm20, b+2, b+0,
// Inner:
tm01, tm12, tm20,
// Bottom:
b+2, b+1, b+0,
],
}),
final_geom: Rc::new(MeshFunc {
verts: vec![],
faces: vec![],
}),
children: vec![
child!(rule!(test, ()), tri_split(0), t+0, tm01, tm20),
child!(rule!(test, ()), tri_split(1), t+1, tm12, tm01),
child!(rule!(test, ()), tri_split(2), t+2, tm20, tm12),
],
}
});

View File

@@ -80,7 +80,7 @@ mod tests {
fn barbs_random() { run_test(examples::barbs(true), 80, "barbs_random", false); }
#[test]
fn pyramid() { run_test(examples::pyramid(), 3, "pyramid", false); }
fn pyramid() { run_test(examples::pyramid2(), 3, "pyramid2", false); }
/*
#[test]
fn twist() {

View File

@@ -85,7 +85,7 @@ pub struct Child<S> {
macro_rules! child {
( $Rule:expr, $Xform:expr, $( $Arg:expr ),* ) => {
Child {
rule: /*std::rc::Rc::new*/($Rule),
rule: /*std::rc::Rc::new*/($Rule).clone(),
xf: $Xform,
arg_vals: vec![$($Arg,)*],
}