|
<HTML xmlns:v="urn:schemas-microsoft-com:vml">
<STYLE>
v\:* { behavior: url(#default#vml); }
</STYLE>
<head>
<style>
button { font-face:arial;font-size:10px;border:1px solid black;}
input { font-face:arial;font-size:10px;border:1px solid black;}
</style>
</head>
<body onload="drawPolygon();">
<script>
/********************************************/
/*********************************************
N-GON
BY JOEY FORTUNA
http://neoncelery.com
COPYRIGHT (C) 2004, Joey Fortuna
PERMISSION TO USE GRANTED PROVIDING THE
ADOPTER INCLUDES THIS NOTICE
*********************************************/
/********************************************/
var nSides=6;
var iRadius=150;
var iStartX=300;
var iStartY=400;
var nGon;
var moveX=0;
var oldMoveX=0;
var moveY=0;
var oldMoveY=0;
var xRotate=0;
var yRotate=0;
var bRightMouseDown=false;
var bLeftMouseDown=false;
var iDistance=525;
var iFov=590;
var iLineYDiff=250;
function drawPolygon() {
nGon=new nGonObj(nSides,iStartX,iStartY,iRadius);
getWinSize();
}
function getWinSize()
{
winX = document.body.clientWidth - 10;
winY = document.body.clientHeight - 10;
nGon.centerX=winX/2;
nGon.centerY=winY/2;
if (nGon.is2D) nGon.draw2D();
else if (nGon.is3D) nGon.draw3D();
}
function changeSides(dir) {
var newSides=document.ngonform.NumSides.value;
newSides=(dir==1)?parseInt(newSides)+1:parseInt(newSides)-1;
if (newSides<3) newSides=3;
document.ngonform.NumSides.value=newSides;
nGon.changeSides(newSides);
return true;
}
function nGonPointObj(tid) {
this.id=tid;
this.redraw=NGON_POINT_redraw;
var newObj;
newObj=document.createElement("div");
newObj.id="nGonPoint"+tid;
newObj.innerHTML=tid;
newObj.style.position="absolute";
newObj.style.textAlign="center";
newObj.style.fontWeight="bold";
newObj.style.fontFamily="arial";
newObj.style.display="none";
newObj.style.width="20px";
this.divObj=document.body.appendChild(newObj);
this.divObj.style.cursor="hand";
this.x=0;
this.y=0;
this.z=0;
this.scrX=0;
this.scrY=0;
this.divObj.style.top=this.y+"px";
this.divObj.style.left=this.x+"px";
this.parallel=false;
return this;
}
function NGON_POINT_redraw() {
this.divObj.style.left=this.scrX+"px";
this.divObj.style.top=this.scrY+"px";
}
function nGonObj(nSides,iStartX,iStartY,iRadius) {
this.rotate2DAngle=0;
this.radiusLength=iRadius;
this.centerX=iStartX;
this.centerY=iStartY;
this.centerZ=0;
this.name="NGonObject";
this.is2D=true;
this.is3D=false;
this.nPoints=new Array();
this.nLines=new Array();
this.angleDivisor=0;
this.angle=0;
this.nSides=nSides;
this.draw2D=NGON_draw2D;
this.draw3D=NGON_draw3D;
this.changeSides=NGON_changeSides;
this.rotate2D=NGON_rotate2D;
this.rotate3D=NGON_rotate3D;
this.clear=NGON_clear;
this.add=NGON_add;
this.setup=NGON_setup;
this.drawLines2D=NGON_drawLines2D;
this.drawLines3D=NGON_drawLines3D;
this.xRadius=iRadius;
this.yRadius=iRadius;
this.setup();
}
function NGON_changeSides(nNewSides) {
this.clear();
this.nSides=nNewSides;
this.setup();
if (nGon.is2D) nGon.draw2D();
else if (nGon.is3D) nGon.draw3D();
}
function NGON_setup() {
this.angleDivisor=this.nSides-2;
this.angle=(this.angleDivisor*Math.PI)/this.nSides;
for (i=0;i<(2*this.nSides)+1;i++) {
var obj,objLine;
obj=new nGonPointObj(i);
objLine = document.body.appendChild(document.createElement("v:Line"));
objLine.style.position="absolute";
objLine.strokecolor = "black";
this.nLines[this.nLines.length]=objLine;
this.add(obj);
}
for (i=0;i<this.nSides;i++) {
objLine = document.body.appendChild(document.createElement("v:Line"));
objLine.style.position="absolute";
objLine.strokecolor = "black";
this.nLines[this.nLines.length]=objLine;
}
return this;
}
function NGON_clear() {
for (i=this.nPoints.length-1;i>=0;i--) {
this.nPoints[i].divObj.style.display="none";
this.nPoints[i].divObj=null;
this.nPoints.pop(i)
}
while (this.nPoints.length>0) this.nPoints.pop(0);
for (i=this.nLines.length-1;i>=0;i--) {
this.nLines[i].style.display="none";
this.nLines[i]=null;
this.nLines.pop(i)
}
while (this.nLines.length>0) this.nLines.pop(0);
}
function NGON_add(obj) {
this.nPoints[this.nPoints.length]=obj;
}
function NGON_drawLines2D() {
for (i=1;i<this.nSides+1;i++) {
var pointObj=this.nPoints[i];
this.nLines[i].from=pointObj.scrX+"px,"+(pointObj.scrY-iLineYDiff)+"px";
if (i<this.nSides+1) this.nLines[i-1].to=pointObj.scrX+","+(pointObj.scrY-iLineYDiff);
}
this.nLines[this.nSides].to=this.nLines[1].from;
this.nLines[0].from=this.nLines[1].from;
}
function NGON_drawLines3D () {
for (i=1;i<this.nSides;i++) {
var pointObj=this.nPoints[i];
this.nLines[i].from=pointObj.scrX+"px,"+(pointObj.scrY-iLineYDiff)+"px";
if (i<this.nSides) this.nLines[i-1].to=pointObj.scrX+","+(pointObj.scrY-iLineYDiff);
}
this.nLines[0].style.display="none";
for (i=this.nSides;i<(2*this.nSides)+1;i++) {
var pointObj=this.nPoints[i];
this.nLines[i].from=pointObj.scrX+"px,"+(pointObj.scrY-iLineYDiff)+"px";
if (i<(2*this.nSides)+1) this.nLines[i-1].to=pointObj.scrX+","+(pointObj.scrY-iLineYDiff);
}
this.nLines[this.nSides].to=this.nLines[1].from;
this.nLines[(2*this.nSides)].to=this.nLines[this.nSides+1].from;
for (i=(2*this.nSides+1);i<(3*this.nSides);i++) {
var pointObj=this.nPoints[i-(2*this.nSides)+1];
var bpointObj=this.nPoints[i-this.nSides+1];
this.nLines[i].from=pointObj.scrX+"px,"+(pointObj.scrY-iLineYDiff)+"px";
this.nLines[i].to=bpointObj.scrX+"px,"+(bpointObj.scrY-iLineYDiff)+"px";
}
this.nLines[(3*this.nSides)].from=this.nLines[this.nSides+1].from;
this.nLines[(3*this.nSides)].to=this.nLines[1].from;
}
function NGON_draw2D() {
var i=0;
centerPoint.style.top=this.centerY+"px";
centerPoint.style.left=this.centerX+"px";
centerPoint.style.display="inline";
for (i=1;i<this.nSides+1;i++) {
this.nPoints[i].divObj.style.display="inline";
var pointObj=this.nPoints[i];
pointObj.x=this.centerX+(this.radiusLength*Math.cos((Math.PI-this.angle)*(i-1)));
pointObj.y=this.centerY+(this.radiusLength*Math.sin((Math.PI-this.angle)*(i-1)));
pointObj.scrX=pointObj.x;
pointObj.scrY=pointObj.y;
this.nPoints[i].redraw();
}
if (this.is2D) this.drawLines2D();
else if (this.is3D) this.drawLines3D();
}
function NGON_draw3D() {
var i=0;
centerPoint.style.top=this.centerY+"px";
centerPoint.style.left=this.centerX+"px";
centerPoint.style.display="none";
for (i=1;i<this.nPoints.length;i++) {
if (i>this.nSides) this.nPoints[i].z=-100;
else this.nPoints[i].z=100;
this.nPoints[i].divObj.style.display="inline";
var pointObj=this.nPoints[i];
pointObj.x=this.centerX+(this.radiusLength*Math.cos((Math.PI-this.angle)*(i-1)));
pointObj.y=this.centerY+(this.radiusLength*Math.sin((Math.PI-this.angle)*(i-1)));
pointObj.scrX=pointObj.x
pointObj.scrY=pointObj.y;
this.nPoints[i].redraw();
}
this.rotate3D(0,0,0);
}
function stepFade(inc,colr) {
inc=inc*2;
if (colr.charAt(0)=='#') colr = colr.substring(1);
var r = HexToInt(colr.substring(0,2));
var g = HexToInt(colr.substring(2,4));
var b = HexToInt(colr.substring(4,6));
newinc=parseInt((255*inc)<=255?255*inc:255);
r=100-(100*(newinc/255));
g=100-(100*(newinc/255));
b=100-(100*(newinc/255));
return "#" + IntToHex(r) + IntToHex(g) + IntToHex(b);
}
function IntToHex(n) {
var result = parseInt(n).toString(16);
if (result.length==1) result = "0"+result;
return result;
}
function HexToInt(hex) {
return parseInt(hex, 16);
}
function NGON_rotate3D(xRotate,yRotate,iZoom) {
var xRotateAngle=(-yRotate)*(2*Math.PI)/180;
var yRotateAngle=(-xRotate)*(2*Math.PI)/180;
var zRotateAngle=0;//xRotate*(2*Math.PI)/180;
for (i=1;i<this.nPoints.length;i++) {
var pointObj=this.nPoints[i];
var x=pointObj.x-this.centerX;
var y=this.centerY-pointObj.y;
var z=pointObj.z;
var newy=y;
var newx=x;
var newz=z;
newy=(y*Math.cos(xRotateAngle))-(z*Math.sin(xRotateAngle)); // X axis
newz=(z*Math.cos(xRotateAngle))+(y*Math.sin(xRotateAngle));
y=newy;
z=newz;
newz=(z*Math.cos(yRotateAngle))-(x*Math.sin(yRotateAngle)); // Y axis
newx=(x*Math.cos(yRotateAngle))+(z*Math.sin(yRotateAngle));
z=newz;
x=newx;
newx=(x*Math.cos(zRotateAngle))-(y*Math.sin(zRotateAngle)); // Z axis
newy=(y*Math.cos(zRotateAngle))+(x*Math.sin(zRotateAngle));
x=newx;
y=newy;
/*
var fSize=10;
// FONT SIZE ADJUSTMENT //
if (!this.parallel) {
fSize=5*(parseInt(1000/(iDistance-newz)));
pointObj.divObj.style.fontSize=fSize+"px";
}
else {
fSize=parseInt(12*((Math.abs(z)/119)));
fSize=parseInt(fSize/(6*(Math.abs(z)/z)));
fSize=(16+(4*fSize));
if (fSize<=0) fSize=1;
pointObj.divObj.style.fontSize=fSize+"px";
}
*/
// PARALLEL PROJECTION //
pointObj.x=newx+this.centerX;
pointObj.y=this.centerY-newy;
// PERSPECTIVE PROJECTION //
// ** DO THIS WITH X/Y VALUES
// ** DERIVED FROM PARALLEL ROTATION
// ** BUT DON''T UPDATE POINTOBJ.X/Y
// ** WITH PROJECTED RESULTS!
iDistance+=iZoom;
if (!this.parallel) {
pointObj.scrX = ((iFov*newx) / (iDistance-(newz+this.centerZ))) + (this.centerX);
pointObj.scrY = (this.centerY) - ((iFov*newy) / (iDistance-(newz+this.centerZ)));
}
else {
pointObj.scrX=pointObj.x;
pointObj.scrY=pointObj.y;
}
pointObj.z=newz;
this.nPoints[i].redraw();
}
this.drawLines3D();
}
function NGON_rotate2D(xRotate) {
var tAngle=xRotate*(5*Math.PI)/180;
for (i=1;i<this.nSides+1;i++) {
var pointObj=this.nPoints[i];
var tx=pointObj.x-this.centerX;
var ty=this.centerY-pointObj.y;
var x,y=0;
x=((tx)*Math.cos(tAngle))-((ty)*Math.sin(tAngle));
y=((ty)*Math.cos(tAngle))+((tx)*Math.sin(tAngle));
pointObj.x=this.centerX+x;
pointObj.y=this.centerY-y;
pointObj.scrX=pointObj.x;
pointObj.scrY=pointObj.y;
/** ROTATING ABOUT THE CENTER ***/
//pointObj.x=this.centerX+((this.radiusLength*Math.cos(xRotate*this.rotate2DAngle+((Math.PI-this.angle)*(i-1)))));
//pointObj.y=this.centerY+((this.radiusLength*Math.sin(xRotate*this.rotate2DAngle+((Math.PI-this.angle)*(i-1)))));
this.nPoints[i].redraw();
}
this.drawLines2D();
}
function MoveHandler(e) {
moveX = window.event.x + document.body.scrollLeft;
moveY = window.event.y;
if (moveX<oldMoveX) xRotate=1;
else if(moveX>oldMoveX) xRotate=-1;
else xRotate=0;
if (moveY<oldMoveY) yRotate=1;
else if(moveY>oldMoveY) yRotate=-1;
else yRotate=0;
oldMoveX=moveX;
oldMoveY=moveY;
if (bLeftMouseDown && xRotate!=0) {
if (xRotate>0) changeSides(0);
else changeSides(1);
if (nGon.is2D) nGon.draw2D();
else if (nGon.is3D) nGon.draw3D();
}
else if (bRightMouseDown && (xRotate!=0 || yRotate!=0)) {
if (nGon.is2D ) nGon.rotate2D(xRotate);
else if (nGon.is3D) nGon.rotate3D(xRotate,yRotate,0);
}
else if (nGon) {
for (i=1;i<nGon.nPoints.length;i++) {
var objPoint=nGon.nPoints[i];
if (moveX>objPoint.scrX-20 &&
moveX<objPoint.scrX+20 &&
moveY>objPoint.scrY-20 &&
moveY<objPoint.scrY+20)
objPoint.divObj.style.color="#ff0000";
else if (objPoint.divObj.style.color=="#ff0000") objPoint.divObj.style.color="#000000";
}
}
}
function KeyHandler(e) {
window.status=window.event.keyCode;
switch(window.event.keyCode) {
case 50:
dimension.innerHTML="2D";
dimension.style.color="#000099";
nGon.is2D=true;
nGon.is3D=false;
nGon.nSides=6;
document.ngonform.NumSides.value=6;
nGon.clear();
nGon.setup();
nGon.draw2D();
break;
case 51:
dimension.innerHTML="3D";
dimension.style.color="#990000";
nGon.is2D=false;
nGon.is3D=true;
nGon.nSides=6;
document.ngonform.NumSides.value=6;
nGon.clear();
nGon.setup();
nGon.draw3D();
break;
case 16: // strafe left;
nGon.centerX-=10;
if (nGon.is3D) nGon.rotate3D(0,0,0);
break;
case 67: // strafe right;
nGon.centerX+=10;
if (nGon.is3D) nGon.rotate3D(0,0,0);
break;
case 80: // toggle parallel
if (nGon.is3D) {
projection.style.color=((nGon.parallel)?"#990000":"#000099");
projection.innerHTML=((nGon.parallel)?"perspective projection":"parallel projection");
nGon.parallel=!nGon.parallel;
nGon.rotate3D(0,0,0);
}
break;
case 37:
if (nGon.is3D) nGon.rotate3D(1,0,0);
break;
case 38:
if (nGon.is3D) nGon.rotate3D(0,1,0);
break;
case 39:
if (nGon.is3D) nGon.rotate3D(-1,0,0);
break;
case 40:
if (nGon.is3D) nGon.rotate3D(0,-1,0);
break;
case 83:
if (nGon.is3D) nGon.rotate3D(0,0,-1);
break;
case 90:
if (nGon.is3D) nGon.rotate3D(0,0,1);
break;
default:
break;
}
}
function PressHandler(e) {
mousegrabber.setCapture(true);
if (window.event.button==1) bLeftMouseDown=true;
else if (window.event.button==2) {bRightMouseDown=true;}
return false;
}
function UpHandler(e) {
mousegrabber.releaseCapture();
bLeftMouseDown=false;
bRightMouseDown=false;
return false;
}
window.onresize = getWinSize;
document.onmouseup=UpHandler;
document.onkeydown = KeyHandler;
document.onmousemove = MoveHandler;
document.onmousedown = PressHandler;
document.oncontextmenu=new Function("return false;");
</script>
<div onmouseup="this.releaseCapture();" id="mousegrabber" style="border:none;font-family:arial;">
<table width=100% cellpadding=0 cellspacing=0>
<tr>
<td>N-Gon</td>
<td align=right><font style="font-size:12px;">
<script src="nav.js"></script>
</td>
</tr>
</table>
<font style="font-size:10px;">
<table><tr>
<td><font style="font-size:10px;"><b>p</b> </td><td><font style="font-size:10px;">- toggles parallel / perspective viewing</td></tr><tr>
<td><font style="font-size:10px;"><b>s</b> </td><td><font style="font-size:10px;">- zoom in</td></tr><tr>
<td><font style="font-size:10px;"><b>z</b> </td><td><font style="font-size:10px;">- zoom out</td></tr><tr>
<td><font style="font-size:10px;"><b>2</b> </td><td><font style="font-size:10px;">- 2D mode</td></tr><tr>
<td><font style="font-size:10px;"><b>3</b> </td><td><font style="font-size:10px;">- 3D mode</td></tr><tr>
<td><font style="font-size:10px;"><b>left-click & drag</b> </td><td><font style="font-size:10px;">- increase or decrease number of sides</td></tr><tr>
<td><font style="font-size:10px;"><b>right-click & drag</b> </td><td><font style="font-size:10px;">- rotate</td></tr>
</tr>
</td>
</table>
viewing in: <span id="dimension" style="font-size:10px;font-weight:bold;color:#000099;">2D</span>
</font>
<div id="projection" style="font-size:10px;font-weight:bold;color:#990000;">perspective projection</div>
<form name=ngonform style="display:inline;">
<font style="font-size:10px;">number of sides: <input type=text name="NumSides" size=2 onfocus="blur();">
</form>
</div>
<div id="centerPoint" style="position:absolute;top=100px;left=100px;display:none;">@</div>
<script>
document.ngonform.NumSides.value=nSides;
</script>
</body>
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.