def calcDeterminant(self, degrees=None): if degrees == None: degrees = self.degrees # +90 because we want the line perpendicular to the front axis steerRad = const.radians(90 + self.steerDeg + degrees) # using ackermann algorithm to steer the vehicle wheels = self.calcWheelsPosition() # find the center front = (wheels[0][0] + (wheels[1][0] - wheels[0][0]) / 2, wheels[0][1] + (wheels[1][1] - wheels[0][1]) / 2) fronti = (front[0] + const.cos(steerRad), front[1] + const.sin(steerRad)) rearA = wheels[2][1] - wheels[3][1] # N *x rearB = wheels[3][0] - wheels[2][0] # N *y rearC = rearA * (wheels[3][0]) + rearB * (wheels[3][1]) # C if rearA < 0 and rearB < 0: rearA = -rearA rearB = -rearB rearC = -rearC frontA = front[1] - fronti[1] frontB = fronti[0] - front[0] frontC = frontA * (fronti[0]) + frontB * (fronti[1]) if frontA < 0 and frontB < 0: frontA = -frontA frontB = -frontB frontC = -frontC determinant = frontA * rearB - rearA * frontB if determinant: return determinant, ((rearB * frontC - frontB * rearC) / determinant, (frontA * rearC - rearA * frontC) / determinant) return None, None
def calcWheelsPosition(self): mysin = const.sin(const.radians(self.degrees)) mycos = const.cos(const.radians(self.degrees)) distX = self.width - const.BUS_WHEELS_POSITION distY = self.height - const.PROPORTION return ([ self.position[0] + mysin * distY + mycos * distX, self.position[1] + mysin * distX - mycos * distY ], [ self.position[0] - mysin * distY + mycos * distX, self.position[1] + mysin * distX + mycos * distY ], [ self.position[0] - mysin * distY - mycos * distX, self.position[1] - mysin * distX + mycos * distY ], [ self.position[0] + mysin * distY - mycos * distX, self.position[1] - mysin * distX - mycos * distY ])
def updatePosition(self): rad = const.radians(self.tLight.degrees) self.position = [ round(-self.offset * const.sin(rad) + const.TL_DISTANCES * 2 / 3 * const.cos(rad) + self.tLight.points[0][0]), round(self.offset * const.cos(rad) + const.TL_DISTANCES * 2 / 3 * const.sin(rad) + self.tLight.points[0][1]) ]
def calcFrontArea(self, view_h=const.DOUBLE_PROPORTION, view_w=const.TWENTYTWO_PROPORTION): mysin = const.sin(const.radians(self.degrees)) mycos = const.cos(const.radians(self.degrees)) points = self.calcPoints() points[2] = list(points[1]) points[3] = list(points[0]) points[0][0] += mysin * (view_h + const.HALF_PROPORTION) + mycos * view_w points[0][1] += mysin * view_w - mycos * (view_h + const.HALF_PROPORTION) points[1][0] += -mysin * (view_h + const.HALF_PROPORTION) + mycos * view_w points[1][1] += mysin * view_w + mycos * (view_h + const.HALF_PROPORTION) points[2][0] -= mysin * (view_h) points[2][1] += mycos * (view_h) points[3][0] += mysin * (view_h) points[3][1] -= mycos * (view_h) return points
def calcPoints(self, position=None, degrees=None): if not position: position = self.position if not degrees: degrees = self.degrees mysin = const.sin(const.radians(degrees)) mycos = const.cos(const.radians(degrees)) return [[ position[0] + mysin * self.height + mycos * self.width, position[1] + mysin * self.width - mycos * self.height ], [ position[0] - mysin * self.height + mycos * self.width, position[1] + mysin * self.width + mycos * self.height ], [ position[0] - mysin * self.height - mycos * self.width, position[1] - mysin * self.width + mycos * self.height ], [ position[0] + mysin * self.height - mycos * self.width, position[1] - mysin * self.width - mycos * self.height ]]
def update(self): accelerate_value = self.acceleration / 2 * self.power / self.weight self.velocity += accelerate_value slip_effect = (1 + self.game.rain / 10) * self.tire_value / max( 0.001, (const.ceil(self.velocity / 4 * 1000) / 1000)) if (self.deceleration and self.velocity > 0) and ( self.game.rain <= const.randint(0, 120) and self.tire_wear <= const.randint(0, 100)): self.velocity -= self.deceleration / 2 * self.power / self.weight # self.acceleration = 0 # self.deceleration = 0 if self.velocity > 0: # rain affects vehicle friction self.velocity = round( self.velocity - const.VEHICLE_FRICTION * (1 + self.game.rain / 60) * const.ceil(self.velocity / 10) * self.weight, const.FLOAT_PRECISION) if self.velocity > 0 and self.steerDeg: self.velocity = round( self.velocity - abs(self.steerDeg) * 0.0005 * (self.velocity**0.2), const.FLOAT_PRECISION) if self.velocity > 0: self.velocity -= slip_effect if accelerate_value and slip_effect > 0.005: self.temp_boost += 0.005 else: self.temp_boost = 0 # limit enderly people at 25 km/h XD if self.senior and self.velocity > 25: self.velocity = 25.0 if self.velocity < 0: self.velocity = 0 if not self.startTimeStop: self.startTimeStop = self.game.currentTimeFromStart self.timeStop = self.game.currentTimeFromStart - self.startTimeStop else: if self.velocity > self.maxVel: self.maxVel = self.velocity if self.velocity < self.minVel: self.minVel = self.velocity if self.startTimeStop and self.velocity > 8: self.totalTimeStop += self.timeStop self.startTimeStop = 0 self.timeStop = 0 elif self.startTimeStop: self.timeStop = self.game.currentTimeFromStart - self.startTimeStop if self.steerDeg: determinant, center = self.calcDeterminant() ## move forward before turn because rain ## radians = const.radians(self.degrees) calc_x = const.cos(radians) * self.velocity * ( self.game.rain / 60) * const.VEHICLE_RENDER calc_y = const.sin(radians) * self.velocity * ( self.game.rain / 60) * const.VEHICLE_RENDER self.move(calc_x, calc_y) ## END ## if center: # i do not need rear calc because it's fine use one of the rear wheels # rotate the vehicle self.rotate( const.copysign( self.velocity * const.VEHICLE_RENDER * 75 / const.DISTANCE(center, self.position), self.steerDeg), center) else: radians = const.radians(self.degrees) calc_x = const.cos(radians) * self.velocity * ( 1 - self.game.rain / 60) * const.VEHICLE_RENDER calc_y = const.sin(radians) * self.velocity * ( 1 - self.game.rain / 60) * const.VEHICLE_RENDER self.move(calc_x, calc_y) else: radians = const.radians(self.degrees) calc_x = const.cos( radians) * self.velocity * const.VEHICLE_RENDER calc_y = const.sin( radians) * self.velocity * const.VEHICLE_RENDER self.move(calc_x, calc_y)