The first part of this example shows a person walking on a floor, and features:
Grouping of SVG objects.
The position of grouped objects in SVG.
Changing the position of grouped objects using an output mapping.
scalestandard library function.
Using text formatting.
The second part of this example shows a person walking around in a room, and features:
Using multiple values in an output mapping.
Using multiple format specifiers in a format pattern.
The following SVG image is used for the example of a person walking on a floor:
The image features a floor (gray bar), a person, and a text label. The person consists of some lines and a circle. These shapes are grouped together, using the Group command from Inkscape’s Object menu. The group can also be seen in the XML representation, as an
svg:g element, with the actual shapes (paths in this case) as children. We assigned the
person id to the
svg:g element, as it represents the entire person. For clarity we gave the sub-elements ids as well, although that was not necessary, as we won’t directly reference them in the CIF/SVG declarations.
Note that we moved the person as a whole, to the start of the floor. Since
svg:g elements don’t have an
y attribute in SVG, Inkscape applies a translation to move the group. This is reflected in the XML as a
transform attribute, with the
translate(-77,12) value. This indicates that the person was moved 77 pixels to the left, and 12 pixels to the bottom (as SVG has its origin in the upper left corner of the canvas).
To get rid of this, once the person is at the correct initial position, we can ungroup the
person group (Ungroup command from Inkscape’s Object menu), and regroup it. By ungrouping the group, the transformation is pushed to the individual elements of the group. The regroup simply adds a new group around the elements, without a translation transformation. The new group is given an automatically generated name, so we need to rename it to
person. This ungroup/group trick is often very useful. After this trick, the image looks as follows:
The text label is to be used to show the position of the person, as a percentage. The left position is represented as 0%, and the right position is represented as 100%. The id of the text label is
The following CIF specification models a person walking on a floor:
// Behavior. automaton person: cont pos = 0.0; location forward: initial; equation pos' = 1.0; edge when pos >= 5.0 goto backward; location backward: equation pos' = -1.0; edge when pos <= 0.0 goto forward; end // Visualization. svgfile "walk_floor.svg"; // width of the floor - width of the person = movement // 180px - 19px = 161px svgout id "person" attr "transform" value fmt("translate(%s,0)", scale(person.pos, 0, 5, 0, 161)); svgout id "pos_txt" text value fmt("%.1f%%", scale(person.pos, 0, 5, 0, 100));
A person starts at position (variable
person.pos) zero (value
0.0), and initially moves
forward. After (s)he has reached position
5.0, the movement is reversed. Once the person is back at the start position, the movement repeats itself.
There are two mappings, one that controls the horizontal position of the
person, and another that controls the text of the text label.
As stated above, the values of variable
person.pos are in the range [0 .. 5]. As can be seen from the comments of the CIF model, the width of the floor and person are 180 pixels and 19 pixels respectively. The person can thus move 161 pixels to the right. The output interval of the
scale standard library function is thus [0 .. 161]. As the vertical position is fixed, no vertical translation is required. The format pattern
"translate(%s,0)" inserts the scaled value into the horizontal amount of the translation. The formatted output updates the
transform attribute, making the person move horizontally.
The text of the text label with id
pos_txt is updated using a second mapping. The value of variable
person.pos is once again scaled using the
scale standard library function. This time the output range is [0 .. 100], to get a percentage. Format pattern
"%.1f%%" uses a
%.1f format specifier to convert that percentage to a textual value, with a single digit after the decimal point. After the value of the percentage, a percentage character is included in escaped form (
%%), to ensure it is not interpreted as a format specifier.
The following SVG image is used for the example of a person walking around in a room:
The image features a room (black rectangle) and a person. The person is the same group of elements as in the example of a person walking on a floor. The same group/ungroup trick is used here as well, to make sure the group has no translation transformation.
The following CIF specification models a person walking around in a room:
// Behavior. automaton person: cont x = 0.0; cont y = 0.0; location right: initial; equation x' = 1.0; equation y' = 0.0; edge when x >= 5.0 goto down; location down: equation x' = 0.0; equation y' = 1.0; edge when y >= 5.0 goto left; location left: equation x' = -1.0; equation y' = 0.0; edge when x <= 0.0 goto up; location up: equation x' = 0.0; equation y' = -1.0; edge when y <= 0.0 goto right; end // Visualization. svgfile "walk_room.svg"; // width of the room - width of the person = horizontal movement // 180px - 19px = 161px // // height of the room - height of the person = vertical movement // 180px - 40x = 140px svgout id "person" attr "transform" value fmt("translate(%s,%s)", scale(person.x, 0, 5, 0, 161), scale(person.y, 0, 5, 0, 140));
A person starts at the top left position, and initially moves to the
right. Once (s)he reaches the right side, (s)he start to move
down, followed by a
up movement. After the
up movement, the person is once again at the top left position, start another walk around the room, etc.
There is only one mapping, which controls both the horizontal and vertical position of the
person. The mapping is similar to the example of a person walking on a floor, except that now both the horizontal and vertical movements are included. The mapping uses two scaled values, one for the horizontal movement, and one for the vertical movement. The format pattern includes both values in the output. The first scaled value controls the horizontal movement, while the second scaled value controls the vertical movement.