Κυριακή 25 Αυγούστου 2024

Palindromes (English Variant)

After the Greek Variant of EERTREE program, I decide to make the english version. M2000 has two vocabularies, Greek and English, Also using the editor and utilizing F5 and Shift F5 we can find and change words or part of words (using Shift).

About the new variant:

We have one class, the MakeTree class, which we make a new object each time we start a palindrome search, We provide one by one character through the call of GetOne, a public member of object of class MakeTree, Each time the internal state change. We can show the internal state, the Structure using the member ShowTheStructure (M2000 isn't case sensitive, except for string type of labels, which rare used).  We have to provide a document object (it is like a string, but internal has a strucutre of paragraphs. Also the = not replace the document with new value but append the value. Also these objects have always the $ suffix, and return a string in an expression, not the object. So we use by reference, using & prefix, to put the object in the ShowTheStructure)

The Get_the_children() function walk on the strecture and make the strings putting in an temporary stack (which expand easy), and as return value the stack object converted to array object (moving fast internal stack values to a tuple - array of one dimension. Tuple have some #functions which used as toppings to convert them, and here we use the #Str() function to make a string from all tupke items.

We expect the export to clipboars (and on screen, of M2000 environment, which we have to press space or click nouse button, because Report command has a "more" function, and stop on every 3/4 of lines display of current display format).

First  number (001) is 1 internal and is the key for Tree list for specific Node. Second number is the length, and third number is the suffix. Some node have items in the myedges list. In 001 we have three items. We see keys as characters and values as numbers (the value 2 correspond to 002, is a soft link to Node(2)). Lists in M2000 works using hash tables, very fast.

So our internal structure is a List of Nodes, and each Node have three members, one of which is a List of Edges (keys of signle characters and values actually keys of List of Nodes). The other two members of Node object are Length and Suffix, and used for the construction based on input only.

Although we use the display of structure at the end, we can use it in any step to follow the construction of the structure.

The idea of eertree palindrome search tree are of Mikhail Rubinchik, Arseny M. Shur, 2015.


1. "eertree"
"ee", "e", "r", "t", "rtr", "ertre", "eertree"
Structure:
001  -1 1 {e}:=2 {r}:=4 {t}:=5
000   0 1 {e}:=3
002   1 0
003   2 2
004   1 0
005   1 0 {r}:=6
006   3 4 {e}:=7
007   5 2 {e}:=8
008   7 3
2. "banana"
"b", "a", "n", "ana", "nan", "anana"
Structure:
001  -1 1 {b}:=2 {a}:=3 {n}:=4
000   0 1
002   1 0
003   1 0 {n}:=6
004   1 0 {a}:=5
005   3 3
006   3 4 {a}:=7
007   5 5
3. "0123214bb5a7aaaa"
"bb", "aa", "aaaa", "0", "1", "2", "3", "4", "b", "5", "a", "7", "a7a", "aaa", "232", "12321"
Structure:
001   -1 1 {0}:=2 {1}:=3 {2}:=4 {3}:=5 {4}:=8 {b}:=9 {5}:=11 {a}:=12 {7}:=13
000   0 1 {b}:=10 {a}:=15
002   1 0
003   1 0
004   1 0
005   1 0 {2}:=6
006   3 4 {1}:=7
007   5 3
008   1 0
009   1 0
010   2 9
011   1 0
012   1 0 {a}:=16
013   1 0 {a}:=14
014   3 12
015   2 12 {a}:=17
016   3 15
017   4 16
4. "aaaa7a5bb4123210"
"aa", "bb", "aaaa", "a", "7", "5", "b", "4", "1", "2", "3", "0", "232", "12321", "a7a", "aaa"
Structure:
001  -1 1 {a}:=2 {7}:=6 {5}:=8 {b}:=9 {4}:=11 {1}:=12 {2}:=13 {3}:=14 {0}:=17
000   0 1 {a}:=3 {b}:=10
002   1 0 {a}:=4
003   2 2 {a}:=5
004   3 3
005   4 4
006   1 0 {a}:=7
007   3 2
008   1 0
009   1 0
010   2 9
011   1 0
012   1 0
013   1 0
014   1 0 {2}:=15
015   3 13 {1}:=16
016   5 12
017   1 0



So this is the program:

\\ https://rosettacode.org/wiki/eertree


Class MakeTree {
Private:
Tree=List
a$, Suffix=1
Class Node {
Private:
myedges=List
Public:
Suffix=0
      Property Length {Value}
Function edges(a$) {
=-1 : If Exist(.myedges, a$) Then =Eval(.myedges)
}
Function ListKey$(Here) {
=Eval$(.myedges, Here)
}
Function Where(Here) {
=.myedges(Here!)
}
Function EdgesNumber() {
=Len(.myedges)
}
Module Append_edge (a$, there) {
Append .myedges, a$:=there
}
Class:
Module Node (.[Length]) {
Read ? .Suffix
}
}
Public:
Module GetOne(x$) {
.a$+=x$
i=Len(.a$)
n=.Suffix
Do {
k=.Tree(n).Length
b=i-k-1
If b>0 Then If Mid$(.a$,b,1)=x$ Then Exit
n=.Tree(n).Suffix
} Always
e=.Tree(n).edges(x$)
If e>=0 Then .Suffix<=e :Continue
.Suffix<=Len(.Tree)
Append .Tree, .Suffix:=.Node(k+2)
.Tree(n).Append_edge x$, .Suffix
If .Tree(.Suffix).Length=1 Then .Tree(.Suffix).Suffix=0 : Continue
Do {
n=.Tree(n).Suffix
b=i-.Tree(n).Length-1
If b>1 Then If Mid$(.a$, b,1)=x$ Then Exit
} Always
e=.Tree(n).edges(x$)
If e>=0 Then .Tree(.Suffix).Suffix=e
}
Module ShowTheStructure (&here$){
For i=0 To Len(.Tree)-1
thatKey$=Eval$(.Tree, i)
For .Tree(i!) {
d$=Format$("{0}{1::-3}{2::-3}",Str$(thatKey$,"000 "),.Length,.Suffix)
If .EdgesNumber()>0 Then
For k=0 To .EdgesNumber()-1
d$+=" {"+.ListKey$(k)+"}:="+.Where(k)
Next
End If
here$=chr$(9)+d$+{
}
}
Next
}
Function Get_the_children() {
Data 0, "", 1, ""
ο=Stack
While Not Empty {
Read n, root$
For .Tree(n) {
Μ=.EdgesNumber()
If Μ=0 Then Continue
Μ--
For i=0 To Μ {
x$= .ListKey$(i)
nxt=.Where(i)
p$ = If$(n=1 -> x$, x$+root$+x$)
Stack ο {Data p$}
Push p$, nxt
}
}
}
= Array(ο)
}
Class:
Module MakeTree {
Append .Tree, 1:=.Node(-1,1),0:=.Node(0,1)
}
}


Palindromo=Lambda many (a$) ->{
Document doc$
Tree=MakeTree()
For i=1 To Len(a$)
Tree.GetOne Mid$(a$,i,1)
Next
many++
doc$= many+". "+Quote$(a$)+{
}
doc$ =  Quote$(Tree.Get_the_children()#Str$(Quote$(", ")))+{
Structure:
}
Tree.ShowTheStructure &doc$

=doc$
}
Document Final$
Final$ = Palindromo("eertree")
Final$ = Palindromo("banana")
Final$ = Palindromo("0123214bb5a7aaaa")
Final$ = Palindromo(StrRev$("0123214bb5a7aaaa"))
Report Final$
Clipboard Final$


Eύρεση Παλίνδρομων Αλφαριθμητικών σε Αλφαριθμητικό.

Το παρακάτω πρόγραμμα είναι μια διασκευή ενός προγράμματος που υπάρχει στο info ως eertree.

Σκοπός του προγράμματος είναι να δείξει πως παράγουμε όλα τα παλίνδρομα μέρη ενός αλφαριθμητικού. Παλίνδρομο είναι το αλφαριθμητικό που διαβάζεται το ίδιο και από τις δυο πλευρές. Ενός χαρακτήρα αλφαριθμητικό είναι παλίνδρομο.

Η ιδέα του EERTREE είναι των Mikhail Rubinchik, Arseny M. Shur του 2015, όπου ο αλγόριθμος εκτελείτε πολύ γρήγορα,

Σε αυτή τη διασκευή έχουμε μια κλάση που λέγεται ΦτιάξεΔένδρο. 

Η κλάση έχει ένα τμήμα που ορίζεται μετά το Κλάση: και έχει ίδιο όνομα με τη κλάση.  Αυτό το τμήμα καλείται μέσα από μια κρυφή συνάρτηση που μεταφέρει το σωρό τιμών, δηλαδή μεταφέρει παραμέτρους αν τους χρειαζόμαστε (όχι σε αυτή τη κλάση) και με την εκτέλεση εντολών διαμορφώνουμε το αντικείμενο πριν αυτό παραδοθεί κατά τη κατασκευή. Δείτε ότι και η εσωτερική κλάση έχει έναν "κατασκευαστή" που παίρνει μια ή δυο τιμές (η δεύτερη είναι προαιρετική).

Το αντικείμενο που μας δίνει η ΦτιάξεΔένδρο()  έχει τρία μέλη δημόσια, δηλαδή μπορούν να κληθούν έξω από το αντικείμενο. Βάζουμε πάντα το όνομα του αντικειμένου, τη τελεία και το όνομα του μέλους. Αν το μέλος είναι τμήμα και έχει παραμέτρους απλά βάζουμε τις παραμέτρους (χωρίς παρενθέσεις γύρω από τη λίστα παραμέτρων. Αν έχουμε συνάρτηση καλούμε τη συνάρτηση αλλά εδώ έχουμε παρενθέσεις ακόμα και αν δεν έχουμε παραμέτρους.

Το τμήμα ΠάρεΈνα με παράμετρο ένα αλφαριθμητικό. Εδώ καλούμε το τμήμα κάθε φορά που δίνουμε ένα χαρακτήρα. Πριν τη διασκευή μια αντίστοιχη λειτουργία γίνονταν για όλο το αλφαριθμητικό, και έμπαινε η παράμετρος το αλφαριθμητικό με όλα τα στοιχεία. Τώρα μπορούμε να προσθέτουμε χαρακτήρες και όποτε θέλουμε παίρνουμε το αποτέλεσμα (μια τη συνάρτηση Μάζεψε_τα_παιδιά()).

Το τμήμα ΔείξεΤηΔομή που παίρνει με αναφορά ένα αντικείμενο τύπου έγγραφο (έχει κατάληξη $ και γυρίζει αλφαριθμητικό, επίσης το = του κάνει πρόσθεση στο τέλος)

Αυτό που βλέπουμε στη δομή είναι ο αριθμός του κόμβου, ως το κλειδί σε μια λίστα κόμβων (εδώ φαίνονται οι αριθμοί με 0 στην αρχή του αριθμού και πλάτος τριών αριθμών). Μετά είναι το ΜήκοςΤμήματος, όπου έχουμε  το -1 στο πρώτο κόμβο. Μετά έχουμε τη κατάληξη (suffix), που έχει σχέση με με μέγεθος του παλίνδρομου, Δείτε ότι στην αρχή είναι 0 και κάποια στιγμή σε ορισμένους κόμβος αλλάζει. Αυτή χρειάζεται για να πάμε προς τα πίσω στο μάζεμα και να μεγαλώνουμε τα παλίνδρομα όταν πρέπει να μεγαλώσουν (πχ στο "t" έχουμε το 5 στο κόμβο 1, πάμε στο 005 και από εκεί βρίσκουμε το "r" και το 6, τυπώνουμε το rτr το οποίο γίνεται ρίζα$ και πάμε στο 006, όπου βρίσκουμε το "e" και το 7, τυπώνουμε το "ertre" και πάμε στο 007, όπου βρίσκουμε το "e" και το 8, τυπώνουμε το "eertree" και πάμε στο 008, όπου όμως δεν υπάρχει στοιχείο στη λίστα με τις άκρες! 

Για εξάσκηση πρέπει να φτιάξετε ένα πινακάκι και να εκτελέσετε το πρόγραμμα του ΠάρεΈνα και κάθε φορά γράφουμε τι αλλάζει και γράφουμε τι αλλάζει στη δομή Δένδρο και στους κόμβους που βάζουμε εκεί.

Τη Συνάρτηση Μάζεψε_τα_παιδιά(). Αυτή η συνάρτηση δουλεύει με τη δομή που δείχνει το προηγούμενο τμήμα, και εμφανίζει όλα τα παλίνδρομα. Στη διασκευή αυτή έχει καταργηθεί η αναδρομή (κλήση στον εαυτό της). και έχει μπει ο χειρισμός του σωρού τιμών (που πάντα υπάρχει διαθέσιμος σε κάθε σημείο προγράμματος). Ο σωρός τιμών σε μια συνάρτηση είναι πάντα καθαρός, αν δεν υπάρχουν παράμετροι αλλιώς έχει τις παραμέτρους. Μαζεύουμε τα παλίνδρομα σε ένα αντικείμενο επίσης σωρό τιμών. Όμως αντί να γυρίσουμε το σωρό τιμών γυρνάμε ένα πίνακα μεταφέρουμε αυτόματα τα στοιχεία του σωρού σε ένα πίνακα. Μας βολεύει ο πίνακας για να δώσουμε μετά μια εντολή που πακετάρει τα στοιχεία σε αλφαριθμητικό, η #Γραφή$(). Αυτή η συνάρτηση πρέπει να γραφτεί αμέσως μετά από έναν πίνακα (χειρίζεται το πίνακα σαν μιας διάστασης πίνακα, εφόσον έχει διάσταση!).

Εσωτερικά στη κλάση ΦτιάξεΔενδρο υπάρχουν ιδιωτικά μέλη, ένα από αυτά είναι μια κλάση, η κλάση Κόμβος. Αυτή τη κλάση τη ξέρει μόνο η ΦτιάξεΔένδρο. Ακόμα και η Κλάση Κόμβος έχει ιδιωτικά μέλη! Η ιδιότητα ΜήκοςΤμήματος μόνο διαβάζεται επειδή έχουμε δώσει μόνο το Αξία. Η ιδιωτική [ΜήκοςΤμήματος] κρατάει την τιμή πίσω από την ιδιότητα, και μέσω αυτής βάζουμε αρχική τιμή.


Το πρόγραμμα (το αντιγράφουμε σε ένα τμήμα):

\\ https://rosettacode.org/wiki/eertree


Κλάση ΦτιάξεΔένδρο {
ιδιωτικο:
Δένδρο=Λίστα
α$, Κατάληξη=1
Κλάση Κόμβος {
Ιδιωτικό:
Οι_άκρες_μου=Λίστα
Δημόσιο:
Κατάληξη=0
      ιδιοτητα ΜήκοςΤμήματος {Αξία}
Συνάρτηση άκρες(α$) {
=-1 : Αν Υπάρχει(.Οι_άκρες_μου, α$) Τότε =εκφρ(.Οι_άκρες_μου)
}
Συνάρτηση Κλειδί$(εδώ) {
=Εκφρ$(.Οι_άκρες_μου, εδώ)
}
Συνάρτηση Που(εδώ) {
=.Οι_άκρες_μου(εδώ!)
}
Συνάρτηση ΠόσεςΑκρες() {
=Μήκος(.Οι_άκρες_μου)
}
Τμήμα προσθήκη_άκρης (α$, που) {
Προσθήκη .Οι_άκρες_μου, α$:=που
}
Κλάση:
Τμήμα Κόμβος (.[ΜήκοςΤμήματος]) {
Διάβασε ? .Κατάληξη
}
}
Δημόσιο:
Τμήμα ΠάρεΈνα(χ$) {
.α$+=χ$
ι=μήκος(.α$)
ν=.Κατάληξη
Επανάλαβε {
κ=.Δένδρο(ν).ΜήκοςΤμήματος
β=ι-κ-1
Αν β>0 Τότε Αν Μεσ$(.α$,β,1)=χ$ Τότε Έξοδος
ν=.Δένδρο(ν).Κατάληξη
} Πάντα
ε=.Δένδρο(ν).άκρες(χ$)
Αν ε>=0 Τότε .Κατάληξη<=ε :Συνέχισε
.Κατάληξη<=Μήκος(.Δένδρο)
Προσθήκη .Δένδρο, .Κατάληξη:=.Κόμβος(κ+2)
.Δένδρο(ν).προσθήκη_άκρης χ$, .Κατάληξη
Αν .Δένδρο(.Κατάληξη).ΜήκοςΤμήματος=1 Τότε .Δένδρο(.Κατάληξη).Κατάληξη=0 : Συνέχισε
Επανέλαβε {  ' ή Επανάλαβε (είναι το ίδιο εδώ)
ν=.Δένδρο(ν).Κατάληξη
β=ι-.Δένδρο(ν).ΜήκοςΤμήματος-1
Αν β>1 Τότε Αν Μεσ$(.α$, β,1)=χ$ Τότε Έξοδος
} Πάντα
ε=.Δένδρο(ν).άκρες(χ$)
Αν ε>=0 Τότε .Δένδρο(.Κατάληξη).Κατάληξη=ε
}
Τμήμα ΔείξεΤηΔομή (&εδώ$){
Για ι=0 έως Μήκος(.Δένδρο)-1
κλ$=Έκφρ$(.Δένδρο, ι)
Για .Δένδρο(ι!) {
εγγραφή$=Μορφη$("{0}{1::-3}{2::-3}",γραφη$(κλ$,"000 "),.ΜήκοςΤμήματος,.κατάληξη)
Αν .ΠόσεςΑκρες()>0 τότε
για κ=0 έως .ΠόσεςΑκρες()-1
εγγραφή$+=" {"+.Κλειδί$(κ)+"}:="+.Που(κ)
επόμενο
τέλος αν
εδώ$=χαρ$(9)+εγγραφή$+{
}
}
Επόμενο
}
Συνάρτηση Μάζεψε_τα_παιδιά() {
Σειρά 0, "", 1, ""
ο=Σωρός
Ενώ Όχι Κενό {
Διάβασε ν, ρίζα$
Για .Δενδρο(ν) {
Μ=.ΠόσεςΑκρες()
Αν Μ=0 Τότε Συνέχισε
Μ--
Για ι=0 Έως Μ {
χ$= .Κλειδί$(ι)
εκεί=.Που(ι)
ρ$ = Αν$(ν=1 -> χ$, χ$+ρίζα$+χ$)
Σωρος ο {Σειρά ρ$}
Βάλε ρ$, εκεί
}
}
}
= Πίνακας(ο)
}
Κλάση:
Τμήμα ΦτιάξεΔένδρο {
Προσθήκη .Δένδρο, 1:=.Κόμβος(-1,1),0:=.Κόμβος(0,1)
}
}


Παλίνδρομο=Λάμδα τόσα (α$) ->{
Εγγραφο εγγραφο$
Δένδρο=ΦτιάξεΔένδρο()
για ι=1 εως μήκος(α$)
Δένδρο.ΠάρεΈνα Μεσ$(α$,ι,1)
επόμενο
τόσα++
εγγραφο$= τόσα+". "+παράθεση$(α$)+{
}
εγγραφο$ =  Παράθεση$(Δένδρο.Μάζεψε_τα_παιδιά()#Γραφή$(Παράθεση$(", ")))+{
Δομή:
}
Δένδρο.ΔείξεΤηΔομή &εγγραφο$
=εγγραφο$
}
Έγγραφο Τελικό$
Τελικό$ = Παλίνδρομο("eertree")
Τελικό$ = Παλίνδρομο("banana")
Τελικό$ = Παλίνδρομο("0123214bb5a7aaaa")
Τελικό$ = Παλίνδρομο(Αναπ$("0123214bb5a7aaaa"))
Αναφορά Τελικό$
Πρόχειρο Τελικό$




Εδώ είναι το αποτέλεσμα (που βγάλαμε στο πρόχειρο, έχω προσθέσει χρώμα)

1. "eertree"
"ee", "e", "r", "t", "rtr", "ertre", "eertree"
Δομή:
001  -1 1 {e}:=2 {r}:=4 {t}:=5
000   0 1 {e}:=3
002   1 0
003   2 2
004   1 0
005   1 0 {r}:=6
006   3 4 {e}:=7
007   5 2 {e}:=8
008   7 3
2. "banana"
"b", "a", "n", "ana", "nan", "anana"
Δομή:
001  -1 1 {b}:=2 {a}:=3 {n}:=4
000   0 1
002   1 0
003   1 0 {n}:=6
004   1 0 {a}:=5
005   3 3
006   3 4 {a}:=7
007   5 5
3. "0123214bb5a7aaaa"
"bb", "aa", "aaaa", "0", "1", "2", "3", "4", "b", "5", "a", "7", "a7a", "aaa", "232", "12321"
Δομή:
001  -1 1 {0}:=2 {1}:=3 {2}:=4 {3}:=5 {4}:=8 {b}:=9 {5}:=11 {a}:=12 {7}:=13
000   0 1 {b}:=10 {a}:=15
002   1 0
003   1 0
004   1 0
005   1 0 {2}:=6
006   3 4 {1}:=7
007   5 3
008   1 0
009   1 0
010   2 9
011   1 0
012   1 0 {a}:=16
013   1 0 {a}:=14
014   3 12
015   2 12 {a}:=17
016   3 15
017   4 16
4. "aaaa7a5bb4123210"
"aa", "bb", "aaaa", "a", "7", "5", "b", "4", "1", "2", "3", "0", "232", "12321", "a7a", "aaa"
Δομή:
001  -1 1 {a}:=2 {7}:=6 {5}:=8 {b}:=9 {4}:=11 {1}:=12 {2}:=13 {3}:=14 {0}:=17
000   0 1 {a}:=3 {b}:=10
002   1 0 {a}:=4
003   2 2 {a}:=5
004   3 3
005   4 4
006   1 0 {a}:=7
007   3 2
008   1 0
009   1 0
010   2 9
011   1 0
012   1 0
013   1 0
014   1 0 {2}:=15
015   3 13 {1}:=16
016   5 12
017   1 0

Τρίτη 20 Αυγούστου 2024

Greek and Türkiye flags

I would like to show Greek and Türkiye flags, drawing by programming, in one post. Although we had fights many times ago,  I hope these two countries to be like brothers, to care for each other. I hope Türkiye be an officially part  of EU for real as soon as posible.


Greek Flag




module GreekFlag (x1=3000, y1=3000, z=12000) {
const white=#FFFFFF
const cyan=#001489


z1027=z*10/27
zs=z-z1027
// ratio 2/3
z1=z*2/3
z19=z1/9
move x1, y1

pen cyan {
polygon cyan, z,0, 0, z1, -z, 0, 0, -z1
}
pen white {
step z1027, z19
polygon white, zs,0, 0, z19, -zs, 0, 0, -z19
step 0, z19*2
polygon white, zs,0, 0, z19, -zs, 0, 0, -z19
step -z1027, z19*2
polygon white, z,0, 0, z19, -z, 0, 0, -z19
step 0, z19*2
polygon white, z,0, 0, z19, -z, 0, 0, -z19
step 0, z19*-5
polygon white, z1027,0, 0, z19, -z1027, 0, 0, -z19
step z19*2, z19*-2
polygon white, z19,0, 0, z19*5, -z19, 0, 0, -z19*5
}
}
cls,0
GreekFlag
GreekFlag 18000, 3000, 6000
drawing {
GreekFlag
} as greekflag
move 8000,10000
image GreekFlag, 9000,,30
a$=key$



Türkiye Flag





// https://en.wikipedia.org/wiki/Flag_of_Turkey
CLS, 0
white=#FFFFFF
red=#E30A17
x1=3000
y1=2000
L=9000
G=L/1.5
A = G DIV 2
B = G DIV 4
C = G DIV 16
D = G * 2/5
E = G / 3
F = G DIV 2
drawing {
STEP -L/2,-G/2
PEN RED {
POLYGON RED, L, 0, 0, G, -L, 0, 0, -G
}
STEP A, A
PEN WHITE {
CIRCLE FILL WHITE, F/2
}
STEP C, 0
PEN RED {
CIRCLE FILL RED, D/2
}
STEP E-D/2+B/2, 0
drawStar(B/2)
} as t_flag
move x1+L/2, y1+G/2
image t_flag, 8000,,0
STEP 0, G*1.2
CIRCLE FILL WHITE, 3000
image t_flag, 3000*1.125,,5


MOVE 20000, 8000
image t_flag, 8000,,-90


A$=KEY$


sub drawStar(d)
local dd=d*tan(36), k=pi/10
step -d, 0
pen white {polygon white, angle k, dd, pi/2, dd, 3*pi/2+k*2, dd, k, dd, -k*2-pi/2, dd, 3*pi/2+k*2, dd, -k+pi, dd, -k*2-pi/2, dd, pi/2, dd, -k+pi, dd}
step d, 0
end sub




Union Flag (updated)


The updated example show the use of drawing to an EMF in memory and then drawing the EMF using rotation 30 degree.

This example show the use of  masking the graphic output by using a path, a surface too place graphics. We need that because we have the slope bands on union flag. Check the flag without using the Path  {} instruction. Paths reset using Path {}; statement or using CLS statement.

Also this example use polar coordinates for specific parts, using absolute direction in radians, and distance in twips (we can use negative values also). Step, Draw and Polygon  use the ANGLE variation (Curve also has ANGLE variation, but not used here).

We see the module which use parameters with initial vsalue, if we didn't provide the parameter. Although we can use this for modules and functions, for modules there is a risk, if we didn't clear the stack of values, before the call, and there are some values on it, it seems for interpretr that we pass some values as arguments. How to not use the remain values of a stack: 1) We use a Stack { } block providing temporary a new empty stack object, we put the call inside the block. 2) We place ? when we use to quide the interpreter to use the initial value. If we didn't provide one we get an error (Variable X can't initialised),



 

Run m2000.exe (the M2000 Interpreter), write Edit A and then copy this program. Press Esc and write Save UnionFlag to save it, Now write A and press enter to execute,

We get Union |Flag at 3/5 and 1/2 ratio.

// https://en.wikipedia.org/wiki/Flag_of_the_United_Kingdom
// https://www.flagcolorcodes.com/united-kingdom
CLS 5,0


module UnionFlag(X1=3000, Y1=1000, z=10000, RATIO=.6) {
RED=#C8102E
BLUE=#012169
WHITE=#FFFFFF
z50=z div 50
z1=int(z*RATIO)
z130=z1 div 30


MOVE X1,Y1
PATH {
POLYGON 0, z+twipsX, 0, 0, z1+twipsY, -z-twipsX, 0, 0,-z1-twipsY
};
PEN BLUE {POLYGON BLUE, z+twipsX, 0, 0, z1+twipsY, -z-twipsX, 0, 0,-z1-twipsY}
MOVE X1+Z/2,Y1+Z1/2
P=ATN(Z1/Z)/180*PI
Z2=SQRT(Z1**2+Z**2)
STEP ANGLE P, -Z2/2
STEP ANGLE P+PI/2, -Z130*3
PEN WHITE {POLYGON WHITE, ANGLE P, Z2, P+PI/2, Z130*6, P, -Z2, P+PI/2, -Z130*6}
STEP ANGLE P+PI/2, Z130
PEN RED {POLYGON RED, ANGLE P, Z2/2, P+PI/2, Z130*2, P, -Z2/2, P+PI/2, -Z130*2}
STEP ANGLE P+PI/2, Z130*2
STEP ANGLE P, Z2/2
PEN RED {POLYGON RED, ANGLE P, Z2/2, P+PI/2, Z130*2, P, -Z2/2, P+PI/2, -Z130*2}
MOVE X1+Z/2,Y1+Z1/2
oldp=p
p=pi/2-p
STEP ANGLE P-PI/2, -Z2/2
STEP ANGLE P, Z130*3
PEN WHITE {POLYGON WHITE, ANGLE P+pi/2, -Z2, P, -Z130*6, P+pi/2,Z2, P, Z130*6}
STEP ANGLE P, -Z130*3
PEN RED {POLYGON RED, ANGLE P+pi/2, -Z2/2, P, -Z130*2, P+pi/2,Z2/2, P, Z130*2}
STEP ANGLE P, Z130*2
STEP ANGLE P+PI/2, -Z2/2
PEN RED {POLYGON RED, ANGLE P+pi/2, -Z2/2, P, -Z130*2, P+pi/2,Z2/2, P, Z130*2}
p=oldp
MOVE X1+Z/2,Y1+Z1/2


STEP -z50*5, -z1/2
PEN white {POLYGON white, z50*10, 0, 0,z1, -z50*10, 0, 0, -z1}
STEP z50*5-z/2, z1/2
STEP 0, -z130*5
PEN white {POLYGON white, z, 0, 0, 10*z130, -z, 0, 0, -10*z130}
STEP z/2, z130*5


STEP -z50*3, -z1/2
PEN red {POLYGON red, z50*6, 0, 0,z1, -z50*6, 0, 0, -z1}
STEP z50*3-z/2, z1/2
STEP 0, -z130*3
PEN red {POLYGON red, z, 0, 0, 6*z130, -z, 0, 0, -6*z130}
STEP z/2, z130*3
path {};
}
unionFlag 1000,8100, 15000, 0.5
unionFlag
unionFlag 16000,1000, 8000
unionFlag 18000,9000, 8000, 0.5
drawing {
unionFlag
} as unionFlag
move 8000,10000
image unionFlag, 9000,,30
a$=key$