الإحداثيات السالبة تُفسد حسابات القطع في موضعين، لا موضع واحد
القسمة بالبتر تضع المكعب −1 في القطعة 0 بدلًا من −1، وعملية % العادية تعطي إزاحة داخل القطعة مقدارها −1 بدلًا من 15. كلاهما خاطئ، وكلاهما يبدو صحيحًا حتى تتجه غرب نقطة الظهور.
كل حساب للقطع بديهي في الربع الموجب وخاطئ في الأرباع الثلاثة الأخرى. هناك بالضبط موضعان يختل فيهما الحساب، وهما مستقلان عن بعضهما، وكلاهما ينتج إجابات تبدو معقولة.
العمليتان
chunk = floor(block / 16) not trunc(block / 16)
offset = ((block % 16) + 16) % 16 not block % 16
إحداثيات المنطقة هي الزوج نفسه، بمستوى أعلى، مع 32 بدلًا من 16:
region = floor(chunk / 32) -> r.<x>.<z>.mca
regionOff = ((chunk % 32) + 32) % 32
إذن المنطقة تساوي 32 × 32 قطعة، أي 512 × 512 مكعبًا.
أين يعضّ كل منهما
القسمة. معظم اللغات تبتر نحو الصفر، وfloor يقرّب نحو سالب اللامحدودية. يتفقان في الموجب ويختلفان في كل سالب ليس من مضاعفات العدد بالضبط:
- المكعب
−1→floor(−1/16) = −1✓، لكنtrunc(−1/16) = 0✗
المكعب −1 يقع مكعبًا واحدًا غرب نقطة الأصل وينتمي إلى القطعة −1. البتر يضعه في القطعة 0، إلى جانب المكعب +1. كل فهرس قطعة سالب يخرج واحدًا أكبر من اللازم.
الباقي. في JavaScript وJava وC ومعظم اللغات الأخرى، يحتفظ % بإشارة المعامل الأيسر:
- المكعب
−1→ الإزاحة الصحيحة15، لكن−1 % 16 = −1✗
الإزاحة −1 ليست موضعًا داخل قطعة عرضها 16 على الإطلاق. فهرسة مصفوفة مكعبات بها إما ترمي استثناءً أو تقرأ خلية خاطئة بصمت.
مثال محلول
المكعب −1290 على محور واحد:
| الخطوة | الصحيح | الساذج |
|---|---|---|
| القطعة | floor(−1290/16) = −81 | trunc = −80 ✗ |
| الإزاحة داخل القطعة | 6 | −1290 % 16 = −10 ✗ |
| المنطقة | floor(−81/32) = −3 | trunc = −2 ✗ |
| الإزاحة داخل المنطقة | 15 | −81 % 32 = −17 ✗ |
أربع قيم، أربع إجابات خاطئة، ولا واحدة منها خارج النطاق بما يكفي لتبدو معطوبة بوضوح. المنطقة −3 تمتد من القطعة −96 إلى −65، والقطعة −81 تقع 15 من بدايتها — وهو بالضبط ما يعيده الباقي المصحَّح.
تحويل نذر فاقد في اتجاه واحد
من العالم العادي إلى نذر يقسم على 8، وهو أيضًا يقرّب للأسفل:
netherX = floor(overworldX / 8)
العودة تضرب موضعك الدقيق في 8، لذا يُعاد ربط كامل مكعب نذر 125 إلى مكان ما في 1000–1007، حسب موضعك داخل ذلك المكعب. هذه ليست رحلة ذهاب وعودة لإحداثيات المكعبات. floor يرمي الباقي:
- العالم العادي
1000→ نذر125→ عودة إلى1000✓ - العالم العادي
1007→ نذر125→ إحداثي المكعب يقول1000✗ — سبعة مكعبات ناقصة
الخطأ من 0 إلى 7 مكعبات لكل محور، أي حتى 7 على X و7 على Z في آن واحد. هذا هو السبب الكامل وراء حاجة الربط الدقيق للبوابات إلى كتابة إحداثي نذر بدلًا من إعادة اشتقاقه: بمجرد أن تقسم، لم يعد موضع العالم العادي الذي جاء منه قابلًا للاستعادة.
بالنسبة لمركز نذر نادرًا ما يهم هذا — 7 مكعبات داخل نطاق الالتقاط الخاص بالبوابة نفسها. أما لربط بوابتين يجب ألا تسرق إحداهما حركة الأخرى، فهو يهم كثيرًا.
الإحداثيات السالبة في العالم العادي تزيد الأمر سوءًا بالطريقة المعتادة: العالم العادي −1 يعطي نذر floor(−1/8) = −1، بينما البتر يعطي 0 ويرسلك إلى الجانب الخاطئ من المحور.