08 maja 2016
Wojciech Jóźwiak
Serial: Astro-obserwator
Rozsuwanie glifów planet
◀ Astro-choroby. Choroba jako energia ◀ ► „Astrologia Ilustrowana” – cykl webinarium ruszył i zapraszam! ►
Gdzie rysować i jak rozmieszczać planety na wykresie kosmogramu, a raczej ich „znaczki” czyli glify? Gdy planety są w koniunkcjach, ich glify rysują się jedne na drugich, a tego trzeba uniknąć. Ludzki rysownik intuicyjnie jakoś je rozsunie. Jak to rozsunięcie zaprogramować? Człowiek widzi obraz kosmogramu jako jedną całość, program nie widzi. Program dostaje ciąg liczb, będących położeniami planet i coś musi z nimi zrobić. Musi wykonać odpowiedni algorytm.
To jest przykładowy kosmogram surowy, bez rozsunięcia planet:
A tu z glifami rozsuniętymi:
Oba przedstawiają urodzeniowy kosmogram Amy Winehouse.
Co robi algorytm? – Wyszukuje klastry (koniunkcje) planet. Najpierw sortuje planety, czyli ustawia je na liście w kolejności ich położeń (długości ekliptycznych). Następnie kolejno (w pętlach) sprawdza, czy wszystkie 10 planet nie tworzą razem jednej wielkiej koniunkcji (klastra, zbitki). Jeśli nie tworzą, to robi to samo dla 9-ciu: sprawdza, czy nie ma koniunkcji po 9 planet. Jeśli nie, to obniża liczbę szukanych zbitek do 8, 7, … itd. Jeśli okaże się, że powiedzmy któreś 4 kolejne planety zbitkę tworzą, to wylicza dla ich glifów nowe rozsunięte długości (położenia kątowe), po czym skreśla te planety z listy, żeby nie przeszkadzały w dalszym wyszukiwaniu. I tak dochodzi do liczby 2 i sprawdza, czy wśród pozostałych planet są koniunkcje po dwie planety – które trzeba rozsunąć.
Taka jest szkicowa idea – a tu jej realizacja jako funkcja w języku JavaScript:
// skrypt JS robiący tablicę długości rozsuniętych glifów
// glyph_separate.js
// _glyphSpace = 7;
function separated(_longs, _glyphSpace){
// _longs – tablica długości planet, _glyphSpace – kąt, jaki zajmuje jeden glif; w stopniach
// Niżej liczymy, ile jest planet (lcount), bo może ich być więcej lub mniej niż 10.
// Po czym przygotowujemy tablicę długości rozesparowanych glifów, longsSeparated.
var lcount = _longs.length;
var longsSeparated = _longs.slice(0);
// Sortujemy tablicę długości, a następnie tworzymy tablicę numerów-identyfikatorów planet
// ustawionych w kolejności rosnącej ich długości, pod nazwą „free”:
var longsSorted = [];
for (var k=0; k=lcount) j=0;
dist = _longs[free[j]] -_longs[free[k]]; if (dist<0) dist += 360.0;
if (dist _glyphSpace){
return _longs;
// To jest właśnie ten przypadek, kiedy dalej nic nie robimy!
}
else
{
// Gdy jednak są klastry... zaczynamy ich szukać.
// Dla wygody ustalamy nową kolejność planet. Początkiem będzie planeta,
// która leży na końcu największego dystansu („rozstępu”):
var maxDist=0.0;
var startQueue;
for (var k=0; k=lcount) j=0;
dist = _longs[free[j]] -_longs[free[k]]; if (dist<0) dist += 360.0;
if (dist>maxDist) {
maxDist = dist;
startQueue = j;
}
}
// Przesuwamy kolejkę „wolnych” planet, od tej od największego dystansu:
var newfree = [];
for (var k=0; k=lcount) j -= lcount;
newfree[k] = free[j];
}
free = newfree;
newFree = []; // pusta.
// Tu zaczyna się mega-pętla, wyszukująca kolejne klastry.
// Oznaczenia: vol: objętość bieżacej próbki planet, beg: początek próbki,
// freeCount: liczba planet do przebadania, clusterMid: środek klastra,
// clusterSize: szerokość klastra, clusterSize2: pół szerokości klastra,
// currPlanetNum: pomocnicza zmienna.
var vol = lcount;
var beg = 0;
var freeCount = lcount;
var clusterMid;
var clusterSize;
var clusterSize2;
var currPlanetNum;
var newFree=[];
do {
// Sprawdzamy, czy bieżący ciąg planet jest klastrem:
dist = _longs[free[beg+vol-1]]-_longs[free[beg]];
if(dist<0) dist +=360.0;
clusterSize = _glyphSpace * (vol-1);
if(dist < clusterSize){
// TAK, jest klastrem! – Liczę środek klastra:
clusterMid = 0.5 * (_longs[free[beg+vol-1]] + _longs[free[beg]]);
clusterSize2 = 0.5 * clusterSize;
// przesuwam planety z tego ciągu/klastra, tzn. nadaję ich glifom nowe długości:
for(k=0; k=beg+vol)){
newFree[j] = free[k];
j++;
}
}
if(newFree.length>0){
free = newFree.slice(0);
freeCount = free.length;
newFree = []; //znow pusta.
if(vol>freeCount) {
vol = freeCount;
}
beg = -1;
// Dlaczego „beg = -1”? – ponieważ za chwilę zostanie powiększona o 1.
}
}
// Instrukcje wspólne dla przypadków klastra i nie-klastra:
if(beg+vol < freeCount){
// bieżąca próbka nie osiągnęła końca listy planet przy danym vol – zwiększamy beg:
beg++;
} else {
// próbka osiągnęła koniec – zmniejszamy vol, beg=0
vol--;
beg = 0;
}
}
while (vol>1);
// Koniec mega-petli!
return longsSeparated;
} // end wariantu, kiedy coś ROBIMY.
} // koniec calej funkcji.
◀ Astro-choroby. Choroba jako energia ◀ ► „Astrologia Ilustrowana” – cykl webinarium ruszył i zapraszam! ►
Komentarze

-- Amerykański gangster Lucky Luciano.
Aby komentować Zaloguj się lub Zarejestruj w Tarace.
