From 6adac570879a44372abb3b239d555dcf1b492e92 Mon Sep 17 00:00:00 2001 From: Star Brilliant Date: Thu, 5 Jun 2014 21:50:00 +0800 Subject: [PATCH] New experimental rotation handling --- danmaku2ass.py | 49 ++++++++++--------------------------------------- 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/danmaku2ass.py b/danmaku2ass.py index 20fa996..935e2d5 100755 --- a/danmaku2ass.py +++ b/danmaku2ass.py @@ -502,46 +502,15 @@ def GetZoomFactor(SourceSize, TargetSize): # Calculation is based on https://github.com/jabbany/CommentCoreLibrary/issues/5#issuecomment-40087282 # and https://github.com/m13253/danmaku2ass/issues/7#issuecomment-41489422 -# Input: X relative horizonal coordinate: 0 for left edge, 1 for right edge. -# Y relative vertical coordinate: 0 for top edge, 1 for bottom edge. # FOV = 1.0/math.tan(100*math.pi/360.0) -# Result: (rotX, rotY, rotZ, shearX, shearY) -def ConvertFlashRotation(rotY, rotZ, X, Y, FOV=math.tan(2*math.pi/9.0)): +# Result: (transX, transY, rotX, rotY, rotZ, scaleX, scaleY) +def ConvertFlashRotation(rotY, rotZ, X, Y, width, height): def WrapAngle(deg): 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: - if costheta > 1: - costheta = 1 - raise ValueError - elif costheta < -1: - costheta = -1 - raise ValueError - except ValueError: - logging.error('Clipped rotation angle: (alpha=%s, X=%s), it is a bug!' % (alpha, X)) - theta = math.acos(costheta)*180/math.pi - else: - 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: - if costheta > 1: - costheta = 1 - raise ValueError - elif costheta < -1: - costheta = -1 - raise ValueError - except ValueError: - logging.error('Clipped rotation angle: (alpha=%s, X=%s), it is a bug!' % (alpha, X)) - theta = -math.acos(costheta)*180/math.pi - return WrapAngle(theta) - X = 2*X-1 - Y = 2*Y-1 rotY = WrapAngle(rotY) rotZ = WrapAngle(rotZ) + if rotY in (90, -90): + rotY -= 1 if rotY == 0 or rotZ == 0: outX = 0 outY = -rotY # Positive value means clockwise in Flash @@ -552,10 +521,12 @@ 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 - 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)) + rotX *= pi/180.0 + rotY *= pi/180.0 + rotZ *= pi/180.0 + trX = (X*math.cos(rotZ)+Y*math.sin(rotZ))/math.cos(rotY)+math.tan(rotY*math.pi/180.0)+(1-math.cos(rotZ)/math.cos(rotY))*width/2-math.sin(rotZ)/math.cos(rotY)*height/2 + trY = Y*math.cos(rotZ)-X*math.sin(rotZ)+math.sin(rotZ)*width/2+(1-cos(rotZ))*height/2 + return (round(trX), round(trY), WrapAngle(round(outX)), WrapAngle(round(outY)), WrapAngle(round(outZ)), 100, 100) def ProcessComments(comments, f, width, height, bottomReserved, fontface, fontsize, alpha, lifetime, reduced, progress_callback):