การซูม การแพน และการหมุนทำงานอย่างไร

เมื่อใช้ OpenGL ฉันกำลังพยายามวาดแผนที่ดั้งเดิมของวิทยาเขตของฉัน

ใครช่วยอธิบายให้ฉันฟังหน่อยได้ไหมว่าปกติแล้วจะใช้งานการแพน ซูม และหมุนอย่างไร

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

สำหรับการแพนกล้อง ค่า x/y ของวิวพอร์ตของฉันจะเลื่อนไป และสำหรับการซูมจะเพิ่ม/ลดวิวพอร์ตของฉันบ้างหรือไม่ แล้วสำหรับการหมุนล่ะ?

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

หรือวิวพอร์ตยังคงเหมือนเดิมและการแพน/ซูม/หมุนทำอย่างอื่นหรือไม่?


ตัวอย่างเช่น หากคุณไปที่ลิงก์นี้ คุณจะ จะเห็นเขาอธิบายการแพนและซูมเหมือนกับที่ฉันมีด้านบน โดยการปรับเปลี่ยนวิวพอร์ต

นี่ไม่ถูกต้องเหรอ?


person KingNestor    schedule 25.02.2009    source แหล่งที่มา


คำตอบ (3)


สามารถทำได้โดยการใช้ชุดคำสั่ง glTranslate, glRotate (ซึ่งแสดงถึงตำแหน่งและการวางแนวของกล้อง) ก่อนที่จะวาดฉาก (ในทางเทคนิคแล้ว คุณจะหมุนทั้งฉาก!)

มีฟังก์ชั่นยูทิลิตี้เช่น gluLookAt ซึ่งเรียงลำดับรายละเอียดบางอย่างเกี่ยวกับเรื่องนี้

เพื่อให้สิ่งต่าง ๆ ดูเรียบง่าย สมมติว่าคุณมีเวกเตอร์สองตัวที่แสดงถึงกล้องของคุณ: ตำแหน่งและทิศทาง

gluLookAt รับตำแหน่ง ปลายทาง และเวกเตอร์ขึ้น

หากคุณใช้คลาสเวกเตอร์ destinaion = position + direction ควรให้จุดปลายทางแก่คุณ

อีกครั้งเพื่อทำให้ทุกอย่างง่ายขึ้น คุณสามารถถือว่าเวกเตอร์ขึ้นเป็น (0,1,0) เสมอ

จากนั้น ก่อนที่จะเรนเดอร์สิ่งใดๆ ในฉากของคุณ ให้โหลดเมทริกซ์เอกลักษณ์และเรียก gluLookAt

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( source.x, source.y, source.z, destination.x, destination.y, destination.z, 0, 1, 0 );

จากนั้นเริ่มวาดวัตถุของคุณ

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

ปัญหาหนึ่งคือ หากคุณมีเพียงเวกเตอร์ทิศทาง "ไปข้างหน้า" คุณจะเคลื่อนมันอย่างไร ซ้ายและขวาอยู่ที่ไหน?

แนวทางของฉันในกรณีนี้คือหาผลคูณไขว้ของ "ทิศทาง" และ (0,1,0)

ตอนนี้คุณสามารถเลื่อนกล้องไปทางซ้ายและขวาได้โดยใช้สิ่งต่อไปนี้

position = position + right * amount; //amount < 0 moves to the left

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

forward = cross( up, right )

พูดตามตรง นี่เป็นแนวทางที่ค่อนข้างแฮ็ก

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

person hasen    schedule 25.02.2009
comment
ฉันขอเสริมว่าไม่ว่าจุดใดวิวพอร์ต (ตามที่ตั้งค่าผ่าน glViewport) จะเข้าสู่กระบวนการนี้ วิวพอร์ตจะกำหนดขอบเขตของหน้าต่างที่คุณจะแสดงผล (ซึ่งอันที่จริงแล้วไม่เป็นความจริง แต่ตอนนี้ลองคิดแบบนี้ดู) และโดยปกติจะขยายทั่วทั้งหน้าต่าง - person Thomas; 25.02.2009

"การกระทำ" ทั้งหมดนี้สามารถทำได้โดยใช้ฟังก์ชันการแปลงเมทริกซ์มุมมองโมเดล คุณควรอ่านเกี่ยวกับ glTranslatef (แพน), glScalef (ซูม), glRotatef (การหมุน) นอกจากนี้ คุณควรอ่านบทช่วยสอนพื้นฐานเกี่ยวกับ OpenGL ด้วย คุณอาจพบว่า ลิงก์นี้มีประโยชน์

person okutane    schedule 25.02.2009

โดยทั่วไปจะมีสามขั้นตอนที่ใช้เมื่อใดก็ตามที่คุณอ้างอิงจุดใดๆ ในพื้นที่ 3 มิติภายใน opengl

ได้รับจุดท้องถิ่น

  • ท้องถิ่น -> การเปลี่ยนแปลงของโลก
  • โลก -> การแปลงกล้อง
  • กล้อง -> การแปลงหน้าจอ (โดยปกติจะเป็นการฉายภาพ ขึ้นอยู่กับว่าคุณใช้เปอร์สเปคทีฟหรือมุมฉาก)

การแปลงแต่ละครั้งจะใช้จุด 3 มิติของคุณ และคูณด้วยเมทริกซ์

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

person FryGuy    schedule 25.02.2009