gardesk/garcalc / eac26fb

Browse files

add stub crates for graphing, geometry, documents

Authored by espadonne
SHA
eac26fb1f4f6e8c76af124052a2c5d58ea8c6bfe
Parents
b5ae272
Tree
23da49a

8 changed files

StatusFile+-
A garcalc-doc/Cargo.toml 15 0
A garcalc-doc/src/lib.rs 99 0
A garcalc-geometry/Cargo.toml 11 0
A garcalc-geometry/src/lib.rs 63 0
A garcalc-graph/Cargo.toml 12 0
A garcalc-graph/src/lib.rs 89 0
A garcalc-graph/src/plot2d.rs 20 0
A garcalc-graph/src/plot3d.rs 21 0
garcalc-doc/Cargo.tomladded
@@ -0,0 +1,15 @@
1
+[package]
2
+name = "garcalc-doc"
3
+version.workspace = true
4
+edition.workspace = true
5
+authors.workspace = true
6
+license.workspace = true
7
+description = "Document format for garcalc (spreadsheet, notes)"
8
+
9
+[dependencies]
10
+garcalc-cas = { workspace = true }
11
+garcalc-graph = { workspace = true }
12
+garcalc-geometry = { workspace = true }
13
+serde = { workspace = true }
14
+serde_json = { workspace = true }
15
+thiserror = { workspace = true }
garcalc-doc/src/lib.rsadded
@@ -0,0 +1,99 @@
1
+//! garcalc-doc: Document format
2
+//!
3
+//! Provides document structure for calculator pages, graphs,
4
+//! geometry, spreadsheets, and notes.
5
+//!
6
+//! This is a stub for Sprint 6-7 implementation.
7
+
8
+use std::collections::HashMap;
9
+
10
+use garcalc_cas::Expr;
11
+use serde::{Deserialize, Serialize};
12
+
13
+/// A garcalc document (similar to TI-Nspire .tns)
14
+#[derive(Debug, Clone, Serialize, Deserialize)]
15
+pub struct Document {
16
+    pub version: u32,
17
+    pub metadata: DocumentMetadata,
18
+    pub pages: Vec<Page>,
19
+    pub variables: HashMap<String, Expr>,
20
+}
21
+
22
+impl Default for Document {
23
+    fn default() -> Self {
24
+        Self {
25
+            version: 1,
26
+            metadata: DocumentMetadata::default(),
27
+            pages: vec![Page::Calculator(CalculatorPage::default())],
28
+            variables: HashMap::new(),
29
+        }
30
+    }
31
+}
32
+
33
+/// Document metadata
34
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
35
+pub struct DocumentMetadata {
36
+    pub title: String,
37
+    pub created: Option<String>,
38
+    pub modified: Option<String>,
39
+}
40
+
41
+/// A page within a document
42
+#[derive(Debug, Clone, Serialize, Deserialize)]
43
+#[serde(tag = "type", rename_all = "snake_case")]
44
+pub enum Page {
45
+    Calculator(CalculatorPage),
46
+    Graph(GraphPage),
47
+    Geometry(GeometryPage),
48
+    Spreadsheet(SpreadsheetPage),
49
+    Notes(NotesPage),
50
+}
51
+
52
+/// Calculator page with expression history
53
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
54
+pub struct CalculatorPage {
55
+    pub entries: Vec<CalculatorEntry>,
56
+}
57
+
58
+/// A single calculation entry
59
+#[derive(Debug, Clone, Serialize, Deserialize)]
60
+pub struct CalculatorEntry {
61
+    pub input: String,
62
+    #[serde(skip_serializing_if = "Option::is_none")]
63
+    pub result: Option<String>,
64
+    #[serde(skip_serializing_if = "Option::is_none")]
65
+    pub error: Option<String>,
66
+}
67
+
68
+/// Graph page (stub)
69
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
70
+pub struct GraphPage {
71
+    pub functions: Vec<String>,
72
+}
73
+
74
+/// Geometry page (stub)
75
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
76
+pub struct GeometryPage {
77
+    pub shapes: Vec<String>,
78
+}
79
+
80
+/// Spreadsheet page
81
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
82
+pub struct SpreadsheetPage {
83
+    pub cells: HashMap<String, Cell>,
84
+    pub rows: usize,
85
+    pub cols: usize,
86
+}
87
+
88
+/// Spreadsheet cell
89
+#[derive(Debug, Clone, Serialize, Deserialize)]
90
+pub struct Cell {
91
+    pub formula: Option<String>,
92
+    pub value: Option<String>,
93
+}
94
+
95
+/// Notes page (stub)
96
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
97
+pub struct NotesPage {
98
+    pub content: String,
99
+}
garcalc-geometry/Cargo.tomladded
@@ -0,0 +1,11 @@
1
+[package]
2
+name = "garcalc-geometry"
3
+version.workspace = true
4
+edition.workspace = true
5
+authors.workspace = true
6
+license.workspace = true
7
+description = "Dynamic geometry system for garcalc"
8
+
9
+[dependencies]
10
+serde = { workspace = true }
11
+thiserror = { workspace = true }
garcalc-geometry/src/lib.rsadded
@@ -0,0 +1,63 @@
1
+//! garcalc-geometry: Dynamic geometry system
2
+//!
3
+//! Provides geometric primitives, constructions, constraints,
4
+//! and measurements for interactive geometry.
5
+//!
6
+//! This is a stub for Sprint 5 implementation.
7
+
8
+use serde::{Deserialize, Serialize};
9
+
10
+/// A 2D point
11
+#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
12
+pub struct Point2D {
13
+    pub x: f64,
14
+    pub y: f64,
15
+}
16
+
17
+/// A unique identifier for shapes
18
+pub type ShapeId = u64;
19
+
20
+/// Geometric shapes
21
+#[derive(Debug, Clone, Serialize, Deserialize)]
22
+pub enum Shape {
23
+    Point(Point2D),
24
+    Line { p1: Point2D, p2: Point2D },
25
+    Segment { p1: Point2D, p2: Point2D },
26
+    Ray { origin: Point2D, direction: Point2D },
27
+    Circle { center: Point2D, radius: f64 },
28
+    Arc { center: Point2D, radius: f64, start_angle: f64, end_angle: f64 },
29
+    Polygon(Vec<Point2D>),
30
+}
31
+
32
+/// Geometric constraints for dynamic geometry
33
+#[derive(Debug, Clone, Serialize, Deserialize)]
34
+pub enum Constraint {
35
+    PointOnLine(ShapeId, ShapeId),
36
+    PointOnCircle(ShapeId, ShapeId),
37
+    Perpendicular(ShapeId, ShapeId),
38
+    Parallel(ShapeId, ShapeId),
39
+    Tangent(ShapeId, ShapeId),
40
+    Coincident(ShapeId, ShapeId),
41
+    Fixed(ShapeId),
42
+}
43
+
44
+/// Geometry canvas state
45
+#[derive(Default)]
46
+pub struct GeometryCanvas {
47
+    pub shapes: Vec<(ShapeId, Shape)>,
48
+    pub constraints: Vec<Constraint>,
49
+    next_id: ShapeId,
50
+}
51
+
52
+impl GeometryCanvas {
53
+    pub fn new() -> Self {
54
+        Self::default()
55
+    }
56
+
57
+    pub fn add_shape(&mut self, shape: Shape) -> ShapeId {
58
+        let id = self.next_id;
59
+        self.next_id += 1;
60
+        self.shapes.push((id, shape));
61
+        id
62
+    }
63
+}
garcalc-graph/Cargo.tomladded
@@ -0,0 +1,12 @@
1
+[package]
2
+name = "garcalc-graph"
3
+version.workspace = true
4
+edition.workspace = true
5
+authors.workspace = true
6
+license.workspace = true
7
+description = "2D/3D graphing engine for garcalc"
8
+
9
+[dependencies]
10
+garcalc-cas = { workspace = true }
11
+serde = { workspace = true }
12
+thiserror = { workspace = true }
garcalc-graph/src/lib.rsadded
@@ -0,0 +1,89 @@
1
+//! garcalc-graph: 2D/3D graphing engine
2
+//!
3
+//! Provides function plotting, parametric curves, implicit curves,
4
+//! and 3D surface visualization.
5
+//!
6
+//! This is a stub for Sprint 3-4 implementation.
7
+
8
+pub mod plot2d;
9
+pub mod plot3d;
10
+
11
+use garcalc_cas::Expr;
12
+use serde::{Deserialize, Serialize};
13
+
14
+/// Color for graph elements
15
+#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
16
+pub struct Color {
17
+    pub r: u8,
18
+    pub g: u8,
19
+    pub b: u8,
20
+    pub a: u8,
21
+}
22
+
23
+impl Color {
24
+    pub const RED: Self = Self { r: 255, g: 0, b: 0, a: 255 };
25
+    pub const BLUE: Self = Self { r: 0, g: 0, b: 255, a: 255 };
26
+    pub const GREEN: Self = Self { r: 0, g: 128, b: 0, a: 255 };
27
+    pub const BLACK: Self = Self { r: 0, g: 0, b: 0, a: 255 };
28
+}
29
+
30
+/// Line style for curves
31
+#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
32
+pub enum LineStyle {
33
+    Solid,
34
+    Dashed,
35
+    Dotted,
36
+}
37
+
38
+/// A plottable function or relation
39
+#[derive(Debug, Clone, Serialize, Deserialize)]
40
+pub enum Plottable {
41
+    /// y = f(x)
42
+    Explicit2D {
43
+        expr: Expr,
44
+        x_var: String,
45
+        color: Color,
46
+        style: LineStyle,
47
+    },
48
+    /// F(x, y) = 0
49
+    Implicit2D {
50
+        expr: Expr,
51
+        x_var: String,
52
+        y_var: String,
53
+        color: Color,
54
+    },
55
+    /// (x(t), y(t))
56
+    Parametric2D {
57
+        x_expr: Expr,
58
+        y_expr: Expr,
59
+        t_var: String,
60
+        t_range: (f64, f64),
61
+        color: Color,
62
+    },
63
+    /// z = f(x, y)
64
+    Explicit3D {
65
+        expr: Expr,
66
+        x_var: String,
67
+        y_var: String,
68
+    },
69
+}
70
+
71
+/// 2D viewport bounds
72
+#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
73
+pub struct Viewport2D {
74
+    pub x_min: f64,
75
+    pub x_max: f64,
76
+    pub y_min: f64,
77
+    pub y_max: f64,
78
+}
79
+
80
+impl Default for Viewport2D {
81
+    fn default() -> Self {
82
+        Self {
83
+            x_min: -10.0,
84
+            x_max: 10.0,
85
+            y_min: -10.0,
86
+            y_max: 10.0,
87
+        }
88
+    }
89
+}
garcalc-graph/src/plot2d.rsadded
@@ -0,0 +1,20 @@
1
+//! 2D plotting (Sprint 3)
2
+
3
+use crate::Viewport2D;
4
+
5
+/// 2D graph state
6
+pub struct Graph2D {
7
+    pub viewport: Viewport2D,
8
+    pub grid_enabled: bool,
9
+    pub axis_labels: bool,
10
+}
11
+
12
+impl Default for Graph2D {
13
+    fn default() -> Self {
14
+        Self {
15
+            viewport: Viewport2D::default(),
16
+            grid_enabled: true,
17
+            axis_labels: true,
18
+        }
19
+    }
20
+}
garcalc-graph/src/plot3d.rsadded
@@ -0,0 +1,21 @@
1
+//! 3D plotting (Sprint 4)
2
+
3
+/// 3D camera state
4
+#[derive(Debug, Clone, Copy)]
5
+pub struct Camera3D {
6
+    pub azimuth: f64,
7
+    pub elevation: f64,
8
+    pub distance: f64,
9
+    pub target: (f64, f64, f64),
10
+}
11
+
12
+impl Default for Camera3D {
13
+    fn default() -> Self {
14
+        Self {
15
+            azimuth: 45.0_f64.to_radians(),
16
+            elevation: 30.0_f64.to_radians(),
17
+            distance: 20.0,
18
+            target: (0.0, 0.0, 0.0),
19
+        }
20
+    }
21
+}