I have another way - however, I do not have time to correctly explain this.
However, my example was written in .NET for use in a Windows application.
My version creates an entire speech bubble in the form of a 2D Polygon Mesh and is partially customizable. This is one way back instead of several parts.
While our platforms do not match, the method uses common mathematical procedures and a procedural cycle. I believe that this technique can be translated into other programming languages ββor platforms.
Private Sub Generate(ByVal Resolution As Integer, Optional ByVal SpeachPointerAngle As Integer = (45 * 3), Optional ByVal PointerBend As Decimal = 15) 'Generated the same way we create vector (wireframe) mesh for an Ellipse but... '... at a predefined defined angle we create 'the size of the Pointer TIP/Corner portion of the speach bubble 'in relation to the EDGE of the ELLIPSE (average) Dim SpeachPointerSize As Integer = 30 If PointerBend > 10 Then PointerBend = 10 If PointerBend < -10 Then PointerBend = -10 'as a variable offset that should be limited to max +/- -15 to 15 degrees relative to current angle as a safe range '- were speach pointer angle determins which side the the pointer appears Dim PointerOffsetValue As Decimal = PointerBend Dim ActualPointerAngle As Decimal 'SpeachPointerAngle = 360 - SpeachPointerAngle ' adjust orientation so that 0 degrees is SOUTH 'Ellipse Size: Dim Size_X As Decimal = 80 Dim Size_Y As Decimal = 50 If Resolution < 30 Then Resolution = 30 Dim Result As Vector2() 'size of each angle step based on resolution (number of vectors ) - Mesh Quality in otherwords. Dim _Step As Decimal = 360 / Resolution 'Our current angle as we step through the loop Dim _CurrentAngle As Decimal = 0 'rounded values Dim _LastAngle As Decimal = 0 Dim _NextAngle As Decimal = _Step Dim SpeachDrawn As Boolean = False ' prevent creating more than 1 point to be safe Dim I2 As Integer = 0 'need a stepper because of skipped IDS 'build the ellipse mesh For i = 0 To Resolution - 1 _LastAngle = _CurrentAngle - 15 _NextAngle = _CurrentAngle + 15 ActualPointerAngle = _CurrentAngle 'side ActualPointerAngle += PointerOffsetValue ' acual angle of point Dim EX As Decimal = System.Math.Cos(Math.Deg2Rad(_CurrentAngle)) * Size_X Dim EY As Decimal = System.Math.Sin(Math.Deg2Rad(_CurrentAngle)) * Size_Y 'Point extrusion size ( trying to be even size all around ) Dim ExtrudeX As Decimal = System.Math.Cos(Math.Deg2Rad(_CurrentAngle)) * (Size_X + SpeachPointerSize) Dim ExtrudeY As Decimal = System.Math.Sin(Math.Deg2Rad(_CurrentAngle)) * (Size_Y + SpeachPointerSize) 'is Pointer angle between Last and Next? If SpeachPointerAngle > _LastAngle And SpeachPointerAngle < _NextAngle Then If (SpeachDrawn = False) Then ' the point for the speachbubble tip Array.Resize(Result, I2 + 1) Result(I2) = New Vector2(ExtrudeX, ExtrudeY) SpeachDrawn = True I2 += 1 Else 'skip End If Else 'normal ellipse vector Array.Resize(Result, I2 + 1) Result(I2) = New Vector2(EX, EY) I2 += 1 End If _CurrentAngle += _Step Next _Vectors = Result End Sub
The above code generated this - drawn into a bitmap using GDI + [DrawPolygon / FillPolygon]: https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash4/380262_10151202393414692_590995900_n.jpg
(Sorry, I cannot post the image directly here, as I have never written here before. I have no reputation yet)
This is a primitive in the graphic assembly that I am developing for .NET that uses my own Vector2.
This speech bubble provides transparency when drawing - as it is one polygon shape instead of multiple shapes.
Basically, we draw an ellipse programmatically, and then extrude the selection point onto the desired side of the ellipse.
A similar approach can be applied using PointF structures.
All shapes in the code are generated around Origin 0,0.
Arrays also change in stages as vectors are added, preventing spaces in the array.
EG - center of speech bubble - Origin 0.0.
I apologize for not explaining my code correctly - I just don't have the time. But this is probably not too hard to understand.