Skip to content

Instantly share code, notes, and snippets.

@tmpvar
Created April 18, 2015 20:35
Show Gist options
  • Save tmpvar/035547417655733a43d2 to your computer and use it in GitHub Desktop.
Save tmpvar/035547417655733a43d2 to your computer and use it in GitHub Desktop.
requirebin sketch
var fc = require('fc');
var vis = require('vishull2d');
var TAU = Math.PI*2;
var center = [0, 0];
var walls = [
[[-10, -10], [10, -10]],
[[10, 100], [10, -10]],
[[10, 100], [-200, 100]],
[[-200, 100], [-200, -100]],
];
var lights = [
[50 , -50, { on: true, color: 'rgba(255, 255, 255, 0.1)'}],
[100, -50, { on: true, color: 'rgba(0, 0, 255, 0.1)'}],
[-100, -100, { on: true, color: 'rgba(255, 0, 255, 0.1)'}],
];
var ctx = fc(function() {
var w = ctx.canvas.width;
var h = ctx.canvas.height;
var hw = w/2;
var hh = h/2;
ctx.clear();
ctx.save();
ctx.translate(hw, hh);
ctx.lineWidth = 5;
ctx.lineCap = "round"
ctx.strokeStyle = 'orange';
walls.forEach(function(wall) {
ctx.beginPath();
ctx.moveTo(wall[0][0], wall[0][1]);
ctx.lineTo(wall[1][0], wall[1][1]);
ctx.stroke();
});
lights.forEach(function(light) {
ctx.save();
ctx.translate(light[0], light[1]);
ctx.fillStyle=light[2].color;
ctx.strokeStyle = 'white'
ctx.beginPath();
ctx.arc(0, 0, 10, 0, TAU, false);
ctx.fill();
ctx.lineWidth = 1.
light[2].on && ctx.stroke();
ctx.restore();
if (!light[2].on) {
return;
}
ctx.save();
// ctx.globalCompositionOperation = 'lighter'
var res = vis(walls, light);
ctx.fillStyle = light[2].color;
ctx.beginPath();
ctx.moveTo(light[0][0], light[0][1]);
res.forEach(function(s) {
ctx.lineTo(s[0], s[1]);
});
ctx.fill();
ctx.restore();
});
ctx.restore();
});
var mouse = [0, 0];
var dragging = false;
var moved = false;
document.addEventListener('mousemove', function(e) {
ctx.dirty();
mouse[0] = e.clientX - (ctx.canvas.width/2)|0;
mouse[1] = e.clientY - (ctx.canvas.height/2)|0;
if (dragging !== false) {
lights[dragging][0] = mouse[0];
lights[dragging][1] = mouse[1];
moved = true;
}
});
document.addEventListener('mousedown', function() {
lights.forEach(function(light, i) {
var dx = light[0] - mouse[0];
var dy = light[1] - mouse[1];
if (Math.sqrt(dx*dx + dy*dy) <= 10) {
dragging = i;
}
});
ctx.dirty();
});
document.addEventListener('mouseup', function() {
if (!moved) {
lights[dragging][2].on = !lights[dragging][2].on;
}
dragging = false;
moved = false;
ctx.dirty();
})
require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({fc:[function(require,module,exports){(function(){var performance=window.performance||{};var performanceNow=performance.now||performance.now||performance.mozNow||performance.msNow||performance.oNow||performance.webkitNow||function(){return(new Date).getTime()};performanceNow=performanceNow.bind(performance);function fc(fn,autorun,dimensions){document.body.style.margin="0px";document.body.style.padding="0px";var canvas=document.createElement("canvas");document.body.appendChild(canvas);canvas.style.position="absolute";canvas.style.left="0px";canvas.style.top="0px";var ctx;dimensions=dimensions||2;if(dimensions===2){ctx=canvas.getContext("2d")}else if(dimensions===3){ctx=canvas.getContext("webgl")||canvas.getContext("experimental-webgl")}if(!ctx){return}var last=performanceNow(),request;function requestFrame(){if(request===null){request=requestAnimationFrame(tick)}}function tick(){request=null;var time=performanceNow();var delta=time-last;last=time;ctx.reset();dimensions===2&&ctx.save();fn&&fn.call(ctx,delta);dimensions===2&&ctx.restore();if(autorun){requestFrame()}}if(dimensions===2){ctx.reset=function fc_reset(){canvas.width=0;canvas.width=window.innerWidth;canvas.height=window.innerHeight};ctx.clear=function fc_clear(color){var orig=ctx.fillStyle;ctx.fillStyle=color||"#223";ctx.fillRect(0,0,canvas.width,canvas.height);ctx.fillStyle=orig}}else{ctx.reset=function fc_reset(){if(canvas.width!==window.innerWidth){canvas.width=window.innerWidth}if(canvas.height!==window.innerHeight){canvas.height=window.innerHeight}}}setTimeout(tick,0);ctx.dirty=function fc_dirty(){last=performanceNow();requestFrame()};ctx.stop=function fc_stop(){autorun=false;request&&cancelAnimationFrame(request);request=null};ctx.start=function fc_start(){autorun=true;requestFrame()};(window.attachEvent||window.addEventListener)("resize",ctx.dirty);ctx.reset();ctx.canvas=canvas;return ctx}if(typeof module!=="undefined"&&typeof module.exports!=="undefined"){module.exports=fc}if(typeof window!=="undefined"){window.fc=window.fc||fc}})()},{}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";function quadrant(x,y){if(x>0){if(y>=0){return 1}else{return 4}}else if(x<0){if(y>=0){return 2}else{return 3}}else if(y>0){return 1}else if(y<0){return 3}return 0}function compareSlope(a,b){var ax=a[0],ay=a[1],bx=b[0],by=b[1],d=quadrant(ax,ay)-quadrant(bx,by);if(d){return d}var p=ax*by,q=ay*bx;if(p>q){return-1}if(p<q){return 1}return 0}module.exports=compareSlope},{}],vishull2d:[function(require,module,exports){"use strict";var compareSlope=require("compare-slope");var EPSILON=1e-8;var MAX_F=1/EPSILON;function segIntersect(s,pt,dx,dy){var s0=s[0],s1=s[1],nx=s1[0]-s0[0],ny=s1[1]-s0[1],ax=s0[0]-pt[0],ay=s0[1]-pt[1],nn=ay*nx-ax*ny,dd=dy*nx-dx*ny;return[dx*nn/dd+pt[0],dy*nn/dd+pt[1]]}function approxEq(x,y){return Math.abs(x-y)<=EPSILON*Math.min(Math.abs(x),Math.abs(y))}function approxCollinear(a,b,c){return approxEq(a[0]*b[1]+b[0]*c[1]+c[0]*a[1],a[0]*c[1]+b[0]*a[1]+c[0]*b[1])}function pointsEqual(a,b){return approxEq(a[0],b[0])&&approxEq(a[1],b[1])}function cooriented(a,b,p,q){var pxqy=p[0]*q[1],pyqx=p[1]*q[0],ap=a[0]*p[1]+q[0]*a[1]+pxqy,an=a[0]*q[1]+p[0]*a[1]+pyqx,bp=b[0]*p[1]+q[0]*b[1]+pxqy,bn=b[0]*q[1]+p[0]*b[1]+pyqx;return ap>an===bp>bn||approxEq(ap,an)||approxEq(bp,bn)}function createVisibleHull(segments,pt){var points=[],os=segments.length;segments=segments.slice(0);segments.push([[MAX_F+pt[0],MAX_F+pt[1]],[-MAX_F+pt[0],MAX_F+pt[1]]]);segments.push([[-MAX_F+pt[0],MAX_F+pt[1]],[-MAX_F+pt[0],-MAX_F+pt[1]]]);segments.push([[-MAX_F+pt[0],-MAX_F+pt[1]],[MAX_F+pt[0],-MAX_F+pt[1]]]);segments.push([[MAX_F+pt[0],-MAX_F+pt[1]],[MAX_F+pt[0],MAX_F+pt[1]]]);for(var i=0,ns=segments.length;i<ns;++i){var s=segments[i],ax=s[0][0]-pt[0],ay=s[0][1]-pt[1],bx=s[1][0]-pt[0],by=s[1][1]-pt[1];if(approxEq(ax,0)&&approxEq(ay,0)||approxEq(bx,0)&&approxEq(by,0)||approxEq(ax,bx)&&approxEq(ay,by)){continue}var a=[ax,ay,i,false],b=[bx,by,i,true];if(by<0&&ay>0){var dy=by-ay,dx=bx-ax,x=ax-ay*dx/dy;if(x>EPSILON){var q=[x,0,i,false];if(!pointsEqual(b,q)){b[3]=false;points.push(b)}if(!pointsEqual(a,q)){a[3]=true;points.push(q);points.push(a)}continue}}if(ay<0&&by>0){var dy=ay-by,dx=ax-bx,x=bx-by*dx/dy;if(x>EPSILON){var q=[x,0,i,false];if(!pointsEqual(a,q)){points.push(a)}if(!pointsEqual(b,q)){points.push(q);points.push(b)}continue}}if(bx>0&&ay<0&&approxEq(by,0)){points.push(a);continue}if(ax>0&&by<0&&approxEq(ay,0)){b[3]=false;points.push(b);continue}var sign=compareSlope(a,b);if(sign<0){points.push(a);points.push(b)}else if(sign>0){b[3]=false;points.push(b);a[3]=true;points.push(a)}}points.sort(compareSlope);points.push([1,0,-1,true]);var vis_hull=[],active=[],pseg=-1,result=[0,0];for(var i=0,np=points.length;i<np;++i){var event=points[i];if(event[3]){if(event[2]>=0){active[active.indexOf(event[2])]=active[active.length-1];active.pop()}}else{active.push(event[2])}if(i<np-1&&compareSlope(points[i],points[i+1])===0){continue}var min_n=Infinity,min_d=1,min_a=-1,dx=event[0],dy=event[1];for(var j=0,na=active.length;j<na;++j){var a=active[j],s=segments[a],s0=s[0],s1=s[1],nx=s1[0]-s0[0],ny=s1[1]-s0[1],ax=pt[0]-s0[0],ay=pt[1]-s0[1],nn=ay*nx-ax*ny,dd=dx*ny-dy*nx;if(dd<0){nn=-nn;dd=-dd}if(nn>0){var xx=min_n*dd,yy=min_d*nn;if(approxEq(xx,yy)){s=segments[min_a];if(cooriented(pt,s0,s[0],s[1])&&cooriented(pt,s1,s[0],s[1])){min_a=a}}else if(xx>yy){min_n=nn;min_d=dd;min_a=a}}}if(min_a<0){continue}var hull_n=vis_hull.length,i1=[dx*min_n/min_d+pt[0],dy*min_n/min_d+pt[1]];if(hull_n===0){vis_hull.push(i1)}else if(pseg!==min_a||event[2]<0){var s=segments[min_a],i0=segIntersect(segments[pseg],pt,dx,dy);if(!pointsEqual(i0,vis_hull[hull_n-1])){vis_hull.push(i0);if(!pointsEqual(i0,i1)){vis_hull.push(i1)}}else if(!pointsEqual(i1,vis_hull[hull_n-1])){vis_hull.push(i1)}}pseg=min_a}var hull_n=vis_hull.length;if(pointsEqual(vis_hull[hull_n-1],vis_hull[0])){vis_hull.pop();--hull_n}return vis_hull}module.exports=createVisibleHull},{"compare-slope":1}]},{},[]);var fc=require("fc");var vis=require("vishull2d");var TAU=Math.PI*2;var center=[0,0];var walls=[[[-10,-10],[10,-10]],[[10,100],[10,-10]],[[10,100],[-200,100]],[[-200,100],[-200,-100]]];var lights=[[50,-50,{on:true,color:"rgba(255, 255, 255, 0.1)"}],[100,-50,{on:true,color:"rgba(0, 0, 255, 0.1)"}],[-100,-100,{on:true,color:"rgba(255, 0, 255, 0.1)"}]];var ctx=fc(function(){var w=ctx.canvas.width;var h=ctx.canvas.height;var hw=w/2;var hh=h/2;ctx.clear();ctx.save();ctx.translate(hw,hh);ctx.lineWidth=5;ctx.lineCap="round";ctx.strokeStyle="orange";walls.forEach(function(wall){ctx.beginPath();ctx.moveTo(wall[0][0],wall[0][1]);ctx.lineTo(wall[1][0],wall[1][1]);ctx.stroke()});lights.forEach(function(light){ctx.save();ctx.translate(light[0],light[1]);ctx.fillStyle=light[2].color;ctx.strokeStyle="white";ctx.beginPath();ctx.arc(0,0,10,0,TAU,false);ctx.fill();ctx.lineWidth=1;light[2].on&&ctx.stroke();ctx.restore();if(!light[2].on){return}ctx.save();var res=vis(walls,light);ctx.fillStyle=light[2].color;ctx.beginPath();ctx.moveTo(light[0][0],light[0][1]);res.forEach(function(s){ctx.lineTo(s[0],s[1])});ctx.fill();ctx.restore()});ctx.restore()});var mouse=[0,0];var dragging=false;var moved=false;document.addEventListener("mousemove",function(e){ctx.dirty();mouse[0]=e.clientX-ctx.canvas.width/2|0;mouse[1]=e.clientY-ctx.canvas.height/2|0;if(dragging!==false){lights[dragging][0]=mouse[0];lights[dragging][1]=mouse[1];moved=true}});document.addEventListener("mousedown",function(){lights.forEach(function(light,i){var dx=light[0]-mouse[0];var dy=light[1]-mouse[1];if(Math.sqrt(dx*dx+dy*dy)<=10){dragging=i}});ctx.dirty()});document.addEventListener("mouseup",function(){if(!moved){lights[dragging][2].on=!lights[dragging][2].on}dragging=false;moved=false;ctx.dirty()});
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"fc": "1.4.3",
"vishull2d": "0.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment