~ubuntu-branches/ubuntu/breezy/garlic/breezy

« back to all changes in this revision

Viewing changes to draw_wheel.c

  • Committer: Bazaar Package Importer
  • Author(s): zhaoway
  • Date: 2001-04-24 07:09:13 UTC
  • Revision ID: james.westby@ubuntu.com-20010424070913-uzpupnwdfhmliebz
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 Damir Zucic */
 
2
 
 
3
/*=============================================================================
 
4
 
 
5
                                draw_wheel.c
 
6
 
 
7
Purpose:
 
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.
 
11
 
 
12
Input:
 
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.
 
20
 
 
21
Output:
 
22
        (1) Helical wheel drawn to the main window.
 
23
        (2) Return value.
 
24
 
 
25
Return value:
 
26
        (1) The number of residues used to prepare the helical wheel.
 
27
 
 
28
Notes:
 
29
        (1) The initial drawing destination is the hidden pixmap, and the
 
30
            content of this pixmap is  copied  later to  the main window.
 
31
 
 
32
        (2) Labels (residue names) are drawn for the last 18 residues.
 
33
 
 
34
========includes:============================================================*/
 
35
 
 
36
#include <stdio.h>
 
37
 
 
38
#include <string.h>
 
39
#include <math.h>
 
40
 
 
41
#include <X11/Xlib.h>
 
42
#include <X11/Xutil.h>
 
43
#include <X11/Xos.h>
 
44
#include <X11/Xatom.h>
 
45
 
 
46
#include "defines.h"
 
47
#include "typedefs.h"
 
48
 
 
49
/*======function prototypes:=================================================*/
 
50
 
 
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 *);
 
57
 
 
58
/*======draw helical wheel:==================================================*/
 
59
 
 
60
size_t DrawWheel_ (RuntimeS *runtimeSP, GUIS *guiSP,
 
61
                   NearestAtomS *nearest_atomSP, size_t pixelsN,
 
62
                   unsigned int refreshI)
 
63
{
 
64
int             max_length;
 
65
int             residuesN, residueI;
 
66
RGBS            rgbS;
 
67
unsigned long   phob_colorID, neutral_colorID, phil_colorID;
 
68
int             scaleI;
 
69
double          min_hyphob, max_hyphob, threshold_hyphob;
 
70
double          delta_hyphob1, delta_hyphob2;
 
71
double          inverse_range1, inverse_range2;
 
72
char            *residue_nameP;
 
73
char            residue_nameA[RESNAMESIZE];
 
74
double          hyphob;
 
75
double          scale_factor;
 
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;
 
80
int             width, height;
 
81
int             helix_step, arc_start, arc_extent, arc_center;
 
82
int             serialI, range_startI, range_endI, residues_in_wheelN = 0;
 
83
size_t          wheelI = 0;
 
84
double          angle, delta_x, delta_y;
 
85
int             label_length;
 
86
char            labelA[SHORTSTRINGSIZE];
 
87
int             text_width, text_height;
 
88
int             ref_angle;
 
89
int             inner_screen_radius, thickness1, thickness2;
 
90
double          alpha0, delta_alpha, alpha1, alpha2;
 
91
XPoint          pointSA[7];
 
92
unsigned long   far_colorID, near_colorID;
 
93
 
 
94
/* The number of residues in sequence buffer: */
 
95
residuesN = runtimeSP->residuesN;
 
96
if (residuesN == 0)
 
97
        {
 
98
        strcpy (runtimeSP->messageA, "The sequence buffer is empty!");
 
99
        runtimeSP->message_length = strlen (runtimeSP->messageA);
 
100
        return 0;
 
101
        }
 
102
 
 
103
/* The maximal residue name length: */
 
104
max_length = RESNAMESIZE - 1;
 
105
 
 
106
/* Residue serial range: */
 
107
range_startI = runtimeSP->range_startI;
 
108
range_endI   = runtimeSP->range_endI;
 
109
 
 
110
/* Count the number of residues in the specified range: */
 
111
for (residueI = 0; residueI < residuesN; residueI++)
 
112
        {
 
113
        /* Check is the residue serial index inside the range: */
 
114
        serialI = *(runtimeSP->serialIP + residueI);
 
115
        if ((serialI < range_startI) || (serialI > range_endI)) continue;
 
116
 
 
117
        /* Increase the count of residues if current */
 
118
        /* residue  belongs to  the specified range: */
 
119
        residues_in_wheelN++;
 
120
        }
 
121
 
 
122
/* Check the number of residues in a wheel: */
 
123
if (residues_in_wheelN == 0)
 
124
        {
 
125
        strcpy (runtimeSP->messageA, "The specified range is empty!");
 
126
        runtimeSP->message_length = strlen (runtimeSP->messageA);
 
127
        return 0;
 
128
        }
 
129
 
 
130
/* Refresh the hidden pixmap, where drawing will be done: */
 
131
RefreshPixmap_ (guiSP->displaySP,
 
132
                guiSP->main_hidden_pixmapID,
 
133
                guiSP->theGCA[0],
 
134
                guiSP->control_winS.x0, guiSP->input_winS.y0,
 
135
                guiSP->main_winS.bg_colorID);
 
136
 
 
137
/*------draw arcs:-----------------------------------------------------------*/
 
138
 
 
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");
 
143
 
 
144
/* Hydrophobicity scale index: */
 
145
scaleI = runtimeSP->hydrophobicity_scaleI;
 
146
 
 
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);
 
151
 
 
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;
 
159
 
 
160
/* Prepare geometric parameters: */
 
161
square_width = guiSP->main_win_free_area_height;
 
162
if (guiSP->main_win_free_area_width < square_width)
 
163
        {
 
164
        square_width = guiSP->main_win_free_area_width;
 
165
        }
 
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;
 
176
height = width;
 
177
 
 
178
/* Prepare the helix step angle (degrees * 64): */
 
179
helix_step = runtimeSP->helix_step_angle * 64;
 
180
 
 
181
/* Prepare the arc extent angle, (degrees * 64): */
 
182
arc_extent = (int) runtimeSP->arc_angle * 64;
 
183
 
 
184
/* Initialize the arc start angle, (degrees * 64): */
 
185
arc_start = 5760 - arc_extent / 2;
 
186
 
 
187
/* Prepare the text color: */
 
188
XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
 
189
                guiSP->main_winS.fg_colorID);
 
190
 
 
191
/* Prepare the arc edge color: */
 
192
XSetForeground (guiSP->displaySP, guiSP->theGCA[1], guiSP->black_colorID);
 
193
 
 
194
/* Scan the sequence: */
 
195
for (residueI = 0; residueI < residuesN; residueI++)
 
196
        {
 
197
        /* Pointer to the current residue name: */
 
198
        residue_nameP = runtimeSP->sequenceP + residueI * max_length;
 
199
 
 
200
        /* Check is the residue serial index inside the range: */
 
201
        serialI = *(runtimeSP->serialIP + residueI);
 
202
        if ((serialI < range_startI) || (serialI > range_endI)) continue;
 
203
 
 
204
        /* Copy the residue name: */
 
205
        strncpy (residue_nameA, residue_nameP, max_length);
 
206
        residue_nameA[max_length] = '\0';
 
207
 
 
208
        /* The corresponding hydrophobicity: */
 
209
        hyphob = (double) Hydrophobicity_ (residue_nameA, scaleI, 0);
 
210
 
 
211
        /* If hydrophobicity is below the threshold value: */
 
212
        if (hyphob <= threshold_hyphob)
 
213
                {
 
214
                scale_factor = (threshold_hyphob - hyphob) * inverse_range2;
 
215
                residue_colorID = WeightColors_ (neutral_colorID, phil_colorID,
 
216
                                                 scale_factor, guiSP);
 
217
                }
 
218
 
 
219
        /* If hydrophobicity is above the threshold value: */
 
220
        else
 
221
                {
 
222
                scale_factor = (hyphob - threshold_hyphob) * inverse_range1;
 
223
                residue_colorID = WeightColors_ (neutral_colorID, phob_colorID,
 
224
                                                 scale_factor, guiSP);
 
225
                }
 
226
 
 
227
        /* Prepare the color: */
 
228
        XSetForeground (guiSP->displaySP, guiSP->theGCA[2], residue_colorID);
 
229
 
 
230
        /* Draw filled arc: */
 
231
        XFillArc (guiSP->displaySP,
 
232
                  guiSP->main_hidden_pixmapID,
 
233
                  guiSP->theGCA[2],
 
234
                  screen_x0, screen_y0,
 
235
                  width, height,
 
236
                  arc_start, arc_extent);
 
237
 
 
238
        /* Draw the outer arc edge: */
 
239
        XDrawArc (guiSP->displaySP,
 
240
                  guiSP->main_hidden_pixmapID,
 
241
                  guiSP->theGCA[1],
 
242
                  screen_x0, screen_y0,
 
243
                  width, height,
 
244
                  arc_start, arc_extent);
 
245
 
 
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);
 
250
        delta_y *= -1;
 
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,
 
255
                   guiSP->theGCA[1],
 
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);
 
261
        delta_y *= -1;
 
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,
 
266
                   guiSP->theGCA[1],
 
267
                   screen_x1, screen_y1,
 
268
                   screen_x2, screen_y2);
 
269
 
 
270
        /* Draw labels for the last 18 residues (not for all!): */
 
271
        if (residues_in_wheelN - wheelI <= 18)
 
272
                {
 
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);
 
277
                delta_y *= -1;
 
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;
 
287
                else screen_y2 -= 2;
 
288
                XDrawString (guiSP->displaySP,
 
289
                             guiSP->main_hidden_pixmapID,
 
290
                             guiSP->theGCA[0],
 
291
                             screen_x2, screen_y2,
 
292
                             labelA, label_length);
 
293
                }
 
294
 
 
295
        /* Update the arc start angle: */
 
296
        arc_start += helix_step;
 
297
        if (arc_start > 23040) arc_start = arc_start - 23040;
 
298
 
 
299
        /* Update the wheel index: */
 
300
        wheelI++;
 
301
        }
 
302
 
 
303
/*------draw the hole in the wheel center:-----------------------------------*/
 
304
 
 
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;
 
309
height = width;
 
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);
 
314
 
 
315
/*------draw polygons which represent backbone:------------------------------*/
 
316
 
 
317
/* This should be done only if angle is not equal to zero: */
 
318
 
 
319
if (helix_step != 0)
 
320
        {
 
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");
 
326
        if (residuesN < 3)
 
327
                {
 
328
                ParseColor_ (&rgbS, &far_colorID, guiSP,
 
329
                             "RGB:AAAA/AAAA/AAAA", "white");
 
330
                }
 
331
 
 
332
        /* Prepare the polygon edge color: */
 
333
        XSetForeground (guiSP->displaySP,
 
334
                        guiSP->theGCA[2],
 
335
                        guiSP->black_colorID);
 
336
 
 
337
        /* Prepare half of the helix step angle in radians: */
 
338
        delta_alpha = DEG_TO_RAD * (double) helix_step / 128.0;
 
339
 
 
340
        /* Prepare the inner radius: */
 
341
        inner_screen_radius = half_screen_radius * cos (delta_alpha);
 
342
 
 
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;
 
348
 
 
349
        /* Initialize the reference angle (X11 units): */
 
350
        ref_angle = 5760;
 
351
 
 
352
        /* Reset the wheel index: */
 
353
        wheelI = 0;
 
354
 
 
355
        /* Scan the sequence again: */
 
356
        for (residueI = 0; residueI < residuesN; residueI++)
 
357
                {
 
358
                /* Check is this serial index inside the range: */
 
359
                serialI = *(runtimeSP->serialIP + residueI);
 
360
                if ((serialI < range_startI) || (serialI > range_endI))
 
361
                        {
 
362
                        continue;
 
363
                        }
 
364
 
 
365
                /* Convert the reference angle to radians: */
 
366
                alpha0 = DEG_TO_RAD * (double) ref_angle / 64.0;
 
367
 
 
368
                /* Prepare two additional angles: */
 
369
                alpha1 = alpha0 - delta_alpha;
 
370
                alpha2 = alpha0 + delta_alpha;
 
371
 
 
372
                /* Now prepare seven points. */
 
373
 
 
374
                /* The first point: */
 
375
                delta_x = (double) half_screen_radius * cos (alpha0);
 
376
                delta_y = (double) half_screen_radius * sin (alpha0);
 
377
                delta_y *= -1;
 
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;
 
382
 
 
383
                /* The second point: */
 
384
                delta_x = (double) inner_screen_radius * cos (alpha1);
 
385
                delta_y = (double) inner_screen_radius * sin (alpha1);
 
386
                delta_y *= -1;
 
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;
 
391
 
 
392
                /* The third point: */
 
393
                delta_x = (double) (inner_screen_radius + thickness2) *
 
394
                          cos (alpha1);
 
395
                delta_y = (double) (inner_screen_radius + thickness2) *
 
396
                          sin (alpha1);
 
397
                delta_y *= -1;
 
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;
 
402
 
 
403
                /* The fourth point: */
 
404
                delta_x = (double) (half_screen_radius + thickness1) *
 
405
                          cos (alpha0);
 
406
                delta_y = (double) (half_screen_radius + thickness1) *
 
407
                          sin (alpha0);
 
408
                delta_y *= -1;
 
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;
 
413
 
 
414
                /* The fifth point: */
 
415
                delta_x = (double) (inner_screen_radius + thickness2) *
 
416
                          cos (alpha2);
 
417
                delta_y = (double) (inner_screen_radius + thickness2) *
 
418
                          sin (alpha2);
 
419
                delta_y *= -1;
 
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;
 
424
 
 
425
                /* The sixth point: */
 
426
                delta_x = (double) inner_screen_radius * cos (alpha2);
 
427
                delta_y = (double) inner_screen_radius * sin (alpha2);
 
428
                delta_y *= -1;
 
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;
 
433
 
 
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;
 
437
 
 
438
                /* Prepare the polygon interior color: */
 
439
                if (residues_in_wheelN > 1)
 
440
                        {
 
441
                        scale_factor = (double) wheelI /
 
442
                                       (double) (residues_in_wheelN - 1);
 
443
                        }
 
444
                else scale_factor = 0.0;
 
445
                residue_colorID = WeightColors_ (far_colorID, near_colorID,
 
446
                                                 scale_factor, guiSP);
 
447
                XSetForeground (guiSP->displaySP,
 
448
                                guiSP->theGCA[2],
 
449
                                residue_colorID);
 
450
 
 
451
                /* Draw the filled polygon: */
 
452
                XFillPolygon (guiSP->displaySP,
 
453
                              guiSP->main_hidden_pixmapID,
 
454
                              guiSP->theGCA[2],
 
455
                              pointSA, 6, Complex, CoordModeOrigin);
 
456
 
 
457
                /* Draw the polygon edge: */
 
458
                XDrawLines (guiSP->displaySP,
 
459
                            guiSP->main_hidden_pixmapID,
 
460
                            guiSP->theGCA[1],
 
461
                            pointSA, 7, CoordModeOrigin);
 
462
 
 
463
                /* Update the reference angle (X11 units): */
 
464
                ref_angle += helix_step;
 
465
                if (ref_angle > 23040) ref_angle = ref_angle - 23040;
 
466
 
 
467
                /* Update the wheel index: */
 
468
                wheelI++;
 
469
                }
 
470
        }
 
471
 
 
472
/*------draw titles:---------------------------------------------------------*/
 
473
 
 
474
/* Draw titles: */
 
475
DrawTitles_ (runtimeSP, guiSP);
 
476
 
 
477
/*------copy the prepared image to the main window:--------------------------*/
 
478
 
 
479
/* Copy hidden pixmap to the main window: */
 
480
XCopyArea (guiSP->displaySP,
 
481
           guiSP->main_hidden_pixmapID, guiSP->main_winS.ID,
 
482
           guiSP->theGCA[0],
 
483
           0, 0,
 
484
           guiSP->main_win_free_area_width, guiSP->main_win_free_area_height,
 
485
           0, 0);
 
486
 
 
487
return residuesN;
 
488
}
 
489
 
 
490
/*===========================================================================*/
 
491
 
 
492