คุณต้องการมุมของลูกศร ณ จุดใดก็ได้ คุณจำได้ว่าในการคำนวณมุมมันมีแทนเจนต์ แต่นี่คือสิ่งที่ความคิดของคุณเริ่มผิดไป:
- สิ่งที่คุณต้องการคือเดลต้า y / เดลต้า x เนื่องจากความชันคืออัตราการเปลี่ยนแปลง (กล่าวถึงในคำตอบอื่น) โปรดทราบว่า x เป็นเพียงตำแหน่งที่คุณอยู่ในเวลาใดก็ได้ไม่ใช่ dx
ตกลงดังนั้นถ้าคุณละเลยความเสียดทานในอากาศแล้วความเร็ว x ของลูกศรจะคงที่
ขั้นแรกให้แยกความเร็วออกเป็นองค์ประกอบ x และ y คุณสามารถถ่ายทำมุม 45 องศาหรือ 60 องศา ดังนั้นคุณต้องเปิดตัวความเร็วและมุมไม่ใช่สเกลาร์
ประการที่สองคำนวณทุกอย่างเป็นสองเท่าไม่ใช่ลอย คุณมีความซับซ้อนเชิงตัวเลขไม่เพียงพอที่จะรู้ว่าเมื่อข้อผิดพลาดของ roundoff จะไม่ฆ่าคุณดังนั้นอย่าพยายาม มันไม่ได้เป็นการประหยัดเวลาที่ดีในทุกกรณี
ประการที่สามอย่าใช้ Math.pow มันช้าและไม่แม่นยำเท่าการคูณสำหรับจำนวนเต็ม นอกจากนี้คุณสามารถประหยัดเวลาได้มากโดยใช้แบบฟอร์มของ Horner (ดูด้านล่าง)
final double DEG2RAD = Math.PI/180;
double ang = launchAngle * DEG2RAD;
double v0x = launchVelocity * cos(ang); // initial velocity in x
double v0y = launchVelocity * sin(ang); // initial velocity in y
double x = (v0x * time);
// double y = (v0y * time) + (0.5 * g * (float)Math.Pow(time, 2));
double y = (0.5 * g * time + v0y) * time
หากคุณต้องการประสิทธิภาพคุณสามารถ precompute 0.5 * g แต่โค้ดข้างต้นจะนำคุณไป 90% จากที่นั่นโดยไม่ต้องทำอะไรบ้าไป เกณฑ์มาตรฐานที่ทำเช่นนี้ 10 ล้านครั้งถ้าคุณชอบมันเป็นที่ยอมรับไม่มากนัก แต่เปอร์เซ็นต์ที่ฉลาดก็ค่อนข้างใหญ่ - ห้องสมุดช้ามากใน Java
ดังนั้นหากคุณต้องการมุมที่ลูกศรควรไปสิ่งที่คุณต้องการคือ
atan(dy/dx)
และในกรณีนี้นั่นจะใช้ได้เพราะ dx เป็นค่าคงที่ แต่โดยทั่วไป dx อาจเป็นศูนย์ดังนั้นคุณมักจะต้องการใช้:
atan2(dy, dx)
ซึ่งเป็นฟังก์ชันที่ออกแบบมาสำหรับงานนี้โดยเฉพาะ
แต่อย่างที่ฉันบอกว่าฟังก์ชั่นห้องสมุดใน Java นั้นช้ามากและในกรณีนี้มีวิธีที่ดีกว่าในการทำโดยไม่ต้องพูดถึง @FxIII ด้านบน
หากความเร็วแนวนอนเป็น v0x เสมอและความเร็วแนวตั้งคือ:
double vy = v0y - 0.5 * g * time;
ดังนั้นเดลต้าของคุณคือ: vx, vy
คุณไม่ต้องการมุม หากคุณต้องการวาดลูกศรให้ใช้สิ่งที่มีชื่อเช่น:
พล็อต (x, y, x + vx, y + vy);
ฉันไม่รู้ว่าคุณกำลังวาดอะไรดังนั้นถ้าคุณต้องการมุมเพื่อหมุนมัน (เช่นคุณกำลังใช้ JOGL) แน่นอนว่าใช้มุมนี้
อย่าลืมว่าคุณกำลังใช้ OpenGL เพื่อเปลี่ยนมุมกลับเป็นองศาเพราะ ATAN2 ส่งคืนเรเดียน:
final double RAD2DEG = 180 / Math.PI;
double ang = Math.atan2(vy,vx); // don't forget, vy first!!!
double deg = ang * RAD2DEG;