Skip to content

Instantly share code, notes, and snippets.

Created August 29, 2017 14:06
Show Gist options
  • Save anonymous/ae0cee20a90bf5df03dc4a7b647e3ac1 to your computer and use it in GitHub Desktop.
Save anonymous/ae0cee20a90bf5df03dc4a7b647e3ac1 to your computer and use it in GitHub Desktop.
Rectangular Spiral
<article>
<h1>Rectangular Spiral</h1>
<p>In this exercise, you will write a Javascript function to draw a rectangular spiral through points arranged on a square grid like this:
</p>
<figure>
<svg class="board" height="201" width="251">
<path d="M25 25L225 25L225 75L225 175L175 175L25 175L25 125L25 75L75 75L175 75L175 125L75 125"/>
<text x="30" y="45">(0,0)</text>
<text x="220" y="195" style="text-anchor: end">(4,3)</text>
</svg>
<pre><code>spiral([0, 0], [4, 3])</code></pre>
<code>=> [[0,0], [4,0], [4,3], [0,3], [0,1], [3,1], [3,2], [1,2]]</code>
</figure>
<p>You will write the function <code>spiral(pt0, pt1)</code>:</p>
<dl>
<dt><code>pt0</code></dt><dd>the <code>[x, y]</code> starting point of the path</dd>
<dt><code>pt1</code></dt><dd>the <code>[x, y]</code> corner of the rectangle opposite the starting point</dd>
</dl>
<blockquote>The starting point <strong>may not</strong> be the upper left corner of the rectangle, but in all cases the two points will be opposite corners of a rectangle.
</blockquote>
<blockquote>In this coordinate system, the positive <code>x</code> axis is to the <strong>right</strong> and the positive <code>y</code> axis is <strong>down</strong>.
</blockquote>
<dl><dt>Return value</dt>
<dd>a list of <code>[x, y]</code> points which define a <strong>clockwise</strong> spiral path passing through all points inside the rectangle</dd>
</dl>
<blockquote>You do not need to list every point that the path will go through, but you may include any intermediate points you wish. </blockquote>
<p>There is additional code on this page that converts the list of points returned by your function to an SVG <code>&lt;path&gt;</code>, so you can visualize your work as you go.</p>
<p>Below is a copy of the previous example, ready for you write your function. Go to the JS window and start editing the function <code>spiral</code> to get started.</p>
<figure id="test0">
<svg class="board" height="201" width="251">
<path d=""/>
<text x="30" y="45">(0,0)</text>
<text x="220" y="195" style="text-anchor: end">(4,3)</text>
</svg>
<pre><code>spiral([0, 0], [4, 3])</code></pre>
<code class="out"></code>
</figure>
<p>When your function works for the above example, test it on the following examples</p>
<figure id="test1">
<svg class="board" height="301" width="151">
<path d=""/>
<text x="120" y="15" style="text-anchor: end">(2,0)</text>
<text x="30" y="295">(0,5)</text>
</svg>
<pre><code>spiral([2, 0], [0, 5])</code></pre>
<code class="out"></code>
</figure>
<figure id="test2">
<svg class="board" height="51" width="451">
<path d=""/>
<text x="30" y="45">(0,0)</text>
<text x="420" y="45" style="text-anchor: end">(8,0)</text>
</svg>
<pre><code>spiral([8, 0], [0, 0])</code></pre>
<code class="out"></code>
</figure>
<figure id="test3">
<svg class="board" height="251" width="251">
<path d=""/>
<text x="80" y="65">(1,1)</text>
<text x="180" y="195">(3,1)</text>
</svg>
<pre><code>spiral([1, 3], [3, 1])</code></pre>
<code class="out"></code>
</figure>
</article>
function spiral(pt0, pt1) {
var points = [];
var startRow = pt0[1]
var startCol = pt0[0]
var endRow = pt1[1]
var endCol = pt1[0]
if(startCol > endCol) {
var temp = startCol
startCol = endCol
endCol = temp
}
if(startRow > endRow) {
var temp = startRow
startRow = endRow
endRow = temp
}
// todo: off by 1 check
while(startRow < endRow && startCol < endCol) {
var i;
//printing across
for(i = startCol; i <= endCol; ++i) {
// i is x
// startrow is y
points.push([i, startRow])
}
startRow++;
// printing down
for(i = startRow; i <= endRow; ++i){
points.push([endCol,i])
}
endCol--
// printing across right to left
if(startCol < endCol) {
for(i = endCol-1; i >= startCol; --i) {
points.push([i,endRow])
}
endRow--
}
// if(startRow < endRow) {
// for(i = endCol-1; i >= startCol; --i) {
// points.push([i,endRow])
// }
// endRow--
// }
if(en < endCol) {
console.log("Made it")
for(i = endRow -1; i >= startRow; --i){
points.push([startCol,i])
}
startCol++
}
}
console.log(points)
// Write your function here
return points
}
// *** DO NOT EDIT BELOW ***
function pointsToPath (list, size=50) {
return "M" + list
.map( pt => pt.map(i => (i + 0.5) * size) )
.map( pt => pt.join(" ") )
.join("L")
}
function renderSpiral(id, pt0, pt1) {
let points = spiral(pt0, pt1)
let node = document.getElementById(id)
let path = node.querySelector(".board path")
let output = node.querySelector(".out")
let d = document.createAttribute("d")
output.textContent = '=> [' + points
.map( pt => '[' + pt.join(',') + ']' )
.join(', ') + ']'
d.value = pointsToPath(points)
path.setAttributeNode(d)
}
renderSpiral('test0', [0, 0], [4, 3])
let testAll = true
if (testAll) {
renderSpiral('test1', [2, 0], [0, 5])
renderSpiral('test2', [8, 0], [0, 0])
renderSpiral('test3', [1, 3], [3, 1])
}
svg.board {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"><path d="M25 0L25 50M0 25L50 25" stroke="blue" fill="none"/><circle r="5" cx="25" cy="25" fill="blue"/></svg>');
}
svg.board path {
stroke: red;
stroke-width: 3px;
fill: none;
}
svg.board text {
fill: blue;
text-anchor: top;
font-size: 12px;
}
article {
max-width: 50em;
margin: 0 auto;
font-family: Helvetica, Arial, sans-serif;
}
code {
font-family: monospace;
font-weight: bold;
color: #383830;
font-size: 120%;
font-style: normal;
}
figure {
margin: 2em 0;
}
figure::after {
display: block;
clear: both;
content: '';
}
figure > svg {
float: left;
margin-right: 2em;
}
p, div {
clear: both;
}
dl {
margin-left: 4em;
}
dt {
font-weight: bold;
color: #383830;
}
blockquote {
margin-left: 4em;
font-style: italic;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment