feat(math6): Глава 3 — Множество (§1–§5 + финал)
§1 множество/элементы/∅ (∈ или ∉ + счёт элементов); §2 способы задания (свойство→множество + проверка по свойству); §3 операции ∩/∪ (наглядно через Math6.venn + счёт результата); §4 круги Эйлера (задача с числами в областях + формула |A∪B|=|A|+|B|−|A∩B|); финал — 5 боссов. Добавлен Math6.venn (две окружности с заливкой областей и числами). Тесты math6: 16/16. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -177,4 +177,36 @@ M.pie = function (segs, opts) {
|
||||
return M.box(S, S, s, { maxw: opts.maxw || S });
|
||||
};
|
||||
|
||||
/* === КРУГИ ЭЙЛЕРА / ДИАГРАММА ВЕННА (два множества) ===
|
||||
* opts: {a,b (подписи), shade:'inter'|'union'|'a'|'b'|'none', shadeColor,
|
||||
* regions:{aOnly,inter,bOnly,outside}} — числа/текст в областях.
|
||||
*/
|
||||
M.venn = function (opts) {
|
||||
opts = opts || {};
|
||||
var W = 300, H = 190, cA = { x: 115, y: 100 }, cB = { x: 185, y: 100 }, r = 66;
|
||||
var sc = opts.shadeColor || '#7c3aed';
|
||||
var s = '<defs><clipPath id="m6vA"><circle cx="' + cA.x + '" cy="' + cA.y + '" r="' + r + '"/></clipPath></defs>';
|
||||
var cir = function (c, fill, op) { return '<circle cx="' + c.x + '" cy="' + c.y + '" r="' + r + '" fill="' + fill + '"' + (op != null ? ' opacity="' + op + '"' : '') + '/>'; };
|
||||
if (opts.shade === 'union') { s += cir(cA, sc, 0.22) + cir(cB, sc, 0.22); }
|
||||
else if (opts.shade === 'inter') { s += '<g clip-path="url(#m6vA)">' + cir(cB, sc, 0.4) + '</g>'; }
|
||||
else if (opts.shade === 'a') { s += cir(cA, sc, 0.3) + '<g clip-path="url(#m6vA)">' + cir(cB, 'var(--card,#fff)', 1) + '</g>'; }
|
||||
else if (opts.shade === 'b') { s += cir(cB, sc, 0.3) + '<g clip-path="url(#m6vA)">' + cir(cB, 'var(--card,#fff)', 1) + '</g>' + '<g clip-path="url(#m6vA)">' + cir(cB, sc, 0.3) + '</g>'; }
|
||||
/* контуры */
|
||||
s += '<circle cx="' + cA.x + '" cy="' + cA.y + '" r="' + r + '" fill="none" stroke="#4f46e5" stroke-width="2.5"/>';
|
||||
s += '<circle cx="' + cB.x + '" cy="' + cB.y + '" r="' + r + '" fill="none" stroke="#e11d48" stroke-width="2.5"/>';
|
||||
/* подписи множеств */
|
||||
s += '<text x="' + (cA.x - 40) + '" y="' + (cA.y - r + 4) + '" font-size="16" font-weight="800" font-family="Unbounded,Inter,sans-serif" fill="#4f46e5">' + (opts.a || 'A') + '</text>';
|
||||
s += '<text x="' + (cB.x + 30) + '" y="' + (cB.y - r + 4) + '" font-size="16" font-weight="800" font-family="Unbounded,Inter,sans-serif" fill="#e11d48">' + (opts.b || 'B') + '</text>';
|
||||
/* числа/текст в областях */
|
||||
var rg = opts.regions;
|
||||
if (rg) {
|
||||
function lab(x, y, t, col) { if (t == null || t === '') return ''; return '<text x="' + x + '" y="' + (y + 5) + '" text-anchor="middle" font-size="15" font-weight="700" font-family="JetBrains Mono,monospace" fill="' + (col || 'var(--text,#0f172a)') + '">' + t + '</text>'; }
|
||||
s += lab(cA.x - 34, cA.y, rg.aOnly);
|
||||
s += lab((cA.x + cB.x) / 2, cA.y, rg.inter);
|
||||
s += lab(cB.x + 34, cB.y, rg.bOnly);
|
||||
if (rg.outside != null) s += lab(W - 22, H - 14, rg.outside, 'var(--muted,#64748b)');
|
||||
}
|
||||
return M.box(W, H, s, { maxw: opts.maxw || W });
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user