BraidDrawing.java 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /* File : BraidDrawing.java
  2. * Program : Handle Reduction Aimation - Applet
  3. * By Jean Fromentin <jfroment@info.unicaen.fr>
  4. * Copyright 2008 Jean Fromentin
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. import java.awt.BasicStroke;
  17. import java.awt.Color;
  18. import java.awt.Graphics;
  19. import java.awt.Graphics2D;
  20. import java.awt.Rectangle;
  21. import java.awt.RenderingHints;
  22. import java.awt.geom.GeneralPath;
  23. public class BraidDrawing extends Braid{
  24. private float strandStep; //The distance between two strand
  25. private float strandWidth; //The width of a strand
  26. private float strandLeft; //The x position of the leftmost strand
  27. private float[][] xPos;
  28. private float yUp;
  29. private float yPos;
  30. public boolean handleNormalDraw; //This variable is true if we draw the handle with the classic metod
  31. public boolean onHandle; //This variable is true if we are in between the handleBegin Node and the handleEnd node
  32. public float trivialHeight;
  33. private Color[] strandColor; //The color of different strand
  34. private Color handleColor=Color.black; //The color of the handle
  35. private Color originalHandleStrandColor; //The original color of the handle strand
  36. static public boolean isDraw; //For not repeat drawing
  37. public boolean firstDraw;
  38. public BraidDrawing(String braidWord){
  39. super(braidWord);
  40. trivialNumber=0;
  41. trivialHeight=0;
  42. handleNormalDraw=true;
  43. isDraw=false;
  44. }
  45. public void initStrandColor(){
  46. strandColor=new Color[strandNumber];
  47. for(int strand=1;strand<strandNumber+1;strand++){
  48. strandColor[strand-1]=Color.getHSBColor((float)1-(float)strand/(float)strandNumber,(float)1,1);
  49. }
  50. }
  51. public void drawTrivial(Graphics g,int indice, int strandNumber,float trivialHeight){
  52. float nextYPos;
  53. nextYPos=yPos+strandStep*trivialHeight;
  54. for(int strand=1;strand<strandNumber+1;strand++){
  55. if(handleNormalDraw || (!handleNormalDraw && !isOnHandle(indice,strand))){
  56. drawLine(g,xPos[indice][strand-1],yPos,xPos[indice+1][strand-1],nextYPos,strandColor[strand-1]);
  57. }
  58. }
  59. yPos=nextYPos;
  60. }
  61. public boolean isOnHandle(int indice,int strand){
  62. return (indice>=handleBeginIndice && indice<=handleEndIndice && strand==handleStrand);
  63. }
  64. public void drawLine(Graphics g, float xA, float yA, float xB,float yB,Color color){
  65. Graphics2D g2=(Graphics2D)g;
  66. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
  67. g2.setStroke(new BasicStroke(strandWidth*2,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
  68. GeneralPath path=new GeneralPath();
  69. float yBezier=(yB-yA)/3;
  70. path.moveTo(xA,yA);
  71. path.curveTo(xA,yA+yBezier,xB,yA+2*yBezier,xB,yB);
  72. g2.setColor(Color.white);
  73. g2.draw(path);
  74. g2.setStroke(new BasicStroke(strandWidth,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
  75. path=new GeneralPath();
  76. path.moveTo(xA,yA);
  77. path.curveTo(xA,yA+yBezier,xB,yA+2*yBezier,xB,yB);
  78. g2.setColor(color);
  79. g2.draw(path);
  80. }
  81. public void drawCrossing(Graphics g,int indice, int strandNumber,int generator, int exp){
  82. int begin;
  83. int step;
  84. GeneralPath gpl,gpm,gpr;
  85. if(exp==1){
  86. begin=1;
  87. }
  88. else{
  89. begin=strandNumber;
  90. }
  91. for(int strand=begin;0<strand && strand<strandNumber+1;strand+=exp){
  92. if(handleNormalDraw || (!handleNormalDraw && !isOnHandle(indice,strand))){
  93. if (strand==generator){
  94. step=1;
  95. }
  96. else if(strand==generator+1){
  97. step=-1;
  98. }
  99. else{
  100. step=0;
  101. }
  102. drawLine(g,xPos[indice][strand-1],yPos,xPos[indice+1][strand+step-1],yPos+strandStep,strandColor[strand-1]);
  103. }
  104. }
  105. yPos+=strandStep;
  106. Color temp=strandColor[generator-1];
  107. strandColor[generator-1]=strandColor[generator];
  108. strandColor[generator]=temp;
  109. if(generator==handleStrand && isOnHandle(indice,handleStrand)){
  110. handleStrand++;
  111. }
  112. else if(generator==handleStrand-1 && isOnHandle(indice,handleStrand)){
  113. handleStrand--;
  114. }
  115. }
  116. public void drawHandle(Graphics g){
  117. float yPos;
  118. int nextHandleStrand;
  119. int generator;
  120. float height;
  121. Node current;
  122. Node backupCurrent;
  123. backupCurrent=getCurrent();
  124. current=handleBegin;
  125. setCurrent(current);
  126. yPos=handleBeginIndice*strandStep+yUp;
  127. nextHandleStrand=handleStrand;
  128. for(int indice=handleBeginIndice;indice<handleEndIndice+1;indice++){
  129. generator=value();
  130. if(generator<0){
  131. generator=-generator;
  132. }
  133. if(generator==handleStrand){
  134. nextHandleStrand=handleStrand+1;
  135. }
  136. else if(generator==handleStrand-1 && generator!=0){
  137. nextHandleStrand=handleStrand-1;
  138. }
  139. else{
  140. nextHandleStrand=handleStrand;
  141. }
  142. if(generator==0){
  143. height=trivialHeight*strandStep;
  144. }
  145. else{
  146. height=strandStep;
  147. }
  148. drawLine(g,xPos[indice][handleStrand-1],yPos,xPos[indice+1][nextHandleStrand-1],yPos+height,handleColor);
  149. handleStrand=nextHandleStrand;
  150. shift();
  151. yPos+=height;
  152. }
  153. setCurrent(backupCurrent);
  154. yPos=yUp;
  155. }
  156. public void draw(Graphics g){
  157. int generator;
  158. int exponent;
  159. initCurrent();
  160. initStrandColor();
  161. yPos=yUp;
  162. int stop=0;
  163. int indice=0;
  164. if(!handleNormalDraw && handleType==1){
  165. drawHandle(g);
  166. }
  167. while(stop==0){
  168. if(getCurrent()==handleBegin){
  169. onHandle=true;
  170. originalHandleStrandColor=strandColor[handleStrand-1];
  171. strandColor[handleStrand-1]=handleColor;
  172. }
  173. generator=value();
  174. exponent=1;
  175. if(generator<0){
  176. exponent=-1;
  177. generator=-generator;
  178. }
  179. if(generator!=0){
  180. drawCrossing(g,indice,strandNumber,generator,exponent);
  181. }
  182. else{
  183. if(indice!=0 && indice!=length()){
  184. drawTrivial(g,indice,strandNumber,trivialHeight);
  185. }
  186. else{
  187. drawTrivial(g,indice,strandNumber,1);
  188. }
  189. }
  190. if(getCurrent()==handleEnd){
  191. onHandle=false;
  192. strandColor[handleStrand-1]=originalHandleStrandColor;
  193. }
  194. if(isEnd()){
  195. stop=1;
  196. }
  197. else{
  198. shift();
  199. }
  200. indice++;
  201. }
  202. drawTrivial(g,indice,strandNumber,1);
  203. if(!handleNormalDraw && handleType==-1){
  204. drawHandle(g);
  205. }
  206. }
  207. public void calcXPos(Graphics g,Rectangle r,int animationStep,float parameterAnimationStep2,float parameterAnimationStep4,float parameterAnimationStep5){
  208. g.setColor(Color.white);
  209. g.fillRect(0,0,r.width,r.height);
  210. strandStep=(float)Math.min((double)r.width/(double)(strandNumber+1),(double)r.height/((double)(length())-((double)1-(double)trivialHeight)*(double)trivialNumber));
  211. strandWidth=strandStep/(float)5;
  212. strandLeft=((float)r.width-((float)(strandNumber+1)*(float)strandStep+strandWidth))/(float)2;
  213. yUp=(float)Math.max((double)0,(double)(r.height-(double)strandStep*((double)(length())-((double)1-(double)trivialHeight)*(double)trivialNumber))/(double)2);
  214. int length=length();
  215. xPos=new float[length+2][];
  216. for(int i=0;i<length+2;i++){
  217. xPos[i]=new float[strandNumber];
  218. for(int j=0;j<strandNumber;j++){
  219. xPos[i][j]=strandLeft+(j+1)*strandStep;
  220. }
  221. }
  222. int generator;
  223. Node current;
  224. if(handleStrand>0){
  225. if(animationStep>=2 && animationStep<=4){
  226. for(int indice=handleBeginIndice+1;indice<=handleEndIndice;indice++){
  227. xPos[indice][handleStrand]+=(parameterAnimationStep2-1)*(float)strandStep;
  228. }
  229. }
  230. if(animationStep==4){
  231. current=handleBegin;
  232. for(int indice=handleBeginIndice+1;indice<=handleEndIndice;indice++){
  233. xPos[indice][handleStrand-1]+=parameterAnimationStep4*(float)strandStep;
  234. }
  235. setCurrent(current);
  236. shift();
  237. for(int indice=handleBeginIndice+2;indice<handleEndIndice;indice++){
  238. generator=value();
  239. if(generator<0){
  240. generator=-generator;
  241. }
  242. if(handleStrand>1 && generator==handleStrand-1){
  243. xPos[indice-1][handleStrand-2]+=parameterAnimationStep4*(float)strandStep;
  244. xPos[indice][handleStrand-2]+=parameterAnimationStep4*(float)strandStep;
  245. }
  246. shift();
  247. }
  248. }
  249. if(animationStep==5){
  250. current=handleBegin;
  251. setCurrent(current);
  252. int currentStrand=handleStrand;
  253. for(int indice=handleBeginIndice;indice<=handleEndIndice;indice++){
  254. generator=value();
  255. if(generator<0){
  256. generator=-generator;
  257. }
  258. if(generator==currentStrand){
  259. currentStrand++;
  260. }
  261. else if(generator==currentStrand-1){
  262. currentStrand--;
  263. }
  264. if(handleStrand>1 && currentStrand==handleStrand-1){
  265. xPos[indice+1][handleStrand-2]+=parameterAnimationStep5*(float)strandStep;
  266. }
  267. shift();
  268. }
  269. }
  270. }
  271. }
  272. public String word(){
  273. boolean stop;
  274. int value;
  275. String res="";
  276. initCurrent();
  277. stop=false;
  278. while(!stop){
  279. value=value();
  280. if(value>0){
  281. res+=(char)((value-1)+'a');
  282. }
  283. else if(value<0){
  284. res+=(char)((-value-1)+'A');
  285. }
  286. if(isEnd()){
  287. stop=true;
  288. }
  289. if(!stop){
  290. shift();
  291. }
  292. }
  293. if(res==""){
  294. res="empty";
  295. }
  296. return res;
  297. }
  298. }