Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpmoxhay <pmoxhay@earthlink.net>2009-06-13 17:33:15 (GMT)
committer pmoxhay <pmoxhay@earthlink.net>2009-06-13 17:33:15 (GMT)
commitf23bde5a91cdf55984fdb3a64925105fe8a7343b (patch)
tree15e92339b71e109b1a81f37a34c63d44aff75cec
parent5e5abae72e478177712260e2e4a23a04fe76aaa8 (diff)
Fixed bug: now avoids spurious length comparisons.
-rw-r--r--TODO11
-rw-r--r--lengthproblem.py171
2 files changed, 174 insertions, 8 deletions
diff --git a/TODO b/TODO
index c7c8eea..8d352eb 100644
--- a/TODO
+++ b/TODO
@@ -2,21 +2,21 @@ Math
General
+ Improve overall performance.
++ Make something happen when progress is completed successfully.
+ Improve user feedback for Drag & Drop via keyboard.
- Progress only when right answer is given (detect errors).
- Fix bug: line segment drop area sometimes stays highlighted.
++ Fix bug: line segment drop targets incorrectly highlighted when moving by key press.
+ Add sound effects.
-+ Improve images of faucet, balance, scissors
-+ Animate pouring of water, cutting by scissors, maybe motion of balance.
-+ Tools (scissors, balance, faucet) selectable from a menu?
++ Improve images of faucet, balance, scissors.
++ Animate pouring of water, maybe also cutting by scissors and motion of balance.
++ Tools (scissors, balance, faucet) also selectable from a menu.
Compare3 Lesson
- Control movement from one problem type to another.
- Don't repeat colors or letters from one problem to the next.
- Don't repeat recently used problems.
- Add more problems for some comparisons.
-+ Make something happen when progress is completed successfully.
-+ Display intersection between Shapes in a different color? IntersectionObject maybe?
- Mass comparison: fit into answer box.
- Fix drawing of mass parallelopipeds (ThreeDObjects).
- Fix behavior of line segments (drops getting rejected).
@@ -24,4 +24,5 @@ Compare3 Lesson
- Amount comparison: fit into answer box (maybe make wider and reposition).
- Amount comparison: refine appearance of object groups.
- Amount comparison: refine appearance of model (make pagelike).
++ Fix bug: length comparisons can give spurious correct result when lengths touch end-to-end, or overlap completely.
diff --git a/lengthproblem.py b/lengthproblem.py
index 3c503e4..9b1aa7d 100644
--- a/lengthproblem.py
+++ b/lengthproblem.py
@@ -95,7 +95,7 @@ class LengthProblem(Problem):
self.problem_number = random.randrange(0, self.n_problems)
# Uncomment to test a particular problem.
- #problem_number = 3
+ self.problem_number = 3
# Define the various problems.
if self.problem_number == 0:
@@ -223,12 +223,76 @@ class LengthProblem(Problem):
new_vectors = [v.scaled(0.8) for v in vectors]
return new_vectors
+ def is_shape_1_vertical(self):
+ if abs(self.shape1.angle % math.pi) < 0.01:
+ return True
+ else :
+ return False
+
+ def is_shape_1_horizontal(self):
+ if abs((self.shape1.angle + math.pi/2.) % math.pi) < 0.01:
+ return True
+ else :
+ return False
+
+ def is_shape_2_vertical(self):
+ if abs(self.shape2.angle % math.pi) < 0.01:
+ return True
+ else :
+ return False
+
+ def is_shape_2_horizontal(self):
+ if abs((self.shape2.angle + math.pi/2.) % math.pi) < 0.01:
+ return True
+ else :
+ return False
+
def check_problem_solved(self):
+ #print ""
#print "Length Problem: check_problem_solved called"
# Make sure the two ShapeObjects both have four points.
if len(self.shape1.points) != 4 or len(self.shape2.points) != 4:
return False
+ # What are the angles?
+ #angle1 = self.shape1.angle
+ #angle1_mod_pi = angle1 % (math.pi)
+ #print "angle1 =",angle1
+ #print "angle1_mod_pi =",angle1_mod_pi
+ #angle2 = self.shape2.angle
+ #angle2_mod_pi = angle2 % (math.pi)
+ #print "angle2 =",angle2
+ #print "angle2_mod_pi =",angle2_mod_pi
+ #
+ #if abs(angle1_mod_pi_over_2) > 0.01 or abs(angle2_mod_pi_over_2) > 0.01:
+ # print "rejected because length is neither horizontal nor vertical"
+ # return False
+
+ b_ver1 = self.is_shape_1_vertical()
+ b_hor1 = self.is_shape_1_horizontal()
+
+ #if b_ver1:
+ # print "Shape", self.shape1.symbol,"is vertical"
+ #elif b_hor1:
+ # print "Shape", self.shape1.symbol,"is horizontal"
+
+ b_ver2 = self.is_shape_2_vertical()
+ b_hor2 = self.is_shape_2_horizontal()
+
+ #if b_ver2:
+ # print "Shape", self.shape2.symbol,"is vertical"
+ #elif b_hor2:
+ # print "Shape", self.shape2.symbol,"is horizontal"
+
+ #if b_ver1 and b_ver2:
+ # print "Both shapes are vertical"
+ #if b_hor1 and b_hor2:
+ # print "Both shapes are vertical"
+
+ if (not (b_ver1 and b_ver2)) and (not (b_hor1 and b_hor2)):
+ #print "Shapes are neither both vertical nor both horizontal."
+ return False
+
# First, find out how many points coincide.
p0 = self.shape1.points
p0 = [self.shape1.transform_point(p) for p in p0]
@@ -246,6 +310,7 @@ class LengthProblem(Problem):
p0 = sorted(p0, cmp=sort_points_arbitrarily)
p1 = sorted(p1, cmp=sort_points_arbitrarily)
+ coords_of_equal_points = []
n_equal = 0
for i in range(0,len(p0)):
for j in range(0,len(p1)):
@@ -253,16 +318,116 @@ class LengthProblem(Problem):
#print "p1[j] =", p1[j]
if p0[i].approx_equal(p1[j]):
n_equal += 1
+ coords_of_equal_points.append(p0[i])
+
#print "n_equal =", n_equal
+ #for i in range (0, len(coords_of_equal_points)):
+ # print "coords_of_equal_points =",coords_of_equal_points[i]
if self.answer == 'equal' and n_equal == 2:
- return True
+ #print "distance between equal points =",(coords_of_equal_points[0] - coords_of_equal_points[1]).length()
+ # Problem not solved if length are compared end-to-end.
+ if (coords_of_equal_points[0] - coords_of_equal_points[1]).length() < 55:
+ return False
+ else:
+ return True
elif (self.answer == 'less' or self.answer == 'greater') and n_equal == 1:
- return True
+ if b_ver1 and b_ver2:
+ if self.are_y_bounds_correct():
+ return True
+ elif b_hor1 and b_hor2:
+ if self.are_x_bounds_correct():
+ return True
return False
+ def are_x_bounds_correct(self):
+ shape_1_x_bounds = self.shape1.bounds_min.x, self.shape1.bounds_max.x
+ shape_2_x_bounds = self.shape2.bounds_min.x, self.shape2.bounds_max.x
+ tolerance = 5
+
+ # Does shape2 fit horizontally within shape 1?
+ if shape_2_x_bounds[0] >= shape_1_x_bounds[0] - tolerance and shape_2_x_bounds[1] <= shape_1_x_bounds[1] + tolerance:
+ return True
+ # Does shape2 fit horizontally within shape 2?
+ elif shape_1_x_bounds[0] >= shape_2_x_bounds[0] - tolerance and shape_1_x_bounds[1] <= shape_2_x_bounds[1] + tolerance:
+ return True
+ else:
+ return False
+
+ # Test whether two vertical shapes are aligned correctly for a comparison.
+ def are_y_bounds_correct(self):
+ shape_1_y_bounds = self.shape1.bounds_min.y, self.shape1.bounds_max.y
+ shape_2_y_bounds = self.shape2.bounds_min.y, self.shape2.bounds_max.y
+ tolerance = 5
+
+ # Does shape2 fit vertically within shape 1?
+ if shape_2_y_bounds[0] >= shape_1_y_bounds[0] - tolerance and shape_2_y_bounds[1] <= shape_1_y_bounds[1] + tolerance:
+ return True
+ # Does shape2 fit vertically within shape 2?
+ elif shape_1_y_bounds[0] >= shape_2_y_bounds[0] - tolerance and shape_1_y_bounds[1] <= shape_2_y_bounds[1] + tolerance:
+ return True
+ else:
+ return False
+
+ #def point_of_one_shape_lies_on_side_of_the_other(self):
+ # # Fill a list with the sides of shape 1.
+ # sides = []
+ # for m in range(0, len(self.shape1.points) - 1):
+ # sides.append( (self.shape1.points[m], self.shape1.points[m + 1]) )
+ # sides.append( (self.shape1.points[len(self.shape1.points) - 1], self.shape1.points[0]) )
+ #
+ # # Check whether a point of shape 2 lies on a side of shape 1.
+ # for i in range(0, len(self.shape2.points) - 1):
+ # for j in range(0, len(sides)):
+ # dist = self.distance_point_from_line(self.shape2.points[i], sides[j])
+ # if dist < 0.01 and self.is_between_end_points(self.shape2.points[i], sides[j]):
+ # return True
+ #
+ # # Fill a list with the sides of shape 2.
+ # sides = []
+ # for m in range(0, len(self.shape2.points) - 1):
+ # sides.append( (self.shape2.points[m], self.shape1.points[m + 1]) )
+ # sides.append( (self.shape2.points[len(self.shape2.points) - 1], self.shape2.points[0]) )
+ #
+ # # Check whether a point of shape 1 lies on a side of shape 2.
+ # for i in range(0, len(self.shape1.points) - 1):
+ # for j in range(0, len(sides)):
+ # dist = self.distance_point_from_line(self.shape1.points[i], sides[j])
+ # if dist < 0.01 and self.is_between_end_points(self.shape1.points[i], sides[j]):
+ # return True
+ #
+ # return False
+
+ #def is_between_end_points(self, point, (point0, point1)):
+ # if point1.x > point0.x:
+ # if point.x > point0.x and point.x < point1.x:
+ # return True
+ # else:
+ # return False
+ # elif point1.x < point0.x:
+ # if point.x > point1.x and point.x < point0.x:
+ # return True
+ # else:
+ # return False
+ # else:
+ # if point1.y > point0.y:
+ # if point.y > point0.y and point.y < point1.y:
+ # return True
+ # elif point1.y < point0.y:
+ # if point.y > point1.y and point.y < point0.y:
+ # return True
+ # else:
+ # return False
+ #
+ # return False
+ #
+ #def distance_point_from_line(self, point, (point0, point1)):
+ # dist = abs( ( (point0.y - point1.y)*point.x + (point1.x - point0.x)*point.y + (point0.x*point1.y - point1.x*point0.y)) \
+ # / math.sqrt( (point1.x - point0.x) ** 2 + (point1.y - point0.y) ** 2) )
+ # return dist
+
def find_answer(self):
if self.shape1.area > self.shape2.area:
self.answer = 'greater'