2013-06-02

Canvas Wipers

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks

Canvas Wipers

The inspiration for this animation came from a wiki page about windscreen wipers. In short, there is one central motor and both wipers are connected to it. The motion range of a single wiper is influenced by the positioning, linkage length and leaver radius. The real wipers contain a lot more parts than this abstracted version does, but none the less, it makes for a pretty interesting animation. Getting all the lengths and positions for elements in this animation was the hacky part of the whole story and this blog entry won't be about that.

Motor to leaver

The motor arm has two linkages connected to the leavers of both wipers. Determining the motor arm position is pretty straight forward and we only need the sin and cos function to do that. But connecting the linkages to wiper leavers requires a bit more math. Basically the motor arm position becomes center of a circle with a radius equal to the length of a linkage. The second circle is the one with the wiper body screw in the center and a radius equal to the wiper leaver length. The leaver and then the wiper position is determined by the intersection of the two circles. In short it's very well explained in the "Intersection of two circles" section of this article.

Leaver to wiper

There is an offset in the angle from leaver position to the wiper position. At the moment the only known data is the intersection of the two circles mentioned above. Turning this into an angle requires two steps.

  • Calculating the distance from the 0 point to the connecting point
  • Calculating the angle

In the code it looks like this (2x is because of the triangle relations and Math.PI * 4 / 5 is the angle delta):

 var circledist = distance(
  leftWiperX - leftWiperLowerHandleR,
  leftWiperY,
  joinLeftX,
  jointLeftY
 );

 var dAngleL = 2 * Math.acos(circledist / (2 * leftWiperLowerHandle)) 
  + Math.PI * 4 / 5;

Wiper blade

After getting the angle getting the the wiper blade is pretty much a parallel line to the wiper carrier. That's just plain old math. To reduce the complexity of an example, a small trick is used. The coordinates of top and bottom of the wiper blade are calculated relative to the wiper carrier length, it's described with this code:

 var wiperFlipLTopX = leftWiperX 
  + Math.cos(dAngleL) 
   * (wiperCarrierLength * wiperFlipUpperRatio);

 var wiperFlipLTopY = leftWiperY 
  + Math.sin(dAngleL) 
   * (wiperCarrierLength * wiperFlipUpperRatio);

 var wiperFlipLBottomX = leftWiperX 
  + Math.cos(dAngleL) 
   * (wiperCarrierLength * wiperFlipLowerRatio);

 var wiperFlipLBottomY = leftWiperY 
  + Math.sin(dAngleL) 
   * (wiperCarrierLength * wiperFlipLowerRatio);

And here's my example on:
CSSDeck
Codepen