# Commits

committed 151783a

optimise line estimate error

• Participants
• Parent commits 10abcd8
• Branches circuit_sketch

# File linetools.py

` 	import psyco`
` 	psyco.full()`
` except ImportError:`
`-	pass`
`+	class Psyco(object):`
`+		def proxy(self, e):`
`+			return e`
`+	psyco = Psyco()`
` `
` __all__ += ["Point"]`
` class Point(object):`
` 	def __add__(self, other):`
` 		return Point(self.x+other.x, self.y+other.y, self.time+other.time)`
` `
`+	def __mul__(self, k):`
`+		"""`
`+			>>> Point(1,2,100)*3`
`+			<Point(3,6)@100.0s>`
`+		"""`
`+		return Point(self.x*k, self.y*k, self.time)`
`+`
` 	def __radd__(self, other):`
` 		if other == 0:`
` 			return self`
` 		return complex(self.x, self.y)`
` `
` 	def __str__(self):`
`-		return "<Point(%s,%s)@%ss>" % (self.x, self.y, self.time)`
`+		return "<Point(%s,%s)@%ss>" % (self.x, self.y, round(self.time, 1))`
` `
` 	def __repr__(self):`
` 		return str(self)`
` `
` @export`
` def points_features(points):`
`+	#~ times = [clock()]`
` 	features = []`
` 	## deviation from line, line-ness`
` 	other_points = points[:]`
` 	stop = other_points.pop(-1)`
` 	error_from_line = 0`
` 	len_of_estimated_line = start.distance_to(stop) or 1`
`+	v = (stop - start)`
` 	for point in other_points:`
` 		u = start.distance_to(point) / len_of_estimated_line`
`-		x = start.x + u*(stop - start).x`
`-		y = start.y + u*(stop - start).y`
`-		error_from_line += Point(x, y).distance_to(point)`
`+		p = start + v*u`
`+		error_from_line += p.distance_to(point)`
` 	if other_points:`
` 		error_from_line /= len(other_points)`
`+	#~ times.append(clock())`
` 	features.append(min(error_from_line / len_of_estimated_line, 2)) # normalize + upper bound`
` 	## segment`
`+	#~ times.append(clock())`
` 	features.append(min(Corner(points).error / len_of_estimated_line, 0.5)) # normalize + upper bound`
` 	## deviation from arc, arc-ness`
`+	#~ times.append(clock())`
` 	arc = points_to_arc(points)`
`+	#~ times.append(clock())`
` 	#~ features.append(arc.error)`
` 	## mean distance from primitive midpoint, circle-ness`
` 	features.append(mean(abs(arc.z.distance_to(p)-arc.r) for p in points) / arc.r) # normalize against radius`
` 	#~ features.append(curvature_len / len_of_estimated_line)`
` 	#~ print curvature_len / len_of_estimated_line,`
` 	#~ variations.append(curvature_len / len_of_estimated_line)`
`+	#~ times.append(clock())`
`+	#~ print [a-b for a, b in zip(times[1:], times[:-1])]`
`+	#~ print [t-times[0] for t in times]`
` 	return features`
` `
` def quick_hist(seq):`
` 		if not len_of_estimated_line: # zero length`
` 			bad_quality = True`
` 		else:`
`+			v = (stop - start)`
` 			for point in points:`
` 				u = start.distance_to(point) / start.distance_to(stop)`
`-				x = start.x + u*(stop - start).x`
`-				y = start.y + u*(stop - start).y`
`-				error += Point(x, y).distance_to(point)`
`+				p = start + v*u`
`+				error += p.distance_to(point)`
` 			if points:`
` 				error /= len(points)`
` 			if error > 10:`
` 	def snap_points(self):`
` 		"""`
` 			>>> Line(points=[Point(0,0,0), Point(5,5,0)]).snap_points()`
`-			[<Point(0,0)@0s>, <Point(2.5,2.5)@0.0s>, <Point(5,5)@0s>]`
`+			[<Point(0,0)@0.0s>, <Point(2.5,2.5)@0.0s>, <Point(5,5)@0.0s>]`
` `
` 		"""`
` 		start = self.points[0]`
` class Corner(Primitive):`
` 	def __init__(self, points):`
` 		if len(points) > 4:`
`-			error, x, line1, line2 = min(two_line_segment(points, x) for x in range(2, len(points)-2))`
`-			#~ print`
`-			#~ print 1 - abs(x - len(points)//2) / x,`
`+			#~ times = [clock()]`
`+			#~ print len(points)`
`+			#~ [x, two_line_segment(points, x)[0] for x in range(2, len(points)-2)]`
`+			error, x, line1, line2 = min(two_line_segment(points, x) for x in range(2, len(points)-2)) #XXX binary search needed`
`+			times.append(clock())`
` 			bad_quality = line1.bad_quality or line2.bad_quality \`
` 				or line1.intersection_with(line2).type not in ["V", "L"] \`
` 				or not (0.2 <= line1.curvature_len() / line2.curvature_len() <= 5)`
` 			points = line1.points + line2.points`
` 			self.line1 = line1`
` 			self.line2 = line2`
`+			#~ times.append(clock())`
`+			#~ print "c", [t-times[0] for t in times]`
` 		else:`
` 			error = Line(points).error`
` 			bad_quality = True`
` 	if full_circle:`
` 		result = Circle(points=new_points, bad_quality=bad_quality, error=normalized_avg_sqrd_residual)`
` 	else:`
`+		if Primitive(points).curvature_len() < 23: #XXX small arcs are more likely lines`
`+			bad_quality = True`
` 		result = Crescent(points=new_points, bad_quality=bad_quality, error=normalized_avg_sqrd_residual)`
` 	result.r = r`
` 	result.z = Point(z.real, z.imag)`
` @export`
` def symbol_midpoint(primitives):`
` 	"""`
`-		>>> symbol_midpoint([Line(points=[Point(0,0,0), Point(5,6,0)])])`
`-		<Point(2.5,3.0)@0.0s>`
`+		>>> symbol_midpoint([Line(points=[Point(0,0,0), Point(5,6,10)])])`
`+		<Point(2.5,3.0)@5.0s>`
` `
` 	"""`
` 	points = []`
` 	logging.root.setLevel(logging.INFO)`
` 	logging.basicConfig()`
` 	#~ System.host = "tablet"`
`-	primitive_recognition_accuracy()`
`+	#~ primitive_recognition_accuracy()`
` 	#~ draw_unrecognised_primitives()`
`-	save_primitive_examples_size()`
`+	#~ save_primitive_examples_size()`
`+	import profile`
`+	c = None`
`+	def f():`
`+		#~ print c`
`+		return 1`
`+	profile.run("f()")`