1 // (c) NPAC 2 // Author: Mehmet Sen at NPAC 3 // Note : This applet is written based on the first version which is 4 // implemented by Ozgur Balsoy and Mehmet Sen. 5 // 6 import java.applet.*; 7 import java.awt.*; 8 import java.util.*; 9 //*******************************************************************// 10 // APPLET *// 11 //*******************************************************************// 12 13 public class GridApplet extends Applet { 14 ControlPanel cp; 15 public void init() { 16 Label status = new Label("Welcome!", Label.CENTER); 17 status.setBackground(Color.pink); 18 GridCanvas canvas = new GridCanvas(status,getImage(getDocumentBase(),"grenbull.gif"),getImage(getDocumentBase(),"redbull.gif")); 19 cp= new ControlPanel(canvas, status); 20 21 setLayout(new BorderLayout()); 22 23 add("North", cp); 24 add("Center", canvas); 25 add("South", status); 26 } 27 public void start() 28 { 29 cp.cellMode.showUp(); 30 } 31 } 32 //************************************************************************ 33 // Control Panel 34 //*******************************************************************/ 35 36 class ControlPanel extends Panel { 37 38 int MAXLINES=20; 39 public choiceCanvas cellMode ; 40 GridCanvas canvas; 41 Label statusLine; 42 Choice rows, cols; 43 // Choice cellMode; 44 public ControlPanel(GridCanvas canvas, Label statusLine) { 45 //setBackground(Color.gray); 46 //setForeground(Color.yellow); 47 48 this.canvas = canvas; 49 this.statusLine = statusLine; 50 this.cellMode=new choiceCanvas(canvas); 51 52 rows=new Choice(); 53 cols=new Choice(); 54 for(int i=1; i<MAXLINES; i++) { 55 rows.addItem(Integer.toString(i)); 56 cols.addItem(Integer.toString(i)); 57 } 58 //cellMode =new Choice(); 59 //cellMode.addItem("Brick"); 60 //cellMode.addItem("Left Brace"); 61 //cellMode.addItem("Right Brace"); 62 63 setLayout(new GridLayout(2,5)); 64 65 add(new Label("Rows: ", Label.RIGHT)); 66 add(rows); 67 add(new Label(" CELL MODE ", Label.LEFT)); 68 //add(cellMode,Label.CENTER); 69 //add(canvas); 70 71 add(new Button("New")); 72 add(new Button("Graph")); 73 74 add(new Label("Columns: ", Label.RIGHT)); 75 add(cols); 76 add(cellMode); 77 78 //add(mymenu); 79 80 81 add(new Button("Check")); 82 add(new Button("Back")); 83 } 84 85 public boolean action(Event evt, Object what) { 86 if(evt.target instanceof Button) { 87 String s=(String)what; 88 statusLine.setText(s); 89 if(s.equals("New")) { 90 canvas.draw(rows.getSelectedIndex()+1, 91 cols.getSelectedIndex()+1); 92 } else if(s.equals("Check")) { 93 canvas.check(); 94 } else if(s.equals("Back")) { 95 canvas.back(); 96 }else if(s.equals("Graph")) { 97 canvas.graph(); 98 } 99 return true; 100 } 101 //else if ( evt.target instanceof Choice) { 102 // String s=(String) what; 103 //canvas.setCellMode(s); 104 // return true; 105 //} 106 return false; 107 } 108 109 } 110 //************************************************************************ 111 // CANVAS 112 //*******************************************************************/ 113 class GridCanvas extends Canvas { 114 int WHITE=0,GRAY=2,BLACK=5,CYAN=34; 115 int LEFT=1,RIGHT=2,BOTH=3,NONE=0; 116 int UNDEFINED=-111; 117 118 int visits=0; 119 int sccvisits=0; 120 int component=0; 121 int dir=1; 122 123 GraphComponent[] finish; 124 GraphComponent[] strongConnComp; 125 126 int GRID=1; 127 int GRAPH=0; 128 int BRICK=0,LEFT_BRACE=1,RIGHT_BRACE=2; 129 int displayMode=GRID; 130 int cellMode=BRICK; 131 Label statusLine; 132 double MARGINS = 0.15; 133 Image ballg; 134 Image ballr; 135 boolean rigid=false; 136 int rows, cols, length; 137 Point gridCorner; 138 GraphComponent[] rowComps, colComps; 139 GridCell[][] cells; 140 boolean gridExist = false; 141 142 int startRow,startCol; //internal usage, no meaning 143 144 public GridCanvas(Label statusLine,Image ballg,Image ballr) { 145 this.ballg=ballg; 146 this.ballr=ballr; 147 this.statusLine = statusLine; 148 } 149 150 public void setCellMode(int mode) { //String mode){ 151 this.cellMode=mode; 152 //if(mode.equals("Brick")) 153 // cellMode=BRICK; 154 //else if (mode.equals("Left Brace")) 155 // cellMode=LEFT_BRACE; 156 //else if (mode.equals("Right Brace")) 157 // cellMode=RIGHT_BRACE; 158 } 159 public void draw(int rows, int cols) { 160 Graphics g=getGraphics(); 161 g.drawImage(ballg,-30,-30,null); 162 g.drawImage(ballr,-60,-60,null); 163 g.dispose(); 164 // asctual statrt 165 166 displayMode=GRID; 167 statusLine.setText("Drawing " + rows + " by " + cols + " grid."); 168 cells=new GridCell[rows][cols]; 169 170 171 rowComps = new GraphComponent[rows]; 172 for(int i=0; i<rows; i++) { 173 rowComps[i] = new GraphComponent( i ); 174 rowComps[i].setRowType(); 175 } 176 177 colComps = new GraphComponent[cols]; 178 for(int i=0; i<cols; i++){ 179 colComps[i] = new GraphComponent( i ); 180 colComps[i].setColType(); 181 } 182 183 int width = (int)(size().width * (1.0 - MARGINS * 2.0)); 184 int height = (int)(size().height * (1.0 - MARGINS * 2.0)); 185 length = Math.min( width / cols, height / rows); 186 187 gridCorner=new Point((size().width - length * cols) / 2, 188 (size().height - length * rows) / 2); 189 190 for(int r=0; r<rows; r++) 191 for(int c=0; c<cols; c++) 192 cells[r][c] = new GridCell(gridCorner.x + c * length, 193 gridCorner.y + r * length, 194 length, r, c ); 195 this.rows = rows; 196 this.cols = cols; 197 gridExist = true; 198 repaint(); 199 } 200 201 public GraphComponent calculateComponentOLD(){ 202 GraphComponent[] comp=new GraphComponent[cols]; 203 for(int c=0; c<cols; c++) { 204 comp[c]=new GraphComponent(colComps[c]); 205 } 206 for(int r=0; r<rows; r++) { // finds individual components 207 Vector v=rowComps[r].getCells(); 208 if(!v.isEmpty()) { 209 GridCell c=(GridCell)(v.firstElement()); 210 for(Enumeration e=rowComps[r].getCells().elements(); e.hasMoreElements(); ) { 211 212 GridCell cell= (GridCell)(e.nextElement()); 213 214 int firstElementID = comp[c.colIndex].ID; 215 int currentCellID = comp[cell.colIndex].ID; 216 217 comp[c.colIndex].merge(comp[cell.colIndex]); 218 219 int greatID = Math.max(firstElementID, currentCellID ); 220 221 for(int j=0; j<cols; j++) 222 if(comp[j].ID == greatID) 223 if( firstElementID < currentCellID ) 224 comp[j] = comp[c.colIndex]; 225 else 226 comp[j] = comp[cell.colIndex]; 227 } 228 } 229 } 230 for(int i=0;i<cols;i++) 231 if ( !comp[i].getCells().isEmpty()) { 232 return comp[i]; 233 } 234 return null; 235 } 236 //***************************************************************// 237 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 238 public void calculateComponent(){ 239 240 /// .... initialize for the Depth First Search .... ///// 241 242 for(int c=0; c<cols; c++) { 243 colComps[c].color=WHITE; 244 colComps[c].rigid=false; 245 colComps[c].rotation=null; 246 } 247 for(int r=0; r<rows; r++) { 248 rowComps[r].color=WHITE; 249 rowComps[r].rigid=false; 250 rowComps[r].rotation=null; 251 } 252 253 strongConnComp= new GraphComponent[cols+rows]; 254 finish= new GraphComponent[cols+rows]; 255 component=0; 256 visits=0; 257 258 /// do Depth First Search 259 for(int c=0; c<cols; c++) 260 if (colComps[c].color==WHITE) { 261 visits=0; 262 DFSforward(colComps[c]); 263 findStrCCs(); 264 } 265 for(int r=0; r<rows; r++) 266 if (rowComps[r].color==WHITE){ 267 DFSforward(rowComps[r]); 268 findStrCCs(); 269 } 270 } //calculateComponent() 271 272 273 274 public void findStrCCs() 275 { 276 /// .... initialize for the Depth First Search .... ///// 277 for(int i=0; i<visits; i++) { 278 finish[i].color=WHITE; 279 } 280 281 for(int i=visits-1;i>=0;i--) { 282 if (finish[i].color==WHITE) { 283 sccvisits=0; 284 //System.out.println("-bc--------->"+(1+finish[i].ID)+finish[i].colType() ); 285 DFSbackward(finish[i]); 286 if (sccvisits > 1) { 287 // System.out.println("OLAY"); 288 Rotate rot=new Rotate(UNDEFINED); 289 rot.id=component++; 290 for (int a=0;a<sccvisits;a++) { 291 strongConnComp[a].rigid=true; 292 strongConnComp[a].rotation=rot; 293 } 294 } 295 } 296 } 297 if (sccvisits==rows+cols) 298 rigid=true; 299 else rigid=false; 300 } 301 public void DFSforward(GraphComponent gc) 302 { 303 gc.color=GRAY; 304 Vector v=gc.getCells(); 305 for(Enumeration e=v.elements(); e.hasMoreElements(); ) { 306 GridCell cell= (GridCell)(e.nextElement()); 307 if (gc.rowType() && cell.rightBrace() && colComps[cell.colIndex].color==WHITE ) 308 DFSforward(colComps[cell.colIndex]); 309 else if (gc.colType() && cell.leftBrace() && rowComps[cell.rowIndex].color==WHITE ) 310 DFSforward(rowComps[cell.rowIndex]); 311 } 312 gc.color=BLACK; 313 gc.cmpcolor=GRAY; 314 finish[visits]=gc; 315 visits++; 316 } 317 318 public void DFSbackward(GraphComponent gc) 319 { 320 gc.color=GRAY; 321 Vector v=gc.getCells(); 322 for(Enumeration e=v.elements(); e.hasMoreElements(); ) { 323 GridCell cell= (GridCell)(e.nextElement()); 324 if (gc.rowType()&&cell.leftBrace() && colComps[cell.colIndex].color==WHITE&& colComps[cell.colIndex].cmpcolor==GRAY ) 325 DFSbackward(colComps[cell.colIndex]); 326 else if (gc.colType() && cell.rightBrace() && rowComps[cell.rowIndex].color==WHITE && rowComps[cell.rowIndex].cmpcolor==GRAY ) 327 DFSbackward(rowComps[cell.rowIndex]); 328 } 329 gc.color=BLACK; 330 gc.cmpcolor=BLACK; 331 strongConnComp[sccvisits]=gc; 332 sccvisits++; 333 } 334 //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 335 // assume only strong conn. comp are checked ,i.e., coming in the parameter 336 public void find_pzf_ngf(GraphComponent gc) 337 { 338 //if (gc.rotation==null) { 339 // Rotate rt=new Rotate(UNDEFINED); 340 // gc.rotation=rt; 341 //} 342 343 Vector v=gc.getCells(); 344 for(Enumeration e=v.elements(); e.hasMoreElements(); ) { 345 GridCell cell= (GridCell)(e.nextElement()); 346 347 if ( gc.rotation.negatif&&gc.rotation.pozitif) /// break the loop 348 return; 349 350 if (rowComps[cell.rowIndex].rotation!=gc.rotation) { 351 if (cell.leftBrace() ) 352 gc.rotation.negatif=true; 353 else 354 gc.rotation.pozitif=true; 355 } 356 else if (colComps[cell.colIndex].rotation!=gc.rotation){ 357 if (cell.leftBrace() ) 358 gc.rotation.pozitif=true; 359 else 360 gc.rotation.negatif=true; 361 } 362 } 363 } 364 365 public void pzf_2_my_followers(GraphComponent gc) 366 { 367 gc.color=CYAN; 368 if (gc.rotation==null) { 369 Rotate rt=new Rotate(UNDEFINED); 370 gc.rotation=rt; 371 } 372 gc.rotation.pozitif=true; // THINK ABOUT LATER 373 gc.rotation.negatif=false; // THINK ABOUT LATER 374 375 Vector v=gc.getCells(); 376 for(Enumeration e=v.elements(); e.hasMoreElements(); ) { 377 GridCell cell= (GridCell)(e.nextElement()); 378 if (gc.rowType() && cell.rightBrace() && colComps[cell.colIndex].color!=CYAN ) 379 pzf_2_my_followers(colComps[cell.colIndex]); 380 else if (gc.colType() && cell.leftBrace() && rowComps[cell.rowIndex].color!=CYAN ) 381 pzf_2_my_followers(rowComps[cell.rowIndex]); 382 } 383 } 384 public void find_simple_pzf_ngf(GraphComponent gc) 385 { 386 if (gc.rotation==null) { 387 Rotate rt=new Rotate(UNDEFINED); 388 gc.rotation=rt; 389 } 390 391 Vector v=gc.getCells(); 392 for(Enumeration e=v.elements(); e.hasMoreElements(); ) { 393 GridCell cell= (GridCell)(e.nextElement()); 394 395 if ( gc.rotation.negatif&&gc.rotation.pozitif) /// break the loop 396 return; 397 if ( gc.colType() ) { 398 if (cell.leftBrace() ) 399 gc.rotation.negatif=true; 400 else 401 gc.rotation.pozitif=true; 402 } 403 else { 404 if (cell.leftBrace() ) 405 gc.rotation.pozitif=true; 406 else 407 gc.rotation.negatif=true; 408 } 409 410 411 } 412 } 413 414 public void calculateDirections(){ 415 boolean alternated=true; 416 417 for(int c=0; c<cols; c++) { 418 if (!colComps[c].rigid ) 419 find_simple_pzf_ngf(colComps[c]); 420 } 421 for(int r=0; r<rows; r++) { 422 if (!rowComps[r].rigid ) 423 find_simple_pzf_ngf(rowComps[r]); 424 } 425 426 // ********** 427 for(int r=0; r<rows; r++) { 428 if (rowComps[r].rigid && !(rowComps[r].rotation.pozitif && rowComps[r].rotation.negatif)) { 429 find_pzf_ngf(rowComps[r]); 430 ///System.out.println(rowComps[r].rotation.pozitif+" "+rowComps[r].rotation.negatif); 431 432 } 433 } 434 for(int c=0; c<cols; c++) { 435 if (colComps[c].rigid && ! (colComps[c].rotation.pozitif && colComps[c].rotation.negatif)) { 436 find_pzf_ngf(colComps[c]); 437 } 438 ///System.out.println(colComps[c].rotation.pozitif+" + - "+colComps[c].rotation.negatif); 439 440 } 441 442 443 for(int c=0; c<cols; c++) { 444 if (colComps[c].rigid &&!colComps[c].rotation.pozitif && !colComps[c].rotation.negatif) { 445 colComps[c].rotation.pozitif=alternated; 446 colComps[c].rotation.negatif=!alternated; 447 alternated=!alternated; 448 } 449 /// System.out.println("--->"+colComps[c].rotation.pozitif+" + - "+colComps[c].rotation.negatif); 450 } 451 452 // ********** 453 for(int c=0; c<cols; c++) { 454 if (colComps[c].rigid &&colComps[c].rotation.pozitif && colComps[c].rotation.negatif) 455 { pzf_2_my_followers(colComps[c]); 456 colComps[c].rotation.negatif=false; 457 } 458 } 459 for(int r=0; r<rows; r++) { 460 if (rowComps[r].rigid && rowComps[r].rotation.pozitif && rowComps[r].rotation.negatif) 461 { pzf_2_my_followers(rowComps[r]); 462 rowComps[r].rotation.negatif=false; 463 } 464 } 465 /* 466 for(int c=0; c<cols; c++) { 467 if (colComps[c].rotation.pozitif && colComps[c].rotation.negatif) 468 System.out.println("col +-"+(c+1)); 469 } 470 for(int r=0; r<rows; r++) { 471 if ( rowComps[r].rotation.pozitif && rowComps[r].rotation.negatif) 472 System.out.println("row +-"+(r+1)); 473 } 474 */ 475 } 476 477 478 public void check(){ 479 if ( !gridExist ) { 480 statusLine.setText("Check : Please define the grid first!"); 481 return; 482 } 483 displayMode=GRID; 484 calculateComponent(); 485 calculateDirections(); 486 487 Graphics g=getGraphics(); 488 for(int k=0; k<5; k++) { 489 animate(k*3); 490 paint(g); 491 // try { 492 //Thread.sleep(200); 493 // } 494 // catch(InterruptedException e) {}; 495 } 496 g.dispose(); 497 498 // check the rigidity 499 if (rigid) 500 statusLine.setText("RIGID"); 501 else statusLine.setText("NOT rigid"); 502 } 503 504 505 public int getMyDirection(GraphComponent gc,int defaultd) { 506 if (gc.rotation==null) 507 System.out.println("BIG MISTAKE"); 508 else if (gc.rotation.pozitif&&gc.rotation.negatif) 509 return 0; 510 else if (!gc.rotation.pozitif&&!gc.rotation.negatif) 511 return defaultd; 512 else if (gc.rotation.pozitif) 513 return -1; 514 else if (gc.rotation.negatif) 515 return 1; 516 return 0; 517 } 518 519 520 public void animate(int angle){ 521 int direction=-1; 522 523 cells[0][0].updateAngle(angle); 524 cells[0][0].place(gridCorner); 525 526 direction=getMyDirection(colComps[0],direction*-1); 527 if ( direction !=0 ) 528 cells[0][0].rotateTop(null,direction); 529 direction=getMyDirection(rowComps[0],direction*-1); 530 if ( direction !=0 ) 531 cells[0][0].rotateLeft(null,direction); 532 533 534 for(int i=1; i<cols; i++) { 535 direction=getMyDirection(colComps[i],direction*-1); 536 if ( direction !=0 ) 537 cells[0][i].rotateTop(cells[0][i-1],direction); 538 else cells[0][i].translateTop(cells[0][i-1]); 539 } 540 541 for(int i=1; i<rows; i++){ 542 direction=getMyDirection(rowComps[i],direction*-1); 543 if ( direction !=0 ) 544 cells[i][0].rotateLeft(cells[i-1][0],direction); 545 else cells[i][0].translateLeft(cells[i-1][0]); 546 } 547 548 GridCell below, corner, right; 549 for(int m=0; m<rows; m++) 550 for(int n=0; n<cols; n++) { 551 if( m < rows-1) below=cells[m+1][n]; 552 else below=null; 553 554 if( n < cols-1) right=cells[m][n+1]; 555 else right=null; 556 557 if ( below==null || right == null ) corner = null; 558 else corner=cells[m+1][n+1]; 559 560 cells[m][n].finish(below,right,corner); 561 } 562 cells[0][0].findShifting(size().height/2,rows*cols); 563 for(int m=0; m<rows; m++) 564 for(int n=0; n<cols; n++) 565 cells[m][n].shift(); 566 } 567 568 //*********************************************************************// 569 570 public void back() 571 { if ( !gridExist ) { 572 statusLine.setText("Back : Please define the grid first!"); 573 return; 574 } 575 displayMode=GRID; 576 Graphics g=getGraphics(); 577 for(int k=4; k>-1; k--) { 578 animate(k*3); 579 paint(g); 580 // try { 581 //Thread.sleep(200); 582 // } 583 // catch(InterruptedException e) {}; 584 } 585 g.dispose(); 586 } 587 588 589 public boolean mouseDown(Event evt, int x, int y) { 590 if ( !gridExist || displayMode==GRAPH) 591 return true; 592 //x -= gridCorner.x; 593 //y -= gridCorner.y; 594 //if(x<(gridCorner.x+length*cols) && y<(gridCorner.y+length*rows) 595 // && x>gridCorner.x && y>gridCorner.y ) { 596 int i,c=-1; //= x / length; 597 int j,r=-1;//= y / length; 598 599 for (i=0;i<rows;i++) 600 for (j=0;j<cols;j++) 601 if ( cells[i][j].myframe().inside(x,y)) { 602 r=i; 603 c=j; 604 break; 605 } 606 if ( r==-1 ) return true; 607 608 cells[r][c].toggleRigid(cellMode); 609 Graphics g=getGraphics(); 610 cells[r][c].paint(g); 611 g.dispose(); 612 613 if(cells[r][c].rigid) { 614 rowComps[r].addCell(cells[r][c]); 615 colComps[c].addCell(cells[r][c]); 616 617 } else { 618 rowComps[r].removeCell(cells[r][c]); 619 colComps[c].removeCell(cells[r][c]); 620 } 621 622 return true; 623 } 624 public void graph() { 625 displayMode=GRAPH; 626 calculateComponent(); 627 repaint(); 628 repaint(); 629 } 630 public void plotGraph(Graphics g) 631 { 632 int [] tx=new int[3]; 633 int [] ty=new int[3]; 634 635 636 int colonsY = (int)(size().height * ( MARGINS )); 637 int rowsY = (int)(size().height * (1.0 - MARGINS )); 638 int stepY = (int)(size().height * ( .08 )); 639 int stepX = (int)(size().width * ( .05 )); 640 int X = (int)(size().width/2); 641 if ( rows > cols ) X -=stepX*rows/2; 642 else X -=stepX*cols/2; 643 double SIN=0.42261826, COS=0.90630779; 644 645 646 for (int i=0;i<rows;i++) 647 for (int j=0;j<cols;j++) 648 if ( rowComps[i].getCells().contains( cells[i][j] ) && 649 colComps[j].getCells().contains( cells[i][j] ) ) { 650 if ( rowComps[i].rigid&&colComps[j].rigid) 651 g.setColor(Color.red); 652 else g.setColor(Color.black); 653 int x1=X+i*stepX+8, y1=rowsY-3*stepY+8; 654 int x2=X + j*stepX+8, y2=colonsY+2*stepY+8; 655 double alfa=-Math.atan( (double)(x2-x1)/(double)(y2-y1)); 656 657 if (cells[i][j].rightBrace() ) 658 { 659 tx[0]=x2; 660 ty[0]=y2; 661 tx[1]=(int) (x2- 15*Math.sin(alfa-0.230)+1); 662 ty[1]=(int) (y2+15*Math.cos(alfa-0.230)); 663 tx[2]=(int) (x2- 15*Math.sin(alfa+0.230)); 664 ty[2]=(int) (y2+15*Math.cos(alfa+0.230)); 665 g.fillPolygon(tx,ty,3); 666 } 667 if (cells[i][j].leftBrace() ) 668 { 669 tx[0]=x1; 670 ty[0]=y1; 671 tx[1]=(int) (x1+ 15*Math.sin(alfa-0.230)+1); 672 ty[1]=(int) (y1-15*Math.cos(alfa-0.230)); 673 tx[2]=(int) (x1+ 15*Math.sin(alfa+0.230)); 674 ty[2]=(int) (y1-15*Math.cos(alfa+0.230)); 675 g.fillPolygon(tx,ty,3); 676 } 677 678 g.drawLine(x1,y1,x2,y2); 679 } 680 g.setColor(Color.black); 681 g.drawString ("COLUMNS",X+stepX*cols/2 -40,colonsY); 682 for (int j=0; j < cols ;j++) { 683 g.drawString(Integer.toString(j+1),X + j*stepX,colonsY+stepY); 684 g.drawImage(ballg,X + j*stepX,colonsY+2*stepY-3,null); 685 } 686 687 for (int i=0; i < rows ;i++){ 688 g.drawString(Integer.toString(i+1),X + i*stepX,rowsY-stepY); 689 g.drawImage(ballr,X + i*stepX,rowsY-3*stepY,null); 690 } 691 g.drawString ("ROWS",X+stepX*rows/2 -15,rowsY); 692 693 } 694 695 696 public void update(Graphics g) { 697 paint(g); 698 } 699 700 public void paint(Graphics g) { 701 702 // draw a rectangle inside canvas to separate canvas from buttons. 703 704 705 g.clearRect(6, 6, size().width-6, size().height-6); 706 g.setColor(Color.yellow); 707 g.fillRect(0,0,size().width-1,4); 708 g.fillRect(0,0,4,size().height-1); 709 g.fillRect(size().width-4,0,4,size().height-1); 710 g.fillRect(0,size().height-4,size().width-1,4); 711 g.setColor(Color.black); 712 g.drawRect(5,5,size().width-11, size().height-11); 713 if(gridExist) 714 if ( displayMode == GRID ) 715 for(int m=0; m<rows; m++) 716 for(int n=0; n<cols; n++) 717 cells[m][n].paint(g); 718 else if ( displayMode == GRAPH ) plotGraph(g); 719 720 } 721 722 } //canvas 723 724 /* 725 for (int i=0;i<255;i++) 726 { 727 g.setColor(new Color((int)(Math.random()*100+100))); 728 g.drawLine(0,0,300,i); 729 g.setColor(new Color((float)Math.random(),(float)Math.random(),(float)Math.random())); 730 g.drawLine(600,0,300,i); 731 732 } 733 */ 734 735 736 // canvas ends here 737 //**************************************************************************** 738 //CELL 739 //****************************************************************************/ 740 class GridCell { 741 742 public Point topLeft; 743 Point topRight, bottomLeft, bottomRight; 744 public int rowIndex, colIndex; 745 public boolean rigid = false; 746 int BRICK=0, LEFT_BRACE=1, RIGHT_BRACE=2; 747 public int rigidType = BRICK; 748 749 int length; 750 double diagonal; 751 static double COS= 0.9961947, SIN = 0.087155743; // cos(5) , sin(5) 752 static double angle =0.0; 753 static int centery,deltay=0; 754 755 public GridCell(int x, int y, int length, int rowIndex, int colIndex) { 756 757 topLeft = new Point(x, y); 758 topRight = new Point(x + length, y); 759 760 bottomLeft = new Point(x, y + length); 761 bottomRight = new Point(x + length, y + length); 762 763 this.length=length; 764 this.diagonal=Math.sqrt(2*length*length); 765 this.rowIndex = rowIndex; 766 this.colIndex = colIndex; 767 } 768 public void place(Point p) 769 { 770 topLeft.x=p.x; 771 topLeft.y=p.y; 772 topRight.x=p.x+length; 773 topRight.y=p.y; 774 bottomLeft.x =p.x; 775 bottomLeft.y =p.y+length; 776 bottomRight.x = p.x+length; 777 bottomRight.y = p.y+length; 778 centery=0; 779 deltay=0; 780 781 } 782 783 784 public void updateAngle(int angle){ 785 //if ( angle >= 15.0 ) 786 // angle=0.0; 787 //angle +=3.0; 788 this.angle=angle; 789 790 COS= Math.cos((angle*Math.PI)/180.0); 791 SIN= Math.sin((angle*Math.PI)/180.0); 792 } 793 794 public void toggleRigid(int type) { 795 rigid = !rigid; 796 rigidType = type; 797 } 798 public boolean leftBrace() { 799 return rigid&&(LEFT_BRACE==rigidType||BRICK==rigidType); 800 } 801 public boolean rightBrace() { 802 return rigid&&(RIGHT_BRACE==rigidType||BRICK==rigidType); 803 } 804 805 public void rotateTop(GridCell neighbor,int direction){ 806 if (neighbor!=null) { 807 topLeft.x=neighbor.topRight.x; 808 topLeft.y=neighbor.topRight.y; 809 } 810 811 topRight.x =(int)(topLeft.x +(double)length*COS); 812 topRight.y =(int)(topLeft.y -(double)length*SIN*direction); 813 } 814 public void rotateLeft(GridCell neighbor,int direction){ 815 if (neighbor!=null) { 816 topLeft.x=neighbor.bottomLeft.x; 817 topLeft.y=neighbor.bottomLeft.y; 818 } 819 820 bottomLeft.x = (int) (topLeft.x +(double)length*SIN*direction); 821 bottomLeft.y = (int) (topLeft.y +(double)length*COS); 822 } 823 public void translateTop(GridCell neighbor){ 824 if (neighbor!=null) { 825 topLeft.x=neighbor.topRight.x; 826 topLeft.y=neighbor.topRight.y; 827 } 828 829 topRight.x =topLeft.x +length; 830 topRight.y =topLeft.y; 831 } 832 public void translateLeft(GridCell neighbor){ 833 if (neighbor!=null) { 834 topLeft.x=neighbor.bottomLeft.x; 835 topLeft.y=neighbor.bottomLeft.y; 836 } 837 838 bottomLeft.x =topLeft.x ; 839 bottomLeft.y =topLeft.y +length; 840 } 841 842 public void finish(GridCell below,GridCell right, GridCell corner){ 843 bottomRight.x= bottomLeft.x + (topRight.x-topLeft.x); 844 bottomRight.y= bottomLeft.y + (topRight.y-topLeft.y); 845 846 if ( below != null ) { 847 below.topRight.x = this.bottomRight.x; 848 below.topRight.y = this.bottomRight.y; 849 } 850 if ( right != null ){ 851 right.bottomLeft.x = this.bottomRight.x; 852 right.bottomLeft.y = this.bottomRight.y; 853 } 854 855 if ( corner != null ) { 856 corner.topLeft.x= this.bottomRight.x; 857 corner.topLeft.y= this.bottomRight.y; 858 } 859 860 centery += bottomRight.y+bottomLeft.y+topRight.y +topLeft.y; 861 862 863 } 864 public void shift(){ 865 topLeft.y += deltay; 866 bottomLeft.y += deltay; 867 bottomRight.y += deltay; 868 topRight.y += deltay; 869 } 870 public void findShifting(int originy,int n ) // how many cells 871 { 872 centery =centery/( 4*n); 873 deltay=originy-centery; 874 } 875 public Polygon myframe() 876 { 877 Polygon frame=new Polygon(); 878 frame.addPoint(topLeft.x,topLeft.y); 879 frame.addPoint(bottomLeft.x,bottomLeft.y); 880 frame.addPoint(bottomRight.x,bottomRight.y); 881 frame.addPoint(topRight.x,topRight.y); 882 frame.addPoint(topLeft.x,topLeft.y); 883 return frame; 884 } 885 886 887 888 public void paint(Graphics g) { 889 Polygon frame=myframe(); 890 891 if(rigid) { 892 if (rigidType==BRICK) { 893 //g.setColor(Color.red); 894 /// g.fillPolygon(frame); 895 //BrickMe(g); 896 BraceMeFromRight(g); 897 BraceMeFromLeft(g); 898 } 899 else if(rigidType==LEFT_BRACE) 900 BraceMeFromLeft(g); 901 else BraceMeFromRight(g); 902 } else { 903 g.setColor(Color.lightGray); 904 g.fillPolygon(frame); 905 } 906 g.setColor(Color.black); 907 g.drawPolygon(frame); 908 } 909 public void BraceMeFromLeft(Graphics g){ 910 int[] x=new int[4]; 911 int[] y=new int[4]; 912 g.setColor(Color.black); 913 g.drawLine(topLeft.x,topLeft.y,bottomRight.x,bottomRight.y); 914 double longDiagonal=Math.sqrt( (topLeft.x- bottomRight.x) * (topLeft.x-bottomRight.x) + 915 (topLeft.y- bottomRight.y)*(topLeft.y-bottomRight.y)); 916 double rate=1.0 - (double)(diagonal)*.90/(double)longDiagonal ; 917 rate/=2.0; 918 919 if (rate < 0.0) rate=0.0; 920 921 922 int x1= (int) (topLeft.x +(-topLeft.x+ bottomRight.x)*rate); 923 int y1= (int) (topLeft.y + (-topLeft.y+ bottomRight.y)*rate); 924 int x2= (int) (bottomRight.x + ( topLeft.x- bottomRight.x)*rate); 925 int y2= (int) (bottomRight.y + ( topLeft.y-bottomRight.y)*rate); 926 g.setColor(Color.yellow); 927 x[0]=x1+2; y[0]=y1; 928 x[1]=x2; y[1]=y2-3; 929 x[2]=x2-2; y[2]=y2; 930 x[3]=x1; y[3]=y1+3; 931 g.fillPolygon(x,y,4); 932 // g.drawLine(x1,y1,x2,y2); 933 // g.drawLine(x1+1,y1,x2+1,y2);g.drawLine(x1,y1+1,x2,y2+1); 934 935 } 936 public void BraceMeFromRight(Graphics g){ 937 int[] x=new int[4]; 938 int[] y=new int[4]; 939 940 g.setColor(Color.black); 941 g.drawLine(topRight.x,topRight.y,bottomLeft.x,bottomLeft.y); 942 943 double longDiagonal=Math.sqrt( (bottomLeft.x- topRight.x) * (bottomLeft.x-topRight.x) + 944 (bottomLeft.y- topRight.y)*(bottomLeft.y-topRight.y)); 945 double rate=1.0 - (double)diagonal*.90/(double)longDiagonal ; 946 rate/=2.0; 947 if (rate < 0.0) rate=0.0; 948 int x1= (int) (bottomLeft.x +(-bottomLeft.x+ topRight.x)*rate); 949 int y1= (int) (bottomLeft.y + (-bottomLeft.y+ topRight.y)*rate); 950 int x2= (int) (topRight.x + ( bottomLeft.x- topRight.x)*rate); 951 int y2= (int) (topRight.y + ( bottomLeft.y-topRight.y)*rate); 952 x[0]=x1+3; y[0]=y1; 953 x[1]=x2; y[1]=y2+3; 954 x[2]=x2-2; y[2]=y2; 955 x[3]=x1; y[3]=y1-2; 956 957 g.setColor(Color.cyan); 958 g.fillPolygon(x,y,4); 959 960 /* g.drawLine(x1,y1,x2,y2); 961 g.drawLine(x1+1,y1,x2+1,y2);g.drawLine(x1,y1+1,x2,y2+1); 962 */ 963 } 964 public void BrickMe(Graphics g){ 965 966 g.setColor(Color.black); 967 968 Point topMid = new Point((topRight.x+topLeft.x)/2,(topRight.y+topLeft.y)/2); 969 Point bottomMid = new Point((bottomRight.x+bottomLeft.x)/2,(bottomRight.y+bottomLeft.y)/2); 970 Point leftMid = new Point((topLeft.x+bottomLeft.x)/2,(bottomLeft.y+topLeft.y)/2); 971 Point rightMid = new Point((bottomRight.x+topRight.x)/2,(bottomRight.y+topRight.y)/2); 972 Point mid =new Point((leftMid.x+rightMid.x)/2, (rightMid.y+leftMid.y)/2); 973 974 Point closeTopLeft = new Point((topLeft.x+leftMid.x)/2,(topLeft.y+leftMid.y)/2); 975 Point closeBottomLeft = new Point((leftMid.x+bottomLeft.x)/2,(leftMid.y+bottomLeft.y)/2); 976 Point closeTopRight = new Point((topRight.x+rightMid.x)/2,(topRight.y+rightMid.y)/2); 977 Point closeBottomRight = new Point((rightMid.x+bottomRight.x)/2,(rightMid.y+bottomRight.y)/2); 978 979 Point closeTopMid = new Point ( (closeTopLeft.x + closeTopRight.x)/2, (closeTopLeft.y + closeTopRight.y)/2); 980 Point closeBottomMid= new Point ( (closeBottomLeft.x + closeBottomRight.x)/2, (closeBottomLeft.y + closeBottomRight.y)/2); 981 982 Point closeTopCloseLeft = new Point( (closeTopLeft.x+closeTopMid.x)/2, (closeTopLeft.y+closeTopMid.y)/2); 983 Point closeTopCloseRight = new Point( (closeTopRight.x+closeTopMid.x)/2, (closeTopRight.y+closeTopMid.y)/2); 984 Point closeBottomCloseLeft = new Point( (closeBottomLeft.x+closeBottomMid.x)/2, (closeBottomLeft.y+closeBottomMid.y)/2); 985 Point closeBottomCloseRight = new Point( (closeBottomRight.x+closeBottomMid.x)/2, (closeBottomRight.y+closeBottomMid.y)/2); 986 987 Point closeLeftMid =new Point ( (leftMid.x+mid.x)/2, (leftMid.y+mid.y)/2); 988 Point closeRightMid =new Point ( (rightMid.x+mid.x)/2, (rightMid.y+mid.y)/2); 989 990 Point bottomCloseLeft = new Point ( (bottomLeft.x+bottomMid.x)/2 , (bottomLeft.y+bottomMid.y)/2); 991 Point bottomCloseRight= new Point ( (bottomRight.x+bottomMid.x)/2 , (bottomRight.y+bottomMid.y)/2); 992 993 g.drawLine ( closeTopLeft.x,closeTopLeft.y,closeTopRight.x,closeTopRight.y); 994 g.drawLine ( closeBottomLeft.x,closeBottomLeft.y,closeBottomRight.x,closeBottomRight.y ); 995 g.drawLine ( leftMid.x,leftMid.y,rightMid.x,rightMid.y); 996 997 g.drawLine ( topMid.x,topMid.y,closeTopMid.x,closeTopMid.y ); 998 999 g.drawLine ( closeTopCloseLeft.x,closeTopCloseLeft.y,closeLeftMid.x,closeLeftMid.y ); 1000 g.drawLine ( closeTopCloseRight.x,closeTopCloseRight.y,closeRightMid.x,closeRightMid.y ); 1001 1002 g.drawLine ( mid.x,mid.y,closeBottomMid.x,closeBottomMid.y); 1003 1004 g.drawLine ( bottomCloseLeft.x,bottomCloseLeft.y,closeBottomCloseLeft.x,closeBottomCloseLeft.y ); 1005 g.drawLine ( bottomCloseRight.x,bottomCloseRight.y,closeBottomCloseRight.x,closeBottomCloseRight.y ); 1006 1007 } 1008 } // cell ends here 1009 class Rotate 1010 { 1011 int id; 1012 1013 int direction; 1014 boolean pozitif; 1015 boolean negatif; 1016 1017 Rotate(int dir) 1018 { 1019 direction=dir; 1020 pozitif=false; 1021 negatif=false; 1022 1023 } 1024 } 1025 1026 //**************************************************************************** 1027 // COMPONENT 1028 //**************************************************************************** 1029 class GraphComponent { 1030 int color; 1031 int cmpcolor; 1032 1033 int type=0; 1034 boolean rigid=false; 1035 Vector cells; 1036 public int ID; 1037 Rotate rotation; 1038 1039 public GraphComponent(int ID) { 1040 this.ID = ID; 1041 cells = new Vector(); 1042 } 1043 1044 public GraphComponent(GraphComponent gc) { 1045 this.ID = gc.ID; 1046 cells = new Vector(); 1047 for(Enumeration e=gc.getCells().elements(); e.hasMoreElements(); ) 1048 addCell((GridCell)(e.nextElement())); 1049 } 1050 1051 public void addCell(GridCell cell) { 1052 cells.addElement(cell); 1053 } 1054 1055 public void removeCell(GridCell cell) { 1056 cells.removeElement(cell); 1057 } 1058 1059 public Vector getCells() { 1060 return cells; 1061 } 1062 1063 public void listCells() { 1064 for(Enumeration e=cells.elements(); e.hasMoreElements(); ) { 1065 GridCell cell=(GridCell)(e.nextElement()); 1066 System.out.print("("+cell.rowIndex + "," + cell.colIndex + ")"); 1067 } 1068 System.out.println(" "); 1069 } 1070 1071 public void merge(GraphComponent comp) { 1072 if(comp.ID == this.ID) return; 1073 if(comp.ID < this.ID) comp.merge(this); 1074 else for(Enumeration e=comp.getCells().elements(); e.hasMoreElements(); ) 1075 addCell((GridCell)(e.nextElement())); 1076 } 1077 public void print(String s) { 1078 System.out.println(s); 1079 1080 for(Enumeration e=getCells().elements(); e.hasMoreElements(); ){ 1081 GridCell cell =(GridCell)(e.nextElement()); 1082 int r=cell.rowIndex+1; 1083 int c=cell.colIndex+1 ; 1084 if(cell.leftBrace()) 1085 System.out.println(c + " --> " + r); 1086 else if (cell.rightBrace()) 1087 System.out.println(c + " <-- " + r); 1088 else System.out.println("ERROR"); 1089 1090 } 1091 } 1092 public void setRowType() {type=0; } 1093 public void setColType() {type=1; } 1094 public boolean colType() {return type==1;} 1095 public boolean rowType() {return type==0;} 1096 } 1097 //**************************************************************************** 1098 // selection buttons 1099 //**************************************************************************** 1100 1101 class choiceCanvas extends Canvas 1102 { 1103 GridCell[] cells; 1104 boolean[] selection; 1105 GridCanvas canvas; 1106 int length; 1107 choiceCanvas(GridCanvas canvas) 1108 { 1109 cells=new GridCell[3]; 1110 selection=new boolean[3]; 1111 this.canvas=canvas; 1112 } 1113 public void showUp() 1114 { 1115 int width = size().width ; 1116 int height = size().height ; 1117 1118 // height=width=20; 1119 length = Math.min( width, height); 1120 //System.out.println(width + " showup "+height); 1121 1122 1123 for(int n=0; n<3; n++) { 1124 cells[n] = new GridCell(n * length, 1125 0 , 1126 length, 0, n ); 1127 cells[n].toggleRigid(n); 1128 selection[n]=false; 1129 } 1130 selection[0]=true; 1131 canvas.setCellMode(0); 1132 repaint(); 1133 } 1134 1135 1136 public void update(Graphics g) { 1137 paint(g); 1138 } 1139 1140 public void paint(Graphics g) { 1141 g.clearRect(0,0,size().width,size().height); 1142 1143 1144 for(int n=0; n<3; n++) { 1145 cells[n].paint(g); 1146 //if(selection[n]) { 1147 g.setColor(Color.white); 1148 g.draw3DRect(cells[n].topLeft.x+2,cells[n].topLeft.y+2, 1149 length-4,length-4,!selection[n]); 1150 g.draw3DRect(cells[n].topLeft.x+1,cells[n].topLeft.y+1, 1151 length-2,length-2,!selection[n]); 1152 // } 1153 1154 1155 } 1156 } 1157 1158 public boolean mouseDown(Event evt, int x, int y) { 1159 for (int j=0;j<3;j++) 1160 if ( cells[j].myframe().inside(x,y)) { 1161 selection[j]=true; 1162 canvas.setCellMode(j); 1163 } else selection[j]=false; 1164 Graphics g=getGraphics(); 1165 paint(g); 1166 g.dispose(); 1167 return true; 1168 } 1169 } 1170