คำถามติดแท็ก rotation

การหมุนเป็นการเคลื่อนที่แบบวงกลมของวัตถุรอบแกนที่ระบุ

2
ฉันกำลังหมุนวัตถุบนสองแกนดังนั้นทำไมมันหมุนรอบแกนที่สามต่อไป?
ฉันเห็นคำถามเกิดขึ้นบ่อยครั้งที่มีปัญหาพื้นฐานนี้ แต่ทุกคำถามล้วนแล้วแต่เกี่ยวข้องกับคุณลักษณะหรือเครื่องมือที่กำหนด นี่คือความพยายามในการสร้างคำตอบที่ยอมรับได้ซึ่งเราสามารถอ้างถึงผู้ใช้เมื่อเกิดเหตุการณ์นี้ขึ้น - ด้วยตัวอย่างภาพเคลื่อนไหวมากมาย! :) สมมติว่าเรากำลังสร้างกล้องตัวแรก แนวคิดพื้นฐานคือควรหันเหมองไปทางซ้ายและขวา ดังนั้นเราจึงเขียนโค้ดแบบนี้ (ใช้ Unity เป็นตัวอย่าง): void Update() { float speed = lookSpeed * Time.deltaTime; // Yaw around the y axis using the player's horizontal input. transform.Rotate(0f, Input.GetAxis("Horizontal") * speed, 0f); // Pitch around the x axis using the player's vertical input. transform.Rotate(-Input.GetAxis("Vertical") * …

2
การคำนวณแรงหมุนของสไปรต์ 2D
ฉันสงสัยว่าใครบางคนมีวิธีการคำนวณสถานการณ์ต่อไปนี้อย่างสวยงาม ฉันมีวัตถุของจำนวนสี่เหลี่ยม (n) จำนวนรูปร่างแบบสุ่ม แต่เราจะแกล้งพวกมันเป็นรูปสี่เหลี่ยมผืนผ้าทั้งหมด เรากำลังจัดการกับแรงโน้มถ่วงไม่ดังนั้นพิจารณาวัตถุในอวกาศจากมุมมองจากบนลงล่าง ฉันกำลังใช้แรงกับวัตถุที่ช่องสี่เหลี่ยมเฉพาะ (ดังที่แสดงด้านล่าง) ฉันจะคำนวณมุมการหมุนได้อย่างไรโดยขึ้นอยู่กับแรงที่ใช้กับตำแหน่งที่ใช้งาน หากนำไปใช้ในจัตุรัสกลางมันจะตรงไป ฉันควรจะทำตัวต่อไปอย่างไรเมื่อย้ายจากจุดศูนย์กลาง ฉันจะคำนวณความเร็วในการหมุนได้อย่างไร
35 2d  rotation  physics  vector 

3
ทีมป้องกันการเขียนทับทำงานในไฟล์ต้นฉบับได้อย่างไร [ปิด]
ปิด. คำถามนี้เป็นคำถามปิดหัวข้อ ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้เป็นหัวข้อสำหรับ Game Exchange Stack Exchange ปิดให้บริการใน4 ปีที่แล้ว มันเป็นไปได้สำหรับฉันที่มีหลายคนที่กำลังทำงานอยู่ในขณะเดียวกันเช่นเอ็นจิ้นเกม สมมติว่านักพัฒนาคนหนึ่งกำลังทำงานAudio.cppและนักพัฒนาที่สองก็กำลังทำงานอยู่Audio.cppสิ่งนี้จัดการโดยทั่วไปในทีมขนาดใหญ่เพื่อต่อสู้กับการเขียนทับได้อย่างไร (ในคำอื่น ๆ ที่จะหยุดสองนักพัฒนาจากการเปิดไฟล์จนกว่านักพัฒนาคนหนึ่งจะเสร็จสิ้น)
26 project-management  version-control  teamwork  java  2d  collision-detection  vector  collision-resolution  unity  directx  directx11  directx10  xna  ios  monogame  windows-phone-8  xamarin  design-patterns  oop  xna  collision-detection  collision-resolution  bounding-boxes  rotation  collision-detection  mathematics  javascript  algorithm  separating-axis-theorem  xna  2d  monogame  image  xna  directx  graphics  performance  opengl  2d  3d  c++  directx11  unity  c#  scale  c#  xna  collision-detection  collision-resolution  leaderboards  scoring  glsl  srgb  tilemap  three.js  tiled  unity  physics  xml  dialog-tree  xna  c#  .net  opengl  lwjgl  vbo  physics  graphics  procedural-generation  simulations  water  opengl  java  textures  lwjgl  frame-buffer  unity  unity  2d  collision-detection  collision-resolution  trigonometry  java  android  libgdx  xna  c#  frame-rate  c++  unreal-4  procedural-generation  java  graphics  lwjgl  slick  c++  software-engineering 

6
วิธีการทำให้แน่ใจว่าวัตถุหมุนได้เข้าเป้าด้วยปลายด้านขวา
ฉันกำลังทำงานกับอาวุธประเภทมีดขว้างปาที่ผู้เล่นมีเป้าหมายฟรีแล้วขว้างมีด มีดหมุนผ่านอากาศและในการปะทะกันหยุดหมุนและผู้ปกครองเองกับวัตถุที่มันชนกัน การหมุนถูกจัดการผ่านทางภาพเคลื่อนไหวในขณะที่เส้นทางของมีดถูกจัดการโดยฟิสิกส์ ปัญหาหนึ่งที่ฉันเผชิญคือทำอย่างไรเพื่อให้แน่ใจว่าเมื่อมีดชนกับศัตรูว่ามีดจะหันเข้าหาพวกเขา ในขณะที่สิ่งที่เกิดขึ้นบางครั้งก็คือมีดฝังอยู่ในมือของศัตรูก่อน ซึ่งไม่สมจริงอย่างเห็นได้ชัด ในเวลาเดียวกันฉันคิดว่ามันไม่มีเหตุผลที่จะมีดที่จะ "กด" ศัตรูถ้ามันชนใบมีดก่อนเนื่องจากอัตราที่มีดหมุนอยู่นอกเหนือการควบคุมของผู้เล่น ฉันได้ดูภาพจากกล้องที่คล้ายกันของ killcam ที่ช้ามาก ๆ และทุกครั้งที่มีการโยนอาวุธมันจะหมุนไปในอากาศและในที่สุดก็จะมีดาบที่ชี้ไปที่เป้าหมาย สำหรับเกมที่ระยะการขว้างปาสอดคล้องกันนี่จะค่อนข้างตรงไปตรงมา แต่ฉันไม่แน่ใจว่าจะทำนายได้อย่างไรเนื่องจากมีปัจจัยที่คาดเดาไม่ได้หลายอย่างที่เกี่ยวข้องเช่น ทิศทางของมีด, การหมุนของมีด, ตำแหน่งของศัตรู, ระยะทางจากศัตรู ฯลฯ หากเป็นไปได้ฉันไม่ต้องการใช้ตรรกะการทำนายที่ซับซ้อนเนื่องจากเกมจะเป็นอุปกรณ์ระดับต่ำ มีวิธี "ควันและกระจก" เพื่อแก้ปัญหานี้หรือไม่? ตัวอย่าง: https://youtu.be/0fav8lFpBko?t=42s

3
ฉันจะหมุนวัตถุโดยอิงจากอ็อฟเซ็ตของวัตถุอื่นได้อย่างไร?
ฉันมีแบบจำลอง 3 มิติของป้อมปืนที่หมุนรอบแกน Y ป้อมปืนนี้มีปืนใหญ่ที่อยู่กึ่งกลางของวัตถุ ฉันต้องการปืนใหญ่ไม่ใช่ป้อมปืนเพื่อเล็งไปที่เป้าหมายที่ระบุ อย่างไรก็ตามฉันสามารถหมุนป้อมปืนได้เท่านั้นและด้วยเหตุนี้ฉันจึงไม่ทราบว่าต้องใช้สมการใดเพื่อบรรลุเป้าหมาย ภาพต่อไปนี้แสดงให้เห็นถึงปัญหาของฉัน: หากฉันมีป้อมปืน "LookAt ()" เป้าหมายเลเซอร์ที่มาจากปืนใหญ่จะพลาดเป้าหมายที่กล่าวไปทั้งหมด ถ้านี่เป็นสถานการณ์จากบนลงล่างอย่างสมบูรณ์และปืนใหญ่ขนานกับป้อมปืนแล้วตรรกะของฉันบอกฉันว่าเป้าหมายปลอมควรอยู่ในตำแหน่งที่เท่ากับเป้าหมายจริงบวกกับออฟเซ็ตที่เท่ากับระหว่าง ป้อมปืนและปืนใหญ่ อย่างไรก็ตามในสถานการณ์จริงของฉันกล้องของฉันมีมุม60ºและปืนใหญ่มีการหมุนเล็กน้อย ภาพต่อไปนี้แสดงให้เห็นถึงสถานการณ์: ฉันไม่แน่ใจอย่างแน่นอนว่าทำไม แต่ถ้าฉันใช้การชดเชยแบบเดียวกันดูเหมือนว่าจะทำงานได้ในขณะที่เล็งไปที่ระยะทางจากป้อมปืน ตรรกะของฉันมีข้อบกพร่องหรือไม่ ฉันขาดพื้นฐานบางอย่างที่นี่หรือไม่? การแก้ไขขั้นสุดท้าย: โซลูชันที่ได้รับจาก @JohnHamilton อัพเดตล่าสุดแก้ไขปัญหานี้ได้อย่างแม่นยำ ตอนนี้ฉันได้ลบรหัสและรูปภาพที่ฉันใช้เพื่อแสดงการใช้งานที่ไม่ถูกต้องของฉัน

2
ใช้ Quaternions: ฉันจะทำอะไรกับพวกเขา? (ไม่มีคณิตศาสตร์)
ฉันเป็นนักพัฒนาเกมและไม่ได้เรียนวิชาคณิตศาสตร์ ดังนั้นฉันต้องการใช้ Quaternions เป็นเครื่องมือเท่านั้น และเพื่อให้สามารถทำงานกับการหมุน 3 มิติได้จำเป็นต้องใช้ Quaternions (หรือเมทริกซ์ แต่ให้อยู่ที่ Quaternions ที่นี่ในคำถามนี้) ฉันคิดว่ามันสำคัญสำหรับนักพัฒนาหลายคนที่จะใช้พวกเขา นั่นเป็นเหตุผลที่ฉันต้องการแบ่งปันความรู้ของฉันและหวังว่าจะเติมเต็มช่องว่างที่ฉันมี ตอนนี้ .... เท่าที่ฉันเข้าใจ: Quaternion สามารถอธิบาย 2 สิ่ง: การวางแนวปัจจุบันของวัตถุ 3 มิติ การแปลงการหมุนที่วัตถุทำได้ (rotationChange) คุณสามารถทำอะไรกับ Quaternion: คูณ: Quaternion endOrientation = การหมุน QuaternionChange * Quaternion currentOrientation; ตัวอย่างเช่น: วัตถุ 3 มิติของฉันหันไปทางซ้าย 90 องศา - และการหมุนของฉันฉันคูณคือการหมุน 180 องศาไปทางขวาในที่สุดวัตถุ 3 มิติของฉัน 90 …

4
ฉันจะโคจรกล้องไปยังจุดที่เป็นเป้าหมายได้อย่างไร
ฉันวาดฉากที่กล้องเคลื่อนไหวอย่างอิสระเกี่ยวกับจักรวาล คลาสกล้องจะติดตามตำแหน่งมุมมอง (หรือดู ) ตำแหน่งของกล้องและเวกเตอร์ขึ้น เวกเตอร์ / คะแนนเหล่านี้จะถูกส่งผ่านไปยัง gluLookAt แพนและซูมนั้นแทบไม่น่าเชื่อ อย่างไรก็ตามฉันกำลังค้นหาการหมุนเกี่ยวกับจุดที่มองว่ามีปัญหามากกว่านี้ ฉันต้องการที่จะเขียน Camera.rotate ฟังก์ชั่นที่ใช้เวลา 2 มุมหนึ่งที่หมุนขึ้น / ลงและหนึ่งที่หมุนซ้าย / ขวาพร้อมทรงกลมจินตนาการว่าเป็นศูนย์กลางเกี่ยวกับการดูที่จุด มีวิธีง่าย ๆ ในการทำเช่นนี้? ฉันอ่านสั้น ๆ เกี่ยวกับควอเทอร์เนี่ยน แต่ฉันอยากจะดูว่ามีวิธีแก้ปัญหาที่ง่ายกว่านี้หรือไม่หากการสร้างฉากของฉันค่อนข้างง่าย

4
จะป้องกันไม่ให้กล้อง FPS ที่ใช้ Quaternion ของฉันเอียงและทำให้ยุ่งเหยิงได้อย่างไร
ฉันกำลังใช้กล้องที่เหมือน FPS และใช้งาน quaternions แต่เมื่อใดก็ตามที่ฉันลองมองหาและจากนั้นไปด้านข้างมันจะเอียงและบางครั้งมันอาจกลับหัวกลับหาง ฉันจะแก้ไขสิ่งนี้ได้อย่างไร

8
วิธีการคำนวณตำแหน่ง / เครื่องหมายมุมของสี่เหลี่ยมหมุน / เอียง
ฉันมีองค์ประกอบสองอย่างคือจุด 2D และพื้นที่สี่เหลี่ยม จุดแทนจุดกึ่งกลางของพื้นที่นั้น ฉันรู้ถึงความกว้างและความสูงของพื้นที่นั้นด้วย และพื้นที่เอียง 40 °เทียบกับกริด ตอนนี้ฉันต้องการคำนวณตำแหน่งสัมบูรณ์ของแต่ละมุมของพื้นที่เอียงนั้นโดยใช้ข้อมูลนี้เท่านั้น เป็นไปได้ไหม

4
วิธีการหมุนบล็อกใน Tetris
ฉันมีตารางกระดานเกมที่มีความสูง 20 แถวและกว้าง 10 คอลัมน์โดยมีจุดกำเนิด (0,0) อยู่ที่มุมซ้ายบน ฉันมี tetrimino ในการเล่นซึ่งประกอบด้วยสี่ช่วงตึก ฉันมีตำแหน่ง x, y ของแต่ละบล็อกที่สัมพันธ์กับจุดกำเนิดมุมซ้ายบน ฉันยังมีตำแหน่งของเดือยจุดที่ฉันต้องการหมุนซึ่งสัมพันธ์กับต้นกำเนิดมุมซ้ายบน แต่ละบล็อกมีตำแหน่งจำนวนเต็มในตารางเกมบอร์ดและดังนั้นเดือยมีตำแหน่งเป็นเศษส่วนในระหว่างบล็อกเช่น (10.5,10.5) คำถามของฉันคือฉันสามารถใช้สูตรใดในการหมุนแต่ละบล็อกรอบเดือย ฉันได้ดูคำถามและคำตอบที่คล้ายกันอยู่แล้ว แต่ไม่พบคำตอบที่ฉันสามารถทำงานได้ ความช่วยเหลือจะได้รับการชื่นชมมาก
16 c++  rotation 

6
จะหมุนวัตถุรอบแกนโลกได้อย่างไร?
ฉันมี Vector3 ซึ่งมีมุมออยเลอร์สำหรับแต่ละแกน โดยปกติเมื่อฉันต้องการสร้างเมทริกซ์การหมุนฉันจะใช้ฟังก์ชันเช่น D3DXMatrixRotationX ผ่านมุมที่เกี่ยวข้องจากเวกเตอร์การหมุนของฉันด้านบนและคูณเมทริกซ์ (ZXY) เพื่อสร้างเมทริกซ์การหมุนโดยรวมซึ่งใช้ในการสร้างเมทริกซ์การแปลงวัตถุทั้งหมด อย่างไรก็ตามวิธีนี้จะสร้างชุดการหมุนในพื้นที่วัตถุ นั่นคือการส่งเวกเตอร์ (90, 0, 90) ไปยังวิธีการของฉันจะสร้างการหมุนในอวกาศโลกได้อย่างมีประสิทธิภาพ (90, 90, 0) มีวิธีใดที่จะทำให้แน่ใจว่าแต่ละองค์ประกอบของเวกเตอร์การหมุนของฉันส่งผลให้เกิดการหมุนรอบแกนโลกตามแนวแกนอวกาศที่เกี่ยวข้องหรือไม่? แก้ไข: นี่เป็นอนิเมชั่นของสิ่งที่กำลังเกิดขึ้น - ฉันต้องการวิธีหมุนรอบแกนสีน้ำเงินไม่ใช่สีแดง แก้ไข 2: เพียงเพื่อทราบว่าฉันไม่ได้มองหาวิธีการแก้ปัญหาที่เกี่ยวข้องกับมุมออยเลอร์ แต่เพียงวิธีที่ฉันสามารถเป็นตัวแทนการเปลี่ยนแปลงของการหมุนรอบหลายแกนทั่วโลก

2
ฉันจะหมุนรอบจุดโดยพลการในแบบ 3 มิติ (แทนที่จะเป็นจุดกำเนิด) ได้อย่างไร
ฉันมีบางรุ่นที่ฉันต้องการหมุนโดยใช้ quaternions ในลักษณะปกติยกเว้นการหมุนเกี่ยวกับจุดกำเนิดฉันต้องการให้ออฟเซ็ตเล็กน้อย ฉันรู้ว่าคุณไม่ได้พูดว่าในพื้นที่ 3 มิติที่คุณหมุนรอบจุด; คุณบอกว่าคุณหมุนรอบแกน ดังนั้นฉันจึงจินตนาการว่ามันหมุนไปรอบ ๆ เวกเตอร์ซึ่งหางอยู่ในตำแหน่งที่ไม่ได้มาจากแหล่งกำเนิด การแปลงเลียนแบบทั้งหมดในเครื่องมือเรนเดอร์ / ฟิสิกส์ของฉันถูกเก็บไว้โดยใช้ SQT (สเกล, quaternion, การแปลความคิดที่ยืมมาจากหนังสือGame Engine Architecture ) ดังนั้นฉันจึงสร้างเมทริกซ์แต่ละเฟรมจากส่วนประกอบเหล่านี้ ในระบบนี้การแปลจะถูกนำไปใช้จากนั้นปรับขนาดแล้วหมุน ในกรณีเฉพาะฉันต้องแปลวัตถุในอวกาศโลกหมุนและหมุนรอบจุดยอดที่ไม่ได้อยู่กึ่งกลางที่จุดกำเนิดของวัตถุ คำถาม:ด้วยข้อ จำกัด ของระบบปัจจุบันของฉันที่อธิบายไว้ข้างต้นฉันจะบรรลุการหมุนเวียนในท้องถิ่นโดยมีศูนย์กลางที่จุดใดจุดหนึ่งนอกเหนือจากจุดกำเนิดได้อย่างไร โหวตอัตโนมัติให้กับทุกคนที่สามารถอธิบายวิธีการทำเช่นนี้โดยใช้เมทริกซ์เท่านั้นเช่นกัน :)

2
ฉันจะทำให้ตัวละคร 2D ของฉันยืนอยู่บนความชันได้อย่างไร
ฉันมีตัวละครตัวนี้ใน Unity3D (โหมด 2D) ... ในความชันที่ดูเหมือนนี้ แต่ฉันต้องการให้ตัวละครยืนตามเส้นสีแดง .. เหมือนด้านล่าง ฉันจะสร้างมันใน Unity3d ได้อย่างไร ฉันได้ตั้งค่านี้แล้ว ฉันกำลังใช้ Addforce แบบง่ายสำหรับการเคลื่อนย้าย ... หากฉันลบข้อ จำกัด ตำแหน่ง z ส่งผลให้เกิดการเคลื่อนไหวแปลก ๆ เช่นการกลิ้งและอื่น ๆ .... ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม :)

3
หมุนวัตถุรอบแกนคงที่
ฉันพยายามให้ผู้ใช้แอปหมุนวัตถุ 3 มิติที่กึ่งกลางหน้าจอโดยลากนิ้วบนหน้าจอ การเคลื่อนไหวในแนวนอนบนหน้าจอหมายถึงการหมุนรอบแกน Y ที่คงที่และการเคลื่อนที่ในแนวตั้งหมายถึงการหมุนรอบแกน X ปัญหาที่ฉันมีคือถ้าฉันอนุญาตให้หมุนรอบหนึ่งแกนวัตถุจะหมุนได้ดี แต่ทันทีที่ฉันแนะนำการหมุนครั้งที่สองวัตถุจะไม่หมุนตามที่คาดไว้ นี่คือภาพของสิ่งที่เกิดขึ้น: แกนสีน้ำเงินแสดงถึงแกนคงที่ของฉัน รูปภาพหน้าจอที่มีแกนสีน้ำเงินคงที่นี้ นี่คือสิ่งที่ฉันต้องการให้วัตถุหมุนในความสัมพันธ์กับ สิ่งที่เกิดขึ้นคือสีแดง นี่คือสิ่งที่ฉันรู้: การหมุนรอบแรกรอบ Y (0, 1, 0) ทำให้โมเดลย้ายจากพื้นที่สีน้ำเงิน (เรียกพื้นที่นี้ A) ไปยังพื้นที่อื่น (เรียกพื้นที่นี้ B) พยายามหมุนอีกครั้งโดยใช้เวกเตอร์ (1, 0, 0) หมุนรอบแกน x ในอวกาศ B ไม่ได้อยู่ในอวกาศ A ซึ่งไม่ใช่สิ่งที่ฉันตั้งใจจะทำ นี่คือสิ่งที่ฉันพยายามให้ในสิ่งที่ฉัน (คิด) ฉันรู้ (ออกจาก coord W เพราะความกะทัดรัด): หมุนไปรอบ ๆ Y (0, 1, 0) …

2
ปัญหาล็อก gimbal ถูกแก้ไขได้อย่างไรโดยใช้การแปลงเมทริกซ์แบบสะสม
ฉันกำลังอ่านหนังสือ "การเรียนรู้การเขียนโปรแกรมกราฟิก 3D สมัยใหม่" โดย Jason L. McKesson ณ ตอนนี้ฉันถึงปัญหาล็อก gimbal และวิธีแก้ปัญหาโดยใช้ quaternions แต่ที่นี่ที่หน้า Quaternions ส่วนหนึ่งของปัญหาคือเรากำลังพยายามเก็บการปฐมนิเทศเป็นชุดของการหมุนแกนสะสม 3 ชุด การวางแนวคือการหมุนไม่ใช่การหมุน และทิศทางไม่แน่นอนชุดของการหมุน ดังนั้นเราต้องปฏิบัติต่อการวางแนวของเรือในฐานะการปฐมนิเทศตามปริมาณที่กำหนด ฉันเดาว่านี่เป็นจุดแรกที่ฉันเริ่มสับสนเพราะฉันไม่เห็นความแตกต่างอย่างมากระหว่างการหมุนและการหมุน ฉันยังไม่เข้าใจว่าทำไมการปฐมนิเทศจึงไม่สามารถแสดงเป็นชุดการหมุนได้ ... นอกจากนี้: ความคิดแรกเกี่ยวกับจุดประสงค์นี้คือเพื่อให้การปฐมนิเทศเป็นเมทริกซ์ เมื่อเวลานั้นมาถึงการปรับเปลี่ยนการปฐมนิเทศเราเพียงแค่นำการแปลงไปใช้กับเมทริกซ์นี้โดยจัดเก็บผลลัพธ์เป็นทิศทางปัจจุบันใหม่ ซึ่งหมายความว่าทุก ๆ yaw pitch และ roll ที่ใช้กับการวางแนวปัจจุบันจะสัมพันธ์กับการวางแนวปัจจุบันนั้น ซึ่งเป็นสิ่งที่เราต้องการอย่างแม่นยำ หากผู้ใช้ใช้การหันเหที่เป็นบวกคุณต้องการให้หันเหที่จะหมุนพวกเขาเมื่อเทียบกับที่พวกเขากำลังชี้ปัจจุบันไม่ได้เกี่ยวข้องกับระบบพิกัดคงที่บางส่วน แนวคิดฉันเข้าใจ แต่ฉันไม่เข้าใจว่าการสะสมการแปลงเมทริกซ์เป็นวิธีแก้ปัญหานี้ได้อย่างไรรหัสที่ให้ในหน้าก่อนหน้านั้นไม่ใช่แค่นั้น นี่คือรหัส: void display() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); …

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