Results 1 to 3 of 3

Thread: Completely Stumped with Hexagons :(

  1. #1

    Thread Starter
    New Member
    Join Date
    Jul 2006
    Posts
    2

    Question Completely Stumped with Hexagons :(

    Ok, I've been trying to do this for far longer than I care to admit, but its obvious even though I CLEPed geometry and trigonometry my understanding of it is pretty pathetic.

    I've successfully made hexmaps with the point up, and the point on the side, and drew them in various scales. I've also got pretty darned reliable pixel to hexagon routines for both. BUT, I have no way to really rotate it and do exactly what I want real time :(

    Basically, I'm trying to make a hexmap that is actually a portion of a larger map, is scrollable, and can be rotated any angle and scaled any scale.

    I will be providing the following information:
    W (Total width of a hex)
    H (Total height of a hex)
    P (Width of the hex part)
    A (Angle of rotation for the entire MAP (NOT each individual hex))
    S (Scale of the map/hex, .5=half, 2=double)
    R (Row of the hex)
    C (Column of the hex)
    X (X offset of the MAP)
    Y (Y offset of the MAP)

    And I need it to return the pixel's X and Y location for the upper left hand point of the hexagon square (basically a point in space at the upper left hand portion of the hex, so I can blt stuff to it later).

    I also need a function that takes the above information, PLUS the pixel X/Y coordinates and returns the hexagon row and column.

    This allows me to have any shape of hexagon and a map that can rotate any angle. I am basically creating a map of a planet with 10km accuracy (roughly 8mb per pixel) where each pixel is a sector of around 10km (1024 pixel square, as each pixel is a 10m "hex"). A texture will be drawn in the background and a hexagonal grid will overlay it (thus it won't look like a crappy hexmap). There will be another file that determines the predominate terrain in each hex, as well as another for altitude (earth would be around 50mb total for this, plus up to 250GB for 65000 unique 10km sectors). Each of these maps will be a bitmap sorta format where a sector is pulled (or up to 4 if your on a corner) and the particular area drawn thats necessary.

    I know I'm asking a lot, but I've tried for a LONG time to get this and have never gotten it to the point I could consider it a "production" piece of code. I don't care if its in VB, C, C#, Java, ASM, whatever (ASM would be nice!) but just want it to work. If you know how to do it and just dont wanna help cause I'm basically asking somebody else to write 2 functions for me, I'd be happy to share anything else I have or perhaps even pay (need a new $50 computer book?).

    I'm trying to do a generic hexagonal game engine that'll have plugins for a HUGE # of board games out there. But I need the code to be very versatile and modular and allow quick coding of the game engines. I'm going to *try* to do it with the .NET GDI to avoid any 3D dependencies, but DX may have to be used if I can't get the 3 layers plus borders and such drawn quick enough (with maybe 2500 hexes on screen max).

    Anyway, thanks for any help you can provide (I've already searched here and all over google with no avail) as I'm pretty darned desparate at this point.



    ...<--------W------->
    ................<-P->
    ^...../``````````\
    |..../............\
    |.../..............\
    |../................\
    H..\................/
    |...\............../
    |....\............/
    |.....\__________/
    V

  2. #2
    New Member
    Join Date
    Mar 2011
    Posts
    1

    Re: Completely Stumped with Hexagons :(


    Public Class Form1
    Private Sub ShapeMakerForm_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    Dim yellowBrush As New SolidBrush(Color.Yellow)
    Dim WidthX = 100.0 'Width
    Dim HeightY = 100.0 'Height
    Dim LocX = 125.0 'Width
    Dim LocY = 125.0 'Height
    Dim v As Integer = CInt(WidthX / 2 * Math.Sin(30 * Math.PI / 180))
    Dim point1 As New Point((WidthX \ 2) + LocX, 0 + LocY)
    Dim point2 As New Point(WidthX + LocX, v + LocY)
    Dim point3 As New Point(WidthX + LocX, (HeightY - v) + LocY)
    Dim point4 As New Point((WidthX \ 2) + LocX, HeightY + LocY)
    Dim point5 As New Point(0 + LocX, (HeightY - v) + LocY)
    Dim point6 As New Point(0 + LocX, v + LocY)
    Dim curvePoints As Point() = {point1, point2, point3, point4, point5, point6}
    e.Graphics.FillPolygon(yellowBrush, curvePoints)
    End Sub
    End Class

  3. #3
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: Completely Stumped with Hexagons :(

    TonyMan's code is very inadequate. At most it appears to draw a single hexagon, though I'd have to inspect it more to say that for sure. Anywho, the first function you want is in the attached VB6 project. The code quality isn't great, but it's easy to translate and improve upon. I'm pasting it in this post as well in case you don't have a VB6 IDE. In that case it should still be fairly self-explanatory. If you have questions about the math or trig please ask.

    Code:
    Dim OldAngle
    
    Private Sub PrintDot(W, H, P, A, S, R, C, X, Y)
    '1. Find unrotated, unscaled hexagon center
    Cx = W / 2 + C * (W - P)
    Cy = H / 2 + R * H
    If C Mod 2 = 1 Then
        Cy = Cy + H / 2
    End If
    
    '2. Move to upper left corner of hexagon from the center
    Cx = Cx - W / 2
    Cy = Cy - H / 2
    
    '3. Calculate the point about which rotation and scaling takes place
    '   This could be passed in place of the X and Y variables, though scrolling
    '   then becomes harder than just adding to X or Y.
    nX = (X) * Cos(-A) - (Y) * Sin(-A)
    nY = (X) * Sin(-A) + (Y) * Cos(-A)
    
    '4. Move the origin to rotate about the above center of rotation and scaling
    Cx = Cx - nX
    Cy = Cy - nY
    
    '4. Apply global scaling
    Cx = Cx * S
    Cy = Cy * S
    
    '5. Apply global rotation
    '   2D rotation matrix:
    '    [cos A  -sin A][Cx] = [Cx * cos A - Cy * sin A]
    '    [sin A   cos A][Cy]   [Cx * sin A + Cy * cos A]
    Tx = Cx * Cos(A) - Cy * Sin(A)
    Ty = Cx * Sin(A) + Cy * Cos(A)
    Cx = Tx
    Cy = Ty
    
    '6. Center the point on the middle of the screen instead of the upper left corner
    Cx = Cx + Me.Width / 2
    Cy = Cy + Me.Height / 2
    
    '(Cx, Cy) is the value you want. Do something with it.
    Me.Circle (Cx, Cy), 60, vbRed
    End Sub
    
    Private Sub RedrawGrid()
    'Random example
    Me.Cls
    
    For R = 0 To 10
    For C = 0 To 10
        PrintDot 700, 500, 150, sldAngle.Value * 3.14159 / 180, sldScale.Value / 10, R, C, sldOffsetX.Value, sldOffsetY.Value
    Next C
    Next R
    End Sub
    
    Private Sub sldAngle_Change()
    'Modify X and Y so that the center of rotation is unchanged.
    'Need to keep around the previous angle so that we can (implicitly) compute
    ' the center of rotation and scaling.
    NewAngle = sldAngle.Value * 3.14159 / 180
    X = sldOffsetX.Value
    Y = sldOffsetY.Value
    
    Tx = X * Cos(NewAngle - OldAngle) - Y * Sin(NewAngle - OldAngle)
    Ty = X * Sin(NewAngle - OldAngle) + Y * Cos(NewAngle - OldAngle)
    
    sldOffsetX.Value = Tx
    sldOffsetY.Value = Ty
    
    RedrawGrid
    
    OldAngle = sldAngle.Value * 3.14159 / 180
    End Sub
    
    Private Sub sldOffsetX_Change()
    RedrawGrid
    End Sub
    
    Private Sub sldOffsetY_Change()
    RedrawGrid
    End Sub
    
    Private Sub sldScale_Change()
    RedrawGrid
    End Sub
    I haven't done the second routine. Ideally you would be able to do it by inverting the logic above, but that could be difficult. If you need help with that I can write something.
    Attached Files Attached Files
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width