Skip to content

Commit

Permalink
Add star model
Browse files Browse the repository at this point in the history
  • Loading branch information
hannobraun committed Jan 26, 2022
1 parent 718b8dd commit dc26d82
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
10 changes: 10 additions & 0 deletions models/star/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "star"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies.fj]
path = "../../fj"
10 changes: 10 additions & 0 deletions models/star/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Fornjot - Star

A model of a star that demonstrates sweeping a sketch to create a 3D shape, concave sketches, and how to generate sketches from code.

To display this model, run the following from the repository root (model parameters are optional):
``` sh
cargo run -- --model start --parameters num_points=5 r1=1.0 r2=2.0 h=1.0
```

![Screenshot of the star model](star.png)
67 changes: 67 additions & 0 deletions models/star/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::{collections::HashMap, f64::consts::PI};

#[no_mangle]
pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
// Number of points of the star
//
// "Points" in the sense of "pointy ends", not in the sense of geometrical
// points, or vertices.
let num_points: u64 = args
.get("num_points")
.map(|arg| arg.parse().unwrap())
.unwrap_or(5);

// Radius of the circle that all the vertices between the pointy ends are on
let r1: f64 = args
.get("r1")
.map(|arg| arg.parse().unwrap())
.unwrap_or(1.0);

// Radius of the circle that all the pointy ends are on
let r2: f64 = args
.get("r2")
.map(|arg| arg.parse().unwrap())
.unwrap_or(2.0);

// The height of the star
let h: f64 = args.get("h").map(|arg| arg.parse().unwrap()).unwrap_or(1.0);

// We need to figure out where to generate vertices, depending on the number
// of points the star is supposed to have. Let's generate an iterator that
// gives us the angle and radius for each vertex.
let num_vertices = num_points * 2;
let vertex_iter = (0..num_vertices).map(|i| {
let angle = 2. * PI / num_vertices as f64 * i as f64;
let radius = if i % 2 == 0 { r1 } else { r2 };
(angle, radius)
});

// Now that we got that iterator prepared, generating the vertices is just a
// bit of trigonometry.
let mut outer = Vec::new();
let mut inner = Vec::new();
for (angle, radius) in vertex_iter {
let (sin, cos) = angle.sin_cos();

let x = cos * radius;
let y = sin * radius;

outer.push([x, y]);
inner.push([x / 2., y / 2.]);
}

let outer = fj::Sketch::from_points(outer);
let inner = fj::Sketch::from_points(inner);

let footprint = fj::Difference2d {
a: outer.into(),
b: inner.into(),
};

let star = fj::Sweep {
shape: footprint.into(),
length: h,
};

star.into()
}
Binary file added models/star/star.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit dc26d82

Please sign in to comment.