Showing
100 changed files
with
79 additions
and
4620 deletions
Too many changes to show.
To preserve performance only 100 of 100+ files are displayed.
1 | +<div align="center"> | ||
2 | + | ||
3 | + <h1><code>wasm-pack-template</code></h1> | ||
4 | + | ||
5 | + <strong>A template for kick starting a Rust and WebAssembly project using <a href="https://github.com/rustwasm/wasm-pack">wasm-pack</a>.</strong> | ||
6 | + | ||
7 | + <p> | ||
8 | + <a href="https://travis-ci.org/rustwasm/wasm-pack-template"><img src="https://img.shields.io/travis/rustwasm/wasm-pack-template.svg?style=flat-square" alt="Build Status" /></a> | ||
9 | + </p> | ||
10 | + | ||
11 | + <h3> | ||
12 | + <a href="https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html">Tutorial</a> | ||
13 | + <span> | </span> | ||
14 | + <a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a> | ||
15 | + </h3> | ||
16 | + | ||
17 | + <sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub> | ||
18 | +</div> | ||
19 | + | ||
20 | +## About | ||
21 | + | ||
22 | +[**📚 Read this template tutorial! 📚**][template-docs] | ||
23 | + | ||
24 | +This template is designed for compiling Rust libraries into WebAssembly and | ||
25 | +publishing the resulting package to NPM. | ||
26 | + | ||
27 | +Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other | ||
28 | +templates and usages of `wasm-pack`. | ||
29 | + | ||
30 | +[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html | ||
31 | +[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html | ||
32 | + | ||
33 | +## 🚴 Usage | ||
34 | + | ||
35 | +### 🐑 Use `cargo generate` to Clone this Template | ||
36 | + | ||
37 | +[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) | ||
38 | + | ||
39 | +``` | ||
40 | +cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project | ||
41 | +cd my-project | ||
42 | +``` | ||
43 | + | ||
44 | +### 🛠️ Build with `wasm-pack build` | ||
45 | + | ||
46 | +``` | ||
47 | +wasm-pack build | ||
48 | +``` | ||
49 | + | ||
50 | +### 🔬 Test in Headless Browsers with `wasm-pack test` | ||
51 | + | ||
52 | +``` | ||
53 | +wasm-pack test --headless --firefox | ||
54 | +``` | ||
55 | + | ||
56 | +### 🎁 Publish to NPM with `wasm-pack publish` | ||
57 | + | ||
58 | +``` | ||
59 | +wasm-pack publish | ||
60 | +``` | ||
61 | + | ||
62 | +## 🔋 Batteries Included | ||
63 | + | ||
64 | +* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating | ||
65 | + between WebAssembly and JavaScript. | ||
66 | +* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) | ||
67 | + for logging panic messages to the developer console. | ||
68 | +* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized | ||
69 | + for small code size. | ||
1 | # Rust playground | 70 | # Rust playground |
2 | 71 | ||
3 | Things I have recently done while learning the Rust programming language. | 72 | Things I have recently done while learning the Rust programming language. |
branches/Cargo.lock
deleted
100644 → 0
branches/Cargo.toml
deleted
100644 → 0
branches/src/main.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Control Flow Examples | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | - | ||
22 | -fn main() { | ||
23 | - let condition = true; | ||
24 | - let number = if condition { | ||
25 | - 5 | ||
26 | - } else { | ||
27 | - 6 | ||
28 | - }; | ||
29 | - | ||
30 | - println!("The value of number is: {}", number); | ||
31 | -} |
fractional/.swp
deleted
100644 → 0
No preview for this file type
fractional/Cargo.toml
deleted
100644 → 0
1 | -[package] | ||
2 | -name = "fractional" | ||
3 | -version = "0.1.0" | ||
4 | -authors = ["Georg Hopp <georg@steffers.org>"] | ||
5 | -edition = "2018" | ||
6 | - | ||
7 | -[dependencies] | ||
8 | -lazy_static = "1.4.0" | ||
9 | -libc = "0.2" | ||
10 | -gl = "0.5.2" | ||
11 | -x11 = { version = "2.3", features = ["glx"] } | ||
12 | -xcb = { version = "0.8", features = ["dri2", "randr", "thread", "xlib_xcb", "shm"] } |
fractional/notes/09e-textures.pdf
deleted
100644 → 0
No preview for this file type
fractional/notes/frontier-map.url
deleted
100644 → 0
1 | -http://www.jongware.com/galaxy1.html |
fractional/notes/html5
deleted
100644 → 0
1 | -I really would like to see a HTML5 canvas as canvas for the 3D code. | ||
2 | - | ||
3 | -Some URLs: | ||
4 | -- https://stackoverflow.com/questions/42806037/modify-canvas-from-wasm | ||
5 | -- https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.HtmlCanvasElement.html | ||
6 | -- https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.CanvasRenderingContext2d.html | ||
7 | -- https://stackoverflow.com/questions/49935207/editing-canvas-pixel-data-in-webassembly-rust |
fractional/notes/math.url
deleted
100644 → 0
1 | -https://www.themathpage.com/Alg/reciprocals.htm |
fractional/notes/polyhedra.pdf
deleted
100644 → 0
No preview for this file type
fractional/notes/texmap.pdf
deleted
100644 → 0
No preview for this file type
fractional/notes/texture-mapping.url
deleted
100644 → 0
1 | -https://en.wikipedia.org/wiki/Texture_mapping | ||
2 | -http://www.gamers.org/dEngine/quake/papers/checker_texmap.html | ||
3 | -https://www.cs.uic.edu/~jbell/CourseNotes/ComputerGraphics/TextureMapping.html | ||
4 | -http://www.decew.net/OSS/References/chapter_2_texture_mapping.pdf | ||
5 | - | ||
6 | -# example affine texture mapping | ||
7 | -http://archive.gamedev.net/archive/reference/articles/article852.html | ||
8 | - | ||
9 | - | ||
10 | -http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/ | ||
11 | - | ||
12 | -# Shader... This also describes z-Buffer... :) | ||
13 | -https://people.ece.cornell.edu/land/OldStudentProjects/cs490-95to96/GUO/report.html | ||
14 | -https://software.intel.com/en-us/articles/the-basics-of-the-art-of-lighting-part-3-lighting-and-shaders/ | ||
15 | -https://docs.unity3d.com/Manual/Lighting.html |
fractional/src/continuous.rs
deleted
100644 → 0
1 | -// | ||
2 | -// A «continued fraction» is a representation of a fraction as a vector | ||
3 | -// of integrals… Irrational fractions will result in infinite most of the | ||
4 | -// time repetitive vectors. They can be used to get a resonable approximation | ||
5 | -// for sqrt on fractionals. | ||
6 | -// | ||
7 | -// Georg Hopp <georg@steffers.org> | ||
8 | -// | ||
9 | -// Copyright © 2019 Georg Hopp | ||
10 | -// | ||
11 | -// This program is free software: you can redistribute it and/or modify | ||
12 | -// it under the terms of the GNU General Public License as published by | ||
13 | -// the Free Software Foundation, either version 3 of the License, or | ||
14 | -// (at your option) any later version. | ||
15 | -// | ||
16 | -// This program is distributed in the hope that it will be useful, | ||
17 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | -// GNU General Public License for more details. | ||
20 | -// | ||
21 | -// You should have received a copy of the GNU General Public License | ||
22 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
23 | -// | ||
24 | -use crate::Fractional; | ||
25 | - | ||
26 | -#[derive(Debug)] | ||
27 | -pub struct Continuous (Vec<i64>); | ||
28 | - | ||
29 | -impl Continuous { | ||
30 | - // calculate a sqrt as continued fraction sequence. Taken from: | ||
31 | - // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots# | ||
32 | - // Continued_fraction_expansion | ||
33 | - pub fn sqrt(x :i64, a0 :i64) -> Self { | ||
34 | - fn inner(v :&mut [i64], x :i64, a0 :i64, mn :i64, dn :i64, an :i64) { | ||
35 | - let mn_1 = dn * an - mn; | ||
36 | - let dn_1 = (x - mn_1 * mn_1) / dn; | ||
37 | - let an_1 = (a0 + mn_1) / dn_1; | ||
38 | - | ||
39 | - v[0] = an; | ||
40 | - // The convergence criteria „an_1 == 2 * a0“ is not good for | ||
41 | - // very small x thus I decided to break the iteration at constant | ||
42 | - // time. Which is the 5 below. | ||
43 | - if v.len() > 1 { | ||
44 | - inner(&mut v[1..], x, a0, mn_1, dn_1, an_1); | ||
45 | - } | ||
46 | - } | ||
47 | - | ||
48 | - let mut v :Vec<i64> = vec!(0; 5); | ||
49 | - inner(&mut v, x, a0, 0, 1, a0); | ||
50 | - Continuous(v) | ||
51 | - } | ||
52 | - | ||
53 | - // general continous fraction form of a fractional... | ||
54 | - pub fn from_prec(f :&Fractional, prec :Option<usize>) -> Self { | ||
55 | - fn inner(v :&mut Vec<i64>, f :Fractional, prec :Option<usize>) { | ||
56 | - let mut process = |prec :Option<usize>| { | ||
57 | - let Fractional(n, d) = f; | ||
58 | - let a = n / d; | ||
59 | - let Fractional(_n, _d) = f.noreduce_sub(a.into()); | ||
60 | - | ||
61 | - v.push(a); | ||
62 | - match _n { | ||
63 | - 1 => v.push(_d), | ||
64 | - 0 => {}, | ||
65 | - _ => inner(v, Fractional(_d, _n), prec), | ||
66 | - } | ||
67 | - }; | ||
68 | - | ||
69 | - match prec { | ||
70 | - Some(0) => {}, | ||
71 | - None => process(None), | ||
72 | - Some(p) => process(Some(p - 1)), | ||
73 | - } | ||
74 | - } | ||
75 | - | ||
76 | - let mut v = match prec { | ||
77 | - None => Vec::with_capacity(100), | ||
78 | - Some(p) => Vec::with_capacity(p + 1), | ||
79 | - }; | ||
80 | - | ||
81 | - inner(&mut v, *f, prec); | ||
82 | - Continuous(v) | ||
83 | - } | ||
84 | - | ||
85 | - pub fn into_prec(&self, prec :Option<usize>) -> Fractional { | ||
86 | - let Continuous(c) = self; | ||
87 | - let p = match prec { | ||
88 | - Some(p) => if p <= c.len() { p } else { c.len() }, | ||
89 | - None => c.len(), | ||
90 | - }; | ||
91 | - | ||
92 | - let to_frac = |acc :Fractional, x :&i64| { | ||
93 | - let Fractional(an, ad) = acc.noreduce_add((*x).into()); | ||
94 | - Fractional(ad, an) | ||
95 | - }; | ||
96 | - | ||
97 | - let Fractional(n, d) = c[..p] | ||
98 | - . into_iter() | ||
99 | - . rev() | ||
100 | - . fold(Fractional(0, 1), to_frac); | ||
101 | - Fractional(d, n) | ||
102 | - } | ||
103 | -} | ||
104 | - | ||
105 | -impl From<&Fractional> for Continuous { | ||
106 | - fn from(x :&Fractional) -> Self { | ||
107 | - Self::from_prec(x, None) | ||
108 | - } | ||
109 | -} | ||
110 | - | ||
111 | -impl Into<Fractional> for &Continuous { | ||
112 | - fn into(self) -> Fractional { | ||
113 | - (&self).into_prec(None) | ||
114 | - } | ||
115 | -} |
fractional/src/fractional.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Some code to support fractional numbers for full precision rational number | ||
3 | -// calculations. (At least for the standard operations.) | ||
4 | -// This also implements a sqrt on fractional numbers, which can not be precise | ||
5 | -// because of the irrational nature of most sqare roots. | ||
6 | -// Fractions can only represent rational numbers precise. | ||
7 | -// | ||
8 | -// Georg Hopp <georg@steffers.org> | ||
9 | -// | ||
10 | -// Copyright © 2019 Georg Hopp | ||
11 | -// | ||
12 | -// This program is free software: you can redistribute it and/or modify | ||
13 | -// it under the terms of the GNU General Public License as published by | ||
14 | -// the Free Software Foundation, either version 3 of the License, or | ||
15 | -// (at your option) any later version. | ||
16 | -// | ||
17 | -// This program is distributed in the hope that it will be useful, | ||
18 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | -// GNU General Public License for more details. | ||
21 | -// | ||
22 | -// You should have received a copy of the GNU General Public License | ||
23 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
24 | -// | ||
25 | -use std::cmp::Ordering; | ||
26 | -use std::convert::{TryFrom, TryInto}; | ||
27 | -use std::fmt::{Formatter, Display}; | ||
28 | -use std::num::TryFromIntError; | ||
29 | -use std::ops::{Add,Sub,Neg,Mul,Div}; | ||
30 | - | ||
31 | -use crate::continuous::Continuous; | ||
32 | - | ||
33 | -#[derive(Debug, Eq, Clone, Copy)] | ||
34 | -pub struct Fractional (pub i64, pub i64); | ||
35 | - | ||
36 | -#[inline] | ||
37 | -fn hcf(x :i64, y :i64) -> i64 { | ||
38 | - match y { | ||
39 | - 0 => x, | ||
40 | - _ => hcf(y, x % y), | ||
41 | - } | ||
42 | -} | ||
43 | - | ||
44 | -pub fn from_vector(xs: &Vec<i64>) -> Vec<Fractional> { | ||
45 | - xs.iter().map(|x| Fractional(*x, 1)).collect() | ||
46 | -} | ||
47 | - | ||
48 | -impl Fractional { | ||
49 | - #[inline] | ||
50 | - pub fn gcd(self, other: Self) -> i64 { | ||
51 | - let Fractional(_, d1) = self; | ||
52 | - let Fractional(_, d2) = other; | ||
53 | - (d1 * d2) / hcf(d1, d2) | ||
54 | - } | ||
55 | - | ||
56 | - #[inline] | ||
57 | - pub fn reduce(self) -> Self { | ||
58 | - let Fractional(n, d) = self; | ||
59 | - let (_n, _d) = if n > d { (n, d) } else { (d, n) }; | ||
60 | - | ||
61 | - // if the difference from _n % _d to _n is very big we are close to | ||
62 | - // a whole number and can ignore the fractional part... this reduces | ||
63 | - // the precision but ensures smaller numbers for numerator and | ||
64 | - // denominator. | ||
65 | - if _d > 1 && (_n % _d) * 10000000 < _n { | ||
66 | - if n == _n { | ||
67 | - Self(_n / _d, 1) | ||
68 | - } else { | ||
69 | - Self(1, _n / _d) | ||
70 | - } | ||
71 | - } else { | ||
72 | - // Self(n / hcf(n, d), d / hcf(n, d)) | ||
73 | - // The above reduces prcisely but results in very large numerator | ||
74 | - // or denominator occasionally. The below is less precise but | ||
75 | - // keeps the numbers small… the bad point is, that it is not very | ||
76 | - // fast. | ||
77 | - let cont = Continuous::from_prec(&self, Some(5)); | ||
78 | - (&cont).into() | ||
79 | - } | ||
80 | - } | ||
81 | - | ||
82 | - pub fn noreduce_add(self, other: Self) -> Self { | ||
83 | - let Fractional(n1, d1) = self; | ||
84 | - let Fractional(n2, d2) = other; | ||
85 | - let n = n1 * (self.gcd(other) / d1) + n2 * (self.gcd(other) / d2); | ||
86 | - Self(n, self.gcd(other)) | ||
87 | - } | ||
88 | - | ||
89 | - pub fn noreduce_sub(self, other: Self) -> Self { | ||
90 | - self.noreduce_add(other.noreduce_neg()) | ||
91 | - } | ||
92 | - | ||
93 | - pub fn noreduce_neg(self) -> Self { | ||
94 | - let Fractional(n, d) = self; | ||
95 | - Self(-n, d) | ||
96 | - } | ||
97 | -} | ||
98 | - | ||
99 | -impl From<i64> for Fractional { | ||
100 | - fn from(x: i64) -> Self { | ||
101 | - Self(x, 1) | ||
102 | - } | ||
103 | -} | ||
104 | - | ||
105 | -impl From<i32> for Fractional { | ||
106 | - fn from(x: i32) -> Self { | ||
107 | - Self(x as i64, 1) | ||
108 | - } | ||
109 | -} | ||
110 | - | ||
111 | -impl TryFrom<usize> for Fractional { | ||
112 | - type Error = &'static str; | ||
113 | - | ||
114 | - fn try_from(x: usize) -> Result<Self, Self::Error> { | ||
115 | - let v = i64::try_from(x); | ||
116 | - match v { | ||
117 | - Err(_) => Err("Conversion from usize to i32 failed"), | ||
118 | - Ok(_v) => Ok(Self(_v, 1)), | ||
119 | - } | ||
120 | - } | ||
121 | -} | ||
122 | - | ||
123 | -impl TryInto<f64> for Fractional { | ||
124 | - type Error = TryFromIntError; | ||
125 | - | ||
126 | - fn try_into(self) -> Result<f64, Self::Error> { | ||
127 | - let n :i32 = self.0.try_into()?; | ||
128 | - let d :i32 = self.1.try_into()?; | ||
129 | - Ok(f64::from(n) / f64::from(d)) | ||
130 | - } | ||
131 | -} | ||
132 | - | ||
133 | -impl TryInto<(i32, i32)> for Fractional { | ||
134 | - type Error = TryFromIntError; | ||
135 | - | ||
136 | - fn try_into(self) -> Result<(i32, i32), Self::Error> { | ||
137 | - let a :i32 = (self.0 / self.1).try_into()?; | ||
138 | - let b :i32 = (self.0 % self.1).try_into()?; | ||
139 | - Ok((a, b)) | ||
140 | - } | ||
141 | -} | ||
142 | - | ||
143 | -impl Display for Fractional { | ||
144 | - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
145 | - write!(f, "({}/{})", self.0, self.1) | ||
146 | - } | ||
147 | -} | ||
148 | - | ||
149 | -impl PartialEq for Fractional { | ||
150 | - fn eq(&self, other: &Self) -> bool { | ||
151 | - let Fractional(n1, d1) = self; | ||
152 | - let Fractional(n2, d2) = other; | ||
153 | - n1 * (self.gcd(*other) / d1) == n2 * (self.gcd(*other) / d2) | ||
154 | - } | ||
155 | -} | ||
156 | - | ||
157 | -impl PartialOrd for Fractional { | ||
158 | - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
159 | - Some(self.cmp(other)) | ||
160 | - } | ||
161 | -} | ||
162 | - | ||
163 | -impl Ord for Fractional { | ||
164 | - fn cmp(&self, other: &Self) -> Ordering { | ||
165 | - let Fractional(n1, d1) = self; | ||
166 | - let Fractional(n2, d2) = other; | ||
167 | - let x = n1 * (self.gcd(*other) / d1); | ||
168 | - let y = n2 * (self.gcd(*other) / d2); | ||
169 | - x.cmp(&y) | ||
170 | - } | ||
171 | -} | ||
172 | - | ||
173 | -impl Add for Fractional { | ||
174 | - type Output = Self; | ||
175 | - | ||
176 | - fn add(self, other: Self) -> Self { | ||
177 | - self.noreduce_add(other).reduce() | ||
178 | - } | ||
179 | -} | ||
180 | - | ||
181 | -impl Sub for Fractional { | ||
182 | - type Output = Self; | ||
183 | - | ||
184 | - fn sub(self, other: Self) -> Self { | ||
185 | - self + -other | ||
186 | - } | ||
187 | -} | ||
188 | - | ||
189 | -impl Neg for Fractional { | ||
190 | - type Output = Self; | ||
191 | - | ||
192 | - fn neg(self) -> Self { | ||
193 | - let Fractional(n, d) = self; | ||
194 | - Self(-n, d) | ||
195 | - } | ||
196 | -} | ||
197 | - | ||
198 | -impl Mul for Fractional { | ||
199 | - type Output = Self; | ||
200 | - | ||
201 | - fn mul(self, other :Self) -> Self { | ||
202 | - let Fractional(n1, d1) = self; | ||
203 | - let Fractional(n2, d2) = other; | ||
204 | - Self(n1 * n2, d1 * d2).reduce() | ||
205 | - } | ||
206 | -} | ||
207 | - | ||
208 | -impl Div for Fractional { | ||
209 | - type Output = Self; | ||
210 | - | ||
211 | - fn div(self, other: Self) -> Self { | ||
212 | - let Fractional(n, d) = other; | ||
213 | - self * Fractional(d, n) | ||
214 | - } | ||
215 | -} | ||
216 | - | ||
217 | - /* some stuff that could be tested... | ||
218 | - let x = Fractional(1, 3); | ||
219 | - let y = Fractional(1, 6); | ||
220 | - | ||
221 | - println!( | ||
222 | - "Greatest common denominator of {} and {}: {}", x, y, x.gcd(y)); | ||
223 | - println!("Numerator of {}: {}", x, x.numerator()); | ||
224 | - println!("Denominator of {}: {}", x, x.denominator()); | ||
225 | - assert_eq!(Fractional(1, 3), Fractional(2, 6)); | ||
226 | - assert_eq!(Fractional(1, 3), Fractional(1, 3)); | ||
227 | - assert_eq!(y < x, true); | ||
228 | - assert_eq!(y > x, false); | ||
229 | - assert_eq!(x == y, false); | ||
230 | - assert_eq!(x == x, true); | ||
231 | - assert_eq!(x + y, Fractional(1, 2)); | ||
232 | - println!("{} + {} = {}", x, y, x + y); | ||
233 | - assert_eq!(x - y, Fractional(1, 6)); | ||
234 | - println!("{} - {} = {}", x, y, x - y); | ||
235 | - assert_eq!(y - x, Fractional(-1, 6)); | ||
236 | - println!("{} - {} = {}", y, x, y - x); | ||
237 | - assert_eq!(-x, Fractional(-1, 3)); | ||
238 | - println!("-{} = {}", x, -x); | ||
239 | - assert_eq!(x * y, Fractional(1, 18)); | ||
240 | - println!("{} * {} = {}", x, y, x * y); | ||
241 | - assert_eq!(x / y, Fractional(2, 1)); | ||
242 | - println!("{} / {} = {}", x, y, x / y); | ||
243 | - assert_eq!(y / x, Fractional(1, 2)); | ||
244 | - println!("{} / {} = {}", y, x, y / x); | ||
245 | - | ||
246 | - println!("Fractional from 3: {}", Fractional::from(3)); | ||
247 | - let z :f64 = Fractional::into(x); | ||
248 | - println!("Floating point of {}: {}", x, z); | ||
249 | - let (d, r) = Fractional::into(x); | ||
250 | - println!("(div, rest) of {}: ({}, {})", x, d, r); | ||
251 | - */ | ||
252 | - |
fractional/src/geometry.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Basic geometric things... | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | -use std::convert::{From, Into}; | ||
22 | -use std::ops::{Add,Sub,Neg,Mul,Div}; | ||
23 | -use std::fmt::Debug; | ||
24 | - | ||
25 | -use crate::easel::{Canvas, Coordinate, Coordinates, Polygon}; | ||
26 | -use crate::transform::{TMatrix, Transformable}; | ||
27 | -use crate::trigonometry::Trig; | ||
28 | -use crate::vector::Vector; | ||
29 | - | ||
30 | -#[derive(Debug, Clone)] | ||
31 | -pub struct Face<T> | ||
32 | -where T: Add + Sub + Neg + Mul + Div + Copy + Trig { | ||
33 | - corners :Vec<usize>, | ||
34 | - normal :Option<Vector<T>>, | ||
35 | -} | ||
36 | - | ||
37 | -#[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
38 | -pub struct Point<T>(pub Vector<T>, T) | ||
39 | - where T: Add + Sub + Neg + Mul + Div + PartialEq + Copy + Trig; | ||
40 | - | ||
41 | -impl<T> Point<T> | ||
42 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
43 | - + Mul<Output = T> + Div<Output = T> | ||
44 | - + PartialEq + Trig + Copy + From<i32> { | ||
45 | - pub fn new(x :T, y :T, z :T) -> Self { | ||
46 | - Self(Vector(x, y, z), 1.into()) | ||
47 | - } | ||
48 | -} | ||
49 | - | ||
50 | -impl<T> Add for Point<T> | ||
51 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
52 | - + Mul<Output = T> + Div<Output = T> | ||
53 | - + PartialEq + Trig + Copy { | ||
54 | - type Output = Self; | ||
55 | - | ||
56 | - fn add(self, other :Self) -> Self { | ||
57 | - let Point(v1, w1) = self; | ||
58 | - let Point(v2, w2) = other; | ||
59 | - Self(v1 + v2, w1 + w2) | ||
60 | - } | ||
61 | -} | ||
62 | - | ||
63 | -impl<T> Neg for Point<T> | ||
64 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
65 | - + Mul<Output = T> + Div<Output = T> | ||
66 | - + PartialEq + Trig + Copy { | ||
67 | - type Output = Self; | ||
68 | - | ||
69 | - fn neg(self) -> Self { | ||
70 | - let Point(v, w) = self; | ||
71 | - Self(-v, -w) | ||
72 | - } | ||
73 | -} | ||
74 | - | ||
75 | -impl<T> Sub for Point<T> | ||
76 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
77 | - + Mul<Output = T> + Div<Output = T> | ||
78 | - + PartialEq + Trig + Copy { | ||
79 | - type Output = Self; | ||
80 | - | ||
81 | - fn sub(self, other :Self) -> Self { | ||
82 | - self + -other | ||
83 | - } | ||
84 | -} | ||
85 | - | ||
86 | -impl<T> Mul for Point<T> | ||
87 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
88 | - + Mul<Output = T> + Div<Output = T> | ||
89 | - + PartialEq + Trig + Copy + From<i32> { | ||
90 | - type Output = Self; | ||
91 | - | ||
92 | - fn mul(self, other :Self) -> Self { | ||
93 | - let a :Vector<T> = self.into(); | ||
94 | - let b :Vector<T> = other.into(); | ||
95 | - | ||
96 | - Point(a * b, 1.into()) | ||
97 | - } | ||
98 | -} | ||
99 | - | ||
100 | -impl<T> From<Vector<T>> for Point<T> | ||
101 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
102 | - + Mul<Output = T> + Div<Output = T> | ||
103 | - + PartialEq + Trig + Copy + From<i32> { | ||
104 | - fn from(v :Vector<T>) -> Self { | ||
105 | - Point(v, 1.into()) | ||
106 | - } | ||
107 | -} | ||
108 | - | ||
109 | -impl<T> Into<Vector<T>> for Point<T> | ||
110 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
111 | - + Mul<Output = T> + Div<Output = T> | ||
112 | - + PartialEq + Trig + Copy + From<i32> { | ||
113 | - fn into(self) -> Vector<T> { | ||
114 | - let Point(v, w) = self; | ||
115 | - | ||
116 | - if w == 0.into() { | ||
117 | - v | ||
118 | - } else { | ||
119 | - v.mul(&w.recip()) | ||
120 | - } | ||
121 | - } | ||
122 | -} | ||
123 | - | ||
124 | -impl<T> Transformable<T> for Point<T> | ||
125 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
126 | - + Mul<Output = T> + Div<Output = T> | ||
127 | - + PartialEq + Debug + Trig + Copy + From<i32> { | ||
128 | - fn transform(&self, m :&TMatrix<T>) -> Self { | ||
129 | - let Point(v, w) = *self; | ||
130 | - let (v, w) = m.apply(&v, w); | ||
131 | - | ||
132 | - if w == 0.into() { | ||
133 | - v.into() | ||
134 | - } else { | ||
135 | - v.mul(&w.recip()).into() | ||
136 | - } | ||
137 | - } | ||
138 | -} | ||
139 | - | ||
140 | -#[derive(Debug)] | ||
141 | -pub struct Polyeder<T> | ||
142 | -where T: Add + Sub + Neg + Mul + Div + PartialEq + Copy + Trig { | ||
143 | - points :Vec<Point<T>>, | ||
144 | - faces :Vec<Face<T>>, | ||
145 | -} | ||
146 | - | ||
147 | -pub trait Primitives<T> | ||
148 | -where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { | ||
149 | - fn transform(&self, m :&TMatrix<T>) -> Self; | ||
150 | - fn project( &self | ||
151 | - , camera :&Camera<T> | ||
152 | - , light :&DirectLight<T> | ||
153 | - , col :u32 ) -> Vec<(Polygon<T>, u32)>; | ||
154 | -} | ||
155 | - | ||
156 | -pub struct Camera<T> | ||
157 | -where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { | ||
158 | - width :T, | ||
159 | - height :T, | ||
160 | - distance :T, | ||
161 | - project :TMatrix<T>, | ||
162 | -} | ||
163 | - | ||
164 | -pub struct DirectLight<T> | ||
165 | -where T: Add + Sub + Neg + Mul + Div + Debug + Copy + Trig + From<i32> { | ||
166 | - direction: Vector<T>, | ||
167 | -} | ||
168 | - | ||
169 | -impl<T> Camera<T> | ||
170 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
171 | - + Mul<Output = T> + Div<Output = T> | ||
172 | - + PartialEq + Debug + Copy + Trig + From<i32> { | ||
173 | - // This code assumes that the size of the viewport is always | ||
174 | - // equal to the size of the physical screen… e.g. window/canvas thus some | ||
175 | - // effects can't be done. See book for examples with different viewport | ||
176 | - // and screen sizes. | ||
177 | - pub fn new(c :&dyn Canvas<T>, angle :i32) -> Self { | ||
178 | - let width :T = (c.width() as i32).into(); | ||
179 | - let height :T = (c.height() as i32).into(); | ||
180 | - let d :T = 1.into(); | ||
181 | - let fov = T::cot(angle) * width; | ||
182 | - let wh = width / 2.into(); | ||
183 | - let hh = height / 2.into(); | ||
184 | - | ||
185 | - Camera { width: width | ||
186 | - , height: height | ||
187 | - , distance: d | ||
188 | - , project: TMatrix::new( | ||
189 | - ( fov, 0.into(), wh, 0.into()) | ||
190 | - , (0.into(), fov, hh, 0.into()) | ||
191 | - , (0.into(), 0.into(), d, 1.into()) | ||
192 | - , (0.into(), 0.into(), 1.into(), 0.into()) ) } | ||
193 | - } | ||
194 | - | ||
195 | - pub fn get_distance(&self) -> T { | ||
196 | - self.distance | ||
197 | - } | ||
198 | - | ||
199 | - pub fn get_projection(&self) -> TMatrix<T> { | ||
200 | - self.project | ||
201 | - } | ||
202 | - | ||
203 | - pub fn project(&self, p :Point<T>) -> Point<T> { | ||
204 | - p.transform(&self.project) | ||
205 | - } | ||
206 | -} | ||
207 | - | ||
208 | -impl<T> DirectLight<T> | ||
209 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
210 | - + Mul<Output = T> + Div<Output = T> | ||
211 | - + Debug + Copy + Trig + From<i32> { | ||
212 | - pub fn new(v :Vector<T>) -> Self { | ||
213 | - DirectLight{ direction: v } | ||
214 | - } | ||
215 | - | ||
216 | - pub fn dir(&self) -> Vector<T> { | ||
217 | - self.direction | ||
218 | - } | ||
219 | -} | ||
220 | - | ||
221 | -impl<T> Face<T> | ||
222 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
223 | - + Mul<Output = T> + Div<Output = T> | ||
224 | - + PartialEq + Debug + Copy + Trig + From<i32> { | ||
225 | - fn new(corners :Vec<usize>, ps :&[Point<T>]) -> Self { | ||
226 | - let mut f = Face{ corners: corners, normal: None }; | ||
227 | - f.update_normal(ps); | ||
228 | - f | ||
229 | - } | ||
230 | - | ||
231 | - fn update_normal(&mut self, ps :&[Point<T>]) { | ||
232 | - let edge10 :Vector<T> = (ps[self.corners[1]] - ps[self.corners[0]]).into(); | ||
233 | - let edge12 :Vector<T> = (ps[self.corners[1]] - ps[self.corners[2]]).into(); | ||
234 | - self.normal = Some(edge10 * edge12); | ||
235 | - } | ||
236 | -} | ||
237 | - | ||
238 | -impl<T> Polyeder<T> | ||
239 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
240 | - + Mul<Output = T> + Div<Output = T> | ||
241 | - + PartialEq + Debug + Copy + Trig + From<i32> { | ||
242 | - fn update_normals(&mut self) { | ||
243 | - for f in self.faces.iter_mut() { | ||
244 | - f.update_normal(&self.points); | ||
245 | - } | ||
246 | - } | ||
247 | - | ||
248 | - // construct via cube, see polyhedra.pdf | ||
249 | - pub fn tetrahedron(a :T) -> Polyeder<T> { | ||
250 | - let f2 :T = 2.into(); | ||
251 | - let ch = a / (f2 * T::sqrt(f2).unwrap()); | ||
252 | - | ||
253 | - let ps = vec!( Point::new(-ch, -ch, ch) // A | ||
254 | - , Point::new(-ch, ch, -ch) // C | ||
255 | - , Point::new( ch, -ch, -ch) // E | ||
256 | - , Point::new( ch, ch, ch) ); // G | ||
257 | - | ||
258 | - // bottom: 1, 2, 3 | ||
259 | - let fs = vec!( Face::new(vec!(2, 1, 0), &ps) // bottom | ||
260 | - , Face::new(vec!(3, 2, 0), &ps) | ||
261 | - , Face::new(vec!(0, 1, 3), &ps) | ||
262 | - , Face::new(vec!(1, 2, 3), &ps) ); | ||
263 | - //let fs = vec!( Face::new(vec!(0, 1, 2), &ps) // bottom | ||
264 | - // , Face::new(vec!(0, 2, 3), &ps) | ||
265 | - // , Face::new(vec!(3, 1, 0), &ps) | ||
266 | - // , Face::new(vec!(3, 2, 1), &ps) ); | ||
267 | - | ||
268 | - Polyeder{ points: ps, faces: fs } | ||
269 | - } | ||
270 | - | ||
271 | - pub fn triangle(a :T) -> Polyeder<T> { | ||
272 | - let f0 :T = 0.into(); | ||
273 | - let f3 :T = 3.into(); | ||
274 | - let f6 :T = 6.into(); | ||
275 | - let zi :T = T::sqrt(f3).unwrap() / f6 * a; | ||
276 | - let zc :T = T::sqrt(f3).unwrap() / f3 * a; | ||
277 | - let ah :T = a / 2.into(); | ||
278 | - | ||
279 | - let ps = vec!( Point::new(-ah, f0, -zi) | ||
280 | - , Point::new( f0, f0, zc) | ||
281 | - , Point::new( ah, f0, -zi) ); | ||
282 | - | ||
283 | - let fs = vec!(Face::new(vec!(0, 1, 2), &ps)); | ||
284 | - | ||
285 | - Polyeder{ points: ps, faces: fs } | ||
286 | - } | ||
287 | - | ||
288 | - pub fn cube(a :T) -> Polyeder<T> { | ||
289 | - let ah :T = a / From::<i32>::from(2); | ||
290 | - | ||
291 | - let ps = vec!( Point::new(-ah, ah, -ah) // 0 => front 1 | ||
292 | - , Point::new(-ah, -ah, -ah) // 1 => front 2 | ||
293 | - , Point::new( ah, -ah, -ah) // 2 => front 3 | ||
294 | - , Point::new( ah, ah, -ah) // 3 => front 4 | ||
295 | - , Point::new(-ah, ah, ah) // 4 => back 1 | ||
296 | - , Point::new(-ah, -ah, ah) // 5 => back 2 | ||
297 | - , Point::new( ah, -ah, ah) // 6 => back 3 | ||
298 | - , Point::new( ah, ah, ah) ); // 7 => back 4 | ||
299 | - | ||
300 | - let fs = vec!( Face::new(vec!(0, 1, 2, 3), &ps) // front | ||
301 | - , Face::new(vec!(7, 6, 5, 4), &ps) // back | ||
302 | - , Face::new(vec!(1, 5, 6, 2), &ps) // top | ||
303 | - , Face::new(vec!(0, 3, 7, 4), &ps) // bottom | ||
304 | - , Face::new(vec!(0, 4, 5, 1), &ps) // left | ||
305 | - , Face::new(vec!(2, 6, 7, 3), &ps) ); // right | ||
306 | - | ||
307 | - Polyeder{ points: ps, faces: fs } | ||
308 | - } | ||
309 | -} | ||
310 | - | ||
311 | -impl<T> Primitives<T> for Polyeder<T> | ||
312 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
313 | - + Mul<Output = T> + Div<Output = T> | ||
314 | - + Debug + Copy + Trig + From<i32> + PartialOrd { | ||
315 | - // TODO Maybe this should also be an instance of Transformable… | ||
316 | - fn transform(&self, m :&TMatrix<T>) -> Self { | ||
317 | - let Polyeder{ points: ps, faces: fs } = self; | ||
318 | - | ||
319 | - let mut p = Polyeder{ | ||
320 | - points: ps.iter().map(|p| p.transform(m)).collect() | ||
321 | - , faces: fs.to_vec() | ||
322 | - }; | ||
323 | - | ||
324 | - // TODO alternatively we could rotate the normals too, but this cannot | ||
325 | - // done with the original matrix… the question is, what is faster. | ||
326 | - p.update_normals(); | ||
327 | - p | ||
328 | - } | ||
329 | - | ||
330 | - fn project( &self | ||
331 | - , camera :&Camera<T> | ||
332 | - , light :&DirectLight<T> | ||
333 | - , color :u32 ) -> Vec<(Polygon<T>, u32)> { | ||
334 | - // Helper to create a Polygon from Coordinates… | ||
335 | - // TODO probably there needs to be a Polygon constructor for this. | ||
336 | - fn polygon<I, T>(c :I) -> Polygon<T> | ||
337 | - where I: Iterator<Item = Coordinate<T>> { | ||
338 | - Polygon(Coordinates(c.collect())) | ||
339 | - } | ||
340 | - | ||
341 | - // this one does the projection... as the projection was the last | ||
342 | - // matrix we do not need to do it here. | ||
343 | - let to_coord = |p :&usize| { | ||
344 | - let Point(v, _) = camera.project(self.points[*p]); | ||
345 | - Coordinate(T::round(&v.x()), T::round(&v.y()), v.z() - 1.into()) | ||
346 | - }; | ||
347 | - let to_poly = |f :&Face<T>| { | ||
348 | - let pg = polygon(f.corners.iter().map(to_coord)); | ||
349 | - let mut r :T = (((color >> 16) & 0xFF) as i32).into(); | ||
350 | - let mut g :T = (((color >> 8) & 0xFF) as i32).into(); | ||
351 | - let mut b :T = (((color ) & 0xFF) as i32).into(); | ||
352 | - let lf :T = match f.normal { | ||
353 | - None => 1.into(), | ||
354 | - Some(n) => n.dot(light.dir()) | ||
355 | - / (n.mag() * light.dir().mag()), | ||
356 | - }; | ||
357 | - | ||
358 | - // this "if" represents a first simple backface culling | ||
359 | - // approach. We only return face that face towards us. | ||
360 | - if lf < 0.into() { | ||
361 | - r = r * -lf; | ||
362 | - g = g * -lf; | ||
363 | - b = b * -lf; | ||
364 | - | ||
365 | - let c :u32 = (r.round() as u32) << 16 | ||
366 | - | (g.round() as u32) << 8 | ||
367 | - | (b.round() as u32); | ||
368 | - | ||
369 | - Some((pg, c)) | ||
370 | - } else { | ||
371 | - None | ||
372 | - }}; | ||
373 | - | ||
374 | - self.faces.iter().filter_map(to_poly).collect() | ||
375 | - } | ||
376 | -} |
fractional/src/lib.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Lib for fractional calculations. | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | -extern crate lazy_static; | ||
22 | - | ||
23 | -pub type Error = &'static str; | ||
24 | - | ||
25 | -pub mod continuous; | ||
26 | -pub mod easel; | ||
27 | -pub mod fractional; | ||
28 | -pub mod transform; | ||
29 | -pub mod trigonometry; | ||
30 | -pub mod vector; | ||
31 | -pub mod xcb; | ||
32 | -pub mod geometry; | ||
33 | - | ||
34 | -use fractional::Fractional; | ||
35 | -use vector::Vector; |
fractional/src/main.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Test our fractional crate / module... | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | -use std::convert::{TryFrom, TryInto, Into}; | ||
22 | -use std::f64::consts::PI as FPI; | ||
23 | -use std::fmt::{Debug, Display}; | ||
24 | -use std::marker::Send; | ||
25 | -use std::num::TryFromIntError; | ||
26 | -use std::ops::{Add,Sub,Neg,Mul,Div}; | ||
27 | -use std::sync::mpsc; | ||
28 | -use std::thread; | ||
29 | -use std::time::{Duration, Instant}; | ||
30 | - | ||
31 | -use fractional::continuous::Continuous; | ||
32 | -use fractional::easel::{ Coordinate, Coordinates, Drawable, Line, Polyline | ||
33 | - , Polygon, Canvas, Fillable }; | ||
34 | -use fractional::fractional::{Fractional, from_vector}; | ||
35 | -use fractional::trigonometry::Trig; | ||
36 | -use fractional::vector::Vector; | ||
37 | -use fractional::transform::{TMatrix, Transformable}; | ||
38 | -use fractional::xcb::XcbEasel; | ||
39 | -use fractional::geometry::{Camera, DirectLight, Polyeder, Primitives}; | ||
40 | - | ||
41 | -fn mean(v: &Vec<i64>) -> Result<Fractional, TryFromIntError> { | ||
42 | - let r = v.iter().fold(0, |acc, x| acc + x); | ||
43 | - let l = i64::try_from(v.len())?; | ||
44 | - Ok(Fractional(r, l)) | ||
45 | -} | ||
46 | - | ||
47 | -fn common_fractional() { | ||
48 | - let a = vec![3, 6, 1, 9]; | ||
49 | - let b = from_vector(&a); | ||
50 | - let c = mean(&a).unwrap(); // This might fail if the len of the | ||
51 | - // vector (usize) does not fit into i32. | ||
52 | - let cr :f64 = c.try_into().unwrap(); | ||
53 | - | ||
54 | - println!(" [i32] : {:?}", a); | ||
55 | - println!(" [Fractional] : {:?}", b); | ||
56 | - println!(" mean of [i32] : {}" , c); | ||
57 | - println!(" as f64 : {}" , cr); | ||
58 | - println!(" again as f64 : {}" , TryInto::<f64>::try_into(c).unwrap()); | ||
59 | -} | ||
60 | - | ||
61 | -fn continuous() { | ||
62 | - let d = Fractional(45, 16); | ||
63 | - let e = Fractional(16, 45); | ||
64 | - | ||
65 | - let dc :Continuous = (&d).into(); | ||
66 | - let ec :Continuous = (&e).into(); | ||
67 | - | ||
68 | - println!("cont frac of d : {} => {:?}", d, dc); | ||
69 | - println!("cont frac of e : {} => {:?}", e, ec); | ||
70 | - println!(" reverted dc : {:?} {}", dc, Into::<Fractional>::into(&dc)); | ||
71 | - println!(" reverted ec : {:?} {}", ec, Into::<Fractional>::into(&ec)); | ||
72 | -} | ||
73 | - | ||
74 | -fn sqrt() { | ||
75 | - let f = Fractional(-9, 4); | ||
76 | - let fr :f64 = f.try_into().unwrap(); | ||
77 | - let sq = f.sqrt(); | ||
78 | - let _sq = fr.sqrt(); | ||
79 | - | ||
80 | - println!("{:>14} : {:?} / {}", format!("sqrt {}", f), sq, _sq); | ||
81 | - | ||
82 | - for f in [ Fractional(9, 4) | ||
83 | - , Fractional(45, 16) | ||
84 | - , Fractional(16, 45) | ||
85 | - , Fractional(9, 3) ].iter() { | ||
86 | - let fr :f64 = (*f).try_into().unwrap(); | ||
87 | - let sq = f.sqrt().unwrap(); | ||
88 | - let sqr :f64 = sq.try_into().unwrap(); | ||
89 | - let _sqr = fr.sqrt(); | ||
90 | - | ||
91 | - println!("{:>14} : {} {} / {}", format!("sqrt {}", f), sq, sqr, _sqr); | ||
92 | - } | ||
93 | -} | ||
94 | - | ||
95 | -fn pi() { | ||
96 | - let pi = Fractional::pi(); | ||
97 | - let pir :f64 = pi.try_into().unwrap(); | ||
98 | - let pit :(i32, i32) = pi.try_into().unwrap(); | ||
99 | - let pi2r :f64 = (pi * pi).try_into().unwrap(); | ||
100 | - | ||
101 | - println!(" Rust π : {}" , FPI); | ||
102 | - println!(" π : {} {}" , pi, pir); | ||
103 | - println!(" π as tuple : {:?}" , pit); | ||
104 | - println!(" Rust π² : {}" , FPI * FPI); | ||
105 | - println!(" π² : {} {}" , pi * pi, pi2r); | ||
106 | -} | ||
107 | - | ||
108 | -fn _sin() { | ||
109 | - for d in [ 0, 30, 45, 90, 135, 180, 225, 270, 315 | ||
110 | - , 9, 17, 31, 73, 89, 123, 213, 312, 876 ].iter() { | ||
111 | - let s = Fractional::sin(*d as i32); | ||
112 | - let sr :f64 = s.try_into().unwrap(); | ||
113 | - let _s = f64::sin(*d as f64 * FPI / 180.0); | ||
114 | - | ||
115 | - println!("{:>14} : {} {} / {}", format!("sin {}", d), s, sr, _s); | ||
116 | - } | ||
117 | -} | ||
118 | - | ||
119 | -fn _tan() { | ||
120 | - for d in [ 0, 30, 45, 90, 135, 180, 225, 270, 315 | ||
121 | - , 9, 17, 31, 73, 89, 123, 213, 312, 876 ].iter() { | ||
122 | - let t = Fractional::tan(*d as i32); | ||
123 | - let tr :f64 = t.try_into().unwrap(); | ||
124 | - let _t = f64::tan(*d as f64 * FPI / 180.0); | ||
125 | - | ||
126 | - println!("{:>14} : {} {} / {}", format!("tan {}", d), t, tr, _t); | ||
127 | - } | ||
128 | -} | ||
129 | - | ||
130 | -fn _cos() { | ||
131 | - for d in [ 0, 30, 45, 90, 135, 180, 225, 270, 315 | ||
132 | - , 9, 17, 31, 73, 89, 123, 213, 312, 876 ].iter() { | ||
133 | - let c = Fractional::cos(*d as i32); | ||
134 | - let cr :f64 = c.try_into().unwrap(); | ||
135 | - let _c = f64::cos(*d as f64 * FPI / 180.0); | ||
136 | - | ||
137 | - println!("{:>14} : {} {} / {}", format!("cos {}", d), c, cr, _c); | ||
138 | - } | ||
139 | -} | ||
140 | - | ||
141 | -fn _vector1() { | ||
142 | - let v1 = Vector(1.into(), 2.into(), 3.into()); | ||
143 | - let v2 = Vector(2.into(), 2.into(), 3.into()); | ||
144 | - let s :Fractional = 3.into(); | ||
145 | - | ||
146 | - _vector(v1, v2, s); | ||
147 | -} | ||
148 | - | ||
149 | -fn _vector2() { | ||
150 | - let v1 = Vector(1.0, 2.0, 3.0); | ||
151 | - let v2 = Vector(2.0, 2.0, 3.0); | ||
152 | - let s = 3.0; | ||
153 | - | ||
154 | - _vector(v1, v2, s); | ||
155 | -} | ||
156 | - | ||
157 | -fn _vector<T>(v1 :Vector<T>, v2 :Vector<T>, s :T) | ||
158 | - where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
159 | - + Mul<Output = T> + Div<Output = T> + Trig + Copy + Display { | ||
160 | - println!("{:>14} : {}", "Vector v1", v1); | ||
161 | - println!("{:>14} : {}", "Vector v2", v2); | ||
162 | - println!("{:>14} : {}", "magnitude v1", v1.mag()); | ||
163 | - println!("{:>14} : {}", "-v1", -v1); | ||
164 | - println!("{:>14} : {}", "v1 + v1", v1 + v1); | ||
165 | - println!("{:>14} : {}", "v1 - v1", v1 - v1); | ||
166 | - println!("{:>14} : {}", "v2 - v1", v2 - v1); | ||
167 | - println!("{:>14} : {}", format!("v1 * {}", s), v1.mul(&s)); | ||
168 | - println!("{:>14} : {}", "norm v1", v1.norm()); | ||
169 | - println!("{:>14} : {}", "magnitude norm v1", v1.norm().mag()); | ||
170 | - println!("{:>14} : {}", "magnitude v1", v1.mag()); | ||
171 | - println!("{:>14} : {}", "norm * magnitude", v1.norm().mul(&v1.mag())); | ||
172 | - println!("{:>14} : {}", "distance v1 v2", v1.distance(v2)); | ||
173 | - println!("{:>14} : {}", "distance v2 v1", v2.distance(v1)); | ||
174 | - println!("{:>14} : {}", "v1 dot v2", v1.dot(v2)); | ||
175 | - println!("{:>14} : {}", "v2 dot v1", v2.dot(v1)); | ||
176 | - println!("{:>14} : {}", "v1 * v2", v1 * v2); | ||
177 | - println!("{:>14} : {}", "v2 * v1", v2 * v1); | ||
178 | -} | ||
179 | - | ||
180 | -fn _transform1() { | ||
181 | - let v = Vector(Fractional(1,1), Fractional(1,1), Fractional(1,1)); | ||
182 | - let v1 = Vector(Fractional(1,1), Fractional(2,1), Fractional(3,1)); | ||
183 | - let v2 = Vector(Fractional(1,1), Fractional(1,1), Fractional(0,1)); | ||
184 | - let v3 = Vector(Fractional(1,1), Fractional(0,1), Fractional(1,1)); | ||
185 | - | ||
186 | - _transform(v, v1, v2, v3); | ||
187 | -} | ||
188 | - | ||
189 | -fn _transform2() { | ||
190 | - let v = Vector(1.0, 1.0, 1.0); | ||
191 | - let v1 = Vector(1.0, 2.0, 3.0); | ||
192 | - let v2 = Vector(1.0, 1.0, 0.0); | ||
193 | - let v3 = Vector(1.0, 0.0, 1.0); | ||
194 | - | ||
195 | - _transform(v, v1, v2, v3); | ||
196 | -} | ||
197 | - | ||
198 | -fn _transform<T>(v :Vector<T>, v1 :Vector<T>, v2 :Vector<T>, v3 :Vector<T>) | ||
199 | - where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
200 | - + Mul<Output = T> + Div<Output = T> + Trig | ||
201 | - + Debug + From<i32> + Copy + Display { | ||
202 | - | ||
203 | - println!("{:>14} : {}", "Vector v1", v1); | ||
204 | - println!( "{:>14} : {}", "translate v1" | ||
205 | - , v.transform(&TMatrix::translate(v))); | ||
206 | - println!(); | ||
207 | - | ||
208 | - fn _rot<T>( o :&str , n :&str , v :&Vector<T> | ||
209 | - , fs :&[&dyn Fn(i32) -> TMatrix<T>] ) | ||
210 | - where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
211 | - + Mul<Output = T> + Div<Output = T> + Trig | ||
212 | - + Debug + From<i32> + Copy + Display { | ||
213 | - | ||
214 | - for d in [ 30, 45, 60, 90, 120, 135, 150, 180 | ||
215 | - , 210, 225, 240, 270, 300, 315, 330 ].iter() { | ||
216 | - let mi = fs.iter().map(|f| f(*d as i32)); | ||
217 | - println!( "{:>14} : {}" | ||
218 | - , format!("{} {} {}", o, d, n) | ||
219 | - , v.transform(&TMatrix::combine(mi)) ); | ||
220 | - } | ||
221 | - } | ||
222 | - | ||
223 | - println!("{:>14} : {}", "Vector v2", v2); | ||
224 | - _rot("rot_x", "v2", &v2, &[&TMatrix::rotate_x]); | ||
225 | - println!(); | ||
226 | - _rot("rot_y", "v2", &v2, &[&TMatrix::rotate_y]); | ||
227 | - println!(); | ||
228 | - _rot("rot_xy", "v2", &v2, &[&TMatrix::rotate_x, &TMatrix::rotate_y]); | ||
229 | - println!(); | ||
230 | - println!("{:>14} : {}", "Vector v3", v3); | ||
231 | - _rot("rot_z", "v3", &v3, &[&TMatrix::rotate_z]); | ||
232 | - println!(); | ||
233 | - | ||
234 | - for d in [ 30, 45, 60, 90, 120, 135, 150, 180 | ||
235 | - , 210, 225, 240, 270, 300, 315, 330 ].iter() { | ||
236 | - println!( "{:>14} : {}" | ||
237 | - , format!("rot_v {} v2", d) | ||
238 | - , v2.transform(&TMatrix::rotate_v(&v, *d as i32)) ); | ||
239 | - } | ||
240 | -} | ||
241 | - | ||
242 | -fn _line() { | ||
243 | - let a = (Coordinate(0, 1, 0.0), Coordinate(6, 4, 0.0)); | ||
244 | - let b = (Coordinate(0, 4, 0.0), Coordinate(6, 1, 0.0)); | ||
245 | - let c = (Coordinate(1, 0, 0.0), Coordinate(6, 8, 0.0)); | ||
246 | - let d = (Coordinate(1, 8, 0.0), Coordinate(6, 0, 0.0)); | ||
247 | - | ||
248 | - for i in [a, b, c, d].iter() { | ||
249 | - println!("{:>14} : {}", Line(i.0, i.1), Line(i.0, i.1).plot()); | ||
250 | - println!("{:>14} : {}", Line(i.1, i.0), Line(i.1, i.0).plot()); | ||
251 | - } | ||
252 | - | ||
253 | - println!(); | ||
254 | - let pl = Polyline( | ||
255 | - Coordinates(vec!(a.0, a.1, b.0, b.1, c.0, c.1, d.0, d.1))); | ||
256 | - println!("{:>14} : {}", pl, pl.plot()); | ||
257 | - | ||
258 | - println!(); | ||
259 | - let pg = Polygon( | ||
260 | - Coordinates(vec!( Coordinate( 0, -10, 0.0) | ||
261 | - , Coordinate( 10, 10, 0.0) | ||
262 | - , Coordinate(-10, 10, 0.0) ))); | ||
263 | - println!("{:>14} : {}", pg, pg.plot()); | ||
264 | - | ||
265 | - let i = Vector(Fractional( 0,1), Fractional(-30,1), Fractional(0,1)); | ||
266 | - let j = Vector(Fractional( 30,1), Fractional( 30,1), Fractional(0,1)); | ||
267 | - let k = Vector(Fractional(-30,1), Fractional( 30,1), Fractional(0,1)); | ||
268 | - | ||
269 | - let rot :TMatrix<Fractional> = TMatrix::rotate_z(20); | ||
270 | - let Vector(ix, iy, _) = i.transform(&rot); | ||
271 | - let Vector(jx, jy, _) = j.transform(&rot); | ||
272 | - let Vector(kx, ky, _) = k.transform(&rot); | ||
273 | - | ||
274 | - fn to_i32(x :Fractional) -> i32 { | ||
275 | - let Fractional(n, d) = x; | ||
276 | - (n / d + if (n % d).abs() < (n / 2).abs() { 0 } else { 1 }) as i32 | ||
277 | - } | ||
278 | - | ||
279 | - println!(); | ||
280 | - let pg = Polygon( | ||
281 | - Coordinates(vec!( Coordinate(to_i32(ix) + 100, to_i32(iy) + 100, 0.0) | ||
282 | - , Coordinate(to_i32(jx) + 100, to_i32(jy) + 100, 0.0) | ||
283 | - , Coordinate(to_i32(kx) + 100, to_i32(ky) + 100, 0.0) ))); | ||
284 | - println!("{:>14} : {}", pg, pg.plot()); | ||
285 | - | ||
286 | - let i = Vector( 0.0, -30.0, 0.0); | ||
287 | - let j = Vector( 30.0, 30.0, 0.0); | ||
288 | - let k = Vector(-30.0, 30.0, 0.0); | ||
289 | - | ||
290 | - let rot :TMatrix<f64> = TMatrix::rotate_z(20); | ||
291 | - let Vector(ix, iy, _) = i.transform(&rot); | ||
292 | - let Vector(jx, jy, _) = j.transform(&rot); | ||
293 | - let Vector(kx, ky, _) = k.transform(&rot); | ||
294 | - | ||
295 | - fn to_i32_2(x :f64) -> i32 { | ||
296 | - x.round() as i32 | ||
297 | - } | ||
298 | - | ||
299 | - println!(); | ||
300 | - let pg = Polygon( | ||
301 | - Coordinates(vec!( Coordinate(to_i32_2(ix) + 100, to_i32_2(iy) + 100, 0.0) | ||
302 | - , Coordinate(to_i32_2(jx) + 100, to_i32_2(jy) + 100, 0.0) | ||
303 | - , Coordinate(to_i32_2(kx) + 100, to_i32_2(ky) + 100, 0.0) ))); | ||
304 | - println!("{:>14} : {}", pg, pg.plot()); | ||
305 | -} | ||
306 | - | ||
307 | -fn _democanvas<T>( xcb :&XcbEasel | ||
308 | - , title :&'static str | ||
309 | - , tx :mpsc::Sender<i32> | ||
310 | - , _triangle :Polyeder<T> | ||
311 | - , tetrahedron :Polyeder<T> | ||
312 | - , cube :Polyeder<T> | ||
313 | - , light :DirectLight<T> ) | ||
314 | - where T: 'static + Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
315 | - + Mul<Output = T> + Div<Output = T> | ||
316 | - + Debug + Copy + Trig + Send + From<i32> + PartialOrd { | ||
317 | - | ||
318 | - let mut canvas = xcb.canvas(151, 151).unwrap(); | ||
319 | - let camera = Camera::<T>::new(&canvas, 45); // the orig. view angle | ||
320 | - // was 50. | ||
321 | - | ||
322 | - canvas.set_title(title); | ||
323 | - canvas.init_events(); | ||
324 | - canvas.start_events(tx.clone()); | ||
325 | - | ||
326 | - thread::spawn(move || { | ||
327 | - let start = Instant::now(); | ||
328 | - let step = Duration::from_millis(25); | ||
329 | - let mut last = Instant::now(); | ||
330 | - | ||
331 | - let t = TMatrix::translate(Vector(0.into() , 0.into() , 150.into())); | ||
332 | - | ||
333 | - loop { | ||
334 | - let deg = ((start.elapsed() / 25).as_millis() % 360) as i32; | ||
335 | - | ||
336 | - let rz = TMatrix::rotate_z(deg); | ||
337 | - let rx = TMatrix::rotate_x(-deg*2); | ||
338 | - let ry = TMatrix::rotate_y(-deg*2); | ||
339 | - | ||
340 | - let rot1 = TMatrix::combine(vec!(rz, rx, t)); | ||
341 | - let rot2 = TMatrix::combine(vec!(rz, ry, t)); | ||
342 | - | ||
343 | - let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) | ||
344 | - , ( cube.transform(&rot2), 0x0000FF) ); | ||
345 | - //let objects = vec!( ( cube.transform(&rot2), 0x0000FF) ); | ||
346 | - //let objects = vec!( (tetrahedron.transform(&rot1), 0xFFFF00) ); | ||
347 | - //let objects = vec!( (triangle.transform(&rot1), 0xFFFF00) ); | ||
348 | - | ||
349 | - canvas.clear(); | ||
350 | - | ||
351 | - for (o, color) in objects { | ||
352 | - for (pg, c) in o.project(&camera, &light, color) { | ||
353 | - //canvas.draw(&pg, Coordinate(0, 0, 0.into()), c); | ||
354 | - (&pg).fill(&mut canvas, c); | ||
355 | - //(&pg).debug(); | ||
356 | - //println!("\n"); | ||
357 | - } | ||
358 | - } | ||
359 | - | ||
360 | - let passed = Instant::now() - last; | ||
361 | - let f = (passed.as_nanos() / step.as_nanos()) as u32; | ||
362 | - | ||
363 | - if f > 1 { | ||
364 | - println!("{} !!! Detected frame drop", title); | ||
365 | - } | ||
366 | - | ||
367 | - last = last + step*(f + 1); | ||
368 | - canvas.put_text( Coordinate(10, 15, 0.into()) | ||
369 | - , &format!( "sleep: {:?}" | ||
370 | - , last - Instant::now() )); | ||
371 | - canvas.show(); | ||
372 | - thread::sleep(last - Instant::now()); | ||
373 | - } | ||
374 | - }); | ||
375 | -} | ||
376 | - | ||
377 | -fn main() { | ||
378 | - common_fractional(); | ||
379 | - println!(); | ||
380 | - continuous(); | ||
381 | - println!(); | ||
382 | - sqrt(); | ||
383 | - println!(); | ||
384 | - pi(); | ||
385 | - println!(); | ||
386 | - _sin(); | ||
387 | - println!(); | ||
388 | - _cos(); | ||
389 | - println!(); | ||
390 | - _tan(); | ||
391 | - println!(); | ||
392 | - _vector1(); | ||
393 | - println!(); | ||
394 | - _vector2(); | ||
395 | - println!(); | ||
396 | - _transform1(); | ||
397 | - println!(); | ||
398 | - _transform2(); | ||
399 | - println!(); | ||
400 | - _line(); | ||
401 | - | ||
402 | - let xcb = XcbEasel::new().unwrap(); | ||
403 | - let (tx, rx) = mpsc::channel(); | ||
404 | - | ||
405 | - | ||
406 | - _democanvas( &xcb, "Something...(f64)", tx.clone() | ||
407 | - , Polyeder::triangle(60.0) | ||
408 | - , Polyeder::tetrahedron(100.0) | ||
409 | - , Polyeder::cube(56.25) | ||
410 | - , DirectLight::new(Vector(0.0, 0.0, 1.0)) ); | ||
411 | - /* | ||
412 | - _democanvas( &xcb, "Something...(Fractional)", tx.clone() | ||
413 | - , Polyeder::triangle(Fractional(60,1)) | ||
414 | - , Polyeder::tetrahedron(Fractional(80,1)) | ||
415 | - , Polyeder::cube(Fractional(55,1)) | ||
416 | - , DirectLight::new(Vector( Fractional(0,1) | ||
417 | - , Fractional(0,1) | ||
418 | - , Fractional(1,1) )) ); | ||
419 | - */ | ||
420 | - | ||
421 | - for x in rx { | ||
422 | - match x { | ||
423 | - 1 => break, | ||
424 | - _ => {}, | ||
425 | - } | ||
426 | - } | ||
427 | -} |
fractional/src/trigonometry.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Some trigonometic functions with Fractions results. | ||
3 | -// Currently only sin, cos and tan are implemented. | ||
4 | -// As I was unable to find a really good integral approximation for them I | ||
5 | -// implement them as a table which is predefined using the floating point | ||
6 | -// function f64::sin and then transformed into a fraction of a given | ||
7 | -// PRECISION. | ||
8 | -// These approximations are quite good and for a few edge cases | ||
9 | -// even better than the floating point implementations. | ||
10 | -// | ||
11 | -// Georg Hopp <georg@steffers.org> | ||
12 | -// | ||
13 | -// Copyright © 2019 Georg Hopp | ||
14 | -// | ||
15 | -// This program is free software: you can redistribute it and/or modify | ||
16 | -// it under the terms of the GNU General Public License as published by | ||
17 | -// the Free Software Foundation, either version 3 of the License, or | ||
18 | -// (at your option) any later version. | ||
19 | -// | ||
20 | -// This program is distributed in the hope that it will be useful, | ||
21 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | -// GNU General Public License for more details. | ||
24 | -// | ||
25 | -// You should have received a copy of the GNU General Public License | ||
26 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
27 | -// | ||
28 | -use std::cmp::Ordering; | ||
29 | -use std::ops::Div; | ||
30 | -use std::ops::Neg; | ||
31 | -use std::marker::Sized; | ||
32 | -use crate::{Fractional, Error}; | ||
33 | -use crate::continuous::Continuous; | ||
34 | - | ||
35 | -pub trait Trig { | ||
36 | - fn pi() -> Self; | ||
37 | - fn recip(self) -> Self; | ||
38 | - fn round(&self) -> i32; | ||
39 | - fn sqrt(self) -> Result<Self, Error> where Self: Sized; | ||
40 | - fn sintab() -> Vec<Self> where Self: Sized; | ||
41 | - fn tantab() -> Vec<Self> where Self: Sized; | ||
42 | - | ||
43 | - fn sin(d :i32) -> Self | ||
44 | - where Self: Sized + Neg<Output = Self> + Copy { | ||
45 | - match d { | ||
46 | - 0 ..=90 => Self::sintab()[d as usize], | ||
47 | - 91 ..=180 => Self::sintab()[180 - d as usize], | ||
48 | - 181..=270 => -Self::sintab()[d as usize - 180], | ||
49 | - 271..=359 => -Self::sintab()[360 - d as usize], | ||
50 | - _ => { | ||
51 | - Self::sin(if d < 0 { d % 360 + 360 } else { d % 360 }) | ||
52 | - }, | ||
53 | - } | ||
54 | - } | ||
55 | - | ||
56 | - fn cos(d :i32) -> Self | ||
57 | - where Self: Sized + Neg<Output = Self> + Copy { | ||
58 | - match d { | ||
59 | - 0 ..=90 => Self::sintab()[90 - d as usize], | ||
60 | - 91 ..=180 => -Self::sintab()[90 - (180 - d as usize)], | ||
61 | - 181..=270 => -Self::sintab()[90 - (d as usize - 180)], | ||
62 | - 271..=359 => Self::sintab()[90 - (360 - d as usize)], | ||
63 | - _ => { | ||
64 | - Self::cos(if d < 0 { d % 360 + 360 } else { d % 360 }) | ||
65 | - }, | ||
66 | - } | ||
67 | - } | ||
68 | - | ||
69 | - fn tan(d :i32) -> Self where Self: Sized + Copy { | ||
70 | - match d { | ||
71 | - 0 ..=179 => Self::tantab()[d as usize], | ||
72 | - 180..=359 => Self::tantab()[d as usize - 180], | ||
73 | - _ => { | ||
74 | - Self::tan(if d < 0 { d % 360 + 360 } else { d % 360 }) | ||
75 | - }, | ||
76 | - } | ||
77 | - } | ||
78 | - | ||
79 | - fn cot(d :i32) -> Self | ||
80 | - where Self: Sized + Copy + From<i32> + Div<Output = Self> { | ||
81 | - Into::<Self>::into(1) / Self::tan(d) | ||
82 | - } | ||
83 | -} | ||
84 | - | ||
85 | -// Try to keep precision as high as possible while having a denominator | ||
86 | -// as small as possible. The values are taken by try and error. | ||
87 | -const PRECISION :i64 = 1000000; | ||
88 | -const MAX_DENOMINATOR :i64 = 7000; | ||
89 | - | ||
90 | -// This is a really close fractional approximation for pi. | ||
91 | -impl Trig for Fractional { | ||
92 | - fn pi() -> Self { | ||
93 | - Fractional(355, 113) | ||
94 | - } | ||
95 | - | ||
96 | - fn recip(self) -> Self { | ||
97 | - let Fractional(n, d) = self; | ||
98 | - Fractional(d, n) | ||
99 | - } | ||
100 | - | ||
101 | - fn round(&self) -> i32 { | ||
102 | - let Fractional(n, d) = self; | ||
103 | - (n / d) as i32 | ||
104 | - } | ||
105 | - | ||
106 | - // This is a really bad approximation of sqrt for a fractional... | ||
107 | - // for (9/3) it will result 3 which if way to far from the truth, | ||
108 | - // which is ~1.7320508075 | ||
109 | - // BUT we can use this value as starting guess for creating a | ||
110 | - // continous fraction for the sqrt... and create a much better | ||
111 | - // fractional representation of the sqrt. | ||
112 | - // So, if inner converges, but is not a perfect square (does not | ||
113 | - // end up in an Ordering::Equal - which is the l > h case) | ||
114 | - // we use the l - 1 as starting guess for sqrt_cfrac. | ||
115 | - // taken from: | ||
116 | - // https://www.geeksforgeeks.org/square-root-of-an-integer/ | ||
117 | - fn sqrt(self) -> Result<Self, Error> { | ||
118 | - // find the sqrt of x in O(log x/2). | ||
119 | - // This stops if a perfect sqare was found. Else it passes | ||
120 | - // the found value as starting guess to the continous fraction | ||
121 | - // sqrt function. | ||
122 | - fn floor_sqrt(x :i64) -> Fractional { | ||
123 | - fn inner(l :i64, h :i64, x :i64) -> Fractional { | ||
124 | - if l > h { | ||
125 | - (&Continuous::sqrt(x, l - 1)).into() | ||
126 | - } else { | ||
127 | - let m = (l + h) / 2; | ||
128 | - match x.cmp(&(m * m)) { | ||
129 | - Ordering::Equal => m.into(), | ||
130 | - Ordering::Less => inner(l, m - 1, x), | ||
131 | - Ordering::Greater => inner(m + 1, h, x), | ||
132 | - } | ||
133 | - } | ||
134 | - } | ||
135 | - | ||
136 | - match x { | ||
137 | - 0 => 0.into(), | ||
138 | - 1 => 1.into(), | ||
139 | - _ => inner(1, x / 2, x), | ||
140 | - } | ||
141 | - } | ||
142 | - | ||
143 | - let Fractional(n, d) = self; | ||
144 | - | ||
145 | - let n = match n.cmp(&0) { | ||
146 | - Ordering::Equal => 0.into(), | ||
147 | - Ordering::Less => return Err("sqrt on negative undefined"), | ||
148 | - Ordering::Greater => floor_sqrt(n), | ||
149 | - }; | ||
150 | - | ||
151 | - let d = match d.cmp(&0) { | ||
152 | - Ordering::Equal => 0.into(), | ||
153 | - Ordering::Less => return Err("sqrt on negative undefined"), | ||
154 | - Ordering::Greater => floor_sqrt(d), | ||
155 | - }; | ||
156 | - | ||
157 | - Ok(n / d) | ||
158 | - } | ||
159 | - | ||
160 | - fn sintab() -> Vec<Self> { | ||
161 | - // hold sin Fractionals from 0 to 89 ... | ||
162 | - // luckily with a bit of index tweeking this can also be used for | ||
163 | - // cosine values. | ||
164 | - lazy_static::lazy_static! { | ||
165 | - static ref SINTAB :Vec<Fractional> = | ||
166 | - (0..=90).map(|x| _sin(x)).collect(); | ||
167 | - } | ||
168 | - | ||
169 | - // fractional sin from f64 sin. (From 0° to 90°) | ||
170 | - fn _sin(d: u32) -> Fractional { | ||
171 | - match d { | ||
172 | - 0 => Fractional(0, 1), | ||
173 | - 90 => Fractional(1, 1), | ||
174 | - _ => generate(d, PRECISION, &f64::sin), | ||
175 | - } | ||
176 | - } | ||
177 | - | ||
178 | - SINTAB.to_vec() | ||
179 | - } | ||
180 | - | ||
181 | - fn tantab() -> Vec<Self> { | ||
182 | - // This table exists only because the sin(α) / cos(α) method | ||
183 | - // yields very large unreducable denominators in a lot of cases. | ||
184 | - lazy_static::lazy_static! { | ||
185 | - static ref TANTAB :Vec<Fractional> = | ||
186 | - (0..180).map(|x| _tan(x)).collect(); | ||
187 | - } | ||
188 | - | ||
189 | - // fractional tan from f64 tan. (From 0° to 179°) | ||
190 | - fn _tan(d: u32) -> Fractional { | ||
191 | - match d { | ||
192 | - 0 => Fractional(0, 1), | ||
193 | - 45 => Fractional(1, 1), | ||
194 | - 90 => Fractional(1, 0), // although they are both inf and -inf. | ||
195 | - 135 => -Fractional(1, 1), | ||
196 | - _ => generate(d, PRECISION, &f64::tan), | ||
197 | - } | ||
198 | - } | ||
199 | - | ||
200 | - TANTAB.to_vec() | ||
201 | - } | ||
202 | -} | ||
203 | - | ||
204 | -// search for a fraction with a denominator less than MAX_DENOMINATOR that | ||
205 | -// provides the minimal PRECISION criteria. | ||
206 | -// !! With f = &f64::tan and d close to the inf boundarys of tan | ||
207 | -// we get very large numerators because the numerator becomes a | ||
208 | -// multiple of the denominator. | ||
209 | -fn generate(d :u32, p :i64, f :&dyn Fn(f64) -> f64) -> Fractional { | ||
210 | - // This is undefined behaviour for very large f64, but our f64 | ||
211 | - // is always between 0.0 and 1000000.0 which should be fine. | ||
212 | - let s = (f((d as f64).to_radians()) * p as f64).round() as i64; | ||
213 | - let Fractional(n, dn) = Fractional(s, p).reduce(); | ||
214 | - match dn.abs().cmp(&MAX_DENOMINATOR) { | ||
215 | - Ordering::Less => Fractional(n, dn), | ||
216 | - _ => generate(d, p + 1, f), | ||
217 | - } | ||
218 | -} | ||
219 | - | ||
220 | -impl Trig for f64 { | ||
221 | - fn pi() -> Self { | ||
222 | - std::f64::consts::PI | ||
223 | - } | ||
224 | - | ||
225 | - fn recip(self) -> Self { | ||
226 | - self.recip() | ||
227 | - } | ||
228 | - | ||
229 | - fn round(&self) -> i32 { | ||
230 | - f64::round(*self) as i32 | ||
231 | - } | ||
232 | - | ||
233 | - fn sqrt(self) -> Result<Self, Error> { | ||
234 | - let x = self.sqrt(); | ||
235 | - match x.is_nan() { | ||
236 | - true => Err("sqrt on negative undefined"), | ||
237 | - false => Ok(x), | ||
238 | - } | ||
239 | - } | ||
240 | - | ||
241 | - fn sintab() -> Vec<Self> { | ||
242 | - lazy_static::lazy_static! { | ||
243 | - static ref SINTAB :Vec<f64> = | ||
244 | - (0..=90).map(|x| _sin(x)).collect(); | ||
245 | - } | ||
246 | - | ||
247 | - // f64 sin. (From 0° to 90°) | ||
248 | - fn _sin(d: u32) -> f64 { | ||
249 | - match d { | ||
250 | - 0 => 0.0, | ||
251 | - 90 => 1.0, | ||
252 | - _ => (d as f64).to_radians().sin(), | ||
253 | - } | ||
254 | - } | ||
255 | - | ||
256 | - SINTAB.to_vec() | ||
257 | - } | ||
258 | - | ||
259 | - fn tantab() -> Vec<Self> { | ||
260 | - // This table exists only because the sin(α) / cos(α) method | ||
261 | - // yields very large unreducable denominators in a lot of cases. | ||
262 | - lazy_static::lazy_static! { | ||
263 | - static ref TANTAB :Vec<f64> = | ||
264 | - (0..180).map(|x| _tan(x)).collect(); | ||
265 | - } | ||
266 | - | ||
267 | - // fractional tan from f64 tan. (From 0° to 179°) | ||
268 | - fn _tan(d: u32) -> f64 { | ||
269 | - match d { | ||
270 | - 0 => 0.0, | ||
271 | - 45 => 1.0, | ||
272 | - 90 => std::f64::INFINITY, | ||
273 | - 135 => -1.0, | ||
274 | - _ => (d as f64).to_radians().tan(), | ||
275 | - } | ||
276 | - } | ||
277 | - | ||
278 | - TANTAB.to_vec() | ||
279 | - } | ||
280 | -} |
fractional/src/xcb.rs
deleted
100644 → 0
1 | -// | ||
2 | -// XCB implementation for drawing some stuff... | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | -extern crate xcb; | ||
22 | - | ||
23 | -use std::sync::Arc; | ||
24 | -use std::ptr; //::{null, null_mut}; | ||
25 | -use std::thread; | ||
26 | -use std::sync::mpsc; | ||
27 | -use std::ops::{Add, Sub, Div}; | ||
28 | - | ||
29 | -use crate::easel::{Easel, Canvas, Drawable, Coordinate, Coordinates}; | ||
30 | - | ||
31 | -#[derive(Clone)] | ||
32 | -pub struct XcbEasel (Arc<xcb::Connection>, i32); | ||
33 | - | ||
34 | -pub struct XcbCanvas<'a, T> { conn :Arc<xcb::Connection> | ||
35 | - , width :u16 | ||
36 | - , height :u16 | ||
37 | - , window :u32 | ||
38 | - , pixmap :u32 | ||
39 | - , gc :u32 | ||
40 | - , zbuf :Vec<T> | ||
41 | - , shm :Box<&'a mut [u32]> } | ||
42 | - | ||
43 | -impl XcbEasel { | ||
44 | - pub fn new() -> Result<XcbEasel, xcb::ConnError> { | ||
45 | - let (conn, num) = xcb::Connection::connect(None)?; | ||
46 | - | ||
47 | - Ok(XcbEasel(Arc::new(conn), num)) | ||
48 | - } | ||
49 | - | ||
50 | - pub fn setup(&self) -> xcb::Setup { | ||
51 | - let XcbEasel(conn, _) = self; | ||
52 | - conn.get_setup() | ||
53 | - } | ||
54 | - | ||
55 | - pub fn screen(&self) -> Option<xcb::Screen> { | ||
56 | - let XcbEasel(_, num) = self; | ||
57 | - self.setup().roots().nth(*num as usize) | ||
58 | - } | ||
59 | - | ||
60 | - pub fn canvas<'a, T>( &self | ||
61 | - , width :u16 | ||
62 | - , height :u16) -> Option<XcbCanvas<'a, T>> | ||
63 | - where T: Clone + From<i32> { | ||
64 | - let Self(conn, _) = self; | ||
65 | - let conn = conn.clone(); | ||
66 | - let screen = match self.screen() { | ||
67 | - None => return None, | ||
68 | - Some(screen) => screen, | ||
69 | - }; | ||
70 | - | ||
71 | - println!("root depth: {}", screen.root_depth()); | ||
72 | - | ||
73 | - let shmseg = conn.generate_id(); | ||
74 | - let gc = conn.generate_id(); | ||
75 | - let pixmap = conn.generate_id(); | ||
76 | - let window = conn.generate_id(); | ||
77 | - | ||
78 | - xcb::create_window( &conn, xcb::COPY_FROM_PARENT as u8, window | ||
79 | - , screen.root(), 0, 0, width, width, 0 | ||
80 | - , xcb::WINDOW_CLASS_INPUT_OUTPUT as u16 | ||
81 | - , screen.root_visual() | ||
82 | - , &[(xcb::CW_BACK_PIXEL, screen.black_pixel())] ); | ||
83 | - | ||
84 | - xcb::create_gc( &conn, gc, screen.root() | ||
85 | - , &[ (xcb::GC_FOREGROUND, screen.white_pixel()) | ||
86 | - , (xcb::GC_GRAPHICS_EXPOSURES, 0) ] ); | ||
87 | - | ||
88 | - let zbuf :Vec<T> = vec!(0.into(); (width * height) as usize); | ||
89 | - let (shmid, shm) = getshm((width * height) as usize); | ||
90 | - xcb::shm::attach(&conn, shmseg, shmid as u32, false); | ||
91 | - unsafe { libc::shmctl(shmid, libc::IPC_RMID, ptr::null_mut()); } | ||
92 | - | ||
93 | - xcb::shm::create_pixmap( &conn, pixmap, window, width, height | ||
94 | - , screen.root_depth(), shmseg, 0 ); | ||
95 | - | ||
96 | - xcb::map_window(&conn, window); | ||
97 | - conn.flush(); | ||
98 | - | ||
99 | - Some(XcbCanvas{ conn: conn | ||
100 | - , width: width | ||
101 | - , height: height | ||
102 | - , window: window | ||
103 | - , pixmap: pixmap | ||
104 | - , gc: gc | ||
105 | - , zbuf: zbuf | ||
106 | - , shm: Box::new(shm) } ) | ||
107 | - } | ||
108 | -} | ||
109 | - | ||
110 | -impl<'a, T> XcbCanvas<'a, T> { | ||
111 | - pub fn set_title(&self, title :&str) { | ||
112 | - let c = xcb::change_property_checked( &self.conn | ||
113 | - , xcb::PROP_MODE_REPLACE as u8 | ||
114 | - , self.window | ||
115 | - , xcb::ATOM_WM_NAME | ||
116 | - , xcb::ATOM_STRING | ||
117 | - , 8 | ||
118 | - , title.as_bytes() ); | ||
119 | - if self.conn.has_error().is_err() || c.request_check().is_err() { | ||
120 | - println!("Error setting title"); | ||
121 | - } | ||
122 | - } | ||
123 | -} | ||
124 | - | ||
125 | -fn getshm<'a>(size :usize) -> (i32, &'a mut [u32]) { | ||
126 | - use std::slice::from_raw_parts_mut; | ||
127 | - | ||
128 | - unsafe { | ||
129 | - let id = libc::shmget( libc::IPC_PRIVATE | ||
130 | - , size * 4 | ||
131 | - , libc::IPC_CREAT | 0o744 ); | ||
132 | - let ptr = libc::shmat(id, ptr::null(), 0); | ||
133 | - (id as i32, from_raw_parts_mut(ptr as *mut u32, size)) | ||
134 | - } | ||
135 | -} | ||
136 | - | ||
137 | -impl Easel for XcbEasel {} | ||
138 | - | ||
139 | -impl<'a, T> Canvas<T> for XcbCanvas<'a, T> | ||
140 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
141 | - + Copy + From<i32> + PartialOrd { | ||
142 | - fn init_events(&self) { | ||
143 | - let mask = [( xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE | ||
144 | - | xcb::EVENT_MASK_KEY_PRESS | ||
145 | - | xcb::EVENT_MASK_STRUCTURE_NOTIFY | ||
146 | - | xcb::EVENT_MASK_PROPERTY_CHANGE )]; | ||
147 | - xcb::change_window_attributes(&self.conn, self.window, &mask); | ||
148 | - self.conn.flush(); | ||
149 | - } | ||
150 | - | ||
151 | - fn start_events(&self, tx :mpsc::Sender<i32>) { | ||
152 | - let conn = self.conn.clone(); | ||
153 | - let window = self.window; | ||
154 | - let pixmap = self.pixmap; | ||
155 | - let gc = self.gc; | ||
156 | - let width = self.width; | ||
157 | - let height = self.height; | ||
158 | - | ||
159 | - thread::spawn(move || { | ||
160 | - loop { | ||
161 | - let event = conn.wait_for_event(); | ||
162 | - | ||
163 | - match event { | ||
164 | - None => break, | ||
165 | - Some(event) => { | ||
166 | - match event.response_type() & !0x80 { | ||
167 | - xcb::PROPERTY_NOTIFY => { | ||
168 | - let prop_notify :&xcb::PropertyNotifyEvent | ||
169 | - = unsafe { xcb::cast_event(&event) }; | ||
170 | - | ||
171 | - if prop_notify.atom() == xcb::ATOM_WM_NAME { | ||
172 | - // retrieving title | ||
173 | - let cookie | ||
174 | - = xcb::get_property( &conn | ||
175 | - , false | ||
176 | - , window | ||
177 | - , xcb::ATOM_WM_NAME | ||
178 | - , xcb::ATOM_STRING | ||
179 | - , 0, 1024 ); | ||
180 | - | ||
181 | - if let Ok(reply) = cookie.get_reply() { | ||
182 | - let r = reply.value(); | ||
183 | - let r = std::str::from_utf8(r).unwrap(); | ||
184 | - | ||
185 | - println!("title changed to: {}", r); | ||
186 | - } | ||
187 | - } | ||
188 | - }, | ||
189 | - | ||
190 | - xcb::EXPOSE => { | ||
191 | - xcb::copy_area( &conn, pixmap, window, gc | ||
192 | - , 0, 0, 0, 0 | ||
193 | - , width, height ); | ||
194 | - conn.flush(); | ||
195 | - }, | ||
196 | - | ||
197 | - xcb::KEY_PRESS => { | ||
198 | - let key_press: &xcb::KeyPressEvent | ||
199 | - = unsafe { xcb::cast_event(&event) }; | ||
200 | - | ||
201 | - println!( "Key '{}' pressed" | ||
202 | - , key_press.detail() ); | ||
203 | - | ||
204 | - // Q (on qwerty) | ||
205 | - if key_press.detail() == 0x18 { | ||
206 | - tx.send(1).unwrap(); | ||
207 | - break; | ||
208 | - } | ||
209 | - }, | ||
210 | - | ||
211 | - _ => {}, | ||
212 | - } | ||
213 | - }, | ||
214 | - } | ||
215 | - } | ||
216 | - }); | ||
217 | - } | ||
218 | - | ||
219 | - fn width(&self) -> u16 { | ||
220 | - self.width | ||
221 | - } | ||
222 | - | ||
223 | - fn height(&self) -> u16 { | ||
224 | - self.height | ||
225 | - } | ||
226 | - | ||
227 | - fn clear(&mut self) { | ||
228 | - self.zbuf = vec!(0.into(); self.zbuf.len()); | ||
229 | - unsafe { | ||
230 | - let ptr = self.shm.as_mut_ptr(); | ||
231 | - ptr::write_bytes( ptr, 0 | ||
232 | - , self.width as usize * self.height as usize); | ||
233 | - } | ||
234 | - } | ||
235 | - | ||
236 | - fn draw(&mut self, d :&dyn Drawable<T>, ofs :Coordinate<T>, color: u32) { | ||
237 | - let Coordinates(c) = d.plot(); | ||
238 | - let Coordinate(xofs, yofs, _) = ofs; | ||
239 | - | ||
240 | - for Coordinate(x, y, zr) in c { | ||
241 | - let idx :usize = ((y+yofs)*(self.width as i32)+x+xofs) as usize; | ||
242 | - if self.zbuf[idx] < zr { | ||
243 | - self.zbuf[idx] = zr; | ||
244 | - self.shm[idx] = color; | ||
245 | - } | ||
246 | - } | ||
247 | - } | ||
248 | - | ||
249 | - fn put_text(&self, ofs :Coordinate<T>, s :&str) { | ||
250 | - let Coordinate(xofs, yofs, _) = ofs; | ||
251 | - xcb::xproto::image_text_8( &self.conn, self.pixmap, self.gc | ||
252 | - , xofs as i16, yofs as i16, s ); | ||
253 | - self.conn.flush(); | ||
254 | - } | ||
255 | - | ||
256 | - fn set_pixel(&mut self, c :Coordinate<T>, color :u32) { | ||
257 | - let Coordinate(x, y, zr) = c; | ||
258 | - let idx :usize = (y * (self.width as i32) + x) as usize; | ||
259 | - | ||
260 | - if self.zbuf[idx] < zr { | ||
261 | - self.zbuf[idx] = zr; | ||
262 | - self.shm[idx] = color; | ||
263 | - } | ||
264 | - } | ||
265 | - | ||
266 | - fn show(&self) { | ||
267 | - xcb::copy_area( &self.conn, self.pixmap, self.window, self.gc | ||
268 | - , 0, 0, 0, 0 | ||
269 | - , self.width, self.height ); | ||
270 | - self.conn.flush(); | ||
271 | - } | ||
272 | -} |
functions/Cargo.lock
deleted
100644 → 0
functions/Cargo.toml
deleted
100644 → 0
functions/src/main.rs
deleted
100644 → 0
guessing_game/Cargo.lock
deleted
100644 → 0
1 | -# This file is automatically @generated by Cargo. | ||
2 | -# It is not intended for manual editing. | ||
3 | -[[package]] | ||
4 | -name = "fuchsia-cprng" | ||
5 | -version = "0.1.1" | ||
6 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
7 | - | ||
8 | -[[package]] | ||
9 | -name = "guessing_game" | ||
10 | -version = "0.1.0" | ||
11 | -dependencies = [ | ||
12 | - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", | ||
13 | -] | ||
14 | - | ||
15 | -[[package]] | ||
16 | -name = "libc" | ||
17 | -version = "0.2.65" | ||
18 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
19 | - | ||
20 | -[[package]] | ||
21 | -name = "rand" | ||
22 | -version = "0.3.23" | ||
23 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
24 | -dependencies = [ | ||
25 | - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", | ||
26 | - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||
27 | -] | ||
28 | - | ||
29 | -[[package]] | ||
30 | -name = "rand" | ||
31 | -version = "0.4.6" | ||
32 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
33 | -dependencies = [ | ||
34 | - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
35 | - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", | ||
36 | - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
37 | - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
38 | - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
39 | -] | ||
40 | - | ||
41 | -[[package]] | ||
42 | -name = "rand_core" | ||
43 | -version = "0.3.1" | ||
44 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
45 | -dependencies = [ | ||
46 | - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||
47 | -] | ||
48 | - | ||
49 | -[[package]] | ||
50 | -name = "rand_core" | ||
51 | -version = "0.4.2" | ||
52 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
53 | - | ||
54 | -[[package]] | ||
55 | -name = "rdrand" | ||
56 | -version = "0.4.0" | ||
57 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
58 | -dependencies = [ | ||
59 | - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
60 | -] | ||
61 | - | ||
62 | -[[package]] | ||
63 | -name = "winapi" | ||
64 | -version = "0.3.8" | ||
65 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
66 | -dependencies = [ | ||
67 | - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
68 | - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
69 | -] | ||
70 | - | ||
71 | -[[package]] | ||
72 | -name = "winapi-i686-pc-windows-gnu" | ||
73 | -version = "0.4.0" | ||
74 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
75 | - | ||
76 | -[[package]] | ||
77 | -name = "winapi-x86_64-pc-windows-gnu" | ||
78 | -version = "0.4.0" | ||
79 | -source = "registry+https://github.com/rust-lang/crates.io-index" | ||
80 | - | ||
81 | -[metadata] | ||
82 | -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" | ||
83 | -"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" | ||
84 | -"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" | ||
85 | -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" | ||
86 | -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" | ||
87 | -"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" | ||
88 | -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" | ||
89 | -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" | ||
90 | -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||
91 | -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
guessing_game/Cargo.toml
deleted
100644 → 0
guessing_game/src/main.rs
deleted
100644 → 0
1 | -use std::io; | ||
2 | -use std::cmp::Ordering; | ||
3 | -use rand::Rng; | ||
4 | - | ||
5 | -fn main() { | ||
6 | - println!("Guess the number!"); | ||
7 | - | ||
8 | - let secret_number = rand::thread_rng() | ||
9 | - .gen_range(1, 101); | ||
10 | - | ||
11 | - loop { | ||
12 | - println!("Please input your guess."); | ||
13 | - | ||
14 | - let mut guess = String::new(); | ||
15 | - | ||
16 | - io::stdin() | ||
17 | - .read_line(&mut guess) | ||
18 | - .expect("Failed to read line"); | ||
19 | - | ||
20 | - let guess: u32 = match guess.trim().parse() { | ||
21 | - Ok(num) => num, | ||
22 | - Err(_) => continue, | ||
23 | - }; | ||
24 | - | ||
25 | - println!("You guessed: {}", guess); | ||
26 | - | ||
27 | - match guess.cmp(&secret_number) { | ||
28 | - Ordering::Less => println!("Too small!"), | ||
29 | - Ordering::Greater => println!("Too big!"), | ||
30 | - Ordering::Equal => { | ||
31 | - println!("You win!"); | ||
32 | - break; | ||
33 | - } | ||
34 | - } | ||
35 | - } | ||
36 | -} |
hello/Cargo.lock
deleted
100644 → 0
hello/Cargo.toml
deleted
100644 → 0
hello/src/main.rs
deleted
100644 → 0
interesting.md
deleted
100644 → 0
1 | -# Here I collect some interesting links. | ||
2 | - | ||
3 | -## cargo environment | ||
4 | - | ||
5 | -Currently I always build all dependencies within th projects own .cargo subdir | ||
6 | -by setting the environment variable CARGO_HOME. | ||
7 | - | ||
8 | - export CARGO_HOME=./.cargo | ||
9 | - | ||
10 | -Actually I am quite unsure if that is really a good idea because this results | ||
11 | -in a lot of rebuilds for each new project. | ||
12 | - | ||
13 | -## Implement Monads with rust. | ||
14 | - | ||
15 | -Which is currently difficult through impossible, but might be feasible with | ||
16 | -some small additions to the rust type system, namely | ||
17 | -«(generic) associated traits.» | ||
18 | - | ||
19 | -[Read here](https://varkor.github.io/blog/2019/03/28/idiomatic-monads-in-rust.html) | ||
20 | - | ||
21 | -### Is impl Trait what we needed? | ||
22 | - | ||
23 | -A new language feature which sounded a bit like the needed one for above is: | ||
24 | - | ||
25 | -[impl Trait](https://medium.com/@iopguy/impl-trait-in-rust-explanation-efde0d94946a) | ||
26 | - | ||
27 | -Crossreading it a bit seems to indicate that this is not like the above needed | ||
28 | -language feature. | ||
29 | - | ||
30 | -## WASM ... on gentoo ... | ||
31 | - | ||
32 | -Right now rust is not really a first class citizen within the gentoo eco | ||
33 | -system. For that reason at least when compiling rust with the `system-llvm` | ||
34 | -use flag some manual preparations are needed. | ||
35 | - | ||
36 | -### general informations about Wasm from MDN ... | ||
37 | - | ||
38 | -[WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) | ||
39 | - | ||
40 | -### rustwasm tutorial | ||
41 | - | ||
42 | -[rustwasm](https://rustwasm.github.io/book/introduction.html) | ||
43 | - | ||
44 | -### location of rustlib ... | ||
45 | - | ||
46 | -`wasm-pack` expects the wasm runtime under /usr/lib/rustlib/ but a gentoo | ||
47 | -installation puts it under /usr/lib/rust-1.39.0/rustlib/. To come around this | ||
48 | -issue I just created a symlink. | ||
49 | - | ||
50 | -Maybe it would be best to send a patch for also settings this symlink to | ||
51 | -upstream eselect-rust. | ||
52 | - | ||
53 | -### Missing lld | ||
54 | - | ||
55 | -Again `wasm-pack` searches for llvm-lld or rust-lld for the link phase. This | ||
56 | -is currently not a dependency for llvm with WASM support, so I installed it | ||
57 | -manually. Finally you have to tell rustc to use lld as linker via this | ||
58 | -environment variable: | ||
59 | - | ||
60 | - export RUSTFLAGS="-C linker=lld" | ||
61 | - | ||
62 | -## Traits when, how & why | ||
63 | - | ||
64 | -A slightly old but still worthwhile post about rusts standard traits. | ||
65 | - | ||
66 | -[About traits](https://llogiq.github.io/2015/07/30/traits.html) | ||
67 | - | ||
68 | -# Side note... 3d math | ||
69 | -[3d math primer](https://www.3dgep.com/3d-math-primer-for-game-programmers-vector-operations/) | ||
70 | -[basic 3d math](https://matrix44.net/cms/notes/opengl-3d-graphics/basic-3d-math-vectors/) | ||
71 | -[vector calculator](https://www.mathportal.org/calculators/matrices-calculators/vector-calculator.php) | ||
72 | -[3d vector mathematics](https://vvvv.org/documentation/3d-vector-mathematics) | ||
73 | -[sin appr. with fractions](https://dsp.stackexchange.com/questions/46629/finding-polynomial-approximations-of-a-sine-wave) | ||
74 | - | ||
75 | -# transformations within a coordinate system. | ||
76 | -[migenius](https://www.migenius.com/articles/3d-transformations-part1-matrices) | ||
77 | -[tutorialspoint](https://www.tutorialspoint.com/computer_graphics/3d_transformation.htm) | ||
78 | - | ||
79 | -# more math... | ||
80 | - | ||
81 | -A whole lot of interesting stuff about continued fractions: | ||
82 | -[continues fractions](http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/cfINTRO.html) | ||
83 | - |
loops/Cargo.lock
deleted
100644 → 0
loops/Cargo.toml
deleted
100644 → 0
loops/src/main.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Loops examples. | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | - | ||
22 | -fn main() { | ||
23 | - // It seams that to use loops this way you absolutely need a mutable. | ||
24 | - // If I build it with a normal type and try to shadow it within the loop | ||
25 | - // the outer variable is always used as input for the shadow, thus it is | ||
26 | - // always the same.... that really sucks. | ||
27 | - let mut counter = 0; | ||
28 | - | ||
29 | - let result = loop { | ||
30 | - counter = counter + 1; | ||
31 | - if counter == 10 { | ||
32 | - break counter * 2; | ||
33 | - } | ||
34 | - }; | ||
35 | - | ||
36 | - println!("The result is {}", result); | ||
37 | - | ||
38 | - // The same is true with «while» ... which again sucks. | ||
39 | - let mut number = 3; | ||
40 | - | ||
41 | - while number != 0 { | ||
42 | - println!("{}!", number); | ||
43 | - number = number - 1; | ||
44 | - } | ||
45 | - | ||
46 | - println!("LIFTOFF!!!"); | ||
47 | - | ||
48 | - // apart from beeing frustrated about the above facts... lets continue. | ||
49 | - let a = [10, 20, 30, 40, 50]; | ||
50 | - let mut index = 0; | ||
51 | - | ||
52 | - while index < 5 { | ||
53 | - println!("the value is: {}", a[index]); | ||
54 | - index = index + 1; | ||
55 | - } | ||
56 | - | ||
57 | - for element in a.iter() { | ||
58 | - println!("the value is still: {}", element); | ||
59 | - } | ||
60 | - | ||
61 | - for number in (1..4).rev() { | ||
62 | - println!("for {}!", number); | ||
63 | - } | ||
64 | -} |
ownership/Cargo.lock
deleted
100644 → 0
ownership/Cargo.toml
deleted
100644 → 0
ownership/src/main.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Examples related to ownership, also introducing String. | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | - | ||
22 | -fn main() { | ||
23 | - concat(); | ||
24 | - move_variable(); | ||
25 | - clone_variable(); | ||
26 | - | ||
27 | - let s = String::from("hello"); // s comes into scope | ||
28 | - | ||
29 | - take_ownership(s); // s's value moves into the function | ||
30 | - // … and so is no longer valid here. | ||
31 | - let x = 5; // x comes into scope | ||
32 | - | ||
33 | - makes_copy(x); // the scalar value has the Copy trait and | ||
34 | - // lives on the stack and thus is still | ||
35 | - // valid here. | ||
36 | - | ||
37 | - let _s1 = gives_ownership(); // move the return value into _s1 | ||
38 | - let s2 = String::from("hello"); // s2 comes into scope | ||
39 | - let _s3 = takes_and_gives(s2); // s2 is moved into function, which in | ||
40 | - // turn moves the return value into _s3. | ||
41 | - | ||
42 | - let s1 = String::from("hello"); // s1 comes into scope. | ||
43 | - let len = calculate_length(&s1); // A reference to s1 is given to a | ||
44 | - // calculate_length which effectively is | ||
45 | - // not s1 itself but another pointer to | ||
46 | - // s1… which is the reason that we still | ||
47 | - // can use it below. | ||
48 | - let _another_s = &s1; // again only a reference which does not | ||
49 | - // take ownership, thus s1 can still be | ||
50 | - // used below. | ||
51 | - println!("The length of '{}' is {}.", s1, len); | ||
52 | - | ||
53 | - // Passing values as reference to a function is called borrowing. A | ||
54 | - // borrowed value can't be changed. | ||
55 | - change(&s1); | ||
56 | - | ||
57 | - // but we can force this… which is probably not the best of ideas most | ||
58 | - // of the time… | ||
59 | - let mut s_mut = String::from("hello"); | ||
60 | - change_mutable(&mut s_mut); | ||
61 | - | ||
62 | - // but you can have only one mutable reference of a value in a single | ||
63 | - // scope. The following would fail with: | ||
64 | - // cannot borrow `s_mut` as mutable more than once at a time second | ||
65 | - // mutable borrow occurs here | ||
66 | - // let r1 = &mut s_mut; | ||
67 | - // let r2 = &mut s_mut; | ||
68 | - // println!("{}, {}", r1, r2); | ||
69 | - | ||
70 | - // We also can't have an immutable reference while we have a mutable one. | ||
71 | - // Look on Page 98 for an explanation. | ||
72 | - | ||
73 | - // The scope of references is not the whole block they are introduced in | ||
74 | - // but goes only until their last usage. Thus if you first have an | ||
75 | - // immutable reference but never use it after a mutable reference is | ||
76 | - // declared, that would be ok… At all this is kind of confusing and very | ||
77 | - // Mozzilaish. :D | ||
78 | - | ||
79 | - // Now we demonstrate string slices… | ||
80 | - let s4 = String::from("hello world"); | ||
81 | - let s_slice = first_word(&s4); | ||
82 | - | ||
83 | - // working with an mutable reference like with s4.clear() will not | ||
84 | - // compile at this point because we already have and use later on an | ||
85 | - // immutable reference. | ||
86 | - | ||
87 | - println!("The slice was: {}", s_slice); | ||
88 | - | ||
89 | - // not that string literals are slices. They are immutable references of | ||
90 | - // the programs TEXT segment. Thats the reason why they are immutable. | ||
91 | - | ||
92 | - // Thus try generic_first_word… | ||
93 | - println!("First word on literal: {}", generic_first_word("hello world")); | ||
94 | - println!("First word on String: {}", generic_first_word(&s4[..])); | ||
95 | -} // x and s go out of scope but nothing happens for s because this function | ||
96 | - // has no longer the ownership of s. | ||
97 | - // s3 goes out of scope and is dropped. s2 was moved and s1 is dropped. | ||
98 | - | ||
99 | -fn concat() { | ||
100 | - let mut s = String::from("hello"); | ||
101 | - s.push_str(", world!"); | ||
102 | - println!("{}", s); | ||
103 | -} | ||
104 | - | ||
105 | -fn move_variable() { | ||
106 | - let s1 = String::from("hello"); | ||
107 | - let s2 = s1; // does not copy data but only the String structure. | ||
108 | - // when using s1 below we get an error that a moved value was borrowed. | ||
109 | - println!("{}, world!", s2); | ||
110 | -} | ||
111 | - | ||
112 | -fn clone_variable() { | ||
113 | - let s1 = String::from("hello"); | ||
114 | - let s2 = s1.clone(); | ||
115 | - // this time both are valid. | ||
116 | - println!("s1 = {}, s2 = {}", s1, s2) | ||
117 | -} | ||
118 | - | ||
119 | -fn take_ownership(some_string: String) { // some_string comes into scope | ||
120 | - println!("{}", some_string); | ||
121 | -} // some_string goes out of scope and «drop» is called, thus memory freed. | ||
122 | - | ||
123 | -fn makes_copy(some_integer: i32) { // some integer comes into scope | ||
124 | - println!("{}", some_integer); | ||
125 | -} // Here, some_integer goes out of scope but because it was a copy and on the | ||
126 | - // stack nothing special happens… beside that stack space is freed. | ||
127 | - | ||
128 | -fn gives_ownership() -> String { // this will move the return value into the | ||
129 | - // calling function. | ||
130 | - let some_string = String::from("hello"); // some_string comes into scope | ||
131 | - some_string | ||
132 | -} | ||
133 | - | ||
134 | -fn takes_and_gives(a_string: String) -> String { // a_string comes into scope | ||
135 | - a_string // and is returned and moved | ||
136 | - // to the calling function. | ||
137 | -} // a_string goes out of scope but nothing happens as it is moved. | ||
138 | - | ||
139 | -fn calculate_length(s: &String) -> usize { // s comes into scope. It is a | ||
140 | - // reference. References do not | ||
141 | - // take ownership of the underlying | ||
142 | - // value which is the String in | ||
143 | - // main. | ||
144 | - s.len() | ||
145 | -} // Here s goes out of scope but because it has no ownership of the String | ||
146 | - // nothing happens. | ||
147 | - | ||
148 | -fn change(_some_string: &String) { | ||
149 | - // the following would give this error: | ||
150 | - // `_some_string` is a `&` reference, so the data it refers to cannot be | ||
151 | - // borrowed as mutable | ||
152 | - // _some_string.push_str(", world!"); | ||
153 | -} | ||
154 | - | ||
155 | -fn change_mutable(some_string: &mut String) { | ||
156 | - some_string.push_str(", world"); | ||
157 | -} | ||
158 | - | ||
159 | -fn first_word(s: &String) -> &str { | ||
160 | - let bytes = s.as_bytes(); | ||
161 | - | ||
162 | - for (i, &item) in bytes.iter().enumerate() { | ||
163 | - if item == b' ' { | ||
164 | - return &s[..i]; | ||
165 | - } | ||
166 | - } | ||
167 | - | ||
168 | - &s[..] | ||
169 | -} | ||
170 | - | ||
171 | -// To make first_word work on either string literals (which are in fact string | ||
172 | -// slices, s.o.) one would write first_word like this… | ||
173 | -fn generic_first_word(s: &str) -> &str { | ||
174 | - let bytes = s.as_bytes(); | ||
175 | - | ||
176 | - for (i, &item) in bytes.iter().enumerate() { | ||
177 | - if item == b' ' { | ||
178 | - return &s[..i]; | ||
179 | - } | ||
180 | - } | ||
181 | - | ||
182 | - &s[..] | ||
183 | -} |
rectangles/Cargo.toml
deleted
100644 → 0
rectangles/src/main.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Examples related to structs… | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | - | ||
22 | -#[derive(Debug)] | ||
23 | -struct Rectangle { | ||
24 | - width: u32, | ||
25 | - height: u32, | ||
26 | -} | ||
27 | - | ||
28 | -impl Rectangle { | ||
29 | - fn area(&self) -> u32 { | ||
30 | - self.width * self.height | ||
31 | - } | ||
32 | - | ||
33 | - fn can_hold(&self, inner: &Rectangle) -> bool { | ||
34 | - self.width >= inner.width && self.height >= inner.height | ||
35 | - } | ||
36 | - | ||
37 | - fn square(size: u32) -> Rectangle { | ||
38 | - Rectangle { width: size, height: size } | ||
39 | - } | ||
40 | -} | ||
41 | - | ||
42 | -fn main() { | ||
43 | - let width1 = 30; | ||
44 | - let height1 = 50; | ||
45 | - | ||
46 | - println!( | ||
47 | - "The area of the rectangle ist {} square pixels.", | ||
48 | - area(width1, height1)); | ||
49 | - | ||
50 | - let rect1 = (30, 50); | ||
51 | - | ||
52 | - println!( | ||
53 | - "The area of the rectangle ist {} square pixels.", | ||
54 | - _area(rect1)); | ||
55 | - | ||
56 | - let rect1 = Rectangle { width: 30, height: 50 }; | ||
57 | - | ||
58 | - println!( | ||
59 | - "The area of the rectangle ist {} square pixels.", | ||
60 | - __area(&rect1)); | ||
61 | - | ||
62 | - println!("_rect1 is {:?}", rect1); | ||
63 | - | ||
64 | - println!( | ||
65 | - "The area of the rectangle ist {} square pixels.", | ||
66 | - rect1.area()); | ||
67 | - | ||
68 | - let rect2 = Rectangle { width: 10, height: 40}; | ||
69 | - let rect3 = Rectangle { width: 60, height: 45}; | ||
70 | - | ||
71 | - println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); | ||
72 | - println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); | ||
73 | - | ||
74 | - let square1 = Rectangle::square(32); | ||
75 | - | ||
76 | - println!("Got the square rectange: {:?}", square1); | ||
77 | -} | ||
78 | - | ||
79 | -fn area(width: u32, height: u32) -> u32 { | ||
80 | - width * height | ||
81 | -} | ||
82 | - | ||
83 | -fn _area(dimensions: (u32, u32)) -> u32 { | ||
84 | - let (width, height) = dimensions; | ||
85 | - width * height | ||
86 | -} | ||
87 | - | ||
88 | -fn __area(rectangle: &Rectangle) -> u32 { | ||
89 | - rectangle.width * rectangle.height | ||
90 | -} |
recursion/Cargo.toml
deleted
100644 → 0
recursion/src/main.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Try some recursion with pattern matching... especially in | ||
3 | -// conjunction with match to get a similar behavious as in e.g. | ||
4 | -// haskell... | ||
5 | -// | ||
6 | -// Georg Hopp <georg@steffers.org> | ||
7 | -// | ||
8 | -// Copyright © 2019 Georg Hopp | ||
9 | -// | ||
10 | -// This program is free software: you can redistribute it and/or modify | ||
11 | -// it under the terms of the GNU General Public License as published by | ||
12 | -// the Free Software Foundation, either version 3 of the License, or | ||
13 | -// (at your option) any later version. | ||
14 | -// | ||
15 | -// This program is distributed in the hope that it will be useful, | ||
16 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | -// GNU General Public License for more details. | ||
19 | -// | ||
20 | -// You should have received a copy of the GNU General Public License | ||
21 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
22 | -// | ||
23 | - | ||
24 | -// Borrowing rules do not apply here because everything lives on the stack. | ||
25 | -fn faculty(x: u32) -> u32 { | ||
26 | - match x { | ||
27 | - 0 => 1, | ||
28 | - _ => x * faculty(x - 1), | ||
29 | - } | ||
30 | -} | ||
31 | - | ||
32 | -// for a tail recursive version we need to pass the currently calculated | ||
33 | -// faculty to an inner tail recursive function. | ||
34 | -// This will probably be optimized better, because the compiler would be | ||
35 | -// able to unroll the complete recursion. | ||
36 | -fn tail_faculty(x: u32) -> u32 { | ||
37 | - fn faculty(x: u32, f: u32) -> u32 { | ||
38 | - match x { | ||
39 | - 0 => f, | ||
40 | - _ => faculty(x - 1, x * f), | ||
41 | - } | ||
42 | - }; | ||
43 | - faculty(x, 1) | ||
44 | -} | ||
45 | - | ||
46 | -fn main() { | ||
47 | - for i in 0..10 { | ||
48 | - println!("Fakultät {} = {}", i, faculty(i)); | ||
49 | - println!("tail recursive Fakultät {} = {}", i, tail_faculty(i)); | ||
50 | - } | ||
51 | -} |
restaurant/Cargo.toml
deleted
100644 → 0
restaurant/src/front_of_house.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Move some restaurant stuff in a different file.... | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | - | ||
22 | -pub mod hosting; | ||
23 | - | ||
24 | -mod serving { | ||
25 | - fn take_order() {} | ||
26 | - fn take_payment() {} | ||
27 | -} |
1 | -// | ||
2 | -// Now also sepatate hosting.... | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | - | ||
22 | -pub fn add_to_waitlist() {} | ||
23 | -fn seat_at_table() {} |
restaurant/src/lib.rs
deleted
100644 → 0
1 | -// | ||
2 | -// Restaurant lib for demontrating rust modules. | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | - | ||
22 | -mod front_of_house; | ||
23 | - | ||
24 | -fn serve_order() {} | ||
25 | - | ||
26 | -mod back_of_house { | ||
27 | - pub struct Breakfast { | ||
28 | - pub toast: String, | ||
29 | - seasonal_fruit: String, | ||
30 | - } | ||
31 | - | ||
32 | - impl Breakfast { | ||
33 | - pub fn summer(toast: &str) -> Breakfast { | ||
34 | - Breakfast { | ||
35 | - toast: String::from(toast), | ||
36 | - seasonal_fruit: String::from("peaches"), | ||
37 | - } | ||
38 | - } | ||
39 | - } | ||
40 | - | ||
41 | - pub enum Appetizer { | ||
42 | - Soup, | ||
43 | - Salad, | ||
44 | - } | ||
45 | - | ||
46 | - fn fix_incorrect_order() { | ||
47 | - cook_order(); | ||
48 | - super::serve_order(); | ||
49 | - } | ||
50 | - | ||
51 | - fn cook_order() {} | ||
52 | -} | ||
53 | - | ||
54 | -// Either absolute: | ||
55 | -// use crate::front_of_house::hosting; | ||
56 | -// or relaive: | ||
57 | -use front_of_house::hosting; | ||
58 | -// we can also provide new names... | ||
59 | -use crate::front_of_house::hosting as host; | ||
60 | -// Public definitions braught into scope with use are | ||
61 | -// private in this scope except we use «pub use» | ||
62 | -pub use front_of_house::hosting as pubhost; | ||
63 | - | ||
64 | -pub fn eat_at_restaurant() { | ||
65 | - // Absolute path | ||
66 | - crate::front_of_house::hosting::add_to_waitlist(); | ||
67 | - | ||
68 | - // Relative path | ||
69 | - front_of_house::hosting::add_to_waitlist(); | ||
70 | - | ||
71 | - // With use'd path | ||
72 | - hosting::add_to_waitlist(); | ||
73 | - | ||
74 | - // With renamed used path | ||
75 | - host::add_to_waitlist(); | ||
76 | - | ||
77 | - pubhost::add_to_waitlist(); | ||
78 | - | ||
79 | - // Order a breakfast in the summer with Rye toast | ||
80 | - let mut meal = back_of_house::Breakfast::summer("Rye"); | ||
81 | - | ||
82 | - // Change our mind about what bread we'd like | ||
83 | - meal.toast = String::from("Wheat"); | ||
84 | - | ||
85 | - println!("I'd like {} toast please", meal.toast); | ||
86 | - | ||
87 | - // The next line won't compile if we uncomment it; we're not allowed | ||
88 | - // to see or modify the seasonal fruit that comes with the meal | ||
89 | - // meal.seasonal_fruit = String::from("blueberries"); | ||
90 | - | ||
91 | - let order1 = back_of_house::Appetizer::Soup; | ||
92 | - let order2 = back_of_house::Appetizer::Salad; | ||
93 | -} |
tutorial/wasm-game-of-life/README.md
deleted
100644 → 0
1 | -<div align="center"> | ||
2 | - | ||
3 | - <h1><code>wasm-pack-template</code></h1> | ||
4 | - | ||
5 | - <strong>A template for kick starting a Rust and WebAssembly project using <a href="https://github.com/rustwasm/wasm-pack">wasm-pack</a>.</strong> | ||
6 | - | ||
7 | - <p> | ||
8 | - <a href="https://travis-ci.org/rustwasm/wasm-pack-template"><img src="https://img.shields.io/travis/rustwasm/wasm-pack-template.svg?style=flat-square" alt="Build Status" /></a> | ||
9 | - </p> | ||
10 | - | ||
11 | - <h3> | ||
12 | - <a href="https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html">Tutorial</a> | ||
13 | - <span> | </span> | ||
14 | - <a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a> | ||
15 | - </h3> | ||
16 | - | ||
17 | - <sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub> | ||
18 | -</div> | ||
19 | - | ||
20 | -## About | ||
21 | - | ||
22 | -[**📚 Read this template tutorial! 📚**][template-docs] | ||
23 | - | ||
24 | -This template is designed for compiling Rust libraries into WebAssembly and | ||
25 | -publishing the resulting package to NPM. | ||
26 | - | ||
27 | -Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other | ||
28 | -templates and usages of `wasm-pack`. | ||
29 | - | ||
30 | -[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html | ||
31 | -[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html | ||
32 | - | ||
33 | -## 🚴 Usage | ||
34 | - | ||
35 | -### 🐑 Use `cargo generate` to Clone this Template | ||
36 | - | ||
37 | -[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) | ||
38 | - | ||
39 | -``` | ||
40 | -cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project | ||
41 | -cd my-project | ||
42 | -``` | ||
43 | - | ||
44 | -### 🛠️ Build with `wasm-pack build` | ||
45 | - | ||
46 | -``` | ||
47 | -wasm-pack build | ||
48 | -``` | ||
49 | - | ||
50 | -### 🔬 Test in Headless Browsers with `wasm-pack test` | ||
51 | - | ||
52 | -``` | ||
53 | -wasm-pack test --headless --firefox | ||
54 | -``` | ||
55 | - | ||
56 | -### 🎁 Publish to NPM with `wasm-pack publish` | ||
57 | - | ||
58 | -``` | ||
59 | -wasm-pack publish | ||
60 | -``` | ||
61 | - | ||
62 | -## 🔋 Batteries Included | ||
63 | - | ||
64 | -* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating | ||
65 | - between WebAssembly and JavaScript. | ||
66 | -* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) | ||
67 | - for logging panic messages to the developer console. | ||
68 | -* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized | ||
69 | - for small code size. |
1 | -// | ||
2 | -// This is an abstraction over a drawing environment. | ||
3 | -// Future note: z-Buffer is described here: | ||
4 | -// https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/perspective-correct-interpolation-vertex-attributes | ||
5 | -// | ||
6 | -// Georg Hopp <georg@steffers.org> | ||
7 | -// | ||
8 | -// Copyright © 2019 Georg Hopp | ||
9 | -// | ||
10 | -// This program is free software: you can redistribute it and/or modify | ||
11 | -// it under the terms of the GNU General Public License as published by | ||
12 | -// the Free Software Foundation, either version 3 of the License, or | ||
13 | -// (at your option) any later version. | ||
14 | -// | ||
15 | -// This program is distributed in the hope that it will be useful, | ||
16 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | -// GNU General Public License for more details. | ||
19 | -// | ||
20 | -// You should have received a copy of the GNU General Public License | ||
21 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
22 | -// | ||
23 | -use std::cmp; | ||
24 | -use std::fmt::{Formatter, Debug, Display, Result}; | ||
25 | -use std::ops::{Add, Sub, Div}; | ||
26 | -use std::sync::mpsc; | ||
27 | - | ||
28 | -pub trait Easel { | ||
29 | - //fn canvas(&mut self, width :u16, height :u16) -> Option<&dyn Canvas>; | ||
30 | -} | ||
31 | - | ||
32 | -pub trait Canvas<T> { | ||
33 | - fn init_events(&self); | ||
34 | - fn start_events(&self, tx :mpsc::Sender<i32>); | ||
35 | - | ||
36 | - fn width(&self) -> u16; | ||
37 | - fn height(&self) -> u16; | ||
38 | - | ||
39 | - fn clear(&mut self); | ||
40 | - fn draw(&mut self, c :&dyn Drawable<T>, ofs :Coordinate<T>, color :u32); | ||
41 | - fn put_text(&self, ofs :Coordinate<T>, s :&str); | ||
42 | - fn set_pixel(&mut self, c :Coordinate<T>, color :u32); | ||
43 | - fn show(&self); | ||
44 | -} | ||
45 | - | ||
46 | -pub trait Drawable<T> { | ||
47 | - fn plot(&self) -> Coordinates<T>; | ||
48 | -} | ||
49 | - | ||
50 | -pub trait Fillable<T> | ||
51 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
52 | - + Debug + Copy + From<i32> { | ||
53 | - fn fill(&self, canvas :&mut dyn Canvas<T>, color :u32); | ||
54 | -} | ||
55 | - | ||
56 | -#[derive(Debug, Clone, Copy)] | ||
57 | -pub struct Coordinate<T>(pub i32, pub i32, pub T); | ||
58 | - | ||
59 | -#[derive(Debug, Clone)] | ||
60 | -pub struct Coordinates<T>(pub Vec<Coordinate<T>>); | ||
61 | - | ||
62 | -#[derive(Debug, Clone, Copy)] | ||
63 | -pub struct LineIterator<T> where T: Debug { | ||
64 | - a :Option<Coordinate<T>> | ||
65 | - , b :Coordinate<T> | ||
66 | - , dx :i32 | ||
67 | - , dy :i32 | ||
68 | - , dz :T | ||
69 | - , sx :i32 | ||
70 | - , sy :i32 | ||
71 | - , err :i32 | ||
72 | - , only_edges :bool | ||
73 | -} | ||
74 | - | ||
75 | -impl<T> Iterator for LineIterator<T> | ||
76 | -where T: Add<Output = T> + Debug + Copy + From<i32> { | ||
77 | - type Item = Coordinate<T>; | ||
78 | - | ||
79 | - fn next(&mut self) -> Option<Self::Item> { | ||
80 | - match self.a { | ||
81 | - None => None, | ||
82 | - Some(a) => { | ||
83 | - let Coordinate(ax, ay, az) = a; | ||
84 | - let Coordinate(bx, by, _) = self.b; | ||
85 | - | ||
86 | - if ax != bx || ay != by { | ||
87 | - match (2 * self.err >= self.dy, 2 * self.err <= self.dx ) { | ||
88 | - (true, false) => { | ||
89 | - let r = self.a; | ||
90 | - self.a = Some(Coordinate( ax + self.sx | ||
91 | - , ay | ||
92 | - , az + self.dz )); | ||
93 | - self.err = self.err + self.dy; | ||
94 | - if self.only_edges { self.next() } else { r } | ||
95 | - }, | ||
96 | - (false, true) => { | ||
97 | - let r = self.a; | ||
98 | - self.a = Some(Coordinate( ax | ||
99 | - , ay + self.sy | ||
100 | - , az + self.dz )); | ||
101 | - self.err = self.err + self.dx; | ||
102 | - r | ||
103 | - }, | ||
104 | - _ => { | ||
105 | - let r = self.a; | ||
106 | - self.a = Some(Coordinate( ax + self.sx | ||
107 | - , ay + self.sy | ||
108 | - , az + self.dz )); | ||
109 | - self.err = self.err + self.dx + self.dy; | ||
110 | - r | ||
111 | - }, | ||
112 | - } | ||
113 | - } else { | ||
114 | - self.a = None; | ||
115 | - Some(self.b) | ||
116 | - } | ||
117 | - } | ||
118 | - } | ||
119 | - } | ||
120 | -} | ||
121 | - | ||
122 | -impl<T> Coordinate<T> | ||
123 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
124 | - + Debug + Clone + Copy + From<i32> { | ||
125 | - fn iter(self, b :&Self, only_edges :bool) -> LineIterator<T> { | ||
126 | - let Coordinate(ax, ay, az) = self; | ||
127 | - let Coordinate(bx, by, bz) = *b; | ||
128 | - | ||
129 | - let dx = (bx - ax).abs(); | ||
130 | - let dy = -(by - ay).abs(); | ||
131 | - | ||
132 | - LineIterator { a: Some(self) | ||
133 | - , b: *b | ||
134 | - , dx: dx | ||
135 | - , dy: dy | ||
136 | - , dz: (bz - az) / cmp::max(dx, -dy).into() | ||
137 | - , sx: if ax < bx { 1 } else { -1 } | ||
138 | - , sy: if ay < by { 1 } else { -1 } | ||
139 | - , err: dx + dy | ||
140 | - , only_edges: only_edges | ||
141 | - } | ||
142 | - } | ||
143 | - | ||
144 | - fn line_iter(self, b :&Self) -> LineIterator<T> { | ||
145 | - self.iter(b, false) | ||
146 | - } | ||
147 | - | ||
148 | - fn line(self, b :&Self) -> Vec<Self> { | ||
149 | - self.line_iter(b).collect() | ||
150 | - } | ||
151 | - | ||
152 | - fn edge_iter(self, b :&Self) -> LineIterator<T> { | ||
153 | - self.iter(b, true) | ||
154 | - } | ||
155 | - | ||
156 | - fn edge(self, b :&Self) -> Vec<Self> { | ||
157 | - self.edge_iter(b).collect() | ||
158 | - } | ||
159 | - | ||
160 | - fn face(edges :&[Self]) -> Vec<Self> { | ||
161 | - edges.to_vec() | ||
162 | - } | ||
163 | -} | ||
164 | - | ||
165 | -impl<T> Display for Coordinate<T> { | ||
166 | - fn fmt(&self, f: &mut Formatter<'_>) -> Result { | ||
167 | - write!(f, "<{},{}>", self.0, self.1) | ||
168 | - } | ||
169 | -} | ||
170 | - | ||
171 | -impl<T> Display for Coordinates<T> where T: Copy { | ||
172 | - fn fmt(&self, f: &mut Formatter<'_>) -> Result { | ||
173 | - let Coordinates(is) = self; | ||
174 | - | ||
175 | - let c = match is[..] { | ||
176 | - [] => String::from(""), | ||
177 | - [a] => format!("{}", a), | ||
178 | - _ => { | ||
179 | - let mut a = format!("{}", is[0]); | ||
180 | - for i in is[1..].iter() { | ||
181 | - a = a + &format!(",{}", i); | ||
182 | - } | ||
183 | - a | ||
184 | - } | ||
185 | - }; | ||
186 | - | ||
187 | - write!(f, "Coordinates[{}]", c) | ||
188 | - } | ||
189 | -} | ||
190 | - | ||
191 | - | ||
192 | -#[derive(Debug, Clone, Copy)] | ||
193 | -pub struct Point<T>(pub Coordinate<T>); | ||
194 | - | ||
195 | -impl<T> Drawable<T> for Point<T> where T: Copy { | ||
196 | - fn plot(&self) -> Coordinates<T> { | ||
197 | - let Point(c) = *self; | ||
198 | - Coordinates(vec!(c)) | ||
199 | - } | ||
200 | -} | ||
201 | - | ||
202 | -impl<T> Display for Point<T> { | ||
203 | - fn fmt(&self, f: &mut Formatter<'_>) -> Result { | ||
204 | - let Point(p) = self; | ||
205 | - write!(f, "Point[{}]", p) | ||
206 | - } | ||
207 | -} | ||
208 | - | ||
209 | -#[derive(Debug, Clone, Copy)] | ||
210 | -pub struct Line<T>(pub Coordinate<T>, pub Coordinate<T>); | ||
211 | - | ||
212 | -impl<T> Drawable<T> for Line<T> | ||
213 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
214 | - + Debug + Clone + Copy + From<i32> { | ||
215 | - fn plot(&self) -> Coordinates<T> { | ||
216 | - let Line(a, b) = *self; | ||
217 | - Coordinates(a.line(&b)) | ||
218 | - } | ||
219 | -} | ||
220 | - | ||
221 | -impl<T> Display for Line<T> { | ||
222 | - fn fmt(&self, f: &mut Formatter<'_>) -> Result { | ||
223 | - let Line(a, b) = self; | ||
224 | - write!(f, "Line[{},{}]", a, b) | ||
225 | - } | ||
226 | -} | ||
227 | - | ||
228 | -#[derive(Debug, Clone)] | ||
229 | -pub struct Polyline<T>(pub Coordinates<T>); | ||
230 | - | ||
231 | -impl<T> Drawable<T> for Polyline<T> | ||
232 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
233 | - + Debug + Clone + Copy + From<i32> { | ||
234 | - fn plot(&self) -> Coordinates<T> { | ||
235 | - let Polyline(Coordinates(cs)) = self; | ||
236 | - | ||
237 | - match cs[..] { | ||
238 | - [] => Coordinates(Vec::<Coordinate<T>>::new()), | ||
239 | - [a] => Coordinates(vec!(a)), | ||
240 | - [a, b] => Coordinates(a.line(&b)), | ||
241 | - _ => { | ||
242 | - let (a, b) = (cs[0], cs[1]); | ||
243 | - let mut r = a.line(&b); | ||
244 | - let mut i = b; | ||
245 | - for j in cs[2..].iter() { | ||
246 | - r.append(&mut i.line(j)[1..].to_vec()); | ||
247 | - i = *j; | ||
248 | - } | ||
249 | - Coordinates(r) | ||
250 | - }, | ||
251 | - } | ||
252 | - } | ||
253 | -} | ||
254 | - | ||
255 | -impl<T> Display for Polyline<T> where T: Copy { | ||
256 | - fn fmt(&self, f: &mut Formatter<'_>) -> Result { | ||
257 | - let Polyline(a) = self; | ||
258 | - write!(f, "PLine[{}]", a) | ||
259 | - } | ||
260 | -} | ||
261 | - | ||
262 | -#[derive(Debug, Clone, Copy)] | ||
263 | -enum Direction { Left, Right } | ||
264 | - | ||
265 | -#[derive(Debug, Clone)] | ||
266 | -pub struct Polygon<T>(pub Coordinates<T>); | ||
267 | - | ||
268 | -#[derive(Debug, Clone)] | ||
269 | -enum VertexIteratorMode { Vertex, Edge } | ||
270 | -#[derive(Debug, Clone)] | ||
271 | -pub struct VertexIterator<'a,T> where T: Debug { | ||
272 | - p :&'a Polygon<T>, | ||
273 | - top :usize, | ||
274 | - current :Option<usize>, | ||
275 | - edge :Option<LineIterator<T>>, | ||
276 | - mode :VertexIteratorMode, | ||
277 | - direction :Direction, | ||
278 | -} | ||
279 | - | ||
280 | -impl<'a,T> VertexIterator<'a,T> | ||
281 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
282 | - + Debug + Copy + From<i32> { | ||
283 | - fn edge(p :&'a Polygon<T>, direction :Direction) -> Self { | ||
284 | - let top = p.vert_min(direction); | ||
285 | - let next = p.next_y(top, direction); | ||
286 | - let edge = match next { | ||
287 | - None => None, | ||
288 | - Some(next) => Some(p.vertex(top).edge_iter(&p.vertex(next))), | ||
289 | - }; | ||
290 | - | ||
291 | - VertexIterator { p: p | ||
292 | - , top: top | ||
293 | - , current: next | ||
294 | - , edge: edge | ||
295 | - , mode: VertexIteratorMode::Edge | ||
296 | - , direction: direction } | ||
297 | - } | ||
298 | - | ||
299 | - fn vertex(p :&'a Polygon<T>, direction :Direction) -> Self { | ||
300 | - let top = p.vert_min(direction); | ||
301 | - let next = p.next_y(top, direction); | ||
302 | - | ||
303 | - VertexIterator { p: p | ||
304 | - , top: top | ||
305 | - , current: next | ||
306 | - , edge: None | ||
307 | - , mode: VertexIteratorMode::Vertex | ||
308 | - , direction: direction } | ||
309 | - } | ||
310 | - | ||
311 | - // if this yields "None" we are finished. | ||
312 | - fn next_edge(&mut self) -> Option<LineIterator<T>> { | ||
313 | - let current = self.current?; | ||
314 | - let next = self.p.next_y(current, self.direction)?; | ||
315 | - let mut edge = self.p.vertex(current).edge_iter(&self.p.vertex(next)); | ||
316 | - | ||
317 | - match edge.next() { | ||
318 | - // It should be impossible that a new edge iterator has no values | ||
319 | - // at all… anyway, just in case I handle it here. | ||
320 | - None => self.next_edge(), | ||
321 | - Some(_) => { | ||
322 | - self.current = Some(next); | ||
323 | - self.edge = Some(edge); | ||
324 | - self.edge | ||
325 | - }, | ||
326 | - } | ||
327 | - } | ||
328 | -} | ||
329 | - | ||
330 | -impl<'a,T> Iterator for VertexIterator<'a,T> | ||
331 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
332 | - + Debug + Copy + From<i32> { | ||
333 | - type Item = Coordinate<T>; | ||
334 | - | ||
335 | - fn next(&mut self) -> Option<Self::Item> { | ||
336 | - match self.mode { | ||
337 | - VertexIteratorMode::Edge => { | ||
338 | - // if for whatever reason edge is "None" finish this iterator. | ||
339 | - let next = self.edge.as_mut()?.next(); | ||
340 | - | ||
341 | - match next { | ||
342 | - Some(_) => next, | ||
343 | - None => { | ||
344 | - self.next_edge()?; | ||
345 | - self.next() | ||
346 | - }, | ||
347 | - } | ||
348 | - }, | ||
349 | - VertexIteratorMode::Vertex => { | ||
350 | - let current = self.current?; | ||
351 | - self.current = self.p.next_y(current, self.direction); | ||
352 | - Some(self.p.vertex(current)) | ||
353 | - }, | ||
354 | - } | ||
355 | - } | ||
356 | -} | ||
357 | - | ||
358 | -impl<T> Polygon<T> | ||
359 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
360 | - + Copy + Debug + From<i32> { | ||
361 | - #[inline] | ||
362 | - fn vertex(&self, v :usize) -> Coordinate<T> { | ||
363 | - let Polygon(Coordinates(cs)) = self; | ||
364 | - cs[v] | ||
365 | - } | ||
366 | - | ||
367 | - fn vert_min<'a>(&'a self, d :Direction) -> usize { | ||
368 | - let Polygon(Coordinates(cs)) = self; | ||
369 | - | ||
370 | - type ICoord<'a,T> = (usize, &'a Coordinate<T>); | ||
371 | - | ||
372 | - // TODO I guess the problem here is that it does not account for the | ||
373 | - // same y vertex on the beggining and the end. So i guess correct | ||
374 | - // would be finding the first one and then dependings on the | ||
375 | - // given direction either search left or right for same y's. | ||
376 | - let fold = |acc :Option<ICoord<'a,T>>, x :ICoord<'a,T>| | ||
377 | - match acc { | ||
378 | - None => Some(x), | ||
379 | - Some(a) => { | ||
380 | - let Coordinate(_, ay, _) = a.1; | ||
381 | - let Coordinate(_, xy, _) = x.1; | ||
382 | - if xy < ay {Some(x)} else {Some(a)} | ||
383 | - }, | ||
384 | - }; | ||
385 | - | ||
386 | - let mut min = cs.iter().enumerate().fold(None, fold).unwrap().0; | ||
387 | - let mut next = self.step(min, d); | ||
388 | - | ||
389 | - while self.vertex(min).1 == self.vertex(next).1 { | ||
390 | - min = next; | ||
391 | - next = self.step(min, d); | ||
392 | - } | ||
393 | - | ||
394 | - min | ||
395 | - } | ||
396 | - | ||
397 | - fn left_edge(&self) -> VertexIterator<T> { | ||
398 | - VertexIterator::edge(self, Direction::Left) | ||
399 | - } | ||
400 | - | ||
401 | - fn right_edge(&self) -> VertexIterator<T> { | ||
402 | - VertexIterator::edge(self, Direction::Right) | ||
403 | - } | ||
404 | - | ||
405 | - fn left_vertices(&self) -> VertexIterator<T> { | ||
406 | - VertexIterator::vertex(self, Direction::Left) | ||
407 | - } | ||
408 | - | ||
409 | - fn right_vertices(&self) -> VertexIterator<T> { | ||
410 | - VertexIterator::vertex(self, Direction::Right) | ||
411 | - } | ||
412 | - | ||
413 | - fn left(&self, v :usize) -> usize { | ||
414 | - let Polygon(Coordinates(cs)) = self; | ||
415 | - | ||
416 | - match v { | ||
417 | - 0 => cs.len() - 1, | ||
418 | - _ => v - 1, | ||
419 | - } | ||
420 | - } | ||
421 | - | ||
422 | - fn right(&self, v :usize) -> usize { | ||
423 | - let Polygon(Coordinates(cs)) = self; | ||
424 | - | ||
425 | - (v + 1) % cs.len() | ||
426 | - } | ||
427 | - | ||
428 | - fn step(&self, v :usize, d :Direction) -> usize { | ||
429 | - match d { | ||
430 | - Direction::Left => self.left(v), | ||
431 | - Direction::Right => self.right(v), | ||
432 | - } | ||
433 | - } | ||
434 | - | ||
435 | - fn next_y(&self, c :usize, d :Direction) -> Option<usize> { | ||
436 | - fn inner<T>( p :&Polygon<T> | ||
437 | - , c :usize | ||
438 | - , n :usize | ||
439 | - , d :Direction) -> Option<usize> | ||
440 | - where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
441 | - + Copy + Debug + From<i32> { | ||
442 | - if c == n { | ||
443 | - None | ||
444 | - } else { | ||
445 | - let Coordinate(_, cy, _) = p.vertex(c); | ||
446 | - let Coordinate(_, ny, _) = p.vertex(n); | ||
447 | - | ||
448 | - if ny < cy { None } else { Some(n) } | ||
449 | - } | ||
450 | - } | ||
451 | - | ||
452 | - inner(self, c, self.step(c, d), d) | ||
453 | - } | ||
454 | - | ||
455 | - pub fn debug(&self) { | ||
456 | - let mut left = self.left_vertices(); | ||
457 | - let mut right = self.right_vertices(); | ||
458 | - | ||
459 | - if left.find(|l| right.find(|r| l.0 == r.0).is_some()).is_some() { | ||
460 | - let left :Vec<Coordinate<T>> = self.left_vertices().collect(); | ||
461 | - let right :Vec<Coordinate<T>> = self.right_vertices().collect(); | ||
462 | - | ||
463 | - println!("==="); | ||
464 | - println!("== poly : {:?}", self); | ||
465 | - println!("== ltop : {:?}", self.vert_min(Direction::Left)); | ||
466 | - println!("== rtop : {:?}", self.vert_min(Direction::Right)); | ||
467 | - println!("== left : {:?}", left); | ||
468 | - println!("== right : {:?}", right); | ||
469 | - println!("==="); | ||
470 | - } | ||
471 | - } | ||
472 | -} | ||
473 | - | ||
474 | -impl<T> Drawable<T> for Polygon<T> | ||
475 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
476 | - + Debug + Clone + Copy + From<i32> { | ||
477 | - fn plot(&self) -> Coordinates<T> { | ||
478 | - let Polygon(Coordinates(cs)) = self; | ||
479 | - | ||
480 | - match cs[..] { | ||
481 | - [] => Coordinates(Vec::<Coordinate<T>>::new()), | ||
482 | - [a] => Coordinates(vec!(a)), | ||
483 | - [a, b] => Coordinates(a.line(&b)), | ||
484 | - _ => { | ||
485 | - let (a, b) = (cs[0], cs[1]); | ||
486 | - let mut r = a.line(&b); | ||
487 | - let mut i = b; | ||
488 | - for j in cs[2..].iter() { | ||
489 | - r.append(&mut i.line(j)[1..].to_vec()); | ||
490 | - i = *j; | ||
491 | - } | ||
492 | - let mut j = a.line(&i); | ||
493 | - let l = j.len(); | ||
494 | - if l > 1 { | ||
495 | - r.append(&mut j[1..l-1].to_vec()); | ||
496 | - } | ||
497 | - Coordinates(r) | ||
498 | - }, | ||
499 | - } | ||
500 | - } | ||
501 | -} | ||
502 | - | ||
503 | -impl<T> Fillable<T> for Polygon<T> | ||
504 | -where T: Add<Output = T> + Sub<Output = T> + Div<Output = T> | ||
505 | - + Debug + Clone + Copy + From<i32> { | ||
506 | - fn fill(&self, canvas :&mut dyn Canvas<T>, color :u32) { | ||
507 | - let scanlines = self.left_edge().zip(self.right_edge()); | ||
508 | - | ||
509 | - for l in scanlines.flat_map(|(l, r)| l.line_iter(&r)) { | ||
510 | - canvas.set_pixel(l, color); | ||
511 | - } | ||
512 | - } | ||
513 | -} | ||
514 | - | ||
515 | -impl<T> Display for Polygon<T> where T: Copy { | ||
516 | - fn fmt(&self, f: &mut Formatter<'_>) -> Result { | ||
517 | - let Polygon(a) = self; | ||
518 | - write!(f, "Poly[{}]", a) | ||
519 | - } | ||
520 | -} |
1 | -// | ||
2 | -// Transformation of vectors in a given coordinate system... | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | -use std::ops::{Add, Sub, Neg, Mul, Div}; | ||
22 | -use std::fmt::Debug; | ||
23 | - | ||
24 | -use crate::Vector; | ||
25 | -use crate::trigonometry::Trig; | ||
26 | - | ||
27 | -#[derive(Debug, Clone, Copy)] | ||
28 | -pub struct TMatrix<T>( (T, T, T, T) | ||
29 | - , (T, T, T, T) | ||
30 | - , (T, T, T, T) | ||
31 | - , (T, T, T, T) ) | ||
32 | - where T: Add + Sub + Neg + Mul + Div + Debug + Trig + From<i32> + Copy; | ||
33 | - | ||
34 | -pub trait Transformable<T> | ||
35 | -where T: Add + Sub + Neg + Mul + Div + Debug + Trig + From<i32> + Copy { | ||
36 | - fn transform(&self, m :&TMatrix<T>) -> Self; | ||
37 | -} | ||
38 | - | ||
39 | -impl<T> TMatrix<T> | ||
40 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
41 | - + Mul<Output = T> + Div<Output = T> | ||
42 | - + Debug + Trig + From<i32> + Copy { | ||
43 | - pub fn new( r1 :(T, T, T, T) | ||
44 | - , r2 :(T, T, T, T) | ||
45 | - , r3 :(T, T, T, T) | ||
46 | - , r4 :(T, T, T, T) ) -> Self { | ||
47 | - TMatrix(r1, r2, r3, r4) | ||
48 | - } | ||
49 | - | ||
50 | - pub fn unit() -> Self { | ||
51 | - Self::new( (1.into(), 0.into(), 0.into(), 0.into()) | ||
52 | - , (0.into(), 1.into(), 0.into(), 0.into()) | ||
53 | - , (0.into(), 0.into(), 1.into(), 0.into()) | ||
54 | - , (0.into(), 0.into(), 0.into(), 1.into()) ) | ||
55 | - } | ||
56 | - | ||
57 | - pub fn translate(v :Vector<T>) -> Self { | ||
58 | - let Vector(x, y, z) = v; | ||
59 | - | ||
60 | - Self::new( (1.into(), 0.into(), 0.into(), x) | ||
61 | - , (0.into(), 1.into(), 0.into(), y) | ||
62 | - , (0.into(), 0.into(), 1.into(), z) | ||
63 | - , (0.into(), 0.into(), 0.into(), 1.into()) ) | ||
64 | - } | ||
65 | - | ||
66 | - pub fn rotate_x(a :i32) -> Self { | ||
67 | - let sin :T = Trig::sin(a); | ||
68 | - let cos :T = Trig::cos(a); | ||
69 | - | ||
70 | - Self::new( (1.into(), 0.into(), 0.into(), 0.into()) | ||
71 | - , (0.into(), cos , -sin , 0.into()) | ||
72 | - , (0.into(), sin , cos , 0.into()) | ||
73 | - , (0.into(), 0.into(), 0.into(), 1.into()) ) | ||
74 | - } | ||
75 | - | ||
76 | - pub fn rotate_y(a :i32) -> Self { | ||
77 | - let sin :T = Trig::sin(a); | ||
78 | - let cos :T = Trig::cos(a); | ||
79 | - | ||
80 | - Self::new( (cos , 0.into(), sin , 0.into()) | ||
81 | - , (0.into(), 1.into(), 0.into(), 0.into()) | ||
82 | - , (-sin , 0.into(), cos , 0.into()) | ||
83 | - , (0.into(), 0.into(), 0.into(), 1.into()) ) | ||
84 | - } | ||
85 | - | ||
86 | - pub fn rotate_z(a :i32) -> Self { | ||
87 | - let sin :T = Trig::sin(a); | ||
88 | - let cos :T = Trig::cos(a); | ||
89 | - | ||
90 | - Self::new( (cos , -sin , 0.into(), 0.into()) | ||
91 | - , (sin , cos , 0.into(), 0.into()) | ||
92 | - , (0.into(), 0.into(), 1.into(), 0.into()) | ||
93 | - , (0.into(), 0.into(), 0.into(), 1.into()) ) | ||
94 | - } | ||
95 | - | ||
96 | - pub fn rotate_v(v :&Vector<T>, a :i32) -> Self { | ||
97 | - let Vector(x, y, z) = *v; | ||
98 | - | ||
99 | - let sin :T = Trig::sin(a); | ||
100 | - let cos :T = Trig::cos(a); | ||
101 | - | ||
102 | - let zero :T = 0.into(); | ||
103 | - let one :T = 1.into(); | ||
104 | - | ||
105 | - Self::new( ( (one - cos) * x * x + cos | ||
106 | - , (one - cos) * x * y - sin * z | ||
107 | - , (one - cos) * x * z + sin * y | ||
108 | - , zero ) | ||
109 | - , ( (one - cos) * x * y + sin * z | ||
110 | - , (one - cos) * y * y + cos | ||
111 | - , (one - cos) * y * z - sin * x | ||
112 | - , zero ) | ||
113 | - , ( (one - cos) * x * z - sin * y | ||
114 | - , (one - cos) * y * z + sin * x | ||
115 | - , (one - cos) * z * z + cos | ||
116 | - , zero ) | ||
117 | - , (0.into(), 0.into(), 0.into(), 1.into()) ) | ||
118 | - } | ||
119 | - | ||
120 | - pub fn scale(v :Vector<T>) -> Self { | ||
121 | - let Vector(x, y, z) = v; | ||
122 | - | ||
123 | - Self::new( ( x, 0.into(), 0.into(), 0.into()) | ||
124 | - , (0.into(), y, 0.into(), 0.into()) | ||
125 | - , (0.into(), 0.into(), z, 0.into()) | ||
126 | - , (0.into(), 0.into(), 0.into(), 1.into()) ) | ||
127 | - } | ||
128 | - | ||
129 | - pub fn combine<I>(mi :I) -> TMatrix<T> | ||
130 | - where I: IntoIterator<Item = TMatrix<T>> { | ||
131 | - | ||
132 | - mi.into_iter().fold(Self::unit(), |acc, x| x * acc) | ||
133 | - } | ||
134 | - | ||
135 | - pub fn apply(&self, v :&Vector<T>, w :T) -> (Vector<T>, T) { | ||
136 | - let TMatrix( (a11, a12, a13, a14) | ||
137 | - , (a21, a22, a23, a24) | ||
138 | - , (a31, a32, a33, a34) | ||
139 | - , (a41, a42, a43, a44) ) = *self; | ||
140 | - let Vector(x, y, z) = *v; | ||
141 | - | ||
142 | - let v = Vector( a11 * x + a12 * y + a13 * z + a14 * w | ||
143 | - , a21 * x + a22 * y + a23 * z + a24 * w | ||
144 | - , a31 * x + a32 * y + a33 * z + a34 * w ); | ||
145 | - let w = a41 * x + a42 * y + a43 * z + a44 * w; | ||
146 | - | ||
147 | - //v.mul(&w.recip()) | ||
148 | - (v, w) | ||
149 | - } | ||
150 | -} | ||
151 | - | ||
152 | -impl<T> Mul for TMatrix<T> | ||
153 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
154 | - + Mul<Output = T> + Div<Output = T> | ||
155 | - + Debug + Trig + From<i32> + Copy { | ||
156 | - type Output = Self; | ||
157 | - | ||
158 | - // ATTENTION: This is not commutative, nor assoziative. | ||
159 | - fn mul(self, other :Self) -> Self { | ||
160 | - let TMatrix( (a11, a12, a13, a14) | ||
161 | - , (a21, a22, a23, a24) | ||
162 | - , (a31, a32, a33, a34) | ||
163 | - , (a41, a42, a43, a44) ) = self; | ||
164 | - let TMatrix( (b11, b12, b13, b14) | ||
165 | - , (b21, b22, b23, b24) | ||
166 | - , (b31, b32, b33, b34) | ||
167 | - , (b41, b42, b43, b44) ) = other; | ||
168 | - | ||
169 | - TMatrix( ( a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41 | ||
170 | - , a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42 | ||
171 | - , a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43 | ||
172 | - , a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44 ) | ||
173 | - , ( a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41 | ||
174 | - , a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42 | ||
175 | - , a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43 | ||
176 | - , a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44 ) | ||
177 | - , ( a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41 | ||
178 | - , a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42 | ||
179 | - , a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43 | ||
180 | - , a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44 ) | ||
181 | - , ( a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41 | ||
182 | - , a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42 | ||
183 | - , a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43 | ||
184 | - , a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44 ) ) | ||
185 | - } | ||
186 | -} |
1 | -// | ||
2 | -// Stuff for manipulating 3 dimensional vectors. | ||
3 | -// | ||
4 | -// Georg Hopp <georg@steffers.org> | ||
5 | -// | ||
6 | -// Copyright © 2019 Georg Hopp | ||
7 | -// | ||
8 | -// This program is free software: you can redistribute it and/or modify | ||
9 | -// it under the terms of the GNU General Public License as published by | ||
10 | -// the Free Software Foundation, either version 3 of the License, or | ||
11 | -// (at your option) any later version. | ||
12 | -// | ||
13 | -// This program is distributed in the hope that it will be useful, | ||
14 | -// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | -// GNU General Public License for more details. | ||
17 | -// | ||
18 | -// You should have received a copy of the GNU General Public License | ||
19 | -// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | -// | ||
21 | -use std::fmt::{Debug, Display, Formatter, Result}; | ||
22 | -use std::ops::{Add, Sub, Neg, Mul, Div}; | ||
23 | - | ||
24 | -use crate::trigonometry::Trig; | ||
25 | -use crate::transform::{TMatrix, Transformable}; | ||
26 | - | ||
27 | -#[derive(Debug, Eq, Clone, Copy)] | ||
28 | -pub struct Vector<T>(pub T, pub T, pub T) | ||
29 | - where T: Add + Sub + Neg + Mul + Div + Trig + Copy; | ||
30 | - | ||
31 | -impl<T> Vector<T> | ||
32 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
33 | - + Mul<Output = T> + Div<Output = T> + Trig + Copy { | ||
34 | - pub fn x(self) -> T { self.0 } | ||
35 | - pub fn y(self) -> T { self.1 } | ||
36 | - pub fn z(self) -> T { self.2 } | ||
37 | - | ||
38 | - pub fn mag(self) -> T { | ||
39 | - let Vector(x, y, z) = self; | ||
40 | - (x * x + y * y + z * z).sqrt().unwrap() | ||
41 | - } | ||
42 | - | ||
43 | - pub fn mul(self, s :&T) -> Self { | ||
44 | - let Vector(x, y, z) = self; | ||
45 | - Vector(x * *s, y * *s, z * *s) | ||
46 | - } | ||
47 | - | ||
48 | - pub fn dot(self, other :Self) -> T { | ||
49 | - let Vector(x1, y1, z1) = self; | ||
50 | - let Vector(x2, y2, z2) = other; | ||
51 | - | ||
52 | - x1 * x2 + y1 * y2 + z1 * z2 | ||
53 | - } | ||
54 | - | ||
55 | - pub fn norm(self) -> Self { | ||
56 | - // TODO This can result in 0 or inf Vectors… | ||
57 | - // Maybe we need to handle zero and inf magnitude here… | ||
58 | - self.mul(&self.mag().recip()) | ||
59 | - } | ||
60 | - | ||
61 | - pub fn distance(self, other :Self) -> T { | ||
62 | - (self - other).mag() | ||
63 | - } | ||
64 | -} | ||
65 | - | ||
66 | -impl<T> Display for Vector<T> | ||
67 | -where T: Add + Sub + Neg + Mul + Div + Trig + Display + Copy { | ||
68 | - fn fmt(&self, f :&mut Formatter<'_>) -> Result { | ||
69 | - let Vector(x, y, z) = self; | ||
70 | - write!(f, "({}, {}, {})", x, y, z) | ||
71 | - } | ||
72 | -} | ||
73 | - | ||
74 | -impl<T> PartialEq for Vector<T> | ||
75 | -where T: Add + Sub + Neg + Mul + Div + Trig + PartialEq + Copy { | ||
76 | - fn eq(&self, other :&Self) -> bool { | ||
77 | - let Vector(x1, y1, z1) = self; | ||
78 | - let Vector(x2, y2, z2) = other; | ||
79 | - x1 == x2 && y1 == y2 && z1 == z2 | ||
80 | - } | ||
81 | -} | ||
82 | - | ||
83 | -impl<T> Add for Vector<T> | ||
84 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
85 | - + Mul<Output = T> + Div<Output = T> + Trig + Copy { | ||
86 | - type Output = Self; | ||
87 | - | ||
88 | - fn add(self, other :Self) -> Self { | ||
89 | - let Vector(x1, y1, z1) = self; | ||
90 | - let Vector(x2, y2, z2) = other; | ||
91 | - Vector(x1 + x2, y1 + y2, z1 + z2) | ||
92 | - } | ||
93 | -} | ||
94 | - | ||
95 | -impl<T> Sub for Vector<T> | ||
96 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
97 | - + Mul<Output = T> + Div<Output = T> + Trig + Copy { | ||
98 | - type Output = Self; | ||
99 | - | ||
100 | - fn sub(self, other :Self) -> Self { | ||
101 | - self + -other | ||
102 | - } | ||
103 | -} | ||
104 | - | ||
105 | -impl<T> Neg for Vector<T> | ||
106 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
107 | - + Mul<Output = T> + Div<Output = T> + Trig + Copy { | ||
108 | - type Output = Self; | ||
109 | - | ||
110 | - fn neg(self) -> Self { | ||
111 | - let Vector(x, y, z) = self; | ||
112 | - Self(-x, -y, -z) | ||
113 | - } | ||
114 | -} | ||
115 | - | ||
116 | -impl<T> Mul for Vector<T> | ||
117 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
118 | - + Mul<Output = T> + Div<Output = T> + Trig + Copy { | ||
119 | - type Output = Self; | ||
120 | - | ||
121 | - fn mul(self, other :Self) -> Self { | ||
122 | - let Vector(ax, ay, az) = self; | ||
123 | - let Vector(bx, by, bz) = other; | ||
124 | - | ||
125 | - Vector( ay * bz - az * by | ||
126 | - , az * bx - ax * bz | ||
127 | - , ax * by - ay * bx ) | ||
128 | - } | ||
129 | -} | ||
130 | - | ||
131 | -impl<T> Transformable<T> for Vector<T> | ||
132 | -where T: Add<Output = T> + Sub<Output = T> + Neg<Output = T> | ||
133 | - + Mul<Output = T> + Div<Output = T> | ||
134 | - + Trig + Copy + Debug + From<i32> { | ||
135 | - fn transform(&self, m :&TMatrix<T>) -> Self { | ||
136 | - let (v, _) = m.apply(self, 0.into()); | ||
137 | - v | ||
138 | - } | ||
139 | -} |
variables/Cargo.lock
deleted
100644 → 0
variables/Cargo.toml
deleted
100644 → 0
variables/src/main.rs
deleted
100644 → 0
wasm-game-of-life/.appveyor.yml
deleted
100644 → 0
1 | -install: | ||
2 | - - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe | ||
3 | - - if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly | ||
4 | - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin | ||
5 | - - rustc -V | ||
6 | - - cargo -V | ||
7 | - | ||
8 | -build: false | ||
9 | - | ||
10 | -test_script: | ||
11 | - - cargo test --locked |
wasm-game-of-life/.cargo-ok
deleted
100644 → 0
wasm-game-of-life/.gitignore
deleted
100644 → 0
wasm-game-of-life/.travis.yml
deleted
100644 → 0
1 | -language: rust | ||
2 | -sudo: false | ||
3 | - | ||
4 | -cache: cargo | ||
5 | - | ||
6 | -matrix: | ||
7 | - include: | ||
8 | - | ||
9 | - # Builds with wasm-pack. | ||
10 | - - rust: beta | ||
11 | - env: RUST_BACKTRACE=1 | ||
12 | - addons: | ||
13 | - firefox: latest | ||
14 | - chrome: stable | ||
15 | - before_script: | ||
16 | - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) | ||
17 | - - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) | ||
18 | - - cargo install-update -a | ||
19 | - - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f | ||
20 | - script: | ||
21 | - - cargo generate --git . --name testing | ||
22 | - # Having a broken Cargo.toml (in that it has curlies in fields) anywhere | ||
23 | - # in any of our parent dirs is problematic. | ||
24 | - - mv Cargo.toml Cargo.toml.tmpl | ||
25 | - - cd testing | ||
26 | - - wasm-pack build | ||
27 | - - wasm-pack test --chrome --firefox --headless | ||
28 | - | ||
29 | - # Builds on nightly. | ||
30 | - - rust: nightly | ||
31 | - env: RUST_BACKTRACE=1 | ||
32 | - before_script: | ||
33 | - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) | ||
34 | - - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) | ||
35 | - - cargo install-update -a | ||
36 | - - rustup target add wasm32-unknown-unknown | ||
37 | - script: | ||
38 | - - cargo generate --git . --name testing | ||
39 | - - mv Cargo.toml Cargo.toml.tmpl | ||
40 | - - cd testing | ||
41 | - - cargo check | ||
42 | - - cargo check --target wasm32-unknown-unknown | ||
43 | - - cargo check --no-default-features | ||
44 | - - cargo check --target wasm32-unknown-unknown --no-default-features | ||
45 | - - cargo check --no-default-features --features console_error_panic_hook | ||
46 | - - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook | ||
47 | - - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" | ||
48 | - - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" | ||
49 | - | ||
50 | - # Builds on beta. | ||
51 | - - rust: beta | ||
52 | - env: RUST_BACKTRACE=1 | ||
53 | - before_script: | ||
54 | - - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) | ||
55 | - - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) | ||
56 | - - cargo install-update -a | ||
57 | - - rustup target add wasm32-unknown-unknown | ||
58 | - script: | ||
59 | - - cargo generate --git . --name testing | ||
60 | - - mv Cargo.toml Cargo.toml.tmpl | ||
61 | - - cd testing | ||
62 | - - cargo check | ||
63 | - - cargo check --target wasm32-unknown-unknown | ||
64 | - - cargo check --no-default-features | ||
65 | - - cargo check --target wasm32-unknown-unknown --no-default-features | ||
66 | - - cargo check --no-default-features --features console_error_panic_hook | ||
67 | - - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook | ||
68 | - # Note: no enabling the `wee_alloc` feature here because it requires | ||
69 | - # nightly for now. |
wasm-game-of-life/Cargo.toml
deleted
100644 → 0
1 | -[package] | ||
2 | -name = "wasm-game-of-life" | ||
3 | -version = "0.1.0" | ||
4 | -authors = ["Georg Hopp <georg@steffers.org>"] | ||
5 | -edition = "2018" | ||
6 | - | ||
7 | -[lib] | ||
8 | -crate-type = ["cdylib", "rlib"] | ||
9 | - | ||
10 | -[features] | ||
11 | -default = ["console_error_panic_hook"] | ||
12 | - | ||
13 | -[dependencies] | ||
14 | -wasm-bindgen = "0.2" | ||
15 | - | ||
16 | -# The `console_error_panic_hook` crate provides better debugging of panics by | ||
17 | -# logging them with `console.error`. This is great for development, but requires | ||
18 | -# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for | ||
19 | -# code size when deploying. | ||
20 | -console_error_panic_hook = { version = "0.1.1", optional = true } | ||
21 | - | ||
22 | -# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size | ||
23 | -# compared to the default allocator's ~10K. It is slower than the default | ||
24 | -# allocator, however. | ||
25 | -# | ||
26 | -# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now. | ||
27 | -wee_alloc = { version = "0.4.2", optional = true } | ||
28 | - | ||
29 | -[dev-dependencies] | ||
30 | -wasm-bindgen-test = "0.2" | ||
31 | - | ||
32 | -[profile.release] | ||
33 | -# Tell `rustc` to optimize for small code size. | ||
34 | -opt-level = "s" |
wasm-game-of-life/LICENSE_APACHE
deleted
100644 → 0
1 | - Apache License | ||
2 | - Version 2.0, January 2004 | ||
3 | - http://www.apache.org/licenses/ | ||
4 | - | ||
5 | -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
6 | - | ||
7 | -1. Definitions. | ||
8 | - | ||
9 | - "License" shall mean the terms and conditions for use, reproduction, | ||
10 | - and distribution as defined by Sections 1 through 9 of this document. | ||
11 | - | ||
12 | - "Licensor" shall mean the copyright owner or entity authorized by | ||
13 | - the copyright owner that is granting the License. | ||
14 | - | ||
15 | - "Legal Entity" shall mean the union of the acting entity and all | ||
16 | - other entities that control, are controlled by, or are under common | ||
17 | - control with that entity. For the purposes of this definition, | ||
18 | - "control" means (i) the power, direct or indirect, to cause the | ||
19 | - direction or management of such entity, whether by contract or | ||
20 | - otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
21 | - outstanding shares, or (iii) beneficial ownership of such entity. | ||
22 | - | ||
23 | - "You" (or "Your") shall mean an individual or Legal Entity | ||
24 | - exercising permissions granted by this License. | ||
25 | - | ||
26 | - "Source" form shall mean the preferred form for making modifications, | ||
27 | - including but not limited to software source code, documentation | ||
28 | - source, and configuration files. | ||
29 | - | ||
30 | - "Object" form shall mean any form resulting from mechanical | ||
31 | - transformation or translation of a Source form, including but | ||
32 | - not limited to compiled object code, generated documentation, | ||
33 | - and conversions to other media types. | ||
34 | - | ||
35 | - "Work" shall mean the work of authorship, whether in Source or | ||
36 | - Object form, made available under the License, as indicated by a | ||
37 | - copyright notice that is included in or attached to the work | ||
38 | - (an example is provided in the Appendix below). | ||
39 | - | ||
40 | - "Derivative Works" shall mean any work, whether in Source or Object | ||
41 | - form, that is based on (or derived from) the Work and for which the | ||
42 | - editorial revisions, annotations, elaborations, or other modifications | ||
43 | - represent, as a whole, an original work of authorship. For the purposes | ||
44 | - of this License, Derivative Works shall not include works that remain | ||
45 | - separable from, or merely link (or bind by name) to the interfaces of, | ||
46 | - the Work and Derivative Works thereof. | ||
47 | - | ||
48 | - "Contribution" shall mean any work of authorship, including | ||
49 | - the original version of the Work and any modifications or additions | ||
50 | - to that Work or Derivative Works thereof, that is intentionally | ||
51 | - submitted to Licensor for inclusion in the Work by the copyright owner | ||
52 | - or by an individual or Legal Entity authorized to submit on behalf of | ||
53 | - the copyright owner. For the purposes of this definition, "submitted" | ||
54 | - means any form of electronic, verbal, or written communication sent | ||
55 | - to the Licensor or its representatives, including but not limited to | ||
56 | - communication on electronic mailing lists, source code control systems, | ||
57 | - and issue tracking systems that are managed by, or on behalf of, the | ||
58 | - Licensor for the purpose of discussing and improving the Work, but | ||
59 | - excluding communication that is conspicuously marked or otherwise | ||
60 | - designated in writing by the copyright owner as "Not a Contribution." | ||
61 | - | ||
62 | - "Contributor" shall mean Licensor and any individual or Legal Entity | ||
63 | - on behalf of whom a Contribution has been received by Licensor and | ||
64 | - subsequently incorporated within the Work. | ||
65 | - | ||
66 | -2. Grant of Copyright License. Subject to the terms and conditions of | ||
67 | - this License, each Contributor hereby grants to You a perpetual, | ||
68 | - worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
69 | - copyright license to reproduce, prepare Derivative Works of, | ||
70 | - publicly display, publicly perform, sublicense, and distribute the | ||
71 | - Work and such Derivative Works in Source or Object form. | ||
72 | - | ||
73 | -3. Grant of Patent License. Subject to the terms and conditions of | ||
74 | - this License, each Contributor hereby grants to You a perpetual, | ||
75 | - worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
76 | - (except as stated in this section) patent license to make, have made, | ||
77 | - use, offer to sell, sell, import, and otherwise transfer the Work, | ||
78 | - where such license applies only to those patent claims licensable | ||
79 | - by such Contributor that are necessarily infringed by their | ||
80 | - Contribution(s) alone or by combination of their Contribution(s) | ||
81 | - with the Work to which such Contribution(s) was submitted. If You | ||
82 | - institute patent litigation against any entity (including a | ||
83 | - cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
84 | - or a Contribution incorporated within the Work constitutes direct | ||
85 | - or contributory patent infringement, then any patent licenses | ||
86 | - granted to You under this License for that Work shall terminate | ||
87 | - as of the date such litigation is filed. | ||
88 | - | ||
89 | -4. Redistribution. You may reproduce and distribute copies of the | ||
90 | - Work or Derivative Works thereof in any medium, with or without | ||
91 | - modifications, and in Source or Object form, provided that You | ||
92 | - meet the following conditions: | ||
93 | - | ||
94 | - (a) You must give any other recipients of the Work or | ||
95 | - Derivative Works a copy of this License; and | ||
96 | - | ||
97 | - (b) You must cause any modified files to carry prominent notices | ||
98 | - stating that You changed the files; and | ||
99 | - | ||
100 | - (c) You must retain, in the Source form of any Derivative Works | ||
101 | - that You distribute, all copyright, patent, trademark, and | ||
102 | - attribution notices from the Source form of the Work, | ||
103 | - excluding those notices that do not pertain to any part of | ||
104 | - the Derivative Works; and | ||
105 | - | ||
106 | - (d) If the Work includes a "NOTICE" text file as part of its | ||
107 | - distribution, then any Derivative Works that You distribute must | ||
108 | - include a readable copy of the attribution notices contained | ||
109 | - within such NOTICE file, excluding those notices that do not | ||
110 | - pertain to any part of the Derivative Works, in at least one | ||
111 | - of the following places: within a NOTICE text file distributed | ||
112 | - as part of the Derivative Works; within the Source form or | ||
113 | - documentation, if provided along with the Derivative Works; or, | ||
114 | - within a display generated by the Derivative Works, if and | ||
115 | - wherever such third-party notices normally appear. The contents | ||
116 | - of the NOTICE file are for informational purposes only and | ||
117 | - do not modify the License. You may add Your own attribution | ||
118 | - notices within Derivative Works that You distribute, alongside | ||
119 | - or as an addendum to the NOTICE text from the Work, provided | ||
120 | - that such additional attribution notices cannot be construed | ||
121 | - as modifying the License. | ||
122 | - | ||
123 | - You may add Your own copyright statement to Your modifications and | ||
124 | - may provide additional or different license terms and conditions | ||
125 | - for use, reproduction, or distribution of Your modifications, or | ||
126 | - for any such Derivative Works as a whole, provided Your use, | ||
127 | - reproduction, and distribution of the Work otherwise complies with | ||
128 | - the conditions stated in this License. | ||
129 | - | ||
130 | -5. Submission of Contributions. Unless You explicitly state otherwise, | ||
131 | - any Contribution intentionally submitted for inclusion in the Work | ||
132 | - by You to the Licensor shall be under the terms and conditions of | ||
133 | - this License, without any additional terms or conditions. | ||
134 | - Notwithstanding the above, nothing herein shall supersede or modify | ||
135 | - the terms of any separate license agreement you may have executed | ||
136 | - with Licensor regarding such Contributions. | ||
137 | - | ||
138 | -6. Trademarks. This License does not grant permission to use the trade | ||
139 | - names, trademarks, service marks, or product names of the Licensor, | ||
140 | - except as required for reasonable and customary use in describing the | ||
141 | - origin of the Work and reproducing the content of the NOTICE file. | ||
142 | - | ||
143 | -7. Disclaimer of Warranty. Unless required by applicable law or | ||
144 | - agreed to in writing, Licensor provides the Work (and each | ||
145 | - Contributor provides its Contributions) on an "AS IS" BASIS, | ||
146 | - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
147 | - implied, including, without limitation, any warranties or conditions | ||
148 | - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
149 | - PARTICULAR PURPOSE. You are solely responsible for determining the | ||
150 | - appropriateness of using or redistributing the Work and assume any | ||
151 | - risks associated with Your exercise of permissions under this License. | ||
152 | - | ||
153 | -8. Limitation of Liability. In no event and under no legal theory, | ||
154 | - whether in tort (including negligence), contract, or otherwise, | ||
155 | - unless required by applicable law (such as deliberate and grossly | ||
156 | - negligent acts) or agreed to in writing, shall any Contributor be | ||
157 | - liable to You for damages, including any direct, indirect, special, | ||
158 | - incidental, or consequential damages of any character arising as a | ||
159 | - result of this License or out of the use or inability to use the | ||
160 | - Work (including but not limited to damages for loss of goodwill, | ||
161 | - work stoppage, computer failure or malfunction, or any and all | ||
162 | - other commercial damages or losses), even if such Contributor | ||
163 | - has been advised of the possibility of such damages. | ||
164 | - | ||
165 | -9. Accepting Warranty or Additional Liability. While redistributing | ||
166 | - the Work or Derivative Works thereof, You may choose to offer, | ||
167 | - and charge a fee for, acceptance of support, warranty, indemnity, | ||
168 | - or other liability obligations and/or rights consistent with this | ||
169 | - License. However, in accepting such obligations, You may act only | ||
170 | - on Your own behalf and on Your sole responsibility, not on behalf | ||
171 | - of any other Contributor, and only if You agree to indemnify, | ||
172 | - defend, and hold each Contributor harmless for any liability | ||
173 | - incurred by, or claims asserted against, such Contributor by reason | ||
174 | - of your accepting any such warranty or additional liability. | ||
175 | - | ||
176 | -END OF TERMS AND CONDITIONS |
wasm-game-of-life/LICENSE_MIT
deleted
100644 → 0
1 | -Copyright (c) 2018 Georg Hopp <georg@steffers.org> | ||
2 | - | ||
3 | -Permission is hereby granted, free of charge, to any | ||
4 | -person obtaining a copy of this software and associated | ||
5 | -documentation files (the "Software"), to deal in the | ||
6 | -Software without restriction, including without | ||
7 | -limitation the rights to use, copy, modify, merge, | ||
8 | -publish, distribute, sublicense, and/or sell copies of | ||
9 | -the Software, and to permit persons to whom the Software | ||
10 | -is furnished to do so, subject to the following | ||
11 | -conditions: | ||
12 | - | ||
13 | -The above copyright notice and this permission notice | ||
14 | -shall be included in all copies or substantial portions | ||
15 | -of the Software. | ||
16 | - | ||
17 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF | ||
18 | -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED | ||
19 | -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
20 | -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | ||
21 | -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
22 | -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
23 | -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR | ||
24 | -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
25 | -DEALINGS IN THE SOFTWARE. |
wasm-game-of-life/README.md
deleted
100644 → 0
1 | -<div align="center"> | ||
2 | - | ||
3 | - <h1><code>wasm-pack-template</code></h1> | ||
4 | - | ||
5 | - <strong>A template for kick starting a Rust and WebAssembly project using <a href="https://github.com/rustwasm/wasm-pack">wasm-pack</a>.</strong> | ||
6 | - | ||
7 | - <p> | ||
8 | - <a href="https://travis-ci.org/rustwasm/wasm-pack-template"><img src="https://img.shields.io/travis/rustwasm/wasm-pack-template.svg?style=flat-square" alt="Build Status" /></a> | ||
9 | - </p> | ||
10 | - | ||
11 | - <h3> | ||
12 | - <a href="https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html">Tutorial</a> | ||
13 | - <span> | </span> | ||
14 | - <a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a> | ||
15 | - </h3> | ||
16 | - | ||
17 | - <sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub> | ||
18 | -</div> | ||
19 | - | ||
20 | -## About | ||
21 | - | ||
22 | -[**📚 Read this template tutorial! 📚**][template-docs] | ||
23 | - | ||
24 | -This template is designed for compiling Rust libraries into WebAssembly and | ||
25 | -publishing the resulting package to NPM. | ||
26 | - | ||
27 | -Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other | ||
28 | -templates and usages of `wasm-pack`. | ||
29 | - | ||
30 | -[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html | ||
31 | -[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html | ||
32 | - | ||
33 | -## 🚴 Usage | ||
34 | - | ||
35 | -### 🐑 Use `cargo generate` to Clone this Template | ||
36 | - | ||
37 | -[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) | ||
38 | - | ||
39 | -``` | ||
40 | -cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project | ||
41 | -cd my-project | ||
42 | -``` | ||
43 | - | ||
44 | -### 🛠️ Build with `wasm-pack build` | ||
45 | - | ||
46 | -``` | ||
47 | -wasm-pack build | ||
48 | -``` | ||
49 | - | ||
50 | -### 🔬 Test in Headless Browsers with `wasm-pack test` | ||
51 | - | ||
52 | -``` | ||
53 | -wasm-pack test --headless --firefox | ||
54 | -``` | ||
55 | - | ||
56 | -### 🎁 Publish to NPM with `wasm-pack publish` | ||
57 | - | ||
58 | -``` | ||
59 | -wasm-pack publish | ||
60 | -``` | ||
61 | - | ||
62 | -## 🔋 Batteries Included | ||
63 | - | ||
64 | -* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating | ||
65 | - between WebAssembly and JavaScript. | ||
66 | -* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) | ||
67 | - for logging panic messages to the developer console. | ||
68 | -* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized | ||
69 | - for small code size. |
wasm-game-of-life/package-lock.json
deleted
100644 → 0
wasm-game-of-life/src/lib.rs
deleted
100644 → 0
1 | -mod utils; | ||
2 | - | ||
3 | -use wasm_bindgen::prelude::*; | ||
4 | - | ||
5 | -// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global | ||
6 | -// allocator. | ||
7 | -#[cfg(feature = "wee_alloc")] | ||
8 | -#[global_allocator] | ||
9 | -static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; | ||
10 | - | ||
11 | -#[wasm_bindgen] | ||
12 | -extern { | ||
13 | - fn alert(s: &str); | ||
14 | -} | ||
15 | - | ||
16 | -#[wasm_bindgen] | ||
17 | -pub fn greet(name: &str) { | ||
18 | - alert(&format!("Hello, wasm-game-of-life! {}", name)); | ||
19 | -} |
wasm-game-of-life/src/utils.rs
deleted
100644 → 0
1 | -pub fn set_panic_hook() { | ||
2 | - // When the `console_error_panic_hook` feature is enabled, we can call the | ||
3 | - // `set_panic_hook` function at least once during initialization, and then | ||
4 | - // we will get better error messages if our code ever panics. | ||
5 | - // | ||
6 | - // For more details see | ||
7 | - // https://github.com/rustwasm/console_error_panic_hook#readme | ||
8 | - #[cfg(feature = "console_error_panic_hook")] | ||
9 | - console_error_panic_hook::set_once(); | ||
10 | -} |
wasm-game-of-life/tests/web.rs
deleted
100644 → 0
1 | -#!/usr/bin/env node | ||
2 | - | ||
3 | -const { spawn } = require("child_process"); | ||
4 | -const fs = require("fs"); | ||
5 | - | ||
6 | -let folderName = '.'; | ||
7 | - | ||
8 | -if (process.argv.length >= 3) { | ||
9 | - folderName = process.argv[2]; | ||
10 | - if (!fs.existsSync(folderName)) { | ||
11 | - fs.mkdirSync(folderName); | ||
12 | - } | ||
13 | -} | ||
14 | - | ||
15 | -const clone = spawn("git", ["clone", "https://github.com/rustwasm/create-wasm-app.git", folderName]); | ||
16 | - | ||
17 | -clone.on("close", code => { | ||
18 | - if (code !== 0) { | ||
19 | - console.error("cloning the template failed!") | ||
20 | - process.exit(code); | ||
21 | - } else { | ||
22 | - console.log("🦀 Rust + 🕸 Wasm = ❤"); | ||
23 | - } | ||
24 | -}); |
wasm-game-of-life/www/.gitignore
deleted
100644 → 0
wasm-game-of-life/www/.travis.yml
deleted
100644 → 0
wasm-game-of-life/www/LICENSE-APACHE
deleted
100644 → 0
1 | - Apache License | ||
2 | - Version 2.0, January 2004 | ||
3 | - http://www.apache.org/licenses/ | ||
4 | - | ||
5 | -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
6 | - | ||
7 | -1. Definitions. | ||
8 | - | ||
9 | - "License" shall mean the terms and conditions for use, reproduction, | ||
10 | - and distribution as defined by Sections 1 through 9 of this document. | ||
11 | - | ||
12 | - "Licensor" shall mean the copyright owner or entity authorized by | ||
13 | - the copyright owner that is granting the License. | ||
14 | - | ||
15 | - "Legal Entity" shall mean the union of the acting entity and all | ||
16 | - other entities that control, are controlled by, or are under common | ||
17 | - control with that entity. For the purposes of this definition, | ||
18 | - "control" means (i) the power, direct or indirect, to cause the | ||
19 | - direction or management of such entity, whether by contract or | ||
20 | - otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
21 | - outstanding shares, or (iii) beneficial ownership of such entity. | ||
22 | - | ||
23 | - "You" (or "Your") shall mean an individual or Legal Entity | ||
24 | - exercising permissions granted by this License. | ||
25 | - | ||
26 | - "Source" form shall mean the preferred form for making modifications, | ||
27 | - including but not limited to software source code, documentation | ||
28 | - source, and configuration files. | ||
29 | - | ||
30 | - "Object" form shall mean any form resulting from mechanical | ||
31 | - transformation or translation of a Source form, including but | ||
32 | - not limited to compiled object code, generated documentation, | ||
33 | - and conversions to other media types. | ||
34 | - | ||
35 | - "Work" shall mean the work of authorship, whether in Source or | ||
36 | - Object form, made available under the License, as indicated by a | ||
37 | - copyright notice that is included in or attached to the work | ||
38 | - (an example is provided in the Appendix below). | ||
39 | - | ||
40 | - "Derivative Works" shall mean any work, whether in Source or Object | ||
41 | - form, that is based on (or derived from) the Work and for which the | ||
42 | - editorial revisions, annotations, elaborations, or other modifications | ||
43 | - represent, as a whole, an original work of authorship. For the purposes | ||
44 | - of this License, Derivative Works shall not include works that remain | ||
45 | - separable from, or merely link (or bind by name) to the interfaces of, | ||
46 | - the Work and Derivative Works thereof. | ||
47 | - | ||
48 | - "Contribution" shall mean any work of authorship, including | ||
49 | - the original version of the Work and any modifications or additions | ||
50 | - to that Work or Derivative Works thereof, that is intentionally | ||
51 | - submitted to Licensor for inclusion in the Work by the copyright owner | ||
52 | - or by an individual or Legal Entity authorized to submit on behalf of | ||
53 | - the copyright owner. For the purposes of this definition, "submitted" | ||
54 | - means any form of electronic, verbal, or written communication sent | ||
55 | - to the Licensor or its representatives, including but not limited to | ||
56 | - communication on electronic mailing lists, source code control systems, | ||
57 | - and issue tracking systems that are managed by, or on behalf of, the | ||
58 | - Licensor for the purpose of discussing and improving the Work, but | ||
59 | - excluding communication that is conspicuously marked or otherwise | ||
60 | - designated in writing by the copyright owner as "Not a Contribution." | ||
61 | - | ||
62 | - "Contributor" shall mean Licensor and any individual or Legal Entity | ||
63 | - on behalf of whom a Contribution has been received by Licensor and | ||
64 | - subsequently incorporated within the Work. | ||
65 | - | ||
66 | -2. Grant of Copyright License. Subject to the terms and conditions of | ||
67 | - this License, each Contributor hereby grants to You a perpetual, | ||
68 | - worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
69 | - copyright license to reproduce, prepare Derivative Works of, | ||
70 | - publicly display, publicly perform, sublicense, and distribute the | ||
71 | - Work and such Derivative Works in Source or Object form. | ||
72 | - | ||
73 | -3. Grant of Patent License. Subject to the terms and conditions of | ||
74 | - this License, each Contributor hereby grants to You a perpetual, | ||
75 | - worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||
76 | - (except as stated in this section) patent license to make, have made, | ||
77 | - use, offer to sell, sell, import, and otherwise transfer the Work, | ||
78 | - where such license applies only to those patent claims licensable | ||
79 | - by such Contributor that are necessarily infringed by their | ||
80 | - Contribution(s) alone or by combination of their Contribution(s) | ||
81 | - with the Work to which such Contribution(s) was submitted. If You | ||
82 | - institute patent litigation against any entity (including a | ||
83 | - cross-claim or counterclaim in a lawsuit) alleging that the Work | ||
84 | - or a Contribution incorporated within the Work constitutes direct | ||
85 | - or contributory patent infringement, then any patent licenses | ||
86 | - granted to You under this License for that Work shall terminate | ||
87 | - as of the date such litigation is filed. | ||
88 | - | ||
89 | -4. Redistribution. You may reproduce and distribute copies of the | ||
90 | - Work or Derivative Works thereof in any medium, with or without | ||
91 | - modifications, and in Source or Object form, provided that You | ||
92 | - meet the following conditions: | ||
93 | - | ||
94 | - (a) You must give any other recipients of the Work or | ||
95 | - Derivative Works a copy of this License; and | ||
96 | - | ||
97 | - (b) You must cause any modified files to carry prominent notices | ||
98 | - stating that You changed the files; and | ||
99 | - | ||
100 | - (c) You must retain, in the Source form of any Derivative Works | ||
101 | - that You distribute, all copyright, patent, trademark, and | ||
102 | - attribution notices from the Source form of the Work, | ||
103 | - excluding those notices that do not pertain to any part of | ||
104 | - the Derivative Works; and | ||
105 | - | ||
106 | - (d) If the Work includes a "NOTICE" text file as part of its | ||
107 | - distribution, then any Derivative Works that You distribute must | ||
108 | - include a readable copy of the attribution notices contained | ||
109 | - within such NOTICE file, excluding those notices that do not | ||
110 | - pertain to any part of the Derivative Works, in at least one | ||
111 | - of the following places: within a NOTICE text file distributed | ||
112 | - as part of the Derivative Works; within the Source form or | ||
113 | - documentation, if provided along with the Derivative Works; or, | ||
114 | - within a display generated by the Derivative Works, if and | ||
115 | - wherever such third-party notices normally appear. The contents | ||
116 | - of the NOTICE file are for informational purposes only and | ||
117 | - do not modify the License. You may add Your own attribution | ||
118 | - notices within Derivative Works that You distribute, alongside | ||
119 | - or as an addendum to the NOTICE text from the Work, provided | ||
120 | - that such additional attribution notices cannot be construed | ||
121 | - as modifying the License. | ||
122 | - | ||
123 | - You may add Your own copyright statement to Your modifications and | ||
124 | - may provide additional or different license terms and conditions | ||
125 | - for use, reproduction, or distribution of Your modifications, or | ||
126 | - for any such Derivative Works as a whole, provided Your use, | ||
127 | - reproduction, and distribution of the Work otherwise complies with | ||
128 | - the conditions stated in this License. | ||
129 | - | ||
130 | -5. Submission of Contributions. Unless You explicitly state otherwise, | ||
131 | - any Contribution intentionally submitted for inclusion in the Work | ||
132 | - by You to the Licensor shall be under the terms and conditions of | ||
133 | - this License, without any additional terms or conditions. | ||
134 | - Notwithstanding the above, nothing herein shall supersede or modify | ||
135 | - the terms of any separate license agreement you may have executed | ||
136 | - with Licensor regarding such Contributions. | ||
137 | - | ||
138 | -6. Trademarks. This License does not grant permission to use the trade | ||
139 | - names, trademarks, service marks, or product names of the Licensor, | ||
140 | - except as required for reasonable and customary use in describing the | ||
141 | - origin of the Work and reproducing the content of the NOTICE file. | ||
142 | - | ||
143 | -7. Disclaimer of Warranty. Unless required by applicable law or | ||
144 | - agreed to in writing, Licensor provides the Work (and each | ||
145 | - Contributor provides its Contributions) on an "AS IS" BASIS, | ||
146 | - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
147 | - implied, including, without limitation, any warranties or conditions | ||
148 | - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||
149 | - PARTICULAR PURPOSE. You are solely responsible for determining the | ||
150 | - appropriateness of using or redistributing the Work and assume any | ||
151 | - risks associated with Your exercise of permissions under this License. | ||
152 | - | ||
153 | -8. Limitation of Liability. In no event and under no legal theory, | ||
154 | - whether in tort (including negligence), contract, or otherwise, | ||
155 | - unless required by applicable law (such as deliberate and grossly | ||
156 | - negligent acts) or agreed to in writing, shall any Contributor be | ||
157 | - liable to You for damages, including any direct, indirect, special, | ||
158 | - incidental, or consequential damages of any character arising as a | ||
159 | - result of this License or out of the use or inability to use the | ||
160 | - Work (including but not limited to damages for loss of goodwill, | ||
161 | - work stoppage, computer failure or malfunction, or any and all | ||
162 | - other commercial damages or losses), even if such Contributor | ||
163 | - has been advised of the possibility of such damages. | ||
164 | - | ||
165 | -9. Accepting Warranty or Additional Liability. While redistributing | ||
166 | - the Work or Derivative Works thereof, You may choose to offer, | ||
167 | - and charge a fee for, acceptance of support, warranty, indemnity, | ||
168 | - or other liability obligations and/or rights consistent with this | ||
169 | - License. However, in accepting such obligations, You may act only | ||
170 | - on Your own behalf and on Your sole responsibility, not on behalf | ||
171 | - of any other Contributor, and only if You agree to indemnify, | ||
172 | - defend, and hold each Contributor harmless for any liability | ||
173 | - incurred by, or claims asserted against, such Contributor by reason | ||
174 | - of your accepting any such warranty or additional liability. | ||
175 | - | ||
176 | -END OF TERMS AND CONDITIONS | ||
177 | - | ||
178 | -APPENDIX: How to apply the Apache License to your work. | ||
179 | - | ||
180 | - To apply the Apache License to your work, attach the following | ||
181 | - boilerplate notice, with the fields enclosed by brackets "[]" | ||
182 | - replaced with your own identifying information. (Don't include | ||
183 | - the brackets!) The text should be enclosed in the appropriate | ||
184 | - comment syntax for the file format. We also recommend that a | ||
185 | - file or class name and description of purpose be included on the | ||
186 | - same "printed page" as the copyright notice for easier | ||
187 | - identification within third-party archives. | ||
188 | - | ||
189 | -Copyright [yyyy] [name of copyright owner] | ||
190 | - | ||
191 | -Licensed under the Apache License, Version 2.0 (the "License"); | ||
192 | -you may not use this file except in compliance with the License. | ||
193 | -You may obtain a copy of the License at | ||
194 | - | ||
195 | - http://www.apache.org/licenses/LICENSE-2.0 | ||
196 | - | ||
197 | -Unless required by applicable law or agreed to in writing, software | ||
198 | -distributed under the License is distributed on an "AS IS" BASIS, | ||
199 | -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
200 | -See the License for the specific language governing permissions and | ||
201 | -limitations under the License. |
wasm-game-of-life/www/LICENSE-MIT
deleted
100644 → 0
1 | -Copyright (c) [year] [name] | ||
2 | - | ||
3 | -Permission is hereby granted, free of charge, to any | ||
4 | -person obtaining a copy of this software and associated | ||
5 | -documentation files (the "Software"), to deal in the | ||
6 | -Software without restriction, including without | ||
7 | -limitation the rights to use, copy, modify, merge, | ||
8 | -publish, distribute, sublicense, and/or sell copies of | ||
9 | -the Software, and to permit persons to whom the Software | ||
10 | -is furnished to do so, subject to the following | ||
11 | -conditions: | ||
12 | - | ||
13 | -The above copyright notice and this permission notice | ||
14 | -shall be included in all copies or substantial portions | ||
15 | -of the Software. | ||
16 | - | ||
17 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF | ||
18 | -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED | ||
19 | -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | ||
20 | -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | ||
21 | -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
22 | -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
23 | -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR | ||
24 | -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
25 | -DEALINGS IN THE SOFTWARE. |
wasm-game-of-life/www/README.md
deleted
100644 → 0
1 | -<div align="center"> | ||
2 | - | ||
3 | - <h1><code>create-wasm-app</code></h1> | ||
4 | - | ||
5 | - <strong>An <code>npm init</code> template for kick starting a project that uses NPM packages containing Rust-generated WebAssembly and bundles them with Webpack.</strong> | ||
6 | - | ||
7 | - <p> | ||
8 | - <a href="https://travis-ci.org/rustwasm/create-wasm-app"><img src="https://img.shields.io/travis/rustwasm/create-wasm-app.svg?style=flat-square" alt="Build Status" /></a> | ||
9 | - </p> | ||
10 | - | ||
11 | - <h3> | ||
12 | - <a href="#usage">Usage</a> | ||
13 | - <span> | </span> | ||
14 | - <a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a> | ||
15 | - </h3> | ||
16 | - | ||
17 | - <sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub> | ||
18 | -</div> | ||
19 | - | ||
20 | -## About | ||
21 | - | ||
22 | -This template is designed for depending on NPM packages that contain | ||
23 | -Rust-generated WebAssembly and using them to create a Website. | ||
24 | - | ||
25 | -* Want to create an NPM package with Rust and WebAssembly? [Check out | ||
26 | - `wasm-pack-template`.](https://github.com/rustwasm/wasm-pack-template) | ||
27 | -* Want to make a monorepo-style Website without publishing to NPM? Check out | ||
28 | - [`rust-webpack-template`](https://github.com/rustwasm/rust-webpack-template) | ||
29 | - and/or | ||
30 | - [`rust-parcel-template`](https://github.com/rustwasm/rust-parcel-template). | ||
31 | - | ||
32 | -## 🚴 Usage | ||
33 | - | ||
34 | -``` | ||
35 | -npm init wasm-app | ||
36 | -``` | ||
37 | - | ||
38 | -## 🔋 Batteries Included | ||
39 | - | ||
40 | -- `.gitignore`: ignores `node_modules` | ||
41 | -- `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you | ||
42 | -- `README.md`: the file you are reading now! | ||
43 | -- `index.html`: a bare bones html document that includes the webpack bundle | ||
44 | -- `index.js`: example js file with a comment showing how to import and use a wasm pkg | ||
45 | -- `package.json` and `package-lock.json`: | ||
46 | - - pulls in devDependencies for using webpack: | ||
47 | - - [`webpack`](https://www.npmjs.com/package/webpack) | ||
48 | - - [`webpack-cli`](https://www.npmjs.com/package/webpack-cli) | ||
49 | - - [`webpack-dev-server`](https://www.npmjs.com/package/webpack-dev-server) | ||
50 | - - defines a `start` script to run `webpack-dev-server` | ||
51 | -- `webpack.config.js`: configuration file for bundling your js with webpack | ||
52 | - | ||
53 | -## License | ||
54 | - | ||
55 | -Licensed under either of | ||
56 | - | ||
57 | -* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) | ||
58 | -* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) | ||
59 | - | ||
60 | -at your option. | ||
61 | - | ||
62 | -### Contribution | ||
63 | - | ||
64 | -Unless you explicitly state otherwise, any contribution intentionally | ||
65 | -submitted for inclusion in the work by you, as defined in the Apache-2.0 | ||
66 | -license, shall be dual licensed as above, without any additional terms or | ||
67 | -conditions. |
wasm-game-of-life/www/bootstrap.js
deleted
100644 → 0
wasm-game-of-life/www/index.html
deleted
100644 → 0
1 | -<!DOCTYPE html> | ||
2 | -<html> | ||
3 | - <head> | ||
4 | - <meta charset="utf-8"> | ||
5 | - <title>Hello wasm-pack!</title> | ||
6 | - </head> | ||
7 | - <body> | ||
8 | - <noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript> | ||
9 | - <script src="./bootstrap.js"></script> | ||
10 | - </body> | ||
11 | -</html> |
wasm-game-of-life/www/index.js
deleted
100644 → 0
This diff could not be displayed because it is too large.
wasm-game-of-life/www/package.json
deleted
100644 → 0
1 | -{ | ||
2 | - "name": "create-wasm-app", | ||
3 | - "version": "0.1.0", | ||
4 | - "description": "create an app to consume rust-generated wasm packages", | ||
5 | - "main": "index.js", | ||
6 | - "bin": { | ||
7 | - "create-wasm-app": ".bin/create-wasm-app.js" | ||
8 | - }, | ||
9 | - "scripts": { | ||
10 | - "build": "webpack --config webpack.config.js", | ||
11 | - "start": "webpack-dev-server" | ||
12 | - }, | ||
13 | - "repository": { | ||
14 | - "type": "git", | ||
15 | - "url": "git+https://github.com/rustwasm/create-wasm-app.git" | ||
16 | - }, | ||
17 | - "keywords": [ | ||
18 | - "webassembly", | ||
19 | - "wasm", | ||
20 | - "rust", | ||
21 | - "webpack" | ||
22 | - ], | ||
23 | - "author": "Ashley Williams <ashley666ashley@gmail.com>", | ||
24 | - "license": "(MIT OR Apache-2.0)", | ||
25 | - "bugs": { | ||
26 | - "url": "https://github.com/rustwasm/create-wasm-app/issues" | ||
27 | - }, | ||
28 | - "homepage": "https://github.com/rustwasm/create-wasm-app#readme", | ||
29 | - "devDependencies": { | ||
30 | - "wasm-game-of-life": "file:../pkg", | ||
31 | - "hello-wasm-pack": "^0.1.0", | ||
32 | - "webpack": "^4.29.3", | ||
33 | - "webpack-cli": "^3.1.0", | ||
34 | - "webpack-dev-server": "^3.1.5", | ||
35 | - "copy-webpack-plugin": "^5.0.0" | ||
36 | - } | ||
37 | -} |
1 | -const CopyWebpackPlugin = require("copy-webpack-plugin"); | ||
2 | -const path = require('path'); | ||
3 | - | ||
4 | -module.exports = { | ||
5 | - entry: "./bootstrap.js", | ||
6 | - output: { | ||
7 | - path: path.resolve(__dirname, "dist"), | ||
8 | - filename: "bootstrap.js", | ||
9 | - }, | ||
10 | - mode: "development", | ||
11 | - plugins: [ | ||
12 | - new CopyWebpackPlugin(['index.html']) | ||
13 | - ], | ||
14 | -}; |
xcb-test/.gitignore
deleted
100644 → 0
xcb-test/Cargo.toml
deleted
100644 → 0
1 | -[package] | ||
2 | -name = "xcb-test" | ||
3 | -version = "0.1.0" | ||
4 | -authors = ["Georg Hopp <georg@steffers.org>"] | ||
5 | -edition = "2018" | ||
6 | - | ||
7 | -[dependencies] | ||
8 | -libc = "0.2" | ||
9 | -gl = "0.5.2" | ||
10 | -x11 = { version = "2.3", features = ["glx"] } | ||
11 | -xcb = { version = "0.8", features = ["dri2", "randr", "thread", "xlib_xcb", "shm"] } |
xcb-test/Makefile
deleted
100644 → 0
xcb-test/alternatives/info.rs
deleted
100644 → 0
1 | -extern crate xcb; | ||
2 | - | ||
3 | -use std::iter::{Iterator}; | ||
4 | -use xcb::randr; | ||
5 | - | ||
6 | -fn main() { | ||
7 | - | ||
8 | - let dpy = ":0"; | ||
9 | - let (conn, screen_num) = xcb::Connection::connect(Some(&dpy)).unwrap(); | ||
10 | - | ||
11 | - let setup = conn.get_setup(); | ||
12 | - let screen = setup.roots().nth(screen_num as usize).unwrap(); | ||
13 | - | ||
14 | - println!(""); | ||
15 | - println!("Informations of screen {}:", screen.root()); | ||
16 | - println!(" width..........: {}", screen.width_in_pixels()); | ||
17 | - println!(" height.........: {}", screen.height_in_pixels()); | ||
18 | - println!(" white pixel....: {:x}", screen.white_pixel()); | ||
19 | - println!(" black pixel....: {:x}", screen.black_pixel()); | ||
20 | - | ||
21 | - let window_dummy = conn.generate_id(); | ||
22 | - xcb::create_window( | ||
23 | - &conn, 0, window_dummy, screen.root() | ||
24 | - , 0, 0, 1, 1, 0, 0, 0, &[]); | ||
25 | - | ||
26 | - conn.flush(); | ||
27 | - | ||
28 | - let cookie = randr::get_screen_info(&conn, window_dummy); | ||
29 | - let reply = cookie.get_reply().unwrap(); | ||
30 | - let sizes = reply.sizes(); | ||
31 | - | ||
32 | - for (i, size) in sizes.enumerate() { | ||
33 | - if i != 0 { println!(""); } | ||
34 | - println!("size of screen {}:", i+1); | ||
35 | - println!(" {} x {} ({}mm x {}mm)", size.width(), size.height(), | ||
36 | - size.mwidth(), size.mheight()); | ||
37 | - } | ||
38 | - | ||
39 | - // ==== | ||
40 | - | ||
41 | - let window = conn.generate_id(); | ||
42 | - | ||
43 | - let values = [ | ||
44 | - (xcb::CW_BACK_PIXEL, screen.white_pixel()), | ||
45 | - (xcb::CW_EVENT_MASK, xcb::EVENT_MASK_EXPOSURE | xcb::EVENT_MASK_KEY_PRESS), | ||
46 | - ]; | ||
47 | - | ||
48 | - xcb::create_window(&conn, | ||
49 | - xcb::COPY_FROM_PARENT as u8, | ||
50 | - window, | ||
51 | - screen.root(), | ||
52 | - 0, 0, | ||
53 | - 150, 150, | ||
54 | - 10, | ||
55 | - xcb::WINDOW_CLASS_INPUT_OUTPUT as u16, | ||
56 | - screen.root_visual(), | ||
57 | - &values); | ||
58 | - | ||
59 | - xcb::map_window(&conn, window); | ||
60 | - | ||
61 | - let title = "Basic Window"; | ||
62 | - // setting title | ||
63 | - xcb::change_property(&conn, xcb::PROP_MODE_REPLACE as u8, window, | ||
64 | - xcb::ATOM_WM_NAME, xcb::ATOM_STRING, 8, title.as_bytes()); | ||
65 | - | ||
66 | - conn.flush(); | ||
67 | - | ||
68 | - // retrieving title | ||
69 | - let cookie = xcb::get_property(&conn, false, window, xcb::ATOM_WM_NAME, | ||
70 | - xcb::ATOM_STRING, 0, 1024); | ||
71 | - if let Ok(reply) = cookie.get_reply() { | ||
72 | - assert_eq!(std::str::from_utf8(reply.value()).unwrap(), title); | ||
73 | - } else { | ||
74 | - panic!("could not retrieve window title!"); | ||
75 | - } | ||
76 | - | ||
77 | - // retrieving a few atoms | ||
78 | - let (wm_state, wm_state_maxv, wm_state_maxh) = { | ||
79 | - let cook = xcb::intern_atom(&conn, true, "_NET_WM_STATE"); | ||
80 | - let cook_maxv = xcb::intern_atom(&conn, true, "_NET_WM_STATE_MAXIMIZED_VERT"); | ||
81 | - let cook_maxh = xcb::intern_atom(&conn, true, "_NET_WM_STATE_MAXIMIZED_HORZ"); | ||
82 | - | ||
83 | - (cook.get_reply().unwrap().atom(), | ||
84 | - cook_maxv.get_reply().unwrap().atom(), | ||
85 | - cook_maxh.get_reply().unwrap().atom()) | ||
86 | - }; | ||
87 | - | ||
88 | - let mut maximized = false; | ||
89 | - | ||
90 | - loop { | ||
91 | - let event = conn.wait_for_event(); | ||
92 | - match event { | ||
93 | - None => { break; } | ||
94 | - Some(event) => { | ||
95 | - let r = event.response_type(); | ||
96 | - if r == xcb::KEY_PRESS as u8 { | ||
97 | - let key_press : &xcb::KeyPressEvent = unsafe { | ||
98 | - xcb::cast_event(&event) | ||
99 | - }; | ||
100 | - | ||
101 | - println!("Key '{}' pressed", key_press.detail()); | ||
102 | - | ||
103 | - if key_press.detail() == 0x3a { // M (on qwerty) | ||
104 | - | ||
105 | - // toggle maximized | ||
106 | - println!("toggle maximized: {} {}", wm_state_maxv, wm_state_maxh); | ||
107 | - | ||
108 | - // ClientMessageData is a memory safe untagged union | ||
109 | - let data = xcb::ClientMessageData::from_data32([ | ||
110 | - if maximized { 0 } else { 1 }, | ||
111 | - wm_state_maxv, wm_state_maxh, | ||
112 | - 0, 0 | ||
113 | - ]); | ||
114 | - | ||
115 | - let ev = xcb::ClientMessageEvent::new(32, window, | ||
116 | - wm_state, data); | ||
117 | - | ||
118 | - xcb::send_event(&conn, false, screen.root(), | ||
119 | - xcb::EVENT_MASK_STRUCTURE_NOTIFY, &ev); | ||
120 | - | ||
121 | - conn.flush(); | ||
122 | - | ||
123 | - maximized = !maximized; | ||
124 | - } | ||
125 | - else if key_press.detail() == 0x18 { // Q (on qwerty) | ||
126 | - break; | ||
127 | - } | ||
128 | - } | ||
129 | - } | ||
130 | - } | ||
131 | - } | ||
132 | -} |
Please
register
or
login
to post a comment