以中心旋转等边三角形
Rotating an equilateral triangle at its center
我正在编写一个 Java Graphics
class 的 Kotlin 函数,它将填充一个中心位于给定坐标的等边三角形。我现在正尝试添加旋转三角形的功能,以度为单位 theta
。
阅读点旋转,我发现方程式 x′ = xcosθ − ysinθ
和 y′ = ycosθ + xsinθ
除了在旋转之前将 x
和 y
平移到原点然后平移返回的结果,似乎是我正在寻找的解决方案。
但是,在实施时,三角形在模拟 3D 中似乎几乎在旋转 space。
我的代码
fun Graphics.fillTriangle(x: Int, y: Int, sideLength: Int, theta: Int = 0) {
var xCords = arrayOf(x - (sideLength / 2),
x + (sideLength / 2),
x)
var yCords = arrayOf((y + (sideLength / (2 * sqrt(3.0)))).toInt(),
(y + (sideLength / (2 * sqrt(3.0)))).toInt(),
(y - (sideLength / sqrt(3.0))).toInt())
if(theta != 0) {
for(i in 0..2) {
xCords[i] = ((xCords[i]-x) * cos(toRadians(theta)) - (yCords[i]-y) * sin(toRadians(theta))).toInt() + x
yCords[i] = ((yCords[i]-y) * cos(toRadians(theta)) + (xCords[i]-x) * sin(toRadians(theta))).toInt() + y
}
}
fillPolygon(xCords.toIntArray(), yCords.toIntArray(), 3)
}
我的实现有什么问题吗?
我明白了。我正在修改 xCord
数组中的坐标,然后用于计算 yCord
数组中的新坐标。
我的新密码
var newX = (((xCords[i]-x) * cos(toRadians(theta)) - (yCords[i]-y)*sin(toRadians(theta)))+ x).toInt()
var newY = (((yCords[i]-y) * cos(toRadians(theta)) + (xCords[i]-x) * sin(toRadians(theta))) + y).toInt()
xCords[i] = newX
yCords[i] = newY
我没有检查你的数学,但我建议一个更简单的方法。对于每个点,计算以原点为中心的三角形的位置,然后添加偏移量。等边三角形只是圆上的三个点,相隔 120 度,所以数学就是 (x, y) = (r*cos(theta), r*sin(theta))
.
fun Graphics.fillTriangle(x: Int, y: Int, sideLength: Int, theta: Int = 0) {
val radius = sideLength / sqrt(3.0)
val angles = (0..2).map { it * (toRadians(theta) + toRadians(120)) }
val xCoords = angles.map { (radius * cos(it) + x).roundToInt() }.toIntArray()
val yCoords = angles.map { (radius * sin(it) + y).roundToInt() }.toIntArray()
fillPolygon(xCoords, yCoords, 3)
}
我正在编写一个 Java Graphics
class 的 Kotlin 函数,它将填充一个中心位于给定坐标的等边三角形。我现在正尝试添加旋转三角形的功能,以度为单位 theta
。
阅读点旋转,我发现方程式 x′ = xcosθ − ysinθ
和 y′ = ycosθ + xsinθ
除了在旋转之前将 x
和 y
平移到原点然后平移返回的结果,似乎是我正在寻找的解决方案。
但是,在实施时,三角形在模拟 3D 中似乎几乎在旋转 space。
我的代码
fun Graphics.fillTriangle(x: Int, y: Int, sideLength: Int, theta: Int = 0) {
var xCords = arrayOf(x - (sideLength / 2),
x + (sideLength / 2),
x)
var yCords = arrayOf((y + (sideLength / (2 * sqrt(3.0)))).toInt(),
(y + (sideLength / (2 * sqrt(3.0)))).toInt(),
(y - (sideLength / sqrt(3.0))).toInt())
if(theta != 0) {
for(i in 0..2) {
xCords[i] = ((xCords[i]-x) * cos(toRadians(theta)) - (yCords[i]-y) * sin(toRadians(theta))).toInt() + x
yCords[i] = ((yCords[i]-y) * cos(toRadians(theta)) + (xCords[i]-x) * sin(toRadians(theta))).toInt() + y
}
}
fillPolygon(xCords.toIntArray(), yCords.toIntArray(), 3)
}
我的实现有什么问题吗?
我明白了。我正在修改 xCord
数组中的坐标,然后用于计算 yCord
数组中的新坐标。
我的新密码
var newX = (((xCords[i]-x) * cos(toRadians(theta)) - (yCords[i]-y)*sin(toRadians(theta)))+ x).toInt()
var newY = (((yCords[i]-y) * cos(toRadians(theta)) + (xCords[i]-x) * sin(toRadians(theta))) + y).toInt()
xCords[i] = newX
yCords[i] = newY
我没有检查你的数学,但我建议一个更简单的方法。对于每个点,计算以原点为中心的三角形的位置,然后添加偏移量。等边三角形只是圆上的三个点,相隔 120 度,所以数学就是 (x, y) = (r*cos(theta), r*sin(theta))
.
fun Graphics.fillTriangle(x: Int, y: Int, sideLength: Int, theta: Int = 0) {
val radius = sideLength / sqrt(3.0)
val angles = (0..2).map { it * (toRadians(theta) + toRadians(120)) }
val xCoords = angles.map { (radius * cos(it) + x).roundToInt() }.toIntArray()
val yCoords = angles.map { (radius * sin(it) + y).roundToInt() }.toIntArray()
fillPolygon(xCoords, yCoords, 3)
}