# Curve Stitching

Curve stitching is the process of "stitching" together multiple straight lines in order to create a curve, like so:

For an explanation of curve stitching, visit this website.

We will be drawing our curve in the top left of the screen, as shown in the image above.

Given an integer n (via STDIN or a function parameter), being the number of lines to draw, and an integer p pixels, being the interval between the starting points, draw a straight line curve.

Horizontal/vertical lines are necessary, and should be part of the line count.

### Example Outputs:

n = 25, p = 15

n = 20, p = 20

This is a challenge, so shortest code wins.

• Oh yeah! D'oh... Commented Sep 12, 2014 at 15:37
• The curve is in fact a parabola. I can't remember where I read that thoughl. If I was a pedant I would point out that it's not a "straight line curve" but an approximation of a curve built up from straight lines :-) Commented Sep 12, 2014 at 16:07
• @Martin Yup, pixels. Commented Sep 12, 2014 at 16:15
• @Martin The horizontal line shouldn't be necessary, because the border of the window will make up the lines. Commented Sep 12, 2014 at 16:41
• Oh dayum I used to do this for fun when bored in class ... didn't know other people had done the exact same thing! Commented Sep 12, 2014 at 20:32

# Python - 74

Since the question doesn't specify units, axes scaling etc. I'm coming up with the following minimum solution:

import pylab
n,p=input()
for i in range(n):pylab.plot([0,i*p],[(i-n)*p,0])


• Disregarding units and axis scaling, the minimum solution saves four characters by omitting *p ;). also, are you sure you're not adding a horizontal and/or vertical line? those are not in the example outputs. finally, I noticed in mine, that it's shorter to offset the first coordinate horizontally instead of the second one (because you can save the - and the parentheses) Commented Sep 12, 2014 at 16:14
• (The question does specify units as pixels now, btw.) Commented Sep 12, 2014 at 19:32

## Mathematica, 5551504764 68 bytes

f=Graphics[Line@Table[#2{{i-1,#+1},{0,i+1}},{i,#}],ImageSize->#*#2]&


Defines a function which yields the image as specified when called like

f[25,15]


Yielding

Edit: Had to add some characters to make sure that the second parameter was actually interpreted as pixels.

Edit: four more bytes to plot the horizontal lines.

# Bash+Imagemagick+xview, 124 bytes

for((;i<$1;));{ s+=" -draw 'line$[i*$2],0 0,$[($1-i++)*$2]'"
}
eval convert -size $[$1*$2]x$[$1*$2] xc:$s png:-|xview stdin  ### Output for ./curvestitch.sh 25 15: • Yay for overflowing the maximum command line length if you're not careful. Nice one Commented Sep 13, 2014 at 22:11 ## Basic 7.0, Commodore 128, 60 58 bytes 0inputn,p:gR1:s=n*p:do:dR1,s,0to0,n:s=s-p:n=n+p:loOwHs>=0  Watch a video of it running: Unfortunately, INPUT command hasn't an abbreviation :( # APL (dzaima/APL), 26 bytes {P5.G.ln↓⍉↑⍵×⍺∘-@3⍳¨⍺1 1⍺}  -2 bytes from Adam using magic Requires ⎕IO←0. (0-indexing) ## Explanation {P5.G.ln↓⍉↑⍵×⍺∘-@3⍳¨⍺1 1⍺} P5.G.ln Create lines using the following sets of four points: ⍺1 1⍺ Array [n,1,1,n] ⍳¨ generate range 0..n for each [0..n,0,0,0..n] @3 to the third element, ⍺∘- subtract it from n.(reversing the last range) [0..n,0,0,n..0] ⍵× scale all items by p ↑ mix , creating columns of coordinates. ↓⍉ transpose, and convert to lists of two points  ## APL (dzaima/APL), 28 bytes {P5.G.ln↓⍉↑(⍵×⍳⍺)⍬⍬(⍵×⍺-⍳⍺)}  Anonymous function which takes n and p as left and right arguments, and displays the pattern, given an adequately sized canvas. Full Program here. Made with a lot of advice and golfing from dzaima. ### Test Cases 25, 15 20, 20 6,72 ## Java + Processing, 62 bytes The original function I made for this question. void c(int n,int p){for(int i=1;i<n;)line(p*i,0,0,p*(n-i++));}  • Does {P5.G.ln↓⍉↑⍵×⍺-@3⍳¨⍺1 1⍺} work? – Adám Commented Oct 21, 2020 at 5:04 • @Adám IncorrectArgsError: @ can't be called dyadically Commented Oct 21, 2020 at 5:24 • OK, but then you have the choice between {P5.G.ln↓⍉↑⍵×⍺∘-@3⍳¨⍺1 1⍺} and {P5.G.ln↓⍉↑⍵×(⍳⍺)⍬⍬(⍺-⍳⍺)} – Adám Commented Oct 21, 2020 at 5:27 • @Adám Added an explanation, hope it's correct. Commented Oct 21, 2020 at 6:03 • Almost: ⍵× is a scaling applied to everything, not just item 3. – Adám Commented Oct 21, 2020 at 6:05 # Perl, 121 130 bytes The input is via STDIN. The values are comma separated. EDIT: We have new rules. I'm not sure why, but the first two pixels are invisible and I had to add an offset... use Tk;<>=~/,/;$c=tkinit->Canvas(-width=>$w=$*$'-$',-height=>$w)->pack;$c->createLine(2,2+$_*$',2+$w-$_*$',2)for 0..~-$;MainLoop


Here are some tests:

25x15:

6x72:

# BBC Basic, 58 ascii characters, tokenised filesize 49

INPUTn,p:p*=2FORi=1TOn:MOVEi*p-p,974DRAW0,974-(n-i)*p:NEXT


p*=2 is needed because in the default mode BBC Basic maps a logical square of 2x2 to a single physical pixel.

BBC Basic has the origin at the bottom left corner of the screen, with y coorinates going up. On my machine the default window has an upper y coordinate of 974 (yours may be different.) 7 characters could be saved if it was permitted to plot in the bottom left corner of the screen. Adding MODE16 after the first : will resize the window so that the upper y coordinate is guaranteed to be 799.

• This is fast becoming a dangerous golfing language. CJam who? Commented Sep 13, 2014 at 2:29

# Java 8, 143 bytes

import java.awt.*;n->p->new Frame(){{add(new Panel(){public void paint(Graphics g){for(int m=0;m<n;)g.drawLine(0,m*p,n*p-++m*p,0);}});show();}}


Output for $$\n=25, p=15\$$:

Output for $$\n=5, p=50\$$:

Explanation:

import java.awt.*;            // Required import for almost everything
n->p->                        // Method with two integer parameters & Frame return-type
new Frame(){                //  Create the Frame
{                          //   In an inner code-block:
public void paint(Graphics g){
//     Overwrite its paint method:
for(int m=0;m<n;)    //      Loop m in the range [0,n):
g.drawLine(        //       Draw a line:
0,m*p,           //        Starting at x=0, y=m*p
n*p-++m*p,0);}});//        to x=n*p-(m+1)*p, y=0
show();}};               //    And afterwards show the Frame

• I think it specifies that vertical and horizontal lines are necessary where it says "Horizontal/vertical lines are necessary, and should be part of the line count." (or am I misunderstanding you?) Commented Sep 4, 2020 at 11:48
• @thedefault. Fixed. And it turned out even 2 bytes shorter. :) Thanks again for noticing. Commented Sep 4, 2020 at 13:26
• I don't know java, but where in the code do you specify the output pixels? When I look at your 2 examples, they seem to be 305 & 176 pixels across, which is less than 25*15 & 5*50. Or is this just a side-effect of the up-/downloading? Commented Sep 4, 2020 at 14:07
• @DominicvanEssen The width/height is actually $(n-1)\times p$, so 360 for the first test case and 200 for the second. But if the pictures shows something different it's probably an issue of automatic cropping when making a screenshot, uploading it to imgur, or showing it at stackexchange. I don't see it mentioning pixels in particular in the drawLine method (it uses Graphics coordinate system, but no idea what it uses by default). Tbh, I have no idea why my screenshots appear smaller than some other answers for the $n=25,p=15$ test case, but the calculations are correct with n & p.. Commented Sep 4, 2020 at 14:53
• Ah, I kind-of assumed that the screenshot/upload/imgur/SE chain was to blame! So if your graphs are the correct sizes on your computer, I take it that the 'graphics' coordinates are defined as 1 coordinate = 1 pixel, which is quite convenient here! Commented Sep 4, 2020 at 14:59

# Html + JavaScript 155 157 183

Edit: learnig what stuff I can cut without functionality loss
Edit 2: as suggested by @Optimizer

<canvas id='c'/><script>
p=prompt,s=p(l=p(t=c.getContext("2d")));for(c.width=c.height=y=s*l,x=0;l--;x-=s)t.moveTo(0,y-=s),t.lineTo(-x,0);t.stroke()
</script>


Fiddle First input number of lines, second input pixel interval

Ungolfed Fiddle

• l=p(s=p(t=c.getContext("2d"))) Commented Sep 13, 2014 at 10:56
• @Optimizer I think I need to set width and height before getting the context Commented Sep 13, 2014 at 13:08
• Nope, this works : jsfiddle.net/6ke43m7c/10 Commented Sep 13, 2014 at 13:11

# R, 100 bytes

function(n,p,P=p*n*1.08){bmp(,P,P)
par(mar=!1:4)
plot.new()
segments((1:n-1)/n,1,0,1:n/n)
dev.off()}


Saves output to bitmap file 'Rplot001.bmp'.
There are some 'wasted' pixels at the top & on the left (so the curve is in the top left corner but not touching the edge). This seems to be within the spec, but could be removed for +13 bytes.

Commented code:

curve_stitch=
function(n,p,                   # n = number of lines, p = pixels between starting points
P=p*n*1.08){                   # P = pixel dimensions of final plot.
# (R expands axes by 4% at each end by default, so to
# ensure that the curve itself is p*n pixels, we need
# to expand the output by +8%
bmp(,P,P)                      # open bitmap output to default filename, with dimensions PxP
par(mar=!1:4)                  # remove margins by setting all to zero
plot.new()                     # define new plot (default data range from 0 to 1)
segments((1:n-1)/n,1,0,1:n/n)  # plot lines within range from 0 to 1
dev.off()                      # close bitmap output to save file
}



Sample output:

curve_stitch(10,10)


curve_stitch(5,50)