VECTOR GRAPHICS

Today I want to share with all aspects of Object2D entities.
I’ve had enough too studied to be able to write a viewer for DXF files.

  1. Object2D degrees and radians are always fully clockwise and counterclockwise not as is normal in trigonometry.
  2. Unlike the CAD software for the origins are not at the point in the lower left but the point at the top left.

Some important commands:

The bow from two points.
With this memory method I can get an arc angle of 180 degrees.

Public Sub DrawArc2points(x1 as double, y1 as double, x2 as double, y2 as double, colore as color)
  Dim xDiff As Double
  dim yDiff as Double
  Dim Radius As Double
  Dim Centerx As double
  dim centery as double
  Dim angolo1 As Double
  dim angolo2 as Double
  dim a As Integer
  
  CenterX = (x1 + x2) / 2
  CenterY = (y1 + y2) / 2
  Radius = Sqrt((CenterX - x1) ^ 2 + (CenterY - y1) ^ 2)
  
  xDiff = CenterX - X1
  yDiff = y1 - CenterY
  
  If Abs(xDiff) < 0.00000001 Then xDiff = 0
  If Abs(yDiff) < 0.00000001 Then yDiff = 0
  
  If xDiff <> 0 Then
    angolo1 = Atan(yDiff / xDiff)
    If xDiff < 0 Then angolo1 = angolo1 + PI
  ElseIf yDiff < 0 Then
    angolo1 = 3 * PI / 2 '90
  Else
    angolo1 = PI / 2 '270
  End If
  If angolo1 < 0 Then angolo1 = angolo1 + PI * 2
  
  
  xDiff = CenterX - X2
  yDiff = Y2 - CenterY
  
  If Abs(xDiff) < 0.00000001 Then xDiff = 0
  If Abs(yDiff) < 0.00000001 Then yDiff = 0
  
  If xDiff <> 0 Then
    angolo2 = Atan(yDiff / xDiff)
    If xDiff < 0 Then angolo2 = angolo2 + PI
  ElseIf yDiff < 0 Then
    angolo2 = 3 * PI / 2 '90
  Else
    angolo2 = PI / 2 '270
  End If
  If angolo2 < 0 Then angolo2 = angolo2 + PI * 2
  
  angolo2 = atan2(sin(angolo2-angolo1), cos(angolo2-angolo1))
  
  dim angolop, angoloa as double
  
  dim ref as double
  if angolo2 > angolo1 then 
    ref = angolo1
    angolo1 = angolo2
    angolo2 = ref
  end if
  
  angolop = 2*PI - angolo2
  'angoloa = angles(0) - angles(1)
  'angolop = deg2rad(angolop)
  angoloa = deg2rad(180)
  
  ' do the results
  
  dim d as new ArcShape
  d.Fill = 0
  d.Border = 100
  d.x = Centerx
  d.y = Centery
  d.Width = radius * 2
  d.Height = Radius * 2
  d.StartAngle = angolop
  d.ArcAngle = angoloa
  
  primarydraw.Append d
 
End Sub

PLEASE NOTE:
the mathematical function below can be used to calculate the angle of the arc.
We know that it is 180 degrees.
However, all features found for VB.NET, C #, C ++ always report a startAngle and endAngle while xojo and we startAngle How big should our corner.

where angolo1 is STARTANGLE and angolo2 is ENDANGLE.

This other function find the radius of circle by three point :

[code]Public Function FindCircle(x1 as double ,y1 as double, x2 as double ,y2 as double ,x3 as double ,y3 as double) as double
// trova il raggio del cerchio in base a 3 punti

dim ax,ay,bx,by,cx,cy,y11,dx1,dy1,dx2,dy2,ox,oy,dx,dy as double
ax = x1
ay = y1 //first Point X and Y
bx = x2
by = y2 // Second Point X and Y
cx = x3
cy = y3 // Third Point X and Y
x1 = (bx + ax) / 2
y11 = (by + ay) / 2
dy1 = bx - ax
dx1 = -(by - ay)
x2 = (cx + bx) / 2
y2 = (cy + by) / 2
dy2 = cx - bx
dx2 = -(cy - by)
ox = (y11 * dx1 * dx2 + x2 * dx1 * dy2 - x1 * dy1 * dx2 - y2 * dx1 * dx2)/ (dx1 * dy2 - dy1 * dx2)
oy = (ox - x1) * dy1 / dx1 + y11
dx = ox - ax
dy = oy - ay
return sqrt(dx * dx + dy * dy)
End Function
[/code]

This other draw an arc with 2 point coords and bulge;
when bulge is + signed arc is in clockwise
when bulge is - signed arc is in anticlockwise

Public Sub Gotbulge(x1 as Double, y1 as Double, x2 as Double, y2 as Double, bulge as double, colore as Color)
  Dim dx As Double
  Dim dy As Double
  Dim xmid As Double
  Dim ymid As Double
  Dim l As Double
  Dim r As Double
  Dim a As Double
  Dim sb As Double
  Dim cx As Double
  Dim cy As Double
  Dim theta_p As Double
  Dim theta_c As Double
  
  'y1 = -y1
  'y2 = -y2
  
  dx = x1 - x2
  dy = y1 - y2
  xmid = dx / 2 + x2
  ymid = dy / 2 + y2
  
  l = Sqrt((dx^2) + (dy^2)) 'linelength from point 1 to point 2
  r = Abs(l * ((bulge * bulge) + 1) / bulge / 4) 'Radius circle
  
  a = Abs(bulge * l / 2)
  sb = bulge / Abs(bulge)
  theta_p = 4 * Atan(bulge)
  
  If dx <> 0 Then
    theta_c = Atan(dy / dx)
  Else
    theta_c = PI / 2
  End If
  
  If dx > 0 Then
    sb = sb * -1
  End If
  
  cx = xmid + sb * (r - a) * Sin(theta_c) 'centerpoint X
  cy = ymid - sb * (r - a) * Cos(theta_c) 'centerpoint Y
  
  Dim angle1 As Double
  Dim angle2 As Double
  
  angle1 = atan2(y1-cy, x1-cx) 'angle 1
  angle2 = atan2(y2-cy, x2-cx) 
  
  angle2 = atan2(sin(angle2-angle1), cos(angle2-angle1))
  
  dim d as new ArcShape
  d.Fill = 0
  d.Border = 100
  d.x = cx
  d.y = cy
  d.Width = r * 2
  d.Height = r * 2
  d.StartAngle = angle1
  d.ArcAngle = angle2
  
  primarydraw.Append d
End Sub

PLEASE NOTE:
there is always the function that returns the size of the angle …

and obviously calculate degrees to radians and vice versa

Public Function deg2rad(deg As Double) as Double
  Return (deg * PI / 180.0)
End Function

Public Function rad2deg(rad as Double) as double
  Return rad / PI * 180.0
End Function

… OK, it’s moment of add other function …
This funct return then hyperbolic sine of Z

Private Function Sinh(z As Double) as Double
  'Ritorna il seno iperbolico di z:
  return (Exp(z) - Exp(-z)) / 2
End Function

And hiperbolic cosine of Z
Private Function Cosh(z As Double) as Double
  ' Ritorna il coseno iperbolico di z:
  Return (Exp(z) + Exp(-z)) / 2
End Function

When you translate funct from other languages, or/and other systems you might collide with the problem that the corners are reflected in different quadrants.
This is because some programming languages, in particular for vector graphics functions angles are run counterclockwise and not as XOJO clockwise.

NB: 0 value isn’t in upper corner but in right corner !!!

for transform angle use this simple command
if use RADIANT

angle = 2*pi - angle 

If use DEGREES

angle = 360 - angle

NB: Some operating systems origins depart from the lower left instead of in the upper left corner of XOJO then all points on the Y coordinate will be reversed.
Can use Y = -Y or a little function more elegant

Private Function invertix(y as double) as double
  return canvas.Height - y
End Function

tomorrow or the day after put quadratic bezier curve, and aproximated bezier…

Nice share. Would it be possible to have project with all methods :slight_smile:

Great work

Ok Here’s the file with trigonometric calculation functions and about 20 of the most famous curves

https://drive.google.com/open?id=0B__n5_gaxcjINjRCUFNnOThUSkE

Curve sample…


Very useful. Thanks for sharing