diff options
author | pmoxhay <pmoxhay@earthlink.net> | 2009-06-13 17:33:15 (GMT) |
---|---|---|
committer | pmoxhay <pmoxhay@earthlink.net> | 2009-06-13 17:33:15 (GMT) |
commit | f23bde5a91cdf55984fdb3a64925105fe8a7343b (patch) | |
tree | 15e92339b71e109b1a81f37a34c63d44aff75cec | |
parent | 5e5abae72e478177712260e2e4a23a04fe76aaa8 (diff) |
Fixed bug: now avoids spurious length comparisons.
-rw-r--r-- | TODO | 11 | ||||
-rw-r--r-- | lengthproblem.py | 171 |
2 files changed, 174 insertions, 8 deletions
@@ -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' |