Dlaczego nie podejdziesz do tego domenowo? Tworzysz kulki, i potem dodajesz metody, dzięki którym obracasz ją wokół wspólnych punktów.
Na początek powtórka z matmy:
Ze wzorów:
x = r * sin(alfa);
y = r * cos(alfa);
gdzie:
x,y - współrzędne w kartezjańskich
r - promień okręgu
alfa - kąt
czyli:
x1 = r1 * sin(alfa);
y1 = r1 * cos(alfa);
x2 = r2 * sin(alfa);
y2 = r2 * cos(alfa);
przechodząc na przyrosty
dx1 = r1 * d(sin(d(alfa)));
dy1 = r1 * d(cos(d(alfa)));
...
gdzie:
d(sin) - zmiana sinus
d(alfa) - zmiana kąta alfa
dodatkowo trzeba uwzględnić translację
dx1 + v = r1 * d(sin(d(alfa))) + v;
dy1 + v = r1 * d(cos(d(alfa))) + v;
v - wektor przesunięcia środka
przechodząc na przyrosty wektora
dx1 + dvx = r1 * d(sin(d(alfa))) + dvx
analogicznie dla dy1
Teraz przechodzimy na Javę:
public class CirclingSphere {
private double currentX;
private double currentY;
private int currentDegreeNumber;
private double radius;
public CirclingSphere(double radius){
this.radius = radius;
this.currentX = 0;
this.currentY = radius;
this.currentDegreeNumber = 0;
}
public void rotate(int angleInDegrees){
double newRadians = toRadian(currentDegreeNumber + angleInDegrees);
double currentRadians = toRadian(currentDegreeNumber);
this.currentX = this.currentX + (radius * getSinusDifference(currentRadians, newRadians));
this.currentY = this.currentY + (radius * getCosinusDifferential(currentRadians, newRadians));
this.currentDegreeNumber = this.currentDegreeNumber + angleInDegrees;
}
public void translate(double x, double y){
this.currentX = this.currentX + x;
this.currentY = this.currentY + y;
}
public double getX(){
return this.currentX;
}
public double getY(){
return this.currentY;
}
private double getSinusDifference(double currentRadians, double newRadians){
return Math.sin(newRadians) - Math.sin(currentRadians);
}
private double getCosinusDifferential(double currentRadians, double newRadians){
return Math.cos(newRadians) - Math.cos(currentRadians);
}
private double toRadian(int numberOfDegrees){
return (Math.PI * numberOfDegrees)/180.0;
}
}
Czas na testy:
public class Main {
public static void main(String[] args){
CirclingSphere first = new CirclingSphere(1);
CirclingSphere second = new CirclingSphere(1.25);
Consumer<Consumer<CirclingSphere>> bothConsumer = circlingSphereConsumer -> {
circlingSphereConsumer.accept(first);
circlingSphereConsumer.accept(second);
System.out.println("First:" + asString(first));
System.out.println("Second:" + asString(second));
};
bothConsumer.accept((cs -> cs.translate(0.1, -0.2))); // przesuwamy do punktu 0.1;-0.2
for(int i=0; i<12; i++){
bothConsumer.accept(cs -> cs.rotate(30)); // obracamy o 30 stopni w kazdym kroku
}
}
private static String asString(CirclingSphere circlingSphere){
return rounded(circlingSphere.getX())+ ";" + rounded(circlingSphere.getY());
}
private static double rounded(double d){
return Math.round(d * 100)/100.0;
}
}