From: Dave Smith on
Walter Roberson <roberson(a)hushmail.com> wrote in message <hn394o$2j0$1(a)canopus.cc.umanitoba.ca>...
> Consider the x coordinates. If you start from a baseline (0 in the case
> of the code) then you need the initial x value (1) for that, and then
> you need the same x value to draw the up (or down) stroke to reach the
> first y value. Then you will need the 2nd x value to draw the line
> across to the second value, and the 2nd x again to draw the up or down
> stroke to the second y value. Keep going in this manner, with 2 copies
> of each x coordinate. When you reach the last y value, you have an
> implicit draw across _past_ that y value to where the next y value would
> start, and you have an implicit return to baseline, so you will need two
> copies of the x coordinate which is length(y)+1 . Thus, what we do is
> construct (1:length(y)+1), then we use repmat(,2,1) two take an
> identical copy of that row. Matlab stores values down columns, so _in
> memory_ the adjacent values at this point will be two copies of each of
> the x coordinates. We could use a temporary variable to hold that and
> then use (:) indexing to "unravel" that down the columns to x1 x1 x2 x2
> etc., or we can do like I did and call reshape explicitly to do the
> unravelling. reshape(,1,[]) means to take the data that is in memory and
> change its dimensions to 1 by "however much you need", so after the
> reshape, we wil be left with x1 x1 x2 x2 .... xn xn xn+1 xn+1 .
>
> Now consider the y coordinates. Because we are starting from the
> baseline, the adjusted y coordinates will need to start with a 0;
> likewise because we return to the baseline at the end, they will need to
> end with 0. That accounts for the [0 <something> 0] portion of the code.
> Now, we need to draw the upstroke or downstroke to reach the first y
> value, so the first y value comes next. We need to hold that y value
> over to the next x value, so a duplicate of the first y value is needed.
> After that, we need to draw up or down to the second y value, and then
> need to hold that value to the next x coordinate, and so on. Thus we are
> once more in the situation of needing to duplicate a vector y1 y2 y3 to
> become y1 y1 y2 y2 y3 and so on, which uses the same duplication code as
> we used for the x. But in the x case, we know that 1:length(y)+1 will
> generate a row vector, but for the purposes of this two-liner, we cannot
> assume that y is already a row vector. To force y to be a row vector, we
> use y(:) which forces y to be a _column_ vector; once we have the column
> vector, we repmat(,1,2) it to make a duplicate column, and then we use
> .' to transpose it into two identical row vectors; the reshape(,1,[])
> then converts it into a single long row vector. Then the [0 ... 0]
> wrapper for the returns to baseline.
>
> The length of the newy vector thus becomes 1 + 2*length(y) + 1, which is
> 2*length(y) + 2, which is 2*(length(y)+1) which is the same as for the
> newx vector, so we have all the coordinates matched up.
>
>
> This isn't the _optimal_ drawing for the line, but that probably doesn't
> matter. If it does matter, then because the structure of it is so clear,
> it should be fairly straight-forward to filter out redundant points; I
> would suggest first removing the redundant up/down strokes (which will
> show up as identical pairs of x and y coordinates adjacent to each
> other), and then to remove the redundant x coordinates (which would show
> up as (x1 y1) (x2 y1) (x3 y1), which is compressible to (x1 y1) (x3 y1))

Thank you. I'm slowly understanding it the more I read it.