source: trunk/gsdl/src/java/org/nzdl/gsdl/GsdlCollageApplet/MyAffineTransform.java@ 6816

Last change on this file since 6816 was 6816, checked in by mdewsnip, 20 years ago

The GsdlCollageApplet: a classifier that displays a collage of the images in a collection. By Katrina Edgar (kde2).

  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1package org.nzdl.gsdl.GsdlCollageApplet;
2
3public class MyAffineTransform {
4
5 public double scaleX = 0;
6 public double scaleY = 0;
7 public double translateX = 0;
8 public double translateY = 0;
9 public boolean overlap = false;
10
11 public MyAffineTransform (int image_x_dim, int image_y_dim) {
12
13 random_set_pos(image_x_dim, image_y_dim);
14 }
15
16 /** The amount to adjust the size of an image so that it fits into the applet screen
17 * @param image_x_dim the width of the image to scale
18 * @param image_y_dim the height of the image to scale
19 * @return a value by which to scale the image to ensure it will fit in the applet */
20 private double scaleFactor (int image_x_dim, int image_y_dim) {
21
22 double scale_factor = 1.0;
23
24 // three quarters of the application width & height
25 int tol_app_x_dim = 3*DisplayImages.app_x_dim_/4;
26 int tol_app_y_dim = 3*DisplayImages.app_y_dim_/4;
27
28 // if the image is too big, calculate a fraction
29 // by which to reduce the image
30 if (image_x_dim>tol_app_x_dim)
31 {
32 scale_factor = image_x_dim/tol_app_x_dim + 1;
33 }
34
35 if (image_y_dim>tol_app_y_dim)
36 {
37 int y_scale_factor = image_y_dim/tol_app_y_dim + 1;
38 // take the biggest of the two as the same fraction must
39 // be applied to both the x and y values to keep the image
40 // in proportion
41 if (y_scale_factor>scale_factor)
42 {
43 scale_factor = y_scale_factor;
44 }
45 }
46
47 return scale_factor;
48 }
49
50 /** Determines the placement of new images on the applet screen <br>
51 * First the image is scaled, then the function loops until a satisfactory
52 * image position is found. This is done by randomly selecting an x and y
53 * co-ordinate for the image, then determining how much whitespace will be
54 * covered if the image were to be placed at this position in the collage.
55 * The standards for loop termination are as follows:<br>
56 * 1. On any occasion a whitespace coverage of greater than 70% will result
57 * in the loop being terminated.<br>
58 * 2. After three times through the loop, a whitespace coverage of 50% will
59 * also allow the loop to terminate (a less stringent condition). <br>
60 * 3. After seven times through, the loop will terminate and the best
61 * position will be used by default.<br>
62 * This function also updates the used space array after image position has been selected.
63 *
64 * @param image_x_dim the width of the image
65 * @param image_y_dim the height of the image
66 * @return a transform operation by which to move the image from the origin */
67 protected void random_set_pos(int image_x_dim, int image_y_dim)
68 {
69
70 double scale_factor = scaleFactor(image_x_dim, image_y_dim);
71
72 // scale the image (will be 1 and therefore no change as a default)
73 image_x_dim/=scale_factor;
74 image_y_dim/=scale_factor;
75
76 // initialise variables required to determine image placement
77 int image_x_pos = 0;
78 int image_y_pos = 0;
79 int best_x = 0;
80 int best_y = 0;
81 double best_clear = 0;
82 double clear = 100;
83 int stoploop = 0;
84
85 do {
86 // increment the loop counter
87 stoploop++;
88
89 // the number of positions that the image could occupy on the x axis
90 int safe_x_dim = DisplayImages.app_x_dim_ - image_x_dim;
91 double rx = Math.random();
92 // randomly pick an x co-ordinate for the image
93 image_x_pos= ((int)(rx*safe_x_dim));
94
95 // same process as for the x co-ordinate
96 // ensuring the y co-ordinate will fit on the screen
97 int safe_y_dim = DisplayImages.app_y_dim_ - image_y_dim;
98 double ry = Math.random();
99 // randomly pick a y co-ordinate for the image
100 image_y_pos= ((int)(ry*safe_y_dim));
101
102 double whitespace = 0;
103 double space = 0;
104
105 // determine how much whitespace the image will cover if placed in the
106 // current position and how much overlap will occur
107 for (int n = image_x_pos; n < (image_x_pos + image_x_dim); n++) {
108 for (int m = image_y_pos; m < (image_y_pos + image_y_dim); m++) {
109 if (DisplayImages.used_space[n][m] == 0)
110 whitespace++;
111 space++;
112 }
113 }
114
115 // divide the amount of whitespace covered by the amount of overlap
116 clear = whitespace/space;
117 // if this value is better than previous calculations, save these co-ordinates
118 if (clear > best_clear) {
119 best_x = image_x_pos;
120 best_y = image_y_pos;
121 best_clear = clear;
122 }
123
124 if ((image_x_dim > (DisplayImages.app_x_dim_ / 2)) || (image_y_dim > (DisplayImages.app_y_dim_ / 2)))
125 break;
126
127 } while ((clear < 0.70 || (stoploop > 3 && clear < 0.50)) && stoploop < 7);
128
129 // if we only terminated because we went through so many times,
130 // then we set the position to the best value possible
131 if (stoploop == 7) {
132 image_x_pos = best_x;
133 image_y_pos = best_y;
134 }
135
136 // indicate that the space where the image is to be placed is now used
137 for (int n = image_x_pos; n < (image_x_pos + image_x_dim); n++)
138 for (int m = image_y_pos; m < (image_y_pos + image_y_dim); m++) {
139 DisplayImages.used_space[n][m]++;
140 if (DisplayImages.used_space[n][m] > DisplayImages.NO_IMAGES_OF_OVERLAP)
141 overlap = true;
142 }
143
144 translateX = image_x_pos;
145 translateY = image_y_pos;
146
147 // scale the image appropriately
148 scaleX = 1.0/scale_factor;
149 scaleY = 1.0/scale_factor;
150
151 return;
152 }
153
154}
Note: See TracBrowser for help on using the repository browser.