4 Stimmen

Wie zeichnet man einen sinoidalen Liniengraphen?

Ich versuche, ein statisches Diagramm basierend auf einem Array von Zahlen zu zeichnen. Dieses Diagramm sollte schön glatt und sinusartig sein. Die unteren Werte sollten immer null sein, die oberen Werte sind in einem Array von Zahlen angegeben.

Beispiel

Ich habe versucht, diesen Effekt mit curveTo() zu erzielen, aber ohne Erfolg.

EDIT: Die Werte sind z.B.: 10, 15, 40, 28, 5, 2, 27 usw.

Kann mir bitte jemand helfen?

3voto

Michael Antipin Punkte 3492

CurveTo() zeichnet nur quadratische Bezierkurven, die im Wesentlichen Parabolenabschnitte sind. Daher müssen Sie einen ausgeklügelten Algorithmus entwerfen, wenn Sie eine Sinuswelle mit variabler Amplitude zeichnen möchten.

Ich schlage vor, dass Sie Ihre Kurve mit geraden Linienabschnitten zeichnen. Es erfordert ziemlich viele Iterationen in einer Schleife, ist aber ein sehr einfacher Ansatz, den man in nur wenigen Minuten codieren kann. Brauchen Sie wirklich etwas Ausgefeilteres?

Alternativ werfen Sie einen Blick auf http://code.google.com/p/bezier/ : ihre Demo ist cool.

Wenn Sie etwas erstellen möchten, das nicht leicht mit einer einzigen Gleichung definiert werden kann, sollten Sie sich die Lagrange-Approximation ansehen: Sie interpoliert gegebene Punkte in eine glatte Funktion.

BEARBEITEN Beispiel Lagrange-Approximation

Der folgende Code zeichnet Folgendes:

Bildbeschreibung hier eingeben

package
{
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Rectangle;

    import org.noregret.math.LagrangeApproximator;

    [SWF(fps="31",width="600",height="600",backgroundColor="0xFFFFFF")]    
    public class LagrangeTest extends Sprite
    {
        private const plot:Sprite = new Sprite();
        private const approx:LagrangeApproximator = new LagrangeApproximator();

        public function LagrangeTest()
        {
            super();
            initialize();
        }

        private function initialize():void
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.addEventListener(Event.RESIZE, onResize);
            onResize();

            addChild(plot);

            // HINZUFÜGEN VON KONTROLLPUNKTEN (habe sie einfach zufällig genommen)
            approx.addValue(0, 0);
            approx.addValue(50, -10);
            approx.addValue(100, 10);
            approx.addValue(150, -20);
            approx.addValue(200, -10);
            approx.addValue(250, -20);
            approx.addValue(300, -10);
            approx.addValue(350, 10);
            approx.addValue(400, -30);
            approx.addValue(450, 50);
            approx.addValue(500, 100);
            approx.addValue(550, 30);
            approx.addValue(600, 0);

            drawCurve(plot, 5, 0, 600);
        }

        private function drawCurve(target:Sprite, step:uint, fromArg:int, toArg:int):void 
        {
            var gfx:Graphics = target.graphics;
            gfx.clear();

            gfx.lineStyle(0, 0xCCCCCC, 1);
            gfx.moveTo(-50, 0);
            gfx.lineTo(50, 0);
            gfx.moveTo(0, -50);
            gfx.lineTo(0, 50);

            gfx.lineStyle(2, 0, 1);

            var minArg:int = Math.min(fromArg, toArg);
            var maxArg:int = Math.max(fromArg, toArg);

            if (step == 0) {
                step = 1;
            }

            var value:Number;
            for (var i:Number = minArg; i<=maxArg; i+=step) {
                value = approx.getApproximationValue(i);
                if (i) {
                    gfx.lineTo(i, value);
                } else {
                    gfx.moveTo(i, value);
                }
            }
        }

        private function onResize(event:Event = null):void
        {
            plot.x = 10;
            plot.y = stage.stageHeight/2;
        }
    }
}

Klasse Approximator

package org.noregret.math 
{
    import flash.geom.Point;
    import flash.utils.Dictionary;

    /**
     * @author Michael "Nox Noctis" Antipin (http://noregret.org)
     */
    public class LagrangeApproximator {

        private const points:Vector. = new Vector.();
        private const pointByArg:Dictionary = new Dictionary();

        private var isSorted:Boolean;

        public function LagrangeApproximator()
        {
        }

        public function addValue(argument:Number, value:Number):void
        {
            var point:Point;
            if (pointByArg[argument] != null) {
                trace("LagrangeApproximator.addValue("+arguments+"): ERROR duplicate function argument!");
                point = pointByArg[argument];
            } else {
                point = new Point();
                points.push(point);
                pointByArg[argument] = point;
            }
            point.x = argument;
            point.y = value;
            isSorted = false;
        }

        public function getApproximationValue(argument:Number):Number
        {
            if (!isSorted) {
                isSorted = true;
                points.sort(sortByArgument);
            }
            var listLength:uint = points.length;
            var point1:Point, point2:Point;
            var result:Number = 0;
            var coefficient:Number;
            for(var i:uint =0; i b.x) {
                return 1;
            }            
            return 0;
        }

        public function get length():int
        {
            return points.length;            
        }

        public function clear():void
        {
            points.length = 0;
            var key:*;
            for (key in pointByArg) {
                delete pointByArg[key];
            }
        }
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X