Python 如何在面向对象的PyOpenGL中进行回击?
我正在用PyOpenGL做一个游戏,我想在一个物体足够近的时候在相机上应用“击退”。反击就是简单地根据敌人面对的方向将相机向后放置 我在一张纸上做了个模型,发现Python 如何在面向对象的PyOpenGL中进行回击?,python,opengl,pygame,pyopengl,opengl-compat,Python,Opengl,Pygame,Pyopengl,Opengl Compat,我正在用PyOpenGL做一个游戏,我想在一个物体足够近的时候在相机上应用“击退”。反击就是简单地根据敌人面对的方向将相机向后放置 我在一张纸上做了个模型,发现 xc = person.pos[0] - camera_pos[0] yc = person.pos[1] - camera_pos[1] zc = person.pos[2] - camera_pos[2] glTranslatef(xc,zc,yc) #my z and y are flipped due to gluLookAt(
xc = person.pos[0] - camera_pos[0]
yc = person.pos[1] - camera_pos[1]
zc = person.pos[2] - camera_pos[2]
glTranslatef(xc,zc,yc) #my z and y are flipped due to gluLookAt()
但它似乎不起作用,我想用物体的表面,而不是x,y和z之间的关系
此外,我还尝试了以下解决方案:
xc,yc,zc = normalize([(camera_pos[0] + (camera_pos[0] - person.pos[0])) * 5,(camera_pos[1] + (camera_pos[1] - person.pos[1])) * 5,(camera_pos[2] + (camera_pos[2] - person.pos[2])) * 5])
glTranslatef(xc,zc,yc)
knockback = False
但不知何故,如果我转向透视图,我可以控制如何回击(例如,如果我面向左侧,我将被回击到左侧)
完整代码:
#!/usr/local/bin/python3
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import math,sys,numpy,random,ctypes
pygame.init()
display = (1500, 900)
screen = pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
pygame.display.set_caption("Game")
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glShadeModel(GL_SMOOTH)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_BLEND)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
glEnable(GL_LIGHT0)
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5, 1])
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1])
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glMatrixMode(GL_MODELVIEW)
gluLookAt(0, -8, 0, 0, 0, 0, 0, 0, 1)
glTranslatef(0,-8,0)
viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()
# init mouse movement and center mouse on screen
displayCenter = [screen.get_size()[i] // 2 for i in range(2)]
mouseMove = [0, 0]
pygame.mouse.set_pos(displayCenter)
cmddown = False
cam_attack = False
cam_damage = random.randint(20,30)
knockback = False
person_count = 1
up_down_angle = 0.0
camera_pos = (0,0,0)
paused = False
run = True
#xzy = xyz
#Functions & Classes
def InverseMat44(mat):
m = [mat[i][j] for i in range(4) for j in range(4)]
inv = [0]*16
inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10]
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10]
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9]
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9]
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10]
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10]
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9]
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9]
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6]
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6]
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5]
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5]
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6]
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6]
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5]
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5]
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]
for i in range(16):
inv[i] /= det
return inv
def touched(tar_x,tar_y,tar_z,tar_x1,tar_y1,tar_z1):
centerPt = pygame.math.Vector3(tar_x,tar_y,tar_z)
point2 = pygame.math.Vector3(tar_x1, tar_y1, tar_z1)
distance = centerPt.distance_to(point2)
return distance
def follower(x,y,z,x1,y1,z1,speed):
dir_x, dir_y = (x1-x, y1-y)
distance = math.hypot(dir_x, dir_y)
dir_x, dir_y = (dir_x/distance, dir_y/distance)
angle = math.degrees(math.atan2(dir_y, dir_x)) + 90
return (dir_x*speed, dir_y*speed, 0, angle)
def random_pos(max_distance):
x_value_change = random.randrange(-max_distance + 2,max_distance + 2)
y_value_change = random.randrange(-max_distance + 2,max_distance + 2)
z_value_change = 0
return (x_value_change, y_value_change, z_value_change)
def blit_text(x,y,font,text,r,g,b):
blending = False
if glIsEnabled(GL_BLEND):
blending = True
glColor3f(r,g,b)
glWindowPos2f(x,y)
for ch in text:
glutBitmapCharacter(font,ctypes.c_int(ord(ch)))
if not blending:
glDisable(GL_BLEND)
def subtract(v0, v1):
return [v0[0]-v1[0], v0[1]-v1[1], v0[2]-v1[2]]
def dot(v0, v1):
return v0[0]*v1[0]+v0[1]*v1[1]+v0[2]*v1[2]
def length(v):
return math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])
def normalize(v):
l = length(v)
return [v[0]/l, v[1]/l, v[2]/l]
# Ray - Sphere intersection
#
# Sphere: dot(p-C, p-C) = R*R `C`: center, `p`: point on the sphere, `R`, radius
# Ray: p(t) = A + B * t `A`: origin, `B`: direction
# Intersection: dot(A+B*t-C, A+B*t-C) = R*R
# t*t*dot(B,B) + 2*t*dot(B,A-C) + dot(A-C,A-C) - R*R = 0
def isectObj(p0, p1, C, R):
A = p0 #Origin
B = normalize(subtract(p1, p0)) #Direction
oc = subtract(A, C)
a = dot(B, B)
b = 2 * dot(oc, B)
c = dot(oc, oc) - R*R
discriminant = b*b - 4*a*c
if discriminant > 0:
t1 = (-b - math.sqrt(discriminant)) / (2*a)
t2 = (-b + math.sqrt(discriminant)) / (2*a)
t = min(t1, t2)
return t if t >= 0.0 else None
return None
class Ground:
def __init__(self,mul=1):
self.vertices = [
[-20,20,-1],
[20,20,-1],
[-20,-300,-1],
[20,-300,-1]
]
def draw(self):
glBegin(GL_QUADS) #Begin fill
for vertex in self.vertices:
glColor3f(0,0.5,0.5)
glVertex3fv(vertex)
glEnd()
class Person:
def __init__(self):
self.vertices = [
[-1,0,1],
[-1,0,-1],
[1,0,-1],
[1,0,1],
[-1,1,1],
[-1,1,-1],
[1,1,-1],
[1,1,1]
]
self.vertices = list(numpy.multiply(numpy.array(self.vertices),1))
self.edges = (
(0,1),
(0,3),
(0,4),
(1,2),
(1,5),
(2,3),
(2,6),
(3,7),
(4,5),
(4,7),
(5,6),
(6,7)
)
self.surfaces = (
(0,1,2,3),
(0,1,5,4),
(4,5,6,7),
(1,2,6,5),
(0,3,7,4),
(2,3,7,6)
)
self.x = self.vertices[1][0]
self.y = self.vertices[1][2]
self.z = self.vertices[1][1]
self.pos = (self.x,self.y,self.z)
self.rot = 0
self.health = 100
self.damage = random.randint(20,40)
self.level = 1
def draw(self):
glTranslated(self.pos[0], self.pos[1], self.pos[2])
glRotated(self.rot,0,0,1)
glBegin(GL_QUADS) #Begin fill
for surface in self.surfaces:
for vertex in surface:
glColor3f(0,1,0)
glVertex3fv(self.vertices[vertex])
glEnd()
glLineWidth(5) #Set width of the line
glBegin(GL_LINES) #Begin outline
for edge in self.edges:
for vertex in edge:
glColor3f(1,1,0)
glVertex3fv(self.vertices[vertex])
glEnd()
def move(self,x,y,z):
self.pos = (self.pos[0]+x,self.pos[1]+y,self.pos[2]+z)
glutInit()
persons = [Person() for person in range(person_count)]
ground = Ground()
for person in persons:
person.pos = random_pos(12)
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_p:
paused = not paused
if not paused:
if event.type == pygame.MOUSEMOTION:
mouseMove = [event.pos[i] - displayCenter[i] for i in range(2)]
pygame.mouse.set_pos(displayCenter)
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
cam_attack = True
pygame.mouse.set_visible(False)
if not paused:
#Get keys
keypress = pygame.key.get_pressed()
#Init model view matrix
glLoadIdentity()
#------------------------View------------------------
#Apply the look up and down (with 90° angle limit)
if up_down_angle < -90:
if mouseMove[1] > 0:
up_down_angle += mouseMove[1]*0.1
elif up_down_angle > 90:
if mouseMove[1] < 0:
up_down_angle += mouseMove[1]*0.1
else:
up_down_angle += mouseMove[1]*0.1
glRotatef(up_down_angle, 1.0, 0.0, 0.0)
#Init the view matrix
glPushMatrix()
glLoadIdentity()
#Apply the movement
if keypress[pygame.K_w]:
glTranslatef(0,0,0.1)
if keypress[pygame.K_s]:
glTranslatef(0,0,-0.1)
if keypress[pygame.K_d]:
glTranslatef(-0.1,0,0)
if keypress[pygame.K_a]:
glTranslatef(0.1,0,0)
if knockback:
#Knockback
xc,yc,zc = normalize([(camera_pos[0] + (camera_pos[0] - person.pos[0])) * 5,(camera_pos[1] + (camera_pos[1] - person.pos[1])) * 5,(camera_pos[2] + (camera_pos[2] - person.pos[2])) * 5])
glTranslatef(xc,zc,yc)
knockback = False
#Apply the look left and right
glRotatef(mouseMove[0]*0.1, 0.0, 1.0, 0.0)
#------------------------View------------------------
#Multiply the current matrix by the new view matrix and store the final view matrix
glMultMatrixf(viewMatrix)
viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
invVM = InverseMat44(viewMatrix)
camera_pos = (invVM[12],invVM[13],invVM[14])
#Apply view matrix
glPopMatrix()
glMultMatrixf(viewMatrix)
#Get current view matrix, projection matrix and viewport rectangle
mv_matrix = glGetDoublev(GL_MODELVIEW_MATRIX)
proj_matrix = glGetDoublev(GL_PROJECTION_MATRIX)
vp_rect = glGetIntegerv(GL_VIEWPORT)
#Calculate "near" and "far" point
pt_near = gluUnProject(displayCenter[0], displayCenter[1], 0, mv_matrix, proj_matrix, vp_rect)
pt_far = gluUnProject(displayCenter[0], displayCenter[1], 1, mv_matrix, proj_matrix, vp_rect)
glLightfv(GL_LIGHT0, GL_POSITION, [1, -1, 1, 0])
#Follow, attack
crosshair_color = (1,1,1)
attacklist = []
for person in persons:
freturn = follower(person.pos[0],person.pos[1],person.pos[2],camera_pos[0],camera_pos[1],camera_pos[2],0.02)
xchange,ychange,zchange = freturn[0],freturn[1],freturn[2]
person.rot = freturn[3]
if (touched(person.pos[0],person.pos[1],person.pos[2],camera_pos[0],camera_pos[1],camera_pos[2])) < 2.5:
xchange,ychange,zchange = 0,0,0
knockback = True
person.move(xchange,ychange,zchange)
if (touched(person.pos[0],person.pos[1],person.pos[2],camera_pos[0],camera_pos[1],camera_pos[2])) < 5 and isectObj(pt_near, pt_far, person.pos, 1) != None:
crosshair_color = (1,0,0)
if len(attacklist) >= 2:
bigger = attacklist[1] > touched(person.pos[0],person.pos[1],person.pos[2],camera_pos[0],camera_pos[1],camera_pos[2])
if bigger == True:
attacklist = [person,touched(person.pos[0],person.pos[1],person.pos[2],camera_pos[0],camera_pos[1],camera_pos[2])]
else:
attacklist = [person,touched(person.pos[0],person.pos[1],person.pos[2],camera_pos[0],camera_pos[1],camera_pos[2])]
if attacklist:
if cam_attack == True:
attacklist[0].health -= cam_damage
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
#Draw crosshair, health
blit_text(displayCenter[0] - 5,displayCenter[1] - 5,GLUT_BITMAP_TIMES_ROMAN_24,"+",crosshair_color[0],crosshair_color[1],crosshair_color[2])
for person in persons:
if person.health > 0:
#print(person.health)
pass
glPushMatrix()
glColor4f(0.2, 0.2, 0.5, 1)
for person in persons:
glPushMatrix()
person.draw()
glPopMatrix()
ground.draw()
glPopMatrix()
for person in persons:
if person.health <= 0:
persons.remove(person)
cam_attack = False
pygame.display.flip()
pygame.time.wait(10)
pygame.quit()
sys.exit()
#/usr/local/bin/python3
导入pygame
从pygame.locals导入*
从OpenGL.GL导入*
从OpenGL.GLU导入*
从OpenGL.GLUT导入*
导入数学、系统、numpy、随机、ctypes
pygame.init()
显示=(1500900)
screen=pygame.display.set_模式(显示,DOUBLEBUF | OPENGL)
pygame.display.set_标题(“游戏”)
glEnable(GL_深度_测试)
glEnable(德国劳埃德大学照明)
glShadeModel(GLU平滑)
glEnable(德国劳埃德船级社颜色材料)
glEnable(GL_混合)
glColorMaterial(GL_前部和后部、GL_环境和_漫反射)
glEnable(Glu LIGHT0)
glLightfv(GL_LIGHT0,GL_环境光[0.5,0.5,0.5,1])
glLightfv(GL_LIGHT0,GL_漫反射,[1.0,1.0,1.0,1])
glMatrixMode(GL_投影)
透视图(45,(显示[0]/显示[1]),0.1,50.0)
glMatrixMode(GLU模型视图)
gluLookAt(0,-8,0,0,0,0,0,0,1)
glTranslatef(0,-8,0)
viewMatrix=glGetFloatv(GL\U模型视图\U矩阵)
glLoadIdentity()
#初始化鼠标移动并使鼠标在屏幕上居中
displayCenter=[screen.get_size()[i]//2用于范围(2)内的i]
mouseMove=[0,0]
pygame.mouse.set_pos(显示中心)
cmddown=False
cam_攻击=错误
凸轮损坏=随机随机随机数(20,30)
击退=错误
人数=1
上下角度=0.0
摄像头位置=(0,0,0)
暂停=错误
运行=真
#xzy=xyz
#函数与类
def倒置EMAT44(垫):
m=[mat[i][j]表示范围(4)中的i,表示范围(4)中的j]
存货=[0]*16
inv[0]=m[5]*m[10]*m[15]-m[5]*m[11]*m[14]-m[9]*m[6]*m[15]+m[9]*m[7]*m[14]+m[13]*m[6]*m[11]-m[13]*m[7]*m[10]
inv[4]=-m[4]*m[10]*m[15]+m[4]*m[11]*m[14]+m[8]*m[6]*m[15]-m[8]*m[7]*m[14]-m[12]*m[6]*m[11]+m[12]*m[7]*m[10]
inv[8]=m[4]*m[9]*m[15]-m[4]*m[11]*m[13]-m[8]*m[5]*m[15]+m[8]*m[7]*m[13]+m[12]*m[5]*m[11]-m[12]*m[7]*m[9]
inv[12]=-m[4]*m[9]*m[14]+m[4]*m[10]*m[13]+m[8]*m[5]*m[14]-m[8]*m[6]*m[13]-m[12]*m[5]*m[10]+m[12]*m[6]*m[9]
inv[1]=-m[1]*m[10]*m[15]+m[1]*m[11]*m[14]+m[9]*m[2]*m[15]-m[9]*m[3]*m[14]-m[13]*m[2]*m[11]+m[13]*m[3]*m[10]
inv[5]=m[0]*m[10]*m[15]-m[0]*m[11]*m[14]-m[8]*m[2]*m[15]+m[8]*m[3]*m[14]+m[12]*m[2]*m[11]-m[12]*m[3]*m[10]
inv[9]=-m[0]*m[9]*m[15]+m[0]*m[11]*m[13]+m[8]*m[1]*m[15]-m[8]*m[3]*m[13]-m[12]*m[1]*m[11]+m[12]*m[3]*m[9]
inv[13]=m[0]*m[9]*m[14]-m[0]*m[10]*m[13]-m[8]*m[1]*m[14]+m[8]*m[2]*m[13]+m[12]*m[1]*m[10]-m[12]*m[2]*m[9]
inv[2]=m[1]*m[6]*m[15]-m[1]*m[7]*m[14]-m[5]*m[2]*m[15]+m[5]*m[3]*m[14]+m[13]*m[2]*m[7]-m[13]*m[3]*m[6]
inv[6]=-m[0]*m[6]*m[15]+m[0]*m[7]*m[14]+m[4]*m[2]*m[15]-m[4]*m[3]*m[14]-m[12]*m[2]*m[7]+m[12]*m[3]*m[6]
inv[10]=m[0]*m[5]*m[15]-m[0]*m[7]*m[13]-m[4]*m[1]*m[15]+m[4]*m[3]*m[13]+m[12]*m[1]*m[7]-m[12]*m[3]*m[5]
inv[14]=-m[0]*m[5]*m[14]+m[0]*m[6]*m[13]+m[4]*m[1]*m[14]-m[4]*m[2]*m[13]-m[12]*m[1]*m[6]+m[12]*m[2]*m[5]
inv[3]=-m[1]*m[6]*m[11]+m[1]*m[7]*m[10]+m[5]*m[11]-m[5]*m[3]*m[10]-m[9]*m[2]*m[7]+m[9]*m[3]*m[6]
inv[7]=m[0]*m[6]*m[11]-m[0]*m[7]*m[10]-m[4]*m[2]*m[11]+m[4]*m[3]*m[10]+m[8]*m[2]*m[7]-m[8]*m[3]*m[6]
inv[11]=-m[0]*m[5]*m[11]+m[0]*m[7]*m[9]+m[4]*m[1]*m[11]-m[4]*m[3]*m[9]-m[8]*m[1]*m[7]+m[8]*m[3]*m[5]
inv[15]=m[0]*m[5]*m[10]-m[0]*m[6]*m[9]-m[4]*m[1]*m[10]+m[4]*m[2]*m[9]+m[8]*m[1]*m[6]-m[8]*m[2]*m[5]
det=m[0]*inv[0]+m[1]*inv[4]+m[2]*inv[8]+m[3]*inv[12]
对于范围(16)中的i:
存货[i]/=det
退货库存
接触def(焦油x、焦油y、焦油z、焦油x1、焦油y1、焦油z1):
centerPt=pygame.math.Vector3(tar_x,tar_y,tar_z)
点2=pygame.math.Vector3(tar_x1,tar_y1,tar_z1)
距离=中心点距离(点2)
返回距离
def随动器(x、y、z、x1、y1、z1、速度):
方向x,方向y=(x1-x,y1-y)
距离=数学形下压(方向x,方向y)
方向x,方向y=(方向x/距离,方向y/距离)
角度=数学角度(数学角度2(方向y,方向x))+90
返回(方向x*速度,方向y*速度,0,角度)
def随机位置(最大距离):
x_值_变化=random.randrange(-max_distance+2,max_distance+2)
y_值_变化=random.randrange(-max_distance+2,max_distance+2)
z_值_变化=0
返回值(x值更改、y值更改、z值更改)
def blit_文本(x、y、字体、文本、r、g、b):
混合=假
如果已启用(GL_混合):
混合=真
GL3F(r、g、b)
glWindowPos2f(x,y)
对于文本中的ch:
glutBitmapCharacter(字体,ctypes.c_int(ord(ch)))
如果不混合:
glDisable(GLU混合)
def减法(v0,v1):
返回[v0[0]-v1[0],v0[1]-v1[1],v0[2]-v1[2]]
def点(v0,v1):
返回v0[0]*v1[0]+v0[1]*v1[1]+v0[2]*v1[2]
def长度(v):
返回math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])
def正常化(v):
l=长度(v)
返回[v[0]/l,v[1]/l,v[2]/l]
#射线球交点
#
#球体:圆点(p-C,p-C)=R*R`C`:圆心,`p`:球体上的点,`R`,半径
#射线:p(t)=A+B*t`A`:原点,`B`:方向
#交点:点(A+B*t-C,A+B