squircle
a square and a circle :)
/**
* Copyright nicoptere ( http://wonderfl.net/user/nicoptere )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/md47
*/
package
{
import com.bit101.components.CheckBox;
import com.bit101.components.HUISlider;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
/**
* @author Nicolas Barradeau
* http://en.nicoptere.net
*/
public class Squircle extends Sprite
{
private var pi:Number = Math.PI;
private var pi_4:Number = pi / 4;
private var totalSlider:HUISlider;
private var radiusSlider:HUISlider;
private var radiusTSlider:HUISlider;
private var displayCircle:CheckBox;
private var displaySquircle:CheckBox;
private var displayInradii:CheckBox;
private var displayInterpolation:CheckBox;
public function Squircle()
{
var oy:int = -10;
radiusSlider = new HUISlider( this, 10, oy += 20, 'radius', update );
radiusSlider.minimum = 50;
radiusSlider.maximum = 250;
radiusSlider.value = 100;
totalSlider = new HUISlider( this, 10, oy+=20, 'total', update );
totalSlider.value = 8;
totalSlider.minimum = 3;
totalSlider.maximum = 96;
displayCircle = new CheckBox( this, 10, oy += 20, 'circle', update );
displaySquircle = new CheckBox( this, 10, oy += 20, 'squircle', update );
radiusTSlider = new HUISlider( this, 10, oy+=20, 'T', update );
radiusTSlider.maximum = 100;
radiusTSlider.value = 100;
displayInradii = new CheckBox( this, 10, oy += 20, 'inradii', update );
displayInterpolation = new CheckBox( this, 10, oy += 20, 'interpolation', update );
displayCircle.selected = displaySquircle.selected = displayInradii.selected = displayInterpolation.selected = true;
totalSlider.width = radiusSlider.width = radiusTSlider.width = 465;
update( null );
}
private function update( e:Event ):void
{
var r:Number = radiusSlider.value, rl:Number = 0;
var c:Point = new Point( 250, 300 ), p:Point, p1:Point;
var squircle:Vector.<Point> = new Vector.<Point>();
var radiusPoints:Vector.<Point> = new Vector.<Point>();
var interpolationPoints:Vector.<Point> = new Vector.<Point>();
var inradii:Vector.<Number> = new Vector.<Number>();
var angles:Vector.<Number> = new Vector.<Number>();
var a:Number = 0, ax:Number = 0, ay:Number = 0;
var i:int, total:int = int( totalSlider.value );
for ( i = 0; i < total; i++ )
{
a = ( Math.PI * 2 / total ) * i;
// stores angle
angles.push( a );
//computes quircle point
ax = get_ax( a );
ay = get_ay( a );
p = new Point( c.x + Math.cos( ax ) * r,
c.y + Math.sin( ay ) * r );
squircle.push( p );
//inradius calculation
rl = radiusLength( a, r );
rl = ( rl + ( r - rl ) * ( radiusTSlider.value * .01 ) );
p1 = new Point( c.x + Math.cos( a ) * rl,
c.y + Math.sin( a ) * rl );
radiusPoints.push( p1 );
//interpolation
interpolationPoints.push( new Point( p.x + ( p1.x - p.x ) * ( radiusTSlider.value * .01 ),
p.y + ( p1.y - p.y ) * ( radiusTSlider.value * .01 ) ) );
}
render( c, r, squircle, radiusPoints, interpolationPoints );
}
private function radiusLength( angle:Number, radius:Number ):Number
{
angle += pi_4;
while( angle < 0 ) angle += Math.PI * 2;
angle %= pi_4 * 2;
if ( angle <= pi_4 ) angle = pi_4 - angle;
if ( angle > pi_4 && angle <= pi_4 * 2 ) angle -= pi_4;
return ( radius * Math.cos( pi_4 ) ) / Math.cos( angle );
}
private function get_ax(a:Number):Number
{
if ( a >= pi * 2 - pi_4 || a <= pi_4 ) return pi_4;
if ( a >= pi - pi_4 && a <= pi + pi_4 ) return pi - pi_4;
return a;
}
private function get_ay(a:Number):Number
{
if ( a >= pi_4 && a <= pi - pi_4 ) return pi_4;
if ( a >= pi + pi_4 && a <= 2 * pi -pi_4 ) return pi * 2 - pi_4;
return a;
}
private function render( center:Point, radius:Number, squircle:Vector.<Point>, radiusPoints:Vector.<Point>, interpolationPoints:Vector.<Point> ):void
{
var p:Point;
var i:int;
graphics.clear();
//circle
if ( displayCircle.selected )
{
graphics.lineStyle( 0, 0xCCCCCC );
graphics.drawCircle( center.x, center.y, radius );
for ( i = 0; i < totalSlider.value; i++ )
{
var a:Number = (Math.PI * 2 / totalSlider.value ) * i;
p = new Point( center.x + Math.cos( a ) * radius,
center.y + Math.sin( a ) * radius );
graphics.lineStyle( 0 );
graphics.drawCircle( p.x, p.y, 2 );
graphics.lineStyle( 0, 0xCCCCCC );
graphics.moveTo( p.x, p.y );
graphics.lineTo( center.x, center.y );
}
}
//squircle
if ( displaySquircle.selected )
{
graphics.lineStyle( 0, 0xFF0000 );
graphics.moveTo( squircle[ 0 ].x, squircle[ 0 ].y );
for each( p in squircle )
{
graphics.lineTo( p.x, p.y );
graphics.drawCircle( p.x, p.y, 2 );
graphics.moveTo( p.x, p.y );
}
graphics.lineTo( squircle[ 0 ].x, squircle[ 0 ].y );
}
//inradii
if ( displayInradii.selected )
{
graphics.lineStyle( 0, 0xFFCC00 );
graphics.moveTo( radiusPoints[ 0 ].x, radiusPoints[ 0 ].y );
for each( p in radiusPoints )
{
graphics.lineTo( p.x, p.y );
graphics.drawCircle( p.x, p.y, 2 );
graphics.moveTo( p.x, p.y );
}
graphics.lineTo( radiusPoints[ 0 ].x, radiusPoints[ 0 ].y );
}
//interpolation
if ( displayInterpolation.selected )
{
if ( displaySquircle.selected && displayInradii.selected )
{
graphics.moveTo( interpolationPoints[ 0 ].x, interpolationPoints[ 0 ].y );
for ( i = 0; i < interpolationPoints.length; i++ )
{
graphics.lineStyle( 0, 0x0033CC, .5 );
graphics.moveTo( squircle[i].x, squircle[i].y );
graphics.lineTo( radiusPoints[i].x, radiusPoints[i].y );
p = interpolationPoints[ i ];
graphics.beginFill( 0x0033CC );
graphics.drawCircle( p.x, p.y, 2 );
graphics.endFill();
}
}
graphics.lineStyle( 0, 0x0033CC );
graphics.moveTo( interpolationPoints[ 0 ].x, interpolationPoints[ 0 ].y );
for each( p in interpolationPoints )
{
graphics.lineTo( p.x, p.y );
}
graphics.lineTo( interpolationPoints[ 0 ].x, interpolationPoints[ 0 ].y );
}
}
}
}