Metadata-Version: 2.4
Name: animageo
Version: 1.3.1
Summary: Convert GeoGebra constructions into high-quality SVG images and MP4 animations using manim
Author-email: Leonid Ivanov <ivaleotion@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://animageo.ru/
Keywords: geometry,dynamic,geogebra,manim,animation,drawing,svg,mp4,python
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Multimedia :: Graphics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: numpy<3.0,>=1.26.0
Requires-Dist: manim<0.22,>=0.20.1
Requires-Dist: pycairo>=1.0.0
Requires-Dist: sympy>=1.12
Requires-Dist: scipy>=1.11
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == "dev"
Requires-Dist: twine>=4.0.0; extra == "dev"
Requires-Dist: setuptools>=65.0.0; extra == "dev"
Requires-Dist: pytest>=7.0.0; extra == "dev"
Dynamic: license-file

# AnimaGeo

## Installation

```bash
pip install --upgrade animageo
```

## Using in terminal

```bash
animageo test.ggb -s default.json -px 240 auto
```

*Description:*

```
usage: animageo [-h] [-o OUTPUT] [-px PX PX] [-s STYLE] [-d] ggbfile

Converting GeoGebra construction file into SVG image.

positional arguments:
  ggbfile              GeoGebra file to convert

options:
  -h, --help           show this help message and exit
  -o, --output OUTPUT  SVG file to export into
  -px PX PX            image width and height in px (values: num or auto)
  -s, --style STYLE    JSON file with style definitions
  -d, --debug          print options
```

## Using in code

1. Prepare code `scene.py`:

```python
from animageo import *

class TestScene(AnimaGeoScene):
    def construct(self):
        # ............................................................
        # Load geometric construction directly from GeoGebra-file     
        self.loadGGB(
            'scene.ggb',
            style='default.json',
            export={'size': {'width': 400, 'height': 'auto'}},
        )
        
        # ............................................................
        # Load your own simplified python-style Code-file for manipulations with geometric construction
        # - add new vars and elements
        # - change previous definitions
        self.loadCode('scene_code.py')

        # ............................................................
        # Stylize elements using their names from GeoGebra-file or from your Code-file
        # - use any predefined attributes from style or from Manim
        self.element('a').style['stroke'] = self.style.col 
        self.element('A_1').style['fill'] = self.style.col_accent

        # ............................................................
        # Export current scene to image with export.size width/height
        self.exportSVG('scene.svg')

        # ............................................................
        # Do whatever you do with Manim, but also specific things:

        # - add special ValueTracker and link it to Var in geometric construction
        x = self.addVar('x', 5)

        # - use predefined methods to Show, Hide and Update geometric elements without animation
        self.HideAll()
        self.Show(['A', 'B'])

        # - use predefined methods to Show, Hide and Update geometric elements with animation
        self.playShow(['a'])
        self.element('b').style['stroke_opacity'] = 0.5
        self.playUpdate(['b'])

        # - use tracker values for animation
        self.addUpdater(x)
        self.play(x.animate.set_value(10))
        self.clearUpdater(x)

        # - you may also want to change geometric elements as Manim objects (but without affecting geometric construction)
        a = self.mobject('a')
        b = self.mobject('b')
        self.play(VGroup(a, b).animate.arrange(buff=1).shift(DOWN))
        self.play(FadeOut(a, b))        
```

and code `scene_code.py`:

```python
from animageo.dsl import *   # IDE-only; dropped by DSL transform at runtime

A = Point(x, 0)
B = Intersect(b, c)
a = Segment(A, B)
```

2. Run compilation:

```bash
manim 'scene.py' TestScene
```


## Style definitions in JSON

JSON-стиль делится на пять верхнеуровневых секций:

- **`presets`** — semantic constants: цвета, размеры, толщины и структуры;
- **`defaults`** — per-type baseline, обычно ссылками на `presets`;
- **`overlay`** — post-import стилизация и автоматика;
- **`rendering`** — настройки рендера и пайплайна;
- **`import`** — правила импорта GGB-значений + встроенная `ImportPolicy`.

Где читать подробнее:

- `docs/styles.md` — главный справочник по стилям и концепции слоёв.
- `docs/architecture.md` — короткая архитектурная схема pipeline.
- `docs/import_policies.md` — только GGB import/adaptation и `ImportPolicy`.
- `docs/field_names.md` — соответствия GGB XML, `ggb_raw`, `elem.style`, JSON и renderer.
- `docs/construction_summary.md` — компактный JSON-summary конструкции для AI style-generation.
- `docs/ai_style_generation_context.md` — полный контекст/контракт для LLM, генерирующей style JSON и опциональный loadCode-compatible DSL.
- `docs/ai_style_json_schema.json` — JSON Schema для проверки сгенерированного style JSON.
- `docs/ai_construction_generation_plan.md` — проработка второго этапа: AI-создание и patch-редактирование конструкций через DSL.
- `docs/ai_construction_generation_context.md` — рабочий prompt-контекст для LLM, генерирующей construction DSL.
- `docs/ai_construction_lab/index.html` — экспериментальная HTML-библиотека запросов, DSL, SVG и ручной оценки.
- `docs/style_guide/index.html` — HTML-гайд с примерами.

Короткое разделение логики: `import` переводит raw-настройки GeoGebra в стиль AnimaGeo; `overlay` задаёт проектные переопределения по типам и именам поверх GGB и DSL; `rendering` управляет тонкими настройками отрисовки и экспорта.

Полный пример:

```json
{
    "name": "default",
    "version": 0.1,

    "presets": {
        "color": {
            "main": "#2581b5",
            "bold": "#000000",
            "aux": "#808080",
            "accent": "#ef60ab",
            "background": "#ffffff",
            "strong": "#000000"
        },
        "point_size":  { "main": 7, "bold": 9,   "aux": 5 },
        "line_width":  { "main": 2, "bold": 2.5, "aux": 1.5 },
        "angle_radius": { "main": 20, "shift": 3, "right": 14 },
        "tick":  { "main": { "tick_width_px": 1, "tick_length_px": 12, "tick_shift_px": 4 } },
        "arrow": { "main": { "arrow_width_px": 7.5, "arrow_length_px": 10.5 } },
        "font_size": { "main": 17 }
    },

    "defaults": {
        "point": {
            "size_px": "point_size.main",
            "fill": "color.strong"
        },
        "segment": {
            "$include": "tick.main",
            "stroke_width_px": "line_width.main"
        },
        "vector": {
            "$include": ["tick.main", "arrow.main"]
        },
        "angle": {
            "arc_size_px": "angle_radius.main",
            "arc_shift_px": "angle_radius.shift",
            "stroke_width_px": "line_width.aux"
        }
    },

    "reference": {
        "size": { "width": 300, "height": 220 },
        "source": "source_view"
    },

    "rendering": {
        "background":             "color.background",
        "line_cap":               "round",
        "right_angle_joint":      "miter",
        "polygon_boundary_layer": "top",
        "points_display":         "only_labels"
    },

    "import": {
        "colors": {
            "#1565c0":     "color.main",
            "#1565c0 0.1": "color.main 0",
            "#d32f2f":     "color.accent",
            "#d32f2f 0.1": "color.accent_light 1",
            "#616161":     "color.aux",
            "#000000 0.6": "color.main",
            "#000000 0.1": "color.light 1",
            "#1565c0 0":   "color.white 1",
            "#d32f2f 0":   "color.white 1"
        },
        "point_size": { "5": "point_size.main" },
        "line_width": { "5": "line_width.main", "3": "line_width.aux" }
    }
}
```

### `rendering` — настройки рендера

| Ключ | Значения | Эффект |
|---|---|---|
| `background` | hex или `color.*` | фон сцены: Manim camera/MP4 и SVG viewport |
| `line_cap` | `"butt"` \| `"round"` \| `"square"` | окончания линий |
| `right_angle_joint` | `"auto"` \| `"bevel"` \| `"miter"` \| `"round"` | соединение сторон прямого угла |
| `polygon_boundary_layer` | `"top"` \| `null` | `"top"` — контур полигона поверх заливки (z-index=10). Касается сегментов-сторон, создаваемых автоматически GeoGebra |
| `points_display` | `"auto"` \| `"only_labels"` \| `"only_points"` | скрыть точки / надписи глобально |
| `label_anchor` | одна из 9 позиций (`"TL"`…`"BR"`, `"MC"` и т. д.) | default-якорь подписей |
| `label_value_precision` | int | default-точность числовых подписей |

Автоматизмы задаются только в `overlay.angle_radius` и `overlay.label_placement`.

`reference` хранит эталонный холст, под который рассчитан стиль. Для экспорта
в другой физический размер используйте runtime-блок `export`:

```python
scene.loadGGB(
    'construction.ggb',
    style='style.json',
    export={'size': {'width': 1920, 'height': 1080}, 'fit': 'contain'},
)
```

Если нужно вписать не весь GeoGebra viewport, а фактический чертеж, используйте
измерение финальных mobject-ов:

```python
scene.loadGGB(
    'construction.ggb',
    style='style.json',
    content={'source': 'rendered_bounds', 'padding': 24},
    export={'size': {'width': 1920, 'height': 1080}},
)
```

`content` размещает конструкцию на reference-холсте; `export` размещает
reference-холст в физическом файле. В `rendered_bounds` бесконечные
`Line`/`Ray` по умолчанию игнорируются (`content.infinite_policy='ignore'`);
если их нужно учитывать по текущей source-камере, задайте `'clip'`.

### `import` — правила импорта из GeoGebra

| Ключ | Тип | Назначение |
|---|---|---|
| `enabled` | bool | `false` отключает весь GGB visual import: geometry и `ggb_raw` сохраняются, baseline берётся из `defaults`, а `colors`/`point_size`/`line_width`/`policy` пропускаются |
| `colors` | dict `"#hex [opacity]" → "color.*|#hex [opacity]"` | ремап цветов из GGB на короткий preset token или hex |
| `point_size` | dict `"N" → "point_size.*"` | маппинг GGB-размера точек на пресет из `point_size` |
| `line_width` | dict `"N" → "line_width.*"` | маппинг GGB-толщины линий на пресет из `line_width` |
| `policy` | объект `ImportPolicy` | гибкие raw-GGB правила конверсии (scalar/DSL/callable). Типовые и именные overrides задавайте в `overlay`. См. `docs/import_policies.md` |

`import.colors` пишет в нормализованный GGB import layer (`elem.ggb_style`)
канонический hex `#rrggbb`, а не raw RGBA-массив. Resolver затем включает
этот слой между `overlay` и `defaults`. Opacity в правой части применяется отдельно:
если она указана (`"color.accent 1"`), соответствующий `fill_opacity` /
`stroke_opacity` явно заменяется; если не указана (`"color.accent"` или
`"#f15b5b"`), текущая opacity элемента сохраняется.

Старые top-level секции (`style`, `technic`, `ggb_export`, `palette`), старые visual keys вроде
`line_width` / `font_size` / `ang_rdefault`, а также удалённые runtime-ключи
вроде `rendering.scale_export` отклоняются validation error.

Полный справочник всех имён через 5 слоёв (GGB / animageo / JSON / manim / SVG) — в `docs/field_names.md`.
