squircle a square and a circle :) nicoptere forked:0favorite:3lines:163license : MIT License modified : 2011-04-10 21:41:14 Embed Tweet 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 ); } } } } Code Fullscreen Preview Fullscreen bradsedito xor andrewexex88.. 2D geometry graphics Point Math.cos Vector Math.PI Math.sin width push length Event Sprite int Number