1
/* Copyright (C) 2000 Damir Zucic */
3
/*=============================================================================
8
Draw helical wheel. This function is used if the main window
9
drawing mode is equal to two. The sequence stored to the sequence
10
buffer is used to prepare the helical wheel.
13
(1) Pointer to RuntimeS structure, with some runtime data.
14
(2) Pointer to GUIS structure, with GUI data.
15
(3) Pointer to NearestAtomS structure, with information about the
16
atom occupying the given pixel.
17
(4) The number of pixels in the main window free area.
18
(5) The refreshI, used to check the NearestAtomS associated with
19
a given pixel. It is currently unused in this function.
22
(1) Helical wheel drawn to the main window.
26
(1) The number of residues used to prepare the helical wheel.
29
(1) The initial drawing destination is the hidden pixmap, and the
30
content of this pixmap is copied later to the main window.
32
(2) Labels (residue names) are drawn for the last 18 residues.
34
========includes:============================================================*/
42
#include <X11/Xutil.h>
44
#include <X11/Xatom.h>
49
/*======function prototypes:=================================================*/
51
int RefreshPixmap_ (Display *, Pixmap, GC,
52
unsigned int, unsigned int, unsigned long);
53
int ParseColor_ (RGBS *, unsigned long *, GUIS *, char *, char *);
54
float Hydrophobicity_ (char *, int, int);
55
unsigned long WeightColors_ (unsigned long, unsigned long, double, GUIS *);
56
int DrawTitles_ (RuntimeS *, GUIS *);
58
/*======draw helical wheel:==================================================*/
60
size_t DrawWheel_ (RuntimeS *runtimeSP, GUIS *guiSP,
61
NearestAtomS *nearest_atomSP, size_t pixelsN,
62
unsigned int refreshI)
65
int residuesN, residueI;
67
unsigned long phob_colorID, neutral_colorID, phil_colorID;
69
double min_hyphob, max_hyphob, threshold_hyphob;
70
double delta_hyphob1, delta_hyphob2;
71
double inverse_range1, inverse_range2;
73
char residue_nameA[RESNAMESIZE];
76
unsigned long residue_colorID;
77
int square_width, screen_margin, screen_radius, half_screen_radius;
78
int screen_x0, screen_y0;
79
int screen_x1, screen_y1, screen_x2, screen_y2;
81
int helix_step, arc_start, arc_extent, arc_center;
82
int serialI, range_startI, range_endI, residues_in_wheelN = 0;
84
double angle, delta_x, delta_y;
86
char labelA[SHORTSTRINGSIZE];
87
int text_width, text_height;
89
int inner_screen_radius, thickness1, thickness2;
90
double alpha0, delta_alpha, alpha1, alpha2;
92
unsigned long far_colorID, near_colorID;
94
/* The number of residues in sequence buffer: */
95
residuesN = runtimeSP->residuesN;
98
strcpy (runtimeSP->messageA, "The sequence buffer is empty!");
99
runtimeSP->message_length = strlen (runtimeSP->messageA);
103
/* The maximal residue name length: */
104
max_length = RESNAMESIZE - 1;
106
/* Residue serial range: */
107
range_startI = runtimeSP->range_startI;
108
range_endI = runtimeSP->range_endI;
110
/* Count the number of residues in the specified range: */
111
for (residueI = 0; residueI < residuesN; residueI++)
113
/* Check is the residue serial index inside the range: */
114
serialI = *(runtimeSP->serialIP + residueI);
115
if ((serialI < range_startI) || (serialI > range_endI)) continue;
117
/* Increase the count of residues if current */
118
/* residue belongs to the specified range: */
119
residues_in_wheelN++;
122
/* Check the number of residues in a wheel: */
123
if (residues_in_wheelN == 0)
125
strcpy (runtimeSP->messageA, "The specified range is empty!");
126
runtimeSP->message_length = strlen (runtimeSP->messageA);
130
/* Refresh the hidden pixmap, where drawing will be done: */
131
RefreshPixmap_ (guiSP->displaySP,
132
guiSP->main_hidden_pixmapID,
134
guiSP->control_winS.x0, guiSP->input_winS.y0,
135
guiSP->main_winS.bg_colorID);
137
/*------draw arcs:-----------------------------------------------------------*/
139
/* Initialize colors used for hydrophobicity: */
140
ParseColor_ (&rgbS, &phob_colorID, guiSP, "RGB:FFFF/0000/0000", "white");
141
ParseColor_ (&rgbS, &neutral_colorID, guiSP, "RGB:FFFF/FFFF/FFFF", "white");
142
ParseColor_ (&rgbS, &phil_colorID, guiSP, "RGB:0000/0000/FFFF", "black");
144
/* Hydrophobicity scale index: */
145
scaleI = runtimeSP->hydrophobicity_scaleI;
147
/* Minimal, maximal and threshold hydrophobicity for current complex: */
148
min_hyphob = (double) Hydrophobicity_ ("", scaleI, 1);
149
max_hyphob = (double) Hydrophobicity_ ("", scaleI, 2);
150
threshold_hyphob = (double) Hydrophobicity_ ("", scaleI, 4);
152
/* Inverse hydrophobicity ranges: */
153
delta_hyphob1 = max_hyphob - threshold_hyphob;
154
if (delta_hyphob1 != 0.0) inverse_range1 = 1.0 / delta_hyphob1;
155
else inverse_range1 = 0.0;
156
delta_hyphob2 = threshold_hyphob - min_hyphob;
157
if (delta_hyphob2 != 0.0) inverse_range2 = 1.0 / delta_hyphob2;
158
else inverse_range2 = 0.0;
160
/* Prepare geometric parameters: */
161
square_width = guiSP->main_win_free_area_height;
162
if (guiSP->main_win_free_area_width < square_width)
164
square_width = guiSP->main_win_free_area_width;
166
screen_margin = guiSP->main_winS.text_line_height +
167
guiSP->main_winS.text_line_height / 2 + 2;
168
screen_radius = square_width / 2 - screen_margin;
169
if (screen_radius < 0) screen_radius = square_width / 2;
170
half_screen_radius = screen_radius / 2;
171
screen_x1 = guiSP->main_win_free_area_width / 2;
172
screen_y1 = guiSP->main_win_free_area_height / 2;
173
screen_x0 = screen_x1 - screen_radius;
174
screen_y0 = screen_y1 - screen_radius;
175
width = 2 * screen_radius;
178
/* Prepare the helix step angle (degrees * 64): */
179
helix_step = runtimeSP->helix_step_angle * 64;
181
/* Prepare the arc extent angle, (degrees * 64): */
182
arc_extent = (int) runtimeSP->arc_angle * 64;
184
/* Initialize the arc start angle, (degrees * 64): */
185
arc_start = 5760 - arc_extent / 2;
187
/* Prepare the text color: */
188
XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
189
guiSP->main_winS.fg_colorID);
191
/* Prepare the arc edge color: */
192
XSetForeground (guiSP->displaySP, guiSP->theGCA[1], guiSP->black_colorID);
194
/* Scan the sequence: */
195
for (residueI = 0; residueI < residuesN; residueI++)
197
/* Pointer to the current residue name: */
198
residue_nameP = runtimeSP->sequenceP + residueI * max_length;
200
/* Check is the residue serial index inside the range: */
201
serialI = *(runtimeSP->serialIP + residueI);
202
if ((serialI < range_startI) || (serialI > range_endI)) continue;
204
/* Copy the residue name: */
205
strncpy (residue_nameA, residue_nameP, max_length);
206
residue_nameA[max_length] = '\0';
208
/* The corresponding hydrophobicity: */
209
hyphob = (double) Hydrophobicity_ (residue_nameA, scaleI, 0);
211
/* If hydrophobicity is below the threshold value: */
212
if (hyphob <= threshold_hyphob)
214
scale_factor = (threshold_hyphob - hyphob) * inverse_range2;
215
residue_colorID = WeightColors_ (neutral_colorID, phil_colorID,
216
scale_factor, guiSP);
219
/* If hydrophobicity is above the threshold value: */
222
scale_factor = (hyphob - threshold_hyphob) * inverse_range1;
223
residue_colorID = WeightColors_ (neutral_colorID, phob_colorID,
224
scale_factor, guiSP);
227
/* Prepare the color: */
228
XSetForeground (guiSP->displaySP, guiSP->theGCA[2], residue_colorID);
230
/* Draw filled arc: */
231
XFillArc (guiSP->displaySP,
232
guiSP->main_hidden_pixmapID,
234
screen_x0, screen_y0,
236
arc_start, arc_extent);
238
/* Draw the outer arc edge: */
239
XDrawArc (guiSP->displaySP,
240
guiSP->main_hidden_pixmapID,
242
screen_x0, screen_y0,
244
arc_start, arc_extent);
246
/* Draw two straight lines from the arc origin to the edge: */
247
angle = DEG_TO_RAD * (double) arc_start / 64.0;
248
delta_x = (double) screen_radius * cos (angle);
249
delta_y = (double) screen_radius * sin (angle);
251
screen_x2 = screen_x1 + (int) delta_x;
252
screen_y2 = screen_y1 + (int) delta_y;
253
XDrawLine (guiSP->displaySP,
254
guiSP->main_hidden_pixmapID,
256
screen_x1, screen_y1,
257
screen_x2, screen_y2);
258
angle = DEG_TO_RAD * (double) (arc_start + arc_extent) / 64.0;
259
delta_x = (double) screen_radius * cos (angle);
260
delta_y = (double) screen_radius * sin (angle);
262
screen_x2 = screen_x1 + (int) delta_x;
263
screen_y2 = screen_y1 + (int) delta_y;
264
XDrawLine (guiSP->displaySP,
265
guiSP->main_hidden_pixmapID,
267
screen_x1, screen_y1,
268
screen_x2, screen_y2);
270
/* Draw labels for the last 18 residues (not for all!): */
271
if (residues_in_wheelN - wheelI <= 18)
273
arc_center = arc_start + arc_extent / 2;
274
angle = DEG_TO_RAD * (double) arc_center / 64.0;
275
delta_x = (double) screen_radius * cos (angle);
276
delta_y = (double) screen_radius * sin (angle);
278
screen_x2 = screen_x1 + (int) delta_x;
279
screen_y2 = screen_y1 + (int) delta_y;
280
sprintf (labelA, "%d:%s", serialI, residue_nameA);
281
label_length = strlen (labelA);
282
text_width = XTextWidth (guiSP->main_winS.fontSP,
283
labelA, label_length);
284
text_height = guiSP->main_winS.font_height;
285
if (screen_x2 < screen_x1) screen_x2 -= text_width - 1;
286
if (screen_y2 > screen_y1) screen_y2 += text_height;
288
XDrawString (guiSP->displaySP,
289
guiSP->main_hidden_pixmapID,
291
screen_x2, screen_y2,
292
labelA, label_length);
295
/* Update the arc start angle: */
296
arc_start += helix_step;
297
if (arc_start > 23040) arc_start = arc_start - 23040;
299
/* Update the wheel index: */
303
/*------draw the hole in the wheel center:-----------------------------------*/
305
/* Prepare geometric parameters: */
306
screen_x0 = guiSP->main_win_free_area_width / 2 - half_screen_radius;
307
screen_y0 = guiSP->main_win_free_area_height / 2 - half_screen_radius;
308
width = 2 * half_screen_radius;
310
XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
311
guiSP->main_winS.bg_colorID);
312
XFillArc (guiSP->displaySP, guiSP->main_hidden_pixmapID, guiSP->theGCA[0],
313
screen_x0, screen_y0, width, height, 0, 23040);
315
/*------draw polygons which represent backbone:------------------------------*/
317
/* This should be done only if angle is not equal to zero: */
321
/* Prepare far and near color: */
322
ParseColor_ (&rgbS, &far_colorID, guiSP,
323
"RGB:4444/4444/4444", "white");
324
ParseColor_ (&rgbS, &near_colorID, guiSP,
325
"RGB:FFFF/FFFF/FFFF", "white");
328
ParseColor_ (&rgbS, &far_colorID, guiSP,
329
"RGB:AAAA/AAAA/AAAA", "white");
332
/* Prepare the polygon edge color: */
333
XSetForeground (guiSP->displaySP,
335
guiSP->black_colorID);
337
/* Prepare half of the helix step angle in radians: */
338
delta_alpha = DEG_TO_RAD * (double) helix_step / 128.0;
340
/* Prepare the inner radius: */
341
inner_screen_radius = half_screen_radius * cos (delta_alpha);
343
/* Prepare two thickness parameters: */
344
thickness1 = screen_radius / 10;
345
if (thickness1 < 4) thickness1 = 4;
346
thickness2 = thickness1 * cos (delta_alpha);
347
if (thickness2 == 0) thickness2 = thickness1;
349
/* Initialize the reference angle (X11 units): */
352
/* Reset the wheel index: */
355
/* Scan the sequence again: */
356
for (residueI = 0; residueI < residuesN; residueI++)
358
/* Check is this serial index inside the range: */
359
serialI = *(runtimeSP->serialIP + residueI);
360
if ((serialI < range_startI) || (serialI > range_endI))
365
/* Convert the reference angle to radians: */
366
alpha0 = DEG_TO_RAD * (double) ref_angle / 64.0;
368
/* Prepare two additional angles: */
369
alpha1 = alpha0 - delta_alpha;
370
alpha2 = alpha0 + delta_alpha;
372
/* Now prepare seven points. */
374
/* The first point: */
375
delta_x = (double) half_screen_radius * cos (alpha0);
376
delta_y = (double) half_screen_radius * sin (alpha0);
378
screen_x2 = screen_x1 + (int) delta_x;
379
screen_y2 = screen_y1 + (int) delta_y;
380
pointSA[0].x = (short) screen_x2;
381
pointSA[0].y = (short) screen_y2;
383
/* The second point: */
384
delta_x = (double) inner_screen_radius * cos (alpha1);
385
delta_y = (double) inner_screen_radius * sin (alpha1);
387
screen_x2 = screen_x1 + (int) delta_x;
388
screen_y2 = screen_y1 + (int) delta_y;
389
pointSA[1].x = (short) screen_x2;
390
pointSA[1].y = (short) screen_y2;
392
/* The third point: */
393
delta_x = (double) (inner_screen_radius + thickness2) *
395
delta_y = (double) (inner_screen_radius + thickness2) *
398
screen_x2 = screen_x1 + (int) delta_x;
399
screen_y2 = screen_y1 + (int) delta_y;
400
pointSA[2].x = (short) screen_x2;
401
pointSA[2].y = (short) screen_y2;
403
/* The fourth point: */
404
delta_x = (double) (half_screen_radius + thickness1) *
406
delta_y = (double) (half_screen_radius + thickness1) *
409
screen_x2 = screen_x1 + (int) delta_x;
410
screen_y2 = screen_y1 + (int) delta_y;
411
pointSA[3].x = (short) screen_x2;
412
pointSA[3].y = (short) screen_y2;
414
/* The fifth point: */
415
delta_x = (double) (inner_screen_radius + thickness2) *
417
delta_y = (double) (inner_screen_radius + thickness2) *
420
screen_x2 = screen_x1 + (int) delta_x;
421
screen_y2 = screen_y1 + (int) delta_y;
422
pointSA[4].x = (short) screen_x2;
423
pointSA[4].y = (short) screen_y2;
425
/* The sixth point: */
426
delta_x = (double) inner_screen_radius * cos (alpha2);
427
delta_y = (double) inner_screen_radius * sin (alpha2);
429
screen_x2 = screen_x1 + (int) delta_x;
430
screen_y2 = screen_y1 + (int) delta_y;
431
pointSA[5].x = (short) screen_x2;
432
pointSA[5].y = (short) screen_y2;
434
/* The seventh point is a copy of the first point: */
435
pointSA[6].x = pointSA[0].x;
436
pointSA[6].y = pointSA[0].y;
438
/* Prepare the polygon interior color: */
439
if (residues_in_wheelN > 1)
441
scale_factor = (double) wheelI /
442
(double) (residues_in_wheelN - 1);
444
else scale_factor = 0.0;
445
residue_colorID = WeightColors_ (far_colorID, near_colorID,
446
scale_factor, guiSP);
447
XSetForeground (guiSP->displaySP,
451
/* Draw the filled polygon: */
452
XFillPolygon (guiSP->displaySP,
453
guiSP->main_hidden_pixmapID,
455
pointSA, 6, Complex, CoordModeOrigin);
457
/* Draw the polygon edge: */
458
XDrawLines (guiSP->displaySP,
459
guiSP->main_hidden_pixmapID,
461
pointSA, 7, CoordModeOrigin);
463
/* Update the reference angle (X11 units): */
464
ref_angle += helix_step;
465
if (ref_angle > 23040) ref_angle = ref_angle - 23040;
467
/* Update the wheel index: */
472
/*------draw titles:---------------------------------------------------------*/
475
DrawTitles_ (runtimeSP, guiSP);
477
/*------copy the prepared image to the main window:--------------------------*/
479
/* Copy hidden pixmap to the main window: */
480
XCopyArea (guiSP->displaySP,
481
guiSP->main_hidden_pixmapID, guiSP->main_winS.ID,
484
guiSP->main_win_free_area_width, guiSP->main_win_free_area_height,
490
/*===========================================================================*/