Skip to content

Instantly share code, notes, and snippets.

@tkojitu
Created March 13, 2012 13:46
Show Gist options
  • Save tkojitu/2028850 to your computer and use it in GitHub Desktop.
Save tkojitu/2028850 to your computer and use it in GitHub Desktop.
include Java
import java.awt.Rectangle
import java.awt.geom.Ellipse2D
import java.awt.geom.Line2D
import java.awt.geom.Point2D
import java.awt.geom.Rectangle2D
import java.lang.Math
import javax.swing.JFrame
class App
include java.lang.Runnable
def createAndShowGui
frame = newFrame
frame.setVisible(true)
end
def newFrame
frame = JFrame.new("Rotate")
frame.setDefaultCloseOperation(JFrame::EXIT_ON_CLOSE)
frame.setContentPane(newPane)
frame.pack
return frame
end
def newPane
pane = RotPanel.new
pane.setPreferredSize(java.awt.Dimension.new(640, 480))
addRects(pane)
return pane
end
def addRects(pane)
pane.addRect(Rectangle.new(100, 100, 100, 200))
pane.addRect(Rectangle.new(200, 100, 100, 200))
pane.addRect(Rectangle.new(300, 100, 100, 200))
# pane.addRotRect(Rectangle.new(100, 100, 100, 200))
# pane.addRotRect(Rectangle.new(200, 100, 100, 200))
pane.addSliceRect(Rectangle.new(100, 100, 300, 200), 3)
end
def run
createAndShowGui
end
end
class RotPanel < javax.swing.JPanel
def initialize
super
@rects = []
end
def addRect(rectangle)
@rects << Rect.new(rectangle)
end
def addRotRect(rectangle)
@rects << RotRect.new(rectangle)
end
def addSliceRect(rectangle, nslice)
@rects << SliceRect.new(rectangle, nslice)
end
def paintComponent(graphics)
@rects.each{|rect| rect.draw(graphics)}
end
end
class Rect
def initialize(rectangle)
@rect = rectangle
end
def draw(graphics)
drawRect(graphics)
drawCenter(graphics)
end
def drawRect(graphics)
saved = graphics.getColor
begin
graphics.setColor(java.awt.Color.blue)
graphics.draw(@rect)
ensure
graphics.setColor(saved)
end
end
def drawCenter(graphics)
ellipse = getCenterEllipse
graphics.draw(ellipse)
end
def getCenterEllipse
x, y = getCenterPoint
return Ellipse2D::Double.new(x - 2.5, y - 2.5, 5, 5)
end
def getCenterPoint
return [@rect.x + @rect.width / 2.0, @rect.y + @rect.height / 2.0]
end
end
class RotRect < Rect
def initialize(rectangle)
super
end
def draw(graphics)
saved = graphics.getTransform
begin
graphics.setTransform(getTrans)
graphics.draw(@rect)
ensure
graphics.setTransform(saved)
end
end
def getTrans
trans = java.awt.geom.AffineTransform.new
x, y = getCenterPoint
trans.rotate(Math.toRadians(30), x, y)
return trans
end
end
class SliceRect
def initialize(rectangle, nslice)
@rect = rectangle
@nslice = nslice
@angle = $angle
end
def draw(graphics)
getRects.each{|rect| drawSlice(graphics, rect)}
drawMostLeftCorner(graphics)
drawMostRightCorner(graphics)
drawUpperLine(graphics)
drawLowerLine(graphics)
end
def getRects
rects = []
width = @rect.width / @nslice
x = @rect.x
@nslice.times do |i|
rects << Rectangle2D::Double.new(x + i * width, @rect.y, width,
@rect.height)
end
return rects
end
def drawSlice(graphics, rect)
drawSliceRect(graphics, rect)
drawSliceCenter(graphics, rect)
end
def drawSliceRect(graphics, rect)
saved = graphics.getTransform
begin
trans = getTrans(rect)
graphics.setTransform(trans)
graphics.draw(rect)
ensure
graphics.setTransform(saved)
end
end
def drawSliceCenter(graphics, rect)
ellipse = getCenterEllipse(rect)
graphics.draw(ellipse)
end
def getCenterEllipse(rect)
x, y = getCenterPoint(rect)
return Ellipse2D::Double.new(x - 2.5, y - 2.5, 5, 5)
end
def getCenterPoint(rect)
return [rect.x + rect.width / 2.0, rect.y + rect.height / 2.0]
end
def getTrans(rect)
trans = java.awt.geom.AffineTransform.new
x, y = getCenterPoint(rect)
trans.rotate(Math.toRadians(@angle), x, y)
return trans
end
def drawMostLeftCorner(graphics)
ellipse = getMostLeftCornerEllipse
graphics.draw(ellipse)
end
def getMostLeftCornerEllipse
mostLeftCorner = getMostLeftCorner
return Ellipse2D::Double.new(mostLeftCorner.getX() - 2.5,
mostLeftCorner.getY() - 2.5, 5, 5)
end
def getMostLeftCorner
mostLeft = getRects[0]
leftTop = Point2D::Double.new(mostLeft.x, mostLeft.y)
leftBottom = Point2D::Double.new(mostLeft.x, mostLeft.y + mostLeft.height)
trans = getTrans(mostLeft)
rotLeftTop = Point2D::Double.new
rotLeftBottom = Point2D::Double.new
trans.transform(leftTop, rotLeftTop)
trans.transform(leftBottom, rotLeftBottom)
if rotLeftTop.x < rotLeftBottom.x
return rotLeftTop
else
return rotLeftBottom
end
end
def drawMostRightCorner(graphics)
ellipse = getMostRightCornerEllipse
graphics.draw(ellipse)
end
def getMostRightCornerEllipse
mostRightCorner = getMostRightCorner
return Ellipse2D::Double.new(mostRightCorner.getX() - 2.5,
mostRightCorner.getY() - 2.5, 5, 5)
end
def getMostRightCorner
mostRight = getRects[-1]
rightTop = Point2D::Double.new(mostRight.x + mostRight.width, mostRight.y)
rightBottom = Point2D::Double.new(mostRight.x + mostRight.width,
mostRight.y + mostRight.height)
trans = getTrans(mostRight)
rotRightTop = Point2D::Double.new
rotRightBottom = Point2D::Double.new
trans.transform(rightTop, rotRightTop)
trans.transform(rightBottom, rotRightBottom)
if rotRightTop.x > rotRightBottom.x
return rotRightTop
else
return rotRightBottom
end
end
def drawUpperLine(graphics)
line = getUpperLine
graphics.draw(line)
end
def getUpperLine
length = @rect.width / @nslice / Math.cos(Math.toRadians($angle))
if @angle > 0
corner = getMostRightCorner
dest = Point2D::Double.new(corner.getX - getLineLength, corner.getY)
return Line2D::Double.new(corner, dest)
else
corner = getMostLeftCorner
dest = Point2D::Double.new(corner.getX + getLineLength, corner.getY)
return Line2D::Double.new(corner, dest)
end
end
def drawLowerLine(graphics)
line = getLowerLine
graphics.draw(line)
end
def getLowerLine
if @angle > 0
corner = getMostLeftCorner
dest = Point2D::Double.new(corner.getX + getLineLength, corner.getY)
return Line2D::Double.new(corner, dest)
else
corner = getMostRightCorner
dest = Point2D::Double.new(corner.getX - getLineLength, corner.getY)
return Line2D::Double.new(corner, dest)
end
end
def getLineLength
sliceWidth = @rect.width / @nslice
hypotenuse = sliceWidth / Math.cos(Math.toRadians($angle))
diff = hypotenuse - sliceWidth
return hypotenuse * @nslice - diff * (@nslice - 1)
end
end
if $0 == __FILE__
$angle = ARGV.empty? ? 30.0 : ARGV[0].to_i
app = App.new
javax.swing.SwingUtilities.invokeLater(app)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment