feat: Phase 4 планиметрии — симметрия (reflect) + правильный n-угольник (ngon)
- GeoEngine: _dependsOn/recompute для constr='reflect' и 'ngon_vertex' - reflect: производная точка-отражение (P'=2·foot-P), зависит от axis+srcPt - ngon: правильный n-угольник по центру и вершине; вершины v1..vn-1 = derived points (constr='ngon_vertex', хранят srcCenter/srcVertex/k/n); при движении центра/вершины все вершины автоматически пересчитываются - GeoSim: _ngonSides=6, setNgonSides(n), инструменты 'reflect'/'ngon' в _handleToolClick - lab.html: кнопки Симметрия и n-угольник, +/- контроллер сторон, хинты Phase 2 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -672,6 +672,25 @@
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.geo-ngon-ctrl {
|
||||
display: flex; align-items: center; justify-content: center; gap: 6px;
|
||||
border: 1.5px solid var(--border); border-radius: 10px;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
.geo-ngon-btn {
|
||||
width: 22px; height: 22px; border-radius: 6px;
|
||||
border: 1px solid var(--border-h);
|
||||
background: transparent; color: var(--text-2);
|
||||
cursor: pointer; display: flex; align-items: center; justify-content: center;
|
||||
transition: background .12s;
|
||||
}
|
||||
.geo-ngon-btn svg { width: 12px; height: 12px; stroke: currentColor; }
|
||||
.geo-ngon-btn:hover { background: rgba(155,93,229,.1); }
|
||||
#geo-ngon-n {
|
||||
font-size: 0.78rem; font-weight: 700; color: var(--text);
|
||||
min-width: 18px; text-align: center;
|
||||
}
|
||||
|
||||
.geo-toggle-row {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 5px 4px; border-radius: 8px; cursor: pointer;
|
||||
@@ -3840,6 +3859,31 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-top:4px">Преобразования</div>
|
||||
<div class="geo-tool-grid">
|
||||
<button id="geo-btn-reflect" class="geo-tool-btn geo-tool-wide" onclick="geoSetTool('reflect',this)" title="Симметрия точки относительно прямой — клик на ось, затем на точку">
|
||||
<svg viewBox="0 0 24 24" fill="none"><line x1="12" y1="2" x2="12" y2="22" stroke-width="1.5" stroke-dasharray="3,2"/><circle cx="6" cy="12" r="3" stroke-width="1.5"/><circle cx="18" cy="12" r="2.5" stroke-width="1.5" opacity=".5"/><line x1="9" y1="12" x2="15" y2="12" stroke-width="1" opacity=".6"/></svg>
|
||||
Симметрия
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-top:4px">Правильный многоугольник</div>
|
||||
<div class="geo-tool-grid">
|
||||
<button id="geo-btn-ngon" class="geo-tool-btn" onclick="geoSetTool('ngon',this)" title="Правильный n-угольник — клик центр, клик вершина">
|
||||
<svg viewBox="0 0 24 24" fill="none"><polygon points="12,3 20.2,8.5 17.3,18 6.7,18 3.8,8.5" stroke-width="1.5" fill="none"/></svg>
|
||||
n-угольник
|
||||
</button>
|
||||
<div class="geo-ngon-ctrl" id="geo-ngon-ctrl">
|
||||
<button class="geo-ngon-btn" onclick="geoNgonN(-1)">
|
||||
<svg viewBox="0 0 16 16" fill="none"><line x1="3" y1="8" x2="13" y2="8" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
</button>
|
||||
<span id="geo-ngon-n">6</span>
|
||||
<button class="geo-ngon-btn" onclick="geoNgonN(+1)">
|
||||
<svg viewBox="0 0 16 16" fill="none"><line x1="8" y1="3" x2="8" y2="13" stroke-width="2" stroke-linecap="round"/><line x1="3" y1="8" x2="13" y2="8" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Display options -->
|
||||
<div class="gp-section-title" style="margin-top:6px">Параметры</div>
|
||||
<label class="geo-toggle-row" onclick="geoToggle('showGrid',this)">
|
||||
@@ -5328,6 +5372,8 @@
|
||||
foot: 'Сначала кликни на прямую/отрезок',
|
||||
circumcircle: 'Кликни 3 точки треугольника — получи описанную окружность',
|
||||
incircle: 'Кликни 3 точки треугольника — получи вписанную окружность',
|
||||
reflect: 'Сначала кликни на ось симметрии (прямую/отрезок)',
|
||||
ngon: 'Клик — центр правильного многоугольника; второй клик — вершина',
|
||||
};
|
||||
|
||||
function geoSetTool(name, btnEl) {
|
||||
@@ -5347,11 +5393,22 @@
|
||||
perpendicular: 'Теперь кликни на точку — через неё проведём перпендикуляр',
|
||||
intersect: 'Теперь кликни на вторую прямую',
|
||||
foot: 'Теперь кликни на точку — найдём основание перпендикуляра',
|
||||
reflect: 'Теперь кликни на точку — получишь её симметричное отражение',
|
||||
};
|
||||
hint.textContent = phase2hints[name] || _GEO_HINTS[name] || '';
|
||||
} else {
|
||||
hint.textContent = _GEO_HINTS[name] || '';
|
||||
}
|
||||
// Показываем/скрываем n-selector только для ngon
|
||||
const ngonCtrl = document.getElementById('geo-ngon-ctrl');
|
||||
// ngon-ctrl всегда виден — расположен рядом с кнопкой в grid
|
||||
}
|
||||
|
||||
function geoNgonN(delta) {
|
||||
if (!geomSim) return;
|
||||
geomSim.setNgonSides(geomSim._ngonSides + delta);
|
||||
const el = document.getElementById('geo-ngon-n');
|
||||
if (el) el.textContent = geomSim._ngonSides;
|
||||
}
|
||||
|
||||
function geoToggle(prop, rowEl) {
|
||||
|
||||
Reference in New Issue
Block a user