Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Help with matrices and circles

I need some help with matrix and circles...

Imagine that I have this matrix:
Code:
    matrix = Table.new(8, 8)
    for x in 0...matrix.xsize
      for y in 0...matrix.ysize
        matrix[x, y] = 0
      end
    end
Which looks like this:
Code:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

Now I need a method to draw a circle from center (x, y) with radious r. For example, a circle with
radious 2 from point (3, 3) will result in this:
Code:
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 1 1 1 0 0 0
0 1 1 1 1 1 0 0
0 0 1 1 1 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

Can someone help me?  :crazy:
 
Method & Class Library has some stuff for drawing circles and lines 'n stuff for the Bitmap class (so, if you're using it in a Window you'll have to do self.contents.draw_circle(*args))

Code:
#============================================================================== 
# ** RGSS.Bitmap.draw
#------------------------------------------------------------------------------
# Description:
# ------------
# Methods created for the Bitmap class that handle general drawing functions.
# Functions include drawing parts of bitmaps and drawing stretched bitmaps.
#  
# Method List:
# ------------
# Bitmap.default_blur_settings=
# Bitmap.default_blur_settings
# Bitmap.default_anim_sprite_settings=
# Bitmap.default_anim_sprite_settings
# blur_settings=
# blur_settings
# anim_sprite_settings=
# anim_sprite_settings
# draw_char_bar
# draw_line
# draw_box
# draw_circle
# draw_ellipse
# draw_polygon
# draw_gradient_polygon
# draw_anim_sprite
# draw_sprite
# draw_equipment
# crop_blt
# fit_blt
# full_blt
# full_fill
# scale_blt
# shade_section
# shade_gradient_section
#
# Modified Methods:
# -----------------
# initialize
#==============================================================================

MACL::Loaded << 'RGSS.Bitmap.draw'

#==============================================================================
# ** Bitmap
#==============================================================================

class Bitmap
  #--------------------------------------------------------------------------
  # * Class Variable Declaration
  #--------------------------------------------------------------------------
  class_accessor :default_blur_settings
  class_accessor :default_anim_sprite_settings
  #--------------------------------------------------------------------------
  # * Class Variable Declaration
  #--------------------------------------------------------------------------
  Bitmap.default_blur_settings        = Blur_Settings
  Bitmap.default_anim_sprite_settings = Anim_Sprite_Settings
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :blur_settings
  attr_accessor :anim_sprite_settings
  #--------------------------------------------------------------------------
  # * Alias Method
  #--------------------------------------------------------------------------
  alias_method :macl_bitmapdraw_init, :initialize
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(*args)
    # Set draw settings
    @blur_settings        = Bitmap.default_blur_settings
    @anim_sprite_settings = Bitmap.default_anim_sprite_settings
    # Original Initialization
    macl_bitmapdraw_init(*args)
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Char Bar
  #   Info      : Draws a Character Bar
  #   Author    : Trickster
  #   Call Info : Integer X, Y - Defines Position
  #               Integer Min, Max - Defines How filled the bar is
  #               Integer Width and height - Defines Dimensions
  #               String Start Content and Finish
  #-------------------------------------------------------------------------
  def draw_char_bar(x, y, min = 1, max = 1, width = nil, height = 32, start = '[',
    content = '¦', finish = ']', color = Color.new(255, 255, 255))
    # Get Width if width is nil
    width = text_size(start + (content * max) + finish).width if width == nil
    # save color
    saved = font.color
    # Set color
    self.font.color = color
    # Get Bar Text
    bar_text = start + content * min.to_i
    # Draw Bar Text
    draw_text(x, y, width, height, bar_text)
    # Draw Finish
    draw_text(x, y, width, height, finish, 2)
    # Restore Color
    self.font.color = saved
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Line
  #   Info      : Draws a line from x1,y1 to x2,y2
  #   Author    : Caesar (Rewrote By Trickster)
  #   Call Info : Integer x1, y1, x2, y2 - Points of the line
  #               Integer width - Thickness of the line
  #               Color color - Color of the line
  #   Comments  : uses the Digital Differential Analyzer Algorithm
  #-------------------------------------------------------------------------
  def draw_line(x1, y1, x2, y2, width = 1, color = Color.new(255, 255, 255))
    # Return if width is less than or 0
    return if width <= 0
    # Reverse all parameters sent if 2 x is less than the first x
    x1, x2, y1, y2 = x2, x1, y2, y1 if x2 < x1    
    # Get S (1/2 width)
    s = width / 2.0
    # If X Coordinates are equal
    if x1 == x2
      # Draw Vertical line
      fill_rect(x1 - s, [y1, y2].min, width, (y2 - y1).abs, color) 
    # If Y Coordinates are equal
    elsif y1 == y2
      # Draw Horizontal line
      fill_rect(x1, y1 - s, x2 - x1, width, color) 
    end
    # Get Length
    length = x2 - x1 < (y2 - y1).abs ? (y2 - y1).abs : x2 - x1
    # Get Increments
    x_increment, y_increment = (x2 - x1) / length.to_f, (y2 - y1) / length.to_f
    # Get Current X and Y
    x, y = x1, y1
    # While Current X is less than end X
    while x < x2
      # Draw Box of width width and width height 
      fill_rect(x-s, y-s, width, width, color)
      # Increment X and Y
      x += x_increment
      y += y_increment
    end
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Box
  #   Info      : Draws a Box
  #   Author    : Trickster
  #   Call Info : Two to Four Arguments Rect Outer Rectangle to Draw Box
  #               Color color color to draw the box in
  #-------------------------------------------------------------------------
  def draw_box(outer, color, width = 1, height = 1)
    fill_rect(outer, color)
    inner = Rect.new(outer.x + width, outer.y + height, outer.width - width * 2, 
    outer.height - height * 2)
    fill_rect(inner, Color.new(0, 0, 0, 0))
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Circle
  #   Info      : Draws A Circle
  #   Author    : SephirothSpawn
  #   Call Info : Integer X and Y Define Position Center Pt of Circle
  #               Integer Radius Radius of the Circle to Draw
  #               Color color Color of the circle to draw
  #-------------------------------------------------------------------------
  def draw_circle(x, y, radius, color = Color.new(255, 255, 255, 255))
    # Starts From Left
    for i in (x - radius)..(x + radius)
      # Finds Distance From Center
      sa = (x - i).abs
      # Finds X Position
      x_ = i < x ? x - sa : i == x ? x : x + sa
      # Finds Top Vertical Portion
      y_ = Integer((radius ** 2 - sa ** 2) ** 0.5)
      # Draws Vertical Bar
      self.fill_rect(x_, y - y_, 1, y_ * 2, color)
    end
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Ellipse
  #   Info      : Draws a Ellispse
  #   Author    : SephirothSpawn
  #   Call Info : Four or Five Arguments
  #               Four Arguments: x, y, a, b
  #                 x the center position of circle
  #                 y the center position of circle
  #                 a the distance from center to right side
  #                 b the distance from center to top side
  #               Five Arguments: (as above) + color
  #                 color the color of the circle drawn (defaults to white)
  #-------------------------------------------------------------------------
  def draw_ellipse(x, y, a, b, color = Color.new(255, 255, 255))
    # Converts Each Argument to Float
    x, y, a, b = x.to_f, y.to_f, a.to_f, b.to_f
    # Gets Square of a and b values
    a2, b2 = a * a, b * b
    # If a is smaller or equal to b
    if a <= b
      # Draws Center Line
      self.fill_rect(x, y - b, 1, b * 2, color)
      # Pass from center to right side
      for i in 1..a
        # Gets Y Distance
        y_ = Integer(Math.sqrt(b2 * (1 - (i ** 2) / a2)))
        # Draws Lines on Each Side
        self.fill_rect(x - i, y - y_, 1, y_ * 2, color)
        self.fill_rect(x + i, y - y_, 1, y_ * 2, color)
      end
    # If b is smaller than b
    else
      # Draws Center Line
      self.fill_rect(x - a, y, a * 2, 1, color)
      # Pass from center to right side
      for i in 1..b
        # Gets X Distance
        x_ = Integer(Math.sqrt(a2 * (1 - i ** 2 / b2)))
        # Draws Lines on Top & Bottom
        self.fill_rect(x - x_, y - i, x_ * 2, 1, color)
        self.fill_rect(x - x_, y + i, x_ * 2, 1, color)
      end
    end
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Polygon
  #   Info      : Draws a Polygon 
  #   Author    : Caesar (Rewrote By Trickster)
  #   Call Info : Array vertices - Points of the polygon
  #               Integer width - Thickness of the lines
  #               Color color - color to draw it in
  #               Boolean filled - false outline true filled
  #               Integer step - fill steps
  #   Comments  : Example of vertices setup [[30, 80], [80, 80], [30, 60]]
  #-------------------------------------------------------------------------
  def draw_polygon(vertices, stroke = 1, color = Color.new(255, 255, 255),
    filled = false, step = 1)
    # Return if no width or not enough points
    return if stroke <= 0 or vertices.size <= 2
    # Get Count
    count = vertices.size
    # Get Points
    x1, y1, x2, y2 = vertices[-1] + vertices[0]
    # Draw Line
    draw_line(x1, y1, x2, y2, stroke, color)
    # Shade if filled
    shade_section(cx, cy, x1, y1, x2, y2, stroke, step, color) if filled
    # Run Through with next
    vertices.each_with_next do |start, point|
      # Get Points
      x1, y1, x2, y2 = start + point
      # Draw Line
      draw_line(x1, y1, x2, y2, stroke, color)
      # Shade if filled
      shade_section(cx, cy, x1, y1, x2, y2, stroke, step, color) if filled
    end
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Gradient Polygon
  #   Info      : Draws a Gradient Polygon  (Filled)
  #   Author    : Caesar (Rewrote By Trickster)
  #   Call Info : Array vertices - Points of the polygon
  #               Integer width - Thickness of the lines
  #               Color color - color to draw it in
  #               Boolean filled - false outline true filled
  #               Integer step - fill steps
  #   Comments  : Example of vertices setup [[30, 80], [80, 80], [30, 60]]
  #-------------------------------------------------------------------------
  def draw_gradient_polygon(cx, cy, vertices, stroke = 1, 
    start_color = Color.new(255, 255, 255), end_color = Color.new(0, 0, 0),
    step = 1)
    # Return if no width or not enough points
    return if stroke <= 0 or vertices.size <= 2
    # Get Count
    count = vertices.size
    # Get Points
    x1, y1, x2, y2 = vertices[-1] + vertices[0]
    # Draw Line
    draw_line(x1, y1, x2, y2, stroke, end_color)
    shade_gradient_section(cx, cy, x1, y1, x2, y2, 2, 1, start_color, end_color)
    # Run Through with next
    vertices.each_with_next do |start, point|
      # Get Points
      x1, y1, x2, y2 = start + point
      # Draw Line
      draw_line(x1, y1, x2, y2, stroke, end_color)
      shade_gradient_section(cx, cy, x1, y1, x2, y2, 1, 0.4, start_color, end_color)
    end
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Animated Sprite
  #   Info      : Draws an Animated Sprite
  #   Author    : SephirothSpawn
  #   Call Info : Six to Seven Arguments Integer x and y Defines Position
  #               Integer W and H Defines Dimensions
  #               String name Character Set Graphic
  #               Integer hue sets hue displacement
  #               Integer stance pose for character
  #-------------------------------------------------------------------------
  def draw_anim_sprite(x, y, w, h, name, hue, stance = 0)
    # Gets Frame
    frame = (Graphics.frame_count / @anim_sprite_settings['f']) % 
            @anim_sprite_settings['w']
    # Draw Sprite
    draw_sprite(x, y, w, h, name, hue, stance, frame)
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Sprite
  #   Info      : Draws an Animated Sprite
  #   Author    : SephirothSpawn
  #   Call Info : Six to Seven Arguments Integer x and y Defines Position
  #               Integer W and H Defines Dimensions
  #               String name Character Set Graphic
  #               Integer hue sets hue displacement
  #               Integer stance pose for character
  #               Integer frame frame of pose to show
  #-------------------------------------------------------------------------
  def draw_sprite(x, y, w, h, name, hue, stance = 0, frame = 0)
    # Gets Bitmap
    bitmap = RPG::Cache.character(name, hue)
    # Bitmap Division
    cw = bitmap.width / @anim_sprite_settings['w']
    ch = bitmap.height / @anim_sprite_settings['h']
    # Gets Animation Offsets
    x_off, y_off = cw * frame, ch * stance
    # Clears Area
    self.fill_rect(Rect.new(x, y, w, h), Color.new(0, 0, 0, 0))
    # Draws Bitmap
    self.scale_blt(Rect.new(x, y, w, h), bitmap, 
      Rect.new(x_off, y_off, cw, ch))
  end
  #-------------------------------------------------------------------------
  # * Name      : Draw Equip
  #   Info      : Draws Item or Equipment icon and name
  #   Author    : SephirothSpawn
  #   Call Info : Three to Eight Arguments
  #               Item - RPG::Item, RPG::Weapon or RPG::Armor
  #               X - Position Icon & Text Being drawn
  #               Y - Position Icon & Test Being drawn
  #               W - Width for Icon & Text to be drawn in
  #               H - Height for Icon & Text to be drawn in (24 min)
  #               A - Alignment of text
  #               T - Type of icon to be used when nil item (See MACL Setup)
  #               Txt - Text when Item is nil
  #-------------------------------------------------------------------------
  def draw_equipment(i, x, y, w = 212, h = 32, a = 0, t = 0, txt = 'Nothing')
    # If Nil Item
    if i.nil?
      # Gets Unequipped Bitmap & Font Color
      bitmap = RPG::Cache.icon(Draw_Equipment_Icon_Settings[t])
      c = Color.disabled
    # If Item Exist
    else
      # Gets Bitmap, Font Color & Item Name
      bitmap = RPG::Cache.icon(i.icon_name)
      c, txt = Color.normal, i.name
    end
    # Sets Font Color, Draws Icon & Text
    old_color = self.font.color.dup
    self.blt(x + 4, y + (h - 24) / 2, bitmap, bitmap.rect, c.alpha)
    self.font.color = c
    self.draw_text(x + 32, y, w - 28, h, txt, a)
    self.font.color = old_color
  end
  #-------------------------------------------------------------------------
  # * Name      : Crop BLT
  #   Info      : Crops to Width and Height, if needed
  #   Author    : Trickster
  #   Call Info : Five - Eight Arguments, Integer X and Y Define Position
  #               Integer Width and Height Defines Dimensions
  #               Bitmap bitmap bitmap to transfer
  #               Integer dir, part to crop
  #               Integer align, alignment (0:left, 1:center, 2:right)
  #               Integer opacity, opacity
  #-------------------------------------------------------------------------
  def crop_blt(x, y, width, height, bitmap, dir = 1, align = 1, opacity = 255)
    # Get Width and Height
    w, h = bitmap.width, bitmap.height
    # If Can Fit
    if w < width and h < height
      # Branch By alignment
      case align
      when 1
        # Add To Make it in the center
        x += (width - w) / 2
      when 2
        # Add to Make it in the right
        x += width - w
      end
      # Draw Bitmap
      full_blt(x, y, bitmap, opacity)
      # Return
      return
    end
    # Get I and J (Position)
    i, j = dir % 3, dir / 3
    # Initialize Crop X and Crop Y (Left Top Align)
    crop_x, crop_y = 0, 0
    # Branch by Horizontal Position
    case i
    when 1
      # Center Align
      crop_x = (w - width) / 2
    when 2
      # Right Align
      crop_x = w - width
    end
    # Branch by Vertical Position
    case j
    when 1
      # Center Align
      crop_y = (h - height) / 2
    when 2
      # Bottom Align
      crop_y = h - height
    end
    # Draw Bitmap Cropped
    blt(x, y, bitmap, Rect.new(crop_x, crop_y, width, height), opacity)
  end
  #-------------------------------------------------------------------------
  # * Name      : Fit BLT
  #   Info      : Zooms to Width and Height, if needed
  #   Author    : Trickster
  #   Call Info : Five-Seven Arguments, Integer X and Y Define Position
  #               Integer Width and Height Defines Dimensions
  #               Bitmap bitmap bitmap to transfer
  #               Integer opacity, opacity
  #               Integer Align, Alignment
  #-------------------------------------------------------------------------
  def fit_blt(x, y, width, height, bitmap, opacity = 255, align = 1)
    # Get Width and Height
    w, h = bitmap.width, bitmap.height
    # If Width or Height is Greater
    if w > width or h > height
      # Get Conversion
      conversion = w / h.to_f
      # if Conversion is smaller than or 1
      if conversion <= 1
        # Get Zoom X and Y
        zoom_x, zoom_y = width * conversion, height
      else
        # Get Zoom X and Y
        zoom_x, zoom_y = width, height / conversion
      end
      # Branch By Align
      case align
      when 1
        # Add To Make it in the center
        x += (width - zoom_x) / 2
      when 2
        # Add to Make it in the right
        x += width - zoom_x
      end
      # Get Destination Rect
      dest_rect = Rect.new(x, y, zoom_x, zoom_y)
      # Stretch to Fit
      stretch_blt(dest_rect, bitmap, bitmap.rect, opacity)
    else
      # Branch By alignment
      case align
      when 1
        # Add To Make it in the center
        x += (width - w) / 2
      when 2
        # Add to Make it in the right
        x += width - w
      end
      # Draw Bitmap
      full_blt(x, y, bitmap, opacity)
    end
  end
  #-------------------------------------------------------------------------
  #   Name      : Full Block Transfer
  #   Info      : Draws a Bitmap
  #   Author    : Trickster
  #   Call Info : Three or Four Arguments
  #               Integer X and Y define position
  #               Bitmap bitmap is the bitmap to draw
  #               Integer Opacity is the transparency (defaults to 255)
  #   Comment   : Lazy method for people who don't want to type bitmap.rect
  #-------------------------------------------------------------------------
  def full_blt(x, y, bitmap, opacity = 255)
    blt(x, y, bitmap, bitmap.rect, opacity)
  end
  #-------------------------------------------------------------------------
  #   Name      : Full Fill
  #   Info      : Fills Whole Bitmap
  #   Author    : Trickster
  #   Call Info : One Argument, Color color the color to be filled
  #   Comment   : Lazy method for people who don't want to type bitmap.rect
  #-------------------------------------------------------------------------
  def full_fill(color)
    fill_rect(rect, color)
  end
  #-------------------------------------------------------------------------
  # * Name      : Scale BLT
  #   Info      : Scales Bitmap to fit Rectangle
  #   Author    : SephirothSpawn
  #   Call Info : Two to Four Arguments
  #               Rect Dest_Rect - Destination Rectangle
  #               Bitmap Src_Bitmap - Source Bitmap
  #               Rect Src_Rect - Source Rectangle for Bitmap
  #               Integer Opacity - Opacity
  #-------------------------------------------------------------------------
  def scale_blt(dest_rect, src_bitmap, src_rect = src_bitmap.rect, o = 255)
    w, h = src_rect.width, src_rect.height
    scale = [w / dest_rect.width.to_f, h / dest_rect.height.to_f].max
    ow, oh = (w / scale).to_i, (h / scale).to_i
    ox, oy = (dest_rect.width - ow) / 2, (dest_rect.height - oh) / 2
    stretch_blt(Rect.new(ox + dest_rect.x, oy + dest_rect.y, ow, oh), 
      src_bitmap, src_rect, o)
  end
  #-------------------------------------------------------------------------
  # * Name      : Shade Section
  #   Info      : Shades a section from (cx,cy), (x1,y1), (x2,y2)
  #   Author    : Trickster
  #   Call Info : Six to Nine Arguments
  #               Integer cx, cy, x1, y1, x2, y2 - Points
  #               Integer Thick - Line Thickness
  #               Integer Step - how many lines to draw (lower = higher accuracy)
  #               Color color - color to shade in
  #-------------------------------------------------------------------------
  def shade_section(cx, cy, x1, y1, x2, y2, thick = 1, step = 1, 
      color = Color.new(255, 255, 255))
    # Reverse all parameters sent if 2 x is less than the first x
    x1, x2, y1, y2 = x2, x1, y2, y1 if x2 < x1    
    # Get Slope
    slope = (y2 - y1).to_f / (x2 - x1)
    # If Slope is infinite
    if slope.infinite?
      y1.step(y2, step) {|y| draw_line(cx, cy, x1, y, thick, color)}
    # If Slope is zero
    elsif slope.zero?
      x1.step(x2, step) {|x| draw_line(cx, cy, x, y1, thick, color)}
    elsif not slope.nan?
      # Get Y intercept
      yint = y1 - slope * x1
      x1.step(x2, step) {|x| draw_line(cx, cy, x, slope * x + yint, thick, color)}
    end
  end
  #-------------------------------------------------------------------------
  # * Name      : Shade Gradient Section
  #   Info      : Shades a section from (cx,cy), (x1,y1), (x2,y2) w/ gradient
  #   Author    : Trickster
  #   Call Info : Six to Ten Arguments
  #               Integer cx, cy, x1, y1, x2, y2 - Points
  #               Integer Thick - Line Thickness
  #               Integer Step - how many lines to draw (lower = higher accuracy)
  #               Color start_color, end_color - Start and end colors
  #-------------------------------------------------------------------------
  def shade_gradient_section(cx, cy, x1, y1, x2, y2, thick = 1, step = 1,
    start_color = Color.new(0, 0, 0), end_color = start_color)
    # Reverse all parameters sent if 2 x is less than the first x
    x1, x2, y1, y2 = x2, x1, y2, y1 if x2 < x1    
    # Get Slope
    slope = (y2 - y1).to_f / (x2 - x1)
    # If Slope is infinite
    if slope.infinite?
      y1.step(y2, step) {|y| draw_gradient_line(cx, cy, x1, y, thick, start_color, end_color)}
    # If Slope is zero
    elsif slope.zero?
      x1.step(x2, step) {|x| draw_gradient_line(cx, cy, x, y1, thick, start_color, end_color)}
    elsif not slope.nan?
      # Get Y intercept
      yint = y1 - slope * x1
      x1.step(x2, step) {|x| draw_gradient_line(cx, cy, x, slope * x + yint, thick, start_color, end_color)}
    end
  end
end

Good luck with it :thumb:
 
@Kain: I don't think that's what he wanted :tongue:

This should do it.

Code:
x = 4
y = 4
r = 2

for i in -r..r
  k = (Math.sqrt((r*r)-(i*i))).to_i
  for j in -k..k
    matrix[x + i, y + j] = 1
  end
end

Hope it helps  :thumb:
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top