11import mcpi .minecraft as minecraft
2- # import mcpi.block as block
2+ import mcpi .block as block
33from mcpi .block import *
44from mcpi .entity import *
55import time
66from math import *
77import server
88
99class Turtle :
10+ TO_RADIANS = pi / 180.
11+ TO_DEGREES = 180. / pi
12+
1013 def __init__ (self ,mc = None ):
1114 if mc :
1215 self .mc = mc
@@ -16,7 +19,6 @@ def __init__(self,mc=None):
1619 self .width = 1
1720 self .pen = True
1821 self .directionIn ()
19- self .pitch = 0
2022 self .positionIn ()
2123 self .delayTime = 0.05
2224 self .nib = []
@@ -66,11 +68,13 @@ def goto(self,x,y,z):
6668 self .delay ()
6769
6870 def verticalangle (self ,angle ):
69- self .pitch = - angle
71+ angles = self .getMinecraftAngles ();
72+ self .matrix = Turtle .matrixMultiply (Turtle .yawMatrix (angles [0 ]), Turtle .pitchMatrix (angle ))
7073 self .directionOut ()
7174
7275 def angle (self ,angle ):
73- self .rotation = - angle
76+ angles = self .getMinecraftAngles ()
77+ self .matrix = Turtle .matrixMultiply (Turtle .yawMatrix (angle ), Turtle .pitchMatrix (angles [1 ]))
7478 self .directionOut ()
7579
7680 def penup (self ):
@@ -94,25 +98,76 @@ def delay(self):
9498 time .sleep (self .delayTime )
9599
96100 def directionIn (self ):
97- self .rotation = self .mc .player .getRotation ()
98- self .pitch = self .mc .player .getPitch ()
101+ rotation = self .mc .player .getRotation ()
102+ pitch = 0 #self.mc.player.getPitch()
103+ self .matrix = Turtle .matrixMultiply (Turtle .yawMatrix (rotation ), Turtle .pitchMatrix (- pitch ))
99104
100- def directionOut (self ):
101- self .pitch %= 360.
102- self .rotation %= 360
105+ @staticmethod
106+ def matrixMultiply (a ,b ):
107+ c = [[0 ,0 ,0 ],[0 ,0 ,0 ],[0 ,0 ,0 ]]
108+ for i in range (3 ):
109+ for j in range (3 ):
110+ c [i ][j ] = a [i ][0 ]* b [0 ][j ] + a [i ][1 ]* b [1 ][j ] + a [i ][2 ]* b [2 ][j ]
111+ return c
103112
104- if self .turtleType :
105- pitch = self .pitch
106- rotation = self .rotation
113+ @staticmethod
114+ def yawMatrix (angleDegrees ):
115+ theta = angleDegrees * Turtle .TO_RADIANS
116+ return [[cos (theta ), 0 , - sin (theta )],
117+ [0 , 1 , 0 ],
118+ [sin (theta ), 0 , cos (theta )]]
119+
120+ @staticmethod
121+ def rollMatrix (angleDegrees ):
122+ theta = angleDegrees * Turtle .TO_RADIANS
123+ return [[cos (theta ), - sin (theta ), 0. ],
124+ [sin (theta ), cos (theta ),0. ],
125+ [0. , 0. , 1. ]]
126+
127+ @staticmethod
128+ def pitchMatrix (angleDegrees ):
129+ theta = angleDegrees * Turtle .TO_RADIANS
130+ return [[1 , 0 , 0 ],
131+ [0 , cos (theta ),sin (theta )],
132+ [0 , - sin (theta ),cos (theta )]]
133+
134+ def yaw (self ,angleDegrees ):
135+ self .matrix = Turtle .matrixMultiply (self .matrix , Turtle .yawMatrix (angleDegrees ))
136+ self .directionOut ()
137+ self .delay ()
107138
108- if pitch >= 270 :
109- pitch = pitch - 360.
110- elif pitch >= 90 :
111- pitch = 180. - pitch
112- rotation = (rotation + 180. ) % 360.
139+ def roll (self ,angleDegrees ):
140+ self .matrix = Turtle .matrixMultiply (self .matrix , Turtle .rollMatrix (angleDegrees ))
141+ self .directionOut ()
142+ self .delay ()
113143
114- self .mc .entity .setRotation (self .turtleId , rotation )
115- self .mc .entity .setPitch (self .turtleId , pitch )
144+ def pitch (self ,angleDegrees ):
145+ self .matrix = Turtle .matrixMultiply (self .matrix , Turtle .pitchMatrix (angleDegrees ))
146+ self .directionOut ()
147+ self .delay ()
148+
149+ def getHeading (self ):
150+ return [self .matrix [0 ][2 ],self .matrix [1 ][2 ],self .matrix [2 ][2 ]]
151+
152+ def getMinecraftAngles (self ):
153+ heading = self .getHeading ()
154+ xz = sqrt (heading [0 ]* heading [0 ] + heading [2 ]* heading [2 ])
155+ if xz >= 1e-9 :
156+ rotation = atan2 (- heading [0 ], heading [2 ]) * Turtle .TO_DEGREES
157+ else :
158+ rotation = 0
159+ pitch = atan2 (- heading [1 ], xz ) * Turtle .TO_DEGREES
160+ return [rotation ,pitch ]
161+
162+ def directionOut (self ):
163+ if self .turtleType :
164+ heading = self .getHeading ()
165+ xz = sqrt (heading [0 ]* heading [0 ] + heading [2 ]* heading [2 ])
166+ if xz >= 1e-9 :
167+ rotation = atan2 (- heading [0 ], heading [2 ]) * Turtle .TO_DEGREES
168+ self .mc .entity .setRotation (self .turtleId ,rotation )
169+ pitch = atan2 (- heading [1 ], xz ) * Turtle .TO_DEGREES
170+ self .mc .entity .setPitch (self .turtleId ,pitch )
116171
117172 def pendelay (self , t ):
118173 self .delayTime = t
@@ -121,24 +176,24 @@ def left(self, angle):
121176 self .right (- angle )
122177
123178 def right (self , angle ):
124- self .rotation += angle
179+ self .matrix = Turtle . matrixMultiply ( Turtle . yawMatrix ( angle ), self . matrix )
125180 self .directionOut ()
126181 self .delay ()
127182
128183 def up (self , angle ):
129- self .pitch -= angle
130- self .directionOut ()
131- self .delay ()
184+ self .pitch (angle )
132185
133186 def down (self , angle ):
134187 self .up (- angle )
135188
136189 def go (self , distance ):
137- pitch = self .pitch * pi / 180.
138- rot = self .rotation * pi / 180.
139- dx = cos (- pitch ) * sin (- rot )
140- dy = sin (- pitch )
141- dz = cos (- pitch ) * cos (- rot )
190+ # pitch = self.pitch * pi/180.
191+ # rot = self.rotation * pi/180.
192+ # at pitch=0: rot=0 -> [0,0,1], rot=90 -> [-1,0,0]
193+ # dx = cos(-pitch) * sin(-rot)
194+ # dy = sin(-pitch)
195+ # dz = cos(-pitch) * cos(-rot)
196+ [dx ,dy ,dz ] = self .getHeading ()
142197 newX = self .position .x + dx * distance
143198 newY = self .position .y + dy * distance
144199 newZ = self .position .z + dz * distance
@@ -151,14 +206,15 @@ def go(self, distance):
151206 self .delay ()
152207
153208 def back (self , distance ):
154- pitch = self .pitch * pi / 180.
155- rot = self .rotation * pi / 180.
156- dx = - cos (- pitch ) * sin (- rot )
157- dy = - sin (- pitch )
158- dz = - cos (- pitch ) * cos (- rot )
159- newX = self .position .x + dx * distance
160- newY = self .position .y + dy * distance
161- newZ = self .position .z + dz * distance
209+ # pitch = self.pitch * pi/180.
210+ # rot = self.rotation * pi/180.
211+ # dx = - cos(-pitch) * sin(-rot)
212+ # dy = - sin(-pitch)
213+ # dz = - cos(-pitch) * cos(-rot)
214+ [dx ,dy ,dz ] = self .getHeading ()
215+ newX = self .position .x - dx * distance
216+ newY = self .position .y - dy * distance
217+ newZ = self .position .z - dz * distance
162218 self .drawLine (self .position .x , self .position .y , self .position .z ,
163219 newX , newY , newZ )
164220 self .position .x = newX
@@ -253,13 +309,10 @@ def drawLine(self, x1, y1, z1, x2, y2, z2):
253309
254310if __name__ == "__main__" :
255311 t = Turtle ()
256- t .pendelay (0.01 )
257- t .penwidth (1 )
258- t .penblock (GLASS )
312+ t .pendelay (0.05 )
313+ t .penblock (GOLD_BLOCK )
259314 t .turtle (HORSE )
260315 for i in range (7 ):
261- print i
262- t .go (100 )
263- t .right (180.0 - 180. / 7 )
264- t .penup ()
316+ t .go (60 )
317+ t .up (180 - 180 / 7 )
265318 t .turtle (None )
0 commit comments