1# path-attribute 2 3A *path-attribute* is used provide the origin and direction of a line 4object (arc, arrow, line, move, or spline). It is an error to use a 5*path-attribute* on 6a block object (box, circle, cylinder, dot, ellipse, file, oval, or text). 7 8There are seven forms: 9 10 * **from** *position* 11 * **then**? **to** *position* 12 * **then**? **go**? *direction* *distance*? 13 * **then**? **go**? *direction* **until**? **even with** *place* 14 * (**then**|**go**) *distance*? **heading** *compass-angle* 15 * (**then**|**go**) *distance*? *compass-direction* 16 * **close** 17 18The "`from`" attribute is used to assign the starting location 19of the line object (its ".start" value). The other six forms 20(collectively called "to" forms) assign 21intermediate vertexes or the end point (.end). If the "`from`" 22is omitted, then "`from previous.end`" is assumed, or if there 23is no previous object, "`from (0,0)`". If no "to" forms are 24provided then a single movement in the current layout direction 25by either the "linewid" or "lineht" (depending on layout direction) 26is used. 27 28The "from" can occur 29either before or after the various "to" subclauses. That does not 30matter. But the order of the various "to" subclauses do matter, of course. 31 32If there are two consecutive *direction* clauses (*direction* is 33always one of "`up`", "`down`", "`left`", or "`right`") then 34the two will be combined to specify a single line segment. 35Hence, the following are equivalent: 36 37 38 * ... **right 4cm up 3cm** ... 39 * ... **go 5cm heading 53.13010235** ... 40 41~~~ pikchr 42leftmargin = 1cm 43A1: arrow thick right 4cm up 3cm 44dot at A1.start 45X1: line thin color gray from (0,-3mm) down 0.4cm 46X2: line same from (4cm,-3mm) down 0.4cm 47arrow thin color gray from X1 to X2 "4cm" above 48X3: line same from (4cm+3mm,0) right 0.4cm 49X4: line same from (4cm+3mm,3cm) right .4cm 50arrow thin color gray from X3 to X4 "3cm" aligned above 51X5: line same from A1.start go 4mm heading 90+53.13010235 52X6: line same from A1.end go 4mm heading 90+53.13010235 53arrow thin color gray from X5 to X6 "5cm" below aligned 54line same from (0,1cm) up 1cm 55spline -> from 1.5cm heading 0 from A1.start \ 56 to 1.5cm heading 10 from A1.start \ 57 to 1.5cm heading 20 from A1.start \ 58 to 1.5cm heading 30 from A1.start \ 59 to 1.5cm heading 40 from A1.start \ 60 to 1.5cm heading 53.13 from A1.start \ 61 thin color gray "53.13°" aligned center small 62~~~ 63 64If two separate movements are desired, one 4cm right and another 3cm up, 65then the "right" and "up" subphrases must be separated by the "`then`" keyword: 66 67 * ... **right 4cm then up 3cm** ... 68 69~~~ pikchr 70leftmargin = 1cm 71A1: arrow thick right 4cm then up 3cm 72dot at A1.start 73X1: line thin color gray from (0,-3mm) down 0.4cm 74X2: line same from (4cm,-3mm) down 0.4cm 75arrow thin color gray from X1 to X2 "4cm" above 76X3: line same from (4cm+3mm,0) right 0.4cm 77X4: line same from (4cm+3mm,3cm) right .4cm 78arrow thin color gray from X3 to X4 "3cm" aligned above 79~~~ 80 81## The "`until even with`" subclause 82 83The "until even with" clause is a Pikchr extension (it does not exist 84in PIC) that makes it easier to specify paths that follow a 85"Manhattan geometry" (lines are axis-aligned) or that negotiate around 86obstacles. The phrase: 87 88> go *direction* until even with *position* 89 90Means to continue the line in the specified *direction* until the 91coordinate being changed matches the corresponding coordinate in 92*position* If the line is going up or down, then it continues until 93the Y coordinate matches the Y coordinate of *position*. If the line 94is going left or right, then it continues until 95the X coordinate matches the X coordinate of *position*. 96 97For example, suppose in the diagram below that we want to draw an arrow 98that begins on Origin.s and ends on Destination.s but goes around 99the Obstacle oval, clearing it by at least one centimeter. 100 101~~~ pikchr toggle 102box "Origin" 103Obstacle: oval ht 300% wid 30% with .n at linewid right of Origin.ne; 104box "Destination" with .nw at linewid right of Obstacle.n 105line invis from 1st oval.s to 1st oval.n "Obstacle" aligned 106~~~ 107 108The arrow might look like this: 109 110~~~ 111 arrow from Origin.s \ 112 down until even with 1cm below Obstacle.s \ 113 then right until even with Destination.s \ 114 then to Destination.s 115~~~ 116 117And we have (annotations added): 118 119~~~ pikchr toggle 120box "Origin" 121Obstacle: oval ht 300% wid 30% with .n at linewid right of Origin.ne; 122box "Destination" with .nw at linewid right of Obstacle.n 123line invis from 1st oval.s to 1st oval.n "Obstacle" aligned 124X: \ 125 arrow from Origin.s \ 126 down until even with 1cm below Obstacle.s \ 127 then right until even with Destination.s \ 128 then to Destination.s 129 130line invis color gray from X.start to 2nd vertex of X \ 131 "down until even with" aligned small \ 132 "1cm below Obstacle.s" aligned small 133line invis color gray from 2nd vertex of X to 3rd vertex of X \ 134 "right until even with Destination.s" aligned small above 135line invis color gray from 3nd vertex of X to 4rd vertex of X \ 136 "to Destination.s" aligned small above 137 138# Evidence that the alternative arrow is equivalent: 139assert( 2nd vertex of X == (Origin.s, 1cm below Obstacle.s) ) 140assert( 3nd vertex of X == (Destination.s, 1cm below Obstacle.s) ) 141~~~ 142 143The "**(** *position* **,** *position* **)**" syntax can be used 144in a similar way. The "**(** *position* **,** *position* **)**" 145syntax means a point whose X coordinate is taken from the first 146position and whose Y coordinate is taken from the second position. 147So the line around the obstacle could have been written like this: 148 149~~~ 150 arrow from Origin.s \ 151 to (Origin.s, 1cm below Obstacle.s) \ 152 then to (Destination.s, 1cm below Obstacle.s) \ 153 then to Destination.s 154~~~ 155 156However, we believe the "`until even with`" notation is easier. 157 158## The "`close`" subclause 159 160The "`close`" attribute closes a multi-segment path so that it 161forms a polygon. When "`close`" is used, the "`.end`" point of the 162object is no longer the last vertex in the path but is instead 163one of "`.e`", "`.s`", "`.w`", or "`.n`" according to the current 164layout direction, as it would be for a block object. 165 166The following diagram illustrates this behavior. The "`.end`" of 167each line is tagged with a red dot. The line that uses "`close`" 168has its end at the "`.e`" point of the bounding box since the 169layout direction is "right". The line without "`close`" has its 170"`.end`" at the last vertex of the line. 171 172~~~ pikchr toggle 173line right 2cm then down .5cm then up 1cm right 1cm \ 174 then up 1cm left 1cm then down .5cm then left 2cm \ 175 close "with 'close'" 176dot color red at last line.end 177 178move to 2.5cm south of last line.start 179line right 2cm then down .5cm then up 1cm right 1cm \ 180 then up 1cm left 1cm then down .5cm then left 2cm \ 181 then down 1cm "without 'close'" 182dot color red at last line.end 183~~~ 184