27 July, 2023

Shapes Based On Parametric Equations: Hypocycloids

Hypocycloid is a parametric curve traced by a fixed point on a circle that rolls on the interior of another larger circle. 

The curve - due to its parametric functionality - finds many applications, both theoretical and practical. They include mechanical and construction engineering, e.g. design of gears, cams, valves, robotics (motion planning), and machine/structures design in general. Contribute also to aesthetically pleasing art designs and animations.

The hypocycloid curves can be generated quite easily in Excel with VBA macro,  presented at the end of this post. Here are some examples of charts with generated hypocycloid curves, both single and combined double curves:

You can try to use the macro for your own specific needs. Just copy it to one of the modules in your workbook sheets and experiment with different settings and parameters.

Sub CreateHypocycloidChart()
'Creates a scatter chart object, sets the chart type, and assigns calculated X and Y values to the chart series.
Dim i As Integer, numPoints As Integer
Dim a As Long, b As Long
Dim a1 As Long, b1 As Long
Dim chartObj As ChartObject
Dim oChart As Chart
Dim xValues() As Double, yValues() As Double
Dim xvValues() As Double, yvValues() As Double
Dim tit As String
'Define the number of data points and calculate X and Y values
numPoints = 800    'Change as needed
ReDim xValues(1 To numPoints)
ReDim yValues(1 To numPoints)
ReDim xvValues(1 To numPoints)
ReDim yvValues(1 To numPoints)

'Set random parameters a,b,a1,b1 within predefined limits
b = WorksheetFunction.RandBetween(1, 30): a = b * WorksheetFunction.RandBetween(1, 10)
b1 = WorksheetFunction.RandBetween(1, 30): a1 = b1 * WorksheetFunction.RandBetween(1, 10)
'To set and use your own parameters for the curves, remove the apostrophe in the next line
‘a = 20: b = 5: a1 = 28: b1 = 4
'Calculate X and Y values using your equations
For i = 1 To numPoints   'First series
    xValues(i) = (a - b) * Cos(WorksheetFunction.Radians(i)) + b * Cos(WorksheetFunction.Radians((a - b)) / b * i)
    yValues(i) = (a - b) * Sin(WorksheetFunction.Radians(i)) - b * Sin(WorksheetFunction.Radians((a - b)) / b * i)
Next i
For i = 1 To numPoints   'Second series
    xvValues(i) = (a1 - b1)*Cos(WorksheetFunction.Radians(i)) + b1*Cos(WorksheetFunction.Radians((a1-b1)) / b1*i)
    yvValues(i) = (a1 - b1)*Sin(WorksheetFunction.Radians(i)) - b1*Sin(WorksheetFunction.Radians((a1 - b1)) / b1*i)
Next i
'Create a new chart object
Set chartObj = ActiveSheet.ChartObjects.Add(Top:=10, Left:=100, Width:=600, Height:=600)
Set oChart = chartObj.Chart
oChart.ChartType = xlXYScatter      'Set the chart type to scatter chart
'Set X and Y values for the chart series
    chartObj.Chart.SeriesCollection(1).Values = yValues
    chartObj.Chart.SeriesCollection(1).xValues = xValues
    chartObj.Chart.SeriesCollection(2).Values = yvValues
    chartObj.Chart.SeriesCollection(2).xValues = xvValues
'The code below formats the chart and plot area; can be modified as needed
    ActiveChart.SetElement (msoElementPrimaryCategoryAxisTitleAdjacentToAxis)
    ActiveChart.SetElement (msoElementPrimaryValueAxisTitleAdjacentToAxis)
    ActiveChart.SetElement (msoElementPrimaryValueGridLinesNone)
    ActiveChart.SetElement (msoElementPrimaryCategoryGridLinesNone)
'Add chart title and title of the axes
    oChart.Axes(xlCategory).HasTitle = True
    oChart.Axes(xlCategory).AxisTitle.Caption = "X values"
    oChart.Axes(xlValue).HasTitle = True
    oChart.Axes(xlValue).AxisTitle.Caption = "Y values"
    oChart.HasTitle = True
    tit = "Epicycloid " & a & "-" & b & ", " & a1 & "-" & b1
    oChart.ChartTitle.Text = tit
    With Selection.Font
        .Bold = msoTrue
        .Size = 14
    End With
    With Selection.Format.Line
        .Visible = msoTrue
        .Weight = 0.25
    End With
    With Selection.Format.Fill
        .Visible = msoTrue
        .ForeColor.RGB = RGB(255, 255, 200)
    End With
    Selection.MarkerStyle = 8
    Selection.MarkerSize = 5
    Selection.Format.Fill.ForeColor.RGB = RGB(192, 0, 0)
    Selection.Format.Line.Visible = msoFalse
    Selection.MarkerStyle = 8
    Selection.MarkerSize = 5
    Selection.Format.Fill.ForeColor.RGB = RGB(192, 0, 100)
    Selection.Format.Line.Visible = msoFalse
    With Selection.Format.Line
        .Visible = msoTrue
        .ForeColor.RGB = RGB(0, 112, 192)
        .Weight = 1
    End With
End Sub

No comments:

Post a Comment

All comments are held for moderation. I reserve the right to edit, censor, delete and - if necessary - block comments.