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