Mercurial > octave-antonio
comparison scripts/geometry/rectint.m @ 7655:ea2344c4140b
rectint.m: vectorize and add tests
author | bill@denney.ws |
---|---|
date | Thu, 27 Mar 2008 14:48:36 -0400 |
parents | 5ed0cb9e9584 |
children | 836618fee9d6 |
comparison
equal
deleted
inserted
replaced
7654:48edf48cd4dc | 7655:ea2344c4140b |
---|---|
41 error ("rectint: expecting arguments to be 2-d arrays"); | 41 error ("rectint: expecting arguments to be 2-d arrays"); |
42 elseif (columns (a) != 4) | 42 elseif (columns (a) != 4) |
43 error ("rectint: a must have 4 columns"); | 43 error ("rectint: a must have 4 columns"); |
44 elseif (columns (b) != 4) | 44 elseif (columns (b) != 4) |
45 error ("rectint: b must have 4 columns"); | 45 error ("rectint: b must have 4 columns"); |
46 elseif any ([a(:,3:4);b(:,3:4)](:) < 0) | |
47 error ("rectint: all widths and heights must be > 0") | |
48 endif | |
49 | |
50 ## This runs faster if the number of rows of a is greater than the | |
51 ## number of rows of b. Swap them and transpose to make it run | |
52 ## faster. | |
53 swapinputs = false (); | |
54 if (rows (a) > rows (b)) | |
55 tmp = a; | |
56 a = b; | |
57 b = tmp; | |
58 swapinputs = true (); | |
46 endif | 59 endif |
47 | 60 |
48 area = zeros (rows (a), rows (b)); | 61 area = zeros (rows (a), rows (b)); |
49 for i = 1:rows (area) | 62 r1 = [a(:,1:2) a(:,1:2)+a(:,3:4)]; |
50 r1 = a(i,:); | 63 r2 = [b(:,1:2) b(:,1:2)+b(:,3:4)]; |
51 for j = 1:columns (area) | 64 for i = 1:columns (area) |
52 r2 = b(j,:); | 65 ## Find the location of each point relative to the other points. |
53 area(i,j) = (overlap (r1([1, 3]), r2([1, 3])) | 66 r1x1small = r1(:,1) < r2(i,1); |
54 * overlap (r1([2, 4]), r2([2, 4]))); | 67 r1x1large = r1(:,1) > r2(i,3); |
55 endfor | 68 r1x1mid = (r1(:,1) >= r2(i,1)) & (r1(:,1) <= r2(i,3)); |
69 r1x2small = r1(:,3) < r2(i,1); | |
70 r1x2large = r1(:,3) > r2(i,3); | |
71 r1x2mid = (r1(:,3) >= r2(i,1)) & (r1(:,3) <= r2(i,3)); | |
72 | |
73 r1y1small = r1(:,2) < r2(i,2); | |
74 r1y1large = r1(:,2) > r2(i,4); | |
75 r1y1mid = (r1(:,2) >= r2(i,2)) & (r1(:,2) <= r2(i,4)); | |
76 r1y2small = r1(:,4) < r2(i,2); | |
77 r1y2large = r1(:,4) > r2(i,4); | |
78 r1y2mid = (r1(:,4) >= r2(i,2)) & (r1(:,4) <= r2(i,4)); | |
79 | |
80 ## determine the width of the rectangle | |
81 ## r1 completely encloses r2 | |
82 area(r1x1small & r1x2large,i) = r2(i,3) - r2(i,1); | |
83 ## the range goes from r2x min to r1x max | |
84 mask = r1x1small & r1x2mid; | |
85 area(mask,i) = r1(mask,3) - r2(i,1); | |
86 ## the range goes from r1x min to r2x max | |
87 mask = r1x1mid & r1x2large; | |
88 area(mask,i) = r2(i,3) - r1(mask,1); | |
89 ## the range goes from r1x min to r1x max | |
90 mask = r1x1mid & r1x2mid; | |
91 area(mask,i) = r1(mask,3) - r1(mask,1); | |
92 | |
93 ## determine the height of the rectangle | |
94 ## r1 completely encloses r2 | |
95 area(r1y1small & r1y2large,i) .*= r2(i,4) - r2(i,2); | |
96 ## the range goes from r2y min to r1y max | |
97 mask = r1y1small & r1y2mid; | |
98 area(mask,i) .*= r1(mask,4) - r2(i,2); | |
99 ## the range goes from r1y min to r2y max | |
100 mask = r1y1mid & r1y2large; | |
101 area(mask,i) .*= r2(i,4) - r1(mask,2); | |
102 ## the range goes from r1x min to r1x max | |
103 mask = r1y1mid & r1y2mid; | |
104 area(mask,i) .*= r1(mask,4) - r1(mask,2); | |
105 | |
56 endfor | 106 endfor |
57 | 107 |
58 endfunction | 108 if swapinputs |
59 | 109 area = area'; |
60 function amt = overlap (r1, r2) | |
61 | |
62 ## Determine whether two ranges overlap. Ranges are given as [value | |
63 ## offset] | |
64 amt = 0; | |
65 | |
66 ## Make sure that the values are in order. | |
67 r1 = sort ([r1(1), r1(1)+r1(2)]); | |
68 r2 = sort ([r2(1), r2(1)+r2(2)]); | |
69 | |
70 ## Is the first point in range 1 in the middle of range 2? | |
71 p1 = sum (r1(1) <= r2) == 1; | |
72 ## is the second? | |
73 p2 = sum (r1(2) <= r2) == 1; | |
74 if (p1) | |
75 if (p2) | |
76 amt = r1(2) - r1(1); | |
77 else | |
78 amt = r2(2) - r1(1); | |
79 endif | |
80 elseif (sum (r1(2) < r2) == 1) | |
81 amt = r1(2) - r2(1); | |
82 endif | 110 endif |
83 | 111 |
84 endfunction | 112 endfunction |
85 | 113 |
86 ## Tests | 114 ## Tests |
115 ## Exactly overlapping | |
116 %!assert(rectint([0 0 1 1], [0 0 1 1]), 1) | |
117 ## rect2 completely enclosed by rect1 | |
118 %!assert(rectint([-1 -1 3 3], [0 0 1 1]), 1) | |
119 ## rect1 completely enclosed by rect2 | |
120 %!assert(rectint([0 0 1 1], [-1 -1 3 3]), 1) | |
121 ## rect1 right and top in rect2 | |
122 %!assert(rectint([-1 -1 1.5 1.5], [0 0 1 1]), 0.25) | |
123 ## rect2 right and top in rect1 | |
124 %!assert(rectint([0 0 1 1], [-1 -1 1.5 1.5]), 0.25) | |
125 ## no overlap - shared corner | |
87 %!assert(rectint([0 0 1 1], [1 1 2 2]), 0) | 126 %!assert(rectint([0 0 1 1], [1 1 2 2]), 0) |
88 %!assert(rectint([0 0 1 1], [0.5 0.5 2 2]), 0.25) | 127 ## no overlap - shared edge |
89 %!assert(rectint([0 0 1 1;0.5 0.5 1 1], [1 1 2 2]), [0;0.25]) | 128 %!assert(rectint([0 0 1 1], [0 1 2 2]), 0) |
90 %!assert(rectint([1 1 2 2], [0 0 1 1;0.5 0.5 1 1]), [0 0.25]) | 129 ## Correct orientation of output |
91 | 130 %!assert(rectint([0 0 1 1;0.5 0.5 1 1;-1 -1 2 2], [1 1 2 2]), [0;0.25;0]) |
131 %!assert(rectint([1 1 2 2], [0 0 1 1;0.5 0.5 1 1;-1 -1 2 2]), [0 0.25 0]) |