void DrawWorldline() { double maxT = 10; /* * for (double properTime = 0; properTime < 20.0; properTime += dT) { * Matrix5d objectToCoordinateBoost = new Matrix5d(LorentzBoost(InitialVelocity), new Vector4d(0.0, -new Vector3d(transform.position))).Inverse(); * double calculatedTime = 0.0; * for (int i=0; i<ProperAccelerations.Count; i++) { * Vector3d A = ProperAccelerations[i]; * double T = AccelerationDurations[i]; * bool lastAccel = false; * if (properTime - calculatedTime <= AccelerationDurations[i]) { * T = properTime - calculatedTime; * lastAccel = true; * } * double aSqr = A.SqrMagnitude(); * double a = A.Magnitude(); * double t = Math.Sinh(T * a) / a; * Vector3d velocity = A * t / Math.Sqrt(1 + t * t * aSqr); * Vector3d displacement = A * (Math.Sqrt(1 + t * t * aSqr) - 1) / aSqr; * Matrix5d M = new Matrix5d(LorentzBoost(velocity), new Vector4d(-t, displacement)); * Matrix5d MInv = M.Inverse(); * objectToCoordinateBoost *= MInv; * calculatedTime += T; * if (lastAccel) break; * } * Vector4d localObjectEvent = new Vector4d(properTime - calculatedTime, new Vector3d()); * * Matrix5d coordinateToObserverStartBoost = new Matrix5d(LorentzBoost(-new Vector3d(observerScript.velocity)), new Vector4d(0, new Vector3d(Observer.transform.position))).Inverse(); * Matrix5d objectToObserverBoost = coordinateToObserverStartBoost * objectToCoordinateBoost; * Vector4d currentObjectEvent = objectToObserverBoost * localObjectEvent; * if (currentObjectEvent.t > 0) { * for (int i = 0; i < observerScript.accelerations.Count; i++) { * Vector3d A = new Vector3d(observerScript.accelerations[i]); * Vector3d X = currentObjectEvent.Space(); * double t = currentObjectEvent.t; * double aSqr = A.SqrMagnitude(); * double a = Math.Sqrt(aSqr); * double t2 = 0; * if (A*A < Math.Pow(1 + A*X, 2)/(t*t)) { * if (t != 0) { * t2 = Math.Abs(t) / Math.Sqrt(-t * t * aSqr + Math.Pow(1 + A * X, 2)); * if ((A * X > -1 && t < 0) || (A * X < -1 && t > 0)) { * t2 = -t2; * } * } * Vector3d velocity = A * t2 / Math.Sqrt(1 + t2 * t2 * aSqr); * Vector3d displacement = A * (Math.Sqrt(1 + t2 * t2 * aSqr) - 1) / aSqr; * double T = ASinh(t2 * a) / a; * Matrix5d M = new Matrix5d(LorentzBoost(velocity), new Vector4d(-t2+T, displacement)); * //Matrix5d MInv = M.Inverse(); * objectToObserverBoost = M * objectToObserverBoost; * } else { * // Rindler Horizon * // Debug.Log("Horizon " + A.x + " " + A.y + " " + A.z + " | " + X.x + " " + X.y + " " + X.z + " | " + t); * } * } * } * currentObjectEvent = objectToObserverBoost * localObjectEvent; * Vector3d drawInObserverFrame = currentObjectEvent.Space(); * drawInObserverFrame.z += currentObjectEvent.t; * Debug.DrawRay(drawInObserverFrame.Vector3(), Vector3.up, Color.green); * } */ bool first = true; Matrix5d initialBoost = new Matrix5d(LorentzBoost(InitialVelocity), new Vector4d(0, new Vector3d(-transform.position))) * new Matrix5d(LorentzBoost(new Vector3d(observerScript.velocity)), new Vector4d(0, new Vector3d(-Observer.transform.position))).Inverse(); Vector4d back = initialBoost.Inverse().MultiplyDirection(new Vector4d { t = -1 }); Vector4d center = initialBoost * new Vector4d(); Debug.DrawRay(center.Draw(), back.Draw() * 1000); for (double observerTime = 0; observerTime < maxT; observerTime += deltaT) { Vector3d observerVelocity = new Vector3d(observerScript.velocity); Matrix5d observerToCoordinateBoost = new Matrix5d(LorentzBoost(observerVelocity), new Vector4d(0, new Vector3d(-Observer.transform.position))).Inverse(); Vector4d localObserver = new Vector4d { t = observerTime }; Vector4d coordObserver = observerToCoordinateBoost * localObserver; //Debug.DrawRay(coordObserverDraw.Vector3(), Vector3.up, Color.cyan); double calculatedTime = 0; Vector4d prevTr = new Vector4d(); int i = 0; double a = 1.0; double prevT = 0; for (; i < observerScript.accelerations.Count; i++) { Vector3d A = new Vector3d(observerScript.accelerations[i]); double T = observerScript.durations[i]; bool lastAccel = false; calculatedTime += prevT; if (observerTime < calculatedTime + T) { T = observerTime - calculatedTime; lastAccel = true; } double aSqr = A.SqrMagnitude(); a = A.Magnitude(); double t = Math.Sinh(T * a) / a; Vector3d velocity = A * t / Math.Sqrt(1 + t * t * aSqr); Vector3d displacement = A * (Math.Sqrt(1 + t * t * aSqr) - 1) / aSqr; //Vector4d newTr = new Vector4d(, new Vector3d()); //Matrix5d Tr = new Matrix5d(Matrix4d.Identity(), prevTr); Matrix5d M = new Matrix5d(LorentzBoost(velocity), new Vector4d(-t + T, displacement)); observerToCoordinateBoost *= new Matrix5d(Matrix4d.Identity(), prevTr) * M.Inverse() * new Matrix5d(Matrix4d.Identity(), new Vector4d(-calculatedTime, new Vector3d())); prevTr = new Vector4d(T + prevT, new Vector3d()); //observerToCoordinateBoost *= MInv * Tr;// * observerToCoordinateBoost; //Debug.Log(simulPlane2.Normal.Space() * displacement + simulPlane2.Normal.t * t - simulPlane2.Distance); //observerToCoordinateBoost *= new Matrix5d(Matrix4d.Identity(), new Vector4d(-prevObserverTime, new Vector3d { x = observerTime })); localObserver = new Vector4d { t = observerTime }; prevT = T; if (lastAccel) { break; } } //localObserverEvent = new Vector4d(observerTime - calculatedTime, new Vector3d()); Matrix5d coordinateToObjectBoost = new Matrix5d(LorentzBoost(InitialVelocity), new Vector4d(0, new Vector3d(-transform.position))); Matrix5d observerToObjectBoost = coordinateToObjectBoost * observerToCoordinateBoost; /* * Vector4d right = observerToObjectBoost.MultiplyDirection(new Vector4d { x = 1 }); * Vector4d up = observerToObjectBoost.MultiplyDirection(new Vector4d { y = 1 }); * Vector4d forward = observerToObjectBoost.MultiplyDirection(new Vector4d { t = 1 }); */ Plane simulPlane = observerToObjectBoost.InvTransposePlaneMultiplication(new Plane { Distance = observerTime }); double simulPlaneT = simulPlane.Normal.t; Vector4d localObject = new Vector4d { t = simulPlane.Distance / simulPlaneT }; calculatedTime = 0; Matrix5d prevBoost = new Matrix5d(); Vector3 offset = Vector3.zero; for (i = 0; i < ProperAccelerations.Count; i++) { Vector3d A = ProperAccelerations[i]; Vector4d N = simulPlane.Normal.Normalized(); Vector3d nX = N.Space(); double nXSqr = nX.SqrMagnitude(); double nT = N.t; double nT2 = nT * nT; double d = simulPlane.Distance; double d2 = d * d; double aSqr = A.SqrMagnitude(); double AnX = A * nX; double AnX2 = AnX * AnX; double t2; //Find intersection time t2 between simulPlane and worldline of particle under proper acceleration A: if (d == 0 && nT == 0 && AnX != 0 && nXSqr >= 0 && aSqr > 0) { t2 = 0; } else if (AnX == 0 && d >= 0 && nT != 0 && nXSqr >= 0 && aSqr > 0) { t2 = d / nT; } else if (aSqr == AnX2 / nT2 && nXSqr >= 0 && nT != 0 && ((d >= 0 && ((nT2 + 2 * d * AnX >= 0 && AnX < 0) || AnX > 0)) || (nT2 + d * AnX > 0 && AnX < 0 && nT2 + 2 * d * AnX < 0))) { t2 = 1 / (nT * (1 / d + 1 / (d + (2 * AnX) / aSqr))); } else if (nXSqr >= 0 && AnX > 0 && nT == 0 && d > 0 && aSqr > 0) { t2 = -(Math.Sqrt(d * (d * aSqr + 2 * AnX)) / AnX); } else if (nXSqr >= 0 && AnX > 0 && nT == 0 && d > 0 && aSqr > 0) { t2 = Math.Sqrt((d * (d * aSqr + 2 * AnX)) / AnX2); } else if (nXSqr >= 0 && ((AnX < 0 && ((nT2 + 2 * d * AnX < 0 && ((nT2 + d * AnX > 0 && nT != 0 && (nT2 + d2 * aSqr + 2 * d * AnX == 0 || (nT2 + d2 * aSqr + 2 * d * AnX > 0 && nT2 * aSqr < AnX2))) || (nT2 * aSqr > AnX2 && nT < 0))) || (d >= 0 && ((nT < 0 && ((aSqr > 0 && nT2 + 2 * d * AnX >= 0 && nT2 * aSqr < AnX2) || nT2 * aSqr > AnX2)) || (nT > 0 && aSqr > 0 && nT2 + 2 * d * AnX >= 0 && nT2 * aSqr < AnX2))) || (nT < 0 && nT2 + d * AnX <= 0 && nT2 * aSqr > AnX2))) || (d >= 0 && AnX > 0 && ((nT != 0 && aSqr > 0 && nT2 * aSqr < AnX2) || (nT > 0 && nT2 * aSqr > AnX2))))) { t2 = -((Math.Abs(AnX) * Math.Sqrt(nT2 + d2 * aSqr + 2 * d * AnX)) / Math.Abs((-nT2) * aSqr + AnX2)) + (nT * (d * aSqr + AnX)) / (nT2 * aSqr - AnX2); } else if (nXSqr >= 0 && ((nT != 0 && nT2 * aSqr < AnX2 && ((aSqr > 0 && d >= 0 && ((nT2 + 2 * d * AnX >= 0 && AnX < 0) || AnX > 0)) || (AnX < 0 && nT2 + 2 * d * AnX < 0 && nT2 + d * AnX > 0 && nT2 + d2 * aSqr + 2 * d * AnX > 0))) || (nT2 * aSqr > AnX2 && ((d >= 0 && ((nT < 0 && AnX > 0) || (nT > 0 && AnX < 0))) || (nT > 0 && AnX < 0 && (nT2 + 2 * d * AnX < 0 || nT2 + d * AnX <= 0)))))) { t2 = (Math.Abs(AnX) * Math.Sqrt(nT2 + d2 * aSqr + 2 * d * AnX)) / Math.Abs((-nT2) * aSqr + AnX2) + (nT * (d * aSqr + AnX)) / (nT2 * aSqr - AnX2); } else { break; } double accel = Math.Sqrt(aSqr); double properTime = ASinh(t2 * accel) / accel; if (properTime < 0) { break; } bool lastAccel = properTime <= AccelerationDurations[i]; properTime = Math.Min(properTime, AccelerationDurations[i]); t2 = Math.Sinh(properTime * accel) / accel; Vector3d velocity = A * t2 / Math.Sqrt(1 + t2 * t2 * aSqr); Vector3d displacement = A * (Math.Sqrt(1 + t2 * t2 * aSqr) - 1) / aSqr; localObject = new Vector4d(t2, displacement); //Matrix5d M = new Matrix5d(LorentzBoost(velocity), new Vector4d(-t2 + properTime, displacement)); observerToObjectBoost = prevBoost * observerToObjectBoost; simulPlane = observerToObjectBoost.InvTransposePlaneMultiplication(new Plane { Distance = observerTime }); //prevBoost = new Matrix5d(LorentzBoost(velocity), new Vector4d(-t2, -displacement)); prevBoost = new Matrix5d(LorentzBoost(velocity), new Vector4d(-t2, displacement)); // -t2, -displacement)); calculatedTime += properTime; if (lastAccel) { break; } simulPlane = prevBoost.InvTransposePlaneMultiplication(simulPlane); offset += Vector3.up * 2; } //Debug.DrawRay(Vector3.zero, simulPlane.Normal.Draw().normalized * (float)simulPlane.Distance); Vector4d objObserver = observerToObjectBoost * localObserver; //Debug.DrawRay(objObserver.Draw(), Vector3.up, Color.HSVToRGB((float)(observerTime / maxT + 0 / 3.0) % 1f, 1, 1)); Vector4d right = observerToObjectBoost.Inverse().MultiplyDirection(new Vector4d { x = 1 }); Vector4d up = observerToObjectBoost.Inverse().MultiplyDirection(new Vector4d { y = 1 }); Vector4d forward = observerToObjectBoost.Inverse().MultiplyDirection(new Vector4d { t = 1 }); Vector4d origin = observerToObjectBoost * localObserver; /* * Debug.DrawRay(offset + origin.Draw(), right.Draw() / (float)a, Color.red); * Debug.DrawRay(offset + origin.Draw(), up.Draw() * (float)deltaT, Color.green); * Debug.DrawRay(offset + origin.Draw(), forward.Draw() * (float)deltaT, Color.blue); * Debug.DrawRay(offset + origin.Draw(), -right.Draw()/ (float)a, Color.red); * Debug.DrawRay(offset + origin.Draw(), -up.Draw() * (float)deltaT, Color.green); * Debug.DrawRay(offset + origin.Draw(), -forward.Draw() * (float)deltaT, Color.blue); */ //Debug.DrawRay(offset + localObject.Draw(), Vector3.up*0.3f, Color.HSVToRGB((float)(observerTime / maxT + i / 3.0) % 1f, 1, 1)); Vector4d objInObserverFrame = observerToObjectBoost.Inverse() * localObject; Debug.DrawRay(objInObserverFrame.Draw(), Vector3.up * 2, Color.HSVToRGB((float)(observerTime / maxT + i / 3.0) % 1f, 1, 1)); } }
Vector4d GetState(double observerTime) { Vector4d localObserverEvent = new Vector4d(); Vector3d observerVelocity = new Vector3d(observerScript.velocity); Matrix5d observerToCoordinateBoost = new Matrix5d(LorentzBoost(observerVelocity), new Vector4d(0, -new Vector3d(Observer.transform.position))).Inverse(); double calculatedTime = 0; if (observerTime > 0) { for (int i = 0; i < observerScript.accelerations.Count; i++) { Vector3d A = new Vector3d(observerScript.accelerations[i]); double T = observerScript.durations[i]; bool lastAccel = false; if (observerTime < localObserverEvent.t + T) { T = observerTime - localObserverEvent.t; lastAccel = true; } localObserverEvent = new Vector4d(T, new Vector3d()); double aSqr = A.SqrMagnitude(); double a = A.Magnitude(); double t = Math.Sinh(T * a) / a; Vector3d velocity = A * t / Math.Sqrt(1 + t * t * aSqr); Vector3d displacement = A * (Math.Sqrt(1 + t * t * aSqr) - 1) / aSqr; Matrix5d M = new Matrix5d(LorentzBoost(velocity), new Vector4d(-t, displacement)); Matrix5d MInv = M.Inverse(); observerToCoordinateBoost *= MInv; calculatedTime += T; if (lastAccel) { break; } } } localObserverEvent = new Vector4d(observerTime - calculatedTime, new Vector3d()); Matrix5d coordinateToObjectStartBoost = new Matrix5d(LorentzBoost(InitialVelocity), new Vector4d(0, -new Vector3d(transform.position))); Matrix5d observerToObjectStartBoost = coordinateToObjectStartBoost * observerToCoordinateBoost; Plane simulPlane = new Plane { Distance = observerTime - calculatedTime }; Vector4d coordinateObserverEvent = observerToObjectStartBoost * localObserverEvent; Vector3d coe = coordinateObserverEvent.Space(); coe.z += coordinateObserverEvent.t; Debug.DrawRay(coe.Vector3(), Vector3.up, Color.white); simulPlane = observerToObjectStartBoost.InvTransposePlaneMultiplication(simulPlane); Vector4d normal4 = simulPlane.Normal.Normalized(); Vector3d normal3 = normal4.Space(); normal3.z += normal4.t; /* * plane.transform.position = coe.Vector3(); * * plane.transform.LookAt(coe.Vector3() - normal3.Vector3(), Vector3.up); * plane.transform.Rotate(90f, 0, 0, Space.Self); */ double d = simulPlane.Distance / normal4.t; Debug.DrawRay(new Vector3(0, 0, (float)d), Vector3.up, Color.red); Vector4d eventInObjectFrame = new Vector4d(d, new Vector3d()); Vector4d eventInObserverFrame = observerToObjectStartBoost.Inverse() * eventInObjectFrame; Vector3d drawInObserverFrame = eventInObserverFrame.Space(); drawInObserverFrame.z += eventInObserverFrame.t + calculatedTime; sphere.transform.position = drawInObserverFrame.Vector3(); Debug.DrawRay(drawInObserverFrame.Vector3(), Vector3.up, Color.white, 10); /* * double di = 10; * for (double i = -10; i < 10; i += di) { * Vector4d e1 = observerToObjectStartBoost * new Vector4d(i + observerTime - calculatedTime, new Vector3d()); * Vector4d e2 = observerToObjectStartBoost * new Vector4d(i + di + observerTime - calculatedTime, new Vector3d()); * Vector3d v1 = e1.Space(); * v1.z += e1.t; * Vector3d v2 = e2.Space(); * v2.z += e2.t; * Debug.DrawLine(v1.Vector3(), v2.Vector3()); * } */ return(new Vector4d()); }