AnyShapeFormula - Tryout
A first attempt at building a tool that can create a shape for an equation by combining several 2-dimensional functions.
Still needs a lot of work, but the principle should be understandable from this example.
/**
* Copyright Quasimondo ( http://wonderfl.net/user/Quasimondo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4zm4
*/
package {
import flash.text.TextField;
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
// Work in progress
// TODO: add more functional elements
// make an interactive drawing tool
// clean up function output
public class AnyShapeFormula extends Sprite {
private var components:Vector.<FunctionElement>;
public function AnyShapeFormula() {
init();
render( 0, 0.01 )
}
private function init():void
{
stage.scaleMode = "noScale";
stage.align = "TL";
components = new Vector.<FunctionElement>();
components.push( new Ellipse( 100, 100, 120, 50, 0, 1 ) );
components.push( new Ellipse( 200, 100, 120, 50, 0, 1 ) );
components.push( new Ellipse( 150, 150, 100, 100, -1, -0.2 ) );
components.push( new Ellipse( 150, 20, 10, 70, -0.32, -0.2 ) );
components.push( new Offset( -1.1 ) );
}
private function render( edge:Number, tolerance:Number ):void
{
var map:BitmapData = new BitmapData( 400, 400, true, 0 );
addChild( new Bitmap( map ) );
for ( var y:int = 0; y < map.height; y++ )
{
for ( var x:int = 0; x < map.width; x++ )
{
var value:Number = 0;
for ( var i:int = 0; i < components.length; i++ )
{
value += components[i].getValueAt( x, y );
}
if ( Math.abs( value - edge ) < tolerance )
map.setPixel32( x, y, 0xff000000 );
}
}
var tf:TextField = new TextField();
tf.autoSize = "left";
addChild( tf );
var formula:String = "";
for ( i = 0; i < components.length; i++ )
{
formula += (i>0?"+":"")+components[i].toString()+"\n";
}
formula = formula.replace("+-","-");
formula = formula.replace("+0)",")");
formula += "= 0";
tf.appendText(formula);
}
}
}
interface FunctionElement
{
function getValueAt( x:Number, y:Number ):Number;
function toString():String;
}
class Offset implements FunctionElement
{
private var o:Number;
function Offset( o:Number )
{
this.o = o;
}
public function getValueAt( x:Number, y:Number ):Number
{
return o;
}
public function toString():String
{
return o.toString();
}
}
class Ellipse implements FunctionElement
{
private var cx:Number;
private var cy:Number;
private var rx:Number;
private var ry:Number;
private var vc:Number;
private var ve:Number;
function Ellipse( cx:Number, cy:Number, rx:Number, ry:Number, vc:Number, ve:Number )
{
this.cx = cx;
this.cy = cy;
this.rx = rx;
this.ry = ry;
this.vc = vc;
this.ve = ve;
}
public function getValueAt( x:Number, y:Number ):Number
{
var dx:Number = (cx - x) / rx;
var dy:Number = (cy - y) / ry;
var d:Number = Math.sqrt( dx * dx + dy *dy );
return vc + (ve - vc) * d;
}
public function toString():String
{
return "((("+cx+"-x)/"+rx+"+("+cy+"-y)/"+ry+")*"+(ve-vc)+"+"+vc+")";
}
}