Beispiel #1
0
	def lines(self):
		lines = []
		
		
		last_vertex = self.__vertices[-1]
		
		for vertex in self.__vertices:
			line = Line.from_points(last_vertex, vertex)
			lines.append(line)
			
			last_vertex = vertex
			
			
		return lines
def compute_segment(polygon, start_state, goal_state, factor):
	s, delta_s = start_state
	g, delta_g = goal_state
	
	
	
	
	
	# Проверка исходной и целевой точек на принадлежность полигону
	if (not polygon.is_inner_point(s)) or (not polygon.is_inner_point(g)):
		return None
		
		
		
		
		
	# Определение коэффициентов прямых
	ls, lg = \
		Line.from_direction(s, delta_s), \
			Line.from_direction(g, delta_g)
			
			
	# Определение центральной точки
	if not Line.are_parallel(ls, lg):
		# Определение точки пересечения прямых
		o = Line.compute_intersection(ls, lg)
		
	elif not Line.are_equivalent(ls, lg):
		# if delta_s / abs(delta_s) == delta_g / abs(delta_g):
		if abs(delta_s / abs(delta_s) - delta_g / abs(delta_g)) < 1.0:
			return None
		else:
			o = (s + g) / 2.0
			
	else:
		# if delta_s / abs(delta_s) == delta_g / abs(delta_g):
		if abs(delta_s / abs(delta_s) - delta_g / abs(delta_g)) < 1.0:
			if ((g - s) / delta_s).real < 0.0:
				return None
				
				
			def trajectory(parameter):
				parameter = max(parameter, 0.0)
				parameter = min(parameter, 1.0)
				
				return parameter * (g - s) + s
				
			trajectory_length = abs(g - s)
			
			
			return trajectory_length, trajectory
		else:
			return None
			
			
	# Определение центра связующей окружности
	c = factor * (delta_s / abs(delta_s) - delta_g / abs(delta_g)) + o
	
	
	# Определение коэффициентов перпендикулярных прямых
	lps = ls.compute_perpendicular(c)
	lpg = lg.compute_perpendicular(c)
	
	
	# Определение точек касания и радиуса окружности
	rs = Line.compute_intersection(ls, lps)
	rg = Line.compute_intersection(lg, lpg)
	r  = abs(rs - c)
	if r < 1.0:
		return None
	
	
	# Проверка существования траектории
	is_existing  = ((rs - s) / delta_s).real >= 0.0
	is_existing &= ((g - rg) / delta_g).real >= 0.0
	
	if not is_existing:
		return None
		
		
		
		
		
	# Построение дуги
	def compute_rotation_angle(start_point, final_point, rotation_direction):
		start_angle = cmath.phase(start_point - c)
		final_angle = cmath.phase(final_point - c)
		
		if rotation_direction > 0:
			rotation_angle = \
				(final_angle - start_angle + 2 * math.pi) \
					% (2 * math.pi)
		else:
			rotation_angle = \
				(start_angle - final_angle + 2 * math.pi) \
					% (2 * math.pi)
					
			rotation_angle *= -1.0
			
		return rotation_angle
		
		
	if r != 0.0:
		# Направление обхода дуги
		angle_direction = \
			cmath.phase(
				(rs - c) \
					/ (rs - delta_s - c)
			)
			
			
		# Вычисление угла дуги
		max_delta_angle = compute_rotation_angle(rs, rg, angle_direction)
		
		
		# Проверка дуги
		intersections = polygon.compute_circle_intersections(c, r)
		
		for intersection in intersections:
			intersection_angle = \
				compute_rotation_angle(
					rs,
					intersection,
					angle_direction
				)
				
				
			if 0.0 < abs(intersection_angle) < abs(max_delta_angle):
				# Траектория выходит за полигон
				return None
				
				
		arc_point = (rs - c) * cmath.rect(1.0, max_delta_angle / 2.0) + c
				
		if not polygon.is_inner_point(arc_point):
			# Траектория выходит за полигон
			return None
	else:
		max_delta_angle = 0.0
		
		if not polygon.is_inner_point(c):
			# Траектория выходит за полигон
			return None
			
			
			
			
			
	# Вычисление длины траектории
	trajectory_length  = abs(rs - s)
	trajectory_length += abs(g - rg)
	trajectory_length += r * abs(max_delta_angle)
	
	
	# Построение траектории
	def trajectory(parameter):
		parameter  = max(parameter, 0.0)
		parameter  = min(parameter, 1.0)
		parameter *= 3.0
		
		
		if 0.0 <= parameter < 1.0:
			return parameter * (rs - s) + s
			
		elif 1.0 <= parameter < 2.0:
			rotation = \
				cmath.rect(
					1.0,
					(parameter - 1.0) * max_delta_angle
				)
				
			return (rs - c) * rotation + c
			
		else:
			return (parameter - 2.0) * (g - rg) + rg
			
			
	return trajectory_length, trajectory