Clean up some notes, try adding randomness to example

This commit is contained in:
Chris Hodapp 2020-05-16 13:20:13 -04:00
parent d868674b45
commit b17e4a1df6
3 changed files with 44 additions and 44 deletions

View File

@ -2,10 +2,8 @@
## Highest priority:
- Continue to refine the 'barbs' example, which broke some new ground.
- Implement the continuous parametric transformations from 2020-05-07
in my notes. This will require some new abstractions.
- Try some non-deterministic examples.
- Get identical or near-identical meshes to `ramhorn_branch` from
Python. (Should just be a matter of tweaking parameters.)
- Look at performance.
@ -26,17 +24,6 @@
## Important but less critical:
- Elegance & succinctness:
- Clean up `ramhorn_branch` because it's ugly.
- What patterns can I factor out? I do some things regularly, like:
the clockwise boundaries, the zigzag connections.
- Declarative macro to shorten this `Tag::Parent`, `Tag::Body`
nonsense - and perhaps force to groups of 3? Does this have any
value, though, over just making helper functions like `p(...)` and
`b(...)`?
- I'm near certain a declarative macros can simplify some bigger
things like my patterns with closures (e.g. the Y combinator like
method for recursive calls).
- Docs on modules
- Compute global scale factor, and perhaps pass it to a rule (to
eventually be used for, perhaps, adaptive subdivision). Note that
@ -54,7 +41,6 @@
## If I'm bored:
- Fix links in tri_mesh docs that use relative paths & do a PR?
- Look in https://www.nalgebra.org/quick_reference/# for "pour
obtain". Can I fix this somehow? Looks like a French-ism that made
its way in.
@ -70,26 +56,8 @@
## Research Areas
- When I have an iterated transform, that is basically transforming by
M, MM=M^2, MMM=M^3, ..., and it seems to me that I should be able to
compute its eigendecomposition and use this to compute fractional
powers of the matrix. Couldn't I then determine the continuous
function I'm approximating by taking the `d/di (M^i)V` - i.e. the
partial derivative of the result of transforming a vector `V` with
`M^i`? (See also:
https://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix#Functional_calculus
and my 2020-04-20 paper notes. My 2020-04-24 org notes have some
things too - this relates to dynamical systems and eigenvalues.)
Later note: I have a feeling I was dead wrong about a bunch of this.
## Reflections & Quick Notes
- My old Python version composed rules in the opposite order and I
think this made things more complicated. I didn't realize that I
did it differently in this code, but it became much easier -
particularly, more "inner" transformations are much easier to write
because all that matters is that they work properly in the
coordinate space they inherit.
- Generalizing to space curves moves this away from the "discrete
automata" roots, but it still ends up needing the machinery I made
for discrete automata.

View File

@ -49,7 +49,7 @@ pub fn cube_thing() -> Rule<()> {
}
*/
pub fn barbs() -> Rule<()> {
pub fn barbs(random: bool) -> Rule<()> {
let (b0, bn);
let base_verts: Vec<VertexUnion> = vec_indexed![
@ -60,9 +60,24 @@ pub fn barbs() -> Rule<()> {
@bn,
];
let barb_incr = id().translate(0.0, 0.0, 0.5).
rotate(&Vector3::y_axis(), -0.2).
scale(0.8);
let barb_incr = |random| {
if random {
let t = rand::thread_rng().gen_range(0.45, 0.55);
let s = rand::thread_rng().gen_range(0.7, 0.9);
let ry = rand::thread_rng().gen_range(-0.3, -0.1);
let rx = rand::thread_rng().gen_range(-0.04, 0.04);
let rz = rand::thread_rng().gen_range(-0.04, 0.04);
id().translate(0.0, 0.0, t).
rotate(&Vector3::y_axis(), ry).
rotate(&Vector3::x_axis(), rx).
rotate(&Vector3::z_axis(), rz).
scale(s)
} else {
id().translate(0.0, 0.0, 0.5).
rotate(&Vector3::y_axis(), -0.2).
scale(0.8)
}
};
let barb = rule_fn!(() => |self_, base_verts| {
let mut next_verts = base_verts;
@ -74,10 +89,12 @@ pub fn barbs() -> Rule<()> {
faces: vec![ 0, 2, 1, 0, 3, 2 ],
};
let b = barb_incr(random);
RuleEval {
geom: Rc::new(geom.transform(&barb_incr)),
geom: Rc::new(geom.transform(&b)),
final_geom: Rc::new(final_geom), // no transform needed (no vertices)
children: vec![ child_iter!(self_, barb_incr, b0..bn) ],
children: vec![ child_iter!(self_, b, b0..bn) ],
}
});
@ -86,10 +103,23 @@ pub fn barbs() -> Rule<()> {
rotate(&Vector3::y_axis(), -FRAC_PI_2).
translate(0.5, 0.0, 0.5)
};
let main_incr = id().translate(0.0, 0.0, 1.0).
rotate(&Vector3::z_axis(), 0.15).
rotate(&Vector3::x_axis(), 0.1).
scale(0.95);
let main_incr = |random| {
if random {
let t = rand::thread_rng().gen_range(0.75, 1.25);
let s = rand::thread_rng().gen_range(0.85, 1.10);
let rz = rand::thread_rng().gen_range(0.05, 0.25);
let rx = rand::thread_rng().gen_range(0.08, 0.12);
id().translate(0.0, 0.0, 1.0).
rotate(&Vector3::z_axis(), rz).
rotate(&Vector3::x_axis(), rx).
scale(s)
} else {
id().translate(0.0, 0.0, 1.0).
rotate(&Vector3::z_axis(), 0.15).
rotate(&Vector3::x_axis(), 0.1).
scale(0.95)
}
};
let main = rule_fn!(() => |self_, base_verts| {
let mut next_verts = base_verts;
@ -107,7 +137,7 @@ pub fn barbs() -> Rule<()> {
geom: Rc::new(geom),
final_geom: Rc::new(final_geom),
children: vec![
child_iter!(self_, main_incr, b0..bn),
child_iter!(self_, main_incr(random), b0..bn),
child!(rule!(barb, ()), main_barb_xf(0), b0 + 0, b0 + 1, a0 + 1, a0 + 0),
child!(rule!(barb, ()), main_barb_xf(1), b0 + 1, b0 + 2, a0 + 2, a0 + 1),
child!(rule!(barb, ()), main_barb_xf(2), b0 + 2, b0 + 3, a0 + 3, a0 + 2),

View File

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