I've been researching this topic for a couple of days and have an idea how how it might work, but I thought I'd post here for some other ideas.
What I'd like to do is generate spaceship sprites/images to be used in a game. The look and feel should be similar to these:
Basically, my idea boils down to something like this:
Generate a base shape that forms the "core" of the ship. Shapes could include circles, ovals, diamonds, rounded-corner rectangles, etc.
Generate smaller sub-shapes that are either overlayed on the core shape, or connected via a simple pipe. (All sub-shapes are mirrored to create a symmetrical ship.)
Generate even smaller sub-shapes (detail shapes), overlay them on any existing shape. (These form the "details" of the ship.)
Choose 3-5 colors, randomly shade each shape so overlayed shapes are not the same color.
Apply texturing or gradients to the core and sub-shapes (not detail shapes) to give the ship a 3-d look.
Does anyone out there know of a way to implement an algorithm such as this to achieve the desired look of the spaceships?
System.Drawing.Drawing2D.GraphicsPath
might be helpful here for building up vector paths. You can then fill and add a stroke to these paths to create the different shapes.
You can use System.Drawing.Drawing2D.LinearGradientBrush
for your gradients.
Would love to see your code if you get something going. This seems like a cool idea.
Just for fun I knocked this together in VB.NET:
Imports System.Drawing.Drawing2D
Public MustInherit Class ShipShape
Public Layout As New Rectangle(0, 0, 128, 128)
Public MustOverride Sub Draw(ByVal g As Graphics)
Public Shared Sub DrawRoundedRectangle(ByVal gp As GraphicsPath, ByVal r As Rectangle, ByVal d As Integer)
gp.AddArc(r.X, r.Y, d, d, 180, 90)
gp.AddLine(CInt(r.X + d / 2), r.Y, CInt(r.X + r.Width - d / 2), r.Y)
gp.AddArc(r.X + r.Width - d, r.Y, d, d, 270, 90)
gp.AddLine(CInt(r.X + r.Width), CInt(r.Y + d / 2), CInt(r.X + r.Width), CInt(r.Y + r.Height - d / 2))
gp.AddArc(r.X + r.Width - d, r.Y + r.Height - d, d, d, 0, 90)
gp.AddLine(CInt(r.X + d / 2), CInt(r.Y + r.Height), CInt(r.X + r.Width - d / 2), CInt(r.Y + r.Height))
gp.AddArc(r.X, r.Y + r.Height - d, d, d, 90, 90)
gp.AddLine(r.X, CInt(r.Y + d / 2), r.X, CInt(r.Y + r.Height - d / 2))
End Sub
Public Shared Sub main()
Dim b As New Bitmap(640, 480)
Dim g As Graphics = Graphics.FromImage(b)
g.Clear(Color.Magenta)
Dim Hull As New HullShape
Hull.Layout = New Rectangle(640 * 0.5 - 128 * 0.5, 480 * 0.5 - 128 * 0.5, 128, 128)
Hull.Draw(g)
Dim Wing1 As New HullShape
Wing1.Layout = New Rectangle(Hull.Layout.X - 32, Hull.Layout.Y - 32, 32, Hull.Layout.Height + 64)
Wing1.Draw(g)
Dim Wing2 As New HullShape
Wing2.Layout = New Rectangle(Hull.Layout.X + Hull.Layout.Width, Hull.Layout.Y - 32, 32, Hull.Layout.Height + 64)
Wing2.Draw(g)
b.Save("test.png")
End Sub
End Class
Public Class HullShape
Inherits ShipShape
Public Overrides Sub Draw(ByVal g As System.Drawing.Graphics)
Dim gp As New GraphicsPath
ShipShape.DrawRoundedRectangle(gp, Layout, 30)
Dim MetalBrush As New LinearGradientBrush(Layout, Color.Gainsboro, Color.Gray, 0)
g.FillPath(MetalBrush, gp)
g.DrawPath(Pens.Black, gp)
End Sub
End Class