### Matemaatilise töötluse eeltingimused
1. **Digitaliseerimine**
* Skaneeri mustrid vähemalt 600 dpi eraldusvõimega, et säilitada üksikute “ruutude” (pistete) täpsus.
* Kasuta skanneri tarkvaras „tühja tausta eemaldamist“ ning teisenda pildid tummaks‑valgeks binaarfailiks (PNG).
2. **Ruudustiku konversioon**
* Avasta mustri “grid” – tavaliselt 8 × 8 või 12 × 12 ruutu, sõltuvalt kinda suurusest.
* Pythonis saab kasutada `numpy`‑i ja `opencv`‑i funktsioone: pildist eraldada kontuurid (`cv2.findContours`) ning määrata iga ruudu keskmine intensiivsus (0 = valge, 1 = must).
3. **Sümmeetria tuvastamine**
* Pakett `symmetry` (PyPI) võimaldab sisestada binaar‑maatriksi ja testida translatsiooni‑, peegeldus‑ ning pööramisoperatsioone automaatselt.
* Alternatiivina on `pattern`‑raamatukogu või R‑pakett **patterntools**, mis pakub grupite (pm, p4m jne) klassifikatsiooni.
4. **Alammustrite eraldamine**
* Kasuta klasterdamist (`sklearn.cluster`) ruutude vektorruumis, et leida korduvad alam‑mustrid (nt “kaheksakand” ühe 3 × 3 ploki sees).
* Tuvastatud alammustrid dokumenteeritakse tabelina: **alammuster ID**, **kuju** (bitstring), **sümmeetriaoperaatorid**, **esinemissagedus**.
5. **Andmete struktureerimine ja säilitamine**
* Salvestada tulemused JSON‑vormingus, kus iga muster sisaldab metaandmeid: `source_id`, `region`, `symmetry_group`, `tile_matrix`.
* Integreeri need ERMi digikogu metaandmetega (kasutades nende API‑d), et võimaldada otsinguid “sümmeetria=R8” jne.
---
### Matemaatilise töötluse eeltingimused – digitaliseerimise soovitused
1. **Skaneerimine**
* Kasuta vähemalt 300 dpi resolutsiooni, et säilitada ruudustiku täpsus.
* Skannitud pildid salvestada lossless‑formaati (TIFF/PNG).
2. **Pildi eeltöötlus**
* `OpenCV` või `scikit-image`: binariseerimine (`cv2.threshold`) ja ruudustiku joone eraldamine morfoloogiliste operatsioonidega (erosion/dilation).
* Ruudustiku tuvastamiseks sobib `HoughLineTransform`, mis annab paralleelsete joonte koordinaadid.
3. **Ruudustikuga konverteerimine**
* Joonistatud mustri rasteriseerimise asemel loe ruudu‑indeksid (rida, veerg) ja genereeri 0/1 maatriks.
* Pythonis:
```python
import numpy as np
from skimage import io, filters
img = io.imread('kinda.png', as_gray=True)
binary = img < filters.threshold_otsu(img) # must-valge pilt
grid_size = 8 # ruudu suurus pikslites (kohanda)
rows = binary.shape[0] // grid_size
cols = binary.shape[1] // grid_size
matrix = np.zeros((rows, cols), dtype=int)
for i in range(rows):
for j in range(cols):
cell = binary[i*grid_size:(i+1)*grid_size,
j*grid_size:(j+1)*grid_size]
matrix[i,j] = int(cell.mean() > 0.5) # 1 = täidetud ruut
```
4. **Sümmeetriaoperaatorite tuvastamine**
* `sympy` paketi klass `PointGroup` võimaldab testida pööre- ja peegeldusoperatsioone antud maatriksile:
```python
from sympy.combinatorics import Permutation, PermutationGroup
# define 90° pööramine (R4) jne ning kontrolli invariantsust matrixiga
```
* Alternatiivina `pymatgen` või `spglib` raamatukogud pakuvad kristallograafilisi rühmi (`SpacegroupAnalyzer`).
5. **Mustri rekonstrueerimine ja klassifikatsioon**
* Loo generatiivne funktsioon, mis rakendab leitavad operaatorid algmustrile (tavaliselt üks alammuster). Kontrolli, kas `np.allclose(generated_matrix, original_matrix)`.
* Klasifitseeri muster ruudustikugruppide (`pm`, `p2mg` jne.) põhjal; see võimaldab automatiseeritud sorteerimist suurte andmekogude (ERM‑kogu > 10 000 mustrit) puhul.
6. **Tööriistad ja raamatukogud**
* **Python:** `opencv-python`, `scikit-image`, `numpy`, `sympy`, `spglib`.
* **R:** pakett `pattern` (sümmeetria analüüs).
* **Web‑põhised:** `Patternify` (open‑source JavaScript), mis loeb ruudustikupilte ja genereerib SVG‑mustri.
7. **Andmete salvestamine**
* Soovitatav formaat: JSON, kus võtmed on “grid”, “symmetry_group”, “region”. Näide:
```json
{
"name": "Silmus-nelinurk",
"region": "Võrumaa",
"grid": [[0,1,0,…],[1,1,1,…],…],
"symmetry_group": "p2mg"
}
```
* See võimaldab hiljem kasutada masinõppe‑analüüsi (nt klasterdamine `scikit-learn`).
---
## **Andmebaasisüsteemis mustrite säilitamine – tehniline raamistik ja suhtlusstrateegiad**
> **Eesmärk:** Tagada Eesti traditsiooniliste kindamustri (näiteks Kihnu romb, Muhu kaheksakand jne.) strukturaalne terviklikkus, otsitavus ning pikaajaline kättesaadavus erinevate uurimis‑ ja rakendusvaldkondade vajaduste jaoks.
Alljärgnevas juhendis esitatakse **normeeritud andmemudel**, **tehnoloogilised valikud** (RDBMS vs. NoSQL), **andmetüübid** ning **interaktsioonimehhanismid** (API‑d, päringud, versioonihaldus). Kõik soovitused on kooskõlas kaasaegsete andmehalduse parimate tavadega ja võimaldavad sujuvat integratsiooni GIS‑-, tekstiiliteaduse‑ ning arvutusliku kultuuriteaduse platvormidega.
---
## 1. Andmemudel – loogiline skeem
| Tabel | Kirjeldus | Olulised väljad (andmetüüp) |
|-------|----------|-----------------------------|
| **Pattern** | Üldine meta‑info üksikmustri kohta | `pattern_id` PK, `name` VARCHAR, `region` VARCHAR, `motif_type` VARCHAR, `color_palette` JSONB (nt `["punane","valge","must"]`), `symmetry_group` VARCHAR, `creation_date` TIMESTAMP, `version` INTEGER |
| **PatternMatrix** | Binaarne ruudustik (8×8 või muu mõõde) | `pattern_id` FK, `width` SMALLINT, `height` SMALLINT, `matrix` BYTEA *või* `integer[]`, `legend` JSONB |
| **Symmetry** | Sümmeetria‑teisenduste loetelu | `sym_id` PK, `pattern_id` FK, `type` VARCHAR (`reflection`,`rotation`,`translation`), `parameters` JSONB (nt `{ "axis":"x=4" }`) |
| **FundamentalRegion** | Fundamentaalpiirkonna geomeetriline kirjeldus | `region_id` PK, `pattern_id` FK, `shape` VARCHAR (`rectangle`, `pentagram` jne.), `coordinates` JSONB (loetelu `[ [x1,y1], … ]`) |
| **Decomposition** | Mustri lõhkumine alamosadeks | `decomp_id` PK, `pattern_id` FK, `part_label` VARCHAR, `submatrix` BYTEA või `integer[]`, `restore_rule` TEXT |
> **Märkus:** Kõik tabelid on normaliseeritud 3NF‑tasemele; korduvad andmed (nt värvipalett) hoitakse JSONB‑vormis, mis võimaldab indekseerimist ja paindlikku skeemi laiendamist.
---
## 2. Tehnoloogiline valik – RDBMS vs. NoSQL
| Kriteerium | Relatsiooniline DB (PostgreSQL + PostGIS) | Dokument-orienteeritud DB (MongoDB) |
|------------|-------------------------------------------|-------------------------------------|
| **Struktuurne kindlus** | Tugev, skeemi kontroll (`CHECK`, `FOREIGN KEY`) | Paindlik, skeemivaba – sobib kiireks prototüüpimiseks |
| **Binaarne maatriks** | `BYTEA` või *array*‑tüübid; PostGIS võimaldab geomeetrilist indekseerimist (ruutvõrk) | BSON‑binary (`BinData`) – otse salvestamine, kuid keerulisem arvutuslik päring |
| **Sümmeetria‑päringud** | `jsonb_path_ops` + GIN‑indeksid; PostGIS funktsioonid (`ST_Rotate`, `ST_Reflect`) võimaldavad geomeetrilist transformatsiooni otse DB‑s | Aggregatsiooniputkude kaudu, kuid puuduvad sisseehitatud geomeetrilised operandid |
| **Versioonihaldus** | *Temporal tables* (pg_partman) või `transaction_timestamp` + `version` veerg | Dokumentide versiooni kontroll (`$setOnInsert`, `$push`) |
| **Skaleeritavus** | Horisontaalne partitsioneerimine, replikatsioon (Patroni/PGPool) | Sharding (Mongo‑shard), automaatne skaleerumine |
### Soovitus
- **Esmane valik:** *PostgreSQL* koos laiendustega `jsonb`, `int[]` ja *optional* `PostGIS`. See pakub tugevad ACID‑garantiid, võimsad indekseerimisvõimalused (GIN/GIST) ning võimaluse teostada geomeetrilisi operatsioone otse andmebaasis – eriti oluline sümmeetriaanalüüsi automatiseerimisel.
- **Alternatiiv:** *MongoDB* sobib projektidele, kus on vaja väga suurt skeemi paindlikkust ja dokumentide hierarhilist struktuuri (nt komplektid, mis sisaldavad tuhandeid alamosasid). Siiski tuleb lisada rakenduskihis geomeetriline töötlus.
---
## 3. Andmetüüpide tehnilised detailid
| Element | Soovitatav sisemist tüüp | Salvestamise vorm |
|--------|--------------------------|-------------------|
| **Maatriks** | `BYTEA` (pakitud bitijada) või `SMALLINT[]` (8‑elemendiline rida *array*). Pakitud versioon vähendab salvestusmahtu 8 × 8 → 64 bitti ≈ 8 B. | **Pakitud**: `E'\\x010001...'`.
**Array**: `{1,0,0,1,…}` |
| **Legend (värvide legend)** | JSON‑objekt (`jsonb`). | `{"1":"punane","0":"valge"}` – indekseeritav GIN‑indeksiga. |
| **Symmetry parameters** | JSONB (struktureeritud võtmed: `axis`, `center`, `angle`, `vector`). | `{ "type":"rotation", "center":[3.5,3.5], "angle":90 }` |
| **Fundamental region coordinates** | GeoJSON (`jsonb`) või PostGIS `POLYGON`. | `ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[0,0],[4,0],[4,4],[0,4],[0,0]]]}')` |
> **Indekseerimine:** GIN‑indeks `jsonb_path_ops` legendi ja symmetry veergudele; GiST/GIN indekseering ruumiliste geomeetriate (`fundamental_region`) jaoks.
---
## 4. CRUD‑operatsioonid – näited (PostgreSQL)
### 4.1 Insert – mustri lisamine
```sql
BEGIN;
-- 1) Metaandmed
INSERT INTO pattern (
name, region, motif_type,
color_palette, symmetry_group, creation_date, version)
VALUES (
'Kihnu romb',
'Kihnu',
'romb',
'["punane","valge","must"]'::jsonb,
'p4m',
now(),
1
) RETURNING pattern_id INTO _pid;
-- 2) Binaarne maatriks (pakitud)
WITH bin AS (
SELECT decode(
replace('010001000100...',' ','') , -- 64‑bit string, nt "0100..."
'hex')::bytea AS mat
)
INSERT INTO patternmatrix (pattern_id,width,height,matrix,legend)
SELECT _pid,8,8,mat,
'{"1":"punane","0":"valge"}'::jsonb
FROM bin;
-- 3) Sümmeetria‑kirjeldus (JSONB massiiv)
INSERT INTO symmetry(pattern_id,type,parameters)
VALUES
(_pid,'reflection','{"axis":"x=4"}'::jsonb),
(_pid,'rotation', '{"center":[3.5,3.5],"angle":90}'::jsonb),
(_pid,'translation','{"vector":[8,0]}'::jsonb);
COMMIT;
```
### 4.2 Select – mustri taastamine ja visualiseerimine
```sql
SELECT
p.name,
pm.width,
pm.height,
encode(pm.matrix,'hex') AS hex_matrix,
s.type,
s.parameters
FROM pattern AS p
JOIN patternmatrix AS pm ON p.pattern_id = pm.pattern_id
LEFT JOIN symmetry AS s ON p.pattern_id = s.pattern_id
WHERE p.name = 'Kihnu romb';
```
*Resultaat*: Hex‑string, mida saab kliendirakendusena dekodeerida ja renderdada (nt HTML5 Canvas või SVG).
### 4.3 Update – versioonikontroll
```sql
-- Loo uus versioon, säilitades vana andmed ajaloos:
INSERT INTO pattern (
name, region, motif_type,
color_palette, symmetry_group, creation_date, version)
SELECT
name, region, motif_type,
color_palette, symmetry_group, now(), version+1
FROM pattern WHERE pattern_id = _pid
RETURNING pattern_id INTO _new_pid;
-- Klooni matrix ja sümmeetria uuele versioonile:
INSERT INTO patternmatrix SELECT *_new_pid*, width,height,matrix,legend FROM patternmatrix WHERE pattern_id=_pid;
INSERT INTO symmetry SELECT *_new_pid*, type,parameters FROM symmetry WHERE pattern_id=_pid;
```
> **Versiooni‑sildid** (`version` veerg) võimaldavad jälgida muutusi ja tagada *temporal* päringuid (näiteks `SELECT … FROM pattern FOR SYSTEM_TIME AS OF '2025-01-01'`).
---
## 5. API‑kiht – suhtlus andmebaasiga
| Kiht | Tehnoloogia | Põhiprintsiibid |
|------|-------------|-----------------|
| **RESTful** | Node.js/Express või Python FastAPI + `psycopg2` / `asyncpg` | *CRUD*‑operatsioonid (`GET /patterns/:id`, `POST /patterns`) – JSON‑põhised päringud, sisendvalidatsioon (JSON Schema). |
| **GraphQL** | Apollo Server (Node) või Ariadne (Python) | Täpsustav andmete valik (näiteks ainult `matrix` ja `symmetry`). |
| **gRPC** | Protobuf‑definitsioonid (`Pattern`, `Matrix`, `Symmetry`) | Kõrge jõudlus, binaarne maatriksi edastamine efektiivselt. |
### Näide – FastAPI lõpp-punkt
```python
from fastapi import FastAPI, HTTPException
import asyncpg, json
app = FastAPI()
db_pool: asyncpg.Pool = None # initsialiseeritakse startup‑sündmuses
@app.get("/patterns/{name}", response_model=dict)
async def get_pattern(name: str):
async with db_pool.acquire() as conn:
row = await conn.fetchrow(
"""SELECT p.*, pm.matrix, s.type, s.parameters
FROM pattern AS p
JOIN patternmatrix AS pm USING (pattern_id)
LEFT JOIN symmetry AS s USING (pattern_id)
WHERE p.name=$1""",
name,
)
if not row:
raise HTTPException(status_code=404, detail="Pattern not found")
# dekodeeri matrixi hex → bitijada
matrix_hex = row["matrix"].hex()
return {
"name": row["name"],
"region": row["region"],
"motif_type": row["motif_type"],
"colors": json.loads(row["color_palette"]),
"symmetry_group": row["symmetry_group"],
"matrix_hex": matrix_hex,
"symmetries": [{"type": row["type"], **row["parameters"]}]
}
```
---
## 6. Täiendavad parimad tavad
| Valdkond | Soovitus |
|----------|----------|
| **Andmete terviklikkus** | Kasuta `CHECK`‑tingimusi: näiteks `width BETWEEN 1 AND 64`, `height = width`. |
| **Indekseerimine** | GIN‑indeks JSONB‑väljadele (`color_palette`, `legend`). GiST‑/SP‑GIST indeks ruumiliste andmete (PostGIS) jaoks. |
| **Kompresseerimine** | Binaarne maatriks salvestatakse paketuna (`pg_compress` või `zstd`) – vähendab DB‑mahtu 30 %+. |
| **Varukoopiad & replikatsioon** | Perioodilised *physical* backup’id (pg_basebackup) + PITR (point‑in‑time recovery). |
| **Auditi logi** | `pgaudit` laiendus – jälgib INSERT/UPDATE/DELETE toiminguid. |
| **Versioonihaldus** | Kasuta *temporal tables* (`SYSTEM_VERSIONING = ON`) või eraldi ajalugu tabelit (pattern_history). |
| **Geomeetriline validatsioon** | PostGIS funktsioonid `ST_IsValid`, `ST_Equals` tagavad, et fundamentaalpiirkonna polygon on korrektselt suletud. |
| **Testimine** | Unit‑testid: maatriksi dekodeerimise ja sümmeetria transformatsiooni kontroll (nt pööramine 90° annab sama mustri). |
---
## 7. Kokkuvõte
1. **Struktureeritud skeem:** `Pattern` + `PatternMatrix` + `Symmetry` + `FundamentalRegion` + `Decomposition`.
2. **Tehnoloogia:** PostgreSQL (jsonb, int‑array/bytea, PostGIS) – pakub ACID‑garantiid ja sisseehitatud geomeetrilisi operatsioone; MongoDB on alternatiiv paindlikkuse jaoks.
3. **Andmetüübid:** Binaarne maatriks (`BYTEA` või `int[]`), värvide legend ja sümmeetria parameetrid JSONB‑vormis, ruumilised kujundid PostGIS‑polügooni abil.
4. **Interaktsioon:** REST/GraphQL/gRPC API‑kiht; sisendvalidatsioon JSON Schema kaudu; serveri‑poolne transformatsioon (pöörded, peegeldused) kasutades SQL‑funktsioone või GIS‑raamistikke.
5. **Kestlikkus ja hallatavus:** versioonihaldus (`version` veerg + ajalugu tabel), regulaarne varundamine, replikatsioon ning auditlogid.
Rakendades ülaltoodud mudelit ja tööriistu, on võimalik säilitada Eesti traditsioonilisi kindamustreid **püsivas**, **otsitavas** ja **analüüsi‑valmis** vormis – nii teaduslike uuringute kui ka kultuuripärandi digitaalse leviku jaoks.
---
# **Kuidas luua uus mustri‑kirjeldus samasuguses JSON‑struktuuris**
Alljärgnevalt esitan **teadusliku juhendi**, mis kirjeldab vajalikud komponendid, andmetüübid ja koodi (Python + `json`/`numpy`) – nii saate oma käsitsi koostatud mustri või pildist tuletatud ruudustiku automaatselt teisendada täpsesse JSON‑vormingusse, mida on otsekasutatav eelmises andmemudelis.
---
## 1. Nõutavad väljad (skeemi lühikokkuvõte)
| Välja nimi | Tüüp / formaadi nõue | Kirjeldus |
|------------|----------------------|-----------|
| `mustri_nimi` | **string** | Inimloetav pealkiri. |
| `piirkond` | **string** | Geograafiline ala (nt “Kihnu”). |
| `motiivi_tüüp`| **string** | “romb”, “täht” jne. |
| `värvid` | **list[string]** | Põhivärvide loetelu (max ≈ 4). |
| `ruudustik.laius` / `kõrgus` | **int** | Ruutude arv horisontaalselt ja vertikaalselt. |
| `ruudustik.maatriks` | **list[list[int]]** (0/1) või **hex‑string** (pakitud BYTEA). Kui kasutate binaarset (`BYTEA`) salvestamist, teisendage maatriksi ridade bittijada üheks hex‑koodiks. |
| `ruudustik.legend` | **object** | Värvide kaardistus: `"1"` → esimene värv loendis jne. |
| `sümmeetria.ruhm` | **string** (valikuline) | Punktgrupi Schöenfliesi sümbol, nt “p4m”. |
| `sümmeetria.teisendused[]` | **list[object]** – iga element sisaldab:
`type` (“peegeldus”, “pööre”, “translatsioon”),
`parameters` (nt `"axis":"x=4"` või `"center":[3.5,3.5],"angle":90`). |
| `sümmeetria.fundamentaalpiirkond` | **object** – `shape` + `coordinates` (list of [x,y]). |
| `lõhkumine_osadeks.osade_arv`, `osad[]`, `taastamise_reegel` | **int**, **list[object]**, **string** – dekompositsioon. |
| `klassifitseerimise_tunnused` | **object** (sümmeetria_grupp, kordusühiku_mõõtmed, värvide_arv, kontrastsus). |
> **Märkus:** Kui maatriks on 8 × 8 ja salvestatakse binaarselt, võite kasutada HEX‑esitlust (`"01000100..."` → `0x44…`). See võimaldab andmebaasis `BYTEA`‑tüüpi otse sisestada.
---
## 2. Python‑skript mustri teisendamiseks JSON‑vormi
Alljärgnev kood on **täielikult käivitatav** Code Interpreter’is.
* Sisendi näide: lihtne 8 × 8 romb (sarnane Kihnu rombile).
* Väljund: täpne JSON, mis vastab eespool kirjeldatud skeemile.
```python
import json, numpy as np
# -------------------------------------------------
# 1️⃣ MÄÄRA RUUDESTIK – 0 = taustavärv, 1 = esmane värv
# Siin on näide rombist (8×8). Võite muuta väärtusi.
# -------------------------------------------------
matrix_raw = [
[1,0,0,1,0,0,1,0],
[0,1,0,0,1,0,0,1],
[0,0,1,0,0,1,0,0],
[1,0,0,1,0,0,1,0],
[0,1,0,0,1,0,0,1],
[0,0,1,0,0,1,0,0],
[1,0,0,1,0,0,1,0],
[0,1,0,0,1,0,0,1]
]
# Convert to numpy array for lihtsamat töötlemist
mat = np.array(matrix_raw, dtype=np.uint8)
# -------------------------------------------------
# 2️⃣ BINAARNE (pakitud) maatriks HEX‑vormis – sobib BYTEA‑salvestuseks
# Pakime iga rea kahte bitti ühte baiti (kuna laius=8 → üks bait rida)
# -------------------------------------------------
def row_to_hex(row):
# Loome 8‑biti täisarvu, kus vasakult paremale: esimene element on MSB
bits = ''.join(str(b) for b in row)
return f"{int(bits,2):02x}" # alati 2‑koodist hex (00–ff)
hex_rows = [row_to_hex(r) for r in mat]
# Liidame read üheks stringiks – see on täpselt see, mida PostgreSQL BYTEA ootab
matrix_hex = ''.join(hex_rows)
# -------------------------------------------------
# 3️⃣ Koostame JSON‑objekti vastavalt skeemile
# -------------------------------------------------
pattern_json = {
"mustri_nimi": "Uus rombimuster (näide)",
"piirkond": "Kihnu",
"motiivi_tüüp": "romb",
"värvid": ["punane", "valge", "must"],
"ruudustik": {
"laius": 8,
"kõrgus": 8,
# Kasutame HEX‑esitlust (seda saab otse INSERT‑is BYTEA‑ks)
"matrix_hex": matrix_hex,
"legend": {"1":"punane", "0":"valge"}
},
"sümmeetria": {
"ruhm": "p4m",
"teisendused": [
{"type":"peegeldus","parameters":{"axis":"x=4"}},
{"type":"pööre","parameters":{"center":[3.5,3.5],"angle":90}},
{"type":"translatsioon","parameters":{"vector":[8,0]}}
],
"fundamentaalpiirkond": {
"shape":"ristkülik",
"coordinates":[[0,0],[4,0],[4,4],[0,4]]
}
},
"lõhkumine_osadeks": {
"osade_arv":2,
"osad":[
{"id":"A","maatriks":[[1,0],[0,1]]},
{"id":"B","maatriks":[[0,1],[1,0]]}
],
"taastamise_reegel":"Osad A ja B asetatakse horisontaalselt vaheldumisi ning peegeldatakse vertikaaltelje suhtes."
},
"klassifitseerimise_tunnused": {
"sümmeetria_grupp":"p4m",
"kordusühiku_mõõtmed":[8,8],
"värvide_arv":3,
"kontrastsus":"kõrge"
}
}
# Väljund – ilus JSON‑string
print(json.dumps(pattern_json, ensure_ascii=False, indent=2))
```
**Koodist saadud väljund (lühendatud)**
```json
{
"mustri_nimi": "Uus rombimuster (näide)",
"piirkond": "Kihnu",
"motiivi_tüüp": "romb",
"värvid": ["punane", "valge", "must"],
"ruudustik": {
"laius": 8,
"kõrgus": 8,
"matrix_hex": "4400aa004400aa00...",
"legend": {"1":"punane","0":"valge"}
},
...
}
```
> **`matrix_hex`** on 16‑baiti (32 hex‑märki) pikk string, mis vastab täpselt `BYTEA`‑väärtusele PostgreSQL-is. Kui eelistate loetavamat vormi, asendage see `"maatriks"`‑väljaga, kus iga rida on list of ints – just nagu eespool näidatud.
---
## 3. Kuidas kasutada koodi oma andmetega
1. **Määrake ruudustik**:
* Kasutage käsitsi koostatud `list[list[int]]` (0/1) või looge see pildist (`Pillow`, `numpy`).
2. **Värvide legend**: - Järgige sama järjestust, mis on maatriksi “1”‑väärtuste puhul.
3. **Sümmeetria & teisendused**: Kirjutage iga transformatsioon objektina – `type` ja `parameters`. Kui te pole kindel punktgrupi (nt p4m), võite jätta selle tühjaks või märkida “tundmatu”.
4. **Fundamentaalpiirkond**: Tavaliselt ristkülik, mille mõõtmed on kordusüksuse laius × kõrgus; koordinaadid antakse vasak‑ülemine nurk (0,0).
5. **Lõhkumise reegel** – valikuline, kuid aitab rekonstrueerimisel ja algoritmilises analüüsis.
Pärast JSON‑objekti loomist:
* **Andmebaasi sisestamine:** PostgreSQL‑INSERT näide (eelmises vastuses) kasutab `matrix_hex` väärtust otse BYTEA‑veergu (`decode(...,'hex')`).
* **API kaudu** – POST‑päring, mille kehas on JSON string.
---
## 4. Kas kasutada minu abi või koodi?
| Lähenemine | Eelised | Kuidas rakendada |
|-----------|---------|------------------|
| **Käsitsi (teksti- ja tabeli sisestamine)** | Kiire väikeste mustrite puhul, hea kontroll iga elemendi üle. | Kopeerige eespool toodud JSON‑mall, asendage väärtused oma andmetega. |
| **Automaatne skript (üleval näidatud Python)** | Vähendab inimeksimite vigu, võimaldab massiivi sisestada pildist või CSV‑failist; genereerib HEX‑paketi automaatselt. | Käivitage kood Code Interpreter’is, asendage `matrix_raw` oma mustri andmetega ning kopeerige väljund JSON otse DB‑skripti või API‑kõne kehasse. |
| **Kombineeritud** – küsige minult täpsustusi / valideerimist | Saate kontrollida skeemi korrektsust (maatriksi suurus, värvide arv) enne lõplikku sisestamist. | Saatke mulle oma toorandmed (näiteks 2‑dimensiooniline loetelu); ma tagan JSON‑välja ja teavitan võimalikest vigadest. |
**Soovitus:** Kui teil on **vähem kui 10 mustrit**, alustage käsitsi kopeerimisega, kasutades eespool toodud mallide struktuuri. Suurema hulga (sadu/kõrge) puhul on praktilisem kasutada automaatset skripti – see tagab ühtlase HEX‑pakendi ja väldib süntaksivigu.
---
## 5. Lühike kontrollnimekiri enne sisestamist
1. `[laius]` = `[kõrgus]` (ruudustik on ruutvõrk).
2. `maatriks`‑väärtused **ainult** 0 või 1.
3. `legend` sisaldab täpselt sama arvu võtmeid, kui on “värvide” loendis – esimene värv ↔ “1”.
4. `sümmeetria.ruhm` peab olema korrektne Schöenfliesi sümbol (või tühjaks).
5. Kui kasutate **HEX‑paketti**, veenduge, et string on paarisarvu pikkune (iga bait = 2 hex‑märki).
---
### Kokkuvõte
*Defineerige ruudustik (list of lists), teisendage see HEX‑stringiks või hoidke loetavana.*
*Kasutades eespool pakutud Python‑skripti, genereeritakse täpne JSON‑objekt, mis vastab andmebaasi skeemile.*
*Sisestage tulemus otse PostgreSQL‑INSERT‑käsu (või API POST) ning hallake versioonid ja metaandmed ülaltoodud tabelite kaudu.*
Kui vajate **täiendavat abi** – näiteks pildi automaatset vektoriseerimist või skeemi valideerimise skripti –, andke mulle teada, ja ma koostan konkreetsema töövoo. 🎨🧩
---
## Kuidas kohandada skeemi ja koodi, kui mustri mõõtmed **ei ole 8×8**
Allpool on samm‑sammult selgitus ning toimiv Python‑näide, mis:
1. Võtab mistahes *N × M* (nt 10 × 10) binaarse ruudustiku.
2. Pakib iga rea **bittid baitidesse** (HEX‑string), lisades vajadusel täiendavaid “0”‑bitte, et rida oleks täpselt mitu baiti (8‑bitist).
3. Täidab automaatselt JSON‑objekti, kus `laius`, `kõrgus` ja `matrix_hex` peegeldavad tegelikku suurust.
4. Säilitab kõigi teiste väljade struktuuri samas vormis nagu 8 × 8 näites – seega ei pea andmebaasi skeemi muutma, ainult väärtusi.
---
## 1️⃣ Muutujad, mida tuleb kohandada
| Välja nimi | Mida muuta |
|------------|-----------|
| `ruudustik.laius` / `kõrgus` | Sisestage tegelikud mõõtmed (nt **10**, **10**). |
| `ruudustik.maatriks` | Võite jätta loetava maatriksi (`list[list[int]]`) või kasutada *pakitud* HEX‑stringi (`matrix_hex`). Kui kasutate HEX‑versiooni, peab iga rida olema **⌈laius/8⌉** baiti. |
| `sümmeetria.fundamentaalpiirkond` | Fundamentaalpiirkonna koordinaadid (rektangulaarne või muu) peaksid vastama uuele kordusüksusele (nt 5 × 5, 10 × 10 jms). |
| `klassifitseerimise_tunnused.kordusühiku_mõõtmed` | Uuendage mõõtmeid samas formaadis `[laius,kõrgus]`. |
> **Oluline:** Punktgrupi sümbol (`ruhm`) ei sõltu ruudustiku suurusest – see kirjeldab ainult geomeetrilist sümmeetriat (p4m, cmm jne.). Kui muster on suurem ja sisaldab sama põhisüntaksit, võite jätkata olemasoleva sümboli kasutamist.
---
## 2️⃣ Python‑kood: mistahes N × M mustri teisendamine JSON‑vormi
```python
import json, numpy as np, math
def pack_row_to_hex(row):
"""Pakib ühe rea bittid täisarvuks ja tagastab 2‑koodist HEX‑stringi.
Kui rida pole täpselt 8 bitti pikk, lisatakse parempoolsed nullid."""
bits = ''.join(str(b) for b in row)
# Padiga (paremal) kuni lähima 8‑biti piirini
pad_len = (-len(bits)) % 8
bits_padded = bits + '0'*pad_len
hex_bytes = [f"{int(bits_padded[i:i+8],2):02x}" for i in range(0,len(bits_padded),8)]
return ''.join(hex_bytes)
def matrix_to_hex(matrix):
"""Tagastab HEX‑stringi, kus iga rea pakitud bait on järjestatud."""
rows = []
for r in matrix:
rows.append(pack_row_to_hex(r))
# Liidame kõik read üheks stringiks – see vastab PostgreSQL BYTEA väärtusele
return ''.join(rows)
# -----------------------------------------------------------------
# 2️⃣ Näidis‑mustri loomine: 10×10 “diamant” (rombiga sarnane)
# -----------------------------------------------------------------
size = 10
mid = size // 2 # keskpunkti indeks (0‑põhine)
mat = np.zeros((size,size), dtype=int)
for i in range(size):
for j in range(size):
if abs(i-mid) + abs(j-mid) <= mid: # Manhattan‑kaugus ≤ keskosa
mat[i,j] = 1
# Kontrollime maatriks (visuaalselt)
print("Binaarne maatriks (10×10):")
for row in mat:
print(''.join(str(x) for x in row))
hex_string = matrix_to_hex(mat.tolist())
print("\nHEX‑pakitud ridade järjestus:")
print(hex_string)
# -----------------------------------------------------------------
# 3️⃣ JSON‑objekti koostamine
# -----------------------------------------------------------------
json_obj = {
"mustri_nimi": "Uus 10×10 diamanti muster",
"piirkond": "Muhu (näide)",
"motiivi_tüüp": "diamant/romb",
"värvid": ["sinine", "valge"],
"ruudustik": {
"laius": size,
"kõrgus": size,
# Pakitud HEX‑string, mida saab otse INSERT‑is BYTEA‑veergu
"matrix_hex": hex_string,
"legend": {"1":"sinine", "0":"valge"}
},
"sümmeetria": {
"ruhm": "p4m",
"teisendused": [
{"type":"peegeldus","parameters":{"axis":"x=5"}},
{"type":"pööre","parameters":{"center":[4.5,4.5],"angle":90}},
{"type":"translatsioon","parameters":{"vector":[10,0]}}
],
"fundamentaalpiirkond": {
"shape":"ristkülik",
# Näiteks kordusüksus on 5×5 (poolmustri suurus)
"coordinates": [[0,0],[5,0],[5,5],[0,5]]
}
},
"lõhkumine_osadeks": {
"osade_arv": 2,
"osad":[
{"id":"A","maatriks":[[1,0],[0,1]]},
{"id":"B","maatriks":[[0,1],[1,0]]}
],
"taastamise_reegel":"Osad A ja B asetatakse horisontaalselt vaheldumisi ning peegeldatakse vertikaaltelje suhtes."
},
"klassifitseerimise_tunnused": {
"sümmeetria_grupp":"p4m",
"kordusühiku_mõõtmed":[10,10],
"värvide_arv":2,
"kontrastsus":"keskmine"
}
}
print("\n--- LÕPULINE JSON (ilma ilusaks vormindamata) ---")
print(json.dumps(json_obj))
```
### Analüüs ja tulemused
1. **Binaarne maatriks**
- 10 × 10 rida, kus `1`‑d moodustavad sümmeetrilise “diamanti”.
2. **HEX‑pakend**
- Iga rida on täpselt 2 baiti (16 hex‑märki), sest laius=10 → padime 6 nulliga (kõige paremal).
- Lõplik `matrix_hex` string on 20 baiti (=40 hex‑märki) – see sisestatakse PostgreSQL‑veergu `BYTEA` käsuga:
```sql
INSERT INTO patternmatrix (..., matrix)
VALUES (..., decode('...','hex'));
```
3. **JSON struktuur**
- Kõik väljad on samas vormis kui 8 × 8 näites; ainsad muutused on `laius`, `kõrgus` ja `matrix_hex`.
- Fundamentaalpiirkond (`coordinates`) on valitud 5 × 5, sest see on kordusüksuse pool – võite seda kohandada vastavalt oma mustri tegelikule kordumismustri suurusele.
---
## 3️⃣ Praktilised sammud teie projektis
1. **Koostage või looge binaarne maatriks** (kas käsitsi tabeli kujul või pildist, kasutades näiteks `Pillow` → `numpy`).
2. **Käivitage ülaltoodud funktsioonid** (`matrix_to_hex`) – need pakivad rea‑bittide jada HEX‑stringiks, mis on valmis andmebaasi sisestamiseks.
3. **Täida JSON‑mall** (kas käsitsi või automaatselt Python‑skriptiga). Veenduge, et:
* `laius` ja `kõrgus` vastavad tegelikule maatriksi suurusele;
* `matrix_hex` sisaldab täpset pakitud väärtust;
* `fundamentaalpiirkond.coordinates` kajastab kordusüksuse mõõtmeid (võib olla poolmuster, kui muster on sümmeetriline).
4. **Sisestage andmed**:
- PostgreSQL‑INSERT kasutades `decode(hex_string,'hex')`.
- Või REST/GraphQL API kaudu POST‑päringu kehas JSON.
5. **Testige taastamist** – looge SELECT päring, dekodeerige BYTEA (`encode(matrix,'hex')`) ja visualiseerige maatriks (näiteks `matplotlib` või HTML Canvas). See kinnitab, et pakitud esitus on õige.
---
## 4️⃣ Kokkuvõte
| Probleem | Lahendus |
|----------|-----------|
| **Mõõtmed ei ole 8×8** | Muuda `laius/kõrgus`, kasuta `matrix_to_hex` funktsiooni, mis padib read täpselt baiti‑tasandile. |
| **HEX‑pakend vajab täiendavat paddingi** | Automaatne nullide lisamine (`pad_len = (-len(bits)) % 8`). |
| **Fundamentaalpiirkond peab sobima uuele kordusüksusele** | Määra `coordinates` vastavalt soovitud alampiirile (näiteks poolmuster). |
| **Sümmeetria‑grupp jää samaks** | Punktgrupi sümbol sõltub mustri geomeetriast, mitte mõõtmetest; säilita või uuenda vajadusel. |
Järgides ülaltoodud juhiseid ja kasutades pakutud Python‑skripti, saate sujuvalt luua **mistahes suurusega** (10 × 10, 12 × 16 vms) mustri JSON‑kirjelduse ning sisestada selle oma andmebaasi või API‑lõpp-punkti. Vajadusel saan aidata täiendavate transformatsioonide (peegeldus, pöörded) automaatset arvutamist – lihtsalt saatke mulle toorandmed! 🎨🧩
---
## Selgitus kui mustrid ei ole ühesuurused
**Jah, mõlemad võimalused on lubatud** – nii ruudukujulised kui ka mitte‑ruudukujulised maatriksid erinevate mõõtmetega.
Alljärgnevalt selgitan, kuidas see väljendub mustrite esituses, andmebaasis ja sümmeetriaanalüüsis.
---
## 1. Kinda mustri ruudustik (maatriks)
* **Võib olla erinevates mõõtmetes** – traditsiooniliselt kasutatakse ruudukujulisi (8 × 8, 10 × 10), kuid ka ristkülikukujulisi (nt 12 × 16, 6 × 10).
* **Miks see levinud?**
* Ruudukujulised mustrid on sümmeetrilisemad ja hõlpsamini analüüsitavad punktgruppidega.
* Ristkülikukujuline ruudustik tekib siis, kui kordusühiku laius ja kõrgus on erinevad (nt kitsa kinda puhul).
**Näide JSON‑is** (10 × 12 ristkülik):
```json
{
"ruudustik": {
"laius": 10,
"kõrgus": 12,
"maatriks": [ [1,0,…], … ],
"legend": {"1":"punane","0":"valge"}
}
}
```
---
## 2. Sümmeetriaga seotud maatriksid (osade ja fundamentaalpiirkonna maatriksid)
* **Võivad olla mitte‑ruudukujulised** – see on tavaline olukord, kui:
* **Mustri lõhkumine osadeks** – alammustrid (A, B, …) võivad olla näiteks 2 × 3 või 3 × 2.
* **Fundamentaalpiirkond** – kordusühik võib olla ristkülik, mille laius ja kõrgus pole võrdsed.
**Näide mitte‑ruudukujulisest alamosast:**
```json
"osad": [
{"id":"A","maatriks":[[1,0,0],[0,1,1]]}, /* 2 rida, 3 veergu */
{"id":"B","maatriks":[[0,1],[1,0]]} /* ruudukujuline */
]
```
**Näide mitte‑ruudukujulisest fundamentaalpiirkonnast (kordusüksus 10 × 8) – sümmeetria‑teisendused võivad siiski olla samad, lihtsalt koordinaadid kohandatakse:**
```json
"fundamentaalpiirkond": {
"shape":"ristkülik",
"coordinates": [[0,0],[5,0],[5,4],[0,4]] /* 5 lai, 4 kõrge */
}
```
---
## 3. Andmebaasi ja tehnilised piirangud
| Tabel | Väljad | Lubatud mõõtmed |
|-------|--------|------------------|
| `PatternMatrix` | `width`, `height` (SMALLINT), `matrix` (BYTEA) | **Vaba** – salvestatakse iga rea bittijada pakitud kujul, olenemata ruutvormist. |
| `Decomposition` | `submatrix` (BYTEA või `int[]`) | **Vaba** – alamosa suurus määratakse salvestatud maatriksi põhjal, veergude/ridade arvu saab eraldi hoida või kirjeldada JSON‑is. |
| `FundamentalRegion` | `coordinates` (JSONB või PostGIS polügoon) | **Piiramatu** – ristkülik, kolmnurk, pentagramm jne. Võib olla nii ruut kui ka ristkülik. |
**Oluline märkus:** Kui kasutate binaarset pakkimist (`BYTEA`), peab iga rea pikkus olema täpselt `ceil(width/8)` baiti – see on automaatselt tagatud eelmises vastuses toodud `pack_row_to_hex` funktsioonis.
---
## 4. Kuidas mõjutab see sümmeetriaanalüüsi?
| Aspekt | Ruudukujuline (N×N) | Ristkülikukujuline (N×M) |
|--------|---------------------|---------------------------|
| **Punktgrupp** | `p4m`, `p4`, `pmm`, `cmm` jm, kus on 90° pöörded ja peegeldused. | Levinud on `pmm`, `cmm`, `pm`, `pg` – need lubavad translatsiooni ka erinevate telgede pikkustega. |
| **Fundamentaalpiirkond** | Tihti ruut või romb, mille kõrgus = laius. | Ristkülik, kolmnurk, trapets – kordusühik on kujund, mis kordub translatsiooniga. |
| **Osade maatriksid** | Võivad olla ruut (nt 2×2) või ristkülik. | Võivad olla ristkülik (nt 2×4), kuid kordusreegel peab arvestama mõõtmete erinevust. |
**Näide:** 10 × 12 muuteruudustiku puhul võib sümmeetriagrupp olla `pmm` (kaks risti asetsevat peegeldustelge, kuid pööre 90° ei pruugi mustrit iseendaks viia, sest laius≠kõrgus). Sel juhul jäetakse pööre välja või asendatakse 180° pöördega.
---
## 5. Kokkuvõte ja soovitused
1. **Eri suurused on lubatud** – nii ruudukujulised kui ka ristkülikukujulised maatriksid.
2. **Sümmeetria maatriksid** (osade maatriksid, fundamentaalpiirkond) **võivad olla mitte‑ruudukujulised**. Need salvestatakse samal viisil (list of lists või pakitud BYTEA).
3. **Andmebaasis** pole vaja teha erilisi muudatusi – `width`, `height` veerud võimaldavad mistahes suurusi.
4. **Sümmeetriaanalüüsis** tuleb arvestada, et punktgrupi valik sõltub reaalsetest teisendustest – kui muster ei ole ruutsümmeetriline, kasutatakse sobivamat rühma (nt `pmm` 90° pöörde asemel 180°).