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