首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >带角度的LibGDX Cut纹理

带角度的LibGDX Cut纹理
EN

Stack Overflow用户
提问于 2021-01-07 00:28:50
回答 1查看 59关注 0票数 2

假设我有一个Texture,我想把它分成两半,放在一条以给定角度旋转的直线上。

在结果中,我希望得到两个Texture对象与相应的原始纹理的一半。如果它可以通过某种转换/屏蔽来完成,那将是非常好的,这样我就不必在运行时存储两个新纹理的副本。

这有可能吗?

我试图绕过Gdx.gl.glSsisors(),但无法让它工作,因为它需要将屏幕坐标作为参数传递。此外,我还尝试使用Pixmap,但找不到任何可以证明这一点的东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-10 18:06:40

这可以通过手动计算两个倾斜的四边形并使用SpriteBatch渲染它们来实现。

沿着角度angle切割一个精灵,我们得到一个表示切割的方向矢量

代码语言:javascript
运行
AI代码解释
复制
public void cut(float angle) {
    Vector2 d = (new Vector2(1.0f, 0.0f)).rotate(angle);

如果我们还为TextureUV Mapping定义了四个角,以及中心和一个向量la d远离中心和lb going -d

代码语言:javascript
运行
AI代码解释
复制
Vector2 c = new Vector2(0.5f, 0.5f);
Vector2 la = (new Vector2(d)).scl( 1.0f).add(c);
Vector2 lb = (new Vector2(d)).scl(-1.0f).add(c);

Vector2 tl = new Vector2(0, 1);
Vector2 tr = new Vector2(1, 1);
Vector2 bl = new Vector2(0, 0);
Vector2 br = new Vector2(1, 0);

然后我们可以计算切割的交点。

代码语言:javascript
运行
AI代码解释
复制
Vector2 i1 = new Vector2();
Vector2 i2 = new Vector2();

if (Intersector.intersectSegments(c, la, tl, tr, i1) || Intersector.intersectSegments(c, lb, tl, tr, i1))
    i2.set(1.0f - i1.x, 1.0f - i1.y);
else {
    if (Intersector.intersectSegments(c, la, tl, bl, i1) || Intersector.intersectSegments(c, lb, tl, bl, i1))
        i2.set(1.0f - i1.x, 1.0f - i1.y);
}

在这一点上,我们知道切割的一半将由顶点i1i2tltrblbr中的两个组成,所以如果我们按远离切割的角度对它们进行排序,然后从i1中取出前4个,我们就得到了构建倾斜四边形所需的顶点:

代码语言:javascript
运行
AI代码解释
复制
Vector2[] vertexList = new Vector2[] {
        tl, tr, bl, br, i1, i2
};

Array<VertexAngle> vas = new Array<>();
for (Vector2 v : vertexList) {
    Vector2 vd = (new Vector2(v)).sub(c);
    float a = d.angle(vd);
    VertexAngle va = new VertexAngle();
    va.v = v;
    va.a = a;
    vas.add(va);
}

vas.sort(new Comparator<VertexAngle>() {
    @Override
    public int compare(VertexAngle a, VertexAngle b) {
        return Float.compare(a.a, b.a);
    }
});

Array<Vector2> nv = new Array<>();
for (VertexAngle va : vas)
    nv.add(va.v);

int index = nv.indexOf(i1, true);

可以通过调用SpriteBatch上的draw来构造和呈现包含绘制调用的顶点数据的浮点数组。

例如:

以上示例的完整源代码如下:

代码语言:javascript
运行
AI代码解释
复制
package com.bornander.sandbox;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;

import java.util.Comparator;

public class SandboxGame extends ApplicationAdapter {
    OrthographicCamera camera;
    SpriteBatch batch;
    Texture texture;
    CutTexture cutTexture;

    public static class CutTexture
    {
        public static class VertexAngle {
            public Vector2 v;
            public float a;
        }

        public static class CutHalf {
            public float[] vertices = new float[4 * 5];

            public void translate(float x, float y) {
                for(int i = 0; i < vertices.length; i += 5) {
                    vertices[i + 0] += x;
                    vertices[i + 1] += y;
                }
            }
        }

        public Vector2 position = new Vector2();
        public Vector2 driftDirection = new Vector2();
        public float drift = 0.0f;
        public Texture source;
        public CutHalf halfA = new CutHalf();
        public CutHalf halfB = new CutHalf();

        public void cut(float angle) {
            Vector2 d = (new Vector2(1.0f, 0.0f)).rotate(angle);
            Vector2 c = new Vector2(0.5f, 0.5f);
            driftDirection.set(d).rotate(90.0f);
            Vector2 la = (new Vector2(d)).scl( 1.0f).add(c);
            Vector2 lb = (new Vector2(d)).scl(-1.0f).add(c);

            Vector2 tl = new Vector2(0, 1);
            Vector2 tr = new Vector2(1, 1);
            Vector2 bl = new Vector2(0, 0);
            Vector2 br = new Vector2(1, 0);

            Vector2 i1 = new Vector2();
            Vector2 i2 = new Vector2();

            if (Intersector.intersectSegments(c, la, tl, tr, i1) || Intersector.intersectSegments(c, lb, tl, tr, i1))
                i2.set(1.0f - i1.x, 1.0f - i1.y);
            else {
                if (Intersector.intersectSegments(c, la, tl, bl, i1) || Intersector.intersectSegments(c, lb, tl, bl, i1))
                    i2.set(1.0f - i1.x, 1.0f - i1.y);
            }

            Vector2[] vertexList = new Vector2[] {
                    tl, tr, bl, br, i1, i2
            };

            Array<VertexAngle> vas = new Array<>();
            for (Vector2 v : vertexList) {
                Vector2 vd = (new Vector2(v)).sub(c);
                float a = d.angle(vd);
                VertexAngle va = new VertexAngle();
                va.v = v;
                va.a = a;
                vas.add(va);
            }

            vas.sort(new Comparator<VertexAngle>() {
                @Override
                public int compare(VertexAngle a, VertexAngle b) {
                    return Float.compare(a.a, b.a);
                }
            });

            Array<Vector2> nv = new Array<>();
            for (VertexAngle va : vas)
                nv.add(va.v);

            int index = nv.indexOf(i1, true);
            int idx = 0;
            int lastIndex = 0;
            for(int j = 0; j < 4; ++j) {
                lastIndex = (index + j) % nv.size;
                Vector2 vertex = nv.get(lastIndex);
                float width = source.getWidth();
                float height = source.getWidth();
                float fx2 = position.x + width * vertex.x - width / 2.0f;
                float fy2 = position.y + height * vertex.y - height / 2.0f;

                halfA.vertices[idx++] = fx2;
                halfA.vertices[idx++] = fy2;
                halfA.vertices[idx++] = Color.WHITE_FLOAT_BITS;
                halfA.vertices[idx++] = vertex.x;
                halfA.vertices[idx++] = 1.0f - vertex.y;
            }

            idx = 0;
            for(int j = 0; j < 4; ++j) {
                Vector2 vertex = nv.get((lastIndex + j) % nv.size);
                float width = source.getWidth();
                float height = source.getWidth();
                float fx2 = position.x + width * vertex.x - width / 2.0f;
                float fy2 = position.y + height * vertex.y - height / 2.0f;

                halfB.vertices[idx++] = fx2;
                halfB.vertices[idx++] = fy2;
                halfB.vertices[idx++] = Color.WHITE_FLOAT_BITS;
                halfB.vertices[idx++] = vertex.x;
                halfB.vertices[idx++] = 1.0f - vertex.y;
            }
        }

        public void render(SpriteBatch batch) {

            float dx = driftDirection.x * drift;
            float dy = driftDirection.y * drift;

            halfA.translate(dx, dy);
            halfB.translate(-dx, -dy);

            batch.draw(source, halfA.vertices, 0, 20);
            batch.draw(source, halfB.vertices, 0, 20);

            halfA.translate(-dx, -dy);
            halfB.translate(dx, dy);
        }
    }

    @Override
    public void create () {
        float aspectRatio = (float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth();
        camera = new OrthographicCamera(800, 800 * aspectRatio);
        camera.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f, 0.0f);
        batch = new SpriteBatch();
        texture = new Texture(Gdx.files.internal("badlogic.jpg"));

        Gdx.gl.glCullFace(0);
        cutTexture = new CutTexture();
        cutTexture.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f);
        cutTexture.source = texture;
        cutTexture.cut(0);
    }

    float[] cutAngles = new float[] { 0.0f, -22.5f, -45.0f, -12.0f, -75.0f, -90.0f};
    int ai = 0;

    @Override
    public void render () {
        if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE))
        {
            cutTexture.drift = 0.0f;
            cutTexture.cut(cutAngles[(ai++) % cutAngles.length]);
        }
        cutTexture.drift -= 64.0f * Gdx.graphics.getDeltaTime();
        Gdx.gl.glClearColor(0.6f, 0.6f, 1.0f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        Gdx.gl.glCullFace(GL20.GL_NONE);
        camera.update();
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        cutTexture.render(batch);
        batch.end();
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65605106

复制
相关文章
TP将时间戳显示成时间格式。
前端调用: {$vo.time|date="Y-m-d",###} “###”代表对它本身生效! 小写y只显示xx比如2016只显示16,大Y 显示的是2016这样! Tags: None Archives QR Code
简单、
2018/07/18
2.4K0
聊天IM的时间戳显示规则
======================================================
meteoric
2018/11/19
4.8K0
时间,时间戳
将如上的时间2016-05-05 20:28:54转换成时间戳,具体的操作过程为:
zhengzongwei
2019/07/31
5.2K0
时间戳 时间
背景 由于团队业务做的是国际项目,就无法避免一个问题--时区问题,很多业务都是跟时间有关。一些时间的对比,时间的展示,都会涉及到时区和时间戳,所以花点时间来简单总结一下 概念 时间戳 时间戳是一个自增的整数,它表示从1970年1月1日零时整的GMT时区开始的那一刻,到现在的毫秒数。假设浏览器所在电脑的时间是准确的,那么世界上无论哪个时区的电脑,它们此刻产生的时间戳数字都是一样的,所以,时间戳可以精确地表示一个时刻,并且与时区无关。 时区 时区(Time Zone)是地球上的区域使用同一个时间定义。188
千往
2018/01/24
5.9K0
Python获取当前时间戳_时间转换时间戳
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/10
9.7K0
Unix 时间戳;时间戳获取和生成
Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
西湖醋鱼
2020/12/30
9.3K0
Linux时间戳转换_时间戳转换软件
在大多数 UNIX 系统中,当前时间存储为自特定时刻以来经过的时间以简化,将时间保持为长整数。所有 UNIX 系统普遍接受的时刻是 1970 年 1 月 1 日凌晨 12:00:00。 这称为 UNIX 时间戳,并被所有现代 UNIX/Linux 系统识别。
全栈程序员站长
2022/11/09
15.8K0
Linux时间戳转换_时间戳转换软件
Python获取时间戳_python爬虫时间戳
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/189145.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/27
5.9K0
时间戳
时间戳是自 1970 年 1 月 1 日(00:00:00 GMT)以来的秒数。它也被称为 Unix 时间戳(Unix Timestamp)。
KEVINGUO_CN
2020/03/17
4K0
Linux时间戳转换_如何获取时间戳
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/09
13.3K0
java 时间戳字符串_Java获取当前时间戳/时间戳转换
public classApp {public static voidmain(String[] args) {//精确到毫秒//获取当前时间戳
全栈程序员站长
2022/08/11
8.5K0
linux 日期转换时间戳_将时间戳转为时间
最近项目上需要用到时间戳,查找了资源终于找到了实现方式,最后时间戳还需要转换成具体的日期格式,查阅了一些资料,还是没有找到具体的实现方式,所以这里总结一些,防止其他小伙伴就掉坑,实现是在freeRTOS系统上的,当前我在linux下尝试实现以下。
全栈程序员站长
2022/11/10
10.6K0
linux 日期转换时间戳_将时间戳转为时间
Android 获取时间戳 和时间戳转日期
获取系统时间戳 public String getTime(){ long time=System.currentTimeMillis()/1000;//获取系统时间的10位的时间戳 String str=String.valueOf(time); return str; } 、获取系统时间 long currentTime = System.currentTimeMillis(); SimpleDateFormat formatter = new SimpleDateForma
程思扬
2022/01/10
7K0
时间戳转换
生成当前时间戳 root@BJ-CentOS7 ~ # date +%s 转换指定时间为时间戳 root@BJ-CentOS7 ~ # date -d "2019-01-24 14:35" +%s 转
大大大黑白格子
2020/06/10
6.1K0
linux获取时间戳_java时间戳转换成时间
leon@ubuntu:~/work$ date -d @1630236318 +”%Y/%m/%d %H:%M:%S” 2021/08/29 11:25:18
全栈程序员站长
2022/11/09
9.1K0
java时间戳
  时间戳是指文件属性里的创建、修改、访问时间。 数字时间戳技术是数字签名技术一种变种的应用。在电子商务交易文件中,时间是十分重要的 信息。在书面合同中,文件签署的日期和签名一样均是十分重要的防止文件被伪造和篡改的关键性内容。
Java架构师必看
2021/05/21
2.5K0
java时间戳
PHP时间戳
我们可以通过 date() 函数提供的丰富格式化来显示需要的时间日期,如下面的例子:
我不是费圆
2020/09/21
5.7K0
python 时间 时间戳 互转
ltime=time.localtime(19532546) timeY=time.strftime("%Y-%m-%d %H:%M:%S",ltime) print(timeY) #2018-09-09
用户5760343
2022/01/09
1.5K0
java当前时间的时间戳_java获取时间戳和当前时间
Calendar.getInstance().getTimeInMillis();
全栈程序员站长
2022/08/18
8.7K0
linux时间戳转换成时间指令_时间戳转换公式
原文地址:http://wanping.blogbus.com/logs/28663569.html
全栈程序员站长
2022/11/11
9.2K0

相似问题

BigQuery -整数显示为日期时间戳

13

Bigquery无效时间戳

11

时间戳31/12/9999 23:59:29

12

BigQuery -日期时间与时间戳

11

BigQuery时间戳到Ruby

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文