New experimental rotation handling

This commit is contained in:
Star Brilliant 2014-06-05 21:50:00 +08:00
parent 12fa6bf48b
commit 6adac57087

View File

@ -502,46 +502,15 @@ def GetZoomFactor(SourceSize, TargetSize):
# Calculation is based on https://github.com/jabbany/CommentCoreLibrary/issues/5#issuecomment-40087282 # Calculation is based on https://github.com/jabbany/CommentCoreLibrary/issues/5#issuecomment-40087282
# and https://github.com/m13253/danmaku2ass/issues/7#issuecomment-41489422 # 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) # FOV = 1.0/math.tan(100*math.pi/360.0)
# Result: (rotX, rotY, rotZ, shearX, shearY) # Result: (transX, transY, rotX, rotY, rotZ, scaleX, scaleY)
def ConvertFlashRotation(rotY, rotZ, X, Y, FOV=math.tan(2*math.pi/9.0)): def ConvertFlashRotation(rotY, rotZ, X, Y, width, height):
def WrapAngle(deg): def WrapAngle(deg):
return 180-((180-deg)%360) 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) rotY = WrapAngle(rotY)
rotZ = WrapAngle(rotZ) rotZ = WrapAngle(rotZ)
if rotY in (90, -90):
rotY -= 1
if rotY == 0 or rotZ == 0: if rotY == 0 or rotZ == 0:
outX = 0 outX = 0
outY = -rotY # Positive value means clockwise in Flash 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 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 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.asin(math.sin(rotY)*math.sin(rotZ))*180/math.pi
if FOV is not None: rotX *= pi/180.0
#outX = CalcPerspectiveCorrection(outX, -Y, FOV*0.75) rotY *= pi/180.0
outY = CalcPerspectiveCorrection(outY, X, FOV) rotZ *= pi/180.0
return (WrapAngle(round(outX)), WrapAngle(round(outY)), WrapAngle(round(outZ)), 0, round(-0.75*Y*math.sin(outY*math.pi/180.0), 3)) 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): def ProcessComments(comments, f, width, height, bottomReserved, fontface, fontsize, alpha, lifetime, reduced, progress_callback):