Class: Vamp::Graphic::Context

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/vamp/graphic/context.rb

Overview

Graphic Context

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dotter) ⇒ Context

Returns a new instance of Context.



17
18
19
# File 'lib/vamp/graphic/context.rb', line 17

def initialize(dotter)
  @dotter = dotter
end

Instance Attribute Details

#dotterObject (readonly)

can set a dot within [0, width] [0, height



15
16
17
# File 'lib/vamp/graphic/context.rb', line 15

def dotter
  @dotter
end

Instance Method Details

#draw_line_direct(x0, y0, x1, y1) ⇒ Object

Bresenham’s line algorithm



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/vamp/graphic/context.rb', line 88

def draw_line_direct(x0, y0, x1, y1)
  dx = (x1 - x0).abs
  sx = x0 < x1 ? 1 : -1
  dy = -(y1 - y0).abs
  sy = y0 < y1 ? 1 : -1
  err = dx + dy
  while true
    dot(x0, y0)
    break if x0 == x1 && y0 == y1
    e2 = 2 * err
    if e2 > dy
      err += dy
      x0 += sx
    end
    if e2 < dx
      err += dx
      y0 += sy
    end
  end
  self
end

#line(x0, y0, x1, y1) ⇒ Object

Cohen–Sutherland clipping algorithm clips a line from P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with diagonal from (xmin, ymin) to (xmax, ymax).



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/vamp/graphic/context.rb', line 24

def line(x0, y0, x1, y1)
  xmin = 0.0
  ymin = 0.0
  xmax = width - 1.0
  ymax = height - 1.0

  # compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
  outcode0 = compute_out_code(x0, y0)
  outcode1 = compute_out_code(x1, y1)

  accept = false

  while true
    if 0 == (outcode0 | outcode1)     # Bitwise OR is 0. Trivially accept and get out of loop
      accept = true
      break
    elsif 0 != (outcode0 & outcode1)  # Bitwise AND is not 0. Trivially reject and get out of loop
      break
    else
      # failed both tests, so calculate the line segment to clip
      # from an outside point to an intersection with clip edge

      # At least one endpoint is outside the clip rectangle; pick it.
      outcodeOut = outcode0 != 0 ? outcode0 : outcode1


      # Now find the intersection point;
      # use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
      if 0 != (outcodeOut & TOP)            # point is above the clip rectangle
        x = x0.to_f + (x1 - x0) * (ymax - y0) / (y1 - y0)
        y = ymax
      elsif (0 != outcodeOut & BOTTOM)      # point is below the clip rectangle
        x = x0.to_f + (x1 - x0) * (ymin - y0) / (y1 - y0)
        y = ymin
      elsif (0 != outcodeOut & RIGHT)       # point is to the right of clip rectangle
        y = y0.to_f + (y1 - y0) * (xmax - x0) / (x1 - x0)
        x = xmax
      elsif (0 != outcodeOut & LEFT)        # point is to the left of clip rectangle
        y = y0.to_f + (y1 - y0) * (xmin - x0) / (x1 - x0)
        x = xmin
      end

      # Now we move outside point to intersection point to clip
      # and get ready for next pass.
      if outcodeOut == outcode0
        x0 = x
        y0 = y
        outcode0 = compute_out_code(x0, y0)
      else
        x1 = x
        y1 = y
        outcode1 = compute_out_code(x1, y1)
      end
    end
  end
  if accept
    draw_line_direct (x0 + 0.5).to_i, (y0 + 0.5).to_i, (x1 + 0.5).to_i, (y1 + 0.5).to_i
  end
  self
end