Skip to content

Commit

Permalink
Update intersection
Browse files Browse the repository at this point in the history
  • Loading branch information
v4nn4 committed Apr 9, 2024
1 parent 6cbebc2 commit adec876
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 48 deletions.
30 changes: 0 additions & 30 deletions examples/hello.rs

This file was deleted.

1 change: 0 additions & 1 deletion examples/parameters_9ap.json

This file was deleted.

9 changes: 3 additions & 6 deletions src/generate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::glyph::Glyph;
use crate::glyph::InternalGlyph;
use crate::intersect::are_strokes_linked;
use crate::parameters::Parameters;
use crate::stroke::InternalStroke;
use crate::stroke::Stroke;
Expand All @@ -15,12 +16,8 @@ impl GlyphGenerator {
}

pub fn are_strokes_intersecting(&self, glyph: &InternalGlyph) -> bool {
glyph.strokes.iter().all(|stroke| {
glyph.strokes.iter().any(|other| {
stroke.index != other.index
&& self.parameters.intersection_matrix[stroke.index][other.index] == 1
})
})
let indices: Vec<usize> = glyph.strokes.iter().map(|stroke| stroke.index).collect();
return are_strokes_linked(&indices, &self.parameters.intersection_matrix);
}

pub fn transform(&self, glyph: &InternalGlyph) -> Vec<InternalGlyph> {
Expand Down
81 changes: 81 additions & 0 deletions src/intersect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use std::collections::HashSet;

fn dfs(node: usize, visited: &mut HashSet<usize>, subgraph: &Vec<Vec<u8>>) {
visited.insert(node);
for (neighbor, &is_connected) in subgraph[node].iter().enumerate() {
if is_connected == 1 && !visited.contains(&neighbor) {
dfs(neighbor, visited, subgraph);
}
}
}

pub fn are_strokes_linked(strokes: &Vec<usize>, intersection_matrix: &Vec<Vec<u8>>) -> bool {
if strokes.is_empty() {
return false;
}

// Create a subgraph for only the strokes of interest
let mut subgraph: Vec<Vec<u8>> = vec![vec![0; strokes.len()]; strokes.len()];
for (i, &stroke1) in strokes.iter().enumerate() {
for (j, &stroke2) in strokes.iter().enumerate() {
subgraph[i][j] = intersection_matrix[stroke1][stroke2];
}
}

let mut visited: HashSet<usize> = HashSet::new();
dfs(0, &mut visited, &subgraph);

visited.len() == strokes.len()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_are_strokes_linked_single() {
assert!(are_strokes_linked(&vec![0], &vec![vec![1]]));
}

#[test]
fn test_are_strokes_linked_pair_connected() {
assert!(are_strokes_linked(
&vec![0, 1],
&vec![vec![1, 1], vec![1, 1]]
));
}

#[test]
fn test_are_strokes_linked_pair_disconnected() {
assert!(!are_strokes_linked(
&vec![0, 1],
&vec![vec![1, 0], vec![0, 1]]
));
}

#[test]
fn test_are_strokes_linked_group_disconnected() {
assert!(!are_strokes_linked(
&vec![0, 1, 2, 3],
&vec![
vec![1, 1, 0, 0],
vec![1, 1, 0, 0],
vec![0, 0, 1, 1],
vec![0, 0, 1, 1],
]
));
}

#[test]
fn test_are_strokes_linked_specific_case() {
assert!(!are_strokes_linked(
&vec![0, 3],
&vec![
vec![1, 1, 1, 0],
vec![1, 1, 0, 1],
vec![1, 0, 1, 1],
vec![0, 1, 1, 1],
]
));
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod generate;
mod glyph;
mod intersect;
mod parameters;
mod stroke;

Expand Down
28 changes: 18 additions & 10 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,31 @@ mod tests {
use crate::parameters::Parameters;
use crate::stroke::InternalStroke;
use crate::stroke::Stroke;
use std::fs;

use relative_path::RelativePath;

struct TestContext {
basic: GlyphGenerator,
advanced: GlyphGenerator,
}

fn load_parameters(parameter_file: &str) -> Parameters {
let tests_dir = RelativePath::new("tests");
let parameters_path = tests_dir.join(parameter_file).to_string();
let parameters_json = fs::read_to_string(parameters_path)
.expect("Failed to read parameters file")
.to_string();
let parameters: Parameters =
serde_json::from_str(&parameters_json).expect("Error deserializing parameters JSON");
return parameters;
}

fn setup() -> TestContext {
let parameters_4ap_str = "{\"parent_strokes\":[{\"x0\":-1.0,\"y0\":-1.0,\"x1\":-1.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":-1.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":1.0,\"y1\":-1.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":1.0,\"y1\":1.0},{\"x0\":1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":1.0}],\"intersection_matrix\":[[1,1,1,1,1,0],[1,1,1,1,0,1],[1,1,1,1,1,1],[1,1,1,1,1,1],[1,0,1,1,1,1],[0,1,1,1,1,1]],\"transformation_matrix\":[[0,5,4,1,4,5,1],[4,1,0,0,5,4,5],[3,3,3,2,2,2,3],[2,2,2,3,3,3,2],[1,4,5,5,0,1,0],[5,0,1,4,1,0,4]]}";
let parameters_9ap_str = "{\"parent_strokes\":[{\"x0\":-1.0,\"y0\":-1.0,\"x1\":-1.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":-1.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":0.0,\"y1\":0.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":-1.0,\"y1\":0.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":0.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":0.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":-1.0,\"x1\":0.0,\"y1\":-1.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":1.0,\"y1\":-1.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":1.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":0.0,\"y1\":0.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":-1.0,\"y1\":0.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":1.0,\"y1\":0.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":0.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":1.0,\"x1\":0.0,\"y1\":-1.0},{\"x0\":1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":1.0},{\"x0\":1.0,\"y0\":-1.0,\"x1\":0.0,\"y1\":0.0},{\"x0\":1.0,\"y0\":-1.0,\"x1\":-1.0,\"y1\":0.0},{\"x0\":1.0,\"y0\":-1.0,\"x1\":1.0,\"y1\":0.0},{\"x0\":1.0,\"y0\":-1.0,\"x1\":0.0,\"y1\":1.0},{\"x0\":1.0,\"y0\":-1.0,\"x1\":0.0,\"y1\":-1.0},{\"x0\":1.0,\"y0\":1.0,\"x1\":0.0,\"y1\":0.0},{\"x0\":1.0,\"y0\":1.0,\"x1\":-1.0,\"y1\":0.0},{\"x0\":1.0,\"y0\":1.0,\"x1\":1.0,\"y1\":0.0},{\"x0\":1.0,\"y0\":1.0,\"x1\":0.0,\"y1\":1.0},{\"x0\":1.0,\"y0\":1.0,\"x1\":0.0,\"y1\":-1.0},{\"x0\":0.0,\"y0\":0.0,\"x1\":-1.0,\"y1\":0.0},{\"x0\":0.0,\"y0\":0.0,\"x1\":1.0,\"y1\":0.0},{\"x0\":0.0,\"y0\":0.0,\"x1\":0.0,\"y1\":1.0},{\"x0\":0.0,\"y0\":0.0,\"x1\":0.0,\"y1\":-1.0},{\"x0\":-1.0,\"y0\":0.0,\"x1\":1.0,\"y1\":0.0},{\"x0\":-1.0,\"y0\":0.0,\"x1\":0.0,\"y1\":1.0},{\"x0\":-1.0,\"y0\":0.0,\"x1\":0.0,\"y1\":-1.0},{\"x0\":1.0,\"y0\":0.0,\"x1\":0.0,\"y1\":1.0},{\"x0\":1.0,\"y0\":0.0,\"x1\":0.0,\"y1\":-1.0},{\"x0\":0.0,\"y0\":1.0,\"x1\":0.0,\"y1\":-1.0}],\"intersection_matrix\":[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,1,0,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,1,0,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1],[1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,1,0,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1],[1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0],[1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,1,1,0,1,1,1,1,1],[1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1],[1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1],[0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],[0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],[1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1],[1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1],[1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1],[1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1],[1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1],[0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1]],\"transformation_matrix\":[[0,15,9,1,9,15,1],[9,1,0,0,15,9,15],[8,8,8,2,2,2,8],[10,16,10,3,21,21,16],[11,18,13,7,24,23,20],[12,17,14,6,25,22,19],[14,19,12,5,22,25,17],[13,20,11,4,23,24,18],[2,2,2,8,8,8,2],[1,9,15,15,0,1,0],[3,21,21,16,10,16,3],[4,23,24,20,13,18,7],[5,22,25,19,14,17,6],[7,24,23,18,11,20,4],[6,25,22,17,12,19,5],[15,0,1,9,1,0,9],[21,3,3,10,16,10,21],[22,5,6,14,19,12,25],[23,4,7,13,20,11,24],[25,6,5,12,17,14,22],[24,7,4,11,18,13,23],[16,10,16,21,3,3,10],[17,12,19,25,6,5,14],[18,11,20,24,7,4,13],[20,13,18,23,4,7,11],[19,14,17,22,5,6,12],[26,27,28,29,28,27,29],[27,26,29,28,29,26,28],[29,28,27,27,26,29,26],[28,29,26,26,27,28,27],[30,30,35,35,35,30,35],[32,33,33,34,31,34,32],[31,34,31,32,33,33,34],[34,31,34,33,32,32,31],[33,32,32,31,34,31,33],[35,35,30,30,30,35,30]]}";
let parameters_4ap: Parameters =
serde_json::from_str(&parameters_4ap_str).expect("Could not load JSON");
let parameters_9ap: Parameters =
serde_json::from_str(&parameters_9ap_str).expect("Could not load JSON");
TestContext {
basic: GlyphGenerator::new(parameters_4ap),
advanced: GlyphGenerator::new(parameters_9ap),
}
return TestContext {
basic: GlyphGenerator::new(load_parameters("parameters_4ap.json")),
advanced: GlyphGenerator::new(load_parameters("parameters_9ap.json")),
};
}

fn from_glyph(generator: &GlyphGenerator, glyph: &Glyph) -> InternalGlyph {
Expand Down
File renamed without changes.
28 changes: 28 additions & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#[cfg(test)]
mod tests {
use glyphs_generator::{compute, initialize};
use std::fs;

use relative_path::RelativePath;

fn setup() {
let tests_dir = RelativePath::new("tests");
let parameters_path = tests_dir.join("parameters_9ap.json").to_string();
let parameters_json = fs::read_to_string(parameters_path)
.expect("Failed to read parameters file")
.to_string();
initialize(parameters_json);
}

#[test]
fn test_computable_example() {
setup();
let tests_dir = RelativePath::new("tests");
let computable_path = tests_dir.join("computable.json").to_string();
let computable_json = fs::read_to_string(computable_path)
.expect("Failed to read computable file")
.to_string();
let result = compute(computable_json);
assert!(result.is_ok());
}
}
2 changes: 1 addition & 1 deletion examples/parameters_4ap.json → tests/parameters_4ap.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"parent_strokes":[{"x0":-1.0,"y0":-1.0,"x1":-1.0,"y1":1.0},{"x0":-1.0,"y0":-1.0,"x1":1.0,"y1":-1.0},{"x0":-1.0,"y0":-1.0,"x1":1.0,"y1":1.0},{"x0":-1.0,"y0":1.0,"x1":1.0,"y1":-1.0},{"x0":-1.0,"y0":1.0,"x1":1.0,"y1":1.0},{"x0":1.0,"y0":-1.0,"x1":1.0,"y1":1.0}],"intersection_matrix":[[1,1,1,1,1,0],[1,1,1,1,0,1],[1,1,1,1,1,1],[1,1,1,1,1,1],[1,0,1,1,1,1],[0,1,1,1,1,1]],"transformation_matrix":[[0,5,4,1,4,5,1],[4,1,0,0,5,4,5],[3,3,3,2,2,2,3],[2,2,2,3,3,3,2],[1,4,5,5,0,1,0],[5,0,1,4,1,0,4]]}
{"parent_strokes":[{"x0":-1.0,"y0":-1.0,"x1":-1.0,"y1":1.0},{"x0":-1.0,"y0":-1.0,"x1":1.0,"y1":-1.0},{"x0":-1.0,"y0":-1.0,"x1":1.0,"y1":1.0},{"x0":-1.0,"y0":1.0,"x1":1.0,"y1":-1.0},{"x0":-1.0,"y0":1.0,"x1":1.0,"y1":1.0},{"x0":1.0,"y0":-1.0,"x1":1.0,"y1":1.0}],"intersection_matrix":[[0,1,1,1,1,0],[1,0,1,1,0,1],[1,1,0,1,1,1],[1,1,1,0,1,1],[1,0,1,1,0,1],[0,1,1,1,1,0]],"transformation_matrix":[[0,5,4,1,4,5,1],[4,1,0,0,5,4,5],[3,3,3,2,2,2,3],[2,2,2,3,3,3,2],[1,4,5,5,0,1,0],[5,0,1,4,1,0,4]]}
Loading

0 comments on commit adec876

Please sign in to comment.