diff --git a/danmaku2ass.py b/danmaku2ass.py index 9ac3b20..61e2593 100755 --- a/danmaku2ass.py +++ b/danmaku2ass.py @@ -511,6 +511,8 @@ def ConvertFlashRotation(rotY, rotZ, X, Y, FOV=math.tan(2*math.pi/9.0)): return 180-((180+deg)%360) def CalcPerspectiveCorrection(alpha, X, FOV=FOV): alpha = WrapAngle(alpha) + if FOV is None: + return alpha if 0 <= alpha <= 180: costheta = (FOV*math.cos(alpha*math.pi/180.0)-X*math.sin(alpha*math.pi/180.0))/(FOV+max(2, abs(X)+1)*math.sin(alpha*math.pi/180.0)) try: @@ -548,8 +550,8 @@ def ConvertFlashRotation(rotY, rotZ, X, Y, FOV=math.tan(2*math.pi/9.0)): outY = math.atan2(-math.sin(rotY)*math.cos(rotZ), math.cos(rotY))*180/math.pi outZ = math.atan2(-math.cos(rotY)*math.sin(rotZ), math.cos(rotZ))*180/math.pi #outX = math.asin(math.sin(rotY)*math.sin(rotZ))*180/math.pi - #outX = math.acos(math.cos(rotY)/math.cos(outY*math.pi/180.0))*180/math.pi - outX = math.atan2(-math.sin(rotY)*math.cos(rotZ)*abs(math.cos(outY*math.pi/180.0)*(1 if math.sin(outY*math.pi/180.0) >= 0 else -1)), math.cos(rotY)*abs(math.sin(outY*math.pi/180.0)*(1 if math.cos(outY*math.pi/180.0) >= 0 else -1)))*180/math.pi + outX = math.acos(math.cos(rotY)/math.cos(outY*math.pi/180.0))*180/math.pi + #outX = math.atan2(-math.sin(rotY)*math.cos(rotZ)*abs(math.cos(outY*math.pi/180.0)*(1 if math.sin(outY*math.pi/180.0) >= 0 else -1)), math.cos(rotY)*abs(math.sin(outY*math.pi/180.0)*(1 if math.cos(outY*math.pi/180.0) >= 0 else -1)))*180/math.pi ''' print( (rotY*180.0/math.pi, rotZ*180.0/math.pi), @@ -560,8 +562,9 @@ def ConvertFlashRotation(rotY, rotZ, X, Y, FOV=math.tan(2*math.pi/9.0)): ) ) ''' - outX = CalcPerspectiveCorrection(outX, -Y, FOV*0.75) - outY = CalcPerspectiveCorrection(outY, X, FOV) + if FOV is not None: + outX = CalcPerspectiveCorrection(outX, -Y, FOV*0.75) + outY = CalcPerspectiveCorrection(outY, X, FOV) return (WrapAngle(round(outX)), WrapAngle(round(outY)), WrapAngle(round(outZ)), 0, round(-0.75*Y*math.sin(outY*math.pi/180.0), 3)) diff --git a/test/test-3drot.py b/test/test-3drot.py new file mode 100755 index 0000000..29009b1 --- /dev/null +++ b/test/test-3drot.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 + +import logging +import math +import sys + +try: + import importlib.machinery + danmaku2ass = importlib.machinery.SourceFileLoader('danmaku2ass', '../danmaku2ass.py').load_module('danmaku2ass') +except (AttributeError, ImportError): + import imp + danmaku2ass = imp.load_source('danmaku2ass', '../danmaku2ass..py') + +extcode = 0 + +def main(): + logging.basicConfig(level=logging.INFO) + for rotY in range(0, 361): + for rotZ in range(0, 361): + outX, outY, outZ, shearX, shearY = danmaku2ass.ConvertFlashRotation(rotY, rotZ, X=0, Y=0, FOV=None) + logging.info('%4d, %4d => %4d, %4d, %4d' % (rotY, rotZ, outX, outY, outZ)) + CompareMatrix(rotY, rotZ, outX, outY, outZ) + +def CompareMatrix(rotY, rotZ, outX, outY, outZ): + def ApproxEqual(a, b, e=0.01): + assert e >= 0 + a_b = a-b + if -e < a_b < e: + return 0 + else: + return a_b + def FormatError(i, j, l, r): + global extcode + if ApproxEqual(l, r) != 0: + extcode = 1 + logging.error('l[%s][%s]=%9.6f r[%s][%s]=%9.6f' % (i, j, l, i, j, r)) + def sind(x): + return math.sin(x*math.pi/180.0) + def cosd(x): + return math.cos(x*math.pi/180.0) + + l = cosd(rotY)*cosd(rotZ) + r = -sind(outX)*sind(outY)*sind(outZ)+cosd(outY)*cosd(outZ) + FormatError(0, 0, l, r) + l = cosd(rotY)*sind(rotZ) + r = -cosd(outX)*sind(outZ) + FormatError(0, 1, l, r) + l = sind(rotY) + r = -sind(outX)*cosd(outY)*sind(outZ)-sind(outY)*cosd(outZ) + FormatError(0, 2, l, r) + l = -sind(rotZ) + r = sind(outX)*sind(outY)*cosd(outZ)+cosd(outY)*sind(outZ) + FormatError(1, 0, l, r) + l = cosd(rotZ) + r = cosd(outX)*cosd(outZ) + FormatError(1, 1, l, r) + l = 0 + r = sind(outX)*cosd(outY)*cosd(outZ)-sind(outY)*sind(outZ) + FormatError(1, 2, l, r) + l = -sind(rotY)*cosd(rotZ) + r = cosd(outX)*sind(outY) + FormatError(2, 0, l, r) + l = -sind(rotY)*sind(rotZ) + r = -sind(outX) + FormatError(2, 1, l, r) + l = cosd(rotY) + r = cosd(outX)*cosd(outY) + FormatError(2, 2, l, r) + +if __name__ == '__main__': + main() + sys.exit(extcode)