Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[RMXP/VX] [Herramienta de Scripter] Rect +

Ver el tema anterior Ver el tema siguiente Ir abajo

[RMXP/VX] [Herramienta de Scripter] Rect +

Mensaje por Wecoc el 2013-09-29, 18:46

Un script para tener más opciones con la clase Rect, no pido créditos, algunas cosas fueron sacadas de internet.

Código:
#==============================================================================
# ** Rect +
#------------------------------------------------------------------------------
#  Autor: Wecoc (no pido créditos)
#==============================================================================

#--------------------------------------------------------------------------
# * Point
#--------------------------------------------------------------------------

class Point
  attr_accessor :x, :y
  
  def initialize(x,y)
    @x = x
    @y = y
  end
  
  def +(p)
    Point.new(@x + p.x, @y + p.y)
  end
  
  def -(p)
    Point.new(@x - p.x, @y - p.y)
  end
  
  def *(scalar)
    Point.new(@x * scalar, @y * scalar)
  end
  
  def dot(p)
    (@x * p.x) + (@y * p.y)
  end
  
  def perp
    Point.new(-@y, @x)
  end
  
  def abs
    Point.new(@x.abs, @y.abs)
  end
  
  def to_s
    "Point: (#{@x}, #{@y})"
  end
  
  def to_a
    return [@x, @y]
  end
  
  def dis(p)
    Math.sqrt((p.x - @x) ** 2 + (p.y - @y) ** 2)
  end
  
  def is_inside?(rect)
    return rect.contain?(self)
  end
  
  def self.midpoint(a, b)
    return Point.new((a.x + b.x) * 0.5, (a.y + b.y) * 0.5)
  end
end

#--------------------------------------------------------------------------
# * Size
#--------------------------------------------------------------------------

class Size
  
  attr_accessor :width
  attr_accessor :height
  
  unless $@
    alias :w :width
    alias :h :height
  end

  def initialize(width, height)
    @width = width
    @height = height
  end

  def to_s
    "Size: (#{@width}, #{@height})"
  end
  
  def to_a
    return [@width, @height]
  end
end

#--------------------------------------------------------------------------
# * Rect
#--------------------------------------------------------------------------

class Rect
  
  attr_accessor :origin
  attr_accessor :size
  
  unless $@
    alias :w :width
    alias :h :height
  end
  
  def initialize(*args)
    case args.size
    when 1 # Rect
      @origin = Point.new(args[0].x.to_f, args[0].y.to_f)
      @size = Size.new(args[0].width.to_f, args[0].height.to_f)
    when 2 # Point, Size
      @origin = Point.new(args[0].x.to_f, args[0].y.to_f)
      @size = Size.new(args[1].width.to_f, args[1].height.to_f)
    when 4 # x, y, width, height
      @origin = Point.new(args[0].to_f, args[1].to_f)
      @size = Size.new(args[2].to_f, args[3].to_f)
    end
    @x = @origin.x
    @y = @origin.y
    @width = @size.width
    @height = @size.height
    set(@origin.x, @origin.y, @size.width, @size.height)
  end
  
  def inset(dx, dy)
    o = Point.new(@origin.x + dx, @origin.y + dy)
    s = Size.new(@size.width - 2*dx, @size.height - 2*dy)
    if s.width < 0 or s.height < 0
      s.width = 0
      s.height = 0
    end
    Rect.new(o, s)
  end
  
  def min_x
    @origin.x
  end
    
  def min_y
    @origin.y
  end
  
  def max_x
    @origin.x + @size.width
  end
  
  def max_y
    @origin.y + @size.height
  end
  
  def center_x
    @origin.x + @size.width / 2.0
  end
  
  def center_y
    @origin.y + @size.height / 2.0
  end
  
  def min
    return Point.new(min_x, min_y)
  end
  
  def max
    return Point.new(max_x, max_y)
  end
  
  def center
    return Point.new(center_x, center_y)
  end
  
  def cut(edge, amount)
    origin = @origin.dup
    size = @size.dup
    case edge
    when :min_x, 0
      origin.x += amount
      size.width -= amount
    when :min_y, 1
      origin.y += amount
      size.height -= amount
    when :max_x, 2
      size.width -= amount
    when :max_y, 3
      size.height -= amount
    end
    if size.width < 0 or size.height < 0
      size.width = 0
      size.height = 0
    end
    Rect.new(origin, size)
  end
  
  def cut!(edge, amount)
    rect = self.cut(edge, amount)
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
  
  def union(r)
    _min_x = min_x
    _min_y = min_y
    _max_x = max_x
    _max_y = max_y
    
    other_min_x = r.min_x
    other_min_y = r.min_y
    other_max_x = r.max_x
    other_max_y = r.max_y
    
    _min_x = other_min_x if other_min_x < _min_x
    _min_y = other_min_y if other_min_y < _min_y
    
    _max_x = other_max_x if other_max_x > _max_x
    _max_y = other_max_y if other_max_y > _max_y
    
    Rect.new(_min_x, _min_y, _max_x - _min_x, _max_y - _min_y)
  end
  
  def union!(r)
    rect = self.union(r)
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
  
  def clamp(r)
    _min_x = min_x
    _min_y = min_y
    _max_x = max_x
    _max_y = max_y
    
    other_min_x = r.min_x
    other_min_y = r.min_y
    other_max_x = r.max_x
    other_max_y = r.max_y
    
    _min_x = other_min_x if other_min_x > _min_x
    _min_y = other_min_y if other_min_y > _min_y
    
    _max_x = other_max_x if other_max_x < _max_x
    _max_y = other_max_y if other_max_y < _max_y
    
    Rect.new(_min_x, _min_y, _max_x - _min_x, _max_y - _min_y)
  end
  
  def clamp!(r)
    rect = self.clamp(r)
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
  
  def normalize
    _x = x
    _y = y
    _width = width
    _height = height
    if width < 0
      _width = width.abs
      _x -= _width
    end
    if height < 0
      _height = height.abs
      _y -= _height
    end
    Rect.new(_x, _y, _width, _height)
  end
  
  def normalize!
    rect = self.normalize
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
  
  def move(dx, dy)
    self.x += dx
    self.y += dy
    return self
  end
  
  def grow(dw, dh)
    self.width += dw
    self.height += dh
    return self
  end
  
  def inflate(dx, dy=dx)
    self.x -= dx / 2
    self.y -= dy / 2
    self.width += dx / 2
    self.height += dy / 2
    return self
  end
  
  def contain?(r)
    if r.is_a?(Rect)
      return (x <= r.x and y <= r.y and max_x >= r.max_x and max_y >= r.max_y)
    else # Point
      return (r.x.between?(x, max_x) and r.y.between?(y, max_y))
    end
  end
    
  def collide?(r)
    if r.is_a?(Rect)
      if x == r.max_x and y.between?(r.min_y, r.max_y)
        return true
      end
      if y == r.max_y and x.between?(r.min_x, r.max_x)
        return true
      end
      if r.x == max_x and r.y.between?(min_y, max_y)
        return true
      end
      if r.y == max_y and r.x.between?(min_x, max_x)
        return true
      end
      return false
    else # Point
      if (r.x == min_x or r.x == max_x) and r.y.between?(min_y, max_y)
        return true
      end
      if (r.y == min_y or r.y == max_y) and r.x.between?(min_x, max_x)
        return true
      end
      return false
    end
  end
    
  def overlap?(r)
    return true if self.contain?(r)
    if max_x > r.min_x and (max_y < r.max_y or min_y < r.min_y)
      return true
    end
    if max_y > r.min_y and (max_x < r.max_x or min_x < r.min_x)
      return true
    end
    if r.max_x > min_x and (r.max_y < max_y or r.min_y < min_y)
      return true
    end
    if r.max_y > min_y and (r.max_x < max_x or r.min_x < min_x)
      return true
    end
    if c0.is_inside?(r) or c1.is_inside?(r) or c2.is_inside?(r) or
     c3.is_inside?(r)
        return true
    end
    if r.c0.is_inside?(self) or r.c1.is_inside?(self) or r.c2.is_inside?(self) or
      rc3.is_inside?(self)
        return true
    end
    return false
  end
  
  def to_s(style=1)
    case style
    when 1
      "(#{x}, #{y}, #{width}, #{height})"
    when 2
      "( #{origin} , #{size} )"
    when 4
      "(#{min_x}, #{min_y}, #{max_x}, #{max_y})"
    end
  end
  
  def to_a
    return [x, y, w, h]
  end
  
  def c0
    return Point.new(min_x, min_y)
  end
  
  def c1
    return Point.new(max_x, min_y)
  end

  def c2
    return Point.new(min_x, max_y)
  end
  
  def c3
    return Point.new(min_x, max_y)
  end
end

#--------------------------------------------------------------------------
# * Array
#--------------------------------------------------------------------------

class Array
  def to_point
    Point.new(self[0], self[1])
  end
  
  def to_size
    Size.new(self[0], self[1])
  end
  
  def to_rect
    case self.size
    when 1 then Rect.new(self[0])
    when 2 then Rect.new(self[0], self[1])
    when 4 then Rect.new(self[0], self[1], self[2], self[3])
    end
  end
end
La particuliaridad de éste script está en usar dos clases "bidimensionales" a parte; Point para las coordenadas y Size para el tamaño.

Point

+ - Suma dos point
- - Resta dos point
* - Multiplica un valor a un point
dot(point) - Multiplica dos point
perp - Devuelve un point (-y, x).
abs - Devuelve el mismo point con valores absolutos
dis(point) - Calcula la distancia entre dos point
is_inside?(rect) - Mira si está dentro de un Rect
Point.midpoint(A, B) - Devuelve el punto medio entre dos puntos

Rect

min_x - x (x mínimo)
min_y - y (y mínimo)
max_x - x + width (x máximo)
max_y - y + height (y máximo)
center_x - x del centro
center_y - y del centro
center - punto central
min - punto mínimo
max - punto máximo
c0 - corner 0 (arriba izquierda). min
c1 - corner 1 (arriba derecha)
c2 - corner 2 (abajo izquierda)
c3 - corner 3 (abajo derecha). max
cut(edge, amount) - corta en un lado una cantidad concreta afectando también al otro lado
union(rect) - junta dos rect formando uno tan grande como para poder contener los dos dentro
clamp(rect) - junta dos rect formando uno tan pequeño como la porción en la que eran coincidentes
normalize - arregla el posible error de width o height negativos alterando las coordenadas para formar el mismo rect con valores positivos.
move(dx, dy) - mueve el rect una distancia concreta
grow(dw, dh) - cambia el tamaño del rect una distancia concreta
inflate(dx, dy=dx) - similar a grow pero actúa desde el centro del rect
contain?(point) - mira si el punto está dentro del rect
contain?(rect) - mira si un rect más pequeño está totalmente dentro del rect
collide?(point) - mira si el punto está tocando los bordes del rect
collide?(rect) - mira si los bordes de los dos rect se tocan en algún punto
overlap?(point) - similar a contain?(point)
overlap?(rect) - mira si dos rect se superponen, similar a contain? pero no tiene por qué estar uno totalmente dentro del otro.
avatar
Wecoc
Administrador
Administrador



Créditos 12297

Gracias : 648

Volver arriba Ir abajo

Re: [RMXP/VX] [Herramienta de Scripter] Rect +

Mensaje por Eron el 2013-10-01, 07:28

Está bien =D
Te lo he ampliado y retocado un poco pero ahora quedan algunas cosas por hacer, lo siento x'D

Código:
#==============================================================================
# ** Rect +
#------------------------------------------------------------------------------
#  Autores: Wecoc, Eron (no pedimos créditos)
#==============================================================================

#--------------------------------------------------------------------------
# * Point
#--------------------------------------------------------------------------

class Point
attr_accessor :x, :y

def initialize(x,y)
  @x = x
  @y = y
end

def +(p)
  Point.new(@x + p.x, @y + p.y)
end

def -(p)
  Point.new(@x - p.x, @y - p.y)
end

def *(scalar)
  Point.new(@x * scalar, @y * scalar)
end

def dot(p)
  (@x * p.x) + (@y * p.y)
end

def perp
  Point.new(-@y, @x)
end

def abs
  Point.new(@x.abs, @y.abs)
end

def to_s
  "Point: (#{@x}, #{@y})"
end

def to_a
  return [@x, @y]
end

def dis(p)
  Math.sqrt((p.x - @x) ** 2 + (p.y - @y) ** 2)
end

def is_inside?(rect)
  return rect.contain?(self)
end

def self.midpoint(a, b)
  return Point.new((a.x + b.x) * 0.5, (a.y + b.y) * 0.5)
end
 
def self.gravity_point(a, b, ag=1, bg =1)
  ag = ag.to_f
  bg = bg.to_f
  nag = ag/(ag+bg)
  nbg = bg/(ag+bg)
  return Point.new((a.x * ag + b.x * bg), (a.y * ag + b.y * bg))
end
end

#--------------------------------------------------------------------------
# * Size
#--------------------------------------------------------------------------

class Size

attr_accessor :width
attr_accessor :height

def initialize(width, height)
  @width = width
  @height = height
end

def to_s
  "Size: (#{@width}, #{@height})"
end

def to_a
  return [@width, @height]
end
end

#--------------------------------------------------------------------------
# * Rect
#--------------------------------------------------------------------------

class Rect

attr_accessor :origin
attr_accessor :size

unless $@
  alias :w :width
  alias :h :height
end

def initialize(*args)
  case args.size
  when 1 # Rect
    @origin = Point.new(args[0].x.to_f, args[0].y.to_f)
    @size = Size.new(args[0].width.to_f, args[0].height.to_f)
  when 2 # Point, Size
    @origin = Point.new(args[0].x.to_f, args[0].y.to_f)
    @size = Size.new(args[1].width.to_f, args[1].height.to_f)
  when 4 # x, y, width, height
    @origin = Point.new(args[0].to_f, args[1].to_f)
    @size = Size.new(args[2].to_f, args[3].to_f)
  end
  @x = @origin.x
  @y = @origin.y
  @width = @size.width
  @height = @size.height
  set(@origin.x, @origin.y, @size.width, @size.height)
end

def inset(dx, dy)
  o = Point.new(@origin.x + dx, @origin.y + dy)
  s = Size.new(@size.width - 2 * dx, @size.height - 2 * dy)
  if s.width < 0 or s.height < 0
    s.width = 0
    s.height = 0
  end
  Rect.new(o, s)
end

# ===================================================================

def w
  return width
end

def h
  return height
end

def w=(value)
  self.width = value
end

def h=(value)
  self.height = value
end

def size
  return Size.new(width, height)
end

def size=(*args)
end

def min_x
  return x
end
 
def min_y
  return y
end

def max_x
  return x + w
end

def max_y
  return y + h
end

def center_x
  return x + w / 2.0
end

def center_y
  return y + h / 2.0
end

def min_x=(value)
end

def min_y=(value)
end

def max_x=(value)
end

def max_y=(value)
end

def center_x=(value)
  # Usar move(dx, dy), calcular dx y dy según value y center_x
end

def center_y=(value)
  # Usar move(dx, dy), calcular dx y dy según value y center_y
end

def min
  return Point.new(min_x, min_y)
end

def max
  return Point.new(max_x, max_y)
end

def center
  return Point.new(center_x, center_y)
end

def min=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def max=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def center=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def left
  return x
end

def top
  return y
end

def right
  return max_x
end

def bottom
  return max_y
end

def left=(value)
  self.x = value
end

def top=(value)
  self.y = value
end

def right=(value)
  self.max_x = value
end

def bottom=(value)
  self.max_y = value
end

def c0
  return Point.new(min_x, min_y)
end

def c1
  return Point.new(max_x, min_y)
end

def c2
  return Point.new(min_x, max_y)
end

def c3
  return Point.new(min_x, max_y)
end

def bottomleft
  return Point.new(min_x, max_y)
end

def bottomleft=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def bottomright
  return Point.new(max_x, max_y)
end

def bottomright=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def midbottom
  return Point.new(center_x, max_y)
end

def midbottom=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def midleft
  return Point.new(min_x, center_y)
end

def midleft=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def midright
  return Point.new(max_x, center_y)
end

def midright=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def midtop
  return Point.new(center_x, min_y)
end

def midtop=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def topleft
  return Point.new(min_x, min_y)
end

def topleft=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

def topright
  return Point.new(min_x, max_y)
end
 
def topright=(*args)
  # Integers, Array o Point, usar move(dx, dy)
end

# ===================================================================

def cut(edge, amount)
  origin = @origin.dup
  size = @size.dup
  case edge
  when :min_x, 0
    origin.x += amount
    size.width -= amount
  when :min_y, 1
    origin.y += amount
    size.height -= amount
  when :max_x, 2
    size.width -= amount
  when :max_y, 3
    size.height -= amount
  end
  if size.width < 0 or size.height < 0
    size.width = 0
    size.height = 0
  end
  Rect.new(origin, size)
end

def cut!(edge, amount)
  rect = self.cut(edge, amount)
  self.x = rect.x
  self.y = rect.y
  self.width = rect.width
  self.height = rect.height
  return self
end

def union(r)
  _min_x = min_x
  _min_y = min_y
  _max_x = max_x
  _max_y = max_y
 
  other_min_x = r.min_x
  other_min_y = r.min_y
  other_max_x = r.max_x
  other_max_y = r.max_y
 
  _min_x = other_min_x if other_min_x < _min_x
  _min_y = other_min_y if other_min_y < _min_y
 
  _max_x = other_max_x if other_max_x > _max_x
  _max_y = other_max_y if other_max_y > _max_y
 
  Rect.new(_min_x, _min_y, _max_x - _min_x, _max_y - _min_y)
end

def union!(r)
  rect = self.union(r)
  self.x = rect.x
  self.y = rect.y
  self.width = rect.width
  self.height = rect.height
  return self
end

def clamp(r)
  _min_x = min_x
  _min_y = min_y
  _max_x = max_x
  _max_y = max_y
 
  other_min_x = r.min_x
  other_min_y = r.min_y
  other_max_x = r.max_x
  other_max_y = r.max_y
 
  _min_x = other_min_x if other_min_x > _min_x
  _min_y = other_min_y if other_min_y > _min_y
 
  _max_x = other_max_x if other_max_x < _max_x
  _max_y = other_max_y if other_max_y < _max_y
 
  Rect.new(_min_x, _min_y, _max_x - _min_x, _max_y - _min_y)
end

def clamp!(r)
  rect = self.clamp(r)
  self.x = rect.x
  self.y = rect.y
  self.width = rect.width
  self.height = rect.height
  return self
end

def normalize
  _x = x
  _y = y
  _width = width
  _height = height
  if width < 0
    _width = width.abs
    _x -= _width
  end
  if height < 0
    _height = height.abs
    _y -= _height
  end
  Rect.new(_x, _y, _width, _height)
end

def normalize!
  rect = self.normalize
  self.x = rect.x
  self.y = rect.y
  self.width = rect.width
  self.height = rect.height
  return self
end

def move(dx, dy)
  Rect.new(self.x + dx, self.y + dy, self.width, self.height)
end

def move!(dx, dy)
  self.x += dx
  self.y += dy
  return self
end

def grow(dw, dh)
  Rect.new(self.x, self.y, self.width + dw, self.height + dh)
end

def grow!(dw, dh)
  self.width += dw
  self.height += dh
  return self
end
 
def inflate(dx, dy=dx)
  Rect.new(x - (dx / 2), y - (dy / 2), width + (dx / 2), height + (dy / 2))
end

def inflate!(dx, dy=dx)
  self.x -= dx / 2
  self.y -= dy / 2
  self.width += dx / 2
  self.height += dy / 2
  return self
end

def contain?(r)
  if r.is_a?(Rect)
    return (x <= r.x and y <= r.y and max_x >= r.max_x and max_y >= r.max_y)
  else # Point
    return (r.x.between?(x, max_x) and r.y.between?(y, max_y))
  end
end
 
def collide?(r)
  if r.is_a?(Rect)
    if x == r.max_x and y.between?(r.min_y, r.max_y)
      return true
    end
    if y == r.max_y and x.between?(r.min_x, r.max_x)
      return true
    end
    if r.x == max_x and r.y.between?(min_y, max_y)
      return true
    end
    if r.y == max_y and r.x.between?(min_x, max_x)
      return true
    end
    return false
  else # Point
    if (r.x == min_x or r.x == max_x) and r.y.between?(min_y, max_y)
      return true
    end
    if (r.y == min_y or r.y == max_y) and r.x.between?(min_x, max_x)
      return true
    end
    return false
  end
end
 
def overlap?(r)
  return true if self.contain?(r)
  if max_x > r.min_x and (max_y < r.max_y or min_y < r.min_y)
    return true
  end
  if max_y > r.min_y and (max_x < r.max_x or min_x < r.min_x)
    return true
  end
  if r.max_x > min_x and (r.max_y < max_y or r.min_y < min_y)
    return true
  end
  if r.max_y > min_y and (r.max_x < max_x or r.min_x < min_x)
    return true
  end
  if c0.is_inside?(r) or c1.is_inside?(r) or c2.is_inside?(r) or
   c3.is_inside?(r)
      return true
  end
  if r.c0.is_inside?(self) or r.c1.is_inside?(self) or r.c2.is_inside?(self) or
    rc3.is_inside?(self)
      return true
  end
  return false
end

# ===================================================================

def to_s(style=1)
  case style
  when 1
    "(#{x}, #{y}, #{width}, #{height})"
  when 2
    "( #{origin} , #{size} )"
  when 4
    "(#{min_x}, #{min_y}, #{max_x}, #{max_y})"
  end
end

def to_a
  return [x, y, w, h]
end
end

#--------------------------------------------------------------------------
# * Array
#--------------------------------------------------------------------------

class Array
def to_point
  Point.new(self[0], self[1])
end

def to_size
  Size.new(self[0], self[1])
end

def to_rect
  case self.size
  when 1 then Rect.new(self[0])
  when 2 then Rect.new(self[0], self[1])
  when 4 then Rect.new(self[0], self[1], self[2], self[3])
  end
end
end
Por cierto muchas de éstas funciones también se podrían usar en ventanas, ¿no?
avatar
Eron
Principiante
Principiante

0/3

Créditos 3599

Gracias : 60

Volver arriba Ir abajo

Re: [RMXP/VX] [Herramienta de Scripter] Rect +

Mensaje por Wecoc el 2013-10-05, 22:23

Eso, tú atarea más al pobre Wecoc...

Creo que ya está

Código:
#==============================================================================
# ** Rect +
#------------------------------------------------------------------------------
#  Autores: Wecoc, Eron (no pedimos créditos)
#==============================================================================

#--------------------------------------------------------------------------
# * Point
#--------------------------------------------------------------------------

class Point
  attr_accessor :x, :y
 
  def initialize(x,y)
    @x = x
    @y = y
  end
 
  def [](i)
    case i
      when 0 then return @x
      when 1 then return @y
    end
  end
 
  def +(p)
    Point.new(@x + p.x, @y + p.y)
  end
 
  def -(p)
    Point.new(@x - p.x, @y - p.y)
  end
 
  def *(scalar)
    Point.new(@x * scalar, @y * scalar)
  end
 
  def dot(p)
    (@x * p.x) + (@y * p.y)
  end
 
  def perp
    Point.new(-@y, @x)
  end
 
  def abs
    Point.new(@x.abs, @y.abs)
  end
 
  def to_s
    "Point: (#{@x}, #{@y})"
  end
 
  def to_a
    return [@x, @y]
  end
 
  def dis(p)
    Math.sqrt((p.x - @x) ** 2 + (p.y - @y) ** 2)
  end
 
  def is_inside?(rect)
    return rect.contain?(self)
  end
 
  def self.midpoint(a, b)
    return Point.new((a.x + b.x) * 0.5, (a.y + b.y) * 0.5)
  end
 
  def self.gravity_point(a, b, ag=1, bg =1)
    ag = ag.to_f
    bg = bg.to_f
    nag = ag/(ag+bg).to_f
    nbg = bg/(ag+bg).to_f
    return Point.new((a.x * nag + b.x * nbg), (a.y * nag + b.y * nbg))
  end
end

#--------------------------------------------------------------------------
# * Size
#--------------------------------------------------------------------------

class Size
 
  attr_accessor :width
  attr_accessor :height
 
  def initialize(width, height)
    @width = width
    @height = height
  end
 
  def [](i)
    case i
      when 0 then return @width
      when 1 then return @height
    end
  end
 
  def to_s
    "Size: (#{@width}, #{@height})"
  end
 
  def to_a
    return [@width, @height]
  end
end

#--------------------------------------------------------------------------
# * Rect
#--------------------------------------------------------------------------

class Rect
 
  attr_accessor :origin
  attr_accessor :size
 
  unless $@
    alias :w :width
    alias :h :height
  end
 
  def initialize(*args)
    case args.size
    when 1 # Rect
      @origin = Point.new(args[0].x.to_f, args[0].y.to_f)
      @size = Size.new(args[0].width.to_f, args[0].height.to_f)
    when 2 # Point, Size
      @origin = Point.new(args[0].x.to_f, args[0].y.to_f)
      @size = Size.new(args[1].width.to_f, args[1].height.to_f)
    when 4 # x, y, width, height
      @origin = Point.new(args[0].to_f, args[1].to_f)
      @size = Size.new(args[2].to_f, args[3].to_f)
    end
    @x = @origin.x
    @y = @origin.y
    @width = @size.width
    @height = @size.height
    set(@origin.x, @origin.y, @size.width, @size.height)
  end
 
  def inset(dx, dy)
    o = Point.new(@origin.x + dx, @origin.y + dy)
    s = Size.new(@size.width - 2 * dx, @size.height - 2 * dy)
    if s.width < 0 or s.height < 0
      s.width = 0
      s.height = 0
    end
    Rect.new(o, s)
  end
 
  def [](i)
    case i
      when 0 then return @x
      when 1 then return @y
      when 2 then return @width
      when 3 then return @height
    end
  end
 
  # ===================================================================
 
  def w
    return width
  end
 
  def h
    return height
  end
 
  def w=(value)
    self.width = value
  end
 
  def h=(value)
    self.height = value
  end
 
  def size
    return Size.new(width, height)
  end
 
  def size=(*args)
  end
 
  def min_x
    return x
  end
 
  def min_y
    return y
  end
 
  def max_x
    return x + w
  end
 
  def max_y
    return y + h
  end
 
  def center_x
    return x + w / 2.0
  end
 
  def center_y
    return y + h / 2.0
  end
 
  def min_x=(value)
    self.width += self.x - value
    self.x = value
  end
 
  def min_y=(value)
    self.height += self.y - value
    self.y = value
  end
 
  def max_x=(value)
    self.width += value - self.max_x
  end
 
  def max_y=(value)
    self.height += value - self.max_y
  end
 
  def center_x=(value)
    move!(value - self.center_x, 0)
  end
 
  def center_y=(value)
    move!(0, value - self.center_y)
  end
 
  def min
    return Point.new(min_x, min_y)
  end
 
  def max
    return Point.new(max_x, max_y)
  end
 
  def center
    return Point.new(center_x, center_y)
  end
 
  def min=(*args)
    case args.size
    when 2 # Integer
      self.min_x = args[0]
      self.min_y = args[1]
    else # Array, Point
      self.min_x = args[0][0]
      self.min_y = args[0][1]
    end
  end
 
  def max=(*args)
    case args.size
    when 2 # Integer
      self.max_x = args[0]
      self.max_y = args[1]
    else # Array, Point
      self.max_x = args[0][0]
      self.max_y = args[0][1]
    end
  end
 
  def center=(*args)
    case args.size
    when 2 # Integer
      self.center_x = args[0]
      self.center_y = args[1]
    else # Array, Point
      self.center_x = args[0][0]
      self.center_y = args[0][1]
    end
  end
 
  def left
    return x
  end
 
  def top
    return y
  end
 
  def right
    return max_x
  end
 
  def bottom
    return max_y
  end
 
  def left=(value)
    self.x = value
  end
 
  def top=(value)
    self.y = value
  end
 
  def right=(value)
    self.max_x = value
  end
 
  def bottom=(value)
    self.max_y = value
  end
 
  def c0
    return Point.new(min_x, min_y)
  end
 
  def c1
    return Point.new(max_x, min_y)
  end
 
  def c2
    return Point.new(min_x, max_y)
  end
 
  def c3
    return Point.new(min_x, max_y)
  end
 
  def bottomleft
    return Point.new(min_x, max_y)
  end
 
  def bottomleft=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.bottomleft
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.bottomleft
    end
    move!(point[0], point[1])
  end
 
  def bottomright
    return Point.new(max_x, max_y)
  end
 
  def bottomright=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.bottomright
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.bottomright
    end
    move!(point[0], point[1])
  end
 
  def midbottom
    return Point.new(center_x, max_y)
  end
 
  def midbottom=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.midbottom
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.midbottom
    end
    move!(point[0], point[1])
  end
 
  def midleft
    return Point.new(min_x, center_y)
  end
 
  def midleft=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.midleft
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.midleft
    end
    move!(point[0], point[1])
  end
 
  def midright
    return Point.new(max_x, center_y)
  end
 
  def midright=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.midright
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.midright
    end
    move!(point[0], point[1])
  end
 
  def midtop
    return Point.new(center_x, min_y)
  end
 
  def midtop=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.midtop
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.midtop
    end
    move!(point[0], point[1])
  end
 
  def topleft
    return Point.new(min_x, min_y)
  end
 
  def topleft=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.topleft
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.topleft
    end
    move!(point[0], point[1])
  end
 
  def topright
    return Point.new(min_x, max_y)
  end
 
  def topright=(*args)
    case args.size
    when 2 # Integers
      point = Point.new(args[0], args[1]) - self.topright
    else # Array, Point
      point = Point.new(args[0][0], args[0][1]) - self.topright
    end
    move!(point[0], point[1])
  end
 
  # ===================================================================
 
  def cut(edge, amount)
    origin = @origin.dup
    size = @size.dup
    case edge
    when :min_x, 0
      origin.x += amount
      size.width -= amount
    when :min_y, 1
      origin.y += amount
      size.height -= amount
    when :max_x, 2
      size.width -= amount
    when :max_y, 3
      size.height -= amount
    end
    if size.width < 0 or size.height < 0
      size.width = 0
      size.height = 0
    end
    Rect.new(origin, size)
  end
 
  def cut!(edge, amount)
    rect = self.cut(edge, amount)
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
 
  def union(r)
    _min_x = min_x
    _min_y = min_y
    _max_x = max_x
    _max_y = max_y
 
    other_min_x = r.min_x
    other_min_y = r.min_y
    other_max_x = r.max_x
    other_max_y = r.max_y
 
    _min_x = other_min_x if other_min_x < _min_x
    _min_y = other_min_y if other_min_y < _min_y
 
    _max_x = other_max_x if other_max_x > _max_x
    _max_y = other_max_y if other_max_y > _max_y
 
    Rect.new(_min_x, _min_y, _max_x - _min_x, _max_y - _min_y)
  end
 
  def union!(r)
    rect = self.union(r)
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
 
  def clamp(r)
    _min_x = min_x
    _min_y = min_y
    _max_x = max_x
    _max_y = max_y
 
    other_min_x = r.min_x
    other_min_y = r.min_y
    other_max_x = r.max_x
    other_max_y = r.max_y
 
    _min_x = other_min_x if other_min_x > _min_x
    _min_y = other_min_y if other_min_y > _min_y
 
    _max_x = other_max_x if other_max_x < _max_x
    _max_y = other_max_y if other_max_y < _max_y
 
    Rect.new(_min_x, _min_y, _max_x - _min_x, _max_y - _min_y)
  end
 
  def clamp!(r)
    rect = self.clamp(r)
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
 
  def normalize
    _x = x
    _y = y
    _width = width
    _height = height
    if width < 0
      _width = width.abs
      _x -= _width
    end
    if height < 0
      _height = height.abs
      _y -= _height
    end
    Rect.new(_x, _y, _width, _height)
  end
 
  def normalize!
    rect = self.normalize
    self.x = rect.x
    self.y = rect.y
    self.width = rect.width
    self.height = rect.height
    return self
  end
 
  def move(dx, dy)
    Rect.new(self.x + dx, self.y + dy, self.width, self.height)
  end
 
  def move!(dx, dy)
    self.x += dx
    self.y += dy
    return self
  end
 
  def grow(dw, dh)
    Rect.new(self.x, self.y, self.width + dw, self.height + dh)
  end
 
  def grow!(dw, dh)
    self.width += dw
    self.height += dh
    return self
  end
 
  def inflate(dx, dy=dx)
    Rect.new(x - (dx / 2), y - (dy / 2), width + (dx / 2), height + (dy / 2))
  end
 
  def inflate!(dx, dy=dx)
    self.x -= dx / 2
    self.y -= dy / 2
    self.width += dx / 2
    self.height += dy / 2
    return self
  end
 
  def contain?(r)
    if r.is_a?(Rect)
      return (x <= r.x and y <= r.y and max_x >= r.max_x and max_y >= r.max_y)
    else # Point
      return (r.x.between?(x, max_x) and r.y.between?(y, max_y))
    end
  end
 
  def collide?(r)
    if r.is_a?(Rect)
      if x == r.max_x and y.between?(r.min_y, r.max_y)
        return true
      end
      if y == r.max_y and x.between?(r.min_x, r.max_x)
        return true
      end
      if r.x == max_x and r.y.between?(min_y, max_y)
        return true
      end
      if r.y == max_y and r.x.between?(min_x, max_x)
        return true
      end
      return false
    else # Point
      if (r.x == min_x or r.x == max_x) and r.y.between?(min_y, max_y)
        return true
      end
      if (r.y == min_y or r.y == max_y) and r.x.between?(min_x, max_x)
        return true
      end
      return false
    end
  end
 
  def overlap?(r)
    return true if self.contain?(r)
    if max_x > r.min_x and (max_y < r.max_y or min_y < r.min_y)
      return true
    end
    if max_y > r.min_y and (max_x < r.max_x or min_x < r.min_x)
      return true
    end
    if r.max_x > min_x and (r.max_y < max_y or r.min_y < min_y)
      return true
    end
    if r.max_y > min_y and (r.max_x < max_x or r.min_x < min_x)
      return true
    end
    if c0.is_inside?(r) or c1.is_inside?(r) or c2.is_inside?(r) or
    c3.is_inside?(r)
        return true
    end
    if r.c0.is_inside?(self) or r.c1.is_inside?(self) or r.c2.is_inside?(self) or
      rc3.is_inside?(self)
        return true
    end
    return false
  end
 
  # ===================================================================
 
  def to_s(style=1)
    case style
    when 1
      "(#{x}, #{y}, #{width}, #{height})"
    when 2
      "( #{origin} , #{size} )"
    when 4
      "(#{min_x}, #{min_y}, #{max_x}, #{max_y})"
    end
  end
 
  def to_a
    return [x, y, w, h]
  end
end

#--------------------------------------------------------------------------
# * Array
#--------------------------------------------------------------------------

class Array
  def to_point
    Point.new(self[0], self[1])
  end
 
  def to_size
    Size.new(self[0], self[1])
  end
 
  def to_rect
    case self.size
      when 1 then Rect.new(self[0])
      when 2 then Rect.new(self[0], self[1])
      when 4 then Rect.new(self[0], self[1], self[2], self[3])
    end
  end
end
avatar
Wecoc
Administrador
Administrador



Créditos 12297

Gracias : 648

Volver arriba Ir abajo

Re: [RMXP/VX] [Herramienta de Scripter] Rect +

Mensaje por Eron el 2013-10-11, 07:30

¡Así me gusta Wecoc! =DD
Sí, atarear a otros es uno de mis pasatiempos preferidos x'D

Oye Wecoc, estaba pensando...
¿Y si hacemos que Window, Bitmap y ésas cosas soporten Point y Size y algunos de éstos métodos, y luego juntamos toda ésta munión de "+" y "AddOn" que hemos ido sacando en un mismo proyecto? Sin el ERON module que eso que hice ahí es un poco especial, pero algunos de los métodos más globales usados allí sí podrían ponerse también x'DD No sé, ya ni recuerdo lo que hice ahí exactamente.

Digo yo, así lo tendríamos más bien organizado.
avatar
Eron
Principiante
Principiante

0/3

Créditos 3599

Gracias : 60

Volver arriba Ir abajo

Re: [RMXP/VX] [Herramienta de Scripter] Rect +

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.