oOo VnSharing oOo

Go Back   Diễn đàn > Trung tâm thương mại > Trung tâm giao dịch > Lưu trữ >

Trả lời
Kết quả 1 đến 9 của 9
 
  • Công cụ
  • Hiển thị
    1. [1000 rep] Nhờ bạn nào rành python

      Như tít, mình đang có một chuơng trình về tạo đường đua cho turtle nhưng bị kẹt ở chỗ chỉ chạy riêng cho hình vuông. Vấn đề là mình muốn sửa logic cho con rùa để có thể quẹo khi đụng parameter với các góc là 360/corners.

      Logic cứng chỉ chạy theo hình vuông (corners = 4) với
      Code:
      myturtle[count].setpos(-300,300)
      Code:
              if myturtle[count].xcor() > 300 and myturtle[count].heading() == 0:
                  myturtle[count].right(360/corners)
              elif myturtle[count].ycor() < -300 and myturtle[count].heading() == (360 - (360/corners)):
                  myturtle[count].right(360/corners)
              if myturtle[count].xcor() < -300 and myturtle[count].heading() == (360 - ((360/corners)*2)):
                  myturtle[count].right(360/corners)
              if myturtle[count].ycor() > 300 and myturtle[count].heading() == (360 - ((360/corners)*3)):
                  myturtle[count].right(360/corners)
      Cảm ơn

      Nói vậy chứ tasukete, sắp deadline rồi
      Sửa lần cuối bởi comtrends123; 07-04-2017 lúc 17:26.

    2. #2
      Nhợn mini
      SP: 370
      Tham gia ngày
      08-12-2014
      Bài viết
      774
      Cấp độ
      4
      Reps
      145
      Cậu có thể define một struct gồm 2 số nguyên trong khoảng [-1; 1], đặt tên nó là Vector2. Ý tưởng là dùng một vector chỉ hướng cho cái xe, nếu xe phải rẽ thì chỉ cần đổi giá trị của vector chỉ hướng. Ví dụ như đang chuyển động với tốc độ dt * Vector2(1; 0) (theo chiều từ trái -> phải), nếu muốn chạy xuống thì chỉ cần viết lại: dt * Vector2(0; 1) (đi theo trục Y, là đi xuống).



      Các hướng có thể có của vector. Vì xe chỉ có 4 hướng đi, nên vector chỉ hướng sẽ chỉ có 4 giá trị.



      Mã giả, cậu có thể tự viết lại bằng Python



      Khỏi rep nhé.

    3. #3
      Tham gia ngày
      22-06-2015
      Bài viết
      143
      Blog Entries
      1
      Cấp độ
      86
      Reps
      4253
      Hỏi lại problem cho chắc, có phải ý bạn là nếu corner = 3 thì con rùa sẽ di chuyển counter-clockwise hoặc clockwise trong hình tam giác dưới đây (mỗi góc tam giác là 60 độ)? @comtrends123



      Hay là khi corner = 3 thì con rùa sẽ di chuyển counter-clockwise hoặc clockwise trong hình hexagon (mỗi góc hexagon là 120 độ) dưới đây?

      Sửa lần cuối bởi Eva Rasta; 09-04-2017 lúc 14:30.

    4. @Eva Rasta corners=3 thì con rùa sẽ đi theo hình tam giác với mỗi góc của tam giác là 60 độ đi theo chiều kim đồng hồ nhé, áp dụng cho các góc 4,5,6,7,8 luôn Theo hình của cậu thì mình cũng từng nghĩ đến việc dùng hình tròn để tính tọa độ của các cạnh rồi mà vẫn bí phần công thức


    5. #5
      Tham gia ngày
      22-06-2015
      Bài viết
      143
      Blog Entries
      1
      Cấp độ
      86
      Reps
      4253
      Mình post code cho cậu test thử nhé. Tí nữa mình sẽ gom nội lực để post doc haha... @comtrends123 Ngoài ra vấn đề của bạn là agent oriented programming đúng không? (Tức là con rùa có tính thông minh, tự tìm đường đi) Chứ không phải là Computer Graphics? (Tức là con rùa chạy theo các đường đã được vạch trước) Nếu là agen oriented programming thì mình sẽ bắt đầu viết doc, còn hong thì chắc phải làm lại cho nó tối ưu.

      Code:
      import numpy as np
      import math
      
      def rotate(direction, angle):
      	theta = np.radians(angle)
      	c, s = np.cos(theta), np.sin(theta)
      	R = np.matrix([[c, -s], [s, c]])
      	return np.round(np.squeeze(np.asarray(direction * R)))
      	
      def norm_vector(vector):
      	return vector / np.linalg.norm(vector,2)
      	
      def norm_dot(vector1, vector2):
      	return np.dot(vector1, vector2) / (np.linalg.norm(vector1,2) * np.linalg.norm(vector2,2))
      	
      def vector_angle(vector1, vector2):
      	return np.rad2deg(np.arccos(norm_dot(vector1, vector2)))
      
      class turtle:
      
      	def __init__(self, environment, position, direction, preferred_direction):
      		self.position = np.array(position) #Global position
      		self.direction = np.array(direction)
      		self.environment = environment
      		self.track = dict()
      		self.track[tuple(self.position)] = 1
      		self.blimit = np.array([])
      		self.ulimit = np.array([])
      		self.preferred_direction = preferred_direction #-1 for counter-clockwise, +1 for clockwise
      		self.preferred_position = self.prefer(self.environment.cdir)
      		self.k = 0
      	
      	def turnAngle(self, angle):
      		return rotate(self.direction, angle)
      	
      	def moveForward(self, direction = None):
      		if direction is None:
      			direction = self.direction
      		return self.position + direction
      		
      	def get_blimit_ulimit(self, position = None):
      		if position is None:
      			position = self.position
      		angle = self.environment.angle(position)
      		k = math.floor(angle / self.environment.cangle)
      		if k != self.k or self.blimit.size == 0:
      			blimit = rotate(self.environment.cdir, self.environment.cangle*k)
      			ulimit = rotate(self.environment.cdir, self.environment.cangle*(k + 1))
      		else:
      			blimit = self.blimit
      			ulimit = self.ulimit
      		return (blimit, ulimit, k)
      	
      	def sense(self, position):
      		blimit, ulimit, k = self.get_blimit_ulimit(position)
      		bedge = position - blimit
      		uedge = position - ulimit
      		if not(np.any(bedge)) or not(np.any(uedge)):
      			return np.inf
      		bangle = vector_angle(bedge, -blimit)
      		uangle = vector_angle(uedge, -ulimit)
      		if bangle + uangle >= 180 - self.environment.cangle:
      			return np.inf
      		track_idx = tuple(position)
      		if track_idx in self.track.keys():
      			return self.track[track_idx]
      		return -norm_dot(position, self.preferred_position)
      		
      	def prefer(self, preferred_position = None):
      		if preferred_position is None:
      			preferred_position = self.preferred_position
      		preferred_position = rotate(preferred_position, self.environment.cangle * self.preferred_direction)
      		return preferred_position
      		
      	def think2act(self):
      		turn2move = [0, -90, 90, 180] #do not turn, turn left, turn right, turn back
      		best_decision = np.inf
      		for i in range(0, len(turn2move)):
      			direction = self.turnAngle(turn2move[i])
      			decision = self.sense(self.moveForward(direction))
      			if decision < best_decision:
      				best_direction = direction
      				best_decision = decision
      		self.direction = best_direction
      		self.position = self.moveForward()
      		self.track[tuple(self.position)] = max(np.ceil(best_decision), 0) + 1
      		self.blimit, self.ulimit, k = self.get_blimit_ulimit()
      		if self.k != k:
      			self.k = k
      			if self.k < -1 or self.k > 0:
      				self.preferred_position = self.prefer()
      		
      class environment:
      
      	def __init__(self, radius, corner):
      		self.center = np.array([0,0])
      		self.radius = radius
      		self.corner = corner
      		self.cangle = 360 / corner
      		self.cdir = self.center + np.array([0, self.radius])
      		
      	def angle(self, vector):
      		angle = vector_angle(self.cdir, vector)
      		if vector[0] < 0:
      			angle = -angle
      		return angle
      
      
      environment = environment(300, 3)
      turtle = turtle(environment, [0, 299], [0, 1], 1)
      for i in range(0,10):
      	turtle.think2act()
      	print turtle.position
      	#print turtle.direction
      Sửa lần cuối bởi Eva Rasta; 10-04-2017 lúc 11:04.

    6. @Eva Rasta mình không nghĩ vạch đường cho con rùa của mình lại cần phức tạp đến như vậy Mình nghĩ mình bài của mình là computer graphic cơ mà vì đề bài ghi là phải avoid hardcoded value nên mình nghĩ phương án để dẫn con rùa đi là bằng cách áp dụng cách tính tọa độ của các điểm để dẫn con rùa đi thôi.
      Code:
      import turtle, random, math
      
      maxturtles = int(input("How many turtles do you want to race?")) #number of turtles
      n = int(input("How many laps do you want to race?")) #number of tracks
      corners = int(input("How many corners do you want to add? Current valid value is only 3 and 4.")) #number of corners
      if maxturtles > 1:
          n = n+1
      #draw a race track
      def racetrack():
          racetrack = turtle.Turtle()
          racetrack.color('black')
          racetrack.pensize(7)
          racetrack.penup()
          racetrack.goto(-320,320)
          racetrack.pd()
          for track in range (corners):
              racetrack.forward(640)
              racetrack.right(360/corners)
      
      racetrack()
      
      #create turtle
      myturtle = []
      
      for count in range(maxturtles):
          myturtle.append(turtle.Turtle())
          turtle.colormode(255)
          myturtle[count].color(random.randint(0,255),random.randint(0,255),random.randint(0,255))
          myturtle[count].shape("turtle")
          myturtle[count].penup()
          myturtle[count].speed(0)
          myturtle[count].setposition(-300,300)
      
      i=0
      if corners == 4:
          while n > i:
              #move turtle
              for count in range(maxturtles):
                  myturtle[count].forward(random.randint(1,10))
                  #print(myturtle[count].pos())
                  #print(myturtle[count].heading())
                  #boarder check
                  if myturtle[count].xcor() > 300 and myturtle[count].heading() == 0:
                      myturtle[count].right(360/corners)
                  elif myturtle[count].ycor() < -300 and myturtle[count].heading() == (360 - (360/corners)):
                      myturtle[count].right(360/corners)
                  if myturtle[count].xcor() < -300 and myturtle[count].heading() == (360 - ((360/corners)*2)):
                      myturtle[count].right(360/corners)
                  if myturtle[count].ycor() > 300 and myturtle[count].heading() == (360 - ((360/corners)*3)):
                      myturtle[count].right(360/corners)
                      n=n-1
      
      if corners == 3:
          a = (math.sqrt((math.pow(300,2) + math.pow(600,2) - 2*300*600*math.cos(math.radians(60)))))-300
          while n > i:
              # move turtle
              for count in range(maxturtles):
                  myturtle[count].forward(random.randint(1, 20))
                  # print(myturtle[count].pos())
                  # print(myturtle[count].heading())
                  # boarder check
                  if myturtle[count].xcor() > 300 and myturtle[count].heading() == 0:
                      myturtle[count].right(360 / corners)
                  elif myturtle[count].ycor() < -a and myturtle[count].heading() == (360 - (360 / corners)):
                      myturtle[count].right(360 / corners)
                  if myturtle[count].xcor() < - 300 and myturtle[count].heading() == (360 - ((360 / corners) * 2)):
                      myturtle[count].right(360 / corners)
                      n = n - 1
      
      turtle.exitonclick()

    7. #7
      Tham gia ngày
      22-06-2015
      Bài viết
      143
      Blog Entries
      1
      Cấp độ
      86
      Reps
      4253
      Được thì mình post doc nhé. @comtrends123

      Code:
      import numpy as np
      import math
      
      def rotate(direction, angle):
      	theta = np.radians(angle)
      	c, s = np.cos(theta), np.sin(theta)
      	R = np.matrix([[c, -s], [s, c]])
      	return np.round(np.squeeze(np.asarray(direction * R)))
      	
      def norm_vector(vector):
      	return vector / np.linalg.norm(vector,2)
      	
      def norm_dot(vector1, vector2):
      	return np.dot(vector1, vector2) / (np.linalg.norm(vector1,2) * np.linalg.norm(vector2,2))
      	
      def vector_angle(vector1, vector2):
      	return np.rad2deg(np.arccos(norm_dot(vector1, vector2)))
      
      class turtle:
      
      	def __init__(self, environment, position, is_clockwise, speed, max_laps):
      		self.position = np.array(position) #Global position
      		self.environment = environment
      		self.is_clockwise = is_clockwise #-1 for counter-clockwise, +1 for clockwise
      		self.turnUnit = self.environment.cangle * self.is_clockwise
      		self.preferred_position = self.prefer(self.environment.cdir)
      		self.direction = self.turn()
      		self.preferred_speed = speed
      		self.speed = self.preferred_speed
      		self.track = 0
      		self.laps = 0
      		self.max_laps = max_laps
      	
      	def turn(self):
      		return norm_vector(self.preferred_position - self.position)
      	
      	def moveForward(self):
      		return self.position + self.direction * self.speed
      		
      		
      	def prefer(self, preferred_position = None):
      		if preferred_position is None:
      			preferred_position = self.preferred_position
      		preferred_position = rotate(preferred_position, self.turnUnit)
      		return preferred_position
      		
      	def think2act(self):
      		if self.laps < self.max_laps:
      			if np.linalg.norm(self.preferred_position - self.position,2) < math.pow(10, -2):
      				self.track = self.track + 1
      				if self.track == self.environment.corner:
      					self.laps = self.laps + 1
      					self.track = -1
      					return 0
      				self.preferred_position = self.prefer()
      				print '---'
      				print self.preferred_position
      				print '---'
      				self.direction = self.turn()
      				self.speed = self.preferred_speed
      			elif np.linalg.norm(self.preferred_position - self.position,2) < np.linalg.norm(self.speed * self.direction, 2):
      				self.speed = np.linalg.norm(self.preferred_position - self.position,2) / np.linalg.norm(self.direction, 2)
      			self.position = self.moveForward()
      			return 1
      		else:
      			return -1
      		
      class environment:
      
      	def __init__(self, radius, corner):
      		self.center = np.array([0,0])
      		self.radius = radius
      		self.corner = corner
      		self.cangle = 360 / corner
      		self.cdir = self.center + np.array([0, self.radius])
      
      
      environment = environment(300, 3)
      turtle = turtle(environment, [0, 300], 1, 100, 3)
      for i in range(0,60):
      	result = turtle.think2act()
      	if result == 1:
      		print turtle.position
      	elif result == 0:
      		print 'completed a lap'
      	else:
      		print 'stopped'

    8. @Eva Rasta Cảm ơn cậu nhé

    9. #9
      Tham gia ngày
      22-06-2015
      Bài viết
      143
      Blog Entries
      1
      Cấp độ
      86
      Reps
      4253


      Lấy tâm đường tròn làm tâm hệ tọa độ, nhớ lại linear algebra, một điểm trên mặt phẳng cũng là một vector có đuôi là tâm tọa độ và có đầu mũi tên nằm ở điểm ấy. Do đó, turtle.position và turtle.preferred_position vừa đóng vai trò là một điểm, vừa đóng vai trò là một tọa độ. turtle.position là vị trí hiện tại của con rùa, turtle.preferred_position là vị trí của đỉnh tiếp theo của đa giác đều mà con rùa muốn chạy tới. turtle.preferred_position được tính bằng cách lần lượt rotate nó sang trái (với tham số angle âm) trong trường hợp muốn rùa di chuyển counter-clockwise, hoặc lần lượt rotate nó sang phải (với tham số angle dương) trong trường hợp muốn rùa di chuyển clockwise. Hướng di chuyển của rùa turtle.direction là một vector đơn vị có hướng là hướng của turtle.preferred_position - turtle.position.

      Một điểm lưu ý nhỏ là nếu set cứng cho turtle.speed thì lỡ như turtle.speed quá lớn, dẫn đến khi con rùa tới gần turtle.preferred_position thì vượt qua turtle.preferred_position luôn. Do đó, tớ đã chỉnh tốc độ của con rùa turtle.speed là động, còn tốc độ người dùng mong muốn là turtle.preferred_speed. Khi con rùa chưa tới gần turtle.preferred_position thì turtle.speed = turtle.preferred_speed, khi con rùa tới gần turtle.preferred_position rồi thì turtle.speed sẽ được chỉnh sao cho lần chạy kế tiếp con rùa sẽ chạm đúng turtle.preferred_position luôn chứ không bị trượt qua nữa.

      @comtrends123

    Đánh dấu

    Quyền viết bài

    • Bạn không thể đăng chủ đề mới
    • Bạn không thể gửi trả lời
    • Bạn không thể gửi đính kèm
    • Bạn không thể sửa bài
    •  

    Theo giờ GMT +7. Bây giờ là 00:41.

    Powered by vBulletin.
    Copyright© 2024 vBulletin Solutions, Inc. All rights reserved.
    Board of Management accepts no responsibility legal of any resources which is shared by members.