lib/rubysketch/processing.rb in rubysketch-0.3.15 vs lib/rubysketch/processing.rb in rubysketch-0.3.16

- old
+ new

@@ -32,11 +32,11 @@ # @param y [Numeric] y of vector # @param z [Numeric] z of vector # @param v [Vector] vector object to copy # @param a [Array] array like [x, y, z] # - def initialize (x = 0, y = 0, z = 0, context: nil) + def initialize(x = 0, y = 0, z = 0, context: nil) @point = case x when Rays::Point then x.dup when Vector then x.getInternal__.dup when Array then Rays::Point.new x[0] || 0, x[1] || 0, x[2] || 0 else Rays::Point.new x || 0, y || 0, z || 0 @@ -44,11 +44,11 @@ @context = context || Context.context__ end # Initializer for dup or clone # - def initialize_copy (o) + def initialize_copy(o) @point = o.getInternal__.dup end # Copy vector object # @@ -70,60 +70,60 @@ # @param v [Vector] vector object to copy # @param a [Array] array with x, y, z # # @return [nil] nil # - def set (*args) - initialize *args + def set(*args) + initialize(*args) self end # Gets x value. # # @return [Numeric] x value of vector # - def x () + def x() @point.x end # Gets y value. # # @return [Numeric] y value of vector # - def y () + def y() @point.y end # Gets z value. # # @return [Numeric] z value of vector # - def z () + def z() @point.z end # Sets x value. # # @return [Numeric] x value of vector # - def x= (x) + def x=(x) @point.x = x end # Sets y value. # # @return [Numeric] y value of vector # - def y= (y) + def y=(y) @point.y = y end # Sets z value. # # @return [Numeric] z value of vector # - def z= (z) + def z=(z) @point.z = z end # Returns the interpolated vector between 2 vectors. # @@ -137,12 +137,12 @@ # @param z [Numeric] z of vector to interpolate # @param amount [Numeric] amount to interpolate # # @return [Vector] interporated vector # - def lerp (*args, amount) - v = toVector__ *args + def lerp(*args, amount) + v = toVector__(*args) self.x = x + (v.x - x) * amount self.y = y + (v.y - y) * amount self.z = z + (v.z - z) * amount self end @@ -153,19 +153,19 @@ # @param v2 [Vector] vector to interpolate # @param amount [Numeric] amount to interpolate # # @return [Vector] interporated vector # - def self.lerp (v1, v2, amount) + def self.lerp(v1, v2, amount) v1.dup.lerp v2, amount end # Returns x, y, z as an array # # @return [Array] array of x, y, z # - def array () + def array() @point.to_a 3 end # Adds a vector. # @@ -178,11 +178,11 @@ # @param y [Vector] y of vector to add # @param z [Vector] z of vector to add # # @return [Vector] added vector # - def add (*args) + def add(*args) @point += toVector__(*args).getInternal__ self end # Subtracts a vector. @@ -196,74 +196,74 @@ # @param y [Vector] y of vector to subtract # @param z [Vector] z of vector to subtract # # @return [Vector] subtracted vector # - def sub (*args) + def sub(*args) @point -= toVector__(*args).getInternal__ self end # Multiplies a vector by scalar. # # @param num [Numeric] number to multiply the vector # # @return [Vector] multiplied vector # - def mult (num) + def mult(num) @point *= num self end # Divides a vector by scalar. # # @param num [Numeric] number to divide the vector # # @return [Vector] divided vector # - def div (num) + def div(num) @point /= num self end # Adds a vector. # # @param v [Vector] vector to add # # @return [Vector] added vector # - def + (v) + def +(v) dup.add v end # Subtracts a vector. # # @param v [Vector] vector to subtract # # @return [Vector] subtracted vector # - def - (v) + def -(v) dup.sub v end # Multiplies a vector by scalar. # # @param num [Numeric] number to multiply the vector # # @return [Vector] multiplied vector # - def * (num) + def *(num) dup.mult num end # Divides a vector by scalar. # # @param num [Numeric] number to divide the vector # # @return [Vector] divided vector # - def / (num) + def /(num) dup.div num end # Adds 2 vectors. # @@ -274,11 +274,11 @@ # @param v2 [Vector] another vector # @param target [Vector] vector to store added vector # # @return [Vector] added vector # - def self.add (v1, v2, target = nil) + def self.add(v1, v2, target = nil) v = v1 + v2 target.set v if self === target v end @@ -291,11 +291,11 @@ # @param v2 [Vector] another vector # @param target [Vector] vector to store subtracted vector # # @return [Vector] subtracted vector # - def self.sub (v1, v2, target = nil) + def self.sub(v1, v2, target = nil) v = v1 - v2 target.set v if self === target v end @@ -308,11 +308,11 @@ # @param num [Numeric] number to multiply the vector # @param target [Vector] vector to store multiplied vector # # @return [Vector] multiplied vector # - def self.mult (v1, num, target = nil) + def self.mult(v1, num, target = nil) v = v1 * num target.set v if self === target v end @@ -325,29 +325,29 @@ # @param num [Numeric] number to divide the vector # @param target [Vector] vector to store divided vector # # @return [Vector] divided vector # - def self.div (v1, num, target = nil) + def self.div(v1, num, target = nil) v = v1 / num target.set v if self === target v end # Returns the length of the vector. # # @return [Numeric] length # - def mag () + def mag() @point.length end # Returns squared length of the vector. # # @return [Numeric] squared length # - def magSq () + def magSq() Rays::Point::dot(@point, @point) end # Changes the length of the vector. # @@ -357,53 +357,53 @@ # @param len [Numeric] length of new vector # @param target [Vector] vector to store new vector # # @return [Vector] vector with new length # - def setMag (target = nil, len) + def setMag(target = nil, len) (target || self).set @point.normal * len end # Changes the length of the vector to 1.0. # # @param target [Vector] vector to store the normalized vector # # @return [Vector] normalized vector # - def normalize (target = nil) + def normalize(target = nil) (target || self).set @point.normal end # Changes the length of the vector if it's length is greater than the max value. # # @param max [Numeric] max length # # @return [Vector] new vector # - def limit (max) + def limit(max) setMag max if magSq > max ** 2 self end # Returns the distance of 2 vectors. # # @param v [Vector] a vector # # @return [Numeric] the distance # - def dist (v) + def dist(v) (self - v).mag end # Returns the distance of 2 vectors. # # @param v1 [Vector] a vector # @param v2 [Vector] another vector # # @return [Numeric] the distance # - def self.dist (v1, v2) + def self.dist(v1, v2) v1.dist v2 end # Calculates the dot product of 2 vectors. # @@ -416,22 +416,22 @@ # @param y [Numeric] y of vector # @param z [Numeric] z of vector # # @return [Numeric] result of dot product # - def dot (*args) + def dot(*args) Rays::Point::dot getInternal__, toVector__(*args).getInternal__ end # Calculates the dot product of 2 vectors. # # @param v1 [Vector] a vector # @param v2 [Vector] another vector # # @return [Numeric] result of dot product # - def self.dot (v1, v2) + def self.dot(v1, v2) v1.dot v2 end # Calculates the cross product of 2 vectors. # @@ -444,11 +444,11 @@ # @param y [Numeric] y of vector # @param z [Numeric] z of vector # # @return [Numeric] result of cross product # - def cross (a, *rest) + def cross(a, *rest) target = self.class === rest.last ? rest.pop : nil v = self.class.new Rays::Point::cross getInternal__, toVector__(a, *rest).getInternal__ target.set v if self.class === target v end @@ -458,42 +458,42 @@ # @param v1 [Vector] a vector # @param v2 [Vector] another vector # # @return [Numeric] result of cross product # - def self.cross (v1, v2, target = nil) + def self.cross(v1, v2, target = nil) v1.cross v2, target end # Rotate the vector. # # @param angle [Numeric] the angle of rotation # # @return [Vector] rotated this object # - def rotate (angle) + def rotate(angle) angle = @context ? @context.toAngle__(angle) : angle * RAD2DEG__ @point.rotate! angle self end # Returns the angle of rotation for this vector. # # @return [Numeric] the angle in radians # - def heading () + def heading() Math.atan2 y, x end # Returns rotated new vector. # # @param angle [Numeric] the angle of rotation # @param target [Vector] vector to store new vector # # @return [Vector] rotated vector # - def self.fromAngle (angle, target = nil) + def self.fromAngle(angle, target = nil) v = self.new(1, 0, 0).rotate(angle) target.set v if target v end @@ -502,11 +502,11 @@ # @param v1 [Vector] a vector # @param v2 [Vector] another vector # # @return [Numeric] angle in radians # - def self.angleBetween (v1, v2) + def self.angleBetween(v1, v2) x1, y1, z1 = v1.array x2, y2, z2 = v2.array return 0 if (x1 == 0 && y1 == 0 && z1 == 0) || (x2 == 0 && y2 == 0 && z2 == 0) x = dot(v1, v2) / (v1.mag * v2.mag) @@ -519,11 +519,11 @@ # # @param target [Vector] a vector to store the new vector # # @return [Vector] a random vector # - def self.random2D (target = nil) + def self.random2D(target = nil) v = self.fromAngle rand 0.0...(Math::PI * 2) target.set v if target v end @@ -531,38 +531,38 @@ # # @param target [Vector] a vector to store the new vector # # @return [Vector] a random vector # - def self.random3D (target = nil) + def self.random3D(target = nil) angle = rand 0.0...(Math::PI * 2) - z = rand -1.0..1.0 + z = rand(-1.0..1.0) z2 = z ** 2 x = Math.sqrt(1.0 - z2) * Math.cos(angle) y = Math.sqrt(1.0 - z2) * Math.sin(angle) v = self.new x, y, z target.set v if target v end # @private - def inspect () + def inspect() "<##{self.class.name} #{x}, #{y}, #{z}>" end # @private - def <=> (o) + def <=>(o) @point <=> o.getInternal__ end # @private - protected def getInternal__ () + protected def getInternal__() @point end # @private - private def toVector__ (*args) + private def toVector__(*args) self.class === args.first ? args.first : self.class.new(*args) end end# Vector @@ -570,38 +570,38 @@ # Image object. # class Image # @private - def initialize (image) + def initialize(image) @image = image end # Gets width of image. # # @return [Numeric] width of image # - def width () + def width() @image.width end # Gets height of image. # # @return [Numeric] height of image # - def height () + def height() @image.height end # Resizes image. # # @param width [Numeric] width for resized image # @param height [Numeric] height for resized image # # @return [nil] nil # - def resize (width, height) + def resize(width, height) @image = Rays::Image.new(width, height).paint do |painter| painter.image @image, 0, 0, width, height end nil end @@ -621,27 +621,27 @@ # @param dw [Numrtic] width of destination region # @param dh [Numrtic] height of destination region # # @return [nil] nil # - def copy (img = nil, sx, sy, sw, sh, dx, dy, dw, dh) + def copy(img = nil, sx, sy, sw, sh, dx, dy, dw, dh) img ||= self @image.paint do |painter| painter.image img.getInternal__, sx, sy, sw, sh, dx, dy, dw, dh end end # Saves image to file. # # @param filename [String] file name to save image # - def save (filename) + def save(filename) @image.save filename end # @private - def getInternal__ () + def getInternal__() @image end end# Image @@ -649,11 +649,11 @@ # Font object. # class Font # @private - def initialize (font) + def initialize(font) @font = font end # Returns bounding box. # @@ -666,11 +666,11 @@ # @param y [Numeric] vertical position of bounding box # @param fontSize [Numeric] font size # # @return [TextBounds] bounding box for text # - def textBounds (str, x = 0, y = 0, fontSize = nil) + def textBounds(str, x = 0, y = 0, fontSize = nil) f = fontSize ? Rays::Font.new(@font.name, fontSize) : @font TextBounds.new x, y, x + f.width(str), y + f.height end end# Font @@ -695,11 +695,11 @@ # Height of bounding box # attr_reader :h # @private - def initialize (x, y, w, h) + def initialize(x, y, w, h) @x, @y, @w, @h = x, y, w, h end end# TextBounds @@ -715,15 +715,15 @@ # Vertical position of touch # attr_reader :y # @private - def initialize (x, y) + def initialize(x, y) @x, @y = x, y end - def id () + def id() raise NotImplementedError end end# Touch @@ -734,11 +734,11 @@ # Returns a list of available camera device names # # @return [Array] device name list # - def self.list () + def self.list() Rays::Camera.device_names end # Initialize camera object. # @@ -749,11 +749,11 @@ # # @param requestWidth [Integer] captured image width # @param requestHeight [Integer] captured image height # @param cameraName [String] camera device name # - def initialize (*args) + def initialize(*args) width, height, name = if args.empty? [-1, -1, nil] elsif args[0].kind_of?(String) [-1, -1, args[0]] @@ -767,61 +767,61 @@ # Start capturing. # # @return [nil] nil # - def start () + def start() raise "Failed to start capture" unless @camera.start nil end # Stop capturing. # # @return [nil] nil # - def stop () + def stop() @camera.stop nil end # Returns is the next captured image available? # # @return [Boolean] true means object has next frame # - def available () + def available() @camera.active? end # Reads next frame image # - def read () + def read() @camera.image end # Returns the width of captured image # # @return [Numeric] the width of captured image # - def width () + def width() @camera.image&.width || 0 end # Returns the height of captured image # # @return [Numeric] the height of captured image # - def height () + def height() @camera.image&.height || 0 end # @private - def getInternal__ () + def getInternal__() @camera.image || dummyImage__ end # @private - private def dummyImage__ () + private def dummyImage__() @dummy ||= Rays::Image.new 1, 1 end end# Capture @@ -850,54 +850,103 @@ # TAU = PI * 2 # RGB mode for colorMode(). # - RGB = :RGB + RGB = :rgb # HSB mode for colorMode(). # - HSB = :HSB + HSB = :hsb # Radian mode for angleMode(). # - RADIANS = :RADIANS + RADIANS = :radians # Degree mode for angleMode(). # - DEGREES = :DEGREES + DEGREES = :degrees # Mode for rectMode(), ellipseMode() and imageMode(). # - CORNER = :CORNER + CORNER = :corner # Mode for rectMode(), ellipseMode() and imageMode(). # - CORNERS = :CORNERS + CORNERS = :corners # Mode for rectMode(), ellipseMode(), imageMode() and textAlign(). # - CENTER = :CENTER + CENTER = :center # Mode for rectMode() and ellipseMode(). # - RADIUS = :RADIUS + RADIUS = :radius - # Mode for textAlign(). - LEFT = :LEFT + # Key codes. + ENTER = :enter + SPACE = :space + TAB = :tab + DELETE = :delete + BACKSPACE = :backspace + ESC = :escape + HOME = :home + #END = :end + PAGEUP = :pageup + PAGEDOWN = :pagedown + CLEAR = :clear + SHIFT = :shift + CONTROL = :control + ALT = :alt + WIN = :win + COMMAND = :command + OPTION = :option + FUNCTION = :function + CAPSLOCK = :capslock + SECTION = :section + HELP = :help + F1 = :f1 + F2 = :f2 + F3 = :f3 + F4 = :f4 + F5 = :f5 + F6 = :f6 + F7 = :f7 + F8 = :f8 + F9 = :f9 + F10 = :f10 + F11 = :f11 + F12 = :f12 + F13 = :f13 + F14 = :f14 + F15 = :f15 + F16 = :f16 + F17 = :f17 + F18 = :f18 + F19 = :f19 + F20 = :f20 + F21 = :f21 + F22 = :f22 + F23 = :f23 + F24 = :f24 + UP = :up + DOWN = :down - # Mode for textAlign(). - RIGHT = :RIGHT + # Key code or Mode for textAlign(). + LEFT = :left + # Key code or Mode for textAlign(). + RIGHT = :right + # Mode for textAlign(). - TOP = :TOP + TOP = :top # Mode for textAlign(). - BOTTOM = :BOTTOM + BOTTOM = :bottom # Mode for textAlign(). - BASELINE = :BASELINE + BASELINE = :baseline # Mode for strokeCap(). # BUTT = :butt @@ -911,11 +960,11 @@ # Mode for strokeCap() and strokeJoin(). # SQUARE = :square - def init__ (image, painter) + def init__(image, painter) @drawing__ = false @hsbColor__ = false @colorMaxes__ = [1.0] * 4 @angleScale__ = 1.0 @rectMode__ = nil @@ -935,33 +984,34 @@ imageMode CORNER textAlign LEFT fill 255 stroke 0 + strokeWeight 1 end - def updateCanvas__ (image, painter) + def updateCanvas__(image, painter) @image__, @painter__ = image, painter end # @private - def beginDraw__ () + def beginDraw__() @matrixStack__.clear @styleStack__.clear @drawing__ = true end # @private - def endDraw__ () + def endDraw__() @drawing__ = false end - def width () + def width() @image__.width end - def height () + def height() @image__.height end # Sets color mode and max color values. # @@ -977,12 +1027,12 @@ # @param max3 [Numeric] max value for blue or brightness # @param maxA [Numeric] max value for alpha # # @return [nil] nil # - def colorMode (mode, *maxes) - mode = mode.upcase.to_sym + def colorMode(mode, *maxes) + mode = mode.downcase.to_sym raise ArgumentError, "invalid color mode: #{mode}" unless [RGB, HSB].include?(mode) raise ArgumentError unless [0, 1, 3, 4].include?(maxes.size) @hsbColor__ = mode == HSB case maxes.size @@ -991,11 +1041,11 @@ end nil end # @private - private def toRGBA__ (*args) + private def toRGBA__(*args) a, b, c, d = args return parseColor__(a, b || alphaMax__) if a.kind_of?(String) rgba = case args.size when 1, 2 then [a, a, a, b || alphaMax__] @@ -1006,40 +1056,40 @@ color = @hsbColor__ ? Rays::Color.hsv(*rgba) : Rays::Color.new(*rgba) color.to_a end # @private - private def parseColor__ (str, alpha) - result = str.match /^\s*##{'([0-9a-f]{2})' * 3}\s*$/i + private def parseColor__(str, alpha) + result = str.match(/^\s*##{'([0-9a-f]{2})' * 3}\s*$/i) raise ArgumentError, "invalid color code: '#{str}'" unless result rgb = result[1..3].map.with_index {|hex, i| hex.to_i(16) / 255.0} return *rgb, (alpha / alphaMax__) end # @private - private def alphaMax__ () + private def alphaMax__() @colorMaxes__[3] end # Sets angle mode. # # @param mode [RADIANS, DEGREES] RADIANS or DEGREES # # @return [nil] nil # - def angleMode (mode) - @angleScale__ = case mode.upcase.to_sym + def angleMode(mode) + @angleScale__ = case mode.downcase.to_sym when RADIANS then RAD2DEG__ when DEGREES then 1.0 else raise ArgumentError, "invalid angle mode: #{mode}" end nil end # @private - def toAngle__ (angle) + def toAngle__(angle) angle * @angleScale__ end # Sets rect mode. Default is CORNER. # @@ -1050,11 +1100,11 @@ # # @param mode [CORNER, CORNERS, CENTER, RADIUS] # # @return [nil] nil # - def rectMode (mode) + def rectMode(mode) @rectMode__ = mode end # Sets ellipse mode. Default is CENTER. # @@ -1065,11 +1115,11 @@ # # @param mode [CORNER, CORNERS, CENTER, RADIUS] # # @return [nil] nil # - def ellipseMode (mode) + def ellipseMode(mode) @ellipseMode__ = mode end # Sets image mode. Default is CORNER. # @@ -1079,16 +1129,16 @@ # # @param mode [CORNER, CORNERS, CENTER] # # @return [nil] nil # - def imageMode (mode) + def imageMode(mode) @imageMode__ = mode end # @private - private def toXYWH__ (mode, a, b, c, d) + private def toXYWH__(mode, a, b, c, d) case mode when CORNER then [a, b, c, d] when CORNERS then [a, b, c - a, d - b] when CENTER then [a - c / 2.0, b - d / 2.0, c, d] when RADIUS then [a - c, b - d, c * 2, d * 2] @@ -1112,11 +1162,11 @@ # @param b [Integer] blue value (0..255) # @param alpha [Integer] alpha value (0..255) # # @return [nil] nil # - def fill (*args) + def fill(*args) @painter__.fill(*toRGBA__(*args)) nil end # Sets stroke color. @@ -1135,62 +1185,62 @@ # @param b [Integer] blue value (0..255) # @param alpha [Integer] alpha value (0..255) # # @return [nil] nil # - def stroke (*args) + def stroke(*args) @painter__.stroke(*toRGBA__(*args)) nil end # Sets stroke weight. # # @param weight [Numeric] width of stroke # # @return [nil] nil # - def strokeWeight (weight) + def strokeWeight(weight) @painter__.stroke_width weight nil end # Sets stroke cap mode. # # @param cap [BUTT, ROUND, SQUARE] # # @return [nil] nil # - def strokeCap (cap) + def strokeCap(cap) @painter__.stroke_cap cap nil end # Sets stroke join mode. # # @param join [MITER, ROUND, SQUARE] # # @return [nil] nil # - def strokeJoin (join) + def strokeJoin(join) @painter__.stroke_join join nil end # Disables filling. # # @return [nil] nil # - def noFill () + def noFill() @painter__.fill nil nil end # Disables drawing stroke. # # @return [nil] nil # - def noStroke () + def noStroke() @painter__.stroke nil nil end # Sets font. @@ -1198,45 +1248,45 @@ # @param name [String] font name # @param size [Numeric] font size (max 256) # # @return [Font] current font # - def textFont (name = nil, size = nil) + def textFont(name = nil, size = nil) setFont__ name, size if name || size Font.new @painter__.font end # Sets text size. # # @param size [Numeric] font size (max 256) # # @return [nil] nil # - def textSize (size) + def textSize(size) setFont__ @painter__.font.name, size nil end - def textWidth (str) + def textWidth(str) @painter__.font.width str end - def textAscent () + def textAscent() @painter__.font.ascent end - def textDescent () + def textDescent() @painter__.font.descent end - def textAlign (horizontal, vertical = BASELINE) + def textAlign(horizontal, vertical = BASELINE) @textAlignH__ = horizontal @textAlignV__ = vertical end # @private - def setFont__ (name, size) + def setFont__(name, size) size = 256 if size && size > 256 @painter__.font name, size end # Clears screen. @@ -1255,15 +1305,15 @@ # @param b [Integer] blue value (0..255) # @param alpha [Integer] alpha value (0..255) # # @return [nil] nil # - def background (*args) + def background(*args) assertDrawing__ - rgba = toRGBA__ *args + rgba = toRGBA__(*args) if rgba[3] == 1 - @painter__.background *rgba + @painter__.background(*rgba) else @painter__.push fill: rgba, stroke: nil do |_| @painter__.rect 0, 0, width, height end end @@ -1275,11 +1325,11 @@ # @param x [Numeric] horizontal position # @param y [Numeric] vertical position # # @return [nil] nil # - def point (x, y) + def point(x, y) assertDrawing__ w = @painter__.stroke_width w = 1 if w == 0 @painter__.ellipse x - (w / 2.0), y - (w / 2.0), w, w nil @@ -1292,11 +1342,11 @@ # @param x2 [Numeric] horizontal position of second point # @param y2 [Numeric] vertical position of second point # # @return [nil] nil # - def line (x1, y1, x2, y2) + def line(x1, y1, x2, y2) assertDrawing__ @painter__.line x1, y1, x2, y2 nil end @@ -1316,11 +1366,11 @@ # @param br [Numeric] radius for bottom-right corner # @param bl [Numeric] radius for bottom-left corner # # @return [nil] nil # - def rect (a, b, c, d, *args) + def rect(a, b, c, d, *args) assertDrawing__ x, y, w, h = toXYWH__ @rectMode__, a, b, c, d case args.size when 0 then @painter__.rect x, y, w, h when 1 then @painter__.rect x, y, w, h, round: args[0] @@ -1337,11 +1387,11 @@ # @param c [Numeric] width of the shape # @param d [Numeric] height of the shape # # @return [nil] nil # - def ellipse (a, b, c, d) + def ellipse(a, b, c, d) assertDrawing__ x, y, w, h = toXYWH__ @ellipseMode__, a, b, c, d @painter__.ellipse x, y, w, h nil end @@ -1352,11 +1402,11 @@ # @param y [Numeric] vertical position of the shape # @param extent [Numeric] width and height of the shape # # @return [nil] nil # - def circle (x, y, extent) + def circle(x, y, extent) ellipse x, y, extent, extent end # Draws an arc. # @@ -1367,15 +1417,15 @@ # @param start [Numeric] angle to start the arc # @param stop [Numeric] angle to stop the arc # # @return [nil] nil # - def arc (a, b, c, d, start, stop) + def arc(a, b, c, d, start, stop) assertDrawing__ x, y, w, h = toXYWH__ @ellipseMode__, a, b, c, d - start = toAngle__ -start - stop = toAngle__ -stop + start = toAngle__(-start) + stop = toAngle__(-stop) @painter__.ellipse x, y, w, h, from: start, to: stop nil end # Draws a square. @@ -1384,11 +1434,11 @@ # @param y [Numeric] vertical position of the shape # @param extent [Numeric] width and height of the shape # # @return [nil] nil # - def square (x, y, extent) + def square(x, y, extent) rect x, y, extent, extent end # Draws a triangle. # @@ -1399,11 +1449,11 @@ # @param x3 [Numeric] horizontal position of third point # @param y3 [Numeric] vertical position of third point # # @return [nil] nil # - def triangle (x1, y1, x2, y2, x3, y3) + def triangle(x1, y1, x2, y2, x3, y3) assertDrawing__ @painter__.line x1, y1, x2, y2, x3, y3, loop: true nil end @@ -1418,11 +1468,11 @@ # @param x4 [Numeric] horizontal position of fourth point # @param y4 [Numeric] vertical position of fourth point # # @return [nil] nil # - def quad (x1, y1, x2, y2, x3, y3, x4, y4) + def quad(x1, y1, x2, y2, x3, y3, x4, y4) assertDrawing__ @painter__.line x1, y1, x2, y2, x3, y3, x4, y4, loop: true nil end @@ -1437,11 +1487,11 @@ # @param cx2 [Numeric] horizontal position of ending control point # @param cy2 [Numeric] vertical position of ending control point # # @return [nil] nil # - def curve (cx1, cy1, x1, y1, x2, y2, cx2, cy2) + def curve(cx1, cy1, x1, y1, x2, y2, cx2, cy2) assertDrawing__ @painter__.curve cx1, cy1, x1, y1, x2, y2, cx2, cy2 nil end @@ -1456,11 +1506,11 @@ # @param x2 [Numeric] horizontal position of second point # @param y2 [Numeric] vertical position of second point # # @return [nil] nil # - def bezier (x1, y1, cx1, cy1, cx2, cy2, x2, y2) + def bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2) assertDrawing__ @painter__.bezier x1, y1, cx1, cy1, cx2, cy2, x2, y2 nil end @@ -1478,11 +1528,11 @@ # @param c [Numeric] equivalent to parameters of the rect(), see rectMode() # @param d [Numeric] equivalent to parameters of the rect(), see rectMode() # # @return [nil] nil # - def text (str, x, y, x2 = nil, y2 = nil) + def text(str, x, y, x2 = nil, y2 = nil) assertDrawing__ if x2 raise ArgumentError, "missing y2 parameter" unless y2 x, y, w, h = toXYWH__ @rectMode__, x, y, x2, y2 case @textAlignH__ @@ -1512,11 +1562,11 @@ # @param c [Numeric] width of the image # @param d [Numeric] height of the image # # @return [nil] nil # - def image (img, a, b, c = nil, d = nil) + def image(img, a, b, c = nil, d = nil) assertDrawing__ i = img.getInternal__ x, y, w, h = toXYWH__ @imageMode__, a, b, c || i.width, d || i.height @painter__.image i, x, y, w, h nil @@ -1537,11 +1587,11 @@ # @param dw [Numrtic] width of destination region # @param dh [Numrtic] height of destination region # # @return [nil] nil # - def copy (img = nil, sx, sy, sw, sh, dx, dy, dw, dh) + def copy(img = nil, sx, sy, sw, sh, dx, dy, dw, dh) assertDrawing__ src = img&.getInternal__ || @window__.canvas @painter__.image src, sx, sy, sw, sh, dx, dy, dw, dh end @@ -1550,11 +1600,11 @@ # @param x [Numeric] horizontal transformation # @param y [Numeric] vertical transformation # # @return [nil] nil # - def translate (x, y) + def translate(x, y) assertDrawing__ @painter__.translate x, y nil end @@ -1567,11 +1617,11 @@ # @param x [Numeric] horizontal scale # @param y [Numeric] vertical scale # # @return [nil] nil # - def scale (x, y) + def scale(x, y) assertDrawing__ @painter__.scale x, y nil end @@ -1579,21 +1629,21 @@ # # @param angle [Numeric] angle for rotation # # @return [nil] nil # - def rotate (angle) + def rotate(angle) assertDrawing__ @painter__.rotate toAngle__ angle nil end # Pushes the current transformation matrix to stack. # # @return [nil] nil # - def pushMatrix (&block) + def pushMatrix(&block) assertDrawing__ @matrixStack__.push @painter__.matrix if block block.call popMatrix @@ -1603,32 +1653,32 @@ # Pops the current transformation matrix from stack. # # @return [nil] nil # - def popMatrix () + def popMatrix() assertDrawing__ raise "matrix stack underflow" if @matrixStack__.empty? @painter__.matrix = @matrixStack__.pop nil end # Reset current transformation matrix with identity matrix. # # @return [nil] nil # - def resetMatrix () + def resetMatrix() assertDrawing__ @painter__.matrix = 1 nil end # Save current style values to the style stack. # # @return [nil] nil # - def pushStyle (&block) + def pushStyle(&block) assertDrawing__ @styleStack__.push [ @painter__.fill, @painter__.stroke, @painter__.stroke_width, @@ -1651,11 +1701,11 @@ # Restore style values from the style stack. # # @return [nil] nil # - def popStyle () + def popStyle() assertDrawing__ raise "style stack underflow" if @styleStack__.empty? @painter__.fill, @painter__.stroke, @painter__.stroke_width, @@ -1673,11 +1723,11 @@ # Save current styles and transformations to stack. # # @return [nil] nil # - def push (&block) + def push(&block) pushMatrix pushStyle if block block.call pop @@ -1686,22 +1736,22 @@ # Restore styles and transformations from stack. # # @return [nil] nil # - def pop () + def pop() popMatrix popStyle end # @private - def getInternal__ () + def getInternal__() @image__ end # @private - private def assertDrawing__ () + private def assertDrawing__() raise "call beginDraw() before drawing" unless @drawing__ end end# GraphicsContext @@ -1712,18 +1762,18 @@ include GraphicsContext # Initialize graphics object. # - def initialize (width, height) + def initialize(width, height) image = Rays::Image.new width, height init__ image, image.painter end # Start drawing. # - def beginDraw (&block) + def beginDraw(&block) @painter__.__send__ :begin_paint beginDraw__ push if block block.call @@ -1731,11 +1781,11 @@ end end # End drawing. # - def endDraw () + def endDraw() pop endDraw__ @painter__.__send__ :end_paint end @@ -1754,30 +1804,33 @@ # @private @@context__ = nil # @private - def self.context__ () + def self.context__() @@context__ end # @private - def initialize (window) + def initialize(window) @@context__ = self tmpdir__.tap {|dir| FileUtils.rm_r dir.to_s if dir.directory?} @window__ = window init__ @window__.canvas, @window__.canvas_painter.paint {background 0.8} - @loop__ = true - @redraw__ = false - @frameCount__ = 0 - @mousePos__ = - @mousePrevPos__ = [0, 0] - @mousePressed__ = false - @touches__ = [] + @loop__ = true + @redraw__ = false + @frameCount__ = 0 + @key__ = nil + @keyCode__ = nil + @keysPressed__ = Set.new + @pointerPos__ = + @pointerPrevPos__ = [0, 0] + @pointersPressed__ = Set.new + @touches__ = [] @window__.before_draw = proc {beginDraw__} @window__.after_draw = proc {endDraw__} drawFrame = -> { @@ -1794,21 +1847,42 @@ @window__.draw = proc do |e| if @loop__ || @redraw__ @redraw__ = false drawFrame.call end - @mousePrevPos__ = @mousePos__ + @pointerPrevPos__ = @pointerPos__ end + updateKeyStates = -> event, pressed { + @key__ = event.chars + @keyCode__ = event.key + if pressed != nil + set, key = @keysPressed__, event.key + pressed ? set.add(key) : set.delete(key) + end + } + updatePointerStates = -> event, pressed = nil { - @mousePos__ = @window__.to_canvas_coord event.pos.x, event.pos.y - @mousePressed__ = pressed if pressed != nil - @touches__ = event.positions.map {|pos| - Touch.new *@window__.to_canvas_coord(pos.x, pos.y) - } + @pointerPos__ = event.pos.to_a + @touches__ = event.positions.map {|pos| Touch.new(*pos.to_a)} + if pressed != nil + set, type = @pointersPressed__, event.pointer_type + pressed ? set.add(type) : set.delete(type) + end } + @window__.key_down = proc do |e| + updateKeyStates.call e, true + @keyPressedBlock__&.call + @keyTypedBlock__&.call unless @key__.empty? + end + + @window__.key_up = proc do |e| + updateKeyStates.call e, false + @keyReleasedBlock__&.call + end + @window__.pointer_down = proc do |e| updatePointerStates.call e, true (@touchStartedBlock__ || @mousePressedBlock__)&.call end @@ -1824,90 +1898,121 @@ @window__.pointer_drag = proc do |e| updatePointerStates.call e (@touchMovedBlock__ || @mouseDraggedBlock__)&.call end + + @window__.motion = proc do |e| + @motionGravity__ = createVector(*e.gravity.to_a(3)) + @motionBlock__&.call + end end - # Define setup block. + # Defines setup block. # - def setup (&block) + def setup(&block) @window__.setup = block nil end - # Define draw block. + # Defines draw block. # - def draw (&block) + def draw(&block) @drawBlock__ = block if block nil end - # @private - private def key__ (&block) - @window__.key = block + # Defines keyPressed block. + # + # @return [Boolean] is any key pressed or not + # + def keyPressed(&block) + @keyPressedBlock__ = block if block + not @keysPressed__.empty? + end + + # Defines keyReleased block. + # + def keyReleased(&block) + @keyReleasedBlock__ = block if block nil end - # Define mousePressed block. + # Defines keyTyped block. # - def mousePressed (&block) + def keyTyped(&block) + @keyTypedBlock__ = block if block + nil + end + + # Defines mousePressed block. + # + # @return [Boolean] is any mouse button pressed or not + # + def mousePressed(&block) @mousePressedBlock__ = block if block - @mousePressed__ + not @pointersPressed__.empty? end - # Define mouseReleased block. + # Defines mouseReleased block. # - def mouseReleased (&block) + def mouseReleased(&block) @mouseReleasedBlock__ = block if block nil end - # Define mouseMoved block. + # Defines mouseMoved block. # - def mouseMoved (&block) + def mouseMoved(&block) @mouseMovedBlock__ = block if block nil end - # Define mouseDragged block. + # Defines mouseDragged block. # - def mouseDragged (&block) + def mouseDragged(&block) @mouseDraggedBlock__ = block if block nil end - # Define touchStarted block. + # Defines touchStarted block. # - def touchStarted (&block) + def touchStarted(&block) @touchStartedBlock__ = block if block nil end - # Define touchEnded block. + # Defines touchEnded block. # - def touchEnded (&block) + def touchEnded(&block) @touchEndedBlock__ = block if block nil end - # Define touchMoved block. + # Defines touchMoved block. # - def touchMoved (&block) + def touchMoved(&block) @touchMovedBlock__ = block if block nil end + # Defines motion block. + # + def motion(&block) + @motionBlock__ = block if block + nil + end + # Changes canvas size. # # @param width [Integer] new width # @param height [Integer] new height # @param pixelDensity [Numeric] new pixel density # # @return [nil] nil # - def size (width, height, pixelDensity: self.pixelDensity) + def size(width, height, pixelDensity: self.pixelDensity) resizeCanvas__ :size, width, height, pixelDensity nil end # Changes canvas size. @@ -1916,28 +2021,28 @@ # @param height [Integer] new height # @param pixelDensity [Numeric] new pixel density # # @return [nil] nil # - def createCanvas (width, height, pixelDensity: self.pixelDensity) + def createCanvas(width, height, pixelDensity: self.pixelDensity) resizeCanvas__ :createCanvas, width, height, pixelDensity nil end # Changes and returns canvas pixel density. # # @param density [Numeric] new pixel density # # @return [Numeric] current pixel density # - def pixelDensity (density = nil) + def pixelDensity(density = nil) resizeCanvas__ :pixelDensity, width, height, density if density @painter__.pixel_density end # @private - def resizeCanvas__ (name, width, height, pixelDensity) + def resizeCanvas__(name, width, height, pixelDensity) raise '#{name}() must be called on startup or setup block' if @started__ @painter__.__send__ :end_paint @window__.__send__ :resize_canvas, width, height, pixelDensity updateCanvas__ @window__.canvas, @window__.canvas_painter @@ -1948,107 +2053,131 @@ # Returns pixel density of display. # # @return [Numeric] pixel density # - def displayDensity () + def displayDensity() @window__.painter.pixel_density end # Returns window width. # # @return [Numeric] window width # - def windowWidth () + def windowWidth() @window__.width end # Returns window height. # # @return [Numeric] window height # - def windowHeight () + def windowHeight() @window__.height end # Returns number of frames since program started. # # @return [Integer] total number of frames # - def frameCount () + def frameCount() @frameCount__ end # Returns number of frames per second. # # @return [Float] frames per second # - def frameRate () + def frameRate() @window__.event.fps end + # Returns the last key that was pressed or released. + # + # @return [String] last key + # + def key() + @key__ + end + + # Returns the last key code that was pressed or released. + # + # @return [Symbol] last key code + # + def keyCode() + @keyCode__ + end + # Returns mouse x position # # @return [Numeric] horizontal position of mouse # - def mouseX () - @mousePos__[0] + def mouseX() + @pointerPos__[0] end # Returns mouse y position # # @return [Numeric] vertical position of mouse # - def mouseY () - @mousePos__[1] + def mouseY() + @pointerPos__[1] end # Returns mouse x position in previous frame # # @return [Numeric] horizontal position of mouse # - def pmouseX () - @mousePrevPos__[0] + def pmouseX() + @pointerPrevPos__[0] end # Returns mouse y position in previous frame # # @return [Numeric] vertical position of mouse # - def pmouseY () - @mousePrevPos__[1] + def pmouseY() + @pointerPrevPos__[1] end # Returns array of touches # # @return [Array] Touch objects # - def touches () + def touches() @touches__ end + # Returns vector for real world gravity + # + # @return [Vector] gravity vector + # + def motionGravity() + @motionGravity__ + end + # Enables calling draw block on every frame. # # @return [nil] nil # - def loop () + def loop() @loop__ = true end # Disables calling draw block on every frame. # # @return [nil] nil # - def noLoop () + def noLoop() @loop__ = false end # Calls draw block to redraw frame. # # @return [nil] nil # - def redraw () + def redraw() @redraw__ = true end # # Utilities @@ -2058,92 +2187,92 @@ # # @param value [Numeric] number # # @return [Numeric] absolute number # - def abs (value) + def abs(value) value.abs end # Returns the closest integer number greater than or equal to the value. # # @param value [Numeric] number # # @return [Numeric] rounded up number # - def ceil (value) + def ceil(value) value.ceil end # Returns the closest integer number less than or equal to the value. # # @param value [Numeric] number # # @return [Numeric] rounded down number # - def floor (value) + def floor(value) value.floor end # Returns the closest integer number. # # @param value [Numeric] number # # @return [Numeric] rounded number # - def round (value) + def round(value) value.round end # Returns the natural logarithm (the base-e logarithm) of a number. # # @param value [Numeric] number (> 0.0) # # @return [Numeric] result number # - def log (n) + def log(n) Math.log n end # Returns Euler's number e raised to the power of value. # # @param value [Numeric] number # # @return [Numeric] result number # - def exp (n) + def exp(n) Math.exp n end # Returns value raised to the power of exponent. # # @param value [Numeric] base number # @param exponent [Numeric] exponent number # # @return [Numeric] value ** exponent # - def pow (value, exponent) + def pow(value, exponent) value ** exponent end # Returns squared value. # # @param value [Numeric] number # # @return [Numeric] squared value # - def sq (value) + def sq(value) value * value end # Returns squared value. # # @param value [Numeric] number # # @return [Numeric] squared value # - def sqrt (value) + def sqrt(value) Math.sqrt value end # Returns the magnitude (or length) of a vector. # @@ -2154,11 +2283,11 @@ # @param y [Numeric] y of point # @param z [Numeric] z of point # # @return [Numeric] magnitude # - def mag (*args) + def mag(*args) x, y, z = *args case args.size when 2 then Math.sqrt x * x + y * y when 3 then Math.sqrt x * x + y * y + z * z else raise ArgumentError @@ -2177,11 +2306,11 @@ # @param y2 [Numeric] y of second point # @param z2 [Numeric] z of second point # # @return [Numeric] distance between 2 points # - def dist (*args) + def dist(*args) case args.size when 4 x1, y1, x2, y2 = *args xx, yy = x2 - x1, y2 - y1 Math.sqrt xx * xx + yy * yy @@ -2199,11 +2328,11 @@ # @param start [Numeric] lower bound of the range # @param stop [Numeric] upper bound of the range # # @return [Numeric] normalized value between 0..1 # - def norm (value, start, stop) + def norm(value, start, stop) (value.to_f - start.to_f) / (stop.to_f - start.to_f) end # Returns the interpolated number between range start..stop. # @@ -2211,11 +2340,11 @@ # @param stop [Numeric] upper bound of the range # @param amount [Numeric] amount to interpolate # # @return [Numeric] interporated number # - def lerp (start, stop, amount) + def lerp(start, stop, amount) start + (stop - start) * amount end # Maps a number from range start1..stop1 to range start2..stop2. # @@ -2225,11 +2354,11 @@ # @param start2 [Numeric] lower bound of the range2 # @param stop2 [Numeric] upper bound of the range2 # # @return [Numeric] mapped number # - def map (value, start1, stop1, start2, stop2) + def map(value, start1, stop1, start2, stop2) lerp start2, stop2, norm(value, start1, stop1) end # Returns minimum value. # @@ -2242,11 +2371,11 @@ # @param c [Numeric] value to compare # @param array [Numeric] values to compare # # @return [Numeric] minimum value # - def min (*args) + def min(*args) args.flatten.min end # Returns maximum value. # @@ -2259,11 +2388,11 @@ # @param c [Numeric] value to compare # @param array [Numeric] values to compare # # @return [Numeric] maximum value # - def max (*args) + def max(*args) args.flatten.max end # Constrains the number between min..max. # @@ -2271,102 +2400,102 @@ # @param min [Numeric] lower bound of the range # @param max [Numeric] upper bound of the range # # @return [Numeric] constrained number # - def constrain (value, min, max) + def constrain(value, min, max) value < min ? min : (value > max ? max : value) end # Converts degree to radian. # # @param degree [Numeric] degree to convert # # @return [Numeric] radian # - def radians (degree) + def radians(degree) degree * DEG2RAD__ end # Converts radian to degree. # # @param radian [Numeric] radian to convert # # @return [Numeric] degree # - def degrees (radian) + def degrees(radian) radian * RAD2DEG__ end # Returns the sine of an angle. # # @param angle [Numeric] angle in radians # # @return [Numeric] the sine # - def sin (angle) + def sin(angle) Math.sin angle end # Returns the cosine of an angle. # # @param angle [Numeric] angle in radians # # @return [Numeric] the cosine # - def cos (angle) + def cos(angle) Math.cos angle end # Returns the ratio of the sine and cosine of an angle. # # @param angle [Numeric] angle in radians # # @return [Numeric] the tangent # - def tan (angle) + def tan(angle) Math.tan angle end # Returns the inverse of sin(). # # @param value [Numeric] value for calculation # # @return [Numeric] the arc sine # - def asin (value) + def asin(value) Math.asin value end # Returns the inverse of cos(). # # @param value [Numeric] value for calculation # # @return [Numeric] the arc cosine # - def acos (value) + def acos(value) Math.acos value end # Returns the inverse of tan(). # # @param value [Numeric] value for valculation # # @return [Numeric] the arc tangent # - def atan (value) + def atan(value) Math.atan value end # Returns the angle from a specified point. # # @param y [Numeric] y of the point # @param x [Numeric] x of the point # # @return [Numeric] the angle in radians # - def atan2 (y, x) + def atan2(y, x) Math.atan2 y, x end # Returns the perlin noise value. # @@ -2378,11 +2507,11 @@ # @param y [Numeric] vertical point in noise space # @param z [Numeric] depth point in noise space # # @return [Numeric] noise value (0.0..1.0) # - def noise (x, y = 0, z = 0) + def noise(x, y = 0, z = 0) Rays.perlin(x, y, z) / 2.0 + 0.5 end # Returns a random number in range low...high # @@ -2395,11 +2524,11 @@ # @param high [Numeric] upper limit # @param choices [Array] array to choose from # # @return [Float] random number # - def random (*args) + def random(*args) return args.first.sample if args.first.kind_of? Array high, low = args.reverse rand (low || 0).to_f...(high || 1).to_f end @@ -2413,47 +2542,47 @@ # @param y [Numeric] y of new vector # @param z [Numeric] z of new vector # # @return [Vector] new vector # - def createVector (*args) - Vector.new *args + def createVector(*args) + Vector.new(*args, context: self) end # Creates a camera object as a video input device. # # @return [Capture] camera object # - def createCapture (*args) - Capture.new *args + def createCapture(*args) + Capture.new(*args) end # Creates a new off-screen graphics context object. # # @param width [Numeric] width of graphics image # @param height [Numeric] height of graphics image # # @return [Graphics] graphics object # - def createGraphics (width, height) + def createGraphics(width, height) Graphics.new width, height end # Loads image. # # @param filename [String] file name to load image # @param extension [String] type of image to load (ex. 'png') # # @return [Image] loaded image object # - def loadImage (filename, extension = nil) + def loadImage(filename, extension = nil) filename = getImage__ filename, extension if filename =~ %r|^https?://| Image.new Rays::Image.load filename end # @private - private def getImage__ (uri, ext) + private def getImage__(uri, ext) ext ||= File.extname uri raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png)$/i tmpdir = tmpdir__ path = tmpdir + Digest::SHA1.hexdigest(uri) @@ -2473,10 +2602,10 @@ end path.to_s end # @private - private def tmpdir__ () + private def tmpdir__() Pathname(Dir.tmpdir) + Digest::SHA1.hexdigest(self.class.name) end end# Context