Skip to content

Commit

Permalink
fix chain
Browse files Browse the repository at this point in the history
  • Loading branch information
Agapanthus committed Mar 7, 2024
1 parent c424c56 commit e5bbf1a
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 238 deletions.
8 changes: 4 additions & 4 deletions editor/src/main.rs
Expand Up @@ -129,7 +129,7 @@ fn make_2d_shape(_settings: &MeshSettings) -> MeshVec3 {
Vec3::new(-2.0, 0.0, 2.0),
];*/

/*let mut p = [
let mut p = [
// e1
Vec3::new(-2.0, 0.0, -2.0),
Vec3::new(-1.0, 0.0, -1.0),
Expand All @@ -147,9 +147,9 @@ fn make_2d_shape(_settings: &MeshSettings) -> MeshVec3 {
// e4
Vec3::new(-2.0, 0.0, 2.0),
];
*/


let mut p = [
/*let mut p = [
Vec3::new(-2.0, 0.0, -2.0),
Vec3::new(-1.0, 0.0, -0.5),
Vec3::new(1.0, 0.0, 0.0),
Expand All @@ -160,7 +160,7 @@ fn make_2d_shape(_settings: &MeshSettings) -> MeshVec3 {
Vec3::new(-4.0, 0.0, 0.0),
Vec3::new(-2.1, 0.0, -0.2),
];
];*/
p.reverse();

let mut mesh = MeshVec3::polygon(&p);
Expand Down
184 changes: 184 additions & 0 deletions src/representation/face/tesselate/sweep/chain.rs
@@ -0,0 +1,184 @@
use super::point::IndexedVertexPoint;
use crate::{
math::{Scalar, Vector2D},
representation::{payload::Payload, IndexType, Mesh},
};
use std::collections::HashMap;

#[derive(Debug, Clone, PartialEq, Eq)]
enum SweepReflexChainDirection {
/// The reflex chain is completely on the left
Left,
/// The reflex chain is completely on the right
Right,
/// The reflex chain consists of the first single item having no preference for a side or is empty
None,
}

/// This structure stores the reflex chain of the untriangulated region above.
/// See https://www.cs.umd.edu/class/spring2020/cmsc754/Lects/lect05-triangulate.pdf
/// It preserves the following invariant:
/// for i>=2, let v_i be the triangle just processed by the algorithm. The untriangulated
/// region to the top of v_i consist of two y-monotone chains, a left and a right chain each containing
/// at least one edge. Only one of the two chains contains more than one edge. The chain with the single
/// edge has its bottom endpoint below the sweep line. Hence, we place the start vertex before the other
/// chain. The currently active chain is indicated by d.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SweepReflexChain<V: IndexType> {
stack: Vec<V>,
d: SweepReflexChainDirection,
}

impl<V: IndexType> SweepReflexChain<V> {
pub fn new() -> Self {
SweepReflexChain {
stack: Vec::new(),
d: SweepReflexChainDirection::None,
}
}

pub fn first(v: V) -> Self {
SweepReflexChain {
stack: vec![v],
d: SweepReflexChainDirection::None,
}
}

/// Add a new value to the left reflex chain
pub fn left<P: Payload>(
&mut self,
value: V,
indices: &mut Vec<V>,
vec2s: &HashMap<V, IndexedVertexPoint<V, P::Vec2, P::S>>,
) -> Self {
println!("left: {:?} {} {:?}", self.d, value, self.stack);
match self.d {
SweepReflexChainDirection::None => {
assert!(self.stack.len() <= 1);
self.stack.push(value);
self.d = SweepReflexChainDirection::Left;
}
SweepReflexChainDirection::Left => {
assert!(self.stack.len() >= 1);

// draw triangles while they are visible
loop {
let l = self.stack.len();
if l <= 1 {
break;
}
let angle = vec2s[&value]
.vec
.angle(vec2s[&self.stack[l - 1]].vec, vec2s[&self.stack[l - 2]].vec);
if angle > P::S::ZERO {
break;
}
println!(
"create vis l: {:?}",
[self.stack[l - 1], self.stack[l - 2], value]
);
indices.extend([self.stack[l - 1], value, self.stack[l - 2]]);
self.stack.pop();
}

// remember on more for the same direction
self.stack.push(value);
}
SweepReflexChainDirection::Right => {
assert!(self.stack.len() >= 1);
// place the next triangle!
if self.stack.len() == 1 {
self.stack.push(value);
self.d = SweepReflexChainDirection::Left;
} else {
// there is enough on the stack to consume
for i in 1..self.stack.len() {
indices.extend([self.stack[i - 1], value, self.stack[i]]);
println!(
"create mul l: {:?}",
[self.stack[i - 1], self.stack[i], value]
);
}
let last = self.stack.pop().unwrap();
self.stack.clear();
self.stack.push(last);
self.stack.push(value);
self.d = SweepReflexChainDirection::Left;
}
}
}
self.clone()
}

/// Add a new value to the right reflex chain
pub fn right<P: Payload>(
&mut self,
value: V,
indices: &mut Vec<V>,
vec2s: &HashMap<V, IndexedVertexPoint<V, P::Vec2, P::S>>,
) -> Self {
println!("right: {:?} {} {:?}", self.d, value, self.stack);
match self.d {
SweepReflexChainDirection::None => {
assert!(self.stack.len() <= 1);
self.stack.push(value);
self.d = SweepReflexChainDirection::Right;
}
SweepReflexChainDirection::Right => {
assert!(self.stack.len() >= 1);

// draw triangles while they are visible
loop {
let l = self.stack.len();
if l <= 1 {
break;
}
let angle = vec2s[&value]
.vec
.angle(vec2s[&self.stack[l - 1]].vec, vec2s[&self.stack[l - 2]].vec);
if angle < P::S::ZERO {
break;
}
println!(
"create vis r: {:?}",
[self.stack[l - 1], self.stack[l - 2], value]
);
indices.extend([self.stack[l - 1], self.stack[l - 2], value]);
self.stack.pop();
}

// remember on more for the same direction
self.stack.push(value);
}
SweepReflexChainDirection::Left => {
assert!(self.stack.len() >= 1);
// place the next triangle!
if self.stack.len() == 1 {
self.stack.push(value);
self.d = SweepReflexChainDirection::Right;
} else {
// there is enough on the stack to consume
for i in 1..self.stack.len() {
indices.extend([self.stack[i - 1], self.stack[i], value]);
println!(
"create mul r: {:?}",
[self.stack[i - 1], self.stack[i], value]
);
}
let last = self.stack.pop().unwrap();
self.stack.clear();
self.stack.push(last);
self.stack.push(value);
self.d = SweepReflexChainDirection::Right;
}
}
}
self.clone()
}

pub fn is_done(&self) -> bool {
self.stack.len() <= 2
//&& self.d != SweepReflexChainDirection::Left
// && self.d != SweepReflexChainDirection::Right
}
}
6 changes: 4 additions & 2 deletions src/representation/face/tesselate/sweep/mod.rs
@@ -1,12 +1,14 @@
use super::{Face, Mesh, Payload};
use crate::{
math::{Scalar, Vector, Vector2D, Vector3D},
representation::{tesselate::sweep::status::SweepReflexChain, IndexType},
representation::IndexType,
};
use itertools::Itertools;
use std::collections::{BinaryHeap, HashMap};
mod chain;
mod point;
mod status;
use chain::SweepReflexChain;
mod vertex_type;
use point::{EventPoint, IndexedVertexPoint};
use status::{EdgeData, IntervalData, SweepLineStatus};
Expand Down Expand Up @@ -163,7 +165,7 @@ where
});

if event.here.index == V::new(3) {
break;
// break;
}
}
VertexType::End => {
Expand Down

0 comments on commit e5bbf1a

Please sign in to comment.