Last active
August 29, 2015 14:15
-
-
Save 910JQK/1c1bb02be78da29b4211 to your computer and use it in GitHub Desktop.
斜二測畫法 (a space geometric projection method)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Projection</title> | |
<script type="text/javascript"> | |
const SVG_NS = "http://www.w3.org/2000/svg"; | |
const POINT_FILTER = /\(([+-]?\d+), ?([+-]?\d+), ?([+-]?\d+)\)/; | |
const k = Math.sqrt(2)/4; | |
var lines = []; | |
function empty_node(node){ | |
while(node.lastChild) | |
node.removeChild(node.lastChild); | |
} | |
function init(){ | |
Add.addEventListener('click', add_line); | |
End.addEventListener('keyup', function(ev){ | |
if(ev.keyCode == 13) | |
add_line(); | |
}); | |
AxisCheckbox.addEventListener('change', function(){ | |
Axis.style.display = (this.checked)? "": "none"; | |
}); | |
AxisCheckbox.checked = true; | |
} | |
function add_line(){ | |
var begin = Begin.value.match(POINT_FILTER); | |
var end = End.value.match(POINT_FILTER); | |
if(!begin || !end){ | |
alert("invalid input!"); | |
return; | |
} | |
begin.shift(); | |
end.shift(); | |
var i; | |
for(i=0; i<3; i++){ | |
begin[i] = Number(begin[i]); | |
end[i] = Number(end[i]); | |
} | |
lines.push({ | |
begin: begin, | |
end: end, | |
x1: begin[0] + k*begin[1], | |
y1: begin[2] + k*begin[1], | |
x2: end[0] + k*end[1], | |
y2: end[2] + k*end[1], | |
dashed: false | |
}); | |
Begin.value = ""; | |
End.value = ""; | |
update_table(); | |
render(); | |
Begin.focus(); | |
} | |
function format_point(x, y, z){ | |
return "(" + x + ", " + y + ", " + z + ")"; | |
} | |
function remove_line(line){ | |
var i; | |
for(i=0; i<lines.length; i++){ | |
if(lines[i] == line){ | |
lines.splice(i, 1); | |
update_table(); | |
render(); | |
break; | |
} | |
} | |
} | |
function update_table(){ | |
empty_node(Table); | |
var i; | |
for(i=0; i<lines.length; i++){ | |
var row = document.createElement("tr"); | |
var begin = document.createElement("td"); | |
var end = document.createElement("td"); | |
var dashed_td = document.createElement("td"); | |
var remove_button_td = document.createElement("td"); | |
begin.textContent = format_point.apply(this, lines[i].begin); | |
end.textContent = format_point.apply(this, lines[i].end); | |
var dashed = document.createElement("input"); | |
var label = document.createElement("span"); | |
dashed.line = lines[i]; | |
dashed.type = "checkbox"; | |
dashed.checked = lines[i].dashed; | |
label.textContent = "dashed"; | |
dashed.addEventListener('change', function(){ | |
this.line.dashed = this.checked; | |
render(); | |
}); | |
var remove_button = document.createElement("button"); | |
remove_button.line = lines[i]; | |
remove_button.textContent = "remove"; | |
remove_button.addEventListener('click', function(){ | |
remove_line(this.line); | |
}); | |
dashed_td.appendChild(dashed); | |
dashed_td.appendChild(label); | |
remove_button_td.appendChild(remove_button); | |
row.appendChild(begin); | |
row.appendChild(end); | |
row.appendChild(dashed_td); | |
row.appendChild(remove_button_td); | |
Table.appendChild(row); | |
} | |
} | |
function render(){ | |
empty_node(UserCanvas); | |
var i, line; | |
for(i=0; i<lines.length; i++){ | |
line = document.createElementNS(SVG_NS, "line"); | |
line.setAttributeNS(null, "x1", lines[i].x1); | |
line.setAttributeNS(null, "x2", lines[i].x2); | |
line.setAttributeNS(null, "y1", lines[i].y1); | |
line.setAttributeNS(null, "y2", lines[i].y2); | |
if(lines[i].dashed) | |
line.setAttributeNS(null, "style", "stroke-dasharray: 10 5;"); | |
UserCanvas.appendChild(line); | |
} | |
window.scrollTo(0, 0); | |
} | |
</script> | |
</head> | |
<body onload="init()"> | |
<div> | |
<svg width="600" height="600"> | |
<g id="Axis" style="stroke: black;" transform="translate(300, 300)"> | |
<g style="stroke-width: 3px;"> | |
<line x1="-275" y1="0" x2="275" y2="0"/> | |
<line x1="0" y1="-275" x2="0" y2="275"/> | |
<line x1="-250" y1="250" x2="250" y2="-250"/> | |
</g> | |
<text x="275" y="20">x</text> | |
<text x="250" y="-230">y</text> | |
<text x="10" y="-275">z</text> | |
</g> | |
<g id="UserCanvas" style="stroke: black;" transform="matrix(1, 0, 0, -1, 300, 300)"></g> | |
</svg> | |
<table id="Table" style="float: right;"></table> | |
</div> | |
<div> | |
<input type="text" id="Begin" placeholder="Begin"/> | |
<input type="text" id="End" placeholder="End"/> | |
<button id="Add">Add</button> | |
<span> | |
<input type="checkbox" id="AxisCheckbox"/> | |
show axis | |
</span> | |
</div> | |
<div>Input two points in space [e.g. (0, 0, 0) and (0, 0, 100)] to create a line segment on the 600x600 2d SVG canvas. The unit is pixel.</div> | |
<div>The points input will be transformed by matrix [[1, sqrt(2)/4, 0], [0, sqrt(2)/4, 1], [0, 0, 0]] so that they can be drawn on the 2d SVG canvas.</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment