View Single Post
Old 11-29-2018, 12:18 PM   #18
wwwmaze
Human being with feelings
 
Join Date: Oct 2009
Posts: 99
Default

I finally managed to finish the triangular shaped kaleidoscope (its not that straightforward):


Hope it works for you guys. Have fun

PHP Code:
// Kaleidoscope (triangle base)
// v0.1

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

//@param1:preview 'preview' 0 0 1 0 1

//@param3:cxn 'center x' 0.5 0 1 0.5 0.01
//@param4:cyn 'center y' 0.5 0 1 0.5 0.01
//@param5:lenn 'length' 0.25 0 1 0.5 0.01
//@param6:rot 'rotate' 0 0 360 180 1
//@param7:sc 'scale' 1 0.01 5 2.5 0.01

//@param9:bg 'graylevel background' 0.5 0 1 0.5 0.01

///@param11:debug 'debug' 0 0 3 2 1

function gfx_line(x,y,x2,y2,tlocal(i,n,dx,dy,dxn,dyn) (
  
dx=(x2-x); dy=(y2-y);
  
n=abs(dx)+abs(dy);
  
dxn=dx/ndyn=dy/n;
  
i=0;
  
loop(n,
    
gfx_fillrect(x+i*dxn,y+i*dyn,t,t);
    
i+=1;
  );
  
gfx_fillrect(x2,y2,1,1);
);
function 
pt(x,yinstance(x,y) (
  
this.x=x;
  
this.y=y;
);
function 
pRot(cx,cy,alocal(tx,tyinstance(x,y) (
  
tx=x-cx;
  
ty=y-cy;
  
x=tx*cos(a)-ty*sin(a);
  
y=tx*sin(a)+ty*cos(a);
  
x+=cx;
  
y+=cy;
);

!
initdone ? (
  
sqrt3div6=sqrt(3)/6;
  
lrot=lcxn=lcyn=llenn=-1;
  
initdone=1;
);


lcxn!=cxn || lcyn!=cyn || llenn!=lenn || lrot!=rot || lsc!=sc || lproject_w!=project_w || lproject_h!=project_h ? (
  
cx=(cxn*project_w)|0;
  
cy=(cyn*project_h)|0;
  
lenNoSc=lenn*max(project_w,project_h);
  
  
trApoNoSc=(sqrt3div6*lenNoSc)|1// apothem/height of center
  
trHnoSc=trApoNoSc*3;
  
lenNoSc=(trApoNoSc/sqrt3div6)|1;
  
wslenNoSc=(sqrt(2*((4*trApoNoSc)^2))+2)|1;
  
  
p1.pt(cx-(lenNoSc-1)/2cy+trApoNoSc);
  
p2.pt(cx+(lenNoSc-1)/2cy+trApoNoSc);
  
p3.pt(cxcy-trApoNoSc*2);
  
  
rotrad=$pi/180*rot;
  
p1.pRot(cx,cy,rotrad);
  
p2.pRot(cx,cy,rotrad);
  
p3.pRot(cx,cy,rotrad);
  
  
linew=(max(project_w,project_h)/200)|1;
  
  
trApo=(sqrt3div6*lenNoSc*sc)|1;
  
trH=trApo*3;
  
len=(trApo/sqrt3div6)|1;
  
wslen=(sqrt(2*((4*trApo)^2))+2)|1;
  
  
startX=(wslen-len)/2;
  
l1.a=-2*trH/len;
  
l1.b=wslen/2+trApo-l1.a*startX;
  
l2.a=-l1.a;
  
l2.b=wslen/2+trApo-l2.a*(wslen+len)/2;
  
l3.b=wslen/2+trApo;
  
  
minX=min(p1.xmin(p2.x,p3.x)) -cx+project_w/2;
  
maxX=max(p1.xmax(p2.x,p3.x)) -cx+project_w/2;
  
minY=min(p1.ymin(p2.y,p3.y)) -cy+project_h/2;
  
maxY=max(p1.ymax(p2.y,p3.y)) -cy+project_h/2;
  
rotoDx=max(0,max(-minX,maxX-project_w));
  
rotoDy=max(0,max(-minY,maxY-project_h));
  
  
rwsw=project_w+2*rotoDx;
  
rwsh=project_h+2*rotoDy;
  
  
lcxn=cxnlcyn=cynllenn=lennlrot=rotlsc=sclproject_w=project_wlproject_h=project_h;
);



input=0;
colorspace='RGBA';

preview ? (
  
gfx_blit(input);
  
gfx_set(1,0,0);
  
gfx_fillrect(cx-(linew-1)/2,cy-(linew-1)/2,linew,linew); 
  
gfx_line(p1.x,p1.y,p2.x,p2.y,linew);
  
gfx_line(p2.x,p2.y,p3.x,p3.y,linew);
  
gfx_line(p3.x,p3.y,p1.x,p1.y,linew);
):(
  
gfx_set(bg);
  
// add margins to work with rotoblit()
  
gfx_dest ws1 gfx_img_resize(ws1,rwsw,rwsh,1);
  
gfx_blit(input,0,rotoDx,rotoDy,project_w,project_h);
  
  
// rotate
  
gfx_dest ws2 gfx_img_resize(ws2,rwsw,rwsh,1);
  
gfx_rotoblit(ws1,-rotrad,  0,0,rwsw,rwsh,  0,0,rwsw,rwsh0, -rwsw/2+cx+rotoDx, -rwsh/2+cy+rotoDy);
  
  
// crop to square (scaled)
  
gfx_dest ws3 gfx_img_resize(ws3,wslen,wslen,1);
  
gfx_blit(ws2,00,0,wslen,wslenrwsw/2-(wslenNoSc-1)/2,rwsh/2-(wslenNoSc-1)/2,wslenNoSc,wslenNoSc);
  
  
// set alpha (create triangle)
  
code="
  _1>wslen-1 ? (_2+=1;_1=0;);
  _2>wslen-1 ? _2=0;
  _2>l3.b || _2<l1.a*(_1+1)+l1.b || _2<l2.a*_1+l2.b ? a=0;
  _1+=1;
  "
;
  
gfx_evalrect(0,0,wslen,wslen,code);
  
  
// create template of 6 rotated/mirrored triangles
  
gfx_dest templates gfx_img_resize(templates,3*len,2*trH);
  
// upper left
  
gfx_blit(ws3,00,0,len,trH,  startX,(wslen-1)/2-2*trApo,len,trH);
  
  
// upper mid
  
gfx_dest rotTr gfx_img_resize(rotTr,wslen,wslen,1);
  
gfx_rotoblit(ws3,$pi/3,00wslenwslen 00wslenwslen,  0,   00);
  
gfx_dest mirrTr gfx_img_resize(mirrTr,wslen,wslen,1);
  
gfx_deltablit(rotTr0,0wslen,wslen,  wslen-1,0,  -1,00,1);

  
gfx_dest=templates;
  
gfx_blit(mirrTr,0len,0,len,trH,   startX, (wslen-1)/2-trApo+1len,trH);
  
gfx_evalrect(len,0,len,1,"a=255"); // remove some rotating artefacts (sporadic for some triangle length)
  
  // upper right
  
gfx_dest rotTr gfx_img_resize(rotTr,wslen,wslen,1);
  
gfx_rotoblit(ws3,$pi*2/3,00wslenwslen 00wslenwslen,  0,   00);
  
  
gfx_dest=templates;
  
gfx_blit(rotTr,02*len,0,len,trH,  startX,(wslen-1)/2-2*trApo+1,len,trH);
  
gfx_evalrect(2*len,trH-1,len,1,"a=255;"); // remove artefacts
  
  // create lower 3 triangles (mirror along x)
  
gfx_deltablit(templates0,trH3*len,trH,  0,trH-1,  1,00,-1);
  
  
  
// build image
  
gfx_dest=-1;
  
gfx_set(bg);gfx_fillrect(0,0,project_w,project_w);
  
gfx_mode=gfx_mode|0x10000;
  
  
// !debug ? (
    
curX=-(len-1)/2;
    
curY=0;
    
curTr=lTr=0;
    while(
curY<=project_h) (
      
curTemX=(curTr%3)*len;
      
curTemY=(curTr/3)<1?0:trH;
      
gfx_blit(templates,0curX,curY,len,trHcurTemX,curTemY,len,trH);
      
curX+=(len-1)/2;
      
curTr=(curTr+1)%6;
      
curX>project_w ? (
        
curY+=trH;
        
curX=-(len-1)/2;
        
curTr=lTr=lTr?0:3;
      );
    );
  
// ):debug==1 ? gfx_blit(ws2,1,0,0,project_w,project_h) : debug==2 ? gfx_blit(ws3,1,0,0,wslen,wslen) : debug==3 ? gfx_blit(templates,1,0,0,3*len,2*trH);
); 

Last edited by wwwmaze; 11-29-2018 at 12:23 PM.
wwwmaze is offline   Reply With Quote