# RhPicture Plug-in Geometry Drawing Routines

Summary: A description of geometry drawing calls as exposed through the RhPicture plug-in

## The general syntax for drawing geometric primitives

RhPicture supports the drawing and filling of several geometric primitives, and the function calls are all very similar. All Draw methods can be used to draw the outlines of geometry and they accept (apart from the essential data that defines the primitive) either a GDI+ Pen object or a GDI Color + Width combo. All Fill methods can be used to paint the contents of geometry and they accept either a GDI Brush object or a single GDI Color.

When drawing geometry you have to use the Image coordinate system. This is a floating point system which is infinite in all directions (though large numbers can cause overflow errors). The origin of the system is located at the upper-left pixel (0,0) and every system unit represents a single pixel. The highest value on the bitmap is (width-1, height-1) and anything drawn beyond this will not be visible.

It is possible in GDI+ to apply a linear transformation to a drawing pipeline, but this feature has not yet been exposed in the RhPicture plug-in.

## Drawing lines, polylines and curves

Lines, polylines and curves are essentially defined by an array of 2D bitmap coordinates. Drawing lines is the simplest example since it doesn't involve variable arrays:

```Dim RhPicture : Set RhPicture = Rhino.GetPluginObject("RhPicture")
Call RhPicture.CreateImage(50, 50, vbWhite)
Call RhPicture.DrawLine(Array(10, 30), Array(40, 10), vbBlack, 4)```

Polylines and curves take an array of 2D points instead of two singular coordinates. When the distance between the first and last point in the array is less than one tenth of a pixel, the polyline/curve is considered closed and no end caps will be drawn. When drawing line geometry, you can also use GDI Pen objects:

```RhPicture.DrawLine(A As Point, B As Point, Col As GDIColor [, Width As Double])
RhPicture.DrawLine(A As Point, B As Point, Pen As GDIPen)
RhPicture.DrawPolyline(Pts() As Point, Col As GDIColor [, Width As Double])
RhPicture.DrawPolyline(Pts() As Point, Pen As GDIPen)
RhPicture.DrawCurve(Pts() As Point, Col As GDIColor [, Width As Double])
RhPicture.DrawCurve(Pts() As Point, Pen As GDIPen)```

Note! The current version of the plug-in does not accept variables which are declared as arrays. You have to box these before calling procedures like DrawPolyline():

```Dim vertices()
'Create a polyline vertex array here
Dim v : v = vertices
Call RhPicture.DrawPolyline(v, vbBlack)```

Drawing the content of polylines and curves requires the same coordinates but the functions are called differently:

```RhPicture.FillPolyline(Pts() As Point, Col As GDIColor)
RhPicture.FillPolyline(Pts() As Point, Brush As GDIBrush)
RhPicture.FillCurve(Pts() As Point, Col As GDIColor)
RhPicture.FillCurve(Pts() As Point, Brush As GDIBrush)```

If the coordinates do not define a closed shape, the shape will be closed with a single linear segment. Instead of GDI Pen objects, Fill routines accept GDI Brush objects.

## Drawing primitives

You can also draw rectangles, circles, and ellipses directly. They work similar to the other drawing methods. Note the difference in coordinate specification between ellipses and circles though:

```RhPicture.DrawRectangle(Corner As Point, Width As Double, Height As Double, Col As GDIColor [, Width As Double])
RhPicture.DrawRectangle(Corner As Point, Width As Double, Height As Double, Pen As GDIPen)
RhPicture.DrawEllipse(Corner As Point, Width As Double, Height As Double, Col As GDIColor [, Width As Double])
RhPicture.DrawEllipse(Corner As Point, Width As Double, Height As Double, Pen As GDIPen)
RhPicture.DrawCircle(Center As Point, Radius As Double, Col As GDIColor [, Width As Double])
RhPicture.DrawCircle(Center As Point, Radius As Double, Pen As GDIPen)```

and…

```RhPicture.FillRectangle(Corner As Point, Width As Double, Height As Double, Col As GDIColor)
RhPicture.FillRectangle(Corner As Point, Width As Double, Height As Double, Brs As GDIBrush)
RhPicture.FillEllipse(Corner As Point, Width As Double, Height As Double, Col As GDIColor)
RhPicture.FillEllipse(Corner As Point, Width As Double, Height As Double, Brs As GDIBrush)
RhPicture.FillCircle(Center As Point, Radius As Double, Col As GDIColor)
RhPicture.FillCircle(Center As Point, Radius As Double, Brs As GDIBrush)```

## Drawing strings

Text is drawn using a single overloaded method:

```RhPicture.DrawString(Text As String, Pt As Point)
RhPicture.DrawString(Text As String, Pt As Point, F as GDIFont)
RhPicture.DrawString(Text As String, Pt As Point, F as GDIFont, Col As GDIColor [, Angle As Double])
RhPicture.DrawString(Text As String, Pt As Point, F as GDIFont, Brs As GDIBrush [, Angle As Double])
RhPicture.DrawString(Text As String, Pt As Point, FontName as String)
RhPicture.DrawString(Text As String, Pt As Point, FontName as String, Col As GDIColor [, Angle As Double])
RhPicture.DrawString(Text As String, Pt As Point, FontName as String, Brs As GDIBrush [, Angle As Double])```

 Parameter Type Description Text String The text to draw. Pt 2D Point The point where the text starts (lower left corner of the baseline) F GDIFont A GDI Font object. FontName String The name of a font family. Col GDIColor The color of the text. Brs GDIBrush A GDI Brush object that defines the fill of the text. Angle Double An angle (in degrees, counter clockwise) that controls the rotation of the text around the basepoint.

## Drawing Images

It's also possible to draw images on top of other images. This allows a number of possibilities which are not possible with texture brushes:

• Scaling of images
• Alpha multipliers
• Blending modes

There are two distinct ways of drawing images in the RhPicture plug-in. The simplest one is very similar to drawing rectangles, except for brushes you have to supply the path to an image file on the disk:

```RhPicture.DrawImage(FileName As String)
RhPicture.DrawImage(FileName As String, Corner As Point [, Width [, Height [, Quality [, Alpha [, Mask]]])```

 Parameter Type Description FileName String The path to an image file on the disk. Corner 2D Point The upper-left corner of the image. Width Double The width of the drawn image in pixel units. If omitted then the actual width is used. Height Double The height of the drawn image in pixel units. If omitted then the actual height is used. Quality Integer The Inteprolation Enumaration of the resampling operation. If the drawn image has to be scaled this value is used. See table below for valid values. Alpha Double A value indicating the opacity of the drawn image. 0.0 means it will be completely transparant, 1.0 means completely opaque. This value is multiplied by the actual alpha channel information in the image, meaning it is still possible to drawn semi-transparant pixels when Alpha equals 1.0 Mask GDI Color A GDI Color that sets the mask-color of the image. This can be used to make single color backgrounds transparent.

 Quality Interpolation constants. Nearest Neighbour Bilinear Bicubic Quality = 0 Quality = 1 Quality = 2

The second way to draw images is to use the Merge methods in RhPicture. Instead of pasting the new image on top of the old one the Merge method performs a per-pixel comparison. The final result is usually a combination of the input pixels. This means that the overlay image cannot be drawn in a different size since that would break the 1-to-1 pixel relationship between the images. You can however specify the upper-left corner of the overlay and the blending mode to be used:

```RhPicture.Merge(Other As RhPicture [, Style As Integer [, Corner As Point]])
RhPicture.Merge(FileName As String [, Style As Integer [, Corner As Point]])```

As you can see you either use an existing image file on the disk or another (not the same, NEVER the same!) instance of the RhPicture plug-in. I'll explain the blendings styles by example. We'll be merging image B with image A:

 ««<

 Merge style enumeration Multiply = 0 Addition = 1 Subtraction = 2 Average = 3 Min = 4 Max = 5

 Blend styles explained Style Description Multiply The unitized channel values {0.0~1.0} are multiplied together, giving the impression of viewing the base image through a pane of tinted glass. The image can only become darker. Addition The RGB values are added together and then clipped back to the {0~255} range. The image can only become brighter. Subtraction The RGB values in the overlay images are subtracted from the RGB values in the base image. The image can only become darker. Average All RGB channels are averaged. Min The final RGB channels contain the lowest values of both sets. Max The final RGB channels contain the highest values of both sets.