Use circles in triangle as low-curvature construction
In the process, add a way to build a sphere by offset and curvature.
This commit is contained in:
parent
3493a798d1
commit
ab830b194e
@ -1,5 +1,6 @@
|
||||
use nalgebra::DVector;
|
||||
|
||||
// the sphere with the given center and radius, with inward-pointing normals
|
||||
pub fn sphere(center_x: f64, center_y: f64, center_z: f64, radius: f64) -> DVector<f64> {
|
||||
let center_norm_sq = center_x * center_x + center_y * center_y + center_z * center_z;
|
||||
DVector::from_column_slice(&[
|
||||
@ -9,4 +10,18 @@ pub fn sphere(center_x: f64, center_y: f64, center_z: f64, radius: f64) -> DVect
|
||||
0.5 / radius,
|
||||
0.5 * (center_norm_sq / radius - radius)
|
||||
])
|
||||
}
|
||||
|
||||
// the sphere of curvature `curv` whose closest point to the origin has position
|
||||
// `off * dir` and normal `dir`, where `dir` is a unit vector. setting the
|
||||
// curvature to zero gives a plane
|
||||
pub fn sphere_with_offset(dir_x: f64, dir_y: f64, dir_z: f64, off: f64, curv: f64) -> DVector<f64> {
|
||||
let norm_sp = 1.0 + off * curv;
|
||||
DVector::from_column_slice(&[
|
||||
norm_sp * dir_x,
|
||||
norm_sp * dir_y,
|
||||
norm_sp * dir_z,
|
||||
0.5 * curv,
|
||||
off * (1.0 + 0.5 * off * curv)
|
||||
])
|
||||
}
|
@ -10,7 +10,6 @@
|
||||
extern crate js_sys;
|
||||
use core::array;
|
||||
use nalgebra::{DMatrix, DVector};
|
||||
use std::f64::consts::FRAC_1_SQRT_2;
|
||||
use sycamore::{prelude::*, motion::create_raf, rt::{JsCast, JsValue}};
|
||||
use web_sys::{console, window, WebGl2RenderingContext, WebGlProgram, WebGlShader, WebGlUniformLocation};
|
||||
|
||||
@ -86,30 +85,59 @@ fn bind_vertex_attrib(
|
||||
|
||||
fn push_gen_construction(
|
||||
sphere_vec: &mut Vec<DVector<f64>>,
|
||||
color_vec: &mut Vec<[f32; 3]>,
|
||||
construction_to_world: &DMatrix<f64>,
|
||||
ctrl_x: f64,
|
||||
ctrl_y: f64,
|
||||
radius_x: f64,
|
||||
radius_y: f64
|
||||
) {
|
||||
// push spheres
|
||||
sphere_vec.push(construction_to_world * engine::sphere(0.5, 0.5, ctrl_x, radius_x));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(-0.5, -0.5, ctrl_y, radius_y));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(-0.5, 0.5, 0.0, 0.75));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(0.5, -0.5, 0.0, 0.5));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(0.0, 0.15, 1.0, 0.25));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(0.0, -0.15, -1.0, 0.25));
|
||||
|
||||
// push colors
|
||||
color_vec.push([1.00_f32, 0.25_f32, 0.00_f32]);
|
||||
color_vec.push([0.00_f32, 0.25_f32, 1.00_f32]);
|
||||
color_vec.push([0.25_f32, 0.00_f32, 1.00_f32]);
|
||||
color_vec.push([0.25_f32, 1.00_f32, 0.00_f32]);
|
||||
color_vec.push([0.75_f32, 0.75_f32, 0.00_f32]);
|
||||
color_vec.push([0.00_f32, 0.75_f32, 0.50_f32]);
|
||||
}
|
||||
|
||||
fn push_low_curv_construction(
|
||||
sphere_vec: &mut Vec<DVector<f64>>,
|
||||
color_vec: &mut Vec<[f32; 3]>,
|
||||
construction_to_world: &DMatrix<f64>,
|
||||
curv_x: f64,
|
||||
curv_y: f64
|
||||
off1: f64,
|
||||
off2: f64,
|
||||
off3: f64,
|
||||
curv1: f64,
|
||||
curv2: f64,
|
||||
curv3: f64,
|
||||
) {
|
||||
sphere_vec.push(construction_to_world * DVector::from_column_slice(&[0.0, -1.0, 0.0, 0.5*curv_x, 0.0]));
|
||||
sphere_vec.push(construction_to_world * DVector::from_column_slice(&[-FRAC_1_SQRT_2, 0.0, -FRAC_1_SQRT_2, 0.5*curv_y, 0.0]));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(0.5, 0.0, 0.5, FRAC_1_SQRT_2));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(-0.5, 0.0, -0.5, FRAC_1_SQRT_2));
|
||||
// push spheres
|
||||
let a = 0.75_f64.sqrt();
|
||||
sphere_vec.push(construction_to_world * engine::sphere(0.0, 0.0, 0.0, 1.0));
|
||||
sphere_vec.push(construction_to_world * engine::sphere_with_offset(1.0, 0.0, 0.0, off1, curv1));
|
||||
sphere_vec.push(construction_to_world * engine::sphere_with_offset(-0.5, a, 0.0, off2, curv2));
|
||||
sphere_vec.push(construction_to_world * engine::sphere_with_offset(-0.5, -a, 0.0, off3, curv3));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(-4.0/3.0, 0.0, 0.0, 1.0/3.0));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(2.0/3.0, -4.0/3.0 * a, 0.0, 1.0/3.0));
|
||||
sphere_vec.push(construction_to_world * engine::sphere(2.0/3.0, 4.0/3.0 * a, 0.0, 1.0/3.0));
|
||||
|
||||
// push colors
|
||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
||||
color_vec.push([1.00_f32, 0.00_f32, 0.25_f32]);
|
||||
color_vec.push([0.25_f32, 1.00_f32, 0.00_f32]);
|
||||
color_vec.push([0.00_f32, 0.25_f32, 1.00_f32]);
|
||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
||||
color_vec.push([0.75_f32, 0.75_f32, 0.75_f32]);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
@ -136,8 +164,12 @@ fn main() {
|
||||
|
||||
// controls for low-curvature example
|
||||
let low_curv_controls = create_node_ref();
|
||||
let curv_x = create_signal(0.0);
|
||||
let curv_y = create_signal(0.0);
|
||||
let curv1 = create_signal(0.0);
|
||||
let curv2 = create_signal(0.0);
|
||||
let curv3 = create_signal(0.0);
|
||||
let off1 = create_signal(1.0);
|
||||
let off2 = create_signal(1.0);
|
||||
let off3 = create_signal(1.0);
|
||||
|
||||
// shared controls
|
||||
let opacity = create_signal(0.5);
|
||||
@ -168,8 +200,12 @@ fn main() {
|
||||
radius_y.track();
|
||||
|
||||
// track controls for low-curvature example
|
||||
curv_x.track();
|
||||
curv_y.track();
|
||||
curv1.track();
|
||||
curv2.track();
|
||||
curv3.track();
|
||||
off1.track();
|
||||
off2.track();
|
||||
off3.track();
|
||||
|
||||
// track shared controls
|
||||
opacity.track();
|
||||
@ -199,17 +235,10 @@ fn main() {
|
||||
}
|
||||
});
|
||||
|
||||
// list construction elements
|
||||
// create list of construction elements
|
||||
const SPHERE_MAX: usize = 200;
|
||||
let mut sphere_vec = Vec::<DVector<f64>>::new();
|
||||
let color_vec = vec![
|
||||
[1.00_f32, 0.25_f32, 0.00_f32],
|
||||
[0.00_f32, 0.25_f32, 1.00_f32],
|
||||
[0.25_f32, 0.00_f32, 1.00_f32],
|
||||
[0.25_f32, 1.00_f32, 0.00_f32],
|
||||
[0.75_f32, 0.75_f32, 0.00_f32],
|
||||
[0.00_f32, 0.75_f32, 0.50_f32],
|
||||
];
|
||||
let mut color_vec = Vec::<[f32; 3]>::new();
|
||||
|
||||
// timing
|
||||
let mut last_time = 0.0;
|
||||
@ -365,17 +394,21 @@ fn main() {
|
||||
|
||||
// update the construction
|
||||
sphere_vec.clear();
|
||||
color_vec.clear();
|
||||
match tab_selection.get() {
|
||||
Tab::GenTab => push_gen_construction(
|
||||
&mut sphere_vec,
|
||||
&mut color_vec,
|
||||
&construction_to_world,
|
||||
ctrl_x.get(), ctrl_y.get(),
|
||||
radius_x.get(), radius_y.get()
|
||||
),
|
||||
Tab::LowCurvTab => push_low_curv_construction(
|
||||
&mut sphere_vec,
|
||||
&mut color_vec,
|
||||
&construction_to_world,
|
||||
curv_x.get(), curv_y.get()
|
||||
off1.get(), off2.get(), off3.get(),
|
||||
curv1.get(), curv2.get(), curv3.get(),
|
||||
)
|
||||
};
|
||||
|
||||
@ -496,25 +529,69 @@ fn main() {
|
||||
}
|
||||
div(ref=low_curv_controls) {
|
||||
div(class="control") {
|
||||
label(for="curv-x") { "Sphere 0 curvature" }
|
||||
label(for="off-1") { "Sphere 1 offset" }
|
||||
input(
|
||||
type="range",
|
||||
id="curv-x",
|
||||
min=0.0,
|
||||
max=2.0,
|
||||
id="off-1",
|
||||
min=-1.0,
|
||||
max=1.0,
|
||||
step=0.001,
|
||||
bind:valueAsNumber=curv_x
|
||||
bind:valueAsNumber=off1
|
||||
)
|
||||
}
|
||||
div(class="control") {
|
||||
label(for="curv-y") { "Sphere 1 curvature" }
|
||||
label(for="off-2") { "Sphere 2 offset" }
|
||||
input(
|
||||
type="range",
|
||||
id="curv-y",
|
||||
id="off-2",
|
||||
min=-1.0,
|
||||
max=1.0,
|
||||
step=0.001,
|
||||
bind:valueAsNumber=off2
|
||||
)
|
||||
}
|
||||
div(class="control") {
|
||||
label(for="off-3") { "Sphere 3 offset" }
|
||||
input(
|
||||
type="range",
|
||||
id="off-3",
|
||||
min=-1.0,
|
||||
max=1.0,
|
||||
step=0.001,
|
||||
bind:valueAsNumber=off3
|
||||
)
|
||||
}
|
||||
div(class="control") {
|
||||
label(for="curv-1") { "Sphere 1 curvature" }
|
||||
input(
|
||||
type="range",
|
||||
id="curv-1",
|
||||
min=0.0,
|
||||
max=2.0,
|
||||
step=0.001,
|
||||
bind:valueAsNumber=curv_y
|
||||
bind:valueAsNumber=curv1
|
||||
)
|
||||
}
|
||||
div(class="control") {
|
||||
label(for="curv-2") { "Sphere 2 curvature" }
|
||||
input(
|
||||
type="range",
|
||||
id="curv-2",
|
||||
min=0.0,
|
||||
max=2.0,
|
||||
step=0.001,
|
||||
bind:valueAsNumber=curv2
|
||||
)
|
||||
}
|
||||
div(class="control") {
|
||||
label(for="curv-3") { "Sphere 3 curvature" }
|
||||
input(
|
||||
type="range",
|
||||
id="curv-3",
|
||||
min=0.0,
|
||||
max=2.0,
|
||||
step=0.001,
|
||||
bind:valueAsNumber=curv3
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user