kind=space (fixed oblique 3D: points, vectors, planes, box) + ~190 figured questions for grade 12 (geometry, discrete, calculus)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -152,6 +152,14 @@ _SOLID = (
|
||||
'مثلث، پنجضلعی و ششضلعی)'
|
||||
)
|
||||
|
||||
_SPACE = (
|
||||
'space (مختصات و بردار در فضای سهبعدی، تصویرِ مایل؛ برای R³، بردارِ سهمؤلفهای، ضربِ داخلی و خارجی، خط و صفحه در فضا): '
|
||||
'{"kind":"space","title":"…","axes":true,"points":{"A":[1,2,3],"B":[3,0,1]},"items":[…]}. محورها: x رو به بیننده، '
|
||||
'y راست، z بالا. items: {"type":"point","point":"A","label":"A(1,2,3)"} · {"type":"vector","from":"O","to":"A","label":"a"} · '
|
||||
'{"type":"segment","from":"A","to":"B","dashed":true} · {"type":"polygon","points":["A","B","C"],"label":"P"} (مثلث یا صفحهی '
|
||||
'متوازیالاضلاعی؛ نیمهشفاف) · {"type":"box","to":[3,2,4]} (مکعبمستطیلِ مختصاتی از مبدأ) · {"type":"drop","point":"A"} '
|
||||
'(خطچینهای تصویرِ نقطه روی صفحههای مختصات). مبدأ "O" خودکار است. رنگ فقط: blue red green orange purple teal.'
|
||||
)
|
||||
_W = lambda words: re.compile('|'.join(words)) # noqa: E731
|
||||
_GEOMETRY_WORDS = (r'مثلث', r'دایره(?!ای)', r'زاویه', r'ضلع', r'چندضلعی', r'مربع', r'مستطیل', r'لوزی', r'ذوزنقه',
|
||||
r'متوازی', r'شعاع', r'قطر', r'وتر', r'محیط', r'مساحت', r'کمان', r'محاطی', r'مماس', r'موازی',
|
||||
@@ -175,6 +183,7 @@ SECTIONS = [
|
||||
(_W((r'احتمال', r'سکه', r'تاس', r'درختی')), _TREE),
|
||||
(_W((r'الگو', r'چوب\s*کبریت', r'دنباله', r'شکل[\u0650\s]*(?:بعدی|شماره|[0-9۰-۹])')), _PATTERN),
|
||||
(_W((r'مکعب', r'منشور', r'هرم', r'استوانه', r'مخروط', r'کره', r'حجم', r'نیمکره')), _SOLID),
|
||||
(_W((r'سهبعدی', r'R³', r'ضرب\s*(?:داخلی|خارجی)', r'مختصات[^.؟]{0,12}فضا', r'بردار[^.؟]{0,20}فضا')), _SPACE),
|
||||
]
|
||||
DIAGRAM_SPEC = '\n'.join([_HEAD] + [text for _, text in SECTIONS])
|
||||
|
||||
@@ -750,6 +759,68 @@ def _tree(node, depth=0) -> dict:
|
||||
return out
|
||||
|
||||
|
||||
_SPACE_COLORS = {'blue', 'red', 'green', 'orange', 'purple', 'teal'}
|
||||
|
||||
|
||||
def _space(spec: dict, title: str) -> dict | None:
|
||||
"""
|
||||
فضای سهبعدی با تصویرِ مایل (ثابت، نه چرخان). مثلِ plane: آیتمِ خراب حذف میشود، شکلِ بیآیتم None است.
|
||||
مختصات در بازهی ±۱۰۰ و فقط عدد؛ هیچ متنِ آزادی جز برچسبهای کوتاه نمیگذرد.
|
||||
"""
|
||||
points = {'O': [0.0, 0.0, 0.0]}
|
||||
raw = spec.get('points') or {}
|
||||
if not isinstance(raw, dict):
|
||||
return None
|
||||
for name, value in list(raw.items())[:MAX_POINTS]:
|
||||
if not isinstance(name, str) or not _NAME_OK.match(name):
|
||||
continue
|
||||
try:
|
||||
if not (isinstance(value, (list, tuple)) and len(value) == 3):
|
||||
raise ValueError('triple')
|
||||
points[name] = [_num(v, -100, 100) for v in value]
|
||||
except ValueError:
|
||||
continue
|
||||
items = []
|
||||
for it in (spec.get('items') or [])[:MAX_ITEMS + 8]:
|
||||
if not isinstance(it, dict):
|
||||
continue
|
||||
try:
|
||||
kind = it.get('type')
|
||||
out = {'type': kind}
|
||||
if it.get('color') in _SPACE_COLORS:
|
||||
out['color'] = it['color']
|
||||
if it.get('label'):
|
||||
out['label'] = _label(it['label'], 24)
|
||||
if kind in ('point', 'drop'):
|
||||
if it.get('point') not in points:
|
||||
continue
|
||||
out['point'] = it['point']
|
||||
elif kind in ('vector', 'segment'):
|
||||
if it.get('from') not in points or it.get('to') not in points:
|
||||
continue
|
||||
out['from'], out['to'] = it['from'], it['to']
|
||||
if it.get('dashed'):
|
||||
out['dashed'] = True
|
||||
elif kind == 'polygon':
|
||||
names = it.get('points')
|
||||
if not (isinstance(names, list) and 3 <= len(names) <= 6 and all(n in points for n in names)):
|
||||
continue
|
||||
out['points'] = list(names)
|
||||
elif kind == 'box':
|
||||
to = it.get('to')
|
||||
if not (isinstance(to, (list, tuple)) and len(to) == 3):
|
||||
continue
|
||||
out['to'] = [_num(v, -100, 100) for v in to]
|
||||
else:
|
||||
continue
|
||||
items.append(out)
|
||||
except ValueError:
|
||||
continue
|
||||
if not items and len(points) < 2:
|
||||
return None
|
||||
return {'kind': 'space', 'title': title, 'axes': spec.get('axes') is not False, 'points': points, 'items': items[:MAX_ITEMS + 8]}
|
||||
|
||||
|
||||
def validate(spec) -> dict | None:
|
||||
"""
|
||||
نسخهی تمیزِ spec، یا None. فقط کلیدها و نوعهای شناختهشده رد میشوند؛
|
||||
@@ -767,6 +838,8 @@ def validate(spec) -> dict | None:
|
||||
return _plane(spec, title)
|
||||
if kind == 'numberline':
|
||||
return _numberline(spec, title)
|
||||
if kind == 'space':
|
||||
return _space(spec, title)
|
||||
if kind == 'fraction':
|
||||
shape = spec.get('shape') if spec.get('shape') in ('circle', 'rect') else 'circle'
|
||||
compare = []
|
||||
|
||||
Reference in New Issue
Block a user