Seeing Is Believing
Tests notwithstanding, there’s both satisfaction and discovery in animating the linkage. So let’s do. (It works!!)
My plan this morning is to add an ArcRod to the linkage animation program and watch it perform. As things stand, we don’t have any of the methods needed to accomplish that, and there is the small matter of selecting which of the two possible solutions is the one that we want. My plan for now is to ignore that last bit and patch in the other methods, just to see what we see. As a side quest, we might consider adding graphics to FixedPoint, to identify places on the screen, such as the center of our so-far imaginary target for the ArcRod.
We need update, init_draw, and draw. I think I can probably type them in with little or no difficulty. (I could be wrong: we’ll find out shortly.)
I’ll move ArcRod over to the “src” side of things: importing will go better that way. The tests still run. Commit: move ArcRod to prod. Then …
class ArcRod:
def update(self, parent_start, parent_finish):
start, finish_1, finish_2 = self.update_both(parent_finish)
return start, finish_1
def init_draw(self, canvas, start, finish):
self._cached_line = canvas.create_line(
start.x, start.y,
finish.x, finish.y,
width=4, fill="blue"
)
def draw(self, canvas, start, finish):
canvas.coords(self._cached_line,
start.x, start.y,
finish.x, finish.y)
That’s surely enough to break. Now I need to put one into the drawing linkage.
It takes a bit of doing, because I want to draw a target wheel. Here’s the added code in the drawing main program:
bell_pos = vector(6, 8)
bell_point = FixedPoint(bell_pos)
components.add(bell_point, None)
bell_crank = Wheel()
components.add(bell_crank, bell_point)
arc_crank = Crank(radius=0.5)
components.add(arc_crank, wheel)
arc_rod = ArcRod(length=5, target_position=bell_pos, target_radius=0.5)
components.add(arc_rod, arc_crank)
components.apply(lambda c, s, f: c.init_draw(canvas, s, f))
Mysteriously, once I set the target_radius to 0.75 instead of 2, we get this result:
It’s working as intended! I note that the positioning of the target is critical, probably should be at the center of the main driving crank plus the length of the ArcRod. And the radius needs to be somewhat larger than the driving crank radius, also 0.5 in our case. If the target radius is equal to or smaller than the driving crank radius, the ArcRod could bind or go around the other way. That would be bad.
But, delightfully, it is working. We still need to provide a way to select which solution is to be used: had I selected the second, the rod would have been to the right of the target rather than the left. (Yes, I did check that.)
When I first set the drawing up, I had accepted a 2 as the radius, and the drawing was, of course, quite wrong, with the rod well off to the left. I was afraid that something was terribly wrong, but then noticed that PyCharm had provided me with the wrong value.
Well, my bad. I’m supposed to be paying attention. It’s not their fault that they offered me that choice and I accepted it.
Point is, it’s working! Callooh! Callay! I am pleased. Good news on a rainy Sunday morning.
See you next time!