Java Android找到三角形中平均颜色的最快方法

Java Android找到三角形中平均颜色的最快方法,java,android,if-statement,Java,Android,If Statement,我有位图和三角形,其中一些实时改变顶点,每个三角形包含同一个三角形内的平均颜色值。但是在三角形中生成平均颜色是一项代价高昂的操作,这就是为什么我只需要为那些至少改变一个顶点的三角形生成平均颜色,并为所有不改变顶点的三角形使用以前生成的颜色 如果我们有三角形▲ACD,▲ABC和▲BEC我发现了相应的颜色:绿色、蓝色、红色。然后顶点E改变位置并弹出新的三角形▲CED,所以我需要生成它的平均颜色,但是由于现有的三角形▲BEC也在改变,它也需要生成它的平均颜色。这意味着三角形▲ACD和▲ABC可以使用先

我有位图和三角形,其中一些实时改变顶点,每个三角形包含同一个三角形内的平均颜色值。但是在三角形中生成平均颜色是一项代价高昂的操作,这就是为什么我只需要为那些至少改变一个顶点的三角形生成平均颜色,并为所有不改变顶点的三角形使用以前生成的颜色

如果我们有三角形▲ACD,▲ABC和▲BEC我发现了相应的颜色:绿色、蓝色、红色。然后顶点E改变位置并弹出新的三角形▲CED,所以我需要生成它的平均颜色,但是由于现有的三角形▲BEC也在改变,它也需要生成它的平均颜色。这意味着三角形▲ACD和▲ABC可以使用先前生成的颜色,因为这些顶点坐标不会更改

为不改变顶点的三角形获取先前生成的颜色的最快方法是什么。三角形是用生成的,所以三角形的顺序会改变,这意味着首先我们可以有一个数组[ACD,ABC,BEC],在顶点E改变位置后,我们可以有一个数组[CED,BEC,ABC,ACD]

如果我有2000个三角形,3个三角形改变了这些顶点,那么剩下的1997个三角形可以使用之前生成的颜色。我有每个三角形的顶点坐标,还有相应的颜色。如果我用前2000个三角形(包含先前生成的颜色的三角形)检查每个1997三角形要确定三角形是否匹配并获得相应的颜色,请检查以确定以前为每个三角形生成的颜色,该颜色为~1997*2000=~3994000总计if

这是需要实时完成的大量操作。有没有什么方法可以加快速度,比如使用HashMaps,我可以使用成对的坐标作为键,使用颜色作为值,或者其他方法

要从点生成Delaunay三角剖分,我使用这个。它保留数组中的点,以及数组中的三角形索引三角形。这意味着要获得三角形坐标,我使用以下代码创建扩展函数:

fun Delaunay.getTriangleCoordinates(): FloatArray {

        val coordinates = FloatArray(triangles.size * 2)
        for (i in 0 until triangles.size / 3) {

            // get triangle points(vertices) indices
            val t0 = triangles[i * 3]
            val t1 = triangles[i * 3 + 1]
            val t2 = triangles[i * 3 + 2]

            // vertex 1
            coordinates[i * 6 + 0] = points[t0].x
            coordinates[i * 6 + 1] = points[t0].y

            // vertex 2
            coordinates[i * 6 + 2] = points[t1].x
            coordinates[i * 6 + 3] = points[t1].y

            // vertex 3
            coordinates[i * 6 + 4] = points[t2].x
            coordinates[i * 6 + 5] = points[t2].y
        }
        return coordinates
    }
为了只检查特定三角形的一个值而不是所有顶点,我们可以得到每个三角形的中心并将其用作关键点。下面的代码再次使用扩展功能对其进行了演示:

fun Delaunay.getTriangleCenterCoordinates(): FloatArray {

        val coordinates = FloatArray((triangles.size / 3) * 2)

        for (i in 0 until triangles.size / 3) {

            val t0 = triangles[i * 3]
            val t1 = triangles[i * 3 + 1]
            val t2 = triangles[i * 3 + 2]

            coordinates[i * 2] = (points[t0].x + points[t1].x + points[t2].x) / 3
            coordinates[i * 2 + 1] = (points[t0].y + points[t1].y + points[t2].y) / 3
        }
        return coordinates
    }
为了使用OpenGL绘制三角形,我需要所有三角形坐标作为FloatArray,这正是我们使用getTriangelCoordinates()得到的。我还需要每个三角形对应的颜色,如IntArray()

下面的代码可以获取顶点已更改的三角形的平均颜色,或者使用先前生成的颜色来表示顶点未更改的三角形

var previousTriangleColors = IntArray(0)
var previousTriangleCenterCoordinates = FloatArray(0)

fun renderDelaunay() {

        // at least three points acquired
        if (delaunayPoints.size >= 3) {

            delaunay = Delaunay(delaunayPoints)

            val triangleCoordinate = delaunay.getTriangleCoordinates()
            val triangleCenterCoordinate = delaunay.getTriangleCenterCoordinates()

            val colors = IntArray(triangleCenterCoordinate.size / 2)
            for (i in 0 until triangleCenterCoordinate.size / 2) {

                // check if triangle vertices are changed or not
                var foundIndex = -1
                for (j in 0 until previousTriangleCenterCoordinates.size / 2) {
                    if (triangleCenterCoordinate[i * 2] == previousTriangleCenterCoordinates[j * 2] &&
                        triangleCenterCoordinate[i * 2 + 1] == previousTriangleCenterCoordinates[j * 2 + 1]
                    ) {
                        foundIndex = j
                        break
                    }
                }


                if (foundIndex != -1) {
                    // if triangle center is NOT changed, then use previously generated color
                    colors[i] = previousTriangleColors[foundIndex]
                } else {

                    // if triangle center is changed, then generate new average color

                    // first triangle vertex
                    val x1 = getImageGraphicCoordinateX(triangleCoordinate[i * 6])
                    val y1 = getImageGraphicCoordinateY(triangleCoordinate[i * 6 + 1])

                    // second triangle vertex
                    val x2 = getImageGraphicCoordinateX(triangleCoordinate[i * 6 + 2])
                    val y2 = getImageGraphicCoordinateY(triangleCoordinate[i * 6 + 3])

                    // third triangle vertex
                    val x3 = getImageGraphicCoordinateX(triangleCoordinate[i * 6 + 4])
                    val y3 = getImageGraphicCoordinateY(triangleCoordinate[i * 6 + 5])

                    // generate new average color for the triangle
                    colors[i] = averageColor(x1.toFloat(), y1.toFloat(), x2.toFloat(), y2.toFloat(), x3.toFloat(), y3.toFloat())
                }
            }
            previousTriangleColors = colors
            previousTriangleCenterCoordinates = triangleCenterCoordinate
        }
    }

这两个嵌套for循环在emulator上运行良好,但在实际的android设备上运行缓慢,因为它使用昂贵的操作。例如,如果位图具有高分辨率4096x4096,这意味着每个三角形将具有大面积,用于生成平均颜色。若我有5000个三角形,有两个嵌套的for循环,若检查,我们得到~5000x5000=25000000,看看三角形顶点坐标是否改变。我可以减少位图的大小,并减少用于生成平均颜色的区域,但这不是重点。由于实时更改单个顶点时,超过98%的三角形没有更改,因此我们可以使用先前生成的颜色,但这两个嵌套循环是应用程序体验滞后的原因。因此,我需要一种更好的方法来检查三角形坐标是否发生了变化。

这是一个非常有趣的问题,我不会投票决定是否结束,也不会说它不好,但是,我认为您的问题可能有点宽泛,因为您没有包含任何代码。鉴于hashmaps是可用的,您是否尝试过使用hashmap的解决方案?也许你可以试着把你的问题集中在你试图用hashmaps解决的问题上,包括你已经尝试过的方法。如果一个顶点改变了,只有与它相连的三角形会改变。是否可能有一个
映射
,其中每个顶点都映射到它所属的三角形列表?因此,您可以重新计算该列表中三角形的颜色。这是一个非常有趣的问题,我不打算投票结束这个问题,也不想说它不好,但是,我认为你的问题可能有点宽泛,因为你没有包含任何代码。鉴于hashmaps是可用的,您是否尝试过使用hashmap的解决方案?也许你可以试着把你的问题集中在你试图用hashmaps解决的问题上,包括你已经尝试过的方法。如果一个顶点改变了,只有与它相连的三角形会改变。是否可能有一个
映射
,其中每个顶点都映射到它所属的三角形列表?因此,您可以重新计算该列表中三角形的颜色。我不确定你是如何生成三角形的。