2018-02-01

Libgdx手写签名

2018-02-01_第1张图片
TIM截图20180201152315.png

1、原理是通过描点来实现,点之间通过贝塞尔曲线来拟合。
'''package com.mytian.mgarden.stages.main;

import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Bezier;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.mytian.mgarden.utils.libgdxutil.BaseStage;

/**

  • Created by gang.zhou on 2018/1/22.
    */

public class DrawingStage extends BaseStage {

ShapeRenderer renderer;

com.badlogic.gdx.utils.Array> paths = new com.badlogic.gdx.utils.Array<>();
com.badlogic.gdx.utils.Array points = new com.badlogic.gdx.utils.Array<>();

@Override
public void onLoadFinish() {
    renderer = new ShapeRenderer();
    renderer.setAutoShapeType(true);
    renderer.setColor(Color.RED);
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    points.clear();
    Vector2 vector2 = screenToStageCoordinates(new Vector2(screenX, screenY));
    points.add(new TimePoint(vector2));
    return true;
}


@Override
public void draw() {
    super.draw();
    renderer.setProjectionMatrix(getCamera().combined);
    renderer.begin(ShapeRenderer.ShapeType.Filled);
    for (Array path : paths) {
        if (path.size == 1) {
            renderer.circle(path.get(0).position.x, path.get(0).position.y, path.get(0).radius);
        } else {
            for (int i = 0; i < path.size; i++) {
                renderer.circle(path.get(i).position.x, path.get(i).position.y, path.get(i).radius);
            }
        }
    }
    if (points.size == 1) {
        renderer.circle(points.get(0).position.x, points.get(0).position.y, points.get(0).radius);
    } else {
        for (int i = 0; i < points.size; i++) {
            renderer.circle(points.get(i).position.x, points.get(i).position.y, points.get(i).radius);
        }
    }
    renderer.end();
}


@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    paths.add(new Array<>(points));
    points.clear();
    return true;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    final Vector2 vector2 = screenToStageCoordinates(new Vector2(screenX, screenY));
    final TimePoint point = new TimePoint(vector2);
    final TimePoint pPoint = points.get(points.size - 1);
    float n = (float) Math.sqrt(Math.pow((point.position.x - pPoint.position.x), 2)
            + Math.pow((point.position.y - pPoint.position.y), 2));
    float v = n / (Math.max(point.time - pPoint.time, 1));
    point.radius = Math.max(5f / (v + 1), 1f);
    final QuadraticBezier bezier = new QuadraticBezier(pPoint.position, new Vector2((pPoint.position.x + point.position.x) / 2.0f
            , (pPoint.position.y + point.position.y) / 2.0f), point.position);
    for (int i = 0; i < n; ++i) {
        TimePoint timePoint = new TimePoint(bezier.apply(1f * i / n));
        timePoint.radius = Math.max(pPoint.radius + (point.radius - pPoint.radius) * (1f * i / n)
                , 1);
        points.add(timePoint);
    }
    points.add(point);
    return true;
}

/**
 *
 */
public static class QuadraticBezier extends Bezier {

    public Vector2 p0;
    public Vector2 p1;
    public Vector2 p2;

    public QuadraticBezier(Vector2 p0, Vector2 p1,
                           Vector2 p2) {
        this.p0 = p0;
        this.p1 = p1;
        this.p2 = p2;
    }

    public Vector2 apply(float f) {
        float f1 = 1.0F - f;
        float f2 = f1 * f1;
        float f3 = f * (2.0F * f1);
        float f4 = f * f;
        final Vector2 tmpVec = new Vector2();
        tmpVec.x = f2 * p0.x + f3 * p1.x + f4 * p2.x;
        tmpVec.y = f2 * p0.y + f3 * p1.y + f4 * p2.y;
        return tmpVec;
    }

}


@Override
public boolean keyDown(int keyCode) {
    if (keyCode == Input.Keys.ENTER) {
        paths.clear();
        points.clear();
    }
    return super.keyDown(keyCode);
}

@Override
public void onBack() {
    paths.clear();
    points.clear();
}

@Override
public void dispose() {
    super.dispose();
    renderer.dispose();
}


static class TimePoint {
    public Vector2 position;
    public long time = System.nanoTime();
    public float radius = 5;

    public TimePoint(Vector2 position) {
        this.position = position;
        time = System.currentTimeMillis();
    }
}

}
'''

你可能感兴趣的:(2018-02-01)