การจัดเก็บตารางฐานสิบหก


10

ฉันได้สร้างกรอบกริดหกเหลี่ยมขนาดเล็กสำหรับ Unity3D และมาถึงภาวะที่กลืนไม่เข้าคายไม่ออกต่อไปนี้แล้ว นี่คือระบบพิกัดของฉัน (นำมาจากที่นี่ ):

ป้อนคำอธิบายรูปภาพที่นี่

มันใช้งานได้ดียกเว้นในความเป็นจริงฉันไม่รู้ว่าจะเก็บมันอย่างไร ตอนแรกฉันตั้งใจจะเก็บมันไว้ในอาร์เรย์ 2D และใช้ภาพเพื่อสร้างแผนที่ของฉัน

ปัญหาหนึ่งคือมันมีค่าลบ (ซึ่งแก้ไขได้ง่ายโดยการชดเชยพิกัดเล็กน้อย)

อย่างไรก็ตามเนื่องจากระบบพิกัดนี้รูปภาพหรือบิตแมปจะต้องเป็นรูปสี่เหลี่ยมขนมเปียกปูนและเนื่องจากโครงสร้างเหล่านี้เป็นรูปทรงสี่เหลี่ยมจึงทำให้เกิดอาการปวดหัวมากแม้ว่าฉันจะแฮ็กบางสิ่งร่วมกัน มีอะไรที่ฉันขาดหายไปที่สามารถแก้ไขได้ไหม ฉันจำได้ว่าเห็นโพสต์ฟอรัมเกี่ยวกับเรื่องนี้ในฟอรัมความสามัคคี แต่ฉันไม่สามารถหาลิงก์ได้อีกต่อไป

การเขียนนักแปลชุดประสานงานเป็นทางออกที่ดีที่สุดหรือไม่

หากพวกคุณคิดว่ามันจะมีประโยชน์ฉันสามารถโพสต์รหัสและรูปภาพของปัญหาของฉัน


1
คุณไม่สามารถบันทึกภาพ PNG ที่โปร่งใสรอบรูปหกเหลี่ยมได้หรือไม่
Markus von Broady

ปัญหาหลักของฉันกับการบันทึกไปยัง pngs และอาร์เรย์คือจำนวนของ "ช่องว่าง" ที่พวกเขาจะต้องมีเพื่อให้ระบบพิกัดนี้ยังคงเหมือนเดิม
PeeC

1
หาก "ช่องว่าง" หมายถึงพิกเซลแบบโปร่งใสเหตุใดจำนวนพิกเซลถึงเป็นปัญหา
Markus von Broady

นั่นเป็นจุดที่ดีมาก รูปแบบภาพส่วนใหญ่จะไม่ทำให้หน่วยความจำจำนวนมากเก็บรูปแบบซ้ำ ๆ กัน แต่ก็ยังทำให้ฉันรำคาญเล็กน้อยที่จะเก็บแผนที่นี้ฉันใช้หน่วยความจำมากขนาดนี้ (พิกเซลสีเทาเป็นพื้นที่ว่างเปล่าสีอื่น ๆ คือพิกัดฐานสิบหกที่ถูกต้อง)
PeeC

1
โอ้คุณกำลังจัดเก็บข้อมูลกริดไม่ใช่ภาพย่อย! ทำไมคุณไม่บันทึกโครงสร้างข้อมูลของคุณ (กริด) ลงในไฟล์ไบนารีหรือเข้ารหัสโดยใช้เช่น JSON และบันทึกลงในไฟล์ข้อความ แม้ว่าฉันไม่ทราบความสามารถของ Unity นอกจากนี้คุณอาจต้องการยืนยันสิ่งนี้ แต่ฉันเชื่อว่าพื้นที่ที่มีสีเดียวกันได้รับการปรับปรุง (บีบอัดอย่างหลวม ๆ ) ในรูปแบบ PNG
Markus von Broady

คำตอบ:


9

พิกัดสี่เหลี่ยมด้านขนานที่คุณใช้นั้นง่ายต่อการใช้งาน แต่มีข้อเสียเปรียบในการใช้แผนที่แปลก ๆ วิธีหนึ่งคือการจัดเก็บด้วยพิกัดออฟเซ็ต แต่จริง ๆ แล้วใช้พิกัดสี่เหลี่ยมด้านขนานในตรรกะเกมของคุณ

การสังเกต: ในแต่ละแถวของแผนที่ข้อมูลกริดนั้นต่อเนื่องกัน พื้นที่ว่างเปล่าทั้งหมดอยู่ทางซ้ายและขวา

วิธีแก้ไข: ภายในแถวนั้นจัดเก็บข้อมูลที่เริ่มต้นที่คอลัมน์ซ้ายสุดแทนคอลัมน์ที่มีเครื่องหมาย 0 คำนวณคอลัมน์แรกของแผนที่รูปสี่เหลี่ยมผืนผ้าในระบบพิกัดของคุณแล้วลบออกจากพิกัดคอลัมน์เพื่อกำหนดว่าจะไปที่ใดในอาเรย์ ใช้งานได้กับพิกัดคอลัมน์เชิงลบด้วย

ทำการแปลงใน getter และ setter สำหรับแผนที่ดังนี้:

inline function get(q, r) {
    first_column_in_this_row = -floor(q/2);
    return array[r][q - first_column_in_this_row];
}

คุณจะต้องแก้ไขสิ่งนี้เพื่อให้สามารถทำงานร่วมกับพิกัดและแผนที่ที่คุณเลือกได้ ในบางเลย์เอาต์คุณจะต้องการชดเชยคอลัมน์ตามแถวแทนที่จะกลับกัน

คุณสามารถใช้เคล็ดลับเดียวกันเพื่อสร้างแผนที่ของรูปร่างอื่น ๆ มันไม่ได้ จำกัด อยู่แค่รูปสี่เหลี่ยม

หากคุณใช้ C หรือ C ++ คุณสามารถใช้เลขคณิตของตัวชี้เพื่อทำให้เร็วขึ้น first_column_in_rowแทนการจัดเก็บอาร์เรย์ของตัวชี้ไปยังอาร์เรย์ที่เก็บอาร์เรย์ของตัวชี้ที่ได้รับการปรับด้วย (อาจไม่สามารถพกพาได้)


มันทำงานได้ไกลที่สุดเท่าที่ฉันจะบอกได้ แต่คณิตศาสตร์นั้นแปลกจริงๆ หลังจากลองใช้สมการหลายอย่างที่ทำให้รู้สึกในหัวของฉันฉันตัดสินyIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)หลังจากการลองผิดลองถูก ไม่รู้เลยว่ามันทำงานอย่างไรยาก
PeeC

ทำสิ่งyIndex = y-((x%2==0)?(-x/2):(-x/2)-1)นั้น x / 2 เป็น btw ตามจำนวนเต็มทั้งหมดจึงไม่จำเป็นต้องปูพื้น
PeeC

6

ส่วนตัวแล้วฉันชอบความเรียบง่ายมากกว่าการบันทึกความทรงจำ อย่าปรับให้เหมาะสมจนกว่าจะต้องการ!

หากคุณยังคงก้มบันทึกสองสามไบต์ต่อไปนี้เป็นวิธีที่คุณสามารถทำได้:

ป้อนคำอธิบายรูปภาพที่นี่

  1. แบ่งสี่เหลี่ยมด้านขนานออกเป็นครึ่งหนึ่งเพื่อสร้างสามเหลี่ยมมุมฉากสองอัน
  2. จัดเรียงสามเหลี่ยมสองรูปใหม่เพื่อจัดทำสี่เหลี่ยมผืนผ้า
  3. (หมายเหตุฉันเพิ่มแถบบัฟเฟอร์สีเขียวเพื่อให้คณิตศาสตร์ทำงานได้ดี)

รหัสไพ ธ อนเพื่อจับคู่พิกัดสี่เหลี่ยมผืนผ้ากับพิกัดสี่เหลี่ยมด้านขนานและด้านหลัง:

# Height of rectangle
H = 15

def r2p(x, y):
"rectangle to parallelogram"
if y < -x/2 + H:
    y = y + H
return (x - 1, y)

def p2r(x,y):
"parallelogram to rectangle"
if y >= H:
    y = y - H
return (x + 1, y)

2
คุณสามารถเลื่อนพิกเซลลงในแนวตั้งได้ - บนภาพที่จะเป็นoffsetY = Math.floor ( (x+1)/2 )
Markus von Broady

1

ไม่จำเป็นต้องบิดเบือนแผนที่ของคุณเนื่องจากการแปลงระหว่างพิกัดรูปสี่เหลี่ยมและพิกัด "บัญญัติ" นั้นรวดเร็วและง่ายดาย นี่คือลิงก์ไปยังคำแนะนำเกี่ยวกับวิธีการใช้งาน:

การแปลงระหว่างพิกัดฐานหกเหลี่ยมแบบเหลี่ยมและ Canonical

เทคนิคนี้รวมการประเมินที่ขี้เกียจกับการแคชของการแปลงที่คำนวณได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.