search

Class myphysicslab.lab.view.DisplayShape

Provided By
All Implemented Interfaces

Displays a MassObject with specified style such as color, border, etc.

Displays the MassObject by filling the shape, drawing the border, and optionally drawing an image. Lastly ornaments are drawn such as a center of gravity marker, drag handles, and name of the MassObject.

Setting Display Attributes

DisplayShape has attributes to determine fill color, border color, border thickness, whether to draw a center of mass symbol, etc. There are two ways to specify these attributes:

1. Modify the style directly

Modify the DisplayShape's style directly after it has been created. Here is a typical example where the DisplayShape is created by myphysicslab.sims.engine2D.RigidBodyObserver.

simList.add(polygon1); // RigidBodyObserver creates a DisplayShape here
var dispPoly1 = displayList.find(polygon1);
dispPoly1.setFillStyle('red');

2. Modify the prototype

DisplayShape allows specifying a prototype DisplayShape. When a display property is undefined, then the property is fetched from the prototype. If it is also undefined on the prototype then a default value is used.

Keep in mind that all objects with a given prototype will be affected by any changes made to the prototype.

Here is an example where we make a prototype that causes the names to be drawn.

var protoShape = new DisplayShape().setNameFont('10pt sans-serif');
var shape1 = new DisplayShape(mass1, protoShape);

See myphysicslab.sims.engine2D.RigidBodyObserver which sets up several prototype objects.

Drawing Name of MassObject

The name of the MassObject is drawn when the #setNameFont property has a valid font specifier string. There are also #setNameColor and #setNameRotate properties that affect how the name is drawn. Example code:

myPolygon.setNameFont('12pt sans-serif').setNameColor('gray');

Here is a script that can be executed in Terminal to show names on all DisplayShapes:

goog.array.forEach(displayList.toArray(), function(d) {
    if (d instanceof DisplayShape) {
      d.setNameFont('12pt sans-serif');
    }
})

Or, if the objects of interest have the same prototype, then you can just change the prototype object.

Drawing an Image

You can draw an image in the DisplayShape by getting an HTMLImageElement that is on the HTML page and using #setImage. For example in the HTML page you would have

<img id="myImage" src="../../images/myImage.png" width="32" height="32">

Then in the JavaScript application after making the DisplayShape, you can assign the image to the DisplayShape:

myPolygon.setImage(document.getElementById('myImage'));

You can further translate, scale, and rotate the image within in DisplayShape by making an AffineTransform and using #setImageAT. You can clip the image to the boundary of the MassObject by using #setImageClip.

You can assign a function to #setImageDraw and do the drawing within that function. The same coordinate system modifications are done in that case. The current path is the shape of the MassObject, so you can for example fill with a pattern.

Both setImage and setImageDraw can be used together. The image is drawn first, then the imageDraw function is called.

The application myphysicslab.sims.engine2D.DoublePendulum2App has examples of

  • drawing a scaled and rotated image inside a DisplayShape
  • filling with a color gradient
  • filling with a repeating tiled pattern

Coordinate System When Drawing An Image

When drawing an image it is important to understand the several coordinate systems involved:

  • simulation coordinates uses the Y increases up convention. The origin can be anywhere, and the units can be any size.

  • JavaScript canvas screen coordinates uses the Y increases down convention, with the origin at the top-left corner of the canvas, and with each unit corresponding to a pixel. The transformation between simulation and screen coordinates is handled by a myphysicslab.lab.view.CoordMap which can be set for the myphysicslab.lab.view.LabView.

  • body coordinates rotates and translates along with a myphysicslab.lab.model.MassObject. Like simulation coordinates it uses the

For drawing the MassObject, we set the canvas to be in body coordinates. But when drawing an image or text, the difference of whether the Y coordinate increases up or down can cause the image or text to be drawn mirrored upside down.

Therefore, before the image is drawn, we make additional transformations to return to something like screen coordinates with

  • Y increases down
  • each unit corresponds to a pixel
  • the origin is at top-left corner of the DisplayShape bounding box
  • but the coordinates are still oriented (rotated and translated) to align with the DisplayShape, similar to body coordinates.

The #setImageAT AffineTransform can then be specified to cause the image to be appear with any combination of rotation, scaling, and positioning. See the diagram below.

There are also differences in how angles are specified in the different coordinate systems; see 'About Coordinates and Angles' in myphysicslab.lab.engine2D.CircularEdge for more information.

The above examples of using an myphysicslab.lab.util.AffineTransform on an image were generated by altering the application myphysicslab.sims.engine2D.DoublePendulum2App.

new DisplayShape( massObject, proto )

Parameters
massObject(myphysicslab.lab.model.MassObject|null|undefined)

the MassObject to display

proto(myphysicslab.lab.view.DisplayShape|null|undefined)

the prototype DisplayShape to inherit properties from

Instance Methods

Instance Properties