001 /*
002 * @(#)MohrCircleCanvas.java
003 */
004
005 import java.awt.*;
006 import java.awt.geom.*;
007 import java.awt.event.*;
008 import java.text.*;
009
010 import wc.*;
011
012 /**
013 * MohrCircleCanvas.java - Desenha o círculo de Mohr.
014 *
015 * <p>
016 * Descrição:
017 * <p>
018 * ===============================================================
019 * <p>
020 * Este arquivo contém a classe que desenha e manipula o
021 * círculo de Mohr.
022 *
023 * <p>
024 * ===============================================================
025 *
026 * @version 1.0 04/09/2004
027 * @author Luiz Fernando Martha
028 * @author Alonso Juvinao Carbono
029 * @author Anderson Resende Pereira
030 * @author Fernando Busato Ramires
031 * @author Paôla Reginal Dalcanal
032 * @author Ricardo Rodrigues de Araujo
033 *
034 */
035 class MohrCircleCanvas extends CanvasWC
036 {
037 /** Tamanho de referência para definição de strokes e tamanho de objetos */
038 protected double ref_size;
039
040 /** Ajuste de janela mostrando origem ou enquadra no círculo */
041 public static final int SHOW_ORIGIN = 0;
042
043 /** Ajuste de janela enquadrando no círculo */
044 public static final int FIT_ON_CIRCLE = 1;
045
046 /** Tipo de ajuste de janela */
047 protected int fit_type;
048
049 /** Visibilidade do estado de tensões corrente */
050 protected boolean vis_statestrs = true;
051
052 /** Visibilidade das tensões principal */
053 protected boolean vis_principalstrs = true;
054
055 /** Visibilidade das tensões no plano inclinado */
056 protected boolean vis_thetastrs = true;
057
058 /** Nenhum ponto selecionado */
059 public static final int NONE_SEL = 0;
060
061 /** Ponto do plano theta selecionado */
062 public static final int THETA_PLANE_SEL = 1;
063
064 /** Ponto do sigmax selecionado */
065 public static final int SIGMAX_SEL = 2;
066
067 /** Ponto do sigmay selecionado */
068 public static final int SIGMAY_SEL = 3;
069
070 /** Ponto do tauxy selecionado */
071 public static final int TAUXY_SEL = 4;
072
073 /** Ponto do tauyx (-tauxy) selecionado */
074 public static final int TAUYX_SEL = 5;
075
076 /** tipo de ponto selecionado pelo mouse */
077 protected static int type_sel;
078
079 /** Driver do programa Mohr-Circle */
080 protected MohrDriver driver;
081
082 /** Círculo */
083 protected Ellipse2D.Double circle;
084
085 /** Fator de proporção em relação ao tamanho horizontal da janela
086 * em coordenadas do mundo para stroke básico do círculo */
087 protected static final double CIRCLE_STROKE_FAC = 0.003;
088
089 /** Stroke básico do círculo */
090 protected BasicStroke circle_stroke;
091
092 /** Eixo horizontal das tensões normais */
093 protected Arrow2D sigaxis;
094
095 /** Coordenada x do início do eixo horizontal */
096 protected double sigaxis_start;
097
098 /** Coordenada x do final do eixo horizontal */
099 protected double sigaxis_end;
100
101 /** Comprimento do eixo horizontal */
102 protected double sigaxis_len;
103
104 /** Eixo vertical das tensões de cisalhamento */
105 protected Arrow2D tauaxis;
106
107 /** Comprimento do eixo vertical */
108 protected double tauaxis_len;
109
110 /** Fator de proporção em relação ao tamanho horizontal da janela
111 * em coordenadas do mundo para stroke básico dos eixos */
112 protected static final double AXIS_STROKE_FAC = 0.002;
113
114 /** Stroke básico dos eixos */
115 protected BasicStroke axis_stroke;
116
117 /** Disco do polo */
118 protected Ellipse2D.Double pole_disk;
119
120 /** Fator de proporção em relação ao tamanho horizontal da janela
121 * em coordenadas do mundo para tamanho de disco */
122 protected static final double DISK_SIZE_FAC = 0.01;
123
124 /** Tamanho de um disco */
125 protected double disk_size;
126
127 /** Disco do centro */
128 protected Ellipse2D.Double center_disk;
129
130 /** Fator de proporção em relação ao tamanho horizontal da janela
131 * em coordenadas do mundo para tamanho do disco do centro */
132 protected static final double CENTER_DISK_SIZE_FAC = 0.005;
133
134 /** Tamanho do disco do centro */
135 protected double center_disk_size;
136
137 /** Fator de proporção em relação ao tamanho horizontal da janela
138 * em coordenadas do mundo para stroke básico das linhas de tensões */
139 protected static final double STRSLINE_STROKE_FAC = 0.001;
140
141 /** Fator de proporção em relação ao tamanho horizontal da janela
142 * em coordenadas do mundo para stroke básico do tracejado das
143 * linhas de tensões */
144 protected static final double STRSLINE_STROKE_DASH_FAC = 0.01;
145
146 /** Vetor de especificação do espaçamento entre desenho opaco e
147 * transparente do tracejado das linhas de tensão */
148 protected float DASHp[];
149
150 /** Fator de proporção em relação ao tamanho horizontal da janela
151 * em coordenadas do mundo para stroke básico do tracejado das
152 * linhas de tensões correspondentes ao estado de tensão fornecido */
153 protected static final double STATESTRSLINE_STROKE_DASH_FAC = 0.02;
154
155 /** Vetor de especificação do espaçamento entre desenho opaco e
156 * transparente do tracejado das linhas das tensões correspondentes
157 * ao estado de tensão fornecido */
158 protected float DASHss[];
159
160 /** Stroke básico das linhas de tensões */
161 protected BasicStroke strsline_stroke;
162
163 /** Stroke básico das linhas de tensões do plano de tensões fornecido */
164 protected BasicStroke statestrsline_stroke;
165
166 /** Objeto plano para desenhar tensões em um plano */
167 protected MohrPlane plane;
168
169 /** Objeto arco para desenhar ângulos */
170 protected MohrArc arc;
171
172 /** Fator de proporção em relação ao tamanho horizontal da janela
173 * em coordenadas do mundo para stroke básico das setas */
174 protected static final double STRESS_ARROW_STROKE_FAC = 0.002;
175
176 /** Stroke básico das setas das tensões */
177 protected BasicStroke stress_arrow_stroke;
178
179 /** Fator de proporção em relação ao tamanho horizontal da janela
180 * em coordenadas do mundo para stroke básico das linhas dos planos */
181 protected static final double PLANE_FACE_STROKE_FAC = 0.0015;
182
183 /** Stroke básico das linhas dos planos */
184 protected BasicStroke plane_face_stroke;
185
186 /** Fonte adotado para desenho */
187 protected Font fnt;
188
189 /** Objeto linha para desenho de linhas auxiliares */
190
191 protected Line2D.Double auxline;
192
193 /** Fator de proporção em relação ao tamanho horizontal da janela
194 * em coordenadas do mundo para stroke básico das linhas auxiliares */
195 protected static final double AUXLINE_STROKE_FAC = 0.002;
196
197 /** Stroke básico das linhas auxiliares */
198 protected BasicStroke auxline_stroke;
199
200 /** Componente x de um vetor auxiliar */
201 protected static double auxvecx;
202
203 /** Componente y de um vetor auxiliar */
204 protected static double auxvecy;
205
206 /** Disco da tensão normal x do estado de tensões fornecido */
207 protected Ellipse2D.Double sigmax_disk;
208
209 /** Disco da tensão normal y do estado de tensões fornecido */
210 protected Ellipse2D.Double sigmay_disk;
211
212 /** Armazena a coordenada x corrente do mouse */
213 protected double last_x;
214
215 /** Armazena a coordenada y corrente do mouse */
216 protected double last_y;
217
218 /** Flag para botão do mouse pressionado */
219 protected boolean pressedInPoint;
220
221 /** Flag para botão do mouse pressionado */
222 protected MohrControls icon;
223
224 /** Centro do círculo de Mohr */
225 protected double center;
226
227 /** Ráio do círculo de Mohr */
228 protected double radius;
229
230 /** Diâmetro do círculo de Mohr */
231 protected double diameter;
232
233 /** Tensão normal na direção x */
234 protected double sigmax;
235
236 /** Tensão normal na direção y */
237 protected double sigmay;
238
239 /** Tensão de cisalhamento */
240 protected double tauxy;
241
242 /** Tensão principal máxima */
243 protected double sigma1;
244
245 /** Tensão principal mínima */
246 protected double sigma2;
247
248 /** Angulo do plano tensão principal máxima */
249 protected double thetap;
250
251 /** Tensão de cisalhamento máxima */
252 protected double taumax;
253
254 /** Coordenada x do pólo */
255 protected double poleX;
256
257 /** Coordenada y do pólo */
258 protected double poleY;
259
260 /** Angulo do plano inclinado */
261 protected double theta;
262
263 /** Tensão normal no plano inclinado */
264 protected double sigtheta;
265
266 /** Tensão de cisalhamento no plano inclinado */
267 protected double tautheta;
268
269
270 /*========================== Constructor =========================*/
271 /**
272 * Constructor: Especifica eixo Y no sentido para cima.
273 */
274 MohrCircleCanvas( MohrDriver driver )
275 {
276 super( UPWARD_Y );
277 this.driver = driver;
278
279 double fit_space;
280
281 fit_type = SHOW_ORIGIN;
282
283 type_sel = NONE_SEL;
284
285 setBackground( Color.white );
286
287 update_sizes( );
288
289 fit_space = sigaxis_len/20.0;
290
291 setWorld( sigaxis_start-fit_space, sigaxis_end+fit_space,
292 -(tauaxis_len+fit_space), tauaxis_len+fit_space );
293
294 ref_size = world_area.width;
295
296 circle = new Ellipse2D.Double( center-radius, -radius, diameter, diameter );
297
298 sigaxis = new Arrow2D( );
299 tauaxis = new Arrow2D( );
300
301 circle_stroke = new BasicStroke(
302 (float)(ref_size*CIRCLE_STROKE_FAC) );
303 axis_stroke = new BasicStroke( (float)(ref_size*AXIS_STROKE_FAC) );
304
305 disk_size = ref_size * DISK_SIZE_FAC;
306 pole_disk = new Ellipse2D.Double( poleX - (disk_size*0.5),
307 poleY - (disk_size*0.5),
308 disk_size, disk_size );
309
310 center_disk_size = ref_size * CENTER_DISK_SIZE_FAC;
311 center_disk = new Ellipse2D.Double( center - (center_disk_size*0.5),
312 0.0 - (center_disk_size*0.5),
313 center_disk_size, center_disk_size );
314
315 DASHp = new float[]{ (float)(ref_size*STRSLINE_STROKE_DASH_FAC) };
316 strsline_stroke = new BasicStroke( (float)(ref_size*STRSLINE_STROKE_FAC),
317 BasicStroke.CAP_BUTT,
318 BasicStroke.JOIN_MITER,
319 10.0f, DASHp, 0.0f );
320
321 DASHss = new float[]{ (float)(ref_size*STATESTRSLINE_STROKE_DASH_FAC) };
322 statestrsline_stroke = new BasicStroke( (float)(ref_size*AXIS_STROKE_FAC),
323 BasicStroke.CAP_BUTT,
324 BasicStroke.JOIN_MITER,
325 10.0f, DASHss, 0.0f );
326
327 stress_arrow_stroke = new BasicStroke(
328 (float)(ref_size*STRESS_ARROW_STROKE_FAC),
329 BasicStroke.CAP_BUTT,
330 BasicStroke.JOIN_MITER, 10.0f );
331 plane_face_stroke = new BasicStroke(
332 (float)(ref_size*PLANE_FACE_STROKE_FAC) );
333
334 plane = new MohrPlane( );
335
336 arc = new MohrArc( );
337
338 sigmax_disk = new Ellipse2D.Double( sigmax - (disk_size*0.5),
339 0.0 - (disk_size*0.5),
340 disk_size, disk_size );
341 sigmay_disk = new Ellipse2D.Double( sigmay - (disk_size*0.5),
342 0.0 - (disk_size*0.5),
343 disk_size, disk_size );
344
345 fnt = new Font( "Times New Roman", Font.ITALIC, 14 );
346
347 auxline = new Line2D.Double( );
348 auxline_stroke = new BasicStroke( (float)(ref_size*AUXLINE_STROKE_FAC) );
349 }
350
351 /*
352 ** ---------------------------------------------------------------
353 ** Private and Protected methods:
354 */
355
356 /*========================== udpate_sizes ===========================*/
357 /**
358 * Armazena em variaveis auxiliares as componentes de um vetor na
359 * direção e sentido dos dois pontos dados e com tamanho especificado.
360 */
361 protected static void resize_vector( double x0, double y0,
362 double x1, double y1,
363 double size )
364 {
365 double v_size = Math.sqrt( (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0) );
366 auxvecx = size * (x1-x0)/ v_size;
367 auxvecy = size * (y1-y0)/ v_size;
368 }
369
370 /*========================== udpate_sizes ===========================*/
371 /**
372 * Atualiza os tamanhos das variáveis de refência.
373 */
374 protected void update_sizes( )
375 {
376 center = driver.getSolver().Center();
377 radius = driver.getSolver().Radius();
378 diameter = 2.0 * radius;
379 sigmax = driver.getSolver().getSigmaX();
380 sigmay = driver.getSolver().getSigmaY();
381 tauxy = driver.getSolver().getTauXY();
382 sigma1 = driver.getSolver().Sigma1();
383 sigma2 = driver.getSolver().Sigma2();
384 thetap = driver.getSolver().ThetaP();
385 taumax = driver.getSolver().TauMax();
386 poleX = driver.getSolver().PoleX();
387 poleY = driver.getSolver().PoleY();
388 theta = driver.getSolver().getTheta();
389 sigtheta = driver.getSolver().SigmaTheta();
390 tautheta = driver.getSolver().TauTheta();
391
392 if( driver.getSolver().IsHydrostatic() )
393 {
394 sigaxis_start = 0.0;
395 sigaxis_end = 2.0*center;
396 sigaxis_len = sigaxis_end - sigaxis_start;
397 tauaxis_len = sigaxis_len * 0.3;
398 return;
399 }
400
401 if( fit_type == FIT_ON_CIRCLE )
402 {
403 sigaxis_start = sigma2;
404 sigaxis_end = sigma1;
405 }
406 else
407 {
408 if( sigma2 > 0.0 )
409 sigaxis_start = 0.0;
410 else
411 sigaxis_start = sigma2;
412
413 if( sigma1 > 0.0 )
414 sigaxis_end = sigma1;
415 else
416 sigaxis_end = 0.0;
417 }
418
419 sigaxis_len = sigaxis_end - sigaxis_start;
420 if( fit_type == FIT_ON_CIRCLE )
421 {
422 sigaxis_start -= 0.2*sigaxis_len;
423 sigaxis_end += 0.2*sigaxis_len;
424 }
425 else
426 {
427 if( sigma2 < 0.0 )
428 sigaxis_start -= 0.2*sigaxis_len;
429 else
430 sigaxis_start = 0.0;
431 if( sigma1 > 0.0 )
432 sigaxis_end += 0.2*sigaxis_len;
433 else
434 sigaxis_end = 0.0;
435 }
436 sigaxis_len = sigaxis_end - sigaxis_start;
437
438 tauaxis_len = 1.2 * radius;
439 }
440
441 /*============================= update_geom ============================*/
442 /**
443 * Atualiza parâmetros geométricos dos objetos do canvas.
444 */
445 protected void update_geom( )
446 {
447 circle.setFrame( center-radius, -radius, diameter, diameter );
448
449 circle_stroke = new BasicStroke(
450 (float)(ref_size*CIRCLE_STROKE_FAC) );
451 axis_stroke = new BasicStroke( (float)(ref_size*AXIS_STROKE_FAC) );
452
453 disk_size = ref_size * DISK_SIZE_FAC;
454 pole_disk.setFrame( poleX - (disk_size*0.5), poleY - (disk_size*0.5),
455 disk_size, disk_size );
456
457 center_disk_size = ref_size * CENTER_DISK_SIZE_FAC;
458 center_disk.setFrame( center - (center_disk_size*0.5),
459 0.0 - (center_disk_size*0.5),
460 center_disk_size, center_disk_size );
461
462 DASHp = new float[]{ (float)(ref_size*STRSLINE_STROKE_DASH_FAC) };
463 strsline_stroke = new BasicStroke( (float)(ref_size*STRSLINE_STROKE_FAC),
464 BasicStroke.CAP_BUTT,
465 BasicStroke.JOIN_MITER,
466 10.0f, DASHp, 0.0f );
467
468 DASHss = new float[]{ (float)(ref_size*STATESTRSLINE_STROKE_DASH_FAC) };
469 statestrsline_stroke = new BasicStroke( (float)(ref_size*AXIS_STROKE_FAC),
470 BasicStroke.CAP_BUTT,
471 BasicStroke.JOIN_MITER,
472 10.0f, DASHss, 0.0f );
473
474 stress_arrow_stroke = new BasicStroke(
475 (float)(ref_size*STRESS_ARROW_STROKE_FAC),
476 BasicStroke.CAP_BUTT,
477 BasicStroke.JOIN_MITER, 10.0f );
478 plane_face_stroke = new BasicStroke(
479 (float)(ref_size*PLANE_FACE_STROKE_FAC) );
480
481 sigmax_disk.setFrame( sigmax - (disk_size*0.5),
482 0.0 - (disk_size*0.5),
483 disk_size, disk_size );
484 sigmay_disk.setFrame( sigmay - (disk_size*0.5),
485 0.0 - (disk_size*0.5),
486 disk_size, disk_size );
487
488 auxline_stroke = new BasicStroke( (float)(ref_size*AUXLINE_STROKE_FAC) );
489 }
490
491 /*================================getTheta==============================*/
492 /**
493 * Esta função retorna o valor do ângulo que a linha (x-poleX,y-poleY)
494 * faz com a horizontal.
495 */
496 protected double getTheta( double x, double y )
497 {
498 double s;
499
500 s = Math.sqrt( (x-poleX) * (x-poleX) + (y-poleY) * (y-poleY) );
501 if( s < 0.001 )
502 {
503 if( Math.abs( poleX-center ) < 0.001 )
504 {
505 if( poleY > 0.0 )
506 return( Math.PI );
507 else
508 return( 0.0 );
509 }
510 else
511 {
512 if( poleX > center )
513 return( Math.atan2( -poleY, poleX-center ) );
514 else
515 return( Math.atan2( poleY, center-poleX ) );
516 }
517 }
518
519 return( Math.atan2( y-poleY, x-poleX ) );
520 }
521
522 /*===========================setSolverTheta==============================*/
523 /**
524 * Esta função atualiza o valor do ângulo do plano que gira.
525 */
526 protected void setSolverTheta( double angt )
527 {
528 driver.getSolver().setTheta( angt );
529 driver.update_draft( );
530 }
531
532 /*================================setSigmax==============================*/
533 /**
534 * Esta função atualiza o valor da tensão sigmax do
535 * estado de tensões corrente.
536 */
537 protected void setSigmax( double sigx )
538 {
539 driver.getSolver().setSigmaX( sigx );
540 driver.update_draft( );
541 }
542
543 /*================================setSigmay==============================*/
544 /**
545 * Esta função atualiza o valor da tensão sigmay do
546 * estado de tensões corrente.
547 */
548 protected void setSigmay( double sigy )
549 {
550 driver.getSolver().setSigmaY( sigy );
551 driver.update_draft( );
552 }
553
554 /*=================================setTauxy===============================*/
555 /**
556 * Esta função atualiza o valor da tensão tauxy do
557 * estado de tensões corrente.
558 */
559 protected void setTauxy( double txy )
560 {
561 driver.getSolver().setTauXY( txy );
562 driver.update_draft( );
563 }
564
565 /*============================MohrCircleSnapTo============================*/
566 /**
567 * Esta função atrai um dado ponto para o círculo de Mohr.
568 */
569 protected static Point2D.Double MohrCircleSnapTo(
570 double cx, double cy, double r,
571 Point2D.Double pt )
572 {
573 double s,t;
574 s = Math.sqrt((pt.x-cx)* (pt.x-cx) + (pt.y-cy)* (pt.y-cy));
575 if( s != 0 )
576 {
577 t = r/s;
578 pt.x = cx + t*(pt.x - cx);
579 pt.y = cy + t*(pt.y - cy);
580 }
581 return( pt );
582 }
583
584 /*================================= pickPoint==============================*/
585 /**
586 * Este método retorna verdadeiro para um dos pontos
587 * selecionados e seta o tipo do ponto selecionado.
588 */
589 protected boolean pickPoint( Point2D.Double pt )
590 {
591 double tol_fac = 0.08;
592 double tol = radius* tol_fac;
593 double x_point = sigtheta;
594 double y_point = tautheta;
595
596 if( (Math.abs(pt.x - sigtheta) <= tol) &&
597 (Math.abs(pt.y - tautheta) <= tol) &&
598 (vis_thetastrs) )
599 {
600 type_sel = THETA_PLANE_SEL;
601 return (true);
602 }
603 else if( (Math.abs(pt.x - sigmax) <= tol) &&
604 (Math.abs(pt.y + tauxy) <= tol) &&
605 (vis_statestrs) )
606 {
607 type_sel = TAUXY_SEL;
608 return(true);
609 }
610 else if( (Math.abs(pt.x - sigmay) <= tol) &&
611 (Math.abs(pt.y - tauxy) <= tol) &&
612 (vis_statestrs) )
613 {
614 type_sel = TAUYX_SEL;
615 return(true);
616 }
617 else if( (Math.abs(pt.x - sigmax) <= tol) &&
618 (Math.abs(pt.y - 0.0) <= tol) &&
619 (vis_statestrs) )
620 {
621 type_sel = SIGMAX_SEL;
622 return(true);
623 }
624 else if( (Math.abs(pt.x - sigmay) <= tol) &&
625 (Math.abs(pt.y - 0.0) <= tol) &&
626 (vis_statestrs) )
627 {
628 type_sel = SIGMAY_SEL;
629 return(true);
630 }
631
632 return (false);
633 }
634
635 /*===============================updatePointPos==============================*/
636 /**
637 * Esta função atualiza a posição do ponto selecionado de acordo
638 * com a posição do mouse.
639 */
640 protected void updatePointPos( Point2D.Double mouse_pos )
641 {
642 double X_new;
643 double Y_new;
644 double X_var;
645 double Y_var;
646 double sigx;
647 double sigy;
648 double txy;
649
650 if( type_sel == THETA_PLANE_SEL )
651 {
652 /*Snap to circle*/
653 mouse_pos = MohrCircleSnapTo( center, 0.0, radius, mouse_pos );
654
655 /* gets the new point position*/
656 X_new = mouse_pos.x;
657 Y_new = mouse_pos.y;
658
659 /*Update the angle theta, sigmatheta and tautheta*/
660 setSolverTheta( getTheta( X_new, Y_new ) );
661 }
662 else if( type_sel == TAUXY_SEL )
663 {
664 Y_var = -mouse_pos.y + last_y;
665 txy = tauxy + Y_var;
666 setTauxy( txy );
667 }
668 else if( type_sel == TAUYX_SEL )
669 {
670 Y_var = mouse_pos.y - last_y;
671 txy = tauxy + Y_var;
672 setTauxy( txy );
673 }
674 else if( type_sel == SIGMAX_SEL )
675 {
676 X_var = mouse_pos.x - last_x;
677 sigx = sigmax + X_var;
678 setSigmax( sigx );
679 }
680 else if( type_sel == SIGMAY_SEL )
681 {
682 X_var = mouse_pos.x - last_x;
683 sigy = sigmay + X_var;
684 setSigmay( sigy );
685 }
686 }
687
688 /*
689 ** ---------------------------------------------------------------
690 ** Public methods:
691 */
692
693 /*=============================== update =============================*/
694 /**
695 * Atualiza o canvas alterando a janela de visualização.
696 */
697 public void update( )
698 {
699 double fit_space;
700
701 update_sizes( );
702
703 fit_space = sigaxis_len/20.0;
704
705 setWorld( sigaxis_start-fit_space, sigaxis_end+fit_space,
706 -(tauaxis_len+fit_space), tauaxis_len+fit_space );
707
708 ref_size = world_area.width;
709
710 update_geom( );
711 repaint( );
712 }
713
714 /*========================== udpate_draft ===========================*/
715 /**
716 * Atualiza o canvas sem alterar a janela de visualização.
717 */
718 public void update_draft( )
719 {
720 update_sizes( );
721 update_geom( );
722 repaint( );
723 }
724
725 /*=============================== redraw =============================*/
726 /**
727 * Redisplay method.
728 * This method is called every time the canvas is updated.
729 * Client's concrete class must implement it.
730 * @param g is the 2D graphics context that the client uses to display
731 */
732 public void redraw( Graphics2D g )
733 {
734 double pi = Math.PI;
735 double arrow_len = sigaxis_len/20;
736 double arrow_factx = arrow_len/10;
737 double offset = driver.getSolver().Radius() * 0.15;
738 double fact = arrow_len/10.0;
739 double theta_radius;
740 double theta_shift;
741 double theta_p0x;
742 double theta_p0y;
743 double theta_p1x;
744 double theta_p1y;
745
746 g.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
747 RenderingHints.VALUE_ANTIALIAS_ON );
748
749 g.setFont( fnt );
750
751 /* Ajusta tamanho do eixo de tensões de cisalhamento */
752 tauaxis_len = (world_area.height*0.5) / 1.1;
753
754 /* Ajusta tamanho do eixos de tensões normais */
755 if( sigaxis_end <= 0.0 )
756 {
757 sigaxis_end += 0.025 * sigaxis_len;
758 sigaxis_len = sigaxis_end - sigaxis_start;
759 }
760
761 /* Desenha os eixos */
762 g.setColor( Color.black );
763 g.setStroke( axis_stroke );
764 sigaxis.DrawArrow( g, sigaxis_start, 0.0, 0.0, sigaxis_len,
765 Arrow2D.SIDE_LEAD, 7.0*pi/18.0, tauaxis_len/30.0);
766 setTextAlignment( NORTH_EAST );
767 drawString( "\u03C3", sigaxis_end+fact, -fact );
768 if( (sigaxis_start <= 0.0) && (sigaxis_end >= 0.0) )
769 {
770 tauaxis.DrawArrow( g, 0.0, 0.0, pi/2, tauaxis_len, Arrow2D.SIDE_LEAD,
771 7.0*pi/18.0, tauaxis_len/30.0 );
772 setTextAlignment( EAST );
773 drawString( "\u03C4", -fact, tauaxis_len+fact );
774 }
775
776 /* Trata caso especial de estado hidrostático de tensões */
777 if( driver.getSolver().IsHydrostatic() )
778 {
779 g.fill( center_disk );
780 setTextAlignment( NORTH );
781 drawString( "Estado Hidrostático de Tensões", center, -fact );
782 setTextAlignment( BASE_LEFT );
783 drawString( "\u03C3x", sigmax+fact, fact );
784 setTextAlignment( BASE_RIGHT );
785 drawString( "\u03C3y", sigmay-fact, fact );
786 return;
787 }
788
789 /* Define cor e stroke para desenhar as linhas auxiliares */
790 g.setColor( Color.gray.brighter() );
791 g.setStroke( auxline_stroke );
792
793 if( Math.abs( tauxy ) > 0.01 )
794 {
795 /* Desenha linha referente ao Sigma X */
796 auxline.setLine( sigmax, 0.0, sigmax, -tauxy );
797 g.draw( auxline );
798
799 /* Desenha linha referente ao Sigma Y */
800 auxline.setLine( sigmay, 0.0, sigmay, tauxy );
801 g.draw( auxline );
802
803 /* Desenha linha que liga Sigma X a Sigma Y */
804 auxline.setLine( sigmay, tauxy, sigmax, -tauxy );
805 g.draw( auxline );
806 }
807
808 if( vis_principalstrs )
809 {
810 /* Desenha linha referente ao Tau max */
811 auxline.setLine( center, 0.0, center, taumax );
812 g.draw( auxline );
813
814 if( Math.abs( thetap ) > 0.01 )
815 {
816 /* Desenha angulo referente à tensão principal máxima (thetap) */
817 theta_radius = radius*0.25;
818 theta_shift = radius*0.05;
819 theta_p0x = poleX + theta_radius + theta_shift;
820 theta_p0y = -tauxy;
821 if( ((poleX > sigmax) && !vis_thetastrs) ||
822 (!vis_statestrs && !vis_thetastrs) )
823 {
824 auxline.setLine( poleX, poleY, theta_p0x, theta_p0y );
825 g.draw( auxline );
826 }
827 if( poleY <= 0.0 )
828 {
829 theta_p1x = sigma1;
830 theta_p1y = 0.0;
831 }
832 else
833 {
834 resize_vector( poleX, poleY, sigma1, 0.0, theta_radius + theta_shift );
835 theta_p1x = poleX - auxvecx;
836 theta_p1y = poleY - auxvecy;
837 auxline.setLine( poleX, poleY, theta_p1x, theta_p1y );
838 g.draw( auxline );
839 }
840 arc.DrawArc( this, g, Color.gray.brighter(),
841 poleX, poleY, theta_p0x, theta_p0y, theta_p1x, theta_p1y,
842 theta_radius, "\u03B8p", theta_shift, auxline_stroke );
843
844 /* Desenha central angulo 2thetap */
845 g.setColor( Color.gray.brighter() );
846 arc.DrawArc( this, g, Color.gray.brighter(),
847 center, 0.0, sigmax, -tauxy, sigma1, 0.0,
848 theta_radius, "2\u03B8p", theta_shift, auxline_stroke );
849 }
850 }
851
852 if( vis_thetastrs )
853 {
854 /* Desenha angulo theta reference ao polo */
855 g.setColor( Color.gray.brighter() );
856 theta_radius = radius*0.35;
857 theta_shift = radius*0.05;
858 theta_p0x = poleX + theta_radius + theta_shift;
859 theta_p0y = -tauxy;
860 if( (poleX >= sigmax) || !vis_statestrs )
861 {
862 if( theta > 0.01 )
863 {
864 auxline.setLine( poleX, poleY, theta_p0x, theta_p0y );
865 g.draw( auxline );
866 }
867 }
868 if( Math.sqrt( (poleX-sigtheta)*(poleX-sigtheta) +
869 (poleY-tautheta)*(poleY-tautheta) ) < 0.001 )
870 {
871 if( ((Math.abs( poleX-center ) < 0.001) && (poleY > 0.0)) ||
872 (poleX > center) )
873 {
874 resize_vector( 0.0, 0.0, -poleY, poleX-center, theta_radius+theta_shift );
875 theta_p1x = poleX + auxvecx;
876 theta_p1y = poleY + auxvecy;
877 }
878 else
879 {
880 resize_vector( 0.0, 0.0, poleY, center-poleX, theta_radius+theta_shift );
881 theta_p1x = poleX + auxvecx;
882 theta_p1y = poleY + auxvecy;
883 if( theta > 0.01 )
884 {
885 auxline.setLine( poleX, poleY, theta_p1x, theta_p1y );
886 g.draw( auxline );
887 }
888 }
889 }
890 else
891 {
892 resize_vector( poleX, poleY, sigtheta, tautheta, theta_radius+theta_shift );
893 if( tautheta > poleY )
894 {
895 theta_p1x = poleX + auxvecx;
896 theta_p1y = poleY + auxvecy;
897 }
898 else
899 {
900 theta_p1x = poleX - auxvecx;
901 theta_p1y = poleY - auxvecy;
902 if( theta > 0.01 )
903 {
904 auxline.setLine( poleX, poleY, theta_p1x, theta_p1y );
905 g.draw( auxline );
906 }
907 }
908 }
909 if( theta > 0.01 )
910 {
911 arc.DrawArc( this, g, Color.gray.brighter(),
912 poleX, poleY, theta_p0x, theta_p0y, theta_p1x, theta_p1y,
913 theta_radius, "\u03B8", theta_shift, auxline_stroke );
914 }
915
916 /* Desenha o angulo central 2theta */
917 g.setColor( Color.gray.brighter() );
918 auxline.setLine( center, 0.0, sigtheta, tautheta );
919 g.draw( auxline );
920 if( theta > 0.01 )
921 {
922 if( theta < (pi-0.01) )
923 arc.DrawArc( this, g, Color.gray.brighter(),
924 center, 0.0, sigmax, -tauxy, sigtheta, tautheta,
925 theta_radius, "2\u03B8", theta_shift, auxline_stroke );
926 else
927 arc.DrawCircle( this, g, Color.gray.brighter(),
928 center, 0.0, sigmax, -tauxy,
929 theta_radius, "2\u03B8", theta_shift, auxline_stroke );
930 }
931
932 /* Desenha linha referente ao Tau theta */
933 auxline.setLine( sigtheta, 0.0, sigtheta, tautheta );
934 g.setColor( Color.black );
935 g.draw( auxline );
936 }
937
938 /* Desenha o círculo */
939 g.setColor( Color.black );
940 g.draw( circle );
941
942 /* Desenha o centro */
943 g.fill( center_disk );
944
945 if( vis_principalstrs )
946 {
947 /* Desenha plano com tensão principal máxima */
948 plane.DrawPlane( this, g, Color.red, center, poleX, poleY,
949 sigma1, 0.0, "\u03C31", " ",
950 offset, arrow_len, stress_arrow_stroke, strsline_stroke,
951 plane_face_stroke, disk_size );
952
953 /* Desenha plano com tensão principal mínima */
954 plane.DrawPlane( this, g, Color.red.darker(), center, poleX, poleY,
955 sigma2, 0.0, "\u03C32", " ",
956 offset, arrow_len, stress_arrow_stroke, strsline_stroke,
957 plane_face_stroke, disk_size );
958
959 /* Escreve os textos das tensões principais */
960 g.setColor( Color.black );
961 setTextAlignment( NORTH_WEST );
962 drawString( "\u03C31", sigma1+fact, -fact );
963 setTextAlignment( NORTH_EAST );
964 drawString( "\u03C32", sigma2-fact, -fact );
965 setTextAlignment( BASE_LEFT );
966 drawString( "\u03C4m", center+fact, taumax/2.0 );
967 }
968
969 if( vis_statestrs )
970 {
971 /* Desenha tensões no plano com normal na direcao x */
972 plane.DrawPlane( this, g, Color.blue.darker(), center, poleX, poleY,
973 sigmax, -tauxy, "\u03C3x", "\u03C4xy",
974 offset, arrow_len, stress_arrow_stroke,
975 statestrsline_stroke, plane_face_stroke,disk_size );
976
977 /* Desenha tensões no plano com normal na direcao y */
978 plane.DrawPlane( this, g, Color.blue.brighter(), center, poleX, poleY,
979 sigmay, tauxy, "\u03C3y", "\u03C4xy",
980 offset, arrow_len, stress_arrow_stroke,
981 statestrsline_stroke, plane_face_stroke,disk_size );
982
983 /* Desenha os discos dos pontos manipuláveis de sigmax e sigmay */
984 g.setColor( Color.blue.darker() );
985 g.fill( sigmax_disk );
986 g.setColor( Color.blue.brighter() );
987 g.fill( sigmay_disk );
988 g.setColor( Color.black );
989 g.setStroke( plane_face_stroke );
990 g.draw( sigmax_disk );
991 g.draw( sigmay_disk );
992 }
993
994 if( vis_thetastrs )
995 {
996 /* Desenha tensões no plano theta */
997 plane.DrawPlane( this, g, Color.green.darker(), center, poleX, poleY,
998 sigtheta, tautheta, "\u03C3\u03B8", "\u03C4\u03B8",
999 offset, arrow_len, stress_arrow_stroke, strsline_stroke,
1000 plane_face_stroke, disk_size );
1001
1002 /* Escreve os textos das tensões no plano theta */
1003 g.setColor( Color.black );
1004 setTextAlignment( BASE_LEFT );
1005 drawString( "\u03C3\u03B8", sigtheta+fact, fact );
1006 setTextAlignment( BASE_RIGHT );
1007 drawString( "\u03C4\u03B8", sigtheta-fact, tautheta/2.0 );
1008 }
1009
1010 /* Desenha o pólo */
1011 if( vis_statestrs || vis_thetastrs || vis_principalstrs )
1012 {
1013 g.setColor( Color.black );
1014 g.fill( pole_disk );
1015 }
1016
1017 /* Escreve os textos das tensões do estado corrente */
1018 setTextAlignment( BASE_LEFT );
1019 drawString( "\u03C3x", sigmax+fact, fact );
1020 setTextAlignment( BASE_RIGHT );
1021 drawString( "\u03C3y", sigmay-fact, fact );
1022 if (tauxy != 0.0)
1023 {
1024 setTextAlignment( BASE_RIGHT );
1025 drawString( "-\u03C4xy", sigmax-fact, -tauxy/2.0 );
1026 }
1027 if (tauxy != 0.0)
1028 {
1029 setTextAlignment( BASE_LEFT );
1030 drawString( "\u03C4xy", sigmay+fact, tauxy/2.0 );
1031 }
1032 }
1033
1034
1035 /**
1036 * Handles the event of mouse motion in canvas with no
1037 * button pressed.
1038 */
1039 public void mouseMoved (MouseEvent e)
1040 {
1041 if( raster_area == null )
1042 return;
1043 Point2D.Double mouse_pos = raster2world( e.getX(),e.getY() );
1044 if( pickPoint( mouse_pos ) ) {
1045 setCursor( Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR ) );
1046 }
1047 else{
1048 setCursor( Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR ) );
1049 }
1050 }
1051
1052 /**
1053 * Handles the event of the user pressing down the mouse button.
1054 */
1055 public void mousePressedWC( MouseEvent e, Point2D.Double mouse_pos )
1056 {
1057 last_x = mouse_pos.x;
1058 last_y = mouse_pos.y;
1059 if (pickPoint(mouse_pos))
1060 {
1061 pressedInPoint = true;
1062 setCursor( Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR) );
1063 }
1064 }
1065
1066 /**
1067 * Handles the event of a user dragging the mouse while holding
1068 * down the mouse button.
1069 */
1070 public void mouseDraggedWC( MouseEvent e, Point2D.Double mouse_pos )
1071 {
1072 if( pressedInPoint)
1073 {
1074 updatePointPos(mouse_pos);
1075 }
1076 last_x = mouse_pos.x;
1077 last_y = mouse_pos.y;
1078 }
1079
1080 /**
1081 * Handles the event of a user releasing the mouse button.
1082 */
1083 public void mouseReleasedWC( MouseEvent e, Point2D.Double mouse_pos )
1084 {
1085 if( pressedInPoint )
1086 {
1087 updatePointPos( mouse_pos );
1088 driver.update( );
1089 }
1090 pressedInPoint = false;
1091 type_sel = NONE_SEL;
1092 }
1093
1094 /**
1095 * Especifica tipo de ajuste de janela.
1096 */
1097 public void setFitType( int fit_type )
1098 {
1099 this.fit_type = fit_type;
1100 }
1101
1102 /**
1103 * Obtem o tipo corrente de ajuste de janela.
1104 */
1105 public int getFitType( )
1106 {
1107 return( fit_type );
1108 }
1109
1110 /**
1111 * Especifica visibilidade do estado de tensões corrente.
1112 */
1113 public void setVisStateStrs( boolean on_off )
1114 {
1115 vis_statestrs = on_off;
1116 }
1117
1118 /**
1119 * Especifica visibilidade das tensões principais.
1120 */
1121 public void setVisPrincipalStrs( boolean on_off )
1122 {
1123 vis_principalstrs = on_off;
1124 }
1125
1126 /**
1127 * Especifica visibilidade das tensões no plano inclinado.
1128 */
1129 public void setVisThetaStrs( boolean on_off )
1130 {
1131 vis_thetastrs = on_off;
1132 }
1133 }
1134