Java libgdx绘制圆弧曲线

Java libgdx绘制圆弧曲线,java,libgdx,Java,Libgdx,libgdx的arc函数(而不是绘制圆弧)绘制饼图段(即,有两条线连接到圆弧的原点) 是否有解决此问题的方法,使libgdx可以绘制类似于html5画布圆弧函数的圆弧曲线?阅读源代码,这似乎是内置的行为: /** Draws an arc using {@link ShapeType#Line} or {@link ShapeType#Filled}. */ public void arc (float x, float y, float radius, float start, float d

libgdx的arc函数(而不是绘制圆弧)绘制饼图段(即,有两条线连接到圆弧的原点)


是否有解决此问题的方法,使libgdx可以绘制类似于html5画布圆弧函数的圆弧曲线?

阅读源代码,这似乎是内置的行为:

/** Draws an arc using {@link ShapeType#Line} or {@link ShapeType#Filled}. */
public void arc (float x, float y, float radius, float start, float degrees, int segments) {
    if (segments <= 0) throw new IllegalArgumentException("segments must be > 0.");
    float colorBits = color.toFloatBits();
    float theta = (2 * MathUtils.PI * (degrees / 360.0f)) / segments;
    float cos = MathUtils.cos(theta);
    float sin = MathUtils.sin(theta);
    float cx = radius * MathUtils.cos(start * MathUtils.degreesToRadians);
    float cy = radius * MathUtils.sin(start * MathUtils.degreesToRadians);

    if (shapeType == ShapeType.Line) {
        check(ShapeType.Line, ShapeType.Filled, segments * 2 + 2);

        renderer.color(colorBits);
        renderer.vertex(x, y, 0);           <--- CENTER
        renderer.color(colorBits);
        renderer.vertex(x + cx, y + cy, 0); <--- LINE TO START POINT
        for (int i = 0; i < segments; i++) {
            renderer.color(colorBits);
            renderer.vertex(x + cx, y + cy, 0);
            float temp = cx;
            cx = cos * cx - sin * cy;
            cy = sin * temp + cos * cy;
            renderer.color(colorBits);
            renderer.vertex(x + cx, y + cy, 0);
        }
        renderer.color(colorBits);
        renderer.vertex(x + cx, y + cy, 0); <-- LINE TO END POINT
...
/**使用{@link ShapeType#Line}或{@link ShapeType#Filled}绘制圆弧*/
公共空心弧(浮动x、浮动y、浮动半径、浮动起点、浮动度、整数段){

如果(段最后我将ShaperEnder分类为子类

public class Arc extends ShapeRenderer{

    private final ImmediateModeRenderer renderer;
    private final Color color = new Color(1, 1, 1, 1);

    public Arc(){
        renderer = super.getRenderer();
    }

    /** Draws an arc using {@link ShapeType#Line} or {@link ShapeType#Filled}. */
    public void arc (float x, float y, float radius, float start, float degrees) {
    int segments = (int)(6 * (float)Math.cbrt(radius) * (degrees / 360.0f));

    if (segments <= 0) throw new IllegalArgumentException("segments must be > 0.");
    float colorBits = color.toFloatBits();
    float theta = (2 * MathUtils.PI * (degrees / 360.0f)) / segments;
    float cos = MathUtils.cos(theta);
    float sin = MathUtils.sin(theta);
    float cx = radius * MathUtils.cos(start * MathUtils.degreesToRadians);
    float cy = radius * MathUtils.sin(start * MathUtils.degreesToRadians);

    for (int i = 0; i < segments; i++) {
        renderer.color(colorBits);
        renderer.vertex(x + cx, y + cy, 0);
        float temp = cx;
        cx = cos * cx - sin * cy;
        cy = sin * temp + cos * cy;
        renderer.color(colorBits);
        renderer.vertex(x + cx, y + cy, 0);
    }
  }
}

角度的正确性很奇怪,不确定这是我的代码还是libGDX,我想你和其他响应者已经发布了当前最好的解决方案。对于任何

  • 不太关心性能
  • 有一个静态背景

  • 这将是在使用相同背景色线条绘制的2条线条上进行渲染,以在之后将其覆盖。是的,这是一个蹩脚但快速且肮脏的小代码解决方案。

    这里有一个使用kotlin扩展的简单解决方案

    /** Draws an arc with 'stroke' of given width  */
    fun ShapeRenderer.strokeArc(strokeWidth: Float, x: Float, y: Float, radius: Float, start: Float, degrees: Float, sampling: Float = 2f, color: Color = Color.WHITE) {
        val segments = ((6 * Math.cbrt(radius.toDouble()) * (Math.abs(degrees) / 360.0f)) * sampling).toInt()
        val colorBits = color.toFloatBits()
    
        for (i in 0 until segments) {
            val x1 = radius * MathUtils.cosDeg(start + (degrees / segments) * i)
            val y1 = radius * MathUtils.sinDeg(start + (degrees / segments) * i)
    
            val x2 = (radius - strokeWidth) * MathUtils.cosDeg(start + (degrees / segments) * i)
            val y2 = (radius - strokeWidth) * MathUtils.sinDeg(start + (degrees / segments) * i)
    
            val x3 = radius * MathUtils.cosDeg(start + (degrees / segments) * (i + 1))
            val y3 = radius * MathUtils.sinDeg(start + (degrees / segments) * (i + 1))
    
            val x4 = (radius - strokeWidth) * MathUtils.cosDeg(start + (degrees / segments) * (i + 1))
            val y4 = (radius - strokeWidth) * MathUtils.sinDeg(start + (degrees / segments) * (i + 1))
    
            renderer.color(colorBits)
            renderer.vertex(x + x1, y + y1, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x3, y + y3, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x2, y + y2, 0f)
    
            renderer.color(colorBits)
            renderer.vertex(x + x3, y + y3, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x2, y + y2, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x4, y + y4, 0f)
        }
    }
    
    为了更好地理解这一点以及为什么内置解决方案会这样做。ShaperEnder使用三角形绘制(就像OpenGL一样),因此您需要3个顶点来绘制三角形。在这里,我们一次绘制一个线段。每个线段由2个三角形组成一个矩形。足够多的矩形开始看起来像一个平滑的圆

    内置ShaperEnder.arc绘制的方式很像一个饼图。如果有足够多的直边切片,它开始看起来像一个完整的饼图,而不是中心的一堆三角形


    我希望这有一定的意义,并允许其他人绘制自己的自定义形状并为将来学习!

    谢谢,当然比我考虑的贝塞尔曲线方法要简单得多,似乎所有这些渲染器。颜色(颜色位);循环中的语句也可能是不必要的,或者每个render.vertex前面都需要一个render.color语句(奇怪)@ejectamenta:是的,我也注意到了这一点。如果涉及到某种缓存,其中的行可以无序绘制,那么这可能是必要的,但要想弄清楚这一点,您需要深入研究源代码。请注意,您的类不尊重
    arc.setColor()
    指令正确。应该通过调用
    setColor()
    来更新
    color
    的值。不过做得好。刚刚向源代码添加了一个工作impl。
        Arc a = new Arc();
        a.setProjectionMatrix(cam.combined);
        a.begin(ShapeType.Line);
        a.arc(10, 10, 10, 30, 120);
        a.end();
    
    /** Draws an arc with 'stroke' of given width  */
    fun ShapeRenderer.strokeArc(strokeWidth: Float, x: Float, y: Float, radius: Float, start: Float, degrees: Float, sampling: Float = 2f, color: Color = Color.WHITE) {
        val segments = ((6 * Math.cbrt(radius.toDouble()) * (Math.abs(degrees) / 360.0f)) * sampling).toInt()
        val colorBits = color.toFloatBits()
    
        for (i in 0 until segments) {
            val x1 = radius * MathUtils.cosDeg(start + (degrees / segments) * i)
            val y1 = radius * MathUtils.sinDeg(start + (degrees / segments) * i)
    
            val x2 = (radius - strokeWidth) * MathUtils.cosDeg(start + (degrees / segments) * i)
            val y2 = (radius - strokeWidth) * MathUtils.sinDeg(start + (degrees / segments) * i)
    
            val x3 = radius * MathUtils.cosDeg(start + (degrees / segments) * (i + 1))
            val y3 = radius * MathUtils.sinDeg(start + (degrees / segments) * (i + 1))
    
            val x4 = (radius - strokeWidth) * MathUtils.cosDeg(start + (degrees / segments) * (i + 1))
            val y4 = (radius - strokeWidth) * MathUtils.sinDeg(start + (degrees / segments) * (i + 1))
    
            renderer.color(colorBits)
            renderer.vertex(x + x1, y + y1, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x3, y + y3, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x2, y + y2, 0f)
    
            renderer.color(colorBits)
            renderer.vertex(x + x3, y + y3, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x2, y + y2, 0f)
            renderer.color(colorBits)
            renderer.vertex(x + x4, y + y4, 0f)
        }
    }