Celtic Knot Generator
Transcription
Celtic Knot Generator
Celtic Knot Generator King Hei Fung Bachelor of Science in Computer Science with Honours The University of Bath May 2007 Celtic Knot Generator This dissertation may be made available for consultation within the University Library and may be photocopied or lent to other libraries for the purposes of consultation. Signed: I Celtic Knot Generator Celtic Knot Generator Submitted by: King Hei Fung COPYRIGHT Attention is drawn to the fact that copyright of this dissertation rests with its author. The Intellectual Property Rights of the products produced as part of the project belong to the University of Bath (see http://www.bath.ac.uk/ordinances/#intelprop). This copy of the dissertation has been supplied on condition that anyone who consults it is understood to recognise that its copyright rests with its author and that no quotation from the dissertation and no information derived from it may be published without the prior written consent of the author. Declaration This dissertation is submitted to the University of Bath in accordance with the requirements of the degree of Bachelor of Science in the Department of Computer Science. No portion of the work in this dissertation has been submitted in support of an application for any other degree or qualification of this or any other university or institution of learning. Except where specifically acknowledged, it is the work of the author. Signed: II Celtic Knot Generator Abstract This dissertation concerns with the study of the pattern of a Celtic knot interlacing pattern and deriving an algorithm which imitating the ray tracing, the design and the implementation of a software system which generates Celtic knot interlacing with the algorithm described. III Celtic Knot Generator Contents CONTENTS.............................................................................................................................. I LIST OF FIGURES................................................................................................................ IV LIST OF TABLES................................................................................................................... V INTRODUCTION..................................................................................................................... 1 1.1OVERVIEW.......................................................................................................................... 1.2LITERATURE SURVEY............................................................................................................ 1.3THE REQUIREMENTS............................................................................................................. 1.4DESIGN............................................................................................................................. 1.5IMPLEMENTATION AND TESTING................................................................................................ 1.6RESULTS............................................................................................................................ 1.7CONCLUSIONS..................................................................................................................... 1.8APPENDIX........................................................................................................................... 1 2 2 3 3 3 3 3 LITERATURE SURVEY.......................................................................................................... 4 2.1INTRODUCTION .................................................................................................................... 4 2.2THE CELT.......................................................................................................................... 5 2.2.1Prehistoric Celt, the origin....................................................................................... 5 2.2.2Roman invasion to Celtic culture and the beginning of Celtic Christianity............... 6 2.2.3Celtic Art.................................................................................................................. 7 2.3CELTIC KNOTS.................................................................................................................. 10 2.3.1The basic structure of a Celtic Knot....................................................................... 10 2.3.2Tile Method........................................................................................................... 13 2.3.3Grid Method.......................................................................................................... 16 2.3.4Grid Method 2....................................................................................................... 21 2.4OTHER KNOTS OR SIMILAR STRUCTURES................................................................................... 25 2.4.1Generic knot.......................................................................................................... 25 2.4.2Knitting.................................................................................................................. 26 2.5INVESTIGATION ON CURRENT IMPLEMENTATION............................................................................ 27 2.5.1Steve Abbott's Computer Drawn Celtic knot work................................................. 27 2.5.2Knotwork Editor..................................................................................................... 29 2.6SUMMARY........................................................................................................................ 30 REQUIREMENTS................................................................................................................. 33 3.1 INTRODUCTION.................................................................................................................. 33 3.2.1Glossary................................................................................................................ 33 3.3REQUIREMENT ANALYSIS...................................................................................................... 34 3.3.1System overview................................................................................................... 34 3.3.2Literature Survey review........................................................................................ 34 i Celtic Knot Generator 3.3.3Project management and Scope........................................................................... 35 3.3.4Deliverables.......................................................................................................... 35 3.4SYSTEM ARCHITECTURE....................................................................................................... 35 3.4.1Choice of programming language......................................................................... 36 3.4.2Hardware requirement........................................................................................... 37 3.5SYSTEM REQUIREMENT SPECIFICATION.................................................................................... 37 3.5.1Functional requirements........................................................................................ 38 3.5.2 Non-Functional requirements............................................................................... 39 DESIGN................................................................................................................................. 40 4.1INTRODUCTION................................................................................................................... 40 4.2SYSTEM STRUCTURE.......................................................................................................... 40 4.3IDENTIFY THE OBJECTS......................................................................................................... 41 4.4INTERACTION BETWEEN CLASSES............................................................................................ 44 4.5COMPONENTS DESIGN......................................................................................................... 45 4.5.1Grid....................................................................................................................... 45 4.5.2sub grid................................................................................................................. 46 4.5.3Knotex................................................................................................................... 46 4.5.4Tracer.................................................................................................................... 49 4.5.5Knotimage............................................................................................................. 50 4.6USER INTERFACE DESIGNED................................................................................................. 52 4.7 PROTOTYPING ................................................................................................................. 53 IMPLEMENTATION AND TEST PLAN................................................................................. 55 5.1STAGE ONE OF IMPLEMENTATION............................................................................................ 55 5.2STAGE TWO OF IMPLEMENTATION............................................................................................ 56 5.3STAGE THREE OF IMPLEMENTATION......................................................................................... 56 5.4STAGE FOUR OF IMPLEMENTATION .......................................................................................... 57 5.5STAGE FIVE OF IMPLEMENTATION ........................................................................................... 58 5.6STAGE SIX OF IMPLEMENTATION ............................................................................................. 59 5.7STAGE SEVEN AND EIGHT.................................................................................................... 59 RESULTS.............................................................................................................................. 60 CONCLUSIONS.................................................................................................................... 61 7.1SYSTEM CRITIQUE.............................................................................................................. 61 7.1.1Knotex................................................................................................................... 61 7.1.2Tracer.................................................................................................................... 62 7.1.3Plotter.................................................................................................................... 62 7.2ACHIEVEMENT.................................................................................................................... 62 7.3PROCESS CRITIQUE............................................................................................................ 63 7.4FUTURE WORK................................................................................................................... 63 7.5THE END AND MORE........................................................................................................... 64 BIBLIOGRAPHY................................................................................................................... 65 TEST RESULTS................................................................................................................... 67 1 STAGE ONE....................................................................................................................... 2STAGE TWO........................................................................................................................ 3STAGE THREE...................................................................................................................... 4STAGE FOUR....................................................................................................................... 5STAGE FIVE......................................................................................................................... ii 67 69 70 71 71 Celtic Knot Generator 6STAGE SIX.......................................................................................................................... 72 USER DOCUMENTATION.................................................................................................... 73 1SYSTEM REQUIREMENTS.......................................................................................................... 73 2COMPILING THE SOURCE WITH COMMAND LINE INTERFACES............................................................... 73 3EXECUTING THE BINARY.......................................................................................................... 73 4WORKING WITH THE PROGRAM ................................................................................................. 74 CODE.................................................................................................................................... 76 iii Celtic Knot Generator List of Figures CELTIC CROSS...................................................................................................................... 7 CELTIC SILVER TORC.......................................................................................................... 8 A PAGE OF BOOK OF KELLS SHOWING THE POTRAIT OF JESUS................................ 9 PART OF A CELTIC KNOT.................................................................................................. 11 8 ELEMENTRY KNOT.......................................................................................................... 11 VERTICAL............................................................................................................................ 13 DIAGONAL........................................................................................................................... 13 HORIZONTAL....................................................................................................................... 13 INTERLACED TILE.............................................................................................................. 15 COMBINATION OF TILES.................................................................................................... 16 RANDOM PLAIT................................................................................................................... 17 JOINED PLAIT...................................................................................................................... 17 COMPLETED PLAIT............................................................................................................ 18 MULTI BANDED PLAIT........................................................................................................ 18 TYPICAL BEZIER CURVE................................................................................................... 25 A SCREEN SHOT OF THE SOFTWARE KNOT3D.............................................................. 28 KNOTWORK EDITOR SCREENSHOT................................................................................. 29 2 BY 2 GRID......................................................................................................................... 41 RESULT FROM STAGE 6 WITH RANDOM COLOURED BANDS...................................... 60 SCREEN DUMP OF THE DESIGNER.................................................................................. 67 SCREEN DUMP OF STAGE 1 INTERFACE........................................................................ 68 KNOTIMAGE TEST.............................................................................................................. 69 TEST OF KNOTEX DUPLICATION AND GRID CONSTRCUTION..................................... 70 STAGE 5 TESTING.............................................................................................................. 71 STAGE 6 TESTING.............................................................................................................. 72 iv Celtic Knot Generator List of Tables TABLE 1 - THE NINE COMBINATIONS OF LINE............................................................... 15 TABLE 2 REFLECTION TABLE........................................................................................... 50 v Celtic Knot Generator Chapter 1 Introduction 1.1 Overview The interlaced ornaments produced by Celtic scribes and stone masons has fascinated people for many centuries. Not only they have a entangling patterns which draw people's attention, it is also a mystery to majority. When i first saw this pattern, these questions came up in my head immediately - What do they really represent? Why are they created in a way of a closed loop like a never ending maelstrom? Where do these patterns firstly appears? Who are the Celts? And the one-million-question is, how do people recreate these patterns? Or does the pattern follow a certain rules of construction so that it can be computed in any ways? The interlacing pattern, ranging from small individual knots to elaborate panels composed of many motifs, provide a rich sources of the interlaced patterns which can be studied mathematically and, to some extend, be computed. But the question remains, are the patterns recreatable on a computer? In the following chapters, we shall address the questions above with existing material which involves some historical, mathematical and even some mythical aspect of the Celtic knots. The main hurdle of this project maybe the mathematical background associated with the algorithm of the pattern itself. The fact is that my mathematic is not of top notch, so this is one main issues that I have to overcome and this is also the reason why I would like to pick up this project – to challenge my ability to learn/tackle difficult problems that I did not dare to pick up. Of course, the patterns itself is of much interest to me. The reason maybe I am interested in world history and Celtic-related history was one of the very first topics that I had came across. Also, Celtic knots, in fact, is very similar to some random knotting I draw when I am thinking. These 1 Celtic Knot Generator patterns may not mean as much as Celtic knots, but I hope one day I may be able to derive an algorithm of the random patterns that I draw. Finally, this project involves the investigation of different available construction methods and to describe, enhance and implement the method to construct a Celtic knot. 1.2 Literature Survey The literature survey is to look into existing articles, journals, books, or research papers that may involves some areas that are concerning with Celtic knots. The early part of the survey should investigate the background of the Celtic knots, like who are the Celts, what does the interlacing mean or why they were making the pattern like what it was. The middle part of the survey would look into different existing construction methods of a Celtic knot and some other related knowings or other areas that may give us insights into developing completely new or enhancing existing methods of construction. The later part of the survey would look into several implementation of Celtic knots design assistant and to address questions like what kind of parameters and data is needed to construct a Celtic knot? Is user intervention needed? Etc. Finally, the conclusion of the survey would focus the project onto a few viable implementation methods and lead to deriving a set of requirements from the survey. 1.3 The Requirements This section would focus on the analysing and specifying the capture of requirements qualifications. The several techniques of constructing a Celtic knot would be evaluated to identify the preferred method with proper justification. Moreover, the decision of scoping down the problem may also be discussed and rationalised by the constrains such as time, other ongoing works or any other factors . 2 Celtic Knot Generator Also, the choice development platform would be discussed , like what programming languages? What software developing approach – object oriented? Or simply procedural. The last but not least, a set of System requirements that the system should follow would also be laid out to tighten up the scope of the project. 1.4 Design After requirements have been set, the next stage would be starting the design of the system. Metrics like how many objects would there be? How will the input be taken care of? would be answered in this section. With the use of figures and diagrams, the abstraction of the system are to be eased. 1.5 Implementation and Testing This section would review the different stages of implementation and suggests the plan of testing for each of the stages. Problems encountered during the implementation would also be addressed. 1.6 Results The result obtained from the program should be demonstrated here. 1.7 Conclusions This section contains critiques and further developments of the whole project. 1.8 Appendix The appendix collected test results, user menu and the program code. 3 Celtic Knot Generator Chapter 2 Literature Survey 2.1 Introduction Celtic knot, which origin is essentially unknown due to its prehistoric nature and the Celtic history of that period was only carried forward by oral tradition( O’Corrain, 1981). However, these Celtic artworks are closely associated with Knot theory, which is a relatively recent branch of algebraic topology originated in the 19th century. Around 1867, Lord Kelvin had in idea that atoms were knots of swirling vortices in the aether. He assumed that classifying and understanding of all possible knots would bring an explanation to some behaviours of atoms where they only absorbs and emit light at only certain wavelengths. Although his idea was proved wrong, many years later, people recalled the idea of knots structures and associate them with many different matters such as string theory, loop quantum gravity or even the study of DNA replication and recombination. But for the scope of the project, we are looking into a specific kind of knots which is called Celtic knots. Although these knots may not be of too much scientific interest, they are certainly fascinating from an artistic point of view considering their prehistoric origin and the broad usage of them. Nowadays, many people seek to understand the structure of Celtic knots by different aspect, for example, the algorithm that may generate the Celtic knots, the meaning behind some certain patterns of Celtic knots since they are used as religious ornaments and probably looking into it artistically. 4 Celtic Knot Generator In this literature review, we will first introduce the idea of Celtic knots from its historical origin, the cultures that affected it, different application of it, to the structure of a Celtic knot and similar patterns, looking into current implementations of Celtic knots or other knots generating systems and finally onto designing a solution for the purpose of this project. 2.2 The Celt This term, Celt, refers to a member of any of a number of peoples in Europe using the Celtic languages, as well as others whose languages is unknown but where associated cultural traits such as Celtic Arts are found in archaeological evidence. (Colins, 2003) This is mainly because of the conflicts or connections between the Celt and the many surrounding cultures at that time. The first literacy reference to the Celtic people dated back in 517 B.C., where they were called 'Keltoi' by the Greek historian Heacataeus. The Keltoi tribe he thought to be located in Rhenania, which is around today's West/South west Germany. In Dixon-Kennedy's book in 1996, he stated that the Celtic Culture is dated around the fourth century B.C. The Celts who were once pagan until the introduction of Roman Christianity in the fourth and fifth centuries A.D. In the following subsections, we will go through the origin of the Celtic culture, the events that influenced it and the Celtic art that resulted from the events. 2.2.1 Prehistoric Celt, the origin The Celts arose in central Europe at the beginning of the first millennium B.C. and were an iron using and horse rearing peoples. By the end of the first millennium B.C. their cultural group had spread up and down the Danube and Rhine, taking in Gaul, Ireland and Britain, across central Europe, into northern Italy and northern Spain. They were the most feared of all the so-called 'barbarian' peoples beyond the urbanity of Greek and Roman civilisation. Their roaming across Europe led some of the Celtic tribes to sack Rome in 390 B.C. (creating a fear of the northern barbarians that was to haunt Romans for hundreds of years to come), and in 279B.C. another Celtic tribe sacked the Greek sanctuary at Delphi, going on to found a Celtic kingdom in Asia-Minor, Galatia (The people to whom St. Paul was to address some of his epistles). Celtic peoples were apparently fierce warriors, with a taste for head hunting and going into battle naked, though armour of varying types are not uncommon artefacts. (Delaney,1989) 5 Celtic Knot Generator Kurta V. et al mentioned that these prehistoric pagan Celts included two casts of people, the tribes and the druids. The druids were the communication channel channel who unify the many Celtic tribes. They and their religion likely came from the megalithic priesthood, who used large stones monuments such as the Stonehenge in today's Salisbury, UK within their rituals, and were most likely to exist more than two millennium B.C. Around 6th century B.C. these druids abandoned the great stones and reverted to natural shrines such as trees or even associated themselves with animals like bears or eagles. The whole Celtic culture were centric to Druids, since they were the teachers, seers, poets, judges, and doctors of the Celtic cultures and were recruited among the ranks of nobility. The specifics of many teachings or religious practices remain shrouded in mystery because the knowledge was only given orally. Despite of that, the general idea of druids' teaching is about attainment to nature, like the seasons, and all aspects of the natural world. They believed that life of the soul was not interrupted by death but would continue into two ways, either dwelling in a spiritual realm or returning to earth in the reincarnation of the soul. This belief was reinforced by the cycle of the seasons. A solid example to this is every year the trees shed their leaves, vegetation withered, and once winter came there was little sign of life from nature and yet with the coming of spring, rebirth occurred and the forest came to life again. This is why they believe even human falls into this cycle as well. Tribes, which made up the other parts of Pagan Celts consisted of numbers of nomadic groups spread across different parts of Europe. These warmongering people often involved in conflicts between other tribes or larger establishments like the Romans. 2.2.2 Roman invasion to Celtic culture and the beginning of Celtic Christianity The Romans, a century after the siege of Rome by the Gaulic Celts and several other Celtic tribes around northern Italy around 390 B.C., won decisively in Third Samnite war against the alliance of Samnite, Etruscan and Celts which marked the end of Celtic domination in Europe, but it was not until 192 B.C. that the Romans conquered the last of Celtic influence in Italy. Then the Roman Empire slowly absorbing the remaining part of Celts in the British Isles. While the regions under Roman rule adopted Christianity along with the rest of the Roman Empire, unconquered areas of Scotland and Ireland moved from polytheism to Celtic Christianity. This act may have abolished many Celtic cultures of their gods 6 Celtic Knot Generator and traditions but on the other hand promoted a fusion between Christianity and Celtic arts and traditions. Illustration 1 shows a Celtic Cross which is the characteristic symbols of Celtic Christianity, despite that it has an older pre-Christian origins. Such Crosses formed a major part of Celtic Art and within which the Celtic knots are used. Illustration 1: Celtic Cross http://www.webmesh.co.uk/nice/newhistory.htm described the adoption of Roman cultures in post-Celtic Britain as a 'political move': “The province's towns and villas were overwhelmingly built by indigenous people - again the wealthy - adopting the new international culture of power. Greco-Roman civilisation displaced the 'Celtic' culture of Iron Age Europe. These islanders actually became Romans, both culturally and legally (the Roman citizenship was more a political status than an ethnic identity). By AD 300, almost everyone in Britannia was 'Roman', legally and culturally, even though of indigenous descent and still mostly speaking 'Celtic' dialects. Roman rule saw profound cultural change, without mass migration.” 2.2.3 Celtic Art Celtic Art, the art of the ancient Celts. Celtic art emerged as an identifiable tradition in about 600 B.C. and flourished until the mid-1st century A.D., when the expansion of Roman Empire and its conquest of the Celts of Britain, Gaul and Germany largely extinguished Celtic Culture. Before the Roman conquest, Celtic art was closely integrated with its society; so 7 Celtic Knot Generator that Celts were used to seeing art as part of their daily life. Some authors suggest that in Celtic society it is virtually impossible to make a distinction between art and decoration. (Pizano-Rodriguez, 2002) The Celt peoples possessed vibrant cultures, and developed superb artistic styles originally influenced by La Tene decorative and metal-working practices of Greek, Etruscan, and Scythian communities with whom they frequently traded. This led to blossoming of an unique Celtic artistry, characterised by complex flowing of lines and patterns. Celtic art is ornamental, avoiding straight lines and only occasionally using symmetry, without the imitation of nature or ideal of beauty central to the classical tradition, but as far as we can understand it can often involves complex symbolism. It includes a variety of styles which import from the Mediterranean cultures, an example being the characteristic over-and-under interlacing, now known as Celtic Knots, which only arrived in the 6th century B.C. while it was already in use by Germanic artists. An anonymous writer, http://www.argusdesigns.com/products/History/celtic.html, says that Celtic art is highly stylised curvilinear art that originated during the second half of the first millennium B.C. among the Celtic people of Iron Age Europe. That refers to two separate traditions: Le Tene art, which was named for a major Celtic artefact site in Switzerland and was produced by the pre-Christian Celts from 5 th centure B.C. until the second century A.D.; and Celtic Christian arts, which was produced in Britain and Ireland from A.D. 400 to 1200. Le Tene art style spread widely throughout the continental Europe. The art principle appeared on objects such as weaponry bracelets, torcs(ill 2) and many household and ritual vessels made with bronze, gold, silver and iron. There are evidence that object made with wood existed, but most of them perished in due of the course of time. Illustration 2: Celtic silver torc As pointed out above, the next phrase of evolution in Celtic Culture was the gradual conversion to Christianity. In R.Megaw and V. Megaw's book in 1989, they describe the Celtic Christianity culture as a mixture of influence from Germanic styles, Mediterranean styles and Christian subject matter. Christianity was established from 8 Celtic Knot Generator fourth century A.D. onwards. In the second half of the sixth century, monasticism, which is a religious practice in which one renounces worldly pursuits in order to fully devote one's life to spiritual work, spread widely throughout Celtic areas. As a result, monks produced most Celtic art of that period. These monks created pictorial gospel called illuminated manuscripts that contained elaborate ornamental and gilded illustrations. Complex interlaced knot work began to appear on these illuminated manuscripts. The Book of Kells (ill 3) is a famous example of the illuminated manuscripts. Illustration 3: a page of Book of kells showing the potrait of jesus 9 Celtic Knot Generator 2.3 Celtic Knots Amongst the many aspects of Celtic arts, Celtic knots or interlacing are certainly one of the most iconic figures. Generally, Celtic Knots are a variety of knots and stylised graphical representations of knots used for decoration. Though Celtic knots were being created in pre-Christian times, these knots are most known for their use in the ornamentation of Christian monuments and illuminated manuscripts like 8th century Book of Kells mentioned in the previous section. These Celtic motif in Pagan and Christian times has a geometric appearance in the form of interlacing knot-work, spirals, or interlacing human, bird and beast figures. Although little to none is known about the meaning behind the knots, there exists some possible explanation: From section 2.1, we learnt that the prehistoric Celts believe that everything falls into an unending cycle just like the changing of seasons, the life cycle of a tree or any things associated to the nature, which includes human. This may be the reason why a Celtic knot-work pattern is a endless knot where there is no breaks between the interlaces. So everything is continuous and unending just like what the Celts believe. Alana from http://www.askalana.com/new-age/celtic.html believes that these intricate knotwork patterns collectively called interlace which are said to not only be Celtic symbols of the interconnectivity of our spiritual life with our physical life but to also represent a never-ending path. Also, Alana points out many people believe that although there are no findings indicating the Celtic knots have any specific meanings, but it is more a matter of lacking of documenting such meanings than a failure to assign significance. Based on the knowledges that most of the Druids, who represents the scholars at the time, only transmit orally their knowings to others, this theory is certainly believable although lacking of solid evidence. James Thrilling, on the other hand, developed a theory that the knot-work designs were, like the crosses that they commonly accompanied, protection against evil: the complex designs would trap and confuse the “evil eye”. Regardless of the meaning behind the Celtic knots, they are certainly a fascinating yet mysterious patterns that catches the eyes of millions of people. The geometric complexity of the knot-work designs is evidence of substantial mathematical sophistication(Fisher, G.) and their analysis leads us to many mathematical questions. In the following sections, we will try to decipher the geometric structure of a Celtic Knots by different methodologies. 2.3.1 The basic structure of a Celtic Knot A Celtic knot is composed by one or more interlacing patterns(ill 4). The “string” 10 Celtic Knot Generator which interlaces with itself to produce a “knot”, where the crossing are alternating between over-crossing and under-crossing and never repeat the same crossing. Illustration 4: part of a celtic knot In J. Romilly Allen's book, he suggested that most of the Celtic knot patterns are made up by eight elementary patterns(illustration 5), where “two of the elementary knots are derived from a three-cord plait, and the remaining six from a four-cord plait”. Illustration 5: 8 elementry knot The basic rules of constructing a Celtic knots may be as follow: 1)Alternating crossings of over- and under-crossings. 2)In each crossings, the interlaced line does not touch each other. 11 Celtic Knot Generator 3)The looping is closed, so no loose ends on both the beginning and the end of the line 4)Equal widths of the band, although some knots may use animals limbs as the “band” which is the exception 5)The width of the band shall be equal to the spacing between bands. 6)The overall shape of a Celtic knots should be symmetric. With the rules above, we shall explore the two most famous methods in the following section, which are called tile method and tile grid method respectively, in order to understand the construction of a Celtic knots in different point of view. 12 Celtic Knot Generator 2.3.2 Tile Method Andy Sloss(Sloss, 1995) wrote a book for the novice who wants to be able to draw knot work in the Celtic style without months of practice. His method starts with a grid of for example 3 x 3 squares, and populate each of them with pre-drawn knot work tiles, which is produced by some simple rules. In his book, he suggested that there are three arch-types of lines in a knot work, which are: Illustration 8: horizontal Illustration 6: vertical Illustration 7: diagonal Each type of the lines connect the two corners of a square tile, so it is possible for two horizontal lines in the same tile each conquering two corners and vice versa. 13 Celtic Knot Generator For each of the square tiles of the grid, the lines all tend to leave or enter the squares at roughly the corners. He summarised that there are nine combinations of line: Type Illustration Diagonal to Diagonal Diagonal to Horizontal Diagonal to Vertical Horizontal to Diagonal Horizontal to Horizontal Horizontal to Vertical Vertical to Diagonal 14 Celtic Knot Generator Vertical to Horizontal Vertical to Vertical Table 1 - The nine combinations of line When two different kinds of line entering the same tile and come across with each other, it is called a “Crossing”. Within the tile, the diagonals need a bit of attention. If the foreground line has either end diagonal, then it must be closed off. This is because it has just crossed over a line in the centre of the section, so it must go under the line where it meets in the corner as stated above where a crossing must alternate between over- and under-crossing, which obeys the rule we stated above. It is possible to create most of the Celtic knots pattern by these basic lines. To combine the square tiles correctly, he defined a rule where for each of the four corners of a tiles are marked with a letter representing the type of the line residing on the corner. For example: H D D V Illustration 9: interlaced tile where H, D,V stands for horizontal, diagonal and vertical respectively. Then matches the tile by the respective corner letter as following, 15 Celtic Knot Generator Illustration 10: combination of tiles a simple Celtic knot pattern is drawn. More complex patterns can be built using the same methodology. Although this method seems to be very straightforward, the computation of this method may not be as easy as a human being. Since this method require many rendering of different tiles, and the number of the tiles required could be very difficult for a computer to render due to the over/under-crossing nature. If the tiles are of pre-rendered, this may be too restrictive for a user to create the pattern with different width, colour of the band for example. Moreover, the complexity will probably become not computable with a very big pattern 2.3.3 Grid Method Another method to construct a Celtic knot is the Grid method, which was first suggested by George Bain's 1951 book. This is a completely different approach to produce the interlacing pattern since it take the knot as a whole rather than individual components. The basic idea of the Grid method can be described in a three steps method which was simplified by Iain Bain in his 1986 book: 16 Celtic Knot Generator 1. First construct with a plait, some regular weaving of perpendicular Illustration 11: random plait braids, notice the overlapping and under lapping between the braids. 2. Joint the neighbouring ends of the bands. Illustration 12: joined plait 17 Celtic Knot Generator 3. Colour the ”outer” bands with with the same colour as the inner bands. Illustration 13: completed plait This s a traditional pattern of a single banded Celtic Knot. However, there exists multiple banded Celtic knots: Illustration 14: multi banded plait where each of the invidious bands with different colour lapping with each other to produce such pattern. But the construction method is basically the same. 18 Celtic Knot Generator To go into details, the steps of creating a Celtic knot with grid method are as follow: 1. Create a n by m grid that determine the overall size of the pattern, each four dots that construct a square will be regarded as a grid. 2. Create putting a dot in the middle of each grid. In a rectangular grid, the amount of dots should be of n-1 by m-1 3. Draw lines between the dots. 4. Draw the plait within the grey area that is defined by the inner dots from step two. 19 Celtic Knot Generator 5. Adding external weaving. The sides are joined naturally and loops are placed at the corners. 6. Define the alternating crossings. 7. Construct the bands according to the weaving and crossings 20 Celtic Knot Generator 8. Remove the construction lines, and the final product. This method is more complicated but by following the exact steps, it is possible to produce Celtic Knots in a accurate manner. Also, the above algorithm should be computable by a computer since the dots and grids can be represented in a computer language more easily. 2.3.4 Grid Method 2 This second grid method bases on the grid just as the first one, but the way to construct the knot is vastly different. This method, described by Cromwell P.,1995, construct the knot by a technique similar to ray-tracing, where a laser is fired from a random point between two vertexes, if the laser hits a “barrier”, it reflect 90 degree to change directions and keep tracing until it is back to its starting point. It is illustrated as following: 21 Celtic Knot Generator 1. Fire a laser from a randomly selected point between two vertexes(the cyan points), 2. If a barrier or the edge is reached, reflect by 90 degree 22 Celtic Knot Generator 3. Repeat until the laser reaches its starting point. 4. Smoothing the sharp at the edges 23 Celtic Knot Generator 5. define interlacing This method is much more easier to follow than the first grid method because the laser tracing appears to be more intuitive. Practically, if the data structure of the grid is well-defined, tracing a pattern as mentioned should not be too difficult. The curves, on the other hand, should be generated by curve fitting method like Bezier curves as following: 24 Celtic Knot Generator The points between vertexes act as the control points for Bezier curves. Illustration 15: typical bezier curve In the mathematical field of numerical analysis, a Bézier curve is a parametric curve important in computer graphics. Generalizations of Bézier curves to higher dimensions are called Bézier surfaces, of which the Bézier triangle is a special case. Bézier curves were widely publicised in 1962 by the French engineer Pierre Bézier, who used them to design automobile bodies. The curves were first developed in 1959 by Paul de Casteljau using de Casteljau's algorithm, a numerically stable method to evaluate Bézier curves.(Prautzsch, H, 2002). 2.4 Other knots or similar structures This section will look at other structures that shares minimal similarity with Celtic knots in order to further explore the structure of Celtic knots. 2.4.1 Generic knot Generic knot here refers the a mathematical topology known as the knot theory inspired by observations of common knots. This specific arrangements of string is what knot theory concern itself with. The figure shown below is a non-trivial knot called the trefoil knot. 25 Celtic Knot Generator Fig 3.5 – a Trefoil knot In Joe Butt 's website, http://ninthwavedesigns.typepad.com/ninth_wave_designs/mathematics/index.html, he mentioned knot theory as a subsection of mathematical discipline of Topology which brings us such novelties as the Klein Bottle. In Topology mathematicians study the properties that do not change through deformations like stretching and twisting, but cutting and tearing are strictly not allowed. To a Topologist a doughnut is the same as a coffee cup, a cube equal to a sphere. This would make for an interesting parallel universe if the laws of matter adhered to these topological principles. 2.4.2 Knitting Cloth Knitting shares some similarity to Celtic knots weaving. One major difference maybe the yarn that has been knit follows a loopy path along its row, as with the red strings in the following diagram: Fig 3.6 – Yarn loop interlacing This may not be a perfect Celtic knots since it do not follow the rule of alternating between over/under-crossing, but it is still an interesting structure. Wada T. et al. 's 1997 paper on knitting describe the structure of knitting loops. A knitted fabric consists of one or more looped yarns, Plain knitted fabric, which is illustrated in the below figure, is one structure of knitted fabrics. As shown in the figure, the column and the row directions of the loop are referred tp as wale and course, respectively. The hatched part of the knitted fabric in the figure is called a knitted loop. 26 Celtic Knot Generator Fig 3.7 Knitted fabric 2.5 Investigation on current implementation 2.5.1 Steve Abbott's Computer Drawn Celtic knot work This is one of the Celtic knot software that is capable of generating knots in 3D and by the Grid method mentioned above. The highlight of the program includes: ● Fully customisable knots factors, from size, scale, shape, breaks between grids, etc. ● Both 2D and 3D graphic support ● Pre-created template grid shape for quick starts ● Exporting and importing of created patterns in different formats ● Detailed help file to explain terminologies ● Random grids generating ● Customisable Grid Shape 27 Celtic Knot Generator Illustration 16: A screen shot of the software Knot3D. This implementation adopted the knot generated method by Christian Mercat which is a slight variant from the Bain's grid method. Although the program provides essentially everything to customise a knot, but some of the settings are too vague to understand by non-expert and the help files do not provide enough examples to these factors, which make many of the functions of the program obsolete. Moreover, the rendering speed is rather slow considering the size of the knot. For example, the knot shown in the screen shot above may take more than one second to generate. If the user would like too produce the above in 3D, the program may take three to four seconds to finish. This could be due the the programming language used to create the program – Visual Basic 6.0, which is a relatively dated language and notorious for its slow performance when compare with many slightly lower level languages. In a nutshell, the problems can be summarised as following: ● The corners of the knot created does not stand out like a Celtic knot meant to be. It could be the corner curving method is quadratic rather than something of higher order like Bezier curve 28 Celtic Knot Generator ● The way to define a customised grid is not straight forwarded, the user has to click multiple times for a grid to be made ● The parameters that can be adjusted do not change the picture generated by a lot if there is any ● The parameters are not documented or explained very well to users who has no knowledges of the structure of the program ● Bad performance when generating three dimension knots even for some very simple pattern(e.g. small width and height). This program can be utilised fully by the experts of the field, but for normal user, this program is too rough to tame. 2.5.2 Knotwork Editor This program, as Knot3D by Abbott, is also based on Christian Mercat's method to create knot works. This program work in the principle of representing knot work by a graph. Then, every modification of the graph will change the knot work. An example of such a graph with the corresponding knot work is shown below. Illustration 17: knotwork editor screenshot 29 Celtic Knot Generator Highlight of the program: ● Creation of any type of graph (trangular, hexagonal, square ...), and immediate visualization of the corresponding knot work ● Toggle of edges type, corresponding to the crossing : up, down, opposite, or long. cf. Mercat's page for explanation. Save and load of graphs Use of a scalable grid (square, or triangular) to place new nodes Possibility of changing the grid origin (press TAB to place on the closest node) Select and move several nodes and edges by one mouse movement Get the dual of the graph : the same knotwork (in theory ...), but with a different graph Pruning of the graph : suppress all nodes connected to only one edge. Useful for one looking for minimal version of the graph. Graph information : number of edges, number of nodes, with or without ghosts, adjacency matrix of the graph Choice of visible structures among nodes, edges, anchors, knotwork and ghost nodes and edges Put an image as background to overlay knotwork on it Choose the style of the graph between 'Celtic', 'round', 'Arabic', and 'flat'. ● ● ● ● ● ● ● ● ● ● This program is simpler than the previous one but still providing many functions. Although lacking of 3D rendering capabilities. With that said, this program became obsolete because of the newer version of Java is not compatible with this version of the software. So I can only test it once while I was using older version of Java Runtime Environment. The overall speed and quality of knot generated is higher than the previous one and yet providing enough customisation. Generally, this program might be better if: ● Implements 3D rendering ● Rebuild to be compatible with modern Java versions ● Implement Help file or tutorial system All in all, Knotwork editor is much more easier to use yet powerful tool to create Celtic knotworks. 2.6 Summary This Literature Review was split into three major sections: At the first major section described the source of the Celtic culture and the many factors that affected their culture. It is conclusive that, before the “Christianisation”, most changes of the Celtic culture were rather an absorbing change rather than a overhaul changes. As stated 30 Celtic Knot Generator in Collis, 2003, the Celts were good at adopting others culture characteristic and integrating them into their own culture. And their believes in a cycle of unending manifest of everything around them may be a source of the unending loop of Celtic knots that they are profound of. Even after Christian Celts, these patterns were used as the decoration in the new religion and became the most distinctive features of their civilisation. In the second part of the review, we tried to understand the structure of Celtic knots by defining some rules of constructing a Celtic knot. From these rules, we tried to verify the different constructing methods of the pattern. First we examined with the tile method, which was apparently more intuitive for human because of the high level pattern matching method involved in the process. Nonetheless, this method is not as easy to compute as it seems. Mainly due to the rendering of individual tiles which are required in every instance of a new knot, and of which the complexity to render such tiles could be very computationally expensive. On the other hand, the grid method is a more algorithmic approach. By following the exact step, creating dots and grids and finally the patterns, which is an appealing method for computer program. Apart from Celtic knots, we also investigated several patterns that share similarity with Celtic knots. The final chapter introduced some of the current implementations that generate Celtic knot patterns by the grid method. Both of the solution is very well implemented, but not without its flaws. It is either due to they are based on dated technologies or simply overly complex and without detailed description into helping user to create the knots that they may have in their mind. The Grid method 2 shall be the focus of this project from now on because I found it amusing and the picture of the structure of the method is already apparent in my mind. In the next chapter, a set of requirements will be set for the implementation of this method. 31 Celtic Knot Generator 32 Celtic Knot Generator Chapter 3 Requirements 3.1 Introduction In this chapter, a set of requirements will be set for the software system to construct a Celtic knot designs with the laser-tracing grid method outlined in section 2.1.4. The system should be able to construct the knots of different dimensions based on the grid size which includes square(n * n) or rectangular(n * m) grids. Due to the constrain of time and skill of the developer, the barrier system shall be optional. So the development can be focused on a basic n by m grids generation of Celtic knot. The following requirement will also follow the general requirement guide line of IEEE/ANSI 830-1998 as much as possible to provide a good overall requirement structure. The requirements of the system will be short because the essence of the system lies on the design of the implementation of the algorithm. 3.2.1 Glossary Apple MAC OS X – a proprietary, graphical operating systems developed, marketed and sold by Apple Inc, the main development platform of this project BUCS – The Bath University Computer Service, which includes the computer systems used in this project. JAVA – A cross platform and object-oriented applications programming language developed by Sun Microsystems in the early 1990s. Microsoft Windows – A family of proprietary software operating systems developed 33 Celtic Knot Generator by Microsoft, one of the operating system that is used by BUSC and also one of the testing platform of the project. MATLAB – Short for “MATrix LABoratory”, a numerical computing environment and programing language created by The MathWorks. Tcl/Tk - is a scripting language created by John Ousterhout. It is most commonly used for rapid prototyping, scripted applications, GUIs and testing. ' 3.3 Requirement Analysis 3.3.1 System overview The essential elements of the system are to able to generate a Celtic knot with the laser-tracing method. The system should focus on the generation of the knots rather than the appeal of it. 3.3.2 Literature Survey review Following the conclusion of the Literature Survey, the choice of Celtic knot generating algorithm is based on its ease to understand, implement and further development of the system. I shall further explore the possibility of implementing the other methods here. The Tile method, the main obstacle of the implementation should be the uncountable amount of possible knots shape and combinations. And to prerender that amount knot shapes may actually require some other tools. The solution to this maybe generating the knots by another program but it will most likely be a program that is implemented with other method, which is losing the meaning of the tile approach. The first Grid method, while appealing to a computer implementation,is not without its flaw. The structure cannot be easily understood and it proofs to be difficult to implement a function without understanding the underlying meaning of the algorithm. The last method was mentioned to be the most intuitive and implementable but not without its diffuses. It may require a very well laid out data structure like the other grid method. To develop this structure, the every element of the knot has to be broken down and be evaluated to see if they are feasible to 34 Celtic Knot Generator program. 3.3.3 Project management and Scope The project started as the semester one of my final year study, but the actual programming work has not started until the second semester. Time was spent on the proposal and literature reviews which enforces the necessary knowledges of carry out the tasks of this project. During the two semesters, there will also be several other projects and works need to be done, so adequate time management is crucial in order to finish this system in time. Extensive research into Celtic knots is also important because the developer had no technical knowledge into the subject beforehand. Moreover, the I do not have too much experiences into generating graphics from a computer language except a couple fundamental computer graphic courses of his previous studies. Also the mathematical background needed to understand and implement the algorithm is essentially unpredictable. Due to all the constrains, the delivered system can only be a prototype system which represents partially the full purposed system. This also implies the development model of the software would be a evolutionary model where rapid prototypings is useful under this circumstances. 3.3.4 Deliverables This project should produce a working version of the purposed system, full documentation(this document) including the requirements, design, implementation metrics and testing results. All these should be delivered by the 3rd of May if no mitigating circumstances has happened to extend this. 3.4 System architecture A evolutionary model is to be used in the development of the system. The main reason behind this is the ease of testing different components by 35 Celtic Knot Generator embracing this method. Because in a evolutionary development model, many prototypes will be created and functionalities shall build up bit by bit over time. Moreover, during the process, each stage of the program can be validated to be working before more functions to be added. This is a win-win situation of a evolutionary model. Also owing to the fact that the system is going to focus on the implementation of a know and consistent algorithm, the requirement would not be changed by a drastic amount. So the software produced would not have the management problem of a every changing requirements which may change the already validated part of the system. A typical model of Evolutionary development 3.4.1 Choice of programming language Celtic knot is a graphic intensive topic, without a mature graphic platform, the implementation could take much longer to finish. User interaction could also be a concern due to the barrier element of the method. A language with established graphic and user-interfacing libraries could ease the implementation so effort can be spent on designing the algorithm rather than getting distracted by technical matters of a language. It should also be a widely available and used language so programming skills in that particular language can be developed and be further used in other area. The three possible solution to this problem could be either JAVA, MATLAB or Tcl/Tk. Amongst the three, Tcl/Tk is the least familiar language to me although it is famous for its rapid-prototyping and GUI developments but owing to the 36 Celtic Knot Generator constrains, I may not be able to master it to finish the system in time. MATLAB is a good choice because of its mathematics intensive background and I have worked with MATLAB for many other academic projects. One of the downside is the interfacing tools are rather limited. Although it can work with JAVA for its interface accessibility, with that said, I may just develop my whole project on one single language to minimise some unforeseeable problems between two different languages. Moreover, MATLAB require a paid software licences which may be difficult for me to obtain to work in home. JAVA is a object-oriented language with a large and widely available library and user-base. Its graphics and interface tools are also rapidly available. Also due to my working environment(consists of MAC OS X and Windows), JAVA provides a good cross-platform compatibility. Although the algorithm may have to be changed slightly to accommodate with OO structure, JAVA is certainly one of the strongest contestant of the three. Based on the above reasoning, the system shall be programmed in JAVA 1.5 platform due to the cross-platform compatibility and the easily available nature. 3.4.2 Hardware requirement Require a system that is able to compile and execute the language of choice and also of no less specification of the computer of BUCS on which the program will most likely to be executed. 3.5 System Requirement Specification The requirements stated here will be the features of the complete system where the system which will most likely be implemented would be a prototype of it. This implies some of the features may only feature in later versions after the due date of the dissertation. The features that will be most likely be implemented would be recognised by a must satisfy criteria while the extended features would be tagged with should and the least important features would be labelled by may. 37 Celtic Knot Generator 3.5.1 Functional requirements 1 Input data requirements 1.1 The two dimensions e.g. (Width and height of the grid )of the grid must be entered separately. The grid size is the base of the algorithm so it is important for the user to define it before other process to proceed 1.2 Drawing the grid must take place after the dimensions are specified The algorithm cannot proceed without a valid size and constructed grids 1.3 Users should be able to specify the barriers by clicking on any vertexes This feature is part of the additional customisation 1.4 Users should be able to erase barriers by clicking on a already existing barrier User must be able to undo undesired user input 1.5 Users must be able see the visual result of the software This is the essence of the project 1.6 Users may be able to specify the colour of the bands of knot This feature is part of the additional customisation 1.7 Users may be able to specify the width of the band of knot This feature is part of the additional customisation 1.8 Input must be carried out by both mouse and keyboard Clicking on vertex relies on a mouse while input dimensions may require a keyboard 2 User Interface requirements 2.1 The interface must consist of a panel to display the visual representation of the knot The visualisation of knot and the control interface should be separated to avoid confusion 2.2 The interface must contain the mean to input the knot 38 Celtic Knot Generator dimensions To suffice basic data requirements 2.3 The interface must contain the mean to initiate the drawing functions To let user take control of when to display the result 2.4 The interface may provide a mean to output the knot image produced This feature is part of the additional functions 3 System requirements 3.1 User must be able to create the interface after user specifies the dimensions of the grids 3.2 Associated data structures must be constructed along with the grid 3.3 User must be able to see the constructed grid 3.4 User must be able to exit the system 3.5.2 Non-Functional requirements ● The Visual output must be generated in an instant ● The software must run on BUCS machine ● Buttons on the interface must be easily accessible 39 Celtic Knot Generator Chapter 4 Design 4.1 Introduction This chapter describe how the problem is analyzed to produce a potential solution. In the requirement chapter, it is to decide that the problem is going to be solved by implementing the Laser-Tracing method with JAVA technologies. Before going into details, I shall break down the problem into objects required to construct a Celtic knot by the specific method. Firstly, I shall describe the overall system structures. Then I will identify the objects of the system and described the different stages of prototyping. 4.2 System Structure The whole system should consist of several subsystems as explained in the requirement chapter, which is the user interface, the tracer and the graphic engine. Each subsystems require date from each other to produce the final result. Their functions are summarised as below: User Interface – Consists of the interface, handles user input and passes input data to the tracer and finally display the resulting graphic Tracer – With the provided input data, generate the base grid and knot pattern and feed it to the graphic engine 40 Celtic Knot Generator Graphic engine – Plot the knot pattern as specified by the tracer, and return the plotted graph to user-interface The interactions is illustrated in the following figure: User User Interface Tracer Graphic Engine Fig Overall system Structure. 4.3 Identify the objects Before displaying the construction grid, it has to be built since this is the base data structure that the rest of the program is based on. The below illustration shows how a grid is represented Illustration 18: 2 by 2 grid 41 Celtic Knot Generator From this grid, there are several obvious components like the actual grid itself. Since it is a 2 by 2 dimension grid, so some of the components are shared in between. For example, the cyan shaded dots in the cross between the four grids. These dots are called “knotex” - the Knot vertex. This would be our first object. The red dots are also knotexes, they are distinguished with different colour for a reason. I shall explain the reason further into this chapter. The second object is the “knot_Grid” itself, which is the base unit of the knot image. The third object, which is not as apparent, is called “subGrid”, which is the small light grey coloured square located inside the grids. As the above figure shown, one “knot_Grid” is corresponding to four “subGrid”. So the above image has 16 of these “subGrid”. And finally, all these components are inside one big “knot_image”, which serves as the base of all the above objects. After the “Knotiamge” is being constructed and shown, the tracing can begin. Every points between two “knotex” is being chosen as the real construction points needed to trace the laser. These points are defined as “knotex” as well. The tracing algorithm is carried out by a logical “tracer” which begins the tracing from an invisible “knotex”. 42 Celtic Knot Generator In the case of a “barrier” existing between two “knotex”, it should have been defined as a stand alone object, but for the ease of data structure, it is being included as a single variable inside the object “knotex”. The “Knotimage” shall produce a picture according to the “tracer” All these objects should be contained in a “Main” window which include all the interfaces and handles all interactions between users and the program. Summarising the above case of tracing a pattern, we got a picture of all the objects required in this program and they are: knotex, Main, knot_Grid, subGrid, tracer, Knotimage The next subsection will describe how do these classes relate and interact with each other. 43 Celtic Knot Generator 4.4 Interaction between classes The interactions between classes is illustrated below: Main Knotimage tracer knot_Grid knotex subGrid Construct Data 44 Celtic Knot Generator 4.5 Components Design This section should mention in detail that how each of the classes should be defined and what do they represent. Coordination system: Coordination system would look different from a normal coordinate system. The system will be implemented will have Y axis exchanged position with -Y axis such that: X 0 Y A negative coordinate would not be accepted under this system. 4.5.1 Grid Grid is constructed according to the location given by the Knotimage class. Knotimage class should pass a grid the total image dimensions, the individual coordinate of the grid, an array to store knotex data and the hash table to store indexes of knotex array when it constructs a grid unit. Grid class also construct sub grid and knotexes according to the coordinate its given. It should also detects duplicated knotex created and not includes them into the array and hash table. Detecting duplicates is simple, it simply has to compare the exact coordinate of the new knotex with those on the array so far. For each Grid, it construct four sub grids and nine knotexes. 45 Celtic Knot Generator 4.5.2 sub grid This class was included in the first proposal of the system, where Gödel numbering system was still in place. Now it is only an empty structure to construct the graphic component in knot image. There are totally four different kind of sub grid, Northwestern, Southeastern, Southwestern and Northeastern. The coordinate for a subGrid is set at its top left or northwestern corner and the base length of a subgrid. The algorithm is as following: For NW subgrid: ● X coordinate = knotex X dimension + (current X location(of the grid) – 1) * (grid total dimension) ● where (grid's total dimension = (length of the width of a subgrid) *2 + (knotex X dimension) * 2) Y coordinate employs a same algorithm. ● For SW: ● X : same as NW's X ● Y: NW's Y + knotex Y dimension*2 + sub grid height * 2 Similar Algorithm applies to NE and SE corners. 4.5.3 Knotex In the system, there are altogether three different types of knotex, each of them represent a single type of vertex inside the grid. But they all have slightly different responsibility. The reason to include them into the same class is for easier management and construction. For each subgrid's corners, there must exist a knotex and depending on the subgrid's position inside a grid, the knotexes can be allocate different types. The first and second type of the knotex is the vertex of each of the grids and the centre of a grid. The barrier is defined such that a barrier can only be placed between two knotexes of the same types, either between two type one, or two type two knotexes. 46 Celtic Knot Generator The third kind of knotex is the actual construction points for the laser tracing, as I named them the “control points” . The origin design of this knotex is each knotex embraces a Gödel's numbering Scheme[Nagel and Newman, 2001], such that the knotex takes the coordinate of X, Y from the knot_grid it is located in, and depending on the edges it is located in the grid, allocates itself a number N of 5 to 8(West = 5 ->North = 6->East = 7 ->South = 8, allocating the numbers in a clockwise fashion). Such that: knotex number = 2X * 3Y * 5N So each knotex would be allocated a unique number(Gödel, Kurt 1931). And the tracer can tell where the knotex is from this number easily since the dimensions is embedded inside the number as well. But one of the major flaw of this is, there is duplicated knotex in between grids, so one knotex would embrace more than one or more ID, which basically devastated the whole numbering system. Rather than a numbering scheme, I picked up a system of a multiple-nodelinked list. Before the tracer can start tracing on these points, the system should link up all the knotexes by their relation position, like a four-way linked list where a knotex has four connections to the adjacent knotexes. The four directions would be Northwest(NW), Northeast(NE), Southeast(SE) and Southwest(SW). The reason of using these four directions is as following: The tracing trail is going through the diagonal of each sub grids, so it is sensible to let the neighbouring knotexes be the four corners of a knotex. 47 Celtic Knot Generator A number of duplicated knotex will be generated in some location where two Knot_grid locates next to each other, so a function or method will be needed to find these duplicates and only keep one of them. All of the knotex will be store in an array or a list, but this list will contains all types of knotex, so an alternative list will be created exclusively for the control points. Due to the face that the coordinate of a control point does not fill up all the “rooms” of a two or more dimensional array, so a one dimensional array will be created to store the points. Moreover, the coordinate of a knotex is not necessary following (0,0), (0,1). schemes. It will be something like the coordinate actually reflects the coordinate of the graphic engine will be plotted to the screen. For example, a knotex at the origin will have the coordinate (0,0), but the second knotex on the X axis would have the coordinate (s, 0) where s is the base of the distance between two knotex on the screen. Another concern to this is the knotex will be accessed very frequently, by looking up on an array is certainly not efficient. So a simple hash table is created to store the index of a particular knotex 's array index, and the hash table, a 2-dimensional array, can be accessed by the coordinate of the knotex. So for a knotex with (s*X, s*Y) coordinate, the hash table shall divide the coordinate by s to retrieve a normalised coordinate and using this number as the index to retrieve index number of the array the knotex is located in. Firstly, this method makes sure it does not break other function which requires applying operations on all of the knotex or control points for that matter, where they can be run through on a single dimensional array. And it ensured the performance when knotex has to be accessed individually. The knotex class also includes a boolean field to make sure that it will only be traced once. To prevent the tracer keep going back to the same knotex over and over. The algorithm to determine which edge or corner the knotex located in is straightforward, so if a knotex k is located in the X minimal edge and Y minimal edge, k is located in the NW corner. If k is at the X max and Y min edge, it is located in a SW corner. If k is at Xmin but its Y is anywhere between the Y max and Y min, then k is located at the northern edge but not at any corners. The other position can be defined by the same metrics with different X, Y of k. 48 Celtic Knot Generator 4.5.4 Tracer After Knotimage has set up all the grids, subgrids and knotexes, the tracer program would link up all the knotexes to their adjacent except the adjacent knotex is covered by a barrier so the laser cannot pass through or the adjacent is the edge barrier so the neighbour to that direction has to set to a null value. After all the linking has been done, the tracer now can walk from a randomly selected knotex with a default direction that should not change unless the tracer has walked to a knotex with a null pointer as its next neighbour of the same direction. Then the tracer has to change its direction depending on which surfaces it has hit and from which direction it hits the service. The direction changing algorithm: Assuming the knotex that the tracer is currently walked on is called k and the tracer itself is called t and the example situation is when t going to a NW direction and it is hitting knotex k with k located at the western edge of the grid. k-> getNW(returns the knotex to k's NW), but owing to the fact that k is located at the western edge, so that k's NW and SW pointers should point to null instead. N While k's NW is null, t would have to change its direction. Following the diagram above, we will be able to see that if a ray hit a west wall while coming from NW, the reflection it will produce is a ray to NE. A reflection table can be summarised as below: 49 Celtic Knot Generator The incoming ray directions The reflected directions North The location of the edges West that is getting South hit East NW NE SW SE NE SW SE SE NW NW NE SW *where empty boxes means it is impossible to happen. Table 2 Reflection table A path array will be generated during the process of tracing, it includes the data of the coordinate of the traced knotex, the nature of the knotex, like edges, corners. This array shall be passed to the Knotimage class to plot the final image. 4.5.5 Knotimage This is the class which draws the grids and plot the final knot image. Before drawing a knot panel, the Knotimage class construct all the needed objects e.g. The grids which then constructs knotexes and subgrids. Then it draws each of the objects as rectangular(a square to be exact) according the their respective coordinate and size. After the grid is set, it will start construct the tracer which will also associating the knotexes to their respective neighbours. When that is done, the knot pattern is ready to be drawn. The plotting algorithm relies on several important techniques to work. First, the graphic engine has to support quadratic curve and Bezier(higher order) curve. And the path array has to have a circular structure, which means the first few sets of coordinates are appended at the end of the array. The reason is the plotting algorithm requires a look ahead algorithm. Owing to the fact that Bezier curves needs at least two control points to construct a curve and even quadratic curves need one control point for the plotting. If the array does not have a circular structure to some extend, the look ahead algorithm will certain cause array overflow problems. The algorithm should be as following: 50 Celtic Knot Generator 1. starts with the first element of the array 2. detects whether the next knotex is located at edge or corner. 3. If it is at corner, see if the next element after the next element is also a corner element 1. if it is the case, with the next, next next elements as the control points and plot a Bezier curve to the element of current + 3 and move the pointer to the current + 3 element 4. if the next element is en edge, plot a quadratic curve with the current + 2 element by using the next element as a control point and move the pointer to the current + 2 element 5. If the next element is neither corner nor edge, plot a straight between the two points and move the pointer to the current + 1 element 6. Repeat 1- 5 until it reaches the end of array. 7. And if another path has to be drawn, pass it to step 1 and start the algorithm again. This algorithm does not take into account of a barrier existing system. 51 Celtic Knot Generator 4.6 User interface Designed Here is an overview of the design of the user interface: Title bar Width input field Height input field The Grid and plotted image panel Draw grid panel button Trace the pattern button Since the user does not have a great deal of item to input, so the interface is relatively simple. 52 Celtic Knot Generator 4.7 Prototyping As mentioned in the requirement chapter, this project embraces a evolutionary development model, which rapid prototyping is essential. So the development of the prototypes would be divided into several stages. Stage 1: the basic interface consist of the “Main” class Stage 2: the implementation of Knotimage class Stage 3: Making the Grid classes which composes of knot_grid,subGrid and knotex, and constructing a visual representation of the Grid Stage 4: Implementing the naive tracer, which ignores the barrier Stage 5: Implement the graphic plotting methods to draw the traced image without curving Stage 6: Improve the plotting algorithm to include curves rendering and thickness Stage 7: Modify tracer to include the barrier constrains, and update the plotting algorithm to accommodate the change Stage 8: Adding interlacing and other customisation of the output All of the above stages can be an exit stage of the project in case the time would run out or get stuck in some other circumstances. After each stage of prototyping, the program will be tested for possible problems and make sure it can produce desired result before moving on to the next stage. 53 Celtic Knot Generator Beginning of Prototyping Implement Stage No problems Problems occured Validating Stage Revalidate Stage objective accomplished Validating Stage As an object-oriented implementation, each classes can be tested individually up to some extend since many of them require data from other classes as suggested by the class-relationship diagram. Each of the methods of the class shall be tested to work as intended. 54 Celtic Knot Generator Chapter 5 Implementation and Test plan 5.1 Stage one of implementation The first stage of the prototyping is to create a basic interface, which is the Main class. Since the interface design is simple so I encountered no problem with the implementation. Additionally, I employed a interface building toolkit called WindowBuilder from Instantiation Inc. This toolkit further ease up the process of building interface because it deploys a WYSIWYG(What You See Is What You Get) system within the Eclipse IDE, which is the main development platform used in this project. Although WindowBuilder was not too stable, but it produces usable interface codes which is sufficient enough. The two buttons are implemented with two individual methods which invokes the initiation of the Knotimage class and the tracing methods, which are yet to be implemented. The objectives are to evaluate the interface created by WindowBuilder and the main testing involved is the two text boxes which are the only input the system would have so far. Stage one Testing: ● To produce a interface as stated at the design stage. See appendix A, for a screen shot of the design screen panel and the actual panel. ● The text boxes should only accept integer of range 2 to 30. See appendix A for detailed test results ● Exit the system by clicking on the exit icon on the title bar 55 Celtic Knot Generator 5.2 Stage two of implementation The next stage of implementation is to implement the Knotimage class which cannot do any drawing on the screens yet, because the knot classes, the underlying data structures, has not been implemented. The main purpose of this stage is to experiment with the button interactions between two different classes. The only problem encountered was that the class was basically empty so there was not much to discuss here. Testing on Stage two: ● Initiate the Knotimage class with Main class's button - place a println statement in Knotimage's constructor 5.3 Stage three of implementation Stage three involves the implementation and visualisation of the grid classes, including knot_grid, knotex, and knotSubGrid. They are the most important data structure of the whole program. Knotex, especially, is the key of the whole algorithm. Hence, this stage is one of the most important stage of the whole program. More intensive testings were carried out for this class. A number of problems arose when these classes were being implemented. One of the main problem was to do with the Godel numbering knotex construction mentioned in the design chapter. After the realisation of the duplicating knotexes issue, I went back to the design stage and rethink the situation: ● Altering the numbering system might be able to solve the duplicated objects ● Objects – knotex should be treated as objects. The numbering scheme maybe too much into procedural? ● The tracing algorithm reminded me the knotex should be connected in some logical wa ● The multi-node linked list system came up and I redesigned the whole knotex class which now consists of four pointers to the nearest neighbours 56 Celtic Knot Generator The knotSubGrid class became obsolete because of the change. The reason I kept it in the system is because it can help to render the sub knot grid section, which does not exist logically but graphically. Testing on Stage 3 ● The testing was done by graphically create a Grid of arbitrary size. The limit of the dimension, 2 to 30, is because a grid of that size cannot be displayed completely on the screen, e.g. 30*72 = 2160, which exceed most typical monitor's resolution nowdays, also the array size above that dimension will be enormous. For example, the size of the hash table is (X * 2 + 1) * ( Y * 2 + 1 ) = 4XY + 2X + 2Y+1, for each increment in X or Y, the hash table size would be increased by 6. For the purpose of this project, which is to investigate the structure of the Celtic knots and the algorithm rather than creating a Knot of size that challenges the Guinness World Record, so the maximum size of the knot would be limited to 30 by 30. ● Test of rendering, check if the interface correctly create all the components ● Test of duplicated knotex elimination – print out all total amount of valid knotex stored in the array. 5.4 Stage four of implementation The naïve tracer would only trace the standard patterns, regardless of the barriers since they are not yet implemented. The stage of the project has encountered some problems with that direction recognising algorithm. The tracer refused to trace any rectangular(n * m) grid. For example, for a 2 by 4 grids, the tracer would stop tracing the pattern when it reaches the second grid. The bug 57 Celtic Knot Generator was caused by a wrongly passed dimension parameter from the Main window to the Knotimage classes. That bug was not found because the value was not used in knotex class to construct the knotexes. Testing on Stage 4 The test will be joined with stage 5, so a visualization of the plot can be seen for easier debugging. 5.5 Stage five of implementation This stage only involves a simple plotting of the straight lines between knotexes. The method was called by a button on the interface “trace”. The naïve plot algorithm //naive plot /*for (int j = 0; j < path.length-3; j++){ polyline.lineTo(path[j][0],path[j][1]); }*/ This algorithm simply utilities java's GeneralPath class to plot the line. “path” is an array consists of all the coordinates of the tracer's tracing result. The first tracing returns a weird result, where only one path has been plotted. Then a function is added to check whether all the knotexes have been traced, if not a second tracer would start from a knotex that is next to the original one until all the knotex has been traced. while(!checkTrace()){ int path[][] = t.trace(co2knotex(start+(now*distance*2),0)); plot(path); //if (now <= Xsize){ now++; //System.out.println(now); } checkTrace{} return true if all the knotex has been traced. Testing on stage 5 ● The plotting algorithm was referenced from Sun's Java tutorial of “Drawing Arbitrary Shapes” http://java.sun.com/docs/books/tutorial/2d/geometry/arbitrary.html ● It may require less testing so the main focus of this test would be the tracer 58 Celtic Knot Generator class. ● Create an arbitrary grid and start tracing 5.6 Stage six of implementation This stage further enhance the naive plotting at stage 5, such that it would create curved edges rather than sharp diagonals by replacing the plotting method with this: while (i < int int int path.length - 3){ next_edge = path[i+1][2]; next_corner = path[i+1][3]; next_next_corner =path[i+2][3]; if ((next_edge == 1)&(next_corner == 0)){ polyline.quadTo(path[i+1][0], path[i+1][1], path[i+2][0], path[i+2][1]); i = i + 2; } if ((next_edge == 0)&(next_corner == 0)){ polyline.lineTo(path[i+1][0],path[i+1][1]); i++; } if((next_corner == 1)&(next_next_corner == 1)){ polyline.curveTo(path[i+1][0], path[i+1][1], path[i+2][0], path[i+2][1], path[i+3][0], path[i+3][1]); i = i + 3; } } A for loop cannot go through a lookahead algorithm as this, since some knotexes became control points for plotting a quadratic or Bezeir curve. So a while loop is in place to handle this algorithm. The algorithm was described in the design chapter. Testing on stage 6 Similar to Stage 5, the testing is to produce a correct plot. 5.7 Stage Seven and Eight These two stages have not been implemented due to time constrain. So stage six is my current exit point. 59 Celtic Knot Generator Chapter 6 Results Illustration 19: Result from stage 6 with random coloured bands The result obtained from stage six of the project is certainly not very satisfying. Since it is still lacking of the definitive feature of a Celtic knot – Crossings, which was planned to implement as the final stage of the development. The program proved that the tracing method is a viable way to construct Celtic knots. 60 Celtic Knot Generator Chapter 7 Conclusions There is a major disappointment into failing to achieve all the design objectives stated in the chapters before. But what done is done, looking back into the past few months, works have been done, progress have been made. The only thing lacking is the efficiency to solve problems when they emerge. From an optimistic point of view, six out of eight stages have been reach, and the algorithm derived from different sources have been successfully implemented to produce a partial result. This chapter shall evaluate each area of the system and outline some well implemented or draw back of the algorithm. 7.1 System Critique 7.1.1 Knotex The current implementation of the knotex generation is just constructing them to a relative position of the coordinate that is given by the knot grid and some parameters that is hard-coded into the class. A better solution could be passing the same metrics, such as the knotex size and sub grid sizes from the main windows, which may also be specified by users. Then the whole knot generation thing would become more reliable. Also it may open a new possibility that a rectangular shaped could use the same tracing algorithm to construct different style of Celtic knots. That may also lead to circular Celtic knots, or even more exotic pattern of pentagon Celtic knots. Also, the main problem associated with the barrier implementation is the interaction of graphics2D objects, which I cannot find the way to develop such a 61 Celtic Knot Generator method yet. If this problem can be resolved, the barrier can be implemented as another class with attributes of two knotex that the barrier is currently blocked. Nonetheless, the current knotex class is quite a mess considering it is actually a combination of two to three objects. A solution to this could be making knotex a super-class of the three different “types” of control points. So the barrier class can only be associated with the cyan and red points. The control points of the line itself should be able to detect when a barrier lies on it so it will let the tracer knows that this current control point is being blocked and the tracer will do necessary reflection to get on with the tracing. 7.1.2 Tracer The tracer, in theory, should be able to handle barrier easily if the knotex class can adopt the change suggested above. Since in the current implementation, the reflection on edges should be the same as the reflection on a barrier, refer to table 2 for detailed information about the reflection. The methods of tracer are filled with nested if-then-else statement to determine whether which is the right direction or many other decision making algorithm. A question here is if the methods can be re-designed as some recursion functions to trace the ray. It should be entirely possible. 7.1.3 Plotter The current plotter is using the GeneralPath class's method to create bezier curves and quadratic curves to connect the knotexes. The original design is the design my own Bezier curve fitting algorithm such that I have have more control over the shape and possibly create the “sharp” corner effect that exists in an usual Celtic knots. 7.2 Achievement ● To be able to conduct literature surveys into academic research fields, this gave me a new point of view into solving problems. ● Digesting different opinions of the same problem and produce a mutual understanding of the views ● To work on a problem domain which is largely unknown beforehand, and be 62 Celtic Knot Generator able to understand the problem and develop a possibly new solution ● Improve the ability to solve programming problem by looking into different direction ● First real attempt at adopting evolutionary development model ● Adequate programming skill ● Accomplishment of a difficult project ● and to finish a comprehensive document as this 7.3 Process Critique The main concern of the whole process is the failure to achieve the objectives which also left the purposed system unfinished nor without adequate polishing. We shall address the process from the early days of development: ● The possible solution could not be found earlier ● Lack of knowledges into pattern generating algorithms ● The design process took too long to finalise ● The documents took up many time from development the program ● Not up to par time management 7.4 Future work As suggested in the system critique section, the future work may be generalising the knot patterns such that not only square knots can be computed. Different kinds of polygons even generating knots in a user defined grid shape. The possibility is really unlimited. A three-dimension tracing model can also be implemented, so generating knots in three dimensional space is also possible with this method. 63 Celtic Knot Generator 7.5 The End and more... The experience I gained from the completion of this project is not restricted to the field of computer science or academic use. Many interchangeable skills like formal writing, time management, explanation of abstract ideas with diagrams and illustrations, accepting different point of views even they are against my own idea. All of these experiences can be applied to many other situation that I may have to tackle after graduation. I must say the time I spent on the project is vast, but it is well worth the effort. Although the project cannot be finished 100%, this is to tell me I still have a lot to learn before I can stand on my own. 64 Celtic knot generator Bibliography Cromwell, Peter. “Celtic knotwork: mathematical art.” Math. Intelligencer 15(1) 1993, 36-47. Nagel, E. et al.,”Godel's proof”, New York University Press, 2001 Prautzsch, H., et al., “Bezier and B-Spline Techniques”, 2002 Gödel, Kurt, "Über formal unentscheidbare Sätze der Principia Mathematica und verwandter Systeme I", Monatsheft für Math. und Physik 38, 1931, S.173-198. Sloss, Andy., “Celtic Knotwork – a Practical handbook”. Bath Press, 1995 Pizano-Rodriguez, Lyn. “Celtic Knotwork Designer”. University of Bath, 2002 Collis, John. “The Celts: Origins, Myths and Inventions”. Stroud: Tempus Publishing, 2003. ISBN 0-7524-2913-2 Delaney, Frank. “The Celts”, Grafton, London 1989 O’Corrain, Donnchadh. “Celtic Ireland”. Academy Press, January 1981 Dixon-Kennedy M., “Celtic Myth and legend: An A-Z of People and places”. Blandford Press, London, 1996. Kurta, V et al., “The Celts”, Rizzoli international Publications, Inc., New York, 1997. Megaw, R. and V., “Celtic Art: From its beginning to the Book of Kells”, Thames and Hudson Ltd., New York, 1989. Thrilling, J., “Medieval Interlace Ornament: the Making of a Cross-Cultural Idiom”, Arte Medievale, Vol. 9, 1995,pp.59-86 Fisher, G., “On Topology of Celtic Knot Designs”, California Polytechnic State University Romilly, J. A., “Celtic Art in Pagan and Christian Times”, Dover Publications, 1993. Bain, G., “Celtic Art: The Methods of Construction”, Dover Publicatoins, 1973. Bain, I., “Celtic Knotwork”, Sterling Publishings, New York, 1986. Wada, T. et al. “Modeling of Plain Knitted Fabrics for Their deformation control”, Ritsumeikan University, 1997 Abbott, S., “Steve Abbott's Computer Drawn Celtic Knotwork”, http://www.abbott.demon.co.uk/knots.html Legland, D., “Knotwork Editor”, 65 Celtic knot generator http://membres.lycos.fr/dlegland/entrelacs/entrelacs.html Temair Ingen Muiredaich, “Design and construction of Celtic Knotwork”, Pennsic XXXIII, 2004 Parks, H.G., “A process for creating Celtic knot work”, Texas A&M University, 2003 Brown, J. et al., “Real-Time Knot Tying Simulation”, Stanford Univesity, 2003 Nicolas, S.A., “Automated Drawing of Knots”, University of Kent Glassner, A., “Celtic Knotwork, Part I”, Microsoft Research, 1999 Astels, D. et al., “A practical Guide to eXtreme programming”, Prentice Hall, 2002 Flanagan, D., “JAVA in a nutshell - 5th edition”, O'Reilly, 2005 Brackeen, D., “Developing Games in Java ”, New Riders, 2003 66 Celtic Knot Generator Appendix A Test Results 1 Stage One The design panel: Illustration 20: Screen dump of the designer 67 Celtic Knot Generator Illustration 21: Screen dump of stage 1 interface The Actual window: System exit test: working as intended – system exits without producing error messages. 68 Celtic Knot Generator 2 Stage Two This line of code is added inside the constructor of the Knotimage class. public Knotimage(int Width, int Height){ ... System.out.println("Knotimage initated: "); ... ... } The console of Eclipse IDE printed the correct constructor message. Illustration 22: knotimage test 69 Celtic Knot Generator 3 Stage Three Testing for correct amount of knotex generated and checking if the Knotimage can generate a grid of specified size: These two lines of code is added to the constructor of Knotimage, where knotexList is the ArrayList which stored all instant of valid knotex(no duplciations). public Knotimage(int Width, int Height){ ... System.out.print("Total knotex: "); System.out.println(knotexList.size()); ... ... } Result: Illustration 23: Test of knotex duplication and grid constrcution The amount of knotex should be 5 * 7 = 35, just as the console reader shows. 70 Celtic Knot Generator 4 Stage Four See stage 5 tests 5 Stage Five Plotting of the naïve knot: Illustration 24: Stage 5 testing 71 Celtic Knot Generator 6 Stage Six Plotting of a curved Celtic knot. Illustration 25: Stage 6 testing 72 Celtic Knot Generator Appendix B User Documentation 1 System requirements Any operating systems and computer hardware that is supported by Sun's JAVA 1.5 JRE(Java Runtime Environment) or above would be able to run the program. 2 Compiling the source with command line interfaces ● Copy the file in /src folder to a convenient location ● execute “javac *.all” ● execute the program with “java Main” 3 Executing the binary Depending on the operating system of choice, most GUI enabled OS can execute the “Main.class” file by double clicking it and the main windows shall start up. 73 Celtic Knot Generator 4 Working with the program ● This window is the main interface, it may look slightly different depending on the Operating system. (The screen shot is taken in Apple Mac OS X 10.4.9) 1. The two text fields are to input the dimension of the grid 2. e.g. Width = 2, Height = 3 3. By pressing the “draw” button after the data has been input, the following screen will appear: 74 Celtic Knot Generator 4. Now press “trace” button: 5. By input the dimension again, go back to step 2 to obtain knots of other shapes. 6. To exit the system, click on the corner button at the title bar to close the window. 75 Celtic Knot Generator Appendix C Code Class – knot_grid.java import java.util.ArrayList; public class knot_grid{ /** knot_grid class */ long knot_no; int X; int Y; int Xcoordinate; int Ycoordinate; int Xsize = 72; int Ysize = 72; ArrayList<knotSubGrid> a = new ArrayList<knotSubGrid>(); ArrayList<knotex> b = new ArrayList<knotex>(); public knot_grid(int W, int H, int Xmax, int Ymax,ArrayList<knotex> list, int[][] hash){ Xcoordinate = (W-1)*Xsize;//the top left coorinate of the grid; Ycoordinate = (H-1)*Ysize; Y = H; X = W; knot_no = Math.round(Math.pow(2,X)*Math.pow(3,Y));//create a unique ID with the X and Y information //System.out.println("wee"); makeSubGrid(X,Y,Xmax,Ymax); makeKnotex(X,Y,Xmax, Ymax,list, hash); } public void makeSubGrid(int X, int Y,int Xmax,int Ymax){ 76 Celtic Knot Generator for (int i = 1; i <=4 ; i++){ knotSubGrid s = new knotSubGrid(X,Y,Xmax,Ymax,i); a.add(s); } } public void makeKnotex(int X,int Y, int Xmax, int Ymax, ArrayList<knotex> list,int[][] hash){ for (int i = 1; i <= 9 ; i++){ } knotex k = new knotex(X,Y,Xmax,Ymax,i); if (!duplicatedKnotex(k, list)){ b.add(k); list.add(k); int x = k.Xcoordinate/36; int y = k.Ycoordinate/36; if (k.type == 3){ hash[x][y] = list.size()-1; } /* System.out.print("X: "); System.out.println(k.Xcoordinate); System.out.print("Y: "); System.out.println(k.Ycoordinate); System.out.println("--------------");*/ }/*else{ System.out.print("rejected X: "); System.out.println(k.Xcoordinate); System.out.print("rejected Y: "); System.out.println(k.Ycoordinate); System.out.println("--------------"); }*/ } boolean duplicatedKnotex(knotex k, ArrayList<knotex> list){ boolean tmp = false; for (int i = 0; i < list.size(); i++){ knotex ktmp = list.get(i); if ((ktmp.Xcoordinate == k.Xcoordinate) & (ktmp.Ycoordinate == k.Ycoordinate)){ tmp = true; } } } return tmp; } 77 Celtic Knot Generator Class – knotex.java public class knotex { /* long belongsToGrid; long position;*/ knotex NW = null; knotex SW = null; knotex NE = null; knotex SE = null; int Xcoordinate; int Ycoordinate; int Xdimension; int Ydimension; int Xsize = 6; int Ysize = 6; int subGridsize = 30; int distance = Xsize+subGridsize; int type = 0; boolean barred = false; boolean traced = false; knotex barrier_pair = null; int corner = 0; int edge = 0; int corner_type = 0 ; public knotex(int X, int Y,int Xmax,int Ymax,int e){ Xdimension = Xmax*distance*2; Ydimension = Ymax*distance*2; switch (e){ case 1: Xcoordinate = 0 + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = 0 + (Y - 1) * (subGridsize*2 + Xsize*2); type = 1;break; case 2: Xcoordinate = subGridsize*2 + Xsize*2 + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = 0 + (Y - 1) * (subGridsize*2 + Xsize*2); type = 1;break; case 3: Xcoordinate = subGridsize*2 + Xsize*2 + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = subGridsize*2 + Ysize*2 + (Y - 1) * (subGridsize*2 + Xsize*2); type = 1;break; case 4: Xcoordinate = 0 + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = subGridsize*2 + Ysize*2 + (Y - 1) * (subGridsize*2 + Xsize*2); type = 1;break; case 5: Xcoordinate = 0 + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = subGridsize + Ysize + (Y - 1) * (subGridsize*2 + Xsize*2); type = 3;break; case 6: Xcoordinate = subGridsize + Xsize + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = 0 + (Y - 1) * (subGridsize*2 + Xsize*2); 78 Celtic Knot Generator type = 3; break; case 7: Xcoordinate = subGridsize*2 + Xsize*2 + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = subGridsize + Ysize + (Y - 1) * (subGridsize*2 + Xsize*2); type = 3; break; case 8: Xcoordinate = subGridsize + Xsize + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = subGridsize*2 + Ysize*2 + (Y - 1) * (subGridsize*2 + Xsize*2); type = 3;break; case 9: Xcoordinate = subGridsize + Xsize + (X - 1) * (subGridsize*2 + Xsize*2); Ycoordinate = subGridsize + Ysize + (Y - 1) * (subGridsize*2 + Xsize*2); type = 2;break; }; /* belongsToGrid = Math.round(Math.pow(2,X)*Math.pow(3,Y)); position = belongsToGrid*Math.round(Math.pow(5,e));*/ defEdge(); } private void defEdge(){ if ((Xcoordinate == 0)||(Ycoordinate == 0)||(Xcoordinate == Xdimension)||(Ycoordinate == Ydimension)){ edge = 1; if(edge == 1){ if (((Xcoordinate == distance)&&(Ycoordinate == Ydimension))||((Xcoordinate == 0)&&(Ycoordinate == Ydimension distance))){ corner = 1; corner_type = 4; }else if (((Xcoordinate == distance)&&(Ycoordinate == 0))||((Xcoordinate == 0)&&(Ycoordinate == distance))){ corner = 1; corner_type = 1; }else if (((Xcoordinate == Xdimension distance)&&(Ycoordinate == 0))||((Xcoordinate == Xdimension)&&(Ycoordinate == distance))){ corner = 1; corner_type = 2; }else if (((Xcoordinate == Xdimension)&&(Ycoordinate == Ydimension - distance))||((Xcoordinate == Xdimension distance)&&(Ycoordinate == Ydimension))){ corner = 1; corner_type = 3; } } } } } 79 Celtic Knot Generator class – Main.java import java.awt.*; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.*; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.SpringLayout; import javax.swing.border.LineBorder; public class Main extends JFrame { private JTextField height_input; private SpringLayout springLayout; private JTextField width_input; int Xmin = 1; int Xmax = 30; int Ymin = 1; int Ymax = 30; Knotimage k; /** * */ private static final long serialVersionUID = 4966650446155049860L; /** * Launch the application * @param args */ public static void main(String args[]) { try { Main frame = new Main(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } /* public void paintComponent(Graphics g) { super.paintComponents(g); Graphics2D g2d = (Graphics2D)g; 80 Celtic Knot Generator Rectangle2D.Double background = new Rectangle2D.Double(400, 750, 0, 0); g2d.setColor(Color.gray); g2d.draw(background); }*/ public void init(){ try{ String wi = width_input.getText(); String hi = height_input.getText(); int wiv = (Integer.valueOf(wi)).intValue(); int hiv = (Integer.valueOf(hi)).intValue(); if((wiv >= Xmin)&&(wiv <= Xmax )&&(hiv >= Ymin)&&(hiv <= Ymax)){ k = new Knotimage(wiv,hiv); k.setBorder(new LineBorder(Color.GRAY,1,true)); k.setBackground(Color.BLACK); getContentPane().add(k); getContentPane().add(k, BorderLayout.CENTER); setVisible(true); //k.selection = 1; }else{ notInt(); } }catch(NumberFormatException e){ notInt(); } } public void notInt(){ JOptionPane.showMessageDialog(this, "Please input a integer number between 2-30"); } /** * Create the frame */ public Main() { super(); setBounds(100, 100, 730, 569); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); super.setTitle("Celtic Knot Generator"); //final JPanel panel = new JPanel(); //panel.setBorder(new LineBorder(Color.GRAY, 1, true)); //panel.setBackground(Color.WHITE); //getContentPane().add(panel, BorderLayout.CENTER); final JPanel panel_1 = new JPanel(); springLayout = new SpringLayout(); panel_1.setLayout(springLayout); panel_1.setPreferredSize(new Dimension(200, 300)); panel_1.setName("controlPanel"); 81 Celtic Knot Generator panel_1.setMinimumSize(new Dimension(200, 600)); getContentPane().add(panel_1, BorderLayout.EAST); final JLabel widthLabel = new JLabel(); widthLabel.setText("Width: "); panel_1.add(widthLabel); springLayout.putConstraint(SpringLayout.EAST, widthLabel, 84, SpringLayout.WEST, panel_1); springLayout.putConstraint(SpringLayout.WEST, widthLabel, 40, SpringLayout.WEST, panel_1); springLayout.putConstraint(SpringLayout.SOUTH, widthLabel, 60, SpringLayout.NORTH, panel_1); springLayout.putConstraint(SpringLayout.NORTH, widthLabel, 44, SpringLayout.NORTH, panel_1); width_input = new JTextField(); width_input.setText("0"); width_input.setPreferredSize(new Dimension(50, 30)); width_input.setMargin(new Insets(1, 2, 1, 2)); width_input.setMinimumSize(new Dimension(10, 2)); width_input.setMaximumSize(new Dimension(10, 5)); panel_1.add(width_input); springLayout.putConstraint(SpringLayout.SOUTH, width_input, 65, SpringLayout.NORTH, panel_1); springLayout.putConstraint(SpringLayout.NORTH, width_input, 35, SpringLayout.NORTH, panel_1); springLayout.putConstraint(SpringLayout.EAST, width_input, 145, SpringLayout.WEST, panel_1); springLayout.putConstraint(SpringLayout.WEST, width_input, 95, SpringLayout.WEST, panel_1); height_input = new JTextField(); height_input.setText("0"); height_input.setPreferredSize(new Dimension(50, 30)); panel_1.add(height_input); springLayout.putConstraint(SpringLayout.SOUTH, height_input, 105, SpringLayout.NORTH, panel_1); springLayout.putConstraint(SpringLayout.EAST, height_input, 145, SpringLayout.WEST, panel_1); springLayout.putConstraint(SpringLayout.WEST, height_input, 0, SpringLayout.WEST, width_input); final JLabel heightLabel = new JLabel(); heightLabel.setText("Height: "); panel_1.add(heightLabel); springLayout.putConstraint(SpringLayout.NORTH, heightLabel, 85, SpringLayout.NORTH, panel_1); springLayout.putConstraint(SpringLayout.EAST, heightLabel, 90, SpringLayout.WEST, panel_1); springLayout.putConstraint(SpringLayout.WEST, heightLabel, 40, SpringLayout.WEST, panel_1); 82 Celtic Knot Generator final JButton drawButton = new JButton(); drawButton.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent arg0) { //System.out.println("wow"); init(); } }); drawButton.setText("Draw"); panel_1.add(drawButton); springLayout.putConstraint(SpringLayout.SOUTH, drawButton, 245, SpringLayout.NORTH, panel_1); springLayout.putConstraint(SpringLayout.EAST, drawButton, 110, SpringLayout.WEST, heightLabel); springLayout.putConstraint(SpringLayout.WEST, drawButton, 5, SpringLayout.WEST, heightLabel); final JButton traceButton = new JButton(); traceButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { k.showTrace(); } }); traceButton.setText("Trace"); panel_1.add(traceButton); springLayout.putConstraint(SpringLayout.EAST, traceButton, 100, SpringLayout.WEST, drawButton); springLayout.putConstraint(SpringLayout.WEST, traceButton, 0, SpringLayout.WEST, drawButton); springLayout.putConstraint(SpringLayout.SOUTH, traceButton, 340, SpringLayout.NORTH, panel_1); springLayout.putConstraint(SpringLayout.NORTH, traceButton, 315, SpringLayout.NORTH, panel_1); final JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); //init(); } //setVisible(true); } 83 Celtic Knot Generator class – tracer.java import java.util.ArrayList; public class tracer { int distance = 30 + 6 ; int Xdimension; int Ydimension; int numberOfKnotex; ArrayList<knotex> ptrs; Knotimage k; public tracer(Knotimage k, int X,int Y){ this.k = k; numberOfKnotex = k.knotexList.size(); this.Xdimension = X; this.Ydimension = Y; /*System.out.print("Xdimension: "); System.out.println(Xdimension); System.out.print("Ydimension: "); System.out.println(Ydimension);*/ ptrs = new ArrayList<knotex>(); ArrayList<knot_grid> arr =k.a; for (int i = 0; i < arr.size(); i++){ knot_grid kg = arr.get(i); for (int j = 0; j < kg.b.size(); j++){ knotex kx = kg.b.get(j); if (kx.type == 3){ ptrs.add(kx); } } } //System.out.println(ptrs.size()); for (int i = 0; i < ptrs.size(); i++){ connectSE(ptrs.get(i)); connectNW(ptrs.get(i)); connectSW(ptrs.get(i)); connectNE(ptrs.get(i)); //printinfo(ptrs.get(i)); } } private void connectNW(knotex knotex){ int Xtmp = knotex.Xcoordinate; int Ytmp = knotex.Ycoordinate; if ((Xtmp == 0)|(Ytmp == 0)| ((!isNull(knotex.NW))&&knotex.NW.barred)){ knotex.NW = null; }else knotex.NW =k.co2knotex(Xtmp-distance,Ytmp-distance); } private void connectNE(knotex knotex){ int Xtmp = knotex.Xcoordinate; int Ytmp = knotex.Ycoordinate; 84 Celtic Knot Generator if ((Xtmp == Xdimension)|(Ytmp == 0)| ((!isNull(knotex.NE))&&knotex.NE.barred)){ knotex.NE = null; }else knotex.NE =k.co2knotex(Xtmp+distance,Ytmp-distance); } private void connectSW(knotex knotex){ int Xtmp = knotex.Xcoordinate; int Ytmp = knotex.Ycoordinate; if ((Xtmp == 0)|(Ytmp == Ydimension)| ((!isNull(knotex.SW))&&knotex.SW.barred)){ knotex.SW = null; }else knotex.SW =k.co2knotex(Xtmp-distance,Ytmp+distance); } private void connectSE(knotex knotex){ int Xtmp = knotex.Xcoordinate; int Ytmp = knotex.Ycoordinate; if ((Xtmp == Xdimension)|(Ytmp == Ydimension)| ((!isNull(knotex.SE))&&knotex.SE.barred)){ knotex.SE = null; }else knotex.SE =k.co2knotex(Xtmp+distance,Ytmp+distance); } public int[][] trace(knotex knotex){ knotex origin = knotex; int[][] temp = new int[1000][5]; int[][] path; int lengthOfPath = 0; knotex now = origin; @SuppressWarnings("unused") knotex previous = knotex; //printinfo(knotex); int direction = 1;//direction 1 = SE, 2 = SW, 3 = NW, 4 = NE do{ //System.out.print("round: "); //System.out.println(lengthOfPath); temp[lengthOfPath][0] = now.Xcoordinate+3; temp[lengthOfPath][1] = now.Ycoordinate+3; temp[lengthOfPath][2] = now.edge; temp[lengthOfPath][3] = now.corner; temp[lengthOfPath][4] = now.corner_type; now.traced = true; switch (direction){ case 1: if(now.SE != null){ previous = now; now = now.SE; direction = getDirection(now,direction); lengthOfPath++; } 85 Celtic Knot Generator break; case 2: if(now.SW != null){ previous = now; now = now.SW; direction = getDirection(now,direction); lengthOfPath++; } break; case 3: if(now.NW != null){ previous = now; now = now.NW; direction = getDirection(now,direction); lengthOfPath++; } break; case 4: if(now.NE != null){ previous = now; now = now.NE; direction = getDirection(now,direction); lengthOfPath++; } break; } }while (!(k.compareKnot(origin, now))); path = new int[lengthOfPath+5][2]; path[lengthOfPath] = temp[0]; path[lengthOfPath+1] = temp[1]; path[lengthOfPath+2] = temp[2]; path[lengthOfPath+3] = temp[3]; path[lengthOfPath+3] = temp[4]; //path[lengthOfPath][0] = knotex.Xcoordinate; //path[lengthOfPath][1] = knotex.Ycoordinate; System.arraycopy(temp, 0, path, 0 , lengthOfPath); return path; } // direction 1 = SE, 2 = SW, 3 = NW, 4 = NE private int getDirection(knotex knotex, int direction){ switch (direction){ case 1: if ((knotex.SE == null)&(knotex.NE == null)){ return direction = 2; }else if ((knotex.SE == null)&(knotex.SW == null)){ return direction = 4; }else return 1; case 2:if ((knotex.SW == null)&(knotex.NW == null)){ return direction = 1; 86 Celtic Knot Generator }else if ((knotex.SE == null)&(knotex.SW == null)){ return direction = 3; }else return 2; case 3:if ((knotex.NE == null)&(knotex.NW == null)){ return direction = 2; }else if ((knotex.NW == null)&(knotex.SW == null)){ return direction = 4; }else return 3; case 4:if ((knotex.NE == null)&(knotex.SE == null)){ return direction = 3; }else if ((knotex.NW == null)&(knotex.NE == null)){ return direction = 1; }else return 4; }return direction; } public boolean ifedge(knotex knotex){ if((knotex.Xcoordinate == 0)||(knotex.Xcoordinate == Xdimension)||(knotex.Ycoordinate == 0)||(knotex.Ycoordinate == Ydimension)){ return true; }else return false; } public void printinfo(knotex knotex){ System.out.println("-------------------"); System.out.print("knot id: "); System.out.println(knotex); System.out.print("knot type: "); System.out.println(knotex.type); System.out.print("X coordinate: "); System.out.print(knotex.Xcoordinate/36); System.out.print(" || Y coordinate: "); System.out.println(knotex.Ycoordinate/36); System.out.print("edge: "); System.out.println(knotex.edge); System.out.print("corner: "); System.out.println(knotex.corner); if (knotex.NW!=null){ System.out.print("NW_X: "); System.out.print(knotex.NW.Xcoordinate/36); 87 Celtic Knot Generator System.out.print(" || NW_Y: "); System.out.println(knotex.NW.Ycoordinate/36); }else System.out.println("NW is null. "); if (knotex.NE!=null){ System.out.print("NE_X: "); System.out.print(knotex.NE.Xcoordinate/36); System.out.print(" || NE_Y: "); System.out.println(knotex.NE.Ycoordinate/36); }else System.out.println("NE is null. "); if (knotex.SW!=null){ System.out.print("SW_X: "); System.out.print(knotex.SW.Xcoordinate/36); System.out.print(" || SW_Y: "); System.out.println(knotex.SW.Ycoordinate/36); }else System.out.println("SW is null. "); if (knotex.SE!=null){ System.out.print("SE_X: "); System.out.print(knotex.SE.Xcoordinate/36); System.out.print(" || SE_Y: "); System.out.println(knotex.SE.Ycoordinate/36); }else System.out.println("SE is null. "); System.out.println("-------------------"); } public boolean isNull(knotex knotex){ if (knotex == null){ return true; }else return false; } } 88 Celtic Knot Generator class- knotSubGrid.java //each subgrid is a quarter of a grid public class knotSubGrid { long parent_knot_grid; long subGrid_no; int Xcoordinate; int Ycoordinate; int Xsize = 30; int Ysize = 30; int knotex_size = 6; public knotSubGrid(int X,int Y,int Xmax, int Ymax, int i){ switch (i){ case 1: Xcoordinate = knotex_size + (X - 1) * (Xsize*2 + knotex_size*2); Ycoordinate = knotex_size + (Y - 1) * (Xsize*2 + knotex_size*2); break; case 2: Xcoordinate = Xsize + knotex_size*2 + (X - 1) * (Xsize*2 + knotex_size*2); Ycoordinate = knotex_size + (Y - 1) * (Xsize*2 + knotex_size*2); break; case 3: Xcoordinate = knotex_size + (X - 1) * (Xsize*2 + knotex_size*2); Ycoordinate = Ysize + knotex_size*2 + (Y - 1) * (Xsize*2 + knotex_size*2); break; case 4: Xcoordinate = Xsize + knotex_size * 2 + (X - 1) * (Xsize*2 + knotex_size*2); Ycoordinate = Ysize + knotex_size * 2 + (Y - 1) * (Xsize*2 + knotex_size*2); break; case 5: Xcoordinate = Xsize + knotex_size + (X - 1) * (Xsize*2 + knotex_size*2); Ycoordinate = Ysize + knotex_size + (Y - 1) * (Xsize*2 + knotex_size*2); break; } } public long getID(){ return this.subGrid_no; } public long getParent(){ return this.parent_knot_grid; } } 89 Celtic Knot Generator class – Knotimage.java //For Graphics, etc. import import import import java.awt.geom.*; java.awt.*; java.util.ArrayList; java.util.Random; import javax.swing.*; public class Knotimage extends JPanel{ /** Knotimage class version 1.0 build 01052007 * This class receive data from Main and construct the X by Y grid * It also passes the infomration to the tracer class */ int Xdimension; int Ydimension; private static final long serialVersionUID = 1L; int Xsize; int Ysize; //int selection; int distance = 36; int start = distance; int now = 0; ArrayList<knot_grid> a; ArrayList<knotex> knotexList; tracer t; int [][] hash; public Knotimage(int Width, int Height){ System.out.println("Knotimage initated: "); Xsize = Width; Ysize = Height; hash = new int [Xsize*2+1][Ysize*2+1]; // hash table size is the amount of total knotex of the system. a = new ArrayList<knot_grid>(); knotexList = new ArrayList<knotex>(); makeGrids(Xsize,Ysize,knotexList, hash); System.out.print("Total knotex: "); System.out.println(knotexList.size()); Xdimension = (Xsize)*72; Ydimension = (Ysize)*72; t = new tracer(this, Xdimension, Ydimension); } public void draws(int X, int Y,int Xsize,int Ysize, int type ,Graphics2D g2){ Color c = Color.GREEN; switch (type){ 90 Celtic Knot Generator case 1: c = Color.CYAN; break; case 2: c = Color.RED;break; case 3: c = Color.GREEN;break; case 4: c = Color.darkGray;break; case 5: c = Color.gray;break; } Rectangle2D rect = new Rectangle2D.Double(); rect.setRect(X,Y,Xsize,Ysize); g2.setColor(c); g2.fill(rect); } public void plotnaive(int[][] path){ Graphics g =getGraphics(); Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, path.length-3); polyline.moveTo(path[0][0],path[0][1]); for (int j = 0; j < path.length-3; j++){ polyline.lineTo(path[j][0],path[j][1]); } g2.setColor(Color.ORANGE); g2.draw(polyline); } public void plot(int[][] path){ Graphics g =getGraphics(); Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, path.length-3); //boolean done = false; int i = 2; polyline.moveTo(path[i][0],path[i][1]); while (i < path.length - 3){ //0 = X, 1 = Y, 2 = edge, 3 = corner, 4 = cornertype int next_edge = path[i+1][2]; int next_corner = path[i+1][3]; int next_next_corner =path[i+2][3]; if ((next_edge == 1)&(next_corner == 0)){ polyline.quadTo(path[i+1][0], path[i+1][1], path[i+2][0], path[i+2][1]); i = i + 2; } 91 Celtic Knot Generator if ((next_edge == 0)&(next_corner == 0)){ polyline.lineTo(path[i+1][0],path[i+1][1]); i++; } if((next_corner == 1)&(next_next_corner == 1)){ polyline.curveTo(path[i+1][0], path[i+1][1], path[i+2][0], path[i+2][1], path[i+3][0], path[i+3][1]); i = i + 3; } } polyline.closePath(); int thickness = 5; //naive plot /*for (int j = 0; j < path.length-3; j++){ polyline.lineTo(path[j][0],path[j][1]); }*/ ArrayList<Color> c = new ArrayList<Color>(); c.add(Color.ORANGE); c.add(Color.RED); c.add(Color.GREEN); c.add(Color.CYAN); c.add(Color.BLUE); c.add(Color.MAGENTA); c.add(Color.YELLOW); c.add(Color.WHITE); Random r = new Random(); int rand = r.nextInt(8); g2.setColor(c.get(rand)); BasicStroke strk1 = new BasicStroke((float)thickness,0,0); g2.setStroke(strk1); g2.draw(polyline); //g2.setColor(Color.ORANGE); //g2.fill(polyline); //g2.setColor(Color.ORANGE); //g2.draw(polyline); } public void paint(Graphics g){ Graphics2D g2 = (Graphics2D)g; Dimension d = getSize(); g2.setBackground(getBackground()); 92 Celtic Knot Generator g2.clearRect(0,0,d.width,d.height); for (int i = 0; i < a.size(); i++){ int Xtmp = (a.get(i)).Xcoordinate; int Ytmp = (a.get(i)).Ycoordinate; int Xsize = (a.get(i)).Xsize; int Ysize = (a.get(i)).Ysize; knot_grid k = a.get(i); draws(Xtmp,Ytmp,Xsize+6,Ysize+6,4,g2); for (int j= 0; j < 4; j++){ int Xxtmp = (k.a.get(j).Xcoordinate); int Yytmp = (k.a.get(j)).Ycoordinate; int Xxsize = (k.a.get(j)).Xsize; int Yysize = (k.a.get(j)).Ysize; draws(Xxtmp,Yytmp,Xxsize,Yysize,5,g2); } } for (int h = 0 ; h < knotexList.size() ; h++){ //System.out.println("ploting"); int Xxtmp = (knotexList.get(h).Xcoordinate); int Yytmp = (knotexList.get(h)).Ycoordinate; int Xxsize = (knotexList.get(h)).Xsize; int Yysize = (knotexList.get(h)).Ysize; int type = (knotexList.get(h)).type; if (type != 3) { draws(Xxtmp,Yytmp,Xxsize,Yysize,type,g2); } } } public void showTrace(){ while(!checkTrace()){ int path[][] = t.trace(co2knotex(start+(now*distance*2),0)); plot(path); //if (now <= Xsize){ now++; //System.out.println(now); } setAutoscrolls(true); } private boolean checkTrace(){ boolean alldone = true; for (int i = 0; i < t.ptrs.size(); i++){ if (!t.ptrs.get(i).traced){ alldone = false; } }return alldone; } private void makeGrids(int X, int Y ,ArrayList<knotex> list, 93 Celtic Knot Generator int[][] hash){ int Xmax = X; int Ymax = Y; //for (int i = 1; i <= dimension; i++ ){ // new knot_grid(Y,X,Xmax,Ymax, Xmin,Ymin); //} for (int j = 1 ; j <= Y; j++){ for (int i = 1;i <= X; i++){ knot_grid k = new knot_grid(i,j,Xmax,Ymax,list, hash); //System.out.println(k); a.add(k); } } //System.out.println(list.size()); } /* public knotex id2knotex(long p){ for (int i = 0; i < knotexList.size();i++){ if (knotexList.get(i).position == p){ return knotexList.get(i); } } return null; }*/ public knotex co2knotex(int X, int Y){ return knotexList.get(hash[X/36][Y/36]); } public boolean compareKnot(knotex k1,knotex k2){ if ((k1.Xcoordinate == k2.Xcoordinate)&(k1.Ycoordinate == k2.Ycoordinate)){ return true; }else return false; } //only proceed if the width and /* private boolean checkDimension(int X, int Y){ int Xtmp = X%2; int Ytmp = Y%2; if ((Xtmp == 0)&(Ytmp == 0)){ return true; }else return false; }*/ } 94