-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cxx
executable file
·400 lines (326 loc) · 16.4 KB
/
main.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
// File: eyes.cpp
// Written by Grant Macklem
// 2:00 PM Recitation
// Last modified Nov 22, 1998
// Flicker-free eyes!
/*******************************************************************************
* eyes.exe Flicker-free, mouse-following, customizably-colored eyes.
* Copyright (C) 1998 Grant Macklem
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* You may contact me, the author by emailing [email protected]
*******************************************************************************/
#include "graphics.h"
#include <iostream>
#include <math.h>
#include <stdlib.h> // Provides exit
#include <ctype.h> // Provides toupper
using namespace std;
const double XBORDER = 150.0; // X-border of the screen, cartesian
const double YBORDER = 112.5; // Y-border of the screen, cartesian
const double X_RAD = 2 * XBORDER / 10.0; // Width of eye ellipse, cartesian
const double Y_RAD = 2 * YBORDER / 12; // Height of eye, cartesian
const double LEFT_X = -1.5 * X_RAD; // X Coordinate of left eye, cartesian
const double LEFT_Y = 0; // Y Coordinate of right eye, cartesian
const double RIGHT_X = 1.5 * X_RAD; // X Coordinate of left eye, cartesian
const double RIGHT_Y = 0; // Y Coordinate of right eye, cartesian
const double I_RADIUS = X_RAD / 2.8; // Radius of iris in cartesian
const double P_RADIUS = X_RAD / 10; // Radius of pupil, cartesian
// Draws the new irises
void draw_iris(int x, int y);
int ytranslate
(double y, // Cartesian Coordinate to be translated into pixles
double yborder); // Top and bottom Cartesian coordinate of the screen
int xtranslate
(double x, // Cartesian Coordinate to be translated into pixles
double xborder); // Left and right Cartesian coordinate of the screen
// Draws the eye initially
void draw_eyes();
void change_left_color(int x, int y);
void change_right_color(int x, int y);
void check_keys();
// Checks to see if the line from the ellipse center to the mouse is vertical
bool check_vertical
(int x, // x location of the mouse
int y, // y location of the mouse
int x1, // x coordinate of ellipse center
int y1, // y coordinate of ellispe center
double& x_intersect, // Return value where iris x-intersects smaller ellipse
double& y_intersect, // Return value where iris y-intersects smaller ellipse
int small_ellipse_x_radius, // x coord of ellipse of center of iris an pupil
int small_ellipse_y_radius);// y coord of ellipse of center of iris an pupil
// Returns the radius of the eyes in pixel coordinates
void get_radius_eyes(int& tx_rad, int& ty_rad);
void update_graphics
(int left_x_intersect, // x intersection of left iris and pupil
int left_y_intersect, // y intersection of left iris and pupil
int right_x_intersect, // x intersection of right iris and pupil
int right_y_intersect, // y intersection of right iris and pupil
int ti_rad, // Radius, in pixels, of iris
int tp_rad, // radius, in pixels, of pupil
int& t); // Graphics page
void get_radius_iris_pupil
(int& ti_rad, // Radius of iris, in pixels
int& tp_rad); // Radius of pupil, in pixels
void find_coordinates
(int x, // x location of the mouse
int y, // y location of the mouse
int x1, // x coordinate of ellipse center
int y1, // y coordinate of ellispe center
double& x_intersect, // Return value where iris x-intersects smaller ellipse
double& y_intersect, // Return value where iris y-intersects smaller ellipse
int small_ellipse_x_radius, // x coord of ellipse of center of iris an pupil
int small_ellipse_y_radius);// y coord of ellipse of center of iris an pupil
int left_color = GREEN;
int right_color = GREEN;
int APIENTRY WinMain
( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
cout << "Moving Eyes, Copyright (C) 1998 Grant Macklem.\n" << endl;
cout << "Press 'Q' to quit" << endl;
initwindow(601, 451);
registermousehandler(WM_MOUSEMOVE, draw_iris);
registermousehandler(WM_LBUTTONDOWN, change_left_color);
registermousehandler(WM_RBUTTONDOWN, change_right_color);
// Draw the eyes, but must supply an initial position to look at.
draw_iris(2,2);
for(;;) // Infinite loop to keep program running... only quits when user
// presses the q key to exit.
{
check_keys();
delay(10);
}
}
void draw_eyes()
{
int x1 = xtranslate(LEFT_X, XBORDER);
int y1 = ytranslate(LEFT_Y, YBORDER);
int x2 = xtranslate(RIGHT_X, XBORDER);
int y2 = ytranslate(RIGHT_Y, YBORDER);
int tx_rad = xtranslate(X_RAD, XBORDER) - xtranslate(0, XBORDER);
int ty_rad = ytranslate(Y_RAD, YBORDER) - ytranslate(0, YBORDER);
setcolor(WHITE);
fillellipse (x1, y1, tx_rad, ty_rad);
fillellipse (x2, y2, tx_rad, ty_rad);
}
void change_left_color(int x, int y)
{
left_color ++; // Increase color by one
left_color %= 15; // Don't allow white as iris color, since that is eye
// color. Also makes sure color is between 0 and 15.
draw_iris(mousex(),mousey());
}
void change_right_color(int x, int y)
{
right_color ++; // Increase color by one
right_color %= 15; // Don't allow white as iris color, since that is eye
// color. Also makes sure color is between 0 and 15.
draw_iris(mousex(),mousey());
}
void draw_iris(int x, int y)
{
int tx_rad, ty_rad, ti_rad, tp_rad;
static int t = 0; // Graphics screen
// The following are in pixel coordinates of the iris ellipse
double small_ellipse_x_radius;
double small_ellipse_y_radius;
// Center of each eye in pixel coordinates.
int x1 = xtranslate(LEFT_X, XBORDER);
int y1 = ytranslate(LEFT_Y, YBORDER);
int x2 = xtranslate(RIGHT_X, XBORDER);
int y2 = ytranslate(RIGHT_Y, YBORDER);
// These variables tell where the line from the center of the eye to the mouse
// intersects the smaller ellipse (where to draw the iris)
double left_x_intersect, left_y_intersect, right_x_intersect, right_y_intersect;
get_radius_eyes(tx_rad, ty_rad);
get_radius_iris_pupil(ti_rad, tp_rad);
small_ellipse_x_radius = tx_rad - ti_rad;
small_ellipse_y_radius = ty_rad - ti_rad;
// Left Iris
find_coordinates(x, y, x1, y1, left_x_intersect, left_y_intersect,
small_ellipse_x_radius, small_ellipse_y_radius);
// Right Iris
find_coordinates(x, y, x2, y2, right_x_intersect, right_y_intersect,
small_ellipse_x_radius, small_ellipse_y_radius);
update_graphics(left_x_intersect, left_y_intersect, right_x_intersect,
right_y_intersect, ti_rad, tp_rad, t);
}
// Checks to see if the line from the ellipse center to the mouse is vertical
bool check_vertical
(int x, // x location of the mouse
int y, // y location of the mouse
int x1, // x coordinate of ellipse center
int y1, // y coordinate of ellispe center
double& x_intersect, // Return value where iris x-intersects smaller ellipse
double& y_intersect, // Return value where iris y-intersects smaller ellipse
int small_ellipse_y_radius) // y coord of ellipse of center of iris an pupil
{
// Center of each eye in pixel coordinates.
if (x == x1)
{
x_intersect = x;
if (abs(y1 - y) >= small_ellipse_y_radius)
{ // Pointer is outside the eye
if ((y1 - y) > 0)
y_intersect = y1 - small_ellipse_y_radius;
else
y_intersect = y1 + small_ellipse_y_radius;
}
else // Pointer is in the eye
y_intersect = y;
return true;
}
return false;
}
void find_coordinates
(int x, // x location of the mouse
int y, // y location of the mouse
int x1, // x coordinate of ellipse center
int y1, // y coordinate of ellispe center
double& x_intersect, // Return value where iris x-intersects smaller ellipse
double& y_intersect, // Return value where iris y-intersects smaller ellipse
int small_ellipse_x_radius, // x coord of ellipse of center of iris an pupil
int small_ellipse_y_radius) // y coord of ellipse of center of iris an pupil
{
bool vertical;
// Fraction variables to calculate intersection points
double numerator, denominator, slope;
vertical = check_vertical(x, y, x1, y1, x_intersect, y_intersect,
small_ellipse_y_radius);
if (!vertical)
{ // Find slope of line from center of eye to mouse pointer, pixel coords
slope = ((double)(y1 - y)) / ((double)(x - x1));
// Pixel coords
numerator = pow(small_ellipse_x_radius, 2.0) * pow(small_ellipse_y_radius, 2.0);
denominator = pow(small_ellipse_y_radius, 2.0) + pow(small_ellipse_x_radius, 2.0) * pow(slope, 2.0);
x_intersect = sqrt(numerator / denominator);
y_intersect = slope * x_intersect;
if (x < x1)
x_intersect = -(abs(x_intersect));
else
x_intersect = abs(x_intersect);
if (y < y1)
y_intersect = -(abs(y_intersect));
else
y_intersect = abs(y_intersect);
x_intersect += x1;
y_intersect += y1;
if ( (pow(x - x1,2.0) / pow(small_ellipse_x_radius, 2.0) + pow(y1 - y, 2.0) / pow(small_ellipse_y_radius, 2.0)) < 1)
{ // Point is inside the eye ellipse
x_intersect = x;
y_intersect = y;
}
} // end if not vertical
}
void get_radius_eyes(int& tx_rad, int& ty_rad)
{
// Radii of the eyes in pixel coordinates
tx_rad = xtranslate(X_RAD, XBORDER) - xtranslate(0, XBORDER);
ty_rad = ytranslate(0, YBORDER) - ytranslate(Y_RAD, YBORDER);
}
void get_radius_iris_pupil(int& ti_rad, int& tp_rad)
{
// Radii of the iris and pupil, respectively, in pixel coordinates
ti_rad = xtranslate(I_RADIUS, XBORDER) - xtranslate(0, XBORDER);
tp_rad = xtranslate(P_RADIUS, XBORDER) - xtranslate(0, XBORDER);
}
void update_graphics(int left_x_intersect, int left_y_intersect,
int right_x_intersect, int right_y_intersect, int ti_rad, int tp_rad, int& t)
{
int active_page = t % 2;
setactivepage(active_page);
clearviewport();
setfillstyle( SOLID_FILL, WHITE );
draw_eyes();
// Left Iris
setcolor (left_color);
setfillstyle( SOLID_FILL, left_color );
fillellipse(left_x_intersect, left_y_intersect, ti_rad, ti_rad);
// Left Pupil
setcolor (BLACK);
setfillstyle( SOLID_FILL, BLACK );
fillellipse(left_x_intersect, left_y_intersect, tp_rad, tp_rad);
// Right Iris
setcolor (right_color);
setfillstyle( SOLID_FILL, right_color );
fillellipse(right_x_intersect, right_y_intersect, ti_rad, ti_rad);
// Right Pupil
setcolor (BLACK);
setfillstyle( SOLID_FILL, BLACK );
fillellipse(right_x_intersect, right_y_intersect, tp_rad, tp_rad);
t++;
setvisualpage(active_page);
}
void check_keys()
{
int command;
if (kbhit()== true)
{
command = toupper(getch());
if (char(command) == 'Q')
{
cout << "Exiting..." << endl;
exit (EXIT_SUCCESS);
}
}
}
// ******************** User X-Coordinate Translate Function *******************
// Translate the user inputted x-coordinate to a screen coordinate
int xtranslate (double x, double xborder)
{
// This function assumes that you want to plot horizontal values that range from
// -xborder (on the left of the graphics screen) to +xborder (on the right of
// the graphics screen).
// The return value of this function tells the x-pixel value that corresponds
// to the parameter x.
double percent; // Percent of x-hemisphere (positive or negative) where
// user defined coordinate is located
int maxx = getmaxx();
int x_value; // Corresponding graphical x-value
percent = x / xborder; // Finds, percentagewise, how far the user defined
// coordinate is located from the y-axis.
// Calculates the graphical x-value by adding to the x-value at the center of
// the screen the percentage further that the user defined x is located. Note
// that if percentage is negative (meaning the user x-coorinate was negative)
// that the following step will be a subtraction.
x_value = maxx/2 + percent * (maxx/2);
return (int)x_value;
}
// ******************** User Y-Coordinate Translate Function *******************
// Translate the user inputted y-coordinate to a screen coordinate
int ytranslate (double y, double yborder)
{
// This function assumes that you want to plot vertical values that range from
// -yborder (on the bottom of the graphics screen) to +yborder (on the topof
// the graphics screen).
// The return value of this function tells the y-pixel value that corresponds
// to the parameter y.
float percent; // Percent of y-hemisphere (positive or negative) where
// user defined coordinate is located
int maxy = getmaxy();
int y_value; // Corresponding graphical y-value
percent = -y / yborder; // Finds, percentagewise, how far the user defined
// coordinate is located from the x-axis. Since the
// y-values run opposite from expected, the negative
// sign is necessary.
// Calculates the graphical y-value by adding to the y-value at the center of
// the screen the percentage further that the user defined y is located. Note
// that if percentage is negative (meaning the user y-coorinate was negative)
// that the following step will be a subtraction.
y_value = maxy/2 + percent * (maxy/2);
return (int)y_value;
}