Skip to content

Instantly share code, notes, and snippets.

@910JQK
Last active August 29, 2015 14:15
Show Gist options
  • Save 910JQK/1c1bb02be78da29b4211 to your computer and use it in GitHub Desktop.
Save 910JQK/1c1bb02be78da29b4211 to your computer and use it in GitHub Desktop.
斜二測畫法 (a space geometric projection method)
<!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