1use crate::error::{ElementError, ElementOrderError};
2use crate::position_modeler::PositionModeler;
3use crate::state_modeler::StateModeler;
4use crate::utils::interp;
5use crate::utils::normalize01_64;
6use crate::{ModelerError, ModelerInput, ModelerInputEventType, ModelerParams, ModelerResult};
7use std::collections::VecDeque;
8use std::vec;
9
10#[derive(Debug)]
18pub(crate) struct WobbleSample {
19 pub position: (f64, f64),
21 pub weighted_position: (f64, f64),
23 pub distance: f64,
25 pub duration: f64,
27 pub time: f64,
29}
30
31pub struct StrokeModeler {
43 pub(crate) params: ModelerParams,
45 pub(crate) wobble_deque: VecDeque<WobbleSample>,
49 pub(crate) wobble_weighted_pos_sum: (f64, f64),
51 pub(crate) wobble_duration_sum: f64,
53 pub(crate) wobble_distance_sum: f64,
55 pub(crate) position_modeler: Option<PositionModeler>,
58 pub(crate) last_event: Option<ModelerInput>,
59 pub(crate) last_corrected_event: Option<(f64, f64)>,
60 pub(crate) state_modeler: StateModeler,
61}
62
63impl Default for StrokeModeler {
64 fn default() -> Self {
65 let params = ModelerParams::suggested();
66
67 Self {
68 params,
69 wobble_deque: VecDeque::with_capacity(
70 (2.0 * params.sampling_min_output_rate * params.wobble_smoother_timeout) as usize,
71 ),
72 wobble_weighted_pos_sum: (0.0, 0.0),
73 wobble_duration_sum: 0.0,
74 wobble_distance_sum: 0.0,
75
76 last_event: None,
77 last_corrected_event: None,
78 position_modeler: None,
79 state_modeler: StateModeler::new(params.stylus_state_modeler_max_input_samples),
80 }
81 }
82}
83
84#[doc = include_str!("../docs/notations.html")]
85#[doc = include_str!("../docs/resampling.html")]
86#[doc = include_str!("../docs/position_modeling.html")]
87#[doc = include_str!("../docs/stylus_state_modeler.html")]
88#[doc = include_str!("../docs/stroke_end.html")]
89impl StrokeModeler {
90 pub fn new(params: ModelerParams) -> Result<Self, String> {
91 params.validate()?;
92 Ok(Self {
93 params,
94 last_event: None,
95 last_corrected_event: None,
96 wobble_deque: VecDeque::with_capacity(
97 (2.0 * params.sampling_min_output_rate * params.wobble_smoother_timeout) as usize,
98 ),
99 wobble_duration_sum: 0.0,
100 wobble_weighted_pos_sum: (0.0, 0.0),
101 wobble_distance_sum: 0.0,
102 position_modeler: None,
103 state_modeler: StateModeler::new(params.stylus_state_modeler_max_input_samples),
104 })
105 }
106
107 pub fn reset(&mut self) {
109 self.wobble_deque.clear();
110 self.wobble_weighted_pos_sum = (0.0, 0.0);
111 self.wobble_duration_sum = 0.0;
112 self.position_modeler = None;
113 self.last_event = None;
114 self.last_corrected_event = None;
115 self.state_modeler
116 .reset(self.params.stylus_state_modeler_max_input_samples);
117 }
118
119 pub fn reset_w_params(&mut self, params: ModelerParams) -> Result<(), String> {
122 params.validate()?;
123 self.params = params;
124 self.wobble_deque = VecDeque::with_capacity(
125 (2.0 * params.sampling_min_output_rate * params.wobble_smoother_timeout) as usize,
126 );
127 self.wobble_weighted_pos_sum = (0.0, 0.0);
128 self.wobble_duration_sum = 0.0;
129 self.wobble_distance_sum = 0.0;
130 self.position_modeler = None;
131 self.last_event = None;
132 self.last_corrected_event = None;
133 self.state_modeler
134 .reset(params.stylus_state_modeler_max_input_samples);
135 Ok(())
136 }
137
138 pub fn update(&mut self, input: ModelerInput) -> Result<Vec<ModelerResult>, ModelerError> {
146 match input.event_type {
147 ModelerInputEventType::Down => {
148 if self.last_event.is_some() {
149 return Err(ModelerError::Element {
150 src: ElementError::Order {
151 src: ElementOrderError::UnexpectedDown,
152 },
153 });
154 }
155 self.wobble_update(&input); self.position_modeler = Some(PositionModeler::new(self.params, input.clone()));
158
159 self.last_event = Some(input.clone());
160 self.last_corrected_event = Some(input.pos);
161 self.state_modeler
162 .reset(self.params.stylus_state_modeler_max_input_samples);
163 self.state_modeler.update(input.clone());
164 Ok(vec![ModelerResult {
165 pos: input.pos,
166 velocity: (0.0, 0.0),
167 acceleration: (0.0, 0.0),
168 time: input.time,
169 pressure: input.pressure,
170 }])
171 }
172 ModelerInputEventType::Move => {
173 if self.last_event.is_none() {
175 return Err(ModelerError::Element {
176 src: ElementError::Order {
177 src: ElementOrderError::UnexpectedMove,
178 },
179 });
180 }
181 let latest_time = self.last_event.as_ref().unwrap().time;
182 let new_time = input.time;
183
184 if new_time - latest_time < 0.0 {
187 return Err(ModelerError::Element {
188 src: ElementError::NegativeTimeDelta,
189 });
190 }
191 if input == *self.last_event.as_ref().unwrap() {
192 return Err(ModelerError::Element {
193 src: ElementError::Duplicate,
194 });
195 }
196
197 self.state_modeler.update(input.clone());
198
199 let n_steps =
201 ((new_time - latest_time) * self.params.sampling_min_output_rate).ceil() as i32;
202
203 if n_steps as usize > self.params.sampling_max_outputs_per_call {
206 return Err(ModelerError::Element {
207 src: ElementError::TooFarApart,
208 });
209 }
210
211 let p_start = self.last_corrected_event.unwrap();
212 let p_end = self.wobble_update(&input);
213 let vec_out: Vec<ModelerResult> = self
216 .position_modeler
217 .as_mut()
218 .unwrap()
219 .update_along_linear_path(p_start, latest_time, p_end, new_time, n_steps)
220 .into_iter()
221 .map(|i| ModelerResult {
222 pressure: self.state_modeler.query(i.pos),
223 pos: i.pos,
224 velocity: i.velocity,
225 acceleration: i.acceleration,
226 time: i.time,
227 })
228 .collect();
229
230 self.last_event = Some(input.clone());
232 self.last_corrected_event = Some(p_end);
233
234 Ok(vec_out)
235 }
236 ModelerInputEventType::Up => {
237 if self.last_event.is_none() {
239 return Err(ModelerError::Element {
240 src: ElementError::Order {
241 src: ElementOrderError::UnexpectedUp,
242 },
243 });
244 }
245 let latest_time = self.last_event.as_ref().unwrap().time;
246 let new_time = input.time;
247
248 if new_time - latest_time < 0.0 {
250 return Err(ModelerError::Element {
251 src: ElementError::NegativeTimeDelta,
252 });
253 }
254 if input == *self.last_event.as_ref().unwrap() {
255 return Err(ModelerError::Element {
256 src: ElementError::Duplicate,
257 });
258 }
259
260 self.state_modeler.update(input.clone());
261
262 let n_tsteps =
264 ((new_time - latest_time) * self.params.sampling_min_output_rate).ceil() as i32;
265
266 if n_tsteps as usize > self.params.sampling_max_outputs_per_call {
269 return Err(ModelerError::Element {
270 src: ElementError::TooFarApart,
271 });
272 }
273
274 let p_start = self.last_corrected_event.unwrap();
275 let p_end = self.wobble_update(&input);
280
281 let mut vec_out = Vec::<ModelerResult>::with_capacity(
282 (n_tsteps as usize) + self.params.sampling_end_of_stroke_max_iterations,
283 );
284
285 vec_out.extend(
286 self.position_modeler
287 .as_mut()
288 .unwrap()
289 .update_along_linear_path(p_start, latest_time, p_end, new_time, n_tsteps)
290 .into_iter()
291 .map(|i| ModelerResult {
292 pressure: self.state_modeler.query(i.pos),
293 pos: i.pos,
294 velocity: i.velocity,
295 time: i.time,
296 acceleration: i.acceleration,
297 }),
298 );
299
300 vec_out.extend(
302 self.position_modeler
303 .as_mut()
304 .unwrap()
305 .model_end_of_stroke(
306 input.pos,
307 1. / self.params.sampling_min_output_rate,
308 self.params.sampling_end_of_stroke_max_iterations,
309 self.params.sampling_end_of_stroke_stopping_distance,
310 )
311 .into_iter()
312 .map(|i| ModelerResult {
313 pressure: self.state_modeler.query(i.pos),
314 pos: i.pos,
315 velocity: i.velocity,
316 acceleration: i.acceleration,
317 time: i.time,
318 }),
319 );
320
321 if vec_out.is_empty() {
322 let state_pos = self.position_modeler.as_ref().unwrap().state.clone();
323 vec_out.push(ModelerResult {
324 pos: state_pos.pos,
325 velocity: state_pos.velocity,
326 acceleration: state_pos.acceleration,
327 time: state_pos.time + 1. / self.params.sampling_min_output_rate,
335 pressure: self.state_modeler.query(state_pos.pos),
336 });
337 }
338
339 self.last_event = None;
341
342 Ok(vec_out)
343 }
344 }
345 }
346
347 pub fn predict(&mut self) -> Result<Vec<ModelerResult>, String> {
352 if self.last_event.is_none() {
354 Err(String::from("empty input events"))
356 } else {
357 let predict = self
359 .position_modeler
360 .as_mut()
361 .unwrap()
362 .model_end_of_stroke(
363 self.last_event.as_ref().unwrap().pos,
364 1. / self.params.sampling_min_output_rate,
365 self.params.sampling_end_of_stroke_max_iterations,
366 self.params.sampling_end_of_stroke_stopping_distance,
367 )
368 .into_iter()
369 .map(|i| ModelerResult {
370 pos: i.pos,
371 velocity: i.velocity,
372 acceleration: i.acceleration,
373 time: i.time,
374 pressure: self.state_modeler.query(i.pos),
375 })
376 .collect();
377 Ok(predict)
378 }
379 }
380 #[doc = include_str!("../docs/wobble.html")]
386 fn wobble_update(&mut self, event: &ModelerInput) -> (f64, f64) {
387 match self.wobble_deque.len() {
388 0 => {
389 self.wobble_deque.push_back(WobbleSample {
390 position: event.pos,
391 weighted_position: (0.0, 0.0),
392 distance: 0.0,
393 duration: 0.0,
394 time: event.time,
395 });
396 event.pos
397 }
398 _ => {
399 let last_el = self.wobble_deque.back().unwrap();
400 let duration = event.time - last_el.time;
401 let weighted_pos = (event.pos.0 * duration, event.pos.1 * duration);
402 let distance = ((event.pos.0 - last_el.position.0).powi(2)
403 + (event.pos.1 - last_el.position.1).powi(2))
404 .sqrt();
405
406 self.wobble_deque.push_back(WobbleSample {
407 position: event.pos,
408 weighted_position: weighted_pos,
409 distance,
410 duration,
411 time: event.time,
412 });
413 let last_pos = self.wobble_weighted_pos_sum;
414 self.wobble_weighted_pos_sum =
415 (last_pos.0 + weighted_pos.0, last_pos.1 + weighted_pos.1);
416 self.wobble_distance_sum += distance;
417 self.wobble_duration_sum += duration;
418
419 while self.wobble_deque.front().unwrap().time
420 < event.time - self.params.wobble_smoother_timeout
421 {
422 let front_el = self.wobble_deque.pop_front().unwrap();
423
424 let last_pos = self.wobble_weighted_pos_sum;
425 self.wobble_weighted_pos_sum = (
426 last_pos.0 - front_el.weighted_position.0,
427 last_pos.1 - front_el.weighted_position.1,
428 );
429 self.wobble_distance_sum -= front_el.distance;
430 self.wobble_duration_sum -= front_el.duration;
431 }
432
433 if self.wobble_duration_sum < 1e-12 {
434 event.pos
435 } else {
436 let avg_position = (
439 self.wobble_weighted_pos_sum.0 / self.wobble_duration_sum,
440 self.wobble_weighted_pos_sum.1 / self.wobble_duration_sum,
441 );
442
443 let avg_speed = self.wobble_distance_sum / self.wobble_duration_sum;
444 let norm_value = normalize01_64(
445 self.params.wobble_smoother_speed_floor,
446 self.params.wobble_smoother_speed_ceiling,
447 avg_speed,
448 );
449 (
450 interp(avg_position.0, event.pos.0, norm_value),
451 interp(avg_position.1, event.pos.1, norm_value),
452 )
453 }
454 }
455 }
456 }
457}
458
459#[cfg(test)]
460mod tests {
461
462 use super::super::*;
463 use crate::results::compare_results;
464
465 #[cfg(test)]
468 fn util_compare_floats(a1: (f64, f64), a2: (f64, f64)) -> bool {
469 return approx::abs_diff_eq!(a1.0, a2.0, epsilon = 0.0001)
470 && approx::abs_diff_eq!(a1.1, a2.1, epsilon = 0.0001);
471 }
472
473 #[test]
476 fn test_wobble_smoother_line() {
477 let mut new_modeler = StrokeModeler::default();
479 new_modeler.wobble_update(&ModelerInput {
480 event_type: ModelerInputEventType::Down,
481 pos: (3., 4.),
482 time: 1.0,
483 pressure: 0.0,
484 });
485 assert!(util_compare_floats(
486 new_modeler.wobble_update(&ModelerInput {
487 event_type: ModelerInputEventType::Move,
488 pos: (3.016, 4.),
489 time: 1.016,
490 pressure: 0.0,
491 }),
492 (3.016, 4.)
493 ));
494 assert!(util_compare_floats(
495 new_modeler.wobble_update(&ModelerInput {
496 event_type: ModelerInputEventType::Move,
497 pos: (3.032, 4.),
498 time: 1.032,
499 pressure: 0.0,
500 }),
501 (3.024, 4.)
502 ));
503 assert!(util_compare_floats(
504 new_modeler.wobble_update(&ModelerInput {
505 event_type: ModelerInputEventType::Move,
506 pos: (3.048, 4.),
507 time: 1.048,
508 pressure: 0.0,
509 }),
510 (3.032, 4.)
511 ));
512 assert!(util_compare_floats(
513 new_modeler.wobble_update(&ModelerInput {
514 event_type: ModelerInputEventType::Move,
515 pos: (3.064, 4.),
516 time: 1.064,
517 pressure: 0.0,
518 }),
519 (3.048, 4.)
520 ));
521 }
522
523 #[test]
524 fn test_wobble_zigzag_slow() {
525 let mut new_modeler = StrokeModeler::default();
527 new_modeler.wobble_update(&ModelerInput {
528 event_type: ModelerInputEventType::Down,
529 pos: (1., 2.),
530 time: 5.0,
531 pressure: 0.0,
532 });
533 assert!(util_compare_floats(
534 new_modeler.wobble_update(&ModelerInput {
535 event_type: ModelerInputEventType::Move,
536 pos: (1.016, 2.),
537 time: 5.016,
538 pressure: 0.0,
539 }),
540 (1.016, 2.0)
541 ));
542 assert!(util_compare_floats(
543 new_modeler.wobble_update(&ModelerInput {
544 event_type: ModelerInputEventType::Move,
545 pos: (1.016, 2.016),
546 time: 5.032,
547 pressure: 0.0,
548 }),
549 (1.016, 2.008)
550 ));
551 assert!(util_compare_floats(
552 new_modeler.wobble_update(&ModelerInput {
553 event_type: ModelerInputEventType::Move,
554 pos: (1.032, 2.016),
555 time: 5.048,
556 pressure: 0.0,
557 }),
558 (1.02133, 2.01067)
559 ));
560 assert!(util_compare_floats(
561 new_modeler.wobble_update(&ModelerInput {
562 event_type: ModelerInputEventType::Move,
563 pos: (1.032, 2.032),
564 time: 5.064,
565 pressure: 0.0,
566 }),
567 (1.0266667, 2.0213333)
568 ));
569 assert!(util_compare_floats(
570 new_modeler.wobble_update(&ModelerInput {
571 event_type: ModelerInputEventType::Move,
572 pos: (1.048, 2.032),
573 time: 5.080,
574 pressure: 0.0,
575 }),
576 (1.0373333, 2.0266667)
577 ));
578 assert!(util_compare_floats(
579 new_modeler.wobble_update(&ModelerInput {
580 event_type: ModelerInputEventType::Move,
581 pos: (1.048, 2.048),
582 time: 5.096,
583 pressure: 0.0,
584 }),
585 (1.0426667, 2.0373333)
586 ));
587 }
588
589 #[test]
590 fn fast_zigzag() {
591 let mut new_modeler = StrokeModeler::default();
592 assert!(util_compare_floats(
593 new_modeler.wobble_update(&ModelerInput {
594 event_type: ModelerInputEventType::Move,
595 pos: (7., 3.024),
596 time: 8.016,
597 pressure: 0.0,
598 }),
599 (7.0, 3.024)
600 ));
601 assert!(util_compare_floats(
602 new_modeler.wobble_update(&ModelerInput {
603 event_type: ModelerInputEventType::Move,
604 pos: (7.024, 3.024),
605 time: 8.032,
606 pressure: 0.0,
607 }),
608 (7.024, 3.024)
609 ));
610 assert!(util_compare_floats(
611 new_modeler.wobble_update(&ModelerInput {
612 event_type: ModelerInputEventType::Move,
613 pos: (7.024, 3.048),
614 time: 8.048,
615 pressure: 0.0,
616 }),
617 (7.024, 3.048)
618 ));
619 assert!(util_compare_floats(
620 new_modeler.wobble_update(&ModelerInput {
621 event_type: ModelerInputEventType::Move,
622 pos: (7.048, 3.048),
623 time: 8.064,
624 pressure: 0.0,
625 }),
626 (7.048, 3.048)
627 ));
628 }
629
630 #[test]
631 fn input_test() {
632 let mut modeler = StrokeModeler::new(ModelerParams::suggested()).unwrap();
633
634 let inputs = vec![
635 ModelerInput {
636 event_type: ModelerInputEventType::Down,
637 pos: (0.0, 0.0),
638 time: 0.0,
639 pressure: 0.1,
640 },
641 ModelerInput {
642 event_type: ModelerInputEventType::Move,
643 pos: (1.0, 0.0),
644 time: 0.02,
645 pressure: 0.3,
646 },
647 ModelerInput {
648 event_type: ModelerInputEventType::Move,
649 pos: (2.0, 0.0),
650 time: 0.04,
651 pressure: 0.5,
652 },
653 ModelerInput {
654 event_type: ModelerInputEventType::Move,
655 pos: (2.5, 1.0),
656 time: 0.06,
657 pressure: 0.8,
658 },
659 ModelerInput {
660 event_type: ModelerInputEventType::Move,
661 pos: (3.0, 1.5),
662 time: 0.12,
663 pressure: 0.9,
664 },
665 ModelerInput {
666 event_type: ModelerInputEventType::Move,
667 pos: (4.0, 2.0),
668 time: 0.13,
669 pressure: 0.8,
670 },
671 ModelerInput {
672 event_type: ModelerInputEventType::Move,
673 pos: (3.8, 2.1),
674 time: 0.14,
675 pressure: 0.7,
676 },
677 ModelerInput {
678 event_type: ModelerInputEventType::Up,
679 pos: (3.5, 2.0),
680 time: 0.14,
681 pressure: 0.2,
682 },
683 ];
684
685 for res in inputs.into_iter().flat_map(|i| modeler.update(i)) {
686 println!("{res:?}");
687 }
688 }
689
690 #[test]
692 fn test_empty_prediction() {
693 let mut engine = StrokeModeler::new(ModelerParams::suggested()).unwrap();
694 assert!(engine.predict().is_err());
695 }
696
697 #[test]
698 fn test_singleinput() {
699 let mut engine = StrokeModeler::default();
700 engine
701 .update(ModelerInput {
702 pos: (4.0, 5.0),
703 event_type: ModelerInputEventType::Down,
704 time: 2.0,
705 pressure: 1.0,
706 })
707 .unwrap();
708 assert_eq!(engine.predict().unwrap().len(), 0);
709 }
710
711 #[test]
713 fn input_rate_slower() {
714 let delta_time = (1. / 30. as f32) as f64;
716 let mut time = 0.0;
717 let mut engine = StrokeModeler::new(ModelerParams {
718 stylus_state_modeler_max_input_samples: 20,
719 ..ModelerParams::suggested()
720 })
721 .unwrap();
722
723 let first_iter = engine.update(ModelerInput {
724 event_type: ModelerInputEventType::Down,
725 pos: (3., 4.),
726 time: time,
727 pressure: 1.0,
728 });
729 assert!(first_iter.is_ok());
730 assert!(compare_results(
731 first_iter.unwrap(),
732 vec![ModelerResult {
733 pos: (3.0, 4.0),
734 ..ModelerResult::default()
735 }]
736 ));
737
738 assert!(engine.predict().is_ok());
739 assert!(engine.predict().unwrap().is_empty());
740
741 time += delta_time;
742 assert!(compare_results(
743 engine
744 .update(ModelerInput {
745 event_type: ModelerInputEventType::Move,
746 pos: (3.2, 4.2),
747 time: time,
748 pressure: 1.0
749 })
750 .unwrap(),
751 vec![
752 ModelerResult {
753 pos: (3.0019, 4.0019),
754 velocity: (0.4007, 0.4007),
755 acceleration: (84.1557, 84.1564),
756 time: 0.0048,
757 pressure: 1.0
758 },
759 ModelerResult {
760 pos: (3.0069, 4.0069),
761 velocity: (1.0381, 1.0381),
762 acceleration: (133.8378, 133.8369),
763 time: 0.0095,
764 pressure: 1.0
765 },
766 ModelerResult {
767 pos: (3.0154, 4.0154),
768 velocity: (1.7883, 1.7883),
769 acceleration: (157.5465, 157.5459),
770 time: 0.0143,
771 pressure: 1.0
772 },
773 ModelerResult {
774 pos: (3.0276, 4.0276),
775 velocity: (2.5626, 2.5626),
776 acceleration: (162.6039, 162.6021),
777 time: 0.0190,
778 pressure: 1.0
779 },
780 ModelerResult {
781 pos: (3.0433, 4.0433),
782 velocity: (3.3010, 3.3010),
783 acceleration: (155.0670, 155.0666),
784 time: 0.0238,
785 pressure: 1.0
786 },
787 ModelerResult {
788 pos: (3.0622, 4.0622),
789 velocity: (3.9665, 3.9665),
790 acceleration: (139.7575, 139.7564),
791 time: 0.0286,
792 pressure: 1.0
793 },
794 ModelerResult {
795 pos: (3.0838, 4.0838),
796 velocity: (4.5397, 4.5397),
797 acceleration: (120.3618, 120.3625),
798 time: 0.0333,
799 pressure: 1.0
800 }
801 ]
802 ));
803
804 assert!(engine.predict().is_ok());
805 assert!(compare_results(
806 engine.predict().unwrap(),
807 vec![
808 ModelerResult {
809 pos: (3.1095, 4.1095),
810 velocity: (4.6253, 4.6253),
811 acceleration: (15.4218, 15.4223),
812 time: 0.0389,
813 pressure: 1.0
814 },
815 ModelerResult {
816 pos: (3.1331, 4.1331),
817 velocity: (4.2563, 4.2563),
818 acceleration: (-66.4341, -66.4339),
819 time: 0.0444,
820 pressure: 1.0
821 },
822 ModelerResult {
823 pos: (3.1534, 4.1534),
824 velocity: (3.6479, 3.6479),
825 acceleration: (-109.5083, -109.5081),
826 time: 0.0500,
827 pressure: 1.0
828 },
829 ModelerResult {
830 pos: (3.1698, 4.1698),
831 velocity: (2.9512, 2.9512),
832 acceleration: (-125.3978, -125.3976),
833 time: 0.0556,
834 pressure: 1.0
835 },
836 ModelerResult {
837 pos: (3.1824, 4.1824),
838 velocity: (2.2649, 2.2649),
839 acceleration: (-123.5318, -123.5310),
840 time: 0.0611,
841 pressure: 1.0
842 },
843 ModelerResult {
844 pos: (3.1915, 4.1915),
845 velocity: (1.6473, 1.6473),
846 acceleration: (-111.1818, -111.1806),
847 time: 0.0667,
848 pressure: 1.0
849 },
850 ModelerResult {
851 pos: (3.1978, 4.1978),
852 velocity: (1.1269, 1.1269),
853 acceleration: (-93.6643, -93.6636),
854 time: 0.0722,
855 pressure: 1.0
856 },
857 ModelerResult {
858 pos: (3.1992, 4.1992),
859 velocity: (1.0232, 1.0232),
860 acceleration: (-74.6390, -74.6392),
861 time: 0.0736,
862 pressure: 1.0
863 }
864 ]
865 ));
866
867 time += delta_time;
868 let second_results = engine.update(ModelerInput {
869 event_type: ModelerInputEventType::Move,
870 pos: (3.5, 4.2),
871 time: time,
872 pressure: 1.0,
873 });
874 assert!(second_results.is_ok());
875 assert!(compare_results(
876 second_results.unwrap(),
877 vec![
878 ModelerResult {
879 pos: (3.1086, 4.1058),
880 velocity: (5.2142, 4.6131),
881 acceleration: (141.6557, 15.4223),
882 time: 0.0381,
883 pressure: 1.0
884 },
885 ModelerResult {
886 pos: (3.1368, 4.1265),
887 velocity: (5.9103, 4.3532),
888 acceleration: (146.1873, -54.5680),
889 time: 0.0429,
890 pressure: 1.0
891 },
892 ModelerResult {
893 pos: (3.1681, 4.1450),
894 velocity: (6.5742, 3.8917),
895 acceleration: (139.4012, -96.9169),
896 time: 0.0476,
897 pressure: 1.0
898 },
899 ModelerResult {
900 pos: (3.2022, 4.1609),
901 velocity: (7.1724, 3.3285),
902 acceleration: (125.6306, -118.2742),
903 time: 0.0524,
904 pressure: 1.0
905 },
906 ModelerResult {
907 pos: (3.2388, 4.1739),
908 velocity: (7.6876, 2.7361),
909 acceleration: (108.1908, -124.4087),
910 time: 0.0571,
911 pressure: 1.0
912 },
913 ModelerResult {
914 pos: (3.2775, 4.1842),
915 velocity: (8.1138, 2.1640),
916 acceleration: (89.5049, -120.1309),
917 time: 0.0619,
918 pressure: 1.0
919 },
920 ModelerResult {
921 pos: (3.3177, 4.1920),
922 velocity: (8.4531, 1.6436),
923 acceleration: (71.2473, -109.2959),
924 time: 0.0667,
925 pressure: 1.0
926 }
927 ]
928 ));
929
930 assert!(engine.predict().is_ok());
931 assert!(compare_results(
932 engine.predict().unwrap(),
933 vec![
934 ModelerResult {
935 pos: (3.3625, 4.1982),
936 velocity: (8.0545, 1.1165),
937 acceleration: (-71.7427, -94.8765),
938 time: 0.0722,
939 pressure: 1.0
940 },
941 ModelerResult {
942 pos: (3.4018, 4.2021),
943 velocity: (7.0831, 0.6987),
944 acceleration: (-174.8469, -75.1957),
945 time: 0.0778,
946 pressure: 1.0
947 },
948 ModelerResult {
949 pos: (3.4344, 4.2043),
950 velocity: (5.8564, 0.3846),
951 acceleration: (-220.8140, -56.5515),
952 time: 0.0833,
953 pressure: 1.0
954 },
955 ModelerResult {
956 pos: (3.4598, 4.2052),
957 velocity: (4.5880, 0.1611),
958 acceleration: (-228.3204, -40.2244),
959 time: 0.0889,
960 pressure: 1.0
961 },
962 ModelerResult {
963 pos: (3.4788, 4.2052),
964 velocity: (3.4098, 0.0124),
965 acceleration: (-212.0678, -26.7709),
966 time: 0.0944,
967 pressure: 1.0
968 },
969 ModelerResult {
970 pos: (3.4921, 4.2048),
971 velocity: (2.3929, -0.0780),
972 acceleration: (-183.0373, -16.2648),
973 time: 0.1000,
974 pressure: 1.0
975 },
976 ModelerResult {
977 pos: (3.4976, 4.2045),
978 velocity: (1.9791, -0.1015),
979 acceleration: (-148.9792, -8.4822),
980 time: 0.1028,
981 pressure: 1.0
982 },
983 ModelerResult {
984 pos: (3.5001, 4.2044),
985 velocity: (1.7911, -0.1098),
986 acceleration: (-135.3759, -5.9543),
987 time: 0.1042,
988 pressure: 1.0
989 }
990 ]
991 ));
992
993 time += delta_time;
995 let update = engine.update(ModelerInput {
996 event_type: ModelerInputEventType::Up,
997 pos: (3.7, 4.4),
998 time: time,
999 pressure: 1.0,
1000 });
1001 assert!(update.is_ok());
1002 assert!(compare_results(
1003 update.unwrap(),
1004 vec![
1005 ModelerResult {
1006 pos: (3.3583, 4.1996),
1007 velocity: (8.5122, 1.5925),
1008 acceleration: (12.4129, -10.7201),
1009 time: 0.0714,
1010 pressure: 1.0
1011 },
1012 ModelerResult {
1013 pos: (3.3982, 4.2084),
1014 velocity: (8.3832, 1.8534),
1015 acceleration: (-27.0783, 54.7731),
1016 time: 0.0762,
1017 pressure: 1.0
1018 },
1019 ModelerResult {
1020 pos: (3.4369, 4.2194),
1021 velocity: (8.1393, 2.3017),
1022 acceleration: (-51.2222, 94.1542),
1023 time: 0.0810,
1024 pressure: 1.0
1025 },
1026 ModelerResult {
1027 pos: (3.4743, 4.2329),
1028 velocity: (7.8362, 2.8434),
1029 acceleration: (-63.6668, 113.7452),
1030 time: 0.0857,
1031 pressure: 1.0
1032 },
1033 ModelerResult {
1034 pos: (3.5100, 4.2492),
1035 velocity: (7.5143, 3.4101),
1036 acceleration: (-67.5926, 119.0224),
1037 time: 0.0905,
1038 pressure: 1.0
1039 },
1040 ModelerResult {
1041 pos: (3.5443, 4.2680),
1042 velocity: (7.2016, 3.9556),
1043 acceleration: (-65.6568, 114.5394),
1044 time: 0.0952,
1045 pressure: 1.0
1046 },
1047 ModelerResult {
1048 pos: (3.5773, 4.2892),
1049 velocity: (6.9159, 4.4505),
1050 acceleration: (-59.9999, 103.9444),
1051 time: 0.1000,
1052 pressure: 1.0
1053 },
1054 ModelerResult {
1055 pos: (3.6115, 4.3141),
1056 velocity: (6.1580, 4.4832),
1057 acceleration: (-136.4312, 5.8833),
1058 time: 0.1056,
1059 pressure: 1.0
1060 },
1061 ModelerResult {
1062 pos: (3.6400, 4.3369),
1063 velocity: (5.1434, 4.0953),
1064 acceleration: (-182.6254, -69.8314),
1065 time: 0.1111,
1066 pressure: 1.0
1067 },
1068 ModelerResult {
1069 pos: (3.6626, 4.3563),
1070 velocity: (4.0671, 3.4902),
1071 acceleration: (-193.7401, -108.9119),
1072 time: 0.1167,
1073 pressure: 1.0
1074 },
1075 ModelerResult {
1076 pos: (3.6796, 4.3719),
1077 velocity: (3.0515, 2.8099),
1078 acceleration: (-182.7957, -122.4598),
1079 time: 0.1222,
1080 pressure: 1.0
1081 },
1082 ModelerResult {
1083 pos: (3.6916, 4.3838),
1084 velocity: (2.1648, 2.1462),
1085 acceleration: (-159.6116, -119.4551),
1086 time: 0.1278,
1087 pressure: 1.0
1088 },
1089 ModelerResult {
1090 pos: (3.6996, 4.3924),
1091 velocity: (1.4360, 1.5529),
1092 acceleration: (-131.1906, -106.7926),
1093 time: 0.1333,
1094 pressure: 1.0
1095 },
1096 ModelerResult {
1097 pos: (3.7028, 4.3960),
1098 velocity: (1.1520, 1.3044),
1099 acceleration: (-102.2117, -89.4872),
1100 time: 0.1361,
1101 pressure: 1.0
1102 }
1103 ]
1104 ));
1105
1106 assert!(engine.predict().is_err());
1108 }
1109
1110 #[test]
1111 fn reset_keep_params() {
1112 let input = ModelerInput {
1113 event_type: ModelerInputEventType::Down,
1114 pos: (3.0, 4.0),
1115 time: 0.0,
1116 pressure: 1.0,
1117 };
1118 let mut engine = StrokeModeler::default();
1119 assert!(engine.update(input.clone()).is_ok());
1120
1121 assert!(engine.reset_w_params(ModelerParams::suggested()).is_ok());
1122 assert!(engine.update(input.clone()).is_ok());
1123 }
1124
1125 #[test]
1127 fn input_rate_faster() {
1128 let delta_time = 1. / 300.;
1129 let mut engine = StrokeModeler::default();
1130
1131 let mut time = 2.0;
1132
1133 let res1 = engine.update(ModelerInput {
1134 event_type: ModelerInputEventType::Down,
1135 pos: (5.0, -3.0),
1136 time: time,
1137 pressure: 1.0,
1138 });
1139
1140 assert!(res1.is_ok());
1141 assert!(compare_results(
1142 res1.unwrap(),
1143 vec![ModelerResult {
1144 pos: (5.0, -3.0),
1145 time: time,
1146 velocity: (0.0, 0.0),
1147 acceleration: (0.0, 0.0),
1148 pressure: 1.0
1149 }]
1150 ));
1151
1152 assert!(engine.predict().is_ok());
1153 assert!(engine.predict().unwrap().is_empty());
1154
1155 time += delta_time;
1156 let res2 = engine.update(ModelerInput {
1157 event_type: ModelerInputEventType::Move,
1158 pos: (5.0, -3.1),
1159 time: time,
1160 pressure: 1.0,
1161 });
1162 assert!(res2.is_ok());
1163 assert!(compare_results(
1164 res2.unwrap(),
1165 vec![ModelerResult {
1166 pos: (5.0, -3.0033),
1167 velocity: (0.0, -0.9818),
1168 acceleration: (0.0, -294.5452),
1169 time: 2.0033,
1170 pressure: 1.0
1171 }]
1172 ));
1173
1174 assert!(compare_results(
1175 engine.predict().unwrap(),
1176 vec![
1177 ModelerResult {
1178 pos: (5.0, -3.0153),
1179 velocity: (0.0, -2.1719),
1180 acceleration: (0.0, -214.2145),
1181 time: 2.0089,
1182 pressure: 1.0
1183 },
1184 ModelerResult {
1185 pos: (5.0, -3.0303),
1186 velocity: (0.0, -2.6885),
1187 acceleration: (0.0, -92.9885),
1188 time: 2.0144,
1189 pressure: 1.0
1190 },
1191 ModelerResult {
1192 pos: (5.0, -3.0456),
1193 velocity: (0.0, -2.7541),
1194 acceleration: (0.0, -11.7992),
1195 time: 2.0200,
1196 pressure: 1.0
1197 },
1198 ModelerResult {
1199 pos: (5.0, -3.0597),
1200 velocity: (0.0, -2.5430),
1201 acceleration: (0.0, 37.9868),
1202 time: 2.0256,
1203 pressure: 1.0
1204 },
1205 ModelerResult {
1206 pos: (5.0, -3.0718),
1207 velocity: (0.0, -2.1852),
1208 acceleration: (0.0, 64.4053),
1209 time: 2.0311,
1210 pressure: 1.0
1211 },
1212 ModelerResult {
1213 pos: (5.0, -3.0817),
1214 velocity: (0.0, -1.7719),
1215 acceleration: (0.0, 74.4011),
1216 time: 2.0367,
1217 pressure: 1.0
1218 },
1219 ModelerResult {
1220 pos: (5.0, -3.0893),
1221 velocity: (0.0, -1.3628),
1222 acceleration: (0.0, 73.6345),
1223 time: 2.0422,
1224 pressure: 1.0
1225 },
1226 ModelerResult {
1227 pos: (5.0, -3.0948),
1228 velocity: (0.0, -0.9934),
1229 acceleration: (0.0, 66.4807),
1230 time: 2.0478,
1231 pressure: 1.0
1232 },
1233 ModelerResult {
1234 pos: (5.0, -3.0986),
1235 velocity: (0.0, -0.6815),
1236 acceleration: (0.0, 56.1448),
1237 time: 2.0533,
1238 pressure: 1.0
1239 }
1240 ]
1241 ));
1242 assert!(engine.predict().is_ok());
1243
1244 time += delta_time;
1245
1246 let res3 = engine.update(ModelerInput {
1247 event_type: ModelerInputEventType::Move,
1248 pos: (4.975, -3.175),
1249 time: time,
1250 pressure: 1.0,
1251 });
1252 assert!(res3.is_ok());
1253 assert!(compare_results(
1254 res3.unwrap(),
1255 vec![ModelerResult {
1256 pos: (4.9992, -3.0114),
1257 velocity: (-0.2455, -2.4322),
1258 acceleration: (-73.6366, -435.1238),
1259 time: 2.0067,
1260 pressure: 1.0
1261 }]
1262 ));
1263
1264 assert!(engine.predict().is_ok());
1265 assert!(compare_results(
1266 engine.predict().unwrap(),
1267 vec![
1268 ModelerResult {
1269 pos: (4.9962, -3.0344),
1270 velocity: (-0.5430, -4.1368),
1271 acceleration: (-53.5537, -306.8140),
1272 time: 2.0122,
1273 pressure: 1.0
1274 },
1275 ModelerResult {
1276 pos: (4.9924, -3.0609),
1277 velocity: (-0.6721, -4.7834),
1278 acceleration: (-23.2474, -116.3963),
1279 time: 2.0178,
1280 pressure: 1.0
1281 },
1282 ModelerResult {
1283 pos: (4.9886, -3.0873),
1284 velocity: (-0.6885, -4.7365),
1285 acceleration: (-2.9498, 8.4358),
1286 time: 2.0233,
1287 pressure: 1.0
1288 },
1289 ModelerResult {
1290 pos: (4.9851, -3.1110),
1291 velocity: (-0.6358, -4.2778),
1292 acceleration: (9.4971, 82.5682),
1293 time: 2.0289,
1294 pressure: 1.0
1295 },
1296 ModelerResult {
1297 pos: (4.9820, -3.1311),
1298 velocity: (-0.5463, -3.6137),
1299 acceleration: (16.1014, 119.5413),
1300 time: 2.0344,
1301 pressure: 1.0
1302 },
1303 ModelerResult {
1304 pos: (4.9796, -3.1471),
1305 velocity: (-0.4430, -2.8867),
1306 acceleration: (18.6005, 130.8578),
1307 time: 2.0400,
1308 pressure: 1.0
1309 },
1310 ModelerResult {
1311 pos: (4.9777, -3.1593),
1312 velocity: (-0.3407, -2.1881),
1313 acceleration: (18.4089, 125.7516),
1314 time: 2.0456,
1315 pressure: 1.0
1316 },
1317 ModelerResult {
1318 pos: (4.9763, -3.1680),
1319 velocity: (-0.2484, -1.5700),
1320 acceleration: (16.6198, 111.2560),
1321 time: 2.0511,
1322 pressure: 1.0
1323 },
1324 ModelerResult {
1325 pos: (4.9754, -3.1739),
1326 velocity: (-0.1704, -1.0564),
1327 acceleration: (14.0365, 92.4447),
1328 time: 2.0567,
1329 pressure: 1.0
1330 }
1331 ]
1332 ));
1333
1334 time += delta_time;
1335 let res4 = engine.update(ModelerInput {
1336 event_type: ModelerInputEventType::Move,
1337 pos: (4.9, -3.2),
1338 time: time,
1339 pressure: 1.0,
1340 });
1341 assert!(res4.is_ok());
1342 assert!(compare_results(
1343 res4.unwrap(),
1344 vec![ModelerResult {
1345 pos: (4.9953, -3.0237),
1346 velocity: (-1.1603, -3.7004),
1347 acceleration: (-274.4622, -380.4507),
1348 time: 2.0100,
1349 pressure: 1.0
1350 }]
1351 ));
1352
1353 assert!(engine.predict().is_ok());
1354 assert!(compare_results(
1355 engine.predict().unwrap(),
1356 vec![
1357 ModelerResult {
1358 pos: (4.9828, -3.0521),
1359 velocity: (-2.2559, -5.1049),
1360 acceleration: (-197.1994, -252.8115),
1361 time: 2.0156,
1362 pressure: 1.0
1363 },
1364 ModelerResult {
1365 pos: (4.9677, -3.0825),
1366 velocity: (-2.7081, -5.4835),
1367 acceleration: (-81.4051, -68.1520),
1368 time: 2.0211,
1369 pressure: 1.0
1370 },
1371 ModelerResult {
1372 pos: (4.9526, -3.1115),
1373 velocity: (-2.7333, -5.2122),
1374 acceleration: (-4.5282, 48.8396),
1375 time: 2.0267,
1376 pressure: 1.0
1377 },
1378 ModelerResult {
1379 pos: (4.9387, -3.1369),
1380 velocity: (-2.4999, -4.5756),
1381 acceleration: (42.0094, 114.5943),
1382 time: 2.0322,
1383 pressure: 1.0
1384 },
1385 ModelerResult {
1386 pos: (4.9268, -3.1579),
1387 velocity: (-2.1326, -3.7776),
1388 acceleration: (66.1132, 143.6292),
1389 time: 2.0378,
1390 pressure: 1.0
1391 },
1392 ModelerResult {
1393 pos: (4.9173, -3.1743),
1394 velocity: (-1.7184, -2.9554),
1395 acceleration: (74.5656, 147.9932),
1396 time: 2.0433,
1397 pressure: 1.0
1398 },
1399 ModelerResult {
1400 pos: (4.9100, -3.1865),
1401 velocity: (-1.3136, -2.1935),
1402 acceleration: (72.8575, 137.1578),
1403 time: 2.0489,
1404 pressure: 1.0
1405 },
1406 ModelerResult {
1407 pos: (4.9047, -3.1950),
1408 velocity: (-0.9513, -1.5369),
1409 acceleration: (65.2090, 118.1874),
1410 time: 2.0544,
1411 pressure: 1.0
1412 },
1413 ModelerResult {
1414 pos: (4.9011, -3.2006),
1415 velocity: (-0.6475, -1.0032),
1416 acceleration: (54.6929, 96.0608),
1417 time: 2.0600,
1418 pressure: 1.0
1419 }
1420 ]
1421 ));
1422
1423 time += delta_time;
1424 let res5 = engine.update(ModelerInput {
1425 event_type: ModelerInputEventType::Move,
1426 pos: (4.825, -3.2),
1427 time: time,
1428 pressure: 1.0,
1429 });
1430
1431 assert!(res5.is_ok());
1432 assert!(compare_results(
1433 res5.unwrap(),
1434 vec![ModelerResult {
1435 pos: (4.9868, -3.0389),
1436 velocity: (-2.5540, -4.5431),
1437 acceleration: (-418.1093, -252.8115),
1438 time: 2.0133,
1439 pressure: 1.0,
1440 }]
1441 ));
1442
1443 assert!(engine.predict().is_ok());
1444 assert!(compare_results(
1445 engine.predict().unwrap(),
1446 vec![
1447 ModelerResult {
1448 pos: (4.9636, -3.0687),
1449 velocity: (-4.1801, -5.3627),
1450 acceleration: (-292.6871, -147.5319),
1451 time: 2.0189,
1452 pressure: 1.0
1453 },
1454 ModelerResult {
1455 pos: (4.9370, -3.0985),
1456 velocity: (-4.7757, -5.3670),
1457 acceleration: (-107.2116, -0.7651),
1458 time: 2.0244,
1459 pressure: 1.0
1460 },
1461 ModelerResult {
1462 pos: (4.9109, -3.1256),
1463 velocity: (-4.6989, -4.8816),
1464 acceleration: (13.8210, 87.3644),
1465 time: 2.0300,
1466 pressure: 1.0
1467 },
1468 ModelerResult {
1469 pos: (4.8875, -3.1486),
1470 velocity: (-4.2257, -4.1466),
1471 acceleration: (85.1835, 132.2997),
1472 time: 2.0356,
1473 pressure: 1.0
1474 },
1475 ModelerResult {
1476 pos: (4.8677, -3.1671),
1477 velocity: (-3.5576, -3.3287),
1478 acceleration: (120.2579, 147.2335),
1479 time: 2.0411,
1480 pressure: 1.0
1481 },
1482 ModelerResult {
1483 pos: (4.8520, -3.1812),
1484 velocity: (-2.8333, -2.5353),
1485 acceleration: (130.3700, 142.8088),
1486 time: 2.0467,
1487 pressure: 1.0
1488 },
1489 ModelerResult {
1490 pos: (4.8401, -3.1914),
1491 velocity: (-2.1411, -1.8288),
1492 acceleration: (124.5846, 127.1714),
1493 time: 2.0522,
1494 pressure: 1.0
1495 },
1496 ModelerResult {
1497 pos: (4.8316, -3.1982),
1498 velocity: (-1.5312, -1.2386),
1499 acceleration: (109.7874, 106.2279),
1500 time: 2.0578,
1501 pressure: 1.0
1502 },
1503 ModelerResult {
1504 pos: (4.8280, -3.2010),
1505 velocity: (-1.2786, -1.0053),
1506 acceleration: (90.9288, 84.0051),
1507 time: 2.0606,
1508 pressure: 1.0
1509 },
1510 ModelerResult {
1511 pos: (4.8272, -3.2017),
1512 velocity: (-1.2209, -0.9529),
1513 acceleration: (83.2052, 75.4288),
1514 time: 2.0613,
1515 pressure: 1.0
1516 }
1517 ]
1518 ));
1519
1520 time += delta_time;
1521 let res6 = engine.update(ModelerInput {
1522 event_type: ModelerInputEventType::Move,
1523 pos: (4.75, -3.225),
1524 time: time,
1525 pressure: 1.0,
1526 });
1527 assert!(res6.is_ok());
1528 assert!(compare_results(
1529 res6.unwrap(),
1530 vec![ModelerResult {
1531 pos: (4.9726, -3.0565),
1532 velocity: (-4.2660, -5.2803),
1533 acceleration: (-513.5957, -221.1678),
1534 time: 2.0167,
1535 pressure: 1.0
1536 }]
1537 ));
1538
1539 assert!(engine.predict().is_ok());
1540 assert!(compare_results(
1541 engine.predict().unwrap(),
1542 vec![
1543 ModelerResult {
1544 pos: (4.9381, -3.0894),
1545 velocity: (-6.2018, -5.9261),
1546 acceleration: (-348.4476, -116.2445),
1547 time: 2.0222,
1548 pressure: 1.0
1549 },
1550 ModelerResult {
1551 pos: (4.9004, -3.1215),
1552 velocity: (-6.7995, -5.7749),
1553 acceleration: (-107.5834, 27.2264),
1554 time: 2.0278,
1555 pressure: 1.0
1556 },
1557 ModelerResult {
1558 pos: (4.8640, -3.1501),
1559 velocity: (-6.5400, -5.1591),
1560 acceleration: (46.7146, 110.8336),
1561 time: 2.0333,
1562 pressure: 1.0
1563 },
1564 ModelerResult {
1565 pos: (4.8319, -3.1741),
1566 velocity: (-5.7897, -4.3207),
1567 acceleration: (135.0462, 150.9226),
1568 time: 2.0389,
1569 pressure: 1.0
1570 },
1571 ModelerResult {
1572 pos: (4.8051, -3.1932),
1573 velocity: (-4.8132, -3.4248),
1574 acceleration: (175.7684, 161.2555),
1575 time: 2.0444,
1576 pressure: 1.0
1577 },
1578 ModelerResult {
1579 pos: (4.7841, -3.2075),
1580 velocity: (-3.7898, -2.5759),
1581 acceleration: (184.2227, 152.7958),
1582 time: 2.0500,
1583 pressure: 1.0
1584 },
1585 ModelerResult {
1586 pos: (4.7683, -3.2176),
1587 velocity: (-2.8312, -1.8324),
1588 acceleration: (172.5480, 133.8294),
1589 time: 2.0556,
1590 pressure: 1.0
1591 },
1592 ModelerResult {
1593 pos: (4.7572, -3.2244),
1594 velocity: (-1.9986, -1.2198),
1595 acceleration: (149.8577, 110.2830),
1596 time: 2.0611,
1597 pressure: 1.0
1598 },
1599 ModelerResult {
1600 pos: (4.7526, -3.2271),
1601 velocity: (-1.6580, -0.9805),
1602 acceleration: (122.6198, 86.1299),
1603 time: 2.0639,
1604 pressure: 1.0
1605 }
1606 ]
1607 ));
1608
1609 time += delta_time;
1610 let res7 = engine.update(ModelerInput {
1611 event_type: ModelerInputEventType::Move,
1612 pos: (4.7, -3.3),
1613 time: time,
1614 pressure: 1.0,
1615 });
1616 assert!(res7.is_ok());
1617 assert!(compare_results(
1618 res7.unwrap(),
1619 vec![ModelerResult {
1620 pos: (4.9529, -3.0778),
1621 velocity: (-5.9184, -6.4042),
1622 acceleration: (-495.7209, -337.1538),
1623 time: 2.0200,
1624 pressure: 1.0
1625 }]
1626 ));
1627 assert!(engine.predict().is_ok());
1628 assert!(compare_results(
1629 engine.predict().unwrap(),
1630 vec![
1631 ModelerResult {
1632 pos: (4.9101, -3.1194),
1633 velocity: (-7.6886, -7.4784),
1634 acceleration: (-318.6394, -193.3594),
1635 time: 2.0256,
1636 pressure: 1.0
1637 },
1638 ModelerResult {
1639 pos: (4.8654, -3.1607),
1640 velocity: (-8.0518, -7.4431),
1641 acceleration: (-65.3698, 6.3579),
1642 time: 2.0311,
1643 pressure: 1.0
1644 },
1645 ModelerResult {
1646 pos: (4.8235, -3.1982),
1647 velocity: (-7.5377, -6.7452),
1648 acceleration: (92.5345, 125.6104),
1649 time: 2.0367,
1650 pressure: 1.0
1651 },
1652 ModelerResult {
1653 pos: (4.7872, -3.2299),
1654 velocity: (-6.5440, -5.7133),
1655 acceleration: (178.8654, 185.7426),
1656 time: 2.0422,
1657 pressure: 1.0
1658 },
1659 ModelerResult {
1660 pos: (4.7574, -3.2553),
1661 velocity: (-5.3529, -4.5748),
1662 acceleration: (214.4027, 204.9362),
1663 time: 2.0478,
1664 pressure: 1.0
1665 },
1666 ModelerResult {
1667 pos: (4.7344, -3.2746),
1668 velocity: (-4.1516, -3.4758),
1669 acceleration: (216.2348, 197.8224),
1670 time: 2.0533,
1671 pressure: 1.0
1672 },
1673 ModelerResult {
1674 pos: (4.7174, -3.2885),
1675 velocity: (-3.0534, -2.5004),
1676 acceleration: (197.6767, 175.5702),
1677 time: 2.0589,
1678 pressure: 1.0
1679 },
1680 ModelerResult {
1681 pos: (4.7056, -3.2979),
1682 velocity: (-2.1169, -1.6879),
1683 acceleration: (168.5711, 146.2573),
1684 time: 2.0644,
1685 pressure: 1.0
1686 },
1687 ModelerResult {
1688 pos: (4.7030, -3.3000),
1689 velocity: (-1.9283, -1.5276),
1690 acceleration: (135.7820, 115.3739),
1691 time: 2.0658,
1692 pressure: 1.0
1693 },
1694 ModelerResult {
1695 pos: (4.7017, -3.3010),
1696 velocity: (-1.8380, -1.4512),
1697 acceleration: (130.0928, 110.0859),
1698 time: 2.0665,
1699 pressure: 1.0
1700 },
1701 ]
1702 ));
1703
1704 time += delta_time;
1705 let res8 = engine.update(ModelerInput {
1706 event_type: ModelerInputEventType::Move,
1707 pos: (4.675, -3.4),
1708 time: time,
1709 pressure: 1.0,
1710 });
1711 assert!(res8.is_ok());
1712 assert!(compare_results(
1713 res8.unwrap(),
1714 vec![ModelerResult {
1715 pos: (4.9288, -3.1046),
1716 velocity: (-7.2260, -8.0305),
1717 acceleration: (-392.2747, -487.9053),
1718 time: 2.0233,
1719 pressure: 1.0
1720 },]
1721 ));
1722
1723 assert!(engine.predict().is_ok());
1724 assert!(compare_results(
1725 engine.predict().unwrap(),
1726 vec![
1727 ModelerResult {
1728 pos: (4.8816, -3.1582),
1729 velocity: (-8.4881, -9.6525),
1730 acceleration: (-227.1831, -291.9628),
1731 time: 2.0289,
1732 pressure: 1.0
1733 },
1734 ModelerResult {
1735 pos: (4.8345, -3.2124),
1736 velocity: (-8.4738, -9.7482),
1737 acceleration: (2.5870, -17.2266),
1738 time: 2.0344,
1739 pressure: 1.0
1740 },
1741 ModelerResult {
1742 pos: (4.7918, -3.2619),
1743 velocity: (-7.6948, -8.9195),
1744 acceleration: (140.2131, 149.1810),
1745 time: 2.0400,
1746 pressure: 1.0
1747 },
1748 ModelerResult {
1749 pos: (4.7555, -3.3042),
1750 velocity: (-6.5279, -7.6113),
1751 acceleration: (210.0428, 235.4638),
1752 time: 2.0456,
1753 pressure: 1.0
1754 },
1755 ModelerResult {
1756 pos: (4.7264, -3.3383),
1757 velocity: (-5.2343, -6.1345),
1758 acceleration: (232.8451, 265.8274),
1759 time: 2.0511,
1760 pressure: 1.0
1761 },
1762 ModelerResult {
1763 pos: (4.7043, -3.3643),
1764 velocity: (-3.9823, -4.6907),
1765 acceleration: (225.3593, 259.8790),
1766 time: 2.0567,
1767 pressure: 1.0
1768 },
1769 ModelerResult {
1770 pos: (4.6884, -3.3832),
1771 velocity: (-2.8691, -3.3980),
1772 acceleration: (200.3802, 232.6849),
1773 time: 2.0622,
1774 pressure: 1.0
1775 },
1776 ModelerResult {
1777 pos: (4.6776, -3.3961),
1778 velocity: (-1.9403, -2.3135),
1779 acceleration: (167.1764, 195.2152),
1780 time: 2.0678,
1781 pressure: 1.0
1782 },
1783 ModelerResult {
1784 pos: (4.6752, -3.3990),
1785 velocity: (-1.7569, -2.0983),
1786 acceleration: (132.0560, 154.9868),
1787 time: 2.0692,
1788 pressure: 1.0
1789 },
1790 ]
1791 ));
1792 time += delta_time;
1793
1794 let res9 = engine.update(ModelerInput {
1795 event_type: ModelerInputEventType::Move,
1796 pos: (4.675, -3.525),
1797 time: time,
1798 pressure: 1.0,
1799 });
1800 assert!(res9.is_ok());
1801 assert!(compare_results(
1802 res9.unwrap(),
1803 vec![ModelerResult {
1804 pos: (4.9022, -3.1387),
1805 velocity: (-7.9833, -10.2310),
1806 acceleration: (-227.1831, -660.1446),
1807 time: 2.0267,
1808 pressure: 1.0
1809 },]
1810 ));
1811
1812 assert!(engine.predict().is_ok());
1813 assert!(compare_results(
1814 engine.predict().unwrap(),
1815 vec![
1816 ModelerResult {
1817 pos: (4.8549, -3.2079),
1818 velocity: (-8.5070, -12.4602),
1819 acceleration: (-94.2781, -401.2599),
1820 time: 2.0322,
1821 pressure: 1.0
1822 },
1823 ModelerResult {
1824 pos: (4.8102, -3.2783),
1825 velocity: (-8.0479, -12.6650),
1826 acceleration: (82.6390, -36.8616),
1827 time: 2.0378,
1828 pressure: 1.0
1829 },
1830 ModelerResult {
1831 pos: (4.7711, -3.3429),
1832 velocity: (-7.0408, -11.6365),
1833 acceleration: (181.2765, 185.1286),
1834 time: 2.0433,
1835 pressure: 1.0
1836 },
1837 ModelerResult {
1838 pos: (4.7389, -3.3983),
1839 velocity: (-5.7965, -9.9616),
1840 acceleration: (223.9801, 301.4933),
1841 time: 2.0489,
1842 pressure: 1.0
1843 },
1844 ModelerResult {
1845 pos: (4.7137, -3.4430),
1846 velocity: (-4.5230, -8.0510),
1847 acceleration: (229.2397, 343.9032),
1848 time: 2.0544,
1849 pressure: 1.0
1850 },
1851 ModelerResult {
1852 pos: (4.6951, -3.4773),
1853 velocity: (-3.3477, -6.1727),
1854 acceleration: (211.5554, 338.0856),
1855 time: 2.0600,
1856 pressure: 1.0
1857 },
1858 ModelerResult {
1859 pos: (4.6821, -3.5022),
1860 velocity: (-2.3381, -4.4846),
1861 acceleration: (181.7131, 303.8597),
1862 time: 2.0656,
1863 pressure: 1.0
1864 },
1865 ModelerResult {
1866 pos: (4.6737, -3.5192),
1867 velocity: (-1.5199, -3.0641),
1868 acceleration: (147.2879, 255.7003),
1869 time: 2.0711,
1870 pressure: 1.0
1871 },
1872 ModelerResult {
1873 pos: (4.6718, -3.5231),
1874 velocity: (-1.3626, -2.7813),
1875 acceleration: (113.2437, 203.5595),
1876 time: 2.0725,
1877 pressure: 1.0
1878 },
1879 ]
1880 ));
1881
1882 time += delta_time;
1883 let res10 = engine.update(ModelerInput {
1885 event_type: ModelerInputEventType::Up,
1886 pos: (4.7, -3.6),
1887 time: time,
1888 pressure: 1.0,
1889 });
1890 assert!(res10.is_ok());
1891 assert!(compare_results(
1892 res10.unwrap(),
1893 vec![
1894 ModelerResult {
1895 pos: (4.8753, -3.1797),
1896 velocity: (-8.0521, -12.3049),
1897 acceleration: (-20.6429, -622.1685),
1898 time: 2.0300,
1899 pressure: 1.0
1900 },
1901 ModelerResult {
1902 pos: (4.8325, -3.2589),
1903 velocity: (-7.7000, -14.2607),
1904 acceleration: (63.3680, -352.0363),
1905 time: 2.0356,
1906 pressure: 1.0
1907 },
1908 ModelerResult {
1909 pos: (4.7948, -3.3375),
1910 velocity: (-6.7888, -14.1377),
1911 acceleration: (164.0215, 22.1350),
1912 time: 2.0411,
1913 pressure: 1.0
1914 },
1915 ModelerResult {
1916 pos: (4.7636, -3.4085),
1917 velocity: (-5.6249, -12.7787),
1918 acceleration: (209.5020, 244.6249),
1919 time: 2.0467,
1920 pressure: 1.0
1921 },
1922 ModelerResult {
1923 pos: (4.7390, -3.4685),
1924 velocity: (-4.4152, -10.8015),
1925 acceleration: (217.7452, 355.8801),
1926 time: 2.0522,
1927 pressure: 1.0
1928 },
1929 ModelerResult {
1930 pos: (4.7208, -3.5164),
1931 velocity: (-3.2880, -8.6333),
1932 acceleration: (202.8961, 390.2804),
1933 time: 2.0578,
1934 pressure: 1.0
1935 },
1936 ModelerResult {
1937 pos: (4.7079, -3.5528),
1938 velocity: (-2.3128, -6.5475),
1939 acceleration: (175.5414, 375.4407),
1940 time: 2.0633,
1941 pressure: 1.0
1942 },
1943 ModelerResult {
1944 pos: (4.6995, -3.5789),
1945 velocity: (-1.5174, -4.7008),
1946 acceleration: (143.1705, 332.4062),
1947 time: 2.0689,
1948 pressure: 1.0
1949 },
1950 ModelerResult {
1951 pos: (4.6945, -3.5965),
1952 velocity: (-0.9022, -3.1655),
1953 acceleration: (110.7325, 276.3669),
1954 time: 2.0744,
1955 pressure: 1.0
1956 },
1957 ModelerResult {
1958 pos: (4.6942, -3.5976),
1959 velocity: (-0.8740, -3.0899),
1960 acceleration: (81.2036, 217.6189),
1961 time: 2.0748,
1962 pressure: 1.0
1963 },
1964 ]
1965 ));
1966
1967 assert!(engine.predict().is_err());
1969 }
1970
1971 #[test]
1972 fn wobble_smoothed() {
1973 let delta_time = 0.0167;
1974 let mut engine = StrokeModeler::default();
1975
1976 let mut time = 4.0;
1977 let res1 = engine.update(ModelerInput {
1978 event_type: ModelerInputEventType::Down,
1979 pos: (-6.0, -2.0),
1980 time: time,
1981 pressure: 1.0,
1982 });
1983 assert!(res1.is_ok());
1984 assert!(compare_results(
1985 res1.unwrap(),
1986 vec![ModelerResult {
1987 pos: (-6.0, -2.0),
1988 time: 4.0,
1989 ..ModelerResult::default()
1990 }]
1991 ));
1992
1993 time += delta_time;
1994
1995 let res2 = engine.update(ModelerInput {
1996 event_type: ModelerInputEventType::Move,
1997 pos: (-6.02, -2.0),
1998 time: time,
1999 ..ModelerInput::default()
2000 });
2001 assert!(res2.is_ok());
2002 assert!(compare_results(
2003 res2.unwrap(),
2004 vec![
2005 ModelerResult {
2006 pos: (-6.0003, -2.0),
2007 velocity: (-0.0615, 0.0),
2008 acceleration: (-14.7276, 0.0),
2009 time: 4.0042,
2010 pressure: 1.0
2011 },
2012 ModelerResult {
2013 pos: (-6.0009, -2.0),
2014 velocity: (-0.1628, 0.0),
2015 acceleration: (-24.2725, 0.0),
2016 time: 4.0084,
2017 pressure: 1.0
2018 },
2019 ModelerResult {
2020 pos: (-6.0021, -2.0),
2021 velocity: (-0.2868, 0.0),
2022 acceleration: (-29.6996, 0.0),
2023 time: 4.0125,
2024 pressure: 1.0
2025 },
2026 ModelerResult {
2027 pos: (-6.0039, -2.0),
2028 velocity: (-0.4203, 0.0),
2029 acceleration: (-31.9728, 0.0),
2030 time: 4.0167,
2031 pressure: 1.0
2032 },
2033 ]
2034 ));
2035
2036 time += delta_time;
2037 let res3 = engine.update(ModelerInput {
2038 event_type: ModelerInputEventType::Move,
2039 pos: (-6.02, -2.02),
2040 time: time,
2041 pressure: 1.0,
2042 });
2043 assert!(res3.is_ok());
2044 assert!(compare_results(
2045 res3.unwrap(),
2046 vec![
2047 ModelerResult {
2048 pos: (-6.0059, -2.0001),
2049 velocity: (-0.4921, -0.0307),
2050 acceleration: (-17.1932, -7.3638),
2051 time: 4.0209,
2052 pressure: 1.0
2053 },
2054 ModelerResult {
2055 pos: (-6.0081, -2.0005),
2056 velocity: (-0.5170, -0.0814),
2057 acceleration: (-5.9729, -12.1355),
2058 time: 4.0251,
2059 pressure: 1.0
2060 },
2061 ModelerResult {
2062 pos: (-6.0102, -2.0010),
2063 velocity: (-0.5079, -0.1434),
2064 acceleration: (2.1807, -14.8493),
2065 time: 4.0292,
2066 pressure: 1.0
2067 },
2068 ModelerResult {
2069 pos: (-6.0122, -2.0019),
2070 velocity: (-0.4755, -0.2101),
2071 acceleration: (7.7710, -15.9860),
2072 time: 4.0334,
2073 pressure: 1.0
2074 },
2075 ]
2076 ));
2077 time += delta_time;
2078 let res4 = engine.update(ModelerInput {
2079 event_type: ModelerInputEventType::Move,
2080 pos: (-6.04, -2.02),
2081 time: time,
2082 pressure: 1.0,
2083 });
2084 assert!(res4.is_ok());
2085 assert!(compare_results(
2086 res4.unwrap(),
2087 vec![
2088 ModelerResult {
2089 pos: (-6.0141, -2.0030),
2090 velocity: (-0.4489, -0.2563),
2091 acceleration: (6.3733, -11.0507),
2092 time: 4.0376,
2093 pressure: 1.0
2094 },
2095 ModelerResult {
2096 pos: (-6.0159, -2.0042),
2097 velocity: (-0.4277, -0.2856),
2098 acceleration: (5.0670, -7.0315),
2099 time: 4.0418,
2100 pressure: 1.0
2101 },
2102 ModelerResult {
2103 pos: (-6.0176, -2.0055),
2104 velocity: (-0.4115, -0.3018),
2105 acceleration: (3.8950, -3.8603),
2106 time: 4.0459,
2107 pressure: 1.0
2108 },
2109 ModelerResult {
2110 pos: (-6.0193, -2.0067),
2111 velocity: (-0.3994, -0.3078),
2112 acceleration: (2.8758, -1.4435),
2113 time: 4.0501,
2114 pressure: 1.0
2115 },
2116 ]
2117 ));
2118
2119 time += delta_time;
2120 let res5 = engine.update(ModelerInput {
2121 event_type: ModelerInputEventType::Move,
2122 pos: (-6.04, -2.04),
2123 time: time,
2124 pressure: 1.0,
2125 });
2126 assert!(res5.is_ok());
2127 assert!(
2128 (compare_results(
2129 res5.unwrap(),
2130 vec![
2131 ModelerResult {
2132 pos: (-6.0209, -2.0082),
2133 velocity: (-0.3910, -0.3372),
2134 acceleration: (2.0142, -7.0427),
2135 time: 4.0543,
2136 pressure: 1.0
2137 },
2138 ModelerResult {
2139 pos: (-6.0225, -2.0098),
2140 velocity: (-0.3856, -0.3814),
2141 acceleration: (1.3090, -10.5977),
2142 time: 4.0585,
2143 pressure: 1.0
2144 },
2145 ModelerResult {
2146 pos: (-6.0241, -2.0116),
2147 velocity: (-0.3825, -0.4338),
2148 acceleration: (0.7470, -12.5399),
2149 time: 4.0626,
2150 pressure: 1.0
2151 },
2152 ModelerResult {
2153 pos: (-6.0257, -2.0136),
2154 velocity: (-0.3811, -0.4891),
2155 acceleration: (0.3174, -13.2543),
2156 time: 4.0668,
2157 pressure: 1.0
2158 },
2159 ]
2160 ))
2161 );
2162 }
2163
2164 #[test]
2165 fn reset_stroke() {
2166 let mut engine = StrokeModeler::default();
2167 let delta_time = 1. / 50.;
2168 let mut time = 0.0;
2169 let res = engine.update(ModelerInput {
2170 event_type: ModelerInputEventType::Down,
2171 pos: (-8.0, -10.0),
2172 time: time,
2173 pressure: 1.0,
2174 });
2175 assert!(res.is_ok());
2176 assert!(!res.unwrap().is_empty());
2177 assert!(engine.predict().is_ok());
2178 assert!(engine.predict().unwrap().is_empty());
2179
2180 time += delta_time;
2181 let res2 = engine.update(ModelerInput {
2182 event_type: ModelerInputEventType::Move,
2183 time: time,
2184 ..ModelerInput::default()
2185 });
2186 assert!(res2.is_ok());
2187 assert!(!res2.unwrap().is_empty());
2188 assert!(engine.predict().is_ok());
2189 assert!(!engine.predict().unwrap().is_empty());
2190
2191 time += delta_time;
2192 let res3 = engine.update(ModelerInput {
2193 event_type: ModelerInputEventType::Move,
2194 time: time,
2195 pos: (-11.0, -5.0),
2196 ..ModelerInput::default()
2197 });
2198 assert!(res3.is_ok());
2199 assert!(!res3.unwrap().is_empty());
2200 assert!(engine.predict().is_ok());
2201 assert!(!engine.predict().unwrap().is_empty());
2202
2203 engine.reset();
2204 assert!(engine.predict().is_err());
2205 }
2206
2207 #[test]
2208 fn ignore_input_before_down() {
2209 let mut engine = StrokeModeler::default();
2210
2211 assert!(
2212 engine
2213 .update(ModelerInput {
2214 event_type: ModelerInputEventType::Move,
2215 ..ModelerInput::default()
2216 })
2217 .is_err()
2218 );
2219 assert!(
2220 engine
2221 .update(ModelerInput {
2222 event_type: ModelerInputEventType::Up,
2223 ..ModelerInput::default()
2224 })
2225 .is_err()
2226 );
2227 }
2228
2229 #[test]
2230 fn tdown_in_progress_error() {
2231 let mut engine = StrokeModeler::default();
2232
2233 assert!(
2234 engine
2235 .update(ModelerInput {
2236 event_type: ModelerInputEventType::Down,
2237 ..ModelerInput::default()
2238 })
2239 .is_ok()
2240 );
2241 assert!(
2242 engine
2243 .update(ModelerInput {
2244 event_type: ModelerInputEventType::Down,
2245 ..ModelerInput::default()
2246 })
2247 .is_err()
2248 );
2249 }
2250
2251 #[test]
2252 fn alternate_params() {
2253 let delta_time = 1. / 50.;
2254 let mut engine = StrokeModeler::new(ModelerParams {
2255 sampling_min_output_rate: 70.0,
2256 stylus_state_modeler_max_input_samples: 20,
2257 ..ModelerParams::suggested()
2258 })
2259 .unwrap();
2260
2261 let mut time = 3.0;
2262
2263 let res1 = engine.update(ModelerInput {
2264 event_type: ModelerInputEventType::Down,
2265 pos: (0.0, 0.0),
2266 time: time,
2267 pressure: 0.5,
2268 });
2269 assert!(res1.is_ok());
2270 assert!(compare_results(
2271 res1.unwrap(),
2272 vec![ModelerResult {
2273 time: 3.0,
2274 pressure: 0.5,
2275 ..ModelerResult::default()
2276 }]
2277 ));
2278
2279 assert!(engine.predict().is_ok());
2280 assert!(engine.predict().unwrap().is_empty());
2281
2282 time += delta_time;
2283
2284 let res2 = engine.update(ModelerInput {
2285 event_type: ModelerInputEventType::Move,
2286 pos: (0.0, 0.5),
2287 time: time,
2288 pressure: 0.4,
2289 });
2290 assert!(res2.is_ok());
2291 assert!(compare_results(
2292 res2.unwrap(),
2293 vec![
2294 ModelerResult {
2295 pos: (0.0, 0.0736),
2296 velocity: (0.0, 7.3636),
2297 acceleration: (0.0, 736.3636),
2298 time: 3.0100,
2299 pressure: 0.4853
2300 },
2301 ModelerResult {
2302 pos: (0.0, 0.2198),
2303 velocity: (0.0, 14.6202),
2304 acceleration: (0.0, 725.6529),
2305 time: 3.0200,
2306 pressure: 0.4560
2307 },
2308 ]
2309 ));
2310
2311 assert!(engine.predict().is_ok());
2312 assert!(compare_results(
2313 engine.predict().unwrap(),
2314 vec![
2315 ModelerResult {
2316 pos: (0.0, 0.3823),
2317 velocity: (0.0, 11.3709),
2318 acceleration: (0.0, -227.4474),
2319 time: 3.0343,
2320 pressure: 0.4235
2321 },
2322 ModelerResult {
2323 pos: (0.0, 0.4484),
2324 velocity: (0.0, 4.6285),
2325 acceleration: (0.0, -471.9660),
2326 time: 3.0486,
2327 pressure: 0.4103
2328 },
2329 ModelerResult {
2330 pos: (0.0, 0.4775),
2331 velocity: (0.0, 2.0389),
2332 acceleration: (0.0, -181.2747),
2333 time: 3.0629,
2334 pressure: 0.4045
2335 },
2336 ModelerResult {
2337 pos: (0.0, 0.4902),
2338 velocity: (0.0, 0.8873),
2339 acceleration: (0.0, -80.6136),
2340 time: 3.0771,
2341 pressure: 0.4020
2342 },
2343 ModelerResult {
2344 pos: (0.0, 0.4957),
2345 velocity: (0.0, 0.3868),
2346 acceleration: (0.0, -35.0318),
2347 time: 3.0914,
2348 pressure: 0.4009
2349 },
2350 ModelerResult {
2351 pos: (0.0, 0.4981),
2352 velocity: (0.0, 0.1686),
2353 acceleration: (0.0, -15.2760),
2354 time: 3.1057,
2355 pressure: 0.4004
2356 },
2357 ModelerResult {
2358 pos: (0.0, 0.4992),
2359 velocity: (0.0, 0.0735),
2360 acceleration: (0.0, -6.6579),
2361 time: 3.1200,
2362 pressure: 0.4002
2363 },
2364 ]
2365 ));
2366 time += delta_time;
2367
2368 let res3 = engine.update(ModelerInput {
2369 pos: (0.2, 1.0),
2370 time: time,
2371 pressure: 0.3,
2372 event_type: ModelerInputEventType::Move,
2373 });
2374 assert!(res3.is_ok());
2375 assert!(compare_results(
2376 res3.unwrap(),
2377 vec![
2378 ModelerResult {
2379 pos: (0.0295, 0.4169),
2380 velocity: (2.9455, 19.7093),
2381 acceleration: (294.5455, 508.9161),
2382 time: 3.0300,
2383 pressure: 0.4166
2384 },
2385 ModelerResult {
2386 pos: (0.0879, 0.6439),
2387 velocity: (5.8481, 22.6926),
2388 acceleration: (290.2612, 298.3311),
2389 time: 3.0400,
2390 pressure: 0.3691
2391 },
2392 ]
2393 ));
2394
2395 assert!(engine.predict().is_ok());
2396 assert!(compare_results(
2397 engine.predict().unwrap(),
2398 vec![
2399 ModelerResult {
2400 pos: (0.1529, 0.8487),
2401 velocity: (4.5484, 14.3374),
2402 acceleration: (-90.9790, -584.8687),
2403 time: 3.0543,
2404 pressure: 0.3293
2405 },
2406 ModelerResult {
2407 pos: (0.1794, 0.9338),
2408 velocity: (1.8514, 5.9577),
2409 acceleration: (-188.7864, -586.5760),
2410 time: 3.0686,
2411 pressure: 0.3128
2412 },
2413 ModelerResult {
2414 pos: (0.1910, 0.9712),
2415 velocity: (0.8156, 2.6159),
2416 acceleration: (-72.5099, -233.9289),
2417 time: 3.0829,
2418 pressure: 0.3056
2419 },
2420 ModelerResult {
2421 pos: (0.1961, 0.9874),
2422 velocity: (0.3549, 1.1389),
2423 acceleration: (-32.2455, -103.3868),
2424 time: 3.0971,
2425 pressure: 0.3024
2426 },
2427 ModelerResult {
2428 pos: (0.1983, 0.9945),
2429 velocity: (0.1547, 0.4965),
2430 acceleration: (-14.0127, -44.9693),
2431 time: 3.1114,
2432 pressure: 0.3011
2433 },
2434 ModelerResult {
2435 pos: (0.1993, 0.9976),
2436 velocity: (0.0674, 0.2164),
2437 acceleration: (-6.1104, -19.6068),
2438 time: 3.1257,
2439 pressure: 0.3005
2440 },
2441 ModelerResult {
2442 pos: (0.1997, 0.9990),
2443 velocity: (0.0294, 0.0943),
2444 acceleration: (-2.6631, -8.5455),
2445 time: 3.1400,
2446 pressure: 0.3002
2447 },
2448 ]
2449 ));
2450
2451 time += delta_time;
2452 let res4 = engine.update(ModelerInput {
2453 event_type: ModelerInputEventType::Move,
2454 pos: (0.4, 1.4),
2455 time: time,
2456 pressure: 0.2,
2457 });
2458 assert!(res4.is_ok());
2459 assert!(compare_results(
2460 res4.unwrap(),
2461 vec![
2462 ModelerResult {
2463 pos: (0.1668, 0.8712),
2464 velocity: (7.8837, 22.7349),
2465 acceleration: (203.5665, 4.2224),
2466 time: 3.0500,
2467 pressure: 0.3245
2468 },
2469 ModelerResult {
2470 pos: (0.2575, 1.0906),
2471 velocity: (9.0771, 21.9411),
2472 acceleration: (119.3324, -79.3721),
2473 time: 3.0600,
2474 pressure: 0.2761
2475 },
2476 ]
2477 ));
2478 assert!(engine.predict().is_ok());
2479 assert!(compare_results(
2480 engine.predict().unwrap(),
2481 vec![
2482 ModelerResult {
2483 pos: (0.3395, 1.2676),
2484 velocity: (5.7349, 12.3913),
2485 acceleration: (-233.9475, -668.4906),
2486 time: 3.0743,
2487 pressure: 0.2325
2488 },
2489 ModelerResult {
2490 pos: (0.3735, 1.3421),
2491 velocity: (2.3831, 5.2156),
2492 acceleration: (-234.6304, -502.2992),
2493 time: 3.0886,
2494 pressure: 0.2142
2495 },
2496 ModelerResult {
2497 pos: (0.3885, 1.3748),
2498 velocity: (1.0463, 2.2854),
2499 acceleration: (-93.5716, -205.1091),
2500 time: 3.1029,
2501 pressure: 0.2062
2502 },
2503 ModelerResult {
2504 pos: (0.3950, 1.3890),
2505 velocity: (0.4556, 0.9954),
2506 acceleration: (-41.3547, -90.3064),
2507 time: 3.1171,
2508 pressure: 0.2027
2509 },
2510 ModelerResult {
2511 pos: (0.3978, 1.3952),
2512 velocity: (0.1986, 0.4339),
2513 acceleration: (-17.9877, -39.3021),
2514 time: 3.1314,
2515 pressure: 0.2012
2516 },
2517 ModelerResult {
2518 pos: (0.3990, 1.3979),
2519 velocity: (0.0866, 0.1891),
2520 acceleration: (-7.8428, -17.1346),
2521 time: 3.1457,
2522 pressure: 0.2005
2523 },
2524 ModelerResult {
2525 pos: (0.3996, 1.3991),
2526 velocity: (0.0377, 0.0824),
2527 acceleration: (-3.4182, -7.4680),
2528 time: 3.1600,
2529 pressure: 0.2002
2530 },
2531 ]
2532 ));
2533 time += delta_time;
2534 let res5 = engine.update(ModelerInput {
2535 event_type: ModelerInputEventType::Up,
2536 pos: (0.7, 1.7),
2537 pressure: 0.1,
2538 time: time,
2539 });
2540 assert!(res5.is_ok());
2541 assert!(compare_results(
2542 res5.unwrap(),
2543 vec![
2544 ModelerResult {
2545 pos: (0.3691, 1.2874),
2546 velocity: (11.1558, 19.6744),
2547 acceleration: (207.8707, -226.6725),
2548 time: 3.0700,
2549 pressure: 0.2256
2550 },
2551 ModelerResult {
2552 pos: (0.4978, 1.4640),
2553 velocity: (12.8701, 17.6629),
2554 acceleration: (171.4340, -201.1508),
2555 time: 3.0800,
2556 pressure: 0.1730
2557 },
2558 ModelerResult {
2559 pos: (0.6141, 1.5986),
2560 velocity: (8.1404, 9.4261),
2561 acceleration: (-331.0815, -576.5752),
2562 time: 3.0943,
2563 pressure: 0.1312
2564 },
2565 ModelerResult {
2566 pos: (0.6624, 1.6557),
2567 velocity: (3.3822, 3.9953),
2568 acceleration: (-333.0701, -380.1579),
2569 time: 3.1086,
2570 pressure: 0.1136
2571 },
2572 ModelerResult {
2573 pos: (0.6836, 1.6807),
2574 velocity: (1.4851, 1.7488),
2575 acceleration: (-132.8005, -157.2520),
2576 time: 3.1229,
2577 pressure: 0.1059
2578 },
2579 ModelerResult {
2580 pos: (0.6929, 1.6916),
2581 velocity: (0.6466, 0.7618),
2582 acceleration: (-58.6943, -69.0946),
2583 time: 3.1371,
2584 pressure: 0.1026
2585 },
2586 ModelerResult {
2587 pos: (0.6969, 1.6963),
2588 velocity: (0.2819, 0.3321),
2589 acceleration: (-25.5298, -30.0794),
2590 time: 3.1514,
2591 pressure: 0.1011
2592 },
2593 ModelerResult {
2594 pos: (0.6986, 1.6984),
2595 velocity: (0.1229, 0.1447),
2596 acceleration: (-11.1311, -13.1133),
2597 time: 3.1657,
2598 pressure: 0.1005
2599 },
2600 ModelerResult {
2601 pos: (0.6994, 1.6993),
2602 velocity: (0.0535, 0.0631),
2603 acceleration: (-4.8514, -5.7153),
2604 time: 3.1800,
2605 pressure: 0.1002
2606 },
2607 ]
2608 ));
2609 assert!(engine.predict().is_err());
2610 }
2611
2612 #[test]
2613 fn generate_output_up_nodelta() {
2614 let delta_time = 1. / 500.;
2615 let mut engine = StrokeModeler::default();
2616 let mut time = 0.0;
2617
2618 let res1 = engine.update(ModelerInput {
2619 event_type: ModelerInputEventType::Down,
2620 pos: (5.0, 5.0),
2621 time: time,
2622 pressure: 1.0,
2623 });
2624 assert!(res1.is_ok());
2625 assert!(compare_results(
2626 res1.unwrap(),
2627 vec![ModelerResult {
2628 pos: (5.0, 5.0),
2629 time: 0.0,
2630 ..ModelerResult::default()
2631 }]
2632 ));
2633 time += delta_time;
2634 let res2 = engine.update(ModelerInput {
2635 event_type: ModelerInputEventType::Move,
2636 pos: (5.0, 5.0),
2637 pressure: 1.0,
2638 time: time,
2639 });
2640 assert!(res2.is_ok());
2641 assert!(compare_results(
2642 res2.unwrap(),
2643 vec![ModelerResult {
2644 pos: (5.0, 5.0),
2645 time: 0.002,
2646 ..ModelerResult::default()
2647 }]
2648 ));
2649 let res3 = engine.update(ModelerInput {
2650 event_type: ModelerInputEventType::Up,
2651 pos: (5.0, 5.0),
2652 time: time,
2653 pressure: 1.0,
2654 });
2655 assert!(res3.is_ok());
2656 assert!(compare_results(
2657 res3.unwrap(),
2658 vec![ModelerResult {
2659 pos: (5.0, 5.0),
2660 time: 0.0076,
2661 pressure: 1.0,
2662 ..ModelerResult::default()
2663 }]
2664 ));
2665 }
2666
2667 #[test]
2668 fn far_apart_times_move() {
2669 let mut engine = StrokeModeler::default();
2670 let res1 = engine.update(ModelerInput {
2671 event_type: ModelerInputEventType::Down,
2672 pos: (0.0, 0.0),
2673 time: 0.0,
2674 pressure: 0.2,
2675 });
2676 assert!(res1.is_ok());
2677 assert!(!res1.unwrap().is_empty());
2678
2679 let res2 = engine.update(ModelerInput {
2680 event_type: ModelerInputEventType::Move,
2681 pos: (0.0, 0.0),
2682 pressure: 0.2,
2683 time: 2147483647.0,
2684 });
2685 assert!(res2.is_err());
2686 }
2687
2688 #[test]
2689 fn far_apart_times_up() {
2690 let mut engine = StrokeModeler::default();
2691 let res1 = engine.update(ModelerInput {
2692 event_type: ModelerInputEventType::Down,
2693 pos: (0.0, 0.0),
2694 time: 0.0,
2695 pressure: 0.2,
2696 });
2697 assert!(res1.is_ok());
2698 assert!(!res1.unwrap().is_empty());
2699
2700 let res2 = engine.update(ModelerInput {
2701 event_type: ModelerInputEventType::Up,
2702 pos: (0.0, 0.0),
2703 pressure: 0.2,
2704 time: 2147483647.0,
2705 });
2706 assert!(res2.is_err());
2707 }
2708
2709 #[test]
2710 fn reject_negative_timedelta() {
2711 let mut engine = StrokeModeler::default();
2712 let res1 = engine.update(ModelerInput {
2713 event_type: ModelerInputEventType::Down,
2714 pos: (0.0, 0.0),
2715 time: 0.0,
2716 pressure: 0.0,
2717 });
2718 assert!(res1.is_ok());
2719 assert!(!res1.unwrap().is_empty());
2720
2721 let res2 = engine.update(ModelerInput {
2722 event_type: ModelerInputEventType::Move,
2723 pos: (1.0, 1.0),
2724 time: -0.1,
2725 pressure: 0.0,
2726 });
2727 assert!(res2.is_err());
2728
2729 let res3 = engine.update(ModelerInput {
2730 event_type: ModelerInputEventType::Move,
2731 pos: (1.0, 1.0),
2732 time: 0.1,
2733 pressure: 1.0,
2734 });
2735 assert!(res3.is_ok());
2736 assert!(!res3.unwrap().is_empty());
2737
2738 let res4 = engine.update(ModelerInput {
2739 event_type: ModelerInputEventType::Up,
2740 pos: (1.0, 1.0),
2741 time: 0.09,
2742 pressure: 1.0,
2743 });
2744 assert!(res4.is_err());
2745 }
2746
2747 #[test]
2748 fn reject_duplicate_input() {
2749 let mut engine = StrokeModeler::default();
2750 let res1 = engine.update(ModelerInput {
2751 event_type: ModelerInputEventType::Down,
2752 pos: (0.0, 0.0),
2753 time: 0.0,
2754 pressure: 0.2,
2755 });
2756 assert!(res1.is_ok());
2757 assert!(!res1.unwrap().is_empty());
2758
2759 let res2 = engine.update(ModelerInput {
2760 event_type: ModelerInputEventType::Down,
2761 pos: (0.0, 0.0),
2762 time: 0.0,
2763 pressure: 0.2,
2764 });
2765 assert!(res2.is_err());
2766
2767 let res3 = engine.update(ModelerInput {
2768 event_type: ModelerInputEventType::Move,
2769 pos: (1.0, 2.0),
2770 time: 0.1,
2771 pressure: 0.1,
2772 });
2773 assert!(res3.is_ok());
2774 assert!(!res3.unwrap().is_empty());
2775
2776 let res4 = engine.update(ModelerInput {
2777 event_type: ModelerInputEventType::Move,
2778 pos: (1.0, 2.0),
2779 time: 0.1,
2780 pressure: 0.1,
2781 });
2782 assert!(res4.is_err());
2783 }
2784}