Plotted Bezier Curve


#1

I’ve been spending some time extending vehicles/cars and implementing the pacejka “magic formula”. In two areas I’d like to be able to plot a bezier curve: Engine power over revs and tyre grip over weight.

For engine power - the engine gains or loses power depending on the revs. Right now I use part of a sine wave - which works, but I’d like to be able to plot it a bit more like this:

And for tire grip it’s the same kind of story. Grip will grow as the weight increases and then diminishes after a certain weight. a little bit like this. You could argue I could use a sine wave for this, but I’d like to have a bit more fidelity than that. Right now I’m using a linear function and it works, but it’s not really what I want.

Is there anything in the engine available to plot these effects or do I need to roll my own?


#2

You mean like this:
https://javadoc.jmonkeyengine.org/com/jme3/scene/plugins/blender/curves/BezierCurve.html

…or drawing on a raster?


#3

I will draw the graph yeah, but I’m not so worried about that. The blender Bezier curve wants a list of Structure objects (which looks like a file/Stream) and a BlenderContext, though, so doesn’t really work…

I have noticed there is a FastMath.interpolateBezier, too, but I’d need to specify control points, which is fine, but it would be nice to get a default control point over say 3 or more points.

It’s not the end of the world. I can roll my own I guess.


#4

Hmmm… if you want default control points then a bezier curve may not be what you want.

As I recall, Java2D also has some curves you might be able to use if will have access to AWT.


#5

Might be wrong but Is this what you want:

https://wiki.jmonkeyengine.org/jme3/advanced/motionpath.html#create-a-motionpath


#6

Yeah, spline is what I was thinking of but already messed up my search once. :slight_smile:


#7

Also this one which creates a debug mesh out of spline:


#8

Yep. Spline does the thing. I do need to specify control points and It’s 3D and I only want 2D, but it’s not calculated that often that it really matters, and it’s native, so that’s always a bonus.

Thanks for the help :slight_smile:

And here’s the code for anyone that ever stumbles across the thread.

package com.jayfella.test;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.material.Materials;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Spline;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3.system.AppSettings;
import com.jme3.texture.Image;
import com.jme3.texture.Texture2D;
import com.jme3.texture.image.ImageRaster;
import com.jme3.util.BufferUtils;

public class TestSpline extends SimpleApplication {

    public static void main(String... args) {
        TestSpline testSpline = new TestSpline();

        AppSettings appSettings = new AppSettings(true);
        appSettings.setResolution(1280, 720);
        appSettings.setFrameRate(120);
        appSettings.setTitle("Seven Days");

        testSpline.setSettings(appSettings);
        testSpline.setShowSettings(false);
        testSpline.setPauseOnLostFocus(false);

        testSpline.start();

    }



    @Override
    public void simpleInitApp() {
        Vector3f[] points = new Vector3f[] {

                // start
                new Vector3f(0, 0, 0),

                // point 1
                new Vector3f(500, 350, 0),
                new Vector3f(700, 200, 0),
                new Vector3f(800, 420, 0),

                // point 2
                new Vector3f(900, 120, 0),
                new Vector3f(1000, 320, 0),
                new Vector3f(1280, 720, 0),
        };


        Spline spline = new Spline(Spline.SplineType.Bezier, points, 0.1f, false);

        int width = cam.getWidth();
        int height = cam.getHeight();

        Image image = new Image();
        image.setWidth(width);
        image.setHeight(height);
        image.setFormat(Image.Format.BGRA8);
        image.setData(BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4));

        ImageRaster raster = ImageRaster.create(image);

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                raster.setPixel(x, y, ColorRGBA.DarkGray);
            }
        }

        for (int x = 0; x < width; x++) {

            float px = (float)x / (float)width;

            Vector3f point = spline.interpolate(px, 0, null);

            int y = (int) point.y;
            System.out.println(y);

            raster.setPixel(x, y, ColorRGBA.Yellow);
        }

        Texture2D texture2D = new Texture2D(image);
        Geometry geometry = new Geometry("", new Quad(width, height));
        geometry.setMaterial(new Material(assetManager, Materials.UNSHADED));
        geometry.getMaterial().setTexture("ColorMap", texture2D);

        guiNode.attachChild(geometry);

    }
}