Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@sugarlabs.org>2014-03-13 04:22:12 (GMT)
committer Walter Bender <walter@sugarlabs.org>2014-03-13 04:22:12 (GMT)
commitf7eddc6b7f2f72b714fef5acbea43f94ff09d6db (patch)
tree3d97b5293535580987ce607b95718eb9dc5ef287
parent2b550f18b8c12304fca1f7601a6e5a934990c000 (diff)
more work on pitch and yaw3d
-rwxr-xr-xTurtleArt/tasprite_factory.py26
-rw-r--r--TurtleArt/taturtle.py117
-rw-r--r--activity/activity.info2
-rw-r--r--plugins/threed/threed.py56
4 files changed, 190 insertions, 11 deletions
diff --git a/TurtleArt/tasprite_factory.py b/TurtleArt/tasprite_factory.py
index 21777df..0e1dd18 100755
--- a/TurtleArt/tasprite_factory.py
+++ b/TurtleArt/tasprite_factory.py
@@ -20,6 +20,26 @@
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
+'''
+The basic idea is to generate SVG for the various blocks used in
+Turtle Art and a few other things, like the turtle itself. There is an
+SVG class and then lots of properties to manipulate.
+
+There are several different classes of shapes and a comment set of
+attributes thfor example, there are methods to generate corners, tabs
+and slots for vertical docking of blocks, "innies" and "outies" for
+horizontal docking of blocks, "clamps" for nesting blocks.
+
+Two additional complexities are expandable regions and dock positions:
+there are regions within some blocks that expand so that the block can
+grow in one dimension without distorting, so, for example, the clamp
+in a repeat block can grow (or shrink) to accommodate the nesting of a
+larger or smaller stack of blocks to repeat; dock positions are used
+to keep track of the absolute position of the tabs, slots, innies and
+outies so that the method that does the docking knows where to
+position blocks.
+'''
+
import pygtk
pygtk.require('2.0')
import gtk
@@ -1494,6 +1514,7 @@ def generator(datapath):
f.write(svg_str)
close_file(f)
+ '''
svg = SVG()
f = open_file(datapath, "clamp.svg")
svg.set_scale(2)
@@ -1504,8 +1525,8 @@ def generator(datapath):
svg_str = svg.clamp()
f.write(svg_str)
close_file(f)
- '''
+ '''
svg = SVG()
f = open_file(datapath, "clampn.svg")
svg.set_scale(2)
@@ -1518,7 +1539,6 @@ def generator(datapath):
f.write(svg_str)
close_file(f)
- '''
svg = SVG()
f = open_file(datapath, "clampe.svg")
svg.set_scale(2)
@@ -1530,7 +1550,6 @@ def generator(datapath):
svg_str = svg.clamp()
f.write(svg_str)
close_file(f)
- '''
svg = SVG()
f = open_file(datapath, "clampb.svg")
@@ -1555,6 +1574,7 @@ def generator(datapath):
svg_str = svg.clamp_until()
f.write(svg_str)
close_file(f)
+ '''
def main():
diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py
index ccdd60b..bf3e152 100644
--- a/TurtleArt/taturtle.py
+++ b/TurtleArt/taturtle.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-#Copyright (c) 2010-13 Walter Bender
+#Copyright (c) 2010-14 Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -26,7 +26,7 @@ import gobject
import cairo
from random import uniform
-from math import sin, cos, pi, sqrt
+from math import sin, cos, pi, sqrt, radians
from taconstants import (TURTLE_LAYER, DEFAULT_TURTLE_COLORS, DEFAULT_TURTLE,
CONSTANTS, Color, ColorObj)
from tasprite_factory import SVG, svg_str_to_pixbuf
@@ -147,6 +147,8 @@ class Turtles:
self._active_turtle.set_z_scale = 20.
self._active_turtle.reset_shapes()
self._active_turtle.set_heading(0.0)
+ self._active_turtle.set_pitch(0.0)
+ self._active_turtle.set_yaw(0.0)
self._active_turtle.set_pen_state(False)
self._active_turtle.move_turtle((0.0, 0.0))
self._active_turtle.set_z(0.0)
@@ -183,12 +185,34 @@ class Turtles:
raise logoerror("#syntaxerror")
return self.dict[turtle_name].get_heading()
+ def get_turtle_roll(self, turtle_name):
+ ''' Rotate about z axis '''
+ return self.get_turtle_heading(turtle_name)
+
+ def get_turtle_pitch(self, turtle_name):
+ ''' Rotate about x axis '''
+ if turtle_name not in self.dict:
+ debug_output('%s not found in turtle dictionary' % (turtle_name),
+ self.turtle_window.running_sugar)
+ raise logoerror("#syntaxerror")
+ return self.dict[turtle_name].get_pitch()
+
+ def get_turtle_yaw(self, turtle_name):
+ ''' Rotate about y axis '''
+ if turtle_name not in self.dict:
+ debug_output('%s not found in turtle dictionary' % (turtle_name),
+ self.turtle_window.running_sugar)
+ raise logoerror("#syntaxerror")
+ return self.dict[turtle_name].get_yaw()
+
def set_turtle(self, turtle_name, colors=None):
''' Select the current turtle and associated pen status '''
if turtle_name not in self.dict:
# if it is a new turtle, start it in the center of the screen
self._active_turtle = self.get_turtle(turtle_name, True, colors)
self._active_turtle.set_heading(0.0, False)
+ self._active_turtle.set_pitch(0.0, False)
+ self._active_turtle.set_yaw(0.0, False)
self._active_turtle.set_xyz(0.0, 0.0, 0.0,
share=False, pendown=False)
self._active_turtle.set_pen_state(True)
@@ -233,7 +257,9 @@ class Turtle:
self._y = 0.0
self._z = 0.0
self._z_scale = 100.
- self._heading = 0.0
+ self._heading = 0.0 # roll
+ self._pitch = 0.0
+ self._yaw = 0.0
self._half_width = 0
self._half_height = 0
self._drag_radius = None
@@ -373,8 +399,31 @@ class Turtle:
round_int(self._heading)]))
self._turtles.turtle_window.send_event(event)
+ def set_pitch(self, pitch, share=True):
+ ''' Set the turtle pitch '''
+ self._pitch = pitch
+ self._pitch %= 360
+
+ # TODO: setup sharing
+ # if self._turtles.turtle_window.sharing() and share:
+ # event = 'r|%s' % (data_to_string(
+ # [self._turtles.turtle_window.nick, round_int(self._pitch)]))
+ # self._turtles.turtle_window.send_event(event)
+
+ def set_yaw(self, yaw, share=True):
+ ''' Set the turtle yaw '''
+ self._yaw = yaw
+ self._yaw %= 360
+
+ # TODO: setup sharing
+ # if self._turtles.turtle_window.sharing() and share:
+ # event = 'r|%s' % (data_to_string(
+ # [self._turtles.turtle_window.nick, round_int(self._yaw)]))
+ # self._turtles.turtle_window.send_event(event)
+
def _update_sprite_heading(self):
''' Update the sprite to reflect the current heading '''
+ # TODO: add sprites for pitch and yaw
i = (int(self._heading + 5) % 360) / (360 / SHAPES)
if not self._hidden and self.spr is not None:
try:
@@ -566,6 +615,39 @@ class Turtle:
self._poly_points.append(('move', pos1[0], pos1[1]))
self._poly_points.append(('line', pos2[0], pos2[1]))
+ def _apply_roll(self):
+ temp = []
+ theta = radians(self._heading)
+ temp.append(self._direction[0] * 1.0)
+ temp.append((self._direction[1] * cos(theta)) +
+ (self._direction[2] * sin(theta)))
+ temp.append((self._direction[1] * -1.0 * sin(theta)) +
+ (self._direction[2] * cos(theta)))
+ self._direction = temp
+ print 'after roll', self._direction
+
+ def _apply_pitch(self):
+ temp = []
+ theta = radians(self._pitch)
+ temp.append((self._direction[0] * cos(theta)) +
+ (self._direction[2] * -1.0 * sin(theta)))
+ temp.append(self._direction[1] * 1.0)
+ temp.append((self._direction[0] * sin(theta)) +
+ (self._direction[2] * cos(theta)))
+ self._direction = temp
+ print 'after pitch', self._direction
+
+ def _apply_yaw(self):
+ temp = []
+ theta = radians(self._yaw)
+ temp.append((self._direction[0] * cos(theta)) +
+ (self._direction[1] * sin(theta)))
+ temp.append((self._direction[0] * -1.0 * sin(theta)) +
+ (self._direction[1] * cos(theta)))
+ temp.append(self._direction[2] * 1.0)
+ self._direction = temp
+ print 'after yaw', self._direction
+
def forward(self, distance, share=True):
scaled_distance = distance * self._turtles.turtle_window.coord_scale
@@ -573,11 +655,23 @@ class Turtle:
if self._z > 0.0:
old[0] = old[0] * ((self._z / self._z_scale) + 1)
old[1] = old[1] * ((self._z / self._z_scale) + 1)
+ old.append(self._z)
+
+ roll = self._heading * DEGTOR # roll
+ if self._pitch != 0.0 or self._yaw != 0.0:
+ self._direction = [1.0, 0.0, 0.0]
+ self._apply_pitch()
+ self._apply_yaw()
+ self._apply_roll()
+ xcor = old[0] + scaled_distance * self._direction[0]
+ ycor = old[1] + scaled_distance * self._direction[1]
+ zcor = old[2] + scaled_distance * self._direction[2]
+ else:
+ xcor = old[0] + scaled_distance * sin(roll)
+ ycor = old[1] + scaled_distance * cos(roll)
+ zcor = old[2]
- xcor = old[0] + scaled_distance * sin(self._heading * DEGTOR)
- ycor = old[1] + scaled_distance * cos(self._heading * DEGTOR)
-
- self.set_xy(xcor, ycor, share)
+ self.set_xyz(xcor, ycor, zcor, share)
if self._turtles.turtle_window.sharing() and share:
event = 'f|%s' % (data_to_string([self._turtles.turtle_window.nick,
@@ -770,6 +864,15 @@ class Turtle:
def get_heading(self):
return self._heading
+ def get_roll(self):
+ return self._heading
+
+ def get_pitch(self):
+ return self._pitch
+
+ def get_yaw(self):
+ return self._yaw
+
def get_color(self):
return self._pen_color
diff --git a/activity/activity.info b/activity/activity.info
index 3f01003..35e24e6 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,6 +1,6 @@
[Activity]
name = TurtleBlocks
-activity_version = 199
+activity_version = 199.3
license = MIT
bundle_id = org.laptop.TurtleArtActivity
exec = sugar-activity TurtleArtActivity.TurtleArtActivity
diff --git a/plugins/threed/threed.py b/plugins/threed/threed.py
index 7cb303b..5a37856 100644
--- a/plugins/threed/threed.py
+++ b/plugins/threed/threed.py
@@ -71,6 +71,56 @@ class Threed(Plugin):
ArgSlot(TYPE_NUMBER)],
call_afterwards=self.after_move))
+ palette.add_block('setp',
+ style='basic-style-1arg',
+ label=_('set pitch'),
+ prim_name='setp',
+ default=0,
+ help_string=_('sets the pitch of the turtle (0 is \
+towards the center of the screen (the horizon).)'))
+ self.tw.lc.def_prim(
+ 'setp', 1,
+ Primitive(Turtle.set_pitch,
+ arg_descs=[ArgSlot(TYPE_NUMBER)],
+ call_afterwards=lambda value: self.after_set(
+ 'pitch', value)))
+
+ palette.add_block('setw',
+ style='basic-style-1arg',
+ label=_('set yaw'),
+ prim_name='setw',
+ default=0,
+ help_string=_('sets the yaw of the turtle (0 is \
+perpendicular to the plane of the screen.)'))
+ self.tw.lc.def_prim(
+ 'setw', 1,
+ Primitive(Turtle.set_pitch,
+ arg_descs=[ArgSlot(TYPE_NUMBER)],
+ call_afterwards=lambda value: self.after_set(
+ 'yaw', value)))
+
+ palette.add_block('pitch_',
+ style='box-style',
+ label=_('pitch'),
+ help_string=_('holds current pitch value of the \
+turtle (can be used in place of a number block)'),
+ value_block=True,
+ prim_name='pitch_')
+ self.tw.lc.def_prim('pitch', 0,
+ Primitive(
+ Turtle.get_pitch, return_type=TYPE_NUMBER))
+
+ palette.add_block('yaw',
+ style='box-style',
+ label=_('yaw'),
+ help_string=_('holds current yaw value of the \
+turtle (can be used in place of a number block)'),
+ value_block=True,
+ prim_name='yaw')
+ self.tw.lc.def_prim('yaw', 0,
+ Primitive(
+ Turtle.get_yaw, return_type=TYPE_NUMBER))
+
def after_move(self, *ignored_args, **ignored_kwargs):
''' Update labels after moving the turtle '''
if self.tw.lc.update_values:
@@ -86,3 +136,9 @@ class Threed(Plugin):
'zcor',
self.tw.turtles.get_active_turtle().get_xyz()[2] /
self.tw.coord_scale)
+
+ def after_set(self, name, value=None):
+ ''' Update the associated value blocks '''
+ if value is not None:
+ if self.tw.lc.update_values:
+ self.tw.lc.update_label_value(name, value)