1 #[macro_use] |
1 #[macro_use] |
2 extern crate fpnum; |
2 extern crate fpnum; |
3 |
3 |
4 use fpnum::{distance, FPNum, FPPoint}; |
4 use fpnum::{distance, FPNum, FPPoint}; |
5 use std::{ |
5 use std::{ |
6 cmp::max, |
6 cmp::{max, min}, |
7 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Range, RangeInclusive, Sub, SubAssign} |
7 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Range, RangeInclusive, Sub, SubAssign}, |
8 }; |
8 }; |
9 |
9 |
10 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
10 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
11 pub struct Point { |
11 pub struct Point { |
12 pub x: i32, |
12 pub x: i32, |
72 self.dot(other.rotate90()) |
72 self.dot(other.rotate90()) |
73 } |
73 } |
74 |
74 |
75 #[inline] |
75 #[inline] |
76 pub fn clamp(self, rect: &Rect) -> Point { |
76 pub fn clamp(self, rect: &Rect) -> Point { |
77 Point::new( |
77 Point::new(rect.x_range().clamp(self.x), rect.y_range().clamp(self.y)) |
78 rect.x_range().clamp(self.x), |
|
79 rect.y_range().clamp(self.y) |
|
80 ) |
|
81 } |
78 } |
82 |
79 |
83 #[inline] |
80 #[inline] |
84 pub fn line_to(self, end: Point) -> Line { |
81 pub fn line_to(self, end: Point) -> Line { |
85 Line::new(self, end) |
82 Line::new(self, end) |
272 impl Rect { |
269 impl Rect { |
273 #[inline] |
270 #[inline] |
274 pub fn new(top_left: Point, bottom_right: Point) -> Self { |
271 pub fn new(top_left: Point, bottom_right: Point) -> Self { |
275 assert!(top_left.x <= bottom_right.x + 1); |
272 assert!(top_left.x <= bottom_right.x + 1); |
276 assert!(top_left.y <= bottom_right.y + 1); |
273 assert!(top_left.y <= bottom_right.y + 1); |
277 Self { top_left, bottom_right } |
274 Self { |
|
275 top_left, |
|
276 bottom_right, |
|
277 } |
278 } |
278 } |
279 |
279 |
280 pub fn from_box(left: i32, right: i32, top: i32, bottom: i32) -> Self { |
280 pub fn from_box(left: i32, right: i32, top: i32, bottom: i32) -> Self { |
281 Self::new(Point::new(left, top), Point::new(right, bottom)) |
281 Self::new(Point::new(left, top), Point::new(right, bottom)) |
282 } |
282 } |
283 |
283 |
284 pub fn from_size(top_left: Point, size: Size) -> Self { |
284 pub fn from_size(top_left: Point, size: Size) -> Self { |
285 Self::new( |
285 Self::new( |
286 top_left, |
286 top_left, |
287 top_left + Point::new(size.width as i32 - 1, size.height as i32 - 1) |
287 top_left + Point::new(size.width as i32 - 1, size.height as i32 - 1), |
288 ) |
288 ) |
289 } |
289 } |
290 |
290 |
291 pub fn from_size_coords(x: i32, y: i32, width: usize, height: usize) -> Self { |
291 pub fn from_size_coords(x: i32, y: i32, width: usize, height: usize) -> Self { |
292 Self::from_size(Point::new(x, y), Size::new(width, height)) |
292 Self::from_size(Point::new(x, y), Size::new(width, height)) |
352 } |
352 } |
353 |
353 |
354 #[inline] |
354 #[inline] |
355 pub fn with_margin(&self, margin: i32) -> Self { |
355 pub fn with_margin(&self, margin: i32) -> Self { |
356 let offset = Point::diag(margin); |
356 let offset = Point::diag(margin); |
357 Self::new( |
357 Self::new(self.top_left() + offset, self.bottom_right() - offset) |
358 self.top_left() + offset, |
|
359 self.bottom_right() - offset |
|
360 ) |
|
361 } |
358 } |
362 |
359 |
363 #[inline] |
360 #[inline] |
364 pub fn x_range(&self) -> RangeInclusive<i32> { |
361 pub fn x_range(&self) -> RangeInclusive<i32> { |
365 self.left()..=self.right() |
362 self.left()..=self.right() |
402 ] |
399 ] |
403 } |
400 } |
404 |
401 |
405 #[inline] |
402 #[inline] |
406 pub fn quotient(self, x: usize, y: usize) -> Point { |
403 pub fn quotient(self, x: usize, y: usize) -> Point { |
407 self.top_left() + |
404 self.top_left() + Point::new((x % self.width()) as i32, (y % self.height()) as i32) |
408 Point::new( |
|
409 (x % self.width()) as i32, |
|
410 (y % self.height()) as i32 |
|
411 ) |
|
412 } |
405 } |
413 } |
406 } |
414 |
407 |
415 trait RangeContains<T> { |
408 trait RangeContains<T> { |
416 fn contains(&self, value: T) -> bool; |
409 fn contains(&self, value: T) -> bool; |
417 } |
410 } |
418 |
411 |
419 impl <T: Ord> RangeContains<T> for Range<T> { |
412 impl<T: Ord> RangeContains<T> for Range<T> { |
420 fn contains(&self, value: T) -> bool { |
413 fn contains(&self, value: T) -> bool { |
421 value >= self.start && value < self.end |
414 value >= self.start && value < self.end |
422 } |
415 } |
423 } |
416 } |
424 |
417 |
425 impl <T: Ord> RangeContains<T> for RangeInclusive<T> { |
418 impl<T: Ord> RangeContains<T> for RangeInclusive<T> { |
426 fn contains(&self, value: T) -> bool { |
419 fn contains(&self, value: T) -> bool { |
427 value >= *self.start() && value <= *self.end() |
420 value >= *self.start() && value <= *self.end() |
428 } |
421 } |
429 } |
422 } |
430 |
423 |
431 trait RangeClamp<T> { |
424 trait RangeClamp<T> { |
432 fn clamp(&self, value: T) -> T; |
425 fn clamp(&self, value: T) -> T; |
433 } |
426 } |
434 |
427 |
435 impl <T: Ord + Copy> RangeClamp<T> for RangeInclusive<T> { |
428 impl<T: Ord + Copy> RangeClamp<T> for RangeInclusive<T> { |
436 fn clamp(&self, value: T) -> T { |
429 fn clamp(&self, value: T) -> T { |
437 if value < *self.start() { |
430 if value < *self.start() { |
438 *self.start() |
431 *self.start() |
439 } else if value > *self.end() { |
432 } else if value > *self.end() { |
440 *self.end() |
433 *self.end() |
477 |
470 |
478 pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = &mut Point> + 'a { |
471 pub fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = &mut Point> + 'a { |
479 let edges_count = self.edges_count(); |
472 let edges_count = self.edges_count(); |
480 let start = self.vertices.as_mut_ptr(); |
473 let start = self.vertices.as_mut_ptr(); |
481 let end = unsafe { start.add(self.vertices.len()) }; |
474 let end = unsafe { start.add(self.vertices.len()) }; |
482 PolygonPointsIteratorMut { source: self, start, end } |
475 PolygonPointsIteratorMut { |
|
476 source: self, |
|
477 start, |
|
478 end, |
|
479 } |
483 } |
480 } |
484 |
481 |
485 fn force_close(&mut self) { |
482 fn force_close(&mut self) { |
486 if !self.vertices.is_empty() { |
483 if !self.vertices.is_empty() { |
487 self.vertices[0] = self.vertices[self.vertices.len() - 1]; |
484 self.vertices[0] = self.vertices[self.vertices.len() - 1]; |
492 (&self.vertices[0..self.edges_count()]) |
489 (&self.vertices[0..self.edges_count()]) |
493 .iter() |
490 .iter() |
494 .zip(&self.vertices[1..]) |
491 .zip(&self.vertices[1..]) |
495 .map(|(s, e)| Line::new(*s, *e)) |
492 .map(|(s, e)| Line::new(*s, *e)) |
496 } |
493 } |
|
494 |
|
495 pub fn bezierize(&mut self, segments_number: u32) { |
|
496 fn calc_point(p1: Point, p2: Point, p3: Point) -> FPPoint { |
|
497 let diff13 = (p1 - p3).to_fppoint(); |
|
498 let diff13_norm = diff13.distance(); |
|
499 |
|
500 if diff13_norm.is_zero() { |
|
501 diff13 |
|
502 } else { |
|
503 let diff12_norm = (p1 - p2).to_fppoint().distance(); |
|
504 let diff23_norm = (p2 - p3).to_fppoint().distance(); |
|
505 let min_distance = min(diff13_norm, min(diff12_norm, diff23_norm)); |
|
506 |
|
507 diff13 * min_distance / diff13_norm / 3 |
|
508 } |
|
509 } |
|
510 |
|
511 if self.vertices.len() < 4 { |
|
512 return; |
|
513 } |
|
514 |
|
515 let delta = fp!(1 / segments_number); |
|
516 let mut bezierized_vertices = Vec::new(); |
|
517 let mut pi = 0; |
|
518 let mut i = 1; |
|
519 let mut ni = 2; |
|
520 let mut right_point = calc_point(self.vertices[pi], self.vertices[i], self.vertices[ni]); |
|
521 let mut left_point; |
|
522 |
|
523 pi += 1; |
|
524 while pi != 0 { |
|
525 pi = i; |
|
526 i = ni; |
|
527 ni += 1; |
|
528 if ni >= self.vertices.len() { |
|
529 ni = 0; |
|
530 } |
|
531 |
|
532 left_point = right_point; |
|
533 right_point = calc_point(self.vertices[pi], self.vertices[i], self.vertices[ni]); |
|
534 |
|
535 bezierized_vertices.extend(BezierCurveSegments::new( |
|
536 Line::new(self.vertices[pi], self.vertices[i]), |
|
537 left_point, |
|
538 -right_point, |
|
539 delta, |
|
540 )); |
|
541 } |
|
542 |
|
543 self.vertices = bezierized_vertices; |
|
544 } |
497 } |
545 } |
498 |
546 |
499 struct PolygonPointsIteratorMut<'a> { |
547 struct PolygonPointsIteratorMut<'a> { |
500 source: &'a mut Polygon, |
548 source: &'a mut Polygon, |
501 start: *mut Point, |
549 start: *mut Point, |
502 end: *mut Point |
550 end: *mut Point, |
503 } |
551 } |
504 |
552 |
505 impl <'a> Iterator for PolygonPointsIteratorMut<'a> { |
553 impl<'a> Iterator for PolygonPointsIteratorMut<'a> { |
506 type Item = &'a mut Point; |
554 type Item = &'a mut Point; |
507 |
555 |
508 fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
556 fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
509 if self.start == self.end { |
557 if self.start == self.end { |
510 None |
558 None |
739 pub struct BezierCurveSegments { |
787 pub struct BezierCurveSegments { |
740 segment: Line, |
788 segment: Line, |
741 c1: FPPoint, |
789 c1: FPPoint, |
742 c2: FPPoint, |
790 c2: FPPoint, |
743 offset: FPNum, |
791 offset: FPNum, |
|
792 max_offset: FPNum, |
744 delta: FPNum, |
793 delta: FPNum, |
|
794 have_finished: bool, |
745 } |
795 } |
746 |
796 |
747 impl BezierCurveSegments { |
797 impl BezierCurveSegments { |
748 pub fn new(segment: Line, p1: Point, p2: Point, delta: FPNum) -> Self { |
798 pub fn new(segment: Line, p1: FPPoint, p2: FPPoint, delta: FPNum) -> Self { |
749 Self { |
799 Self { |
750 segment, |
800 segment, |
751 c1: (segment.start - p1).to_fppoint(), |
801 c1: segment.start.to_fppoint() - p1, |
752 c2: (segment.end - p2).to_fppoint(), |
802 c2: segment.end.to_fppoint() - p2, |
753 offset: fp!(0), |
803 offset: fp!(0), |
|
804 max_offset: fp!(4095 / 4096), |
754 delta, |
805 delta, |
|
806 have_finished: false, |
755 } |
807 } |
756 } |
808 } |
757 } |
809 } |
758 |
810 |
759 impl Iterator for BezierCurveSegments { |
811 impl Iterator for BezierCurveSegments { |
760 type Item = Point; |
812 type Item = Point; |
761 |
813 |
762 fn next(&mut self) -> Option<Self::Item> { |
814 fn next(&mut self) -> Option<Self::Item> { |
763 if self.offset < fp!(1) { |
815 if self.offset < self.max_offset { |
764 let offset_sq = self.offset * self.offset; |
816 let offset_sq = self.offset * self.offset; |
765 let offset_cub = offset_sq * self.offset; |
817 let offset_cub = offset_sq * self.offset; |
766 |
818 |
767 let r1 = fp!(1) - self.offset * 3 + offset_sq * 3 - offset_cub; |
819 let r1 = fp!(1) - self.offset * 3 + offset_sq * 3 - offset_cub; |
768 let r2 = self.offset * 3 - offset_sq * 6 + offset_cub * 3; |
820 let r2 = self.offset * 3 - offset_sq * 6 + offset_cub * 3; |