332 lines
8.7 KiB
Ruby
Executable File
332 lines
8.7 KiB
Ruby
Executable File
#
|
|
# GENERIC CLASS
|
|
# Author:: Mark Harrison-Ball <Mark.Harrison-Ball@rockstargames.com>
|
|
# Date:: 20 Februray 2013 (AP3)
|
|
# Purpose:
|
|
# Draw a graph Utility
|
|
#
|
|
|
|
require 'System.Drawing'
|
|
path = File.expand_path $0
|
|
path = File.dirname(path)
|
|
require "#{path}/../../Global/image/Image.rb"
|
|
require "#{path}/../../Global/array/arrayUtils.rb"
|
|
|
|
|
|
class Graph
|
|
attr_reader :image
|
|
attr_reader :graphics
|
|
#attr_reader :defaultPenColor
|
|
attr_reader :pen
|
|
|
|
|
|
def initialize( x , y )
|
|
#Image
|
|
@x = x
|
|
@y = y
|
|
|
|
#margin
|
|
@margin = 20
|
|
|
|
#Graph
|
|
@gX = x-(@margin*2)
|
|
@gY = y-(@margin*2)
|
|
|
|
# Brush List
|
|
@BrushBeige = System::Drawing::SolidBrush.new(System::Drawing::Color.FromArgb(243,237,237))
|
|
@BrushGrey = System::Drawing::SolidBrush.new(System::Drawing::Color.FromArgb(160,160,160))
|
|
@BrushBlack = System::Drawing::SolidBrush.new(System::Drawing::Color.Black)
|
|
@BrushDarkGrey = System::Drawing::SolidBrush.new(System::Drawing::Color.FromArgb(150,150,150))
|
|
|
|
# Pen List
|
|
@PenBeige = System::Drawing::Pen.new(System::Drawing::Color.FromArgb(223,217,217))
|
|
@PenGrey = System::Drawing::Pen.new(System::Drawing::Color.FromArgb(97,95,95))
|
|
@PenBlack = System::Drawing::Pen.new(System::Drawing::Color.Black)
|
|
@PenRed = System::Drawing::Pen.new(System::Drawing::Color.Red)
|
|
@PenGreen = System::Drawing::Pen.new(System::Drawing::Color.Green)
|
|
@PenBlue = System::Drawing::Pen.new(System::Drawing::Color.Blue)
|
|
@PenPurple = System::Drawing::Pen.new(System::Drawing::Color.Purple)
|
|
|
|
# Font List
|
|
@DrawFont = System::Drawing::Font.new("Arial", 6)
|
|
|
|
# Pen Array List
|
|
@penList = [@PenRed, @PenGreen, @PenBlue, @PenPurple]
|
|
|
|
@gWidth = 0
|
|
@gHeight = 0
|
|
@marginX = 20
|
|
@marginY = 20
|
|
# Used for negative values
|
|
@setMinHOffset = 0
|
|
|
|
#fillbackground()
|
|
@Title = ""
|
|
|
|
@arrayUtils = ArrayUtils.new()
|
|
|
|
@stringformat = System::Drawing::StringFormat.new()
|
|
@right = System::Drawing::StringAlignment.Far
|
|
@center = System::Drawing::StringAlignment.Center
|
|
@left = System::Drawing::StringAlignment.Near
|
|
|
|
@stringformat.Alignment = @right
|
|
|
|
end
|
|
|
|
def path
|
|
@image.path()
|
|
end
|
|
|
|
def new(path)
|
|
@image = Image.new( @x , @y, path )
|
|
@graphics = System::Drawing::Graphics.from_image(@image.source)
|
|
fillbackground()
|
|
end
|
|
|
|
def save()
|
|
@image.save()
|
|
end
|
|
|
|
|
|
# draw a list of blocks
|
|
# block list is a list of pairs
|
|
# timecode is based on 0 -1
|
|
def drawblocks(blocklist)
|
|
|
|
blocklist.each do | block |
|
|
x1 = @x * block[0].to_f
|
|
x2 = @x * block[1].to_f
|
|
|
|
x3 = x2-x1
|
|
if x3 < 1 then
|
|
x3 = 1
|
|
end
|
|
drawtext('B', x1, 9, @center)
|
|
drawFillRectangle(@BrushDarkGrey, x1, (@margin/2)+5, x3, @gY+(@margin/2)-5)
|
|
end
|
|
end
|
|
# a Array of points
|
|
# Confim how many vectoras and draw all of them
|
|
# RED, GREEN and BLUE
|
|
def drawgraph(vectorArray, title = "")
|
|
@Title = title
|
|
|
|
#puts " Procewsing data: #{vectorArray} "
|
|
@gWidth = getMaxWidth(vectorArray)
|
|
@gHeight = setMaxHeight(vectorArray)
|
|
|
|
drawGraphInfo(vectorArray)
|
|
#puts " Drawn Graph Info"
|
|
# If vector
|
|
puts "Vecotr is a #{vectorArray[0].class}"
|
|
if vectorArray[0].class == Array then
|
|
#puts 'Is an Array'
|
|
(0..vectorArray[0].size-1).each do |x|
|
|
tempArray = Array.new()
|
|
(0..vectorArray.size-2).each do |n|
|
|
tempArray << vectorArray[n][x]
|
|
end
|
|
draw(tempArray, x)
|
|
end
|
|
else
|
|
# draw liner
|
|
#puts 'Not a Array, prob FOV'
|
|
#puts vectorArray.min
|
|
#puts vectorArray.max
|
|
draw(vectorArray, 0)
|
|
end
|
|
|
|
end
|
|
|
|
#private
|
|
def header()
|
|
drawFillRectangle(@BrushGrey, 0,0, @x, 14)
|
|
drawtext("BLOCKING TAGS", @x/2,0)
|
|
|
|
end
|
|
|
|
def drawgrid(array)
|
|
# work out steps for every 10
|
|
maxSize = array.size
|
|
|
|
# Set our Fontheigh here in the future
|
|
fontHeight = -5
|
|
|
|
|
|
|
|
|
|
stepX = @gX.to_f / maxSize.to_f
|
|
stepY = @gY.to_f / maxSize.to_f
|
|
|
|
#puts "stepX = #{stepX}"
|
|
|
|
# Horizitonal Gird and numbers
|
|
stepMultiplier = @gY.to_f/maxSize.to_f
|
|
#puts "stepMultiplier = #{stepMultiplier}"
|
|
mStep = maxSize/30
|
|
(0..maxSize).step(mStep) { |n|
|
|
drawline(@PenBeige, @margin+(stepX*n), @margin, @margin+(stepX*n), @gY+@margin)
|
|
drawtext(n, @margin+(stepX*n), @gY+@margin+4, @center)
|
|
}
|
|
drawline(@PenBeige, @gX.to_f+@margin-1, @margin, @gX.to_f+@margin-1, @gY+@margin)
|
|
# BIt of a cheat as we daw the last grid line 1 pixel in so its drawn on the screen
|
|
#drawtext(maxSize, @gX.to_f+@margin, @gY+@margin+4, @center)
|
|
#drawtext("frames", ((@margin+(@gX/2))-mStep),(@y-12))
|
|
|
|
# Verticl Gird and numbers
|
|
|
|
# Get our min max length
|
|
range = @arrayUtils.retRange(array)
|
|
#puts "range = #{range}"
|
|
#puts "Min = #{@arrayUtils.retMin(array)}"
|
|
#puts "Max = #{@arrayUtils.retMax(array)}"
|
|
# Mininmun number of Grid divisions
|
|
gridStepDivision = 10
|
|
|
|
|
|
|
|
# Check if we have a range, if not then the graph range difference is 0 and nothing has changed
|
|
if range > 0 then
|
|
# Divid our range by our bitmap display height size (@gY) to get our step multiplier
|
|
stepMultiplier = @gY.to_f/range.to_f
|
|
# Set our step Grid Y Size
|
|
mStep = range/gridStepDivision
|
|
#puts "mStep = #{mStep}"
|
|
# Get our offset if numbers are negative
|
|
#yOffset = @arrayUtils.retMin(array).abs
|
|
yOffset = @arrayUtils.retMin(array) * -1
|
|
#puts "ABS of #{@arrayUtils.retMin(array)} = #{yOffset} "
|
|
|
|
(@arrayUtils.retMin(array)..@arrayUtils.retMax(array)).step(mStep) { |n|
|
|
yHeight = @margin + ((n+yOffset)*stepMultiplier)
|
|
drawline(@PenBeige, @margin, yHeight, @gX+@margin, yHeight)
|
|
value = '%.2f' % n
|
|
drawtext(value, @margin, yHeight+fontHeight, @right)
|
|
}
|
|
value = '%.2f' % @arrayUtils.retMax(array)
|
|
drawtext(value, @margin, @gY+@margin+fontHeight, @right)
|
|
|
|
else
|
|
# Draw single line at centre as nothing has changed
|
|
drawline(@PenBeige, @margin, @margin+(@gY.to_f/2), @gX+@margin, @margin+(@gY.to_f/2))
|
|
drawtext(0, @margin, @margin+(@gY.to_f/2)+fontHeight, @right)
|
|
end
|
|
|
|
# GRID OUTLINES
|
|
# vertical
|
|
drawline(@PenBlack, @margin, @gY+@margin, @gX+@margin, @gY+@margin)
|
|
# Hotizontal
|
|
drawline(@PenBlack, @margin, @gY+@margin, @margin, @margin)
|
|
|
|
end
|
|
|
|
def drawGraphInfo(vectorArray)
|
|
drawgrid(vectorArray)
|
|
header()
|
|
drawtext(@Title, 20+@margin,20+@margin)
|
|
end
|
|
|
|
|
|
def getMaxHeight(array)
|
|
return @arrayUtils.retRange(array)
|
|
|
|
end
|
|
|
|
def setMaxHeight(array)
|
|
|
|
min = @arrayUtils.retMin(array)
|
|
|
|
#puts "min = #{min}"
|
|
|
|
# GEt are shift so number is positive
|
|
#heighShift = min * -1
|
|
#startPoint = (max.to_f - min.to_f / 2) + heighShift
|
|
|
|
# GET OUR OFFSET SO ITS STARTS AT 0
|
|
@setMinHOffset = 0.0
|
|
if min != 0.0 then
|
|
@setMinHOffset = min * -1
|
|
end
|
|
|
|
|
|
|
|
maxheightRange = getMaxHeight(array)
|
|
result = @gY.to_f/maxheightRange.to_f #-@margin
|
|
return result
|
|
|
|
|
|
# For nulll chnage
|
|
if maxheightRange != 0.0 then
|
|
result = (@y.to_f-@margin)/maxheightRange
|
|
else # Array does not contain any differences, so draw at 0 center of image
|
|
@setMinHOffset = (@gY/2)
|
|
#result =
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
def getMaxWidth(array)
|
|
return (@gX.to_f)/(array.size-2).to_f
|
|
end
|
|
|
|
|
|
def fillbackground()
|
|
@graphics.FillRectangle(@BrushBeige, 0,0, @x, @y)
|
|
end
|
|
|
|
|
|
|
|
def draw(pointArray, penIndex)
|
|
if @arrayUtils.retRange(pointArray) > 0 then
|
|
(0..pointArray.size-2).each do |n|
|
|
|
|
pen = @penList[penIndex]
|
|
|
|
x1 = @margin+(n*@gWidth)
|
|
y1 = @margin+((pointArray[n]+@setMinHOffset)*@gHeight)
|
|
|
|
y2 = @gY + @margin
|
|
y2 = @margin+((pointArray[n+1]+@setMinHOffset)*@gHeight)
|
|
|
|
#draw lin emin and max height
|
|
x2 = @margin+((n+1)*@gWidth)
|
|
drawline(pen, x1, y1, x2, y2 )
|
|
#drawcircle(pen, x1, y1, 2)
|
|
end
|
|
else
|
|
pen = @penList[0]
|
|
drawline(pen, @margin,@margin+(@gY/2), @margin+@gX, @margin+(@gY/2) )
|
|
end
|
|
|
|
end
|
|
|
|
# draw a line
|
|
def drawline(penColor, x1, y1, x2, y2)
|
|
#puts " X1:#{x1} , Y1:#{y1} , X2:#{x2} ,Y2:#{y2}"
|
|
@graphics.DrawLine(penColor, x1, y1, x2, y2)
|
|
end
|
|
|
|
# Draw a circle
|
|
def drawcircle(penColor, x1, y1, d1)
|
|
@graphics.DrawEllipse(penColor, x1-(d1/2), y1-(d1/2), d1, d1)
|
|
end
|
|
|
|
# Draw Text
|
|
def drawtext(text, x, y, align = @left )
|
|
@stringformat.Alignment = align
|
|
@graphics.DrawString(text.to_s, @DrawFont, @BrushBlack, x, y, @stringformat)
|
|
end
|
|
# Draw solid rectangel
|
|
def drawFillRectangle(brushColor, x1, y1, w, h)
|
|
newRectangle = System::Drawing::Rectangle.new(x1, y1, w, h)
|
|
@graphics.FillRectangle(brushColor, newRectangle)
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|