旋转的矩形被移动(SVG - 旋转矩阵)
Rotated rectangle is shifted (SVG - rotation matrix)
我使用 SVG 来处理一些公式。当我旋转一个矩形时,矩形会移动...
package main
import (
"bytes"
"fmt"
"log"
"math"
"os"
)
type Point struct {
X, Y float64
}
/* With SVG path the points are
A B
D C
*/
type Rect struct {
A Point
B Point
C Point
D Point
}
func (r *Rect) Rotate(a float64) {
r.A.X = r.A.X * math.Cos(dToR(a)) - r.A.Y * math.Sin(dToR(a))
r.A.Y = r.A.X * math.Sin(dToR(a)) + r.A.Y * math.Cos(dToR(a))
r.B.X = r.B.X * math.Cos(dToR(a)) - r.B.Y * math.Sin(dToR(a))
r.B.Y = r.B.X * math.Sin(dToR(a)) + r.B.Y * math.Cos(dToR(a))
r.C.X = r.C.X * math.Cos(dToR(a)) - r.C.Y * math.Sin(dToR(a))
r.C.Y = r.C.X * math.Sin(dToR(a)) + r.C.Y * math.Cos(dToR(a))
r.D.X = r.D.X * math.Cos(dToR(a)) - r.D.Y * math.Sin(dToR(a))
r.D.Y = r.D.X * math.Sin(dToR(a)) + r.D.Y * math.Cos(dToR(a))
}
// degree to radian
func dToR(deg float64) float64 {
return deg * (math.Pi / 180.0)
}
// radian to degree
func rToD(rad float64) float64 {
return rad * (180.0 / math.Pi)
}
func writeSvg(data []byte) error {
f, err := os.OpenFile("test.svg", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return err
}
defer f.Close()
_, err = f.Write(data)
if err != nil {
return err
}
return nil
}
func main() {
var b bytes.Buffer
b.WriteString("<svg width=\"600\" height=\"600\" xmlns=\"http://www.w3.org/2000/svg\">")
b.WriteString("<g stroke=\"black\" stroke-width=\"2.5\" fill=\"none\">")
b.WriteString("<path d=\"M")
r := &Rect {
Point{-200, -100},
Point{200, -100},
Point{200, 100},
Point{-200, 100},
}
moveX := 300.0
moveY := 300.0
r.Rotate(30)
b.WriteString(fmt.Sprintf("%.14f %.14f L", moveX+r.A.X, moveY+r.A.Y))
b.WriteString(fmt.Sprintf("%.14f %.14f ", moveX+r.B.X, moveY+r.B.Y))
b.WriteString(fmt.Sprintf("%.14f %.14f ", moveX+r.C.X, moveY+r.C.Y))
b.WriteString(fmt.Sprintf("%.14f %.14f Z", moveX+r.D.X, moveY+r.D.Y))
b.WriteString("\"/>\n")
b.WriteString("</g></svg>")
err := writeSvg(b.Bytes())
if err != nil {
log.Fatal(err)
}
}
结果如下所示(黑色矩形)
矩形已旋转,但角度不是 90 度...这是一个简单且有据可查的公式,但我找不到我的错误。
(在 SVG 中还有其他方法来绘制和旋转东西,但我使用的是公式。)
在您的 Rotate
函数中,您计算的新 x
、y
坐标不正确。您根据 r.A.X
和 r.A.Y
的当前值计算 r.A.X
,然后根据 r.A.X
的新值计算 r.A.Y
,这会让您失望.
您需要知道原始 x
、y
值,然后根据这些值计算新值。
rad := dToR(a)
x, y := r.A.X, r.A.Y
r.A.X = x*math.Cos(rad) - y*math.Sin(rad)
r.A.Y = x*math.Sin(rad) + y*math.Cos(rad)
我使用 SVG 来处理一些公式。当我旋转一个矩形时,矩形会移动...
package main
import (
"bytes"
"fmt"
"log"
"math"
"os"
)
type Point struct {
X, Y float64
}
/* With SVG path the points are
A B
D C
*/
type Rect struct {
A Point
B Point
C Point
D Point
}
func (r *Rect) Rotate(a float64) {
r.A.X = r.A.X * math.Cos(dToR(a)) - r.A.Y * math.Sin(dToR(a))
r.A.Y = r.A.X * math.Sin(dToR(a)) + r.A.Y * math.Cos(dToR(a))
r.B.X = r.B.X * math.Cos(dToR(a)) - r.B.Y * math.Sin(dToR(a))
r.B.Y = r.B.X * math.Sin(dToR(a)) + r.B.Y * math.Cos(dToR(a))
r.C.X = r.C.X * math.Cos(dToR(a)) - r.C.Y * math.Sin(dToR(a))
r.C.Y = r.C.X * math.Sin(dToR(a)) + r.C.Y * math.Cos(dToR(a))
r.D.X = r.D.X * math.Cos(dToR(a)) - r.D.Y * math.Sin(dToR(a))
r.D.Y = r.D.X * math.Sin(dToR(a)) + r.D.Y * math.Cos(dToR(a))
}
// degree to radian
func dToR(deg float64) float64 {
return deg * (math.Pi / 180.0)
}
// radian to degree
func rToD(rad float64) float64 {
return rad * (180.0 / math.Pi)
}
func writeSvg(data []byte) error {
f, err := os.OpenFile("test.svg", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return err
}
defer f.Close()
_, err = f.Write(data)
if err != nil {
return err
}
return nil
}
func main() {
var b bytes.Buffer
b.WriteString("<svg width=\"600\" height=\"600\" xmlns=\"http://www.w3.org/2000/svg\">")
b.WriteString("<g stroke=\"black\" stroke-width=\"2.5\" fill=\"none\">")
b.WriteString("<path d=\"M")
r := &Rect {
Point{-200, -100},
Point{200, -100},
Point{200, 100},
Point{-200, 100},
}
moveX := 300.0
moveY := 300.0
r.Rotate(30)
b.WriteString(fmt.Sprintf("%.14f %.14f L", moveX+r.A.X, moveY+r.A.Y))
b.WriteString(fmt.Sprintf("%.14f %.14f ", moveX+r.B.X, moveY+r.B.Y))
b.WriteString(fmt.Sprintf("%.14f %.14f ", moveX+r.C.X, moveY+r.C.Y))
b.WriteString(fmt.Sprintf("%.14f %.14f Z", moveX+r.D.X, moveY+r.D.Y))
b.WriteString("\"/>\n")
b.WriteString("</g></svg>")
err := writeSvg(b.Bytes())
if err != nil {
log.Fatal(err)
}
}
结果如下所示(黑色矩形)
矩形已旋转,但角度不是 90 度...这是一个简单且有据可查的公式,但我找不到我的错误。
(在 SVG 中还有其他方法来绘制和旋转东西,但我使用的是公式。)
在您的 Rotate
函数中,您计算的新 x
、y
坐标不正确。您根据 r.A.X
和 r.A.Y
的当前值计算 r.A.X
,然后根据 r.A.X
的新值计算 r.A.Y
,这会让您失望.
您需要知道原始 x
、y
值,然后根据这些值计算新值。
rad := dToR(a)
x, y := r.A.X, r.A.Y
r.A.X = x*math.Cos(rad) - y*math.Sin(rad)
r.A.Y = x*math.Sin(rad) + y*math.Cos(rad)