1/* rotate images and matricies by fixed angles
2 */
3Rotate_fixed = class {
4        /* rotate image clockwise in 90 degree increments
5         */
6        _rotate_widget default a
7                = map_unary widget a
8        {
9                widget image = class
10                        Image value {
11                        _check_args = [
12                                [image, "image", check_Image]
13                        ] ++ super._check_args;
14                        _vislevel = 3;
15
16                        angle = Option "Rotate by" [
17                                "Don't rotate",
18                                "90 degrees clockwise",
19                                "180 degrees",
20                                "90 degrees anticlockwise"
21                        ] default;
22
23                        value = [
24                                image.value,
25                                rot90 image.value,
26                                rot180 image.value,
27                                rot270 image.value
28                        ] ? angle;
29                }
30        }
31
32        /* clockwise rotate by 90 degrees
33         */
34        R90 x = _rotate_widget 1 x;
35
36        /* rotate by 180 degrees
37         */
38        R180 x = _rotate_widget 2 x;
39
40        /* clockwise rotate by 270 degrees
41         */
42        R270 x = _rotate_widget 3 x;
43
44        /* rotate by 45 degrees ... square, odd-length-sides, matrices only
45         */
46        R45 x = map_unary rot45 x;
47}
48
49/* rotate image anticlockwise by any angle
50 */
51Rotate_free a
52	= map_unary widget a
53{
54	widget image = class
55		Image value {
56		_check_args = [
57			[image, "image", check_Image]
58		] ++ super._check_args;
59		_vislevel = 3;
60
61		angle = Slider 0 360 0;
62
63		value = rotate angle image.value;
64	}
65}
66
67#separator
68
69/* mirror left/right or up/down
70 */
71Flip = class {
72	/* mirror object up/down
73	 */
74	Up_down x = map_unary flipud x;
75
76	/* mirror object left/right
77	 */
78	Left_right x = map_unary fliplr x;
79}
80
81/* swap rows and columns
82 */
83Transpose x = map_unary transpose x;
84
85#separator
86
87/* smallest rotate that gets arrow vertical or horizontal
88 */
89Straighten_arrow x
90	= map_unary straighten x
91{
92	straighten arrow
93		= rotate angle'' arrow.image
94	{
95		x = arrow.width;
96		y = arrow.height;
97
98		angle = im (polar (x, y));
99
100		angle'
101			= angle - 360, angle > 315
102			= angle - 180, angle > 135
103			= angle;
104
105		angle''
106			= -angle', angle' >= (-45) && angle' < 45
107			= 90 - angle';
108	}
109}
110