Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1530

VB6 Cairo-Paths and Projections

$
0
0
The Demo shows, how to create Path-Objects via simple helper-functions (of return-type cCairoPath) -
and how to "Append" and then "Stroke" these Paths via similar named methods on a cCairoContext.

I guess, this is also a topic for "Makers" (Laser-Cutting, 3D-Printing)...

Simple Path-construction-functions as e.g.:
- a path for a single tooth of a gear (or its horizontal expansion via loop)
- or a single path for a curve, or a circle
are relatively easy to "code by hand".

But what if e.g. a "horizontal line of teeth" (as used on a "rack") needs to follow a curved- or circular track?
Such "combined complex paths" are difficult to "define by hand" -
and that's where the second part of the Demo comes into play:
showing how one can project one path in a way, so that it "follows" another Path.

E.g. if you look at the 1st ScreenShot here, which shows the Demo after it was just starting up:
(showing the "yet un-projected two Paths" which we've generated, a "horizontal line of teeths" and "a circle"):
Name:  PathProjection1.png
Views: 29
Size:  43.3 KB

Ok, now - with a single Method-call (ProjectPathData) on the cairo-context, we can combine the two paths
(producing a combined path for a "42-teeth-gear"):
Name:  PathProjection2.png
Views: 26
Size:  39.1 KB

Third and last image is just showing, that any (horizontally designed) Path-Renderings -
can be projected onto any other (arbitrary) path or curve.
Name:  PathProjection3.jpg
Views: 26
Size:  42.7 KB

Here is the code for a single (empty) Form-Project (which needs a reference to RC6):
Code:

Option Explicit

Const TeethCount = 42, TeethHeight = 5, SinglePeriodDistance = 12

Private CC As cCairoContext, WithEvents Btn As VB.CommandButton
 
Private Sub Form_Load()
  Set Btn = Controls.Add("VB.CommandButton", "Btn") 'add a checkbox dynamically
      Btn.Caption = "Project teeth to circular Path": Btn.Visible = 1
     
  Move Left, Top, ScaleX(590, vbPixels, vbTwips), ScaleY(320, vbPixels, vbTwips)
End Sub

Private Sub Form_Resize() 'the usual lines, to keep CC as a "Form-covering-context
  ScaleMode = vbPixels: Set CC = Cairo.CreateSurface(ScaleWidth, ScaleHeight).CreateContext
  RefreshDrawings False
End Sub

Private Sub Btn_Click()
  RefreshDrawings
  Btn.Caption = "Project teeth to " & IIf(InStr(Btn.Caption, "curved"), "circular Path", "curved Path")
End Sub

Private Sub RefreshDrawings(Optional ByVal UseProjection As Boolean = True)
  CC.Paint 1, Cairo.CreateCheckerPattern
 
  Dim PPath As cCairoPath: Set PPath = CreateProjectionPath()
  Dim TPath As cCairoPath: Set TPath = CreateTeethPath()
 
  If UseProjection Then TPath.ProjectPathData_Using PPath '<- here's where the magic happens (TPath will now "follow along" PPath)

  CC.Save '<- isolates the render-output of our two paths...
    CC.TranslateDrawings 55, 55 '...because we use a transform (here only, to provide some shifting)
   
    RenderStrokedPath PPath, 1, vbBlue
    RenderStrokedPath TPath, 2, vbRed
  CC.Restore
 
  Set Picture = CC.Surface.Picture
End Sub

Sub RenderStrokedPath(Path As cCairoPath, Optional ByVal LineWidth& = 1, Optional ByVal Color&)
  CC.AppendPath Path 'add the Projection-Path to the context
  CC.SetLineWidth LineWidth
  CC.Stroke , Cairo.CreateSolidPatternLng(Color)
End Sub

Function CreateProjectionPath() As cCairoPath
  Dim PC As cCairoContext
  Set PC = Cairo.CreateSurface(1, 1).CreateContext 'ensure a "Projection-Context"
 
  If InStr(Btn.Caption, "curved") Then
    PC.CurveTo 0, 0, 90, 0, 190, 120
    PC.RelCurveTo 120, 150, 90, 0, 190, -66
  Else
    PC.Arc 80, 100, (TeethCount * SinglePeriodDistance) / (2 * Cairo.PI)
  End If

  Set CreateProjectionPath = PC.CopyPath(True) 'return the resulting path
End Function

Function CreateTeethPath(Optional ByVal StepsPerToothPeriod& = 32) As cCairoPath
  Dim PC As cCairoContext, i As Long, j As Long, x As Double, y As Double
  Set PC = Cairo.CreateSurface(1, 1).CreateContext 'ensure a "Projection-Context"
 
  PC.MoveTo 0, 0 'ensure a valid starting-point for the (horizontal to the right) teeth-renderings
 
  For i = 1 To TeethCount 'repeat the whole thing, according to our TeethCount-constant
      AddSingleToothTo PC, x, y, StepsPerToothPeriod
  Next
 
  Set CreateTeethPath = PC.CopyPath(True) 'return the resulting path
End Function

Sub AddSingleToothTo(PC As cCairoContext, x, y, StepsPerToothPeriod)
  Dim i As Long
  For i = 1 To StepsPerToothPeriod 'this loop is a generator for a simpe, single "SinusTooth"
      x = x + SinglePeriodDistance / StepsPerToothPeriod
      y = Sin(i / StepsPerToothPeriod * 2 * Cairo.PI) * TeethHeight
      PC.LineTo x, -y
  Next
End Sub

Have fun,

Olaf
Attached Images
   

Viewing all articles
Browse latest Browse all 1530

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>