Чтобы повернуть точку P количество R градусов вокруг начала координат:
P2.x = P.x * cos ( R ) - P.y * sin ( R )
P2.y = P.x * sin ( R ) + P.y * cos ( R )
[править]
Вы, вероятно, хотите повернуть вокруг произвольной точки в центре квадранта, в котором вы храните объекты. Если ваш квадрант имеет ширину 200x100 единиц, вам нужно будет вращаться вокруг точки <100,50>
.
Чтобы повернуть точку P вокруг местоположения C , отличного от начала координат, необходимо сначала перевести местоположение в начало координат, затем повернуть вокруг начала координат и затем перевести обратно на C. Другими словами,
P2 = P - C
P3 = поворот ( P2 )
P4 = P3 + C
Вы можете увидеть это в действии на http://phrogz.net/SVG/rotations.xhtml - щелкните, чтобы установить центр вращения или изменить величину вращения, и для группы точек будет установлено преобразование, которое переводится в начало координат, вращается, а затем переводит обратно снова.
Соберите все вместе, и чтобы повернуть точку с атрибутами x
и y
вокруг произвольной точки в Ruby, вы должны использовать такой код:
Point = Struct.new(:x,:y) do
def self.to_proc
lambda{ |x| self.new *x }
end
def rotate( degrees, origin=Point.new(0,0) )
radians = degrees * Math::PI/180
x2 = x-origin.x; y2 = y-origin.y
cos = Math.cos(radians); sin = Math.sin(radians)
self.class.new(
x2*cos - y2*sin + origin.x,
x2*sin + y2*cos + origin.y
)
end
def inspect
"<%.1f,%.1f>" % [x,y]
end
end
points = [ [0,0], [1,2], [3,4], [5,6] ].map(&Point)
p points
#=> [<0.0,0.0>, <1.0,2.0>, <3.0,4.0>, <5.0,6.0>]
p points.map{ |p| p.rotate(90) }
#=> [<0.0,0.0>, <-2.0,1.0>, <-4.0,3.0>, <-6.0,5.0>]
p points.map{ |p| p.rotate(90,Point.new(3,4)) }
#=> [<7.0,1.0>, <5.0,2.0>, <3.0,4.0>, <1.0,6.0>]