Skip to content

Instantly share code, notes, and snippets.

@ZumiKua
Created August 14, 2015 15:24
Show Gist options
  • Save ZumiKua/9ee499c1b2f8adb6f11f to your computer and use it in GitHub Desktop.
Save ZumiKua/9ee499c1b2f8adb6f11f to your computer and use it in GitHub Desktop.
#TODO 应该将每个点数组抽象成图形,然后实现normalize!以及rot方法
#fuck it, it works.
class Point
attr :x,true
attr :y,true
attr :z,true
def hash
x<<16|y<<8|z
end
def ==(o)
self.hash == o.hash
end
def initialize(a,b,c)
@x = a
@y = b
@z = c
end
end
class Routine
attr :src,true
attr :dsts
def initialize(from)
@c = 0
@src = from
@dsts = []
end
def to(dest,c)
@c |= 1<<c
@dsts[c] = dest
end
def complete?
return @c == 0xFFFF
end
end
def rot(points,angle,method_a,method_b)
case angle
when 0
return nil
when 1
points.each do |p|
t = p.__send__(method_b)
p.__send__(method_b.to_s+"=",p.__send__(method_a))
p.__send__(method_a.to_s+"=",-t)
end
when 2
points.each do |p|
p.__send__(method_a.to_s+"=",-p.__send__(method_a))
p.__send__(method_b.to_s+"=",-p.__send__(method_b))
end
when 3
points.each do |p|
t = p.__send__(method_b)
p.__send__(method_b.to_s+"=",-p.__send__(method_a))
p.__send__(method_a.to_s+"=",t)
end
end
end
def x_rot(points,angle)
rot(points,angle,'y','z')
end
def y_rot(points,angle)
rot(points,angle,'z','x')
end
def z_rot(points,angle)
rot(points,angle,'x','y')
end
def normalize!(points)
p = points.first.dup
points.each do |g|
g.x -= p.x
g.y -= p.y
g.z -= p.z
end
end
def rot_decide(i,p)
case i / 4
when 0
x_rot(p,i%4)
when 1
y_rot(p,i%4)
when 2
z_rot(p,i%4)
end
end
arr = [[Point.new(0,0,0),Point.new(1,0,0),Point.new(2,0,0),Point.new(3,0,0)]]
routines = [Routine.new(0)]
until(routines.all?{|r| r.complete?})
arr.each_with_index do |g,gi|
16.times do |i|
next if routines[gi].dsts[i]
tmp = Marshal.load(Marshal.dump(g))
rot_decide(i,tmp)
normalize!(tmp)
unless (di = arr.index(tmp))
arr.push tmp
routines.push Routine.new(arr.size - 1)
di = arr.size - 1
puts arr.size
end
routines[gi].to(di,i)
end
end
end
=begin
def x_rot(points,angle)
case angle
when 0
return points
when 1
points.each do |p|
t = p.z
p.z = p.y
p.y = -t
end
when 2
points.each do |p|
p.z = -p.z
p.y = -p.y
end
when 3
points.each do |p|
t = p.z
p.z = -p.y
p.y = p.z
end
end
end
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment