( CAVEAT: Burada iki yaklaşım kullanıyorum: birincisi d'yi bir yay uzunluğu olarak, ikincisi bunu dikey bir uzunluk olarak alır. Bu yaklaşımların her ikisi de nispeten küçük d değerleri için iyi olmalıdır, ancak yerine getirmezler yorumlarda açıklandığı gibi kesin soru.)
Bununla ilgili matematik, neyse ki, nispeten basittir. Her şeyden önce, merkez konumumuzdan mevcut konumumuza göreli vektörü bulabiliriz:
deltaX = oX-cX;
deltaY = oY-cY;
Ve bu göreli vektöre sahip olduktan sonra, üzerinde çalıştığımız dairenin yarıçapını, uzunluğunu bularak öğrenebiliriz:
radius = sqrt(deltaX*deltaX+deltaY*deltaY);
Dahası, göreceli vektörümüzden cX'ten oX'a kadar olan çizginin tam açısını bulabiliriz:
curTheta = atan2(deltaX, deltaY);
Şimdi işler biraz daha zorlaşıyor. Her şeyden önce, bir dairenin çevresinin - yani 2π açısal ölçüsü olan bir yayın 'ark uzunluğunun' 2πr olduğunu anlayın. Genel olarak, r yarıçapı dairesi boyunca θ açısal ölçüsü olan bir yayın yay uzunluğu sadece justr'dir. Diyagramınızdaki d'yi yay uzunluğu olarak kullanacak olsaydık ve yarıçapı bildiğimizden, bizi bölerek yeni konuma götürmek için tetadaki değişikliği bulabiliriz:
deltaTheta = d/radius; // treats d as a distance along the arc
D'nin doğrusal bir mesafe olması gerektiği durumda, işler biraz daha karmaşıktır, ama neyse ki fazla değildir. Burada d, diğer iki tarafı dairenin yarıçapı olan (sırasıyla cX / cY'den oX / oY ve aX / aY'ye) olan bir izoceles üçgeninin bir tarafıdır ve bu izoceles üçgeninin ikiye bölünmesi, her biri iki sağ üçgen verir. bir tarafı olarak d / 2 ve hipotenüs olarak yarıçapı vardır; bu, açımızın yarısının sinüsünün (d / 2) / yarıçap olduğu anlamına gelir ve bu nedenle tam açı bunun sadece iki katıdır:
deltaTheta = 2*asin(d/(2*radius)); // treats d as a linear distance
Eğer asini bu formülden çıkarır ve 2'leri iptal ederseniz, bu son formülle nasıl olur; bu sin (x) 'in küçük x değerleri için yaklaşık x olduğunu söylemekle aynıdır, ki bu da yararlı bir yaklaşımdır.
Şimdi yeni açıyı sadece ekleyerek veya çıkararak bulabiliriz:
newTheta = curTheta+deltaTheta; // This will take you to aX, aY. For bX/bY, use curTheta-deltaTheta
Yeni açıya sahip olduktan sonra, güncellenmiş göreli vektörümüzü bulmak için bazı temel trigileri kullanabiliriz:
newDeltaX = radius*cos(newTheta);
newDeltaY = radius*sin(newTheta);
ve merkez konumumuzdan ve bağıl vektörünüzden (sonunda) hedef noktayı bulabiliriz:
aX = cX+newDeltaX;
aY = cY+newDeltaY;
Şimdi, tüm bunlarla birlikte, farkında olmak için bazı büyük uyarılar var . Birincisi, bu matematiğin çoğunlukla kayan nokta olduğunu ve aslında neredeyse olması gerektiğini fark edeceksiniz; bir döngüde güncellemek ve her adımda tamsayı değerlere geri dönmek için bu yöntemi kullanmaya çalışmak, çemberinizi yakınlaştırmamaktan (döngüde her gittiğinizde içe veya dışa doğru sarılmaktan) ilk başlamamaya kadar her şeyi yapabilir yer! (D'niz çok küçükse, o zaman aX / aY veya bX / bY'nin yuvarlatılmış sürümlerinin tam olarak oX / oY başlangıç konumunuz olduğunu keşfedebilirsiniz.) Bir diğeri için, bu özellikle pahalıya çalıştığı şey için çok pahalı yapmak; Eğer karakter bir çember yayı hareketli olacak biliyorsanız genel olarak, tüm yay önceden ve dışarı planlamalısınız değilburadaki en pahalı hesaplamaların birçoğu maliyetleri azaltmak için önden yüklenebileceğinden, çerçeveden çerçeveye böyle işaretleyin. Maliyetleri azaltmanın başka bir iyi yolu, eğer gerçekten bu şekilde artımlı olarak güncellemek istiyorsanız, ilk etapta trig kullanmamaktır; d küçükse ve tam ancak çok yakın olmasına ihtiyacınız yoksa, oX / oY'ye d uzunluğunda bir vektör ekleyerek merkezinize doğru dik bir 'hile' yapabilirsiniz (a. (dX, dY) ile dik vektör (-dY, dX) ile verilir ve sonra doğru uzunluğa küçültülür. Bu kodu adım adım açıklamayacağım, ancak umarım şimdiye kadar gördükleriniz göz önüne alındığında mantıklı olacaktır. Son adımda yeni delta vektörünü örtük olarak 'küçülttüğümüzü',
deltaX = oX-cX; deltaY = oY-cY;
radius = sqrt(deltaX*deltaX+deltaY*deltaY);
orthoX = -deltaY*d/radius;
orthoY = deltaX*d/radius;
newDeltaX = deltaX+orthoX; newDeltaY = deltaY+orthoY;
newLength = sqrt(newDeltaX*newDeltaX+newDeltaY*newDeltaY);
aX = cX+newDeltaX*radius/newLength; aY = cY+newDeltaY*radius/newLength;
d
bir doğrusal uzaklık veya bir ark?