Download rust/crates/hyperkitty-art/src/scene_graph.rs from Snapkitty/hyperkitty-constraint-dsl: direct link, hf CLI and curl.
- Browser
- Download file 6.79 kB
-
https://huggingface.co/Snapkitty/hyperkitty-constraint-dsl/resolve/main/rust/crates/hyperkitty-art/src/scene_graph.rs
- Command line
-
hf download hf://Snapkitty/hyperkitty-constraint-dsl/rust/crates/hyperkitty-art/src/scene_graph.rs
-
curl -L -o scene_graph.rs https://huggingface.co/Snapkitty/hyperkitty-constraint-dsl/resolve/main/rust/crates/hyperkitty-art/src/scene_graph.rs
6.79 kB
| //! Scene Graph - Intermediate representation for rendering | |
| use crate::theorem_ast::{TheoremAst, TheoremKind}; | |
| use serde::{Deserialize, Serialize}; | |
| pub struct Color { | |
| pub r: u8, | |
| pub g: u8, | |
| pub b: u8, | |
| pub a: u8, | |
| } | |
| impl Color { | |
| pub fn rgb(r: u8, g: u8, b: u8) -> Self { | |
| Self { r, g, b, a: 255 } | |
| } | |
| pub fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self { | |
| Self { r, g, b, a } | |
| } | |
| pub fn theorem_color(kind: &TheoremKind) -> Self { | |
| match kind { | |
| TheoremKind::QLGSphere => Self::rgb(70, 130, 180), // Steel blue | |
| TheoremKind::SLABalance => Self::rgb(34, 139, 34), // Forest green | |
| TheoremKind::QRAIdentity => Self::rgb(220, 20, 60), // Crimson | |
| TheoremKind::QRAAbsorber => Self::rgb(139, 69, 19), // Saddle brown | |
| TheoremKind::WitnessExhaustion => Self::rgb(255, 165, 0), // Orange | |
| TheoremKind::TripartiteIso => Self::rgb(128, 0, 128), // Purple | |
| TheoremKind::JordanCommutativity => Self::rgb(0, 128, 128), // Teal | |
| TheoremKind::NANDCompleteness => Self::rgb(255, 20, 147), // Deep pink | |
| TheoremKind::Custom(_) => Self::rgb(128, 128, 128), // Gray | |
| } | |
| } | |
| } | |
| pub struct Transform { | |
| pub x: f64, | |
| pub y: f64, | |
| pub z: f64, | |
| pub scale: f64, | |
| pub rotation: f64, | |
| } | |
| impl Transform { | |
| pub fn identity() -> Self { | |
| Self { | |
| x: 0.0, | |
| y: 0.0, | |
| z: 0.0, | |
| scale: 1.0, | |
| rotation: 0.0, | |
| } | |
| } | |
| pub fn translated(x: f64, y: f64) -> Self { | |
| Self { | |
| x, | |
| y, | |
| z: 0.0, | |
| scale: 1.0, | |
| rotation: 0.0, | |
| } | |
| } | |
| } | |
| pub enum NodeGeometry { | |
| Sphere { radius: f64 }, | |
| Cube { size: f64 }, | |
| Plane { width: f64, height: f64 }, | |
| Point { radius: f64 }, | |
| Line { x1: f64, y1: f64, x2: f64, y2: f64 }, | |
| Text { content: String, font_size: f64 }, | |
| Group, | |
| } | |
| pub struct Node { | |
| pub id: String, | |
| pub geometry: NodeGeometry, | |
| pub transform: Transform, | |
| pub color: Color, | |
| pub children: Vec<Node>, | |
| pub label: Option<String>, | |
| } | |
| pub struct SceneGraph { | |
| pub name: String, | |
| pub root: Node, | |
| pub bounds: (f64, f64, f64, f64), // (x_min, y_min, x_max, y_max) | |
| } | |
| impl SceneGraph { | |
| pub fn new(name: String) -> Self { | |
| Self { | |
| name, | |
| root: Node { | |
| id: "root".to_string(), | |
| geometry: NodeGeometry::Group, | |
| transform: Transform::identity(), | |
| color: Color::rgb(255, 255, 255), | |
| children: vec![], | |
| label: None, | |
| }, | |
| bounds: (0.0, 0.0, 100.0, 100.0), | |
| } | |
| } | |
| pub fn from_theorem(theorem: &TheoremAst) -> Self { | |
| match theorem.kind { | |
| TheoremKind::QLGSphere => Self::qlg_sphere_scene(), | |
| TheoremKind::SLABalance => Self::sla_balance_scene(), | |
| TheoremKind::WitnessExhaustion => Self::witness_exhaustion_scene(), | |
| TheoremKind::NANDCompleteness => Self::nand_completeness_scene(), | |
| _ => Self::generic_theorem_scene(&theorem.name), | |
| } | |
| } | |
| fn qlg_sphere_scene() -> Self { | |
| let mut scene = Self::new("QLG Sphere".to_string()); | |
| scene.root.geometry = NodeGeometry::Sphere { radius: 50.0 }; | |
| scene.root.color = Color::theorem_color(&TheoremKind::QLGSphere); | |
| scene.root.label = Some("x² + y² + z² = 1".to_string()); | |
| scene.bounds = (-60.0, -60.0, 60.0, 60.0); | |
| scene | |
| } | |
| fn sla_balance_scene() -> Self { | |
| let mut scene = Self::new("SLA Balance".to_string()); | |
| let debit = Node { | |
| id: "debit".to_string(), | |
| geometry: NodeGeometry::Cube { size: 20.0 }, | |
| transform: Transform::translated(-25.0, 0.0), | |
| color: Color::rgb(220, 20, 60), | |
| children: vec![], | |
| label: Some("Debit (δ)".to_string()), | |
| }; | |
| let credit = Node { | |
| id: "credit".to_string(), | |
| geometry: NodeGeometry::Cube { size: 20.0 }, | |
| transform: Transform::translated(25.0, 0.0), | |
| color: Color::rgb(34, 139, 34), | |
| children: vec![], | |
| label: Some("Credit (ι)".to_string()), | |
| }; | |
| scene.root.children = vec![debit, credit]; | |
| scene.bounds = (-50.0, -30.0, 50.0, 30.0); | |
| scene | |
| } | |
| fn witness_exhaustion_scene() -> Self { | |
| let mut scene = Self::new("Witness Exhaustion".to_string()); | |
| let mut children = vec![]; | |
| for step in 0..3 { | |
| let node = Node { | |
| id: format!("step_{}", step), | |
| geometry: NodeGeometry::Point { radius: 8.0 }, | |
| transform: Transform::translated((step as f64 - 1.0) * 30.0, 0.0), | |
| color: Color::rgb(255, 165, 0), | |
| children: vec![], | |
| label: Some(format!("Step {}", step)), | |
| }; | |
| children.push(node); | |
| } | |
| scene.root.children = children; | |
| scene.bounds = (-40.0, -30.0, 40.0, 30.0); | |
| scene | |
| } | |
| fn nand_completeness_scene() -> Self { | |
| let mut scene = Self::new("NAND Completeness".to_string()); | |
| let mut children = vec![]; | |
| for (i, gate) in ["NOT", "AND", "OR"].iter().enumerate() { | |
| let node = Node { | |
| id: format!("gate_{}", gate), | |
| geometry: NodeGeometry::Cube { size: 15.0 }, | |
| transform: Transform::translated((i as f64 - 1.0) * 30.0, 0.0), | |
| color: Color::rgb(255, 20, 147), | |
| children: vec![], | |
| label: Some(gate.to_string()), | |
| }; | |
| children.push(node); | |
| } | |
| scene.root.children = children; | |
| scene.bounds = (-50.0, -30.0, 50.0, 30.0); | |
| scene | |
| } | |
| fn generic_theorem_scene(name: &str) -> Self { | |
| let mut scene = Self::new(name.to_string()); | |
| scene.root.label = Some(name.to_string()); | |
| scene | |
| } | |
| } | |
| mod tests { | |
| use super::*; | |
| fn sphere_scene() { | |
| let scene = SceneGraph::qlg_sphere_scene(); | |
| assert_eq!(scene.name, "QLG Sphere"); | |
| } | |
| fn balance_scene() { | |
| let scene = SceneGraph::sla_balance_scene(); | |
| assert_eq!(scene.root.children.len(), 2); | |
| } | |
| fn witness_exhaustion_scene() { | |
| let scene = SceneGraph::witness_exhaustion_scene(); | |
| assert_eq!(scene.root.children.len(), 3); | |
| } | |
| } | |