radiosity op• Data kinds: table → matrix
• Call: import fullseye as fs; fs.ledger.form_factor_matrix(patches, n_quad=3, symmetric=True, far_ratio=8.0, memory_budget_mb=256.0) (implementation को सीधे call करना हो तो import radiosity3d; radiosity3d.form_factor_matrix(patches, n_quad=3, symmetric=True, far_ratio=8.0, memory_budget_mb=256.0), registry से लेना हो तो opsoptics.get("form_factor_matrix"))
• GPU: नहीं (केवल CPU reference implementation)
radiosity_patches समूह के सभी patch-युग्मों के view factors F_ij (अवरोध दृश्य की किरणों से)।
> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।
Each pair is form_factor_polygons (n_quad × n_quad Gauss points on the receiver, Lambert's contour sum to the sender) restricted to pairs that face each other; when the patches came from a scene, each Gauss point tests one ray to the sender's centre against the scene. Pairs farther apart than *far_ratio* times the larger patch's diagonal use the receiver's centroid alone (the sender is still exact); far_ratio=None integrates every pair fully. symmetric=True (default) enforces reciprocity exactly by averaging A_i F_ij and A_j F_ji (the raw values agree to the quadrature accuracy) — the progressive solver's F_ij A_i / A_j is then
exactly F_ji.
Candidate pairs use the former, faster all-at-once calculation while its largest temporary fits *memory_budget_mb*, and 256-patch blocks otherwise. The default 256 MB keeps the former path for a 384-patch closed box but blocks 4,096 patches, whose candidate expression alone needs 1.00 GiB. On the 2026-10-21 development machine, whole-call CPU time / tracemalloc peak were 0.234 s / 115 MiB (original), 0.219 s / 60 MiB (default), and 0.234 s / 60 MiB (forced blocks) for 384 patches; the isolated 4,096-patch candidate case measured 0.547 s / 1,152 MiB, 1.500 s / 195 MiB, and 1.516 s / 195 MiB respectively. Pass 0 to always block, or a sufficiently large value to never block.
Returns the (N, N) matrix (matrix), zero diagonal. In a closed enclosure each row sums to 1 (to the quadrature accuracy); an opening shows as a row sum < 1.
Raises ValueError: an empty or unmarked table (not radiosity_patches);
*n_quad* not an integer in [1, 16]; *far_ratio* below 1; or a negative or
non-finite *memory_budget_mb*.
optics के सभी ops गणना से पहले input की जाँच करते हैं (कुछ भी चुपचाप पास नहीं होता):
• Unit argument के नाम में ही लिखी होती है — _mm / _um / _deg / _mrad। mm और µm की गड़बड़ी crash नहीं करती, बल्कि "सही दिखने वाला पर गलत उत्तर" देती है, इसलिए नाम से इसे रोका जाता है। मान के आकार से unit का अनुमान बिल्कुल नहीं लगाया जाता।
• String से ValueError — float('50') सफल हो जाता है, इसलिए बिना parse किया config value length के रूप में निकल जाता (मापा गया: thin_lens('50', '200') सही दिखने वाला 66.667 mm लौटा रहा था)। bool को भी True == 1 वाले implicit promotion के रूप में अस्वीकार किया जाता है।
• complex / masked array से ValueError (केवल real-valued slots; imaginary part को चुपचाप छोड़ना या mask हटाना अस्वीकार)। हर input पर NaN/Inf से ValueError। घोषित अपवाद: bottle_fit_from_pattern का u_map न मापे जा सके पिक्सेल को NaN के रूप में लेता है (अनंत अब भी अस्वीकार)।
• शून्य से भाग और उससे जुड़े मामलों को नाम लेकर अस्वीकार किया जाता है: focal length 0, radius of curvature 0, refractive index <= 0, पूरी तरह opaque aperture (सब 0, इसलिए normalisation 0/0), ऐसा PSF जिसका योग <= 0 हो, S0 = 0 वाला Stokes vector, और front focal point पर रखा object (image अनंत पर)।
• केवल 2 ops non-finite value लौटाते हैं, और वह भी contract के रूप में लिखा हुआ: depth_of_field hyperfocal distance से आगे far_mm = inf (hyperfocal distance की परिभाषा यही है) और gaussian_beam waist पर wavefront_radius_mm = inf (plane wavefront की radius of curvature)। दोनों साथ में एक finite साथी (far_is_infinite / curvature_per_mm) भी लौटाते हैं। इसके अलावा कोई भी चुपचाप आया NaN/Inf अंदर ही पकड़ा जाता है और ValueError देता है — "float64 overflow हुआ" और "उत्तर अनंत है" अलग-अलग दावे हैं, इसलिए पहले को दूसरे का चेहरा पहनाकर नहीं लौटाया जाता। घोषित अपवाद: bottle_background_map जिन पिक्सेल की किरण अनुपयोगी है (पूर्ण आंतरिक परावर्तन आदि) उनके लिए u_mm में NaN लौटाता है, साथ में valid मास्क और गिनती भी।
• Size की सीमा: generate होने वाले grid के लिए optics.MAX_GRID (4096), दिए गए field/PSF/aperture के लिए optics.MAX_FIELD_ELEMENTS (2^24), ABCD element chain के लिए optics.MAX_SYSTEM_ELEMENTS (1024), Zernike के लिए MAX_ZERNIKE_TERMS (512) / MAX_ZERNIKE_ORDER (40) / MAX_ZERNIKE_BASIS (2^25)। छोटे argument से बहुत बड़ा internal allocation होने वाले रास्तों (मापा गया: n_max=40 × 4096² पर 108 GB) को fail-closed ढंग से बंद किया गया है।
• भौतिक रूप से असंभव states भी अस्वीकार: degree of polarisation > 1 वाला Stokes vector, ऋणात्मक transmittance, ऋणात्मक intensity, और n-|m| odd जैसे अमान्य Zernike indices।
• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।
• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।
• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।
• poc_pocket_interreflection — py -3.11 examples/poc_pocket_interreflection.py
matrix को input के रूप में लेते हैं)abcd_trace · emva_filter_distortion · mueller_apply · mueller_checks · equirect_rotate · pixel_shift_capture · pixel_shift_merge · pixel_shift_motion_mask
radiosity)form_factor_parallel_rects · form_factor_perpendicular_rects · form_factor_polygons · radiosity_patches · radiosity_progressive_3d · render_optscene_gi
*Provenance: radiosity3d.py — OPTICS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.