1 /*
2 * xnec2c - GTK2-based version of nec2c, the C translation of NEC2
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*
20 * draw_structure.c
21 *
22 * Structure drawing routines for xnec2c
23 */
24
25 #include "draw_structure.h"
26 #include "shared.h"
27
28 /*-----------------------------------------------------------------------*/
29
30 /* Draw_Structure()
31 *
32 * Draws xyz axes, wire segments and patches
33 */
34 void
Draw_Structure(GtkWidget * drawingarea)35 Draw_Structure( GtkWidget *drawingarea )
36 {
37 /* Abort if xnec2c may be quit by user */
38 if( isFlagSet(MAIN_QUIT) )
39 return;
40
41 /* Cairo context */
42 cairo_t *cr = gdk_cairo_create( structure_pixmap );
43
44 /* Clear pixmap */
45 cairo_set_source_rgb( cr, BLACK );
46 cairo_rectangle(
47 cr, 0.0, 0.0,
48 (double)structure_proj_params.pixmap_width,
49 (double)structure_proj_params.pixmap_height);
50 cairo_fill( cr );
51
52 /* Process and draw geometry if available, else clear screen */
53 Process_Wire_Segments();
54 Process_Surface_Patches();
55 Draw_XYZ_Axes( structure_pixmap, structure_proj_params );
56 Draw_Surface_Patches( structure_segs+data.n, data.m );
57 Draw_Wire_Segments( structure_segs, data.n );
58
59 /* Show gain in direction of viewer */
60 Show_Viewer_Gain( main_window,
61 "main_gain_entry", structure_proj_params );
62
63 /* Render pixmap to screen */
64 gdk_window_set_back_pixmap(
65 drawingarea->window, structure_pixmap, FALSE );
66 gdk_window_clear( drawingarea->window );
67
68 /* Reset "new current data" flag */
69 crnt.newer = 0;
70
71 /* Display frequency step */
72 Display_Fstep( structure_fstep_entry, calc_data.fstep );
73
74 /* Wait for GTK to complete its tasks */
75 while( g_main_context_iteration(NULL, FALSE) );
76
77 cairo_destroy( cr );
78
79 } /* Draw_Structure() */
80
81 /*-----------------------------------------------------------------------*/
82
83 /* New_Wire_Data()
84 *
85 * Calculates some projection parameters
86 * when new wire segment data is created
87 */
88 void
New_Wire_Data(void)89 New_Wire_Data( void )
90 {
91 /* Abort if no wire data */
92 if( data.n == 0 ) return;
93
94 double
95 r, /* Distance of a point from XYZ origin */
96 r_max; /* Maximum value of above */
97
98 int idx;
99
100 /* Find segment end furthest from xyz axes origin */
101 r_max = 0.0;
102 for( idx = 0; idx < data.n; idx++ )
103 {
104 r = sqrt(
105 (double)data.x1[idx] * (double)data.x1[idx] +
106 (double)data.y1[idx] * (double)data.y1[idx] +
107 (double)data.z1[idx] * (double)data.z1[idx] );
108 if( r > r_max )
109 r_max = r;
110
111 r = sqrt(
112 (double)data.x2[idx] * (double)data.x2[idx] +
113 (double)data.y2[idx] * (double)data.y2[idx] +
114 (double)data.z2[idx] * (double)data.z2[idx] );
115 if( r > r_max )
116 r_max = r;
117
118 } /* for( idx = 0; idx < data.n; idx++ ) */
119
120 /* Max value of segment r saved if appropriate */
121 if( r_max > structure_proj_params.r_max )
122 structure_proj_params.r_max = r_max;
123
124 /* Redraw structure on screen */
125 New_Projection_Parameters(
126 structure_pixmap_width,
127 structure_pixmap_height,
128 &structure_proj_params );
129
130 } /* New_Wire_Data() */
131
132 /*-----------------------------------------------------------------------*/
133
134 /* New_Patch_Data()
135 *
136 * Calculates some projection parameters
137 * when new surface patch data is created
138 */
139 void
New_Patch_Data(void)140 New_Patch_Data( void )
141 {
142 /* Abort if no patch data */
143 if( data.m == 0 ) return;
144
145 double
146 s, /* Side/2 of a square that will represent a patch */
147 sx, sy, sz, /* Length of components of s in the X, Y, Z axes */
148 r, /* Distance of points in patch from XYZ co-ordinates */
149 r_max; /* Maximum value of above */
150
151 int idx, i;
152 size_t mreq;
153
154 /* Allocate memory for patch line segments */
155 mreq = (size_t)(2 * data.m) * sizeof(double);
156 mem_realloc( (void **)&data.px1, mreq, "in draw_structure.c" );
157 mem_realloc( (void **)&data.py1, mreq, "in draw_structure.c" );
158 mem_realloc( (void **)&data.pz1, mreq, "in draw_structure.c" );
159 mem_realloc( (void **)&data.px2, mreq, "in draw_structure.c" );
160 mem_realloc( (void **)&data.py2, mreq, "in draw_structure.c" );
161 mem_realloc( (void **)&data.pz2, mreq, "in draw_structure.c" );
162
163 /* Find point furthest from xyz axes origin */
164 r_max = 0.0;
165 for( idx = 0; idx < data.m; idx++ )
166 {
167 i = 2 * idx;
168
169 /* Side/2 of square representing a patch (sqrt of patch area) */
170 s = (double)sqrt( data.pbi[idx] ) / 2.0;
171
172 /* Projection of s on xyz components of t1 */
173 sx = s * (double)data.t1x[idx];
174 sy = s * (double)data.t1y[idx];
175 sz = s * (double)data.t1z[idx];
176
177 /* End 1 of line seg parallel to t1 vector */
178 data.px1[i] = (double)data.px[idx] + sx;
179 data.py1[i] = (double)data.py[idx] + sy;
180 data.pz1[i] = (double)data.pz[idx] + sz;
181
182 /* Its distance from XYZ origin */
183 r = sqrt(
184 data.px1[i]*data.px1[i] +
185 data.py1[i]*data.py1[i] +
186 data.pz1[i]*data.pz1[i] );
187 if( r > r_max )
188 r_max = r;
189
190 /* End 2 of line seg parallel to t1 vector */
191 data.px2[i] = (double)data.px[idx] - sx;
192 data.py2[i] = (double)data.py[idx] - sy;
193 data.pz2[i] = (double)data.pz[idx] - sz;
194
195 /* Its distance from XYZ origin */
196 r = sqrt(
197 data.px2[i]*data.px2[i] +
198 data.py2[i]*data.py2[i] +
199 data.pz2[i]*data.pz2[i] );
200 if( r > r_max )
201 r_max = r;
202
203 i++;
204
205 /* Projection of s on xyz components of t2 */
206 sx = s * (double)data.t2x[idx];
207 sy = s * (double)data.t2y[idx];
208 sz = s * (double)data.t2z[idx];
209
210 /* End 1 of line parallel to t2 vector */
211 data.px1[i] = (double)data.px[idx] + sx;
212 data.py1[i] = (double)data.py[idx] + sy;
213 data.pz1[i] = (double)data.pz[idx] + sz;
214
215 /* Its distance from XYZ origin */
216 r = sqrt(
217 data.px1[i]*data.px1[i] +
218 data.py1[i]*data.py1[i] +
219 data.pz1[i]*data.pz1[i] );
220 if( r > r_max )
221 r_max = r;
222
223 /* End 2 of line parallel to t2 vector */
224 data.px2[i] = (double)data.px[idx] - sx;
225 data.py2[i] = (double)data.py[idx] - sy;
226 data.pz2[i] = (double)data.pz[idx] - sz;
227
228 /* Its distance from XYZ origin */
229 r = sqrt(
230 data.px2[i]*data.px2[i] +
231 data.py2[i]*data.py2[i] +
232 data.pz2[i]*data.pz2[i] );
233 if( r > r_max )
234 r_max = r;
235
236 } /* for( idx = 0; idx < data.m; idx++ ) */
237
238 /* Max value of patch r saved if appropriate */
239 if( r_max > structure_proj_params.r_max )
240 structure_proj_params.r_max = r_max;
241
242 /* Redraw structure on screen */
243 New_Projection_Parameters(
244 structure_pixmap_width,
245 structure_pixmap_height,
246 &structure_proj_params );
247
248 } /* New_Patch_Data() */
249
250 /*-----------------------------------------------------------------------*/
251
252 /* Process_Wire_Segments()
253 *
254 * Processes wire segment data so they can be drawn on Screen
255 */
256 void
Process_Wire_Segments(void)257 Process_Wire_Segments( void )
258 {
259 int idx;
260
261 /* Project all wire segs from xyz frame to screen frame */
262 for( idx = 0; idx < data.n; idx++ )
263 Set_Gdk_Segment(
264 &structure_segs[idx],
265 &structure_proj_params,
266 (double)data.x1[idx],
267 (double)data.y1[idx],
268 (double)data.z1[idx],
269 (double)data.x2[idx],
270 (double)data.y2[idx],
271 (double)data.z2[idx] );
272
273 } /* Process_Wire_Segments() */
274
275 /*-----------------------------------------------------------------------*/
276
277 /* Process_Surface_Patches()
278 *
279 * Processes surface patch data so they can be drawn on Screen
280 */
281 void
Process_Surface_Patches(void)282 Process_Surface_Patches( void )
283 {
284 int idx, m2;
285
286 /* Project all patch segs from xyz frame to screen frame */
287 /* Patches are represented by 2 line segs parallel to t1 */
288 /* and t2 vectors. Length of segs is sqrt of patch area */
289 m2 = data.m * 2;
290 for( idx = 0; idx < m2; idx++ )
291 Set_Gdk_Segment(
292 &structure_segs[idx+data.n],
293 &structure_proj_params,
294 data.px1[idx],
295 data.py1[idx],
296 data.pz1[idx],
297 data.px2[idx],
298 data.py2[idx],
299 data.pz2[idx] );
300
301 } /* Process_Surface_Patches() */
302
303 /*-----------------------------------------------------------------------*/
304
305 /* Draw_Wire_Segments()
306 *
307 * Draws all wire segments of the input structure
308 */
309
310 void
Draw_Wire_Segments(GdkSegment * segm,gint nseg)311 Draw_Wire_Segments( GdkSegment *segm, gint nseg )
312 {
313 /* Abort if no wire segs or new input pending */
314 if( !nseg || isFlagSet(INPUT_PENDING) )
315 return;
316
317 int idx, i;
318
319 /* Cairo context */
320 cairo_t *cr = gdk_cairo_create( structure_pixmap );
321
322 /* Draw networks */
323 for( idx = 0; idx < netcx.nonet; idx++ )
324 {
325 int i1, i2;
326
327 i1 = netcx.iseg1[idx]-1;
328 i2 = netcx.iseg2[idx]-1;
329
330 switch( netcx.ntyp[idx] )
331 {
332 case 1: /* Two-port network */
333 {
334 GdkPoint points[4];
335
336 /* Draw a box between segs to represent two-port network */
337 points[0].x = segm[i1].x1 + (segm[i2].x1 - segm[i1].x1)/3;
338 points[0].y = segm[i1].y1 + (segm[i2].y1 - segm[i1].y1)/3;
339 points[1].x = segm[i2].x1 + (segm[i1].x1 - segm[i2].x1)/3;
340 points[1].y = segm[i2].y1 + (segm[i1].y1 - segm[i2].y1)/3;
341 points[2].x = segm[i2].x2 + (segm[i1].x2 - segm[i2].x2)/3;
342 points[2].y = segm[i2].y2 + (segm[i1].y2 - segm[i2].y2)/3;
343 points[3].x = segm[i1].x2 + (segm[i2].x2 - segm[i1].x2)/3;
344 points[3].y = segm[i1].y2 + (segm[i2].y2 - segm[i1].y2)/3;
345
346 cairo_set_source_rgb( cr, MAGENTA );
347 Cairo_Draw_Polygon( cr, points, 4 );
348 cairo_fill( cr );
349
350 /* Draw connecting lines */
351 Cairo_Draw_Line( cr,
352 segm[i1].x1, segm[i1].y1,
353 segm[i2].x1, segm[i2].y1 );
354 Cairo_Draw_Line( cr,
355 segm[i1].x2, segm[i1].y2,
356 segm[i2].x2, segm[i2].y2 );
357 }
358 break;
359
360 case 2: /* Straight transmission line */
361 /* Set cr attributes for transmission line */
362 cairo_set_source_rgb( cr, CYAN );
363
364 Cairo_Draw_Line( cr,
365 segm[i1].x1, segm[i1].y1,
366 segm[i2].x1, segm[i2].y1 );
367 Cairo_Draw_Line( cr,
368 segm[i1].x2, segm[i1].y2,
369 segm[i2].x2, segm[i2].y2 );
370 break;
371
372 case 3: /* Crossed transmisson line */
373 /* Set cr attributes for transmission line */
374 cairo_set_source_rgb( cr, CYAN );
375
376 Cairo_Draw_Line( cr,
377 segm[i1].x1, segm[i1].y1,
378 segm[i2].x2, segm[i2].y2 );
379 Cairo_Draw_Line( cr,
380 segm[i1].x2, segm[i1].y2,
381 segm[i2].x1, segm[i2].y1 );
382
383 } /* switch( netcx.ntyp ) */
384
385 } /* for( idx = 0; idx < netcx.nonet; idx++ ) */
386
387 /* Draw currents/charges if enabled, return */
388 /* Current or charge calculations do not contain wavelength */
389 /* factors, since they are drawn normalized to their max value */
390 if(
391 (isFlagSet(DRAW_CURRENTS) ||
392 isFlagSet(DRAW_CHARGES)) &&
393 crnt.valid )
394 {
395 static double cmax; /* Max of seg current/charge */
396 /* To color structure segs */
397 double red = 0.0, grn = 0.0, blu = 0.0;
398 char label[11];
399 size_t s = sizeof( label );
400
401 /* Loop over all wire segs, find max current/charge */
402 if( crnt.newer )
403 {
404 cmax = 0.0;
405 for( idx = 0; idx < nseg; idx++ )
406 {
407 if( isFlagSet(DRAW_CURRENTS) )
408 /* Calculate segment current magnitude */
409 cmag[idx] = (double)cabs( crnt.cur[idx] );
410 else
411 /* Calculate segment charge density */
412 cmag[idx] = (double)cabs( cmplx(crnt.bii[idx], crnt.bir[idx]) );
413
414 /* Find max current/charge magnitude */
415 if( cmag[idx] > cmax )
416 cmax = cmag[idx];
417 }
418
419 /* Show max value in color code label */
420 if( isFlagSet(DRAW_CURRENTS) )
421 snprintf( label, s, "%10.3E", cmax * (double)data.wlam );
422 else
423 snprintf( label, s, "%10.3E", cmax * 1.0E-6/(double)calc_data.fmhz );
424 gtk_label_set_text(
425 GTK_LABEL(lookup_widget(structure_drawingarea,
426 "main_colorcode_maxlabel")), label );
427
428 } /* if( crnt.newer ) */
429
430 /* Draw segments in color code according to current */
431 for( idx = 0; idx < nseg; idx++ )
432 {
433 /* Calculate RGB value for seg current */
434 Value_to_Color( &red, &grn, &blu, cmag[idx], cmax );
435
436 /* Set cr attributes for segment */
437 cairo_set_source_rgb( cr, red, grn, blu );
438
439 /* Draw segment */
440 Cairo_Draw_Line( cr,
441 segm[idx].x1, segm[idx].y1,
442 segm[idx].x2, segm[idx].y2 );
443 } /* for( idx = 0; idx < nseg; idx++ ) */
444
445 cairo_destroy( cr );
446 return;
447 } /* if( isFlagSet(DRAW_CURRENTS) || isFlagSet(DRAW_CHARGES) ) */
448
449 /* Draw segs if not all loaded */
450 cairo_set_line_width( cr, 2.0 );
451 if( zload.nldseg != nseg )
452 {
453 /* Set gc attributes for segments */
454 if( isFlagSet(OVERLAY_STRUCT) &&
455 (structure_proj_params.type == RDPATTERN_DRAWINGAREA) )
456 cairo_set_source_rgb( cr, WHITE );
457 else
458 cairo_set_source_rgb( cr, BLUE );
459
460 /* Draw wire segments */
461 Cairo_Draw_Segments( cr, segm, nseg );
462 }
463
464 /* Draw lumped loaded segments */
465 cairo_set_source_rgb( cr, YELLOW );
466 cairo_set_line_width( cr, 9.0 );
467 for( idx = 0; idx < zload.nldseg; idx++ )
468 {
469 if( zload.ldtype[idx] != 5 )
470 {
471 i = zload.ldsegn[idx]-1;
472 Cairo_Draw_Line( cr,
473 segm[i].x1, segm[i].y1,
474 segm[i].x2, segm[i].y2 );
475 }
476 }
477
478 /* Set gc attributes for excitation */
479 cairo_set_source_rgb( cr, RED );
480 cairo_set_line_width( cr, 5.0 );
481
482 /* Draw excitation sources */
483 for( idx = 0; idx < vsorc.nsant; idx++ )
484 {
485 i = vsorc.isant[idx]-1;
486 Cairo_Draw_Line( cr,
487 segm[i].x1, segm[i].y1,
488 segm[i].x2, segm[i].y2 );
489 }
490
491 for( idx = 0; idx < vsorc.nvqd; idx++ )
492 {
493 i = vsorc.ivqd[idx]-1;
494 Cairo_Draw_Line( cr,
495 segm[i].x1, segm[i].y1,
496 segm[i].x2, segm[i].y2 );
497 }
498
499 /* Draw resistivity loaded segments */
500 cairo_set_source_rgb( cr, YELLOW );
501 cairo_set_line_width( cr, 2.0 );
502 for( idx = 0; idx < zload.nldseg; idx++ )
503 {
504 if( zload.ldtype[idx] == 5 )
505 {
506 i = zload.ldsegn[idx]-1;
507 Cairo_Draw_Line( cr,
508 segm[i].x1, segm[i].y1,
509 segm[i].x2, segm[i].y2 );
510 }
511 }
512
513 cairo_destroy( cr );
514 } /* Draw_Wire_Segments() */
515
516 /*-----------------------------------------------------------------------*/
517
518 /* Draw_Surface_Patches()
519 *
520 * Draws the line segments that represent surface patches
521 */
522 void
Draw_Surface_Patches(GdkSegment * segm,gint npatch)523 Draw_Surface_Patches( GdkSegment *segm, gint npatch )
524 {
525 /* Abort if no patches */
526 if( ! npatch )
527 return;
528
529 /* Cairo context */
530 cairo_t *cr = gdk_cairo_create( structure_pixmap );
531
532 /* Draw currents if enabled, return */
533 if( isFlagSet(DRAW_CURRENTS) && crnt.valid )
534 {
535 /* Buffers for t1,t2 currents below */
536 static double cmax;
537
538 /* Current along x,y,z and t1,t2 vector directions */
539 complex double cx, cy, cz, ct1, ct2;
540
541 double red = 0.0, grn = 0.0, blu = 0.0;
542
543 int i, j;
544
545 /* Find max value of patch current magnitude */
546 if( crnt.newer )
547 {
548 j= data.n;
549 cmax = 0.0;
550
551 for( i = 0; i < npatch; i++ )
552 {
553 /* Calculate current along x,y,z vectors */
554 cx = (complex double)crnt.cur[j];
555 cy = (complex double)crnt.cur[j+1];
556 cz = (complex double)crnt.cur[j+2];
557
558 /* Calculate current along t1 and t2 tangent vectors */
559 ct1 = cx*(double)data.t1x[i] +
560 cy*(double)data.t1y[i] +
561 cz*(double)data.t1z[i];
562 ct2 = cx*(double)data.t2x[i] +
563 cy*(double)data.t2y[i] +
564 cz*(double)data.t2z[i];
565
566 /* Save current magnitudes */
567 ct1m[i] = (double)cabs( ct1 );
568 ct2m[i] = (double)cabs( ct2 );
569
570 /* Find current magnitude max */
571 if( ct1m[i] > cmax ) cmax = ct1m[i];
572 if( ct2m[i] > cmax ) cmax = ct2m[i];
573
574 j += 3;
575
576 } /* for( i = 0; i < npatch; i++ ) */
577
578 } /* if( crnt.newer ) */
579
580 /* Draw patches in color code according to current */
581 for( i = 0; i < npatch; i++ )
582 {
583 j = 2 * i;
584
585 /* Calculate RGB value for patch t1 current */
586 Value_to_Color( &red, &grn, &blu, ct1m[i], cmax );
587
588 /* Set cr attributes for patch t1 */
589 cairo_set_source_rgb( cr, red, grn, blu );
590
591 /* Draw patch t1 */
592 Cairo_Draw_Line( cr,
593 segm[j].x1, segm[j].y1,
594 segm[j].x2, segm[j].y2 );
595
596 /* Calculate RGB value for patch t2 current */
597 Value_to_Color( &red, &grn, &blu, ct2m[i], cmax );
598
599 /* Set cr attributes for patch t2 */
600 cairo_set_source_rgb( cr, red, grn, blu );
601
602 /* Draw patch t2 */
603 j++;
604 Cairo_Draw_Line( cr,
605 segm[j].x1, segm[j].y1,
606 segm[j].x2, segm[j].y2 );
607
608 } /* for( idx = 0; idx < npatch; idx++ ) */
609
610 } /* if( isFlagSet(DRAW_CURRENTS) ) */
611 else
612 {
613 int idx;
614
615 /* Set gc attributes for patches */
616 if( isFlagSet(OVERLAY_STRUCT) &&
617 (structure_proj_params.type == RDPATTERN_DRAWINGAREA) )
618 cairo_set_source_rgb( cr, WHITE );
619 else cairo_set_source_rgb( cr, BLUE );
620
621 /* Draw patch segments */
622 int nsg = 2 * npatch;
623 for( idx = 0; idx < nsg; idx++ )
624 {
625 Cairo_Draw_Line( cr,
626 segm[idx].x1, segm[idx].y1,
627 segm[idx].x2, segm[idx].y2 );
628 }
629 }
630
631 cairo_destroy( cr );
632 } /* Draw_Surface_Patches() */
633
634 /*-----------------------------------------------------------------------*/
635
636 /* Redo_Currents()
637 *
638 * Refreshes plots on new frequency in spinbutton
639 */
640 gboolean
Redo_Currents(gpointer udata)641 Redo_Currents( gpointer udata )
642 {
643 /* Abort if no geometry data */
644 if( ((data.n == 0) && (data.m == 0)) ||
645 isFlagClear(ENABLE_EXCITN) )
646 return FALSE;
647
648 /* Makes calcs use the extra buffer in rad_pattern */
649 calc_data.fstep = calc_data.nfrq;
650 save.last_freq = 0.0;
651 New_Frequency();
652
653 /* Display freq data in entry widgets */
654 if( isFlagSet(PLOT_FREQ_LINE) )
655 Plot_Frequency_Data();
656
657 /* Redraw structure on screen */
658 if( (structure_drawingarea != NULL) &&
659 (isFlagSet(DRAW_CURRENTS) || isFlagSet(DRAW_CHARGES)) )
660 Draw_Structure( structure_drawingarea );
661
662 return FALSE;
663 } /* Redo_Currents() */
664
665 /*-----------------------------------------------------------------------*/
666
667 /* New_Structure_Projection_Angle()
668 *
669 * Calculates new projection parameters when a
670 * structure projection angle (Wr or Wi) changes
671 */
672 void
New_Structure_Projection_Angle(void)673 New_Structure_Projection_Angle(void)
674 {
675 /* sin and cos of structure rotation and inclination angles */
676 structure_proj_params.sin_wr = sin(structure_proj_params.Wr/(double)TD);
677 structure_proj_params.cos_wr = cos(structure_proj_params.Wr/(double)TD);
678 structure_proj_params.sin_wi = sin(structure_proj_params.Wi/(double)TD);
679 structure_proj_params.cos_wi = cos(structure_proj_params.Wi/(double)TD);
680
681 /* Trigger a redraw of structure drawingarea */
682 if( isFlagClear(INPUT_PENDING) )
683 Draw_Structure( structure_drawingarea );
684
685 /* Trigger a redraw of plots drawingarea */
686 if( isFlagSet(PLOT_ENABLED) && isFlagSet(PLOT_GVIEWER) )
687 Plot_Frequency_Data();
688
689 } /* New_Structure_Projection_Angle() */
690
691 /*-----------------------------------------------------------------------*/
692
693 /* Init_Struct_Drawing()
694 *
695 * Initializes drawing parameters after geometry input
696 */
697 void
Init_Struct_Drawing(void)698 Init_Struct_Drawing( void )
699 {
700 /* We need n segs for wires + 2m for patces */
701 size_t mreq = (size_t)(data.n + 2*data.m) * sizeof(GdkSegment);
702 mem_realloc( (void **)&structure_segs, mreq, "in draw_structure.c" );
703 New_Wire_Data();
704 New_Patch_Data();
705 }
706
707 /*-----------------------------------------------------------------------*/
708
709 /* Show_Viewer_Gain()
710 *
711 * Shows gain in direction of viewer
712 */
713 void
Show_Viewer_Gain(GtkWidget * window,const char * widget,projection_parameters_t proj_params)714 Show_Viewer_Gain(
715 GtkWidget *window,
716 const char *widget,
717 projection_parameters_t proj_params )
718 {
719 if( isFlagSet(DRAW_CURRENTS) ||
720 isFlagSet(DRAW_CHARGES) ||
721 isFlagSet(DRAW_GAIN) ||
722 isFlagSet(FREQ_LOOP_RUNNING) )
723 {
724 char txt[8];
725
726 if( isFlagSet(ENABLE_RDPAT) && (calc_data.fstep >= 0) )
727 {
728 snprintf( txt, sizeof(txt), "%7.2f",
729 Viewer_Gain(proj_params, calc_data.fstep) );
730 gtk_entry_set_text(
731 GTK_ENTRY(lookup_widget(window, widget)), txt );
732 }
733 }
734
735 } /* Show_Viewer_Gain() */
736
737 /*-----------------------------------------------------------------------*/
738
739