-----------------------------
\
\
\.
Public Class segment Private _P1 As PointF Private _P2 As PointF Public c As Double 'y = cx+d Public d As Double 'd = y - cx Private _Translation As SizeF Public Sub New(ByVal P1 As PointF, ByVal P2 As PointF, ByVal Translation As SizeF) _Translation = Translation _P1 = P1 + Translation _P2 = P2 + Translation If (_P2.X - _P1.X) = 0 Then c = 0 Else c = (_P2.Y - _P1.Y) / (_P2.X - _P1.X) End If d = _P1.Y - (_P1.X * c) End Sub Public Function Intersection(ByVal a As Double, ByVal b As Double) As PointF Dim retour As New PointF If c = 0 Then ' 2 cotés sont horizontaux (résoudre l 'intersection par les y) retour.X = CSng(_P1.X) retour.Y = CSng(_P1.X / a) ElseIf d = 0 Then ' 2 cotés sont verticaux (résoudre l 'intersection par les x) retour.Y = CSng(_P1.Y) retour.X = CSng((_P1.Y - b) / a) Else 'quelconque If c <> a And a <> 0 Then retour.X = CSng((d - b) / (a - c)) 'x = (d -b)/(a-c) retour.Y = CSng(a * retour.X + b) Else : retour = Nothing End If End If ' Ne pas oublier de faire une translation inverse sur les points trouvés et ensuite vérifier que le résultat appartient ' au segment des cotés (un rectangle.contains peut faire l'affaire) Dim ok As Boolean = False If Not (retour.X >= _P1.X Xor retour.X <= _P2.X) Then If Not (retour.Y >= _P1.Y Xor retour.Y <= _P2.Y) Then ok = True End If If Not IsNothing(retour) And ok Then Return retour - _Translation Else : Return Nothing End If End Function End Class Qu'on utiliserai comme ceci: Dim a As New segment(New PointF(7, 0), New PointF(7, 7), New SizeF(-4, -3)) ' point d'un coté + origine des rayons 'Pour angle de -Pi a +Pi Dim Ang as double=b = sin (angle) / cos (angle) Dim R As PointF = a.Intersection(ang, 0) ' Equation d'un rayon
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionle premier segment R = W1
______w1______________
|
|
0 .__R_____________ |
\x |
R1---> \ |
\ |
\ | H1
\ |
\ |
\ |
\ |
Tx et Ty
Public Class segment2 Public R1 As PointF ' les 2 coins du rectangle Public R2 As PointF ' les 2 coins du rectangle Public T As SizeF ' le centre des rayons Public Segm As New List(Of PointF) ' Le retour des points calculés ' Initialisation de la class Public Sub New(ByVal C1 As PointF, ByVal C2 As PointF, ByVal Translation As SizeF, ByVal Portions As Double) T = Translation : R1 = C1 - T : R2 = C2 - T For Angle As Double = -Math.PI To Math.PI Step Math.PI / Portions Dim a As Double = Math.Tan(Angle) Calcul(a, R1.X, False) ' Calcul selon les 4 cotés et leurs inclinaisons Calcul(a, R1.Y, True) Calcul(a, R2.X, False) Calcul(a, R2.Y, True) Next End Sub Public Sub Calcul(ByRef a As Double, ByRef Alpha As Single, ByRef Horizontal As Boolean) Dim ok As Boolean = False, Pt As PointF If Horizontal Then Pt = New PointF(CSng(Alpha / a), Alpha) If Not (Pt.X >= R1.X Xor Pt.X <= R2.X) Then ok = True Else Pt = New PointF(Alpha, CSng(Alpha * a)) If Not (Pt.Y >= R1.Y Xor Pt.Y <= R2.Y) Then ok = True End If If ok Then Segm.Add(Pt + T) End Sub End Class
Dim a As New segment2(New PointF(200, 200), New PointF(400, 400), New SizeF(350, 350), 16) ' les 2 coins du rectangle , le centre des rayons, le nombre de rayons For Each Seg As PointF In a.Segm ' Trace le segment de (350, 350) au Point Seg Next
Option Explicit Private Type COORD x As Single y As Single End Type Dim p1 As COORD Dim p2 As COORD Dim xc As Integer Dim yc As Integer Const PI As Double = 3.14159265358979 Const PId16 As Double = PI / 16 Private Sub Form_Activate() p1.x = 20: p1.y = 20 p2.x = 500: p2.y = 500 xc = 200: yc = 200 Me.Line (p1.x, p1.y)-(p2.x, p2.y), vbRed, B Call CERCLE End Sub Private Sub CERCLE() Dim a As Single Dim angle As Single For angle = -PI To PI Step PId16 a = Sin(angle) / Cos(angle) Call CALCUL(a, p1.x, False) Call CALCUL(a, p1.y, True) Call CALCUL(a, p2.x, False) Call CALCUL(a, p2.y, True) Next angle End Sub Private Sub CALCUL(a As Single, alpha As Single, droit As Boolean) Dim pt As COORD Dim ok As Boolean If droit Then pt.x = alpha / a pt.y = alpha If Not (pt.x >= p1.x Xor pt.x <= p2.x) Then ok = True Else pt.x = alpha pt.y = alpha * a If Not (pt.y >= p1.y Xor pt.y <= p2.y) Then ok = True End If If ok Then Me.Line (xc, yc)-(pt.x, pt.y) End Sub
Option Explicit
Private Type COORD
x As Single
y As Single
End Type
Dim p1 As COORD
Dim p2 As COORD
Dim pp1 As COORD
Dim pp2 As COORD
Dim xc As Integer
Dim yc As Integer
Const PI As Double = 3.14159265358979
Const PId16 As Double = PI / 16
Private Sub Form_Activate()
p1.x = 20: p1.y = 20
p2.x = 500: p2.y = 500
xc = 200: yc = 200
Me.Line (p1.x, p1.y)-(p2.x, p2.y), vbRed, B
Call CERCLE
End Sub
Private Sub CERCLE()
Dim a As Single
Dim angle As Single
pp1.x=p1.x-xc
pp1.y=p1.y-yc
pp2.x=p2.x-xc
pp2.y=p2.y-yc
For angle = -PI To PI Step PId16
a = Tan(angle)
Call CALCUL(a, pp1.x, False)
Call CALCUL(a, pp1.y, True)
Call CALCUL(a, pp2.x, False)
Call CALCUL(a, pp2.y, True)
Next angle
End Sub
Private Sub CALCUL(a As Single, alpha As Single, droit As Boolean)
Dim pt As COORD
Dim ok As Boolean
If droit Then
pt.x = alpha / a
pt.y = alpha
If Not (pt.x >= pp1.x Xor pt.x <= pp2.x) Then ok = True
Else
pt.x = alpha
pt.y = alpha * a
If Not (pt.y >= pp1.y Xor pt.y <= pp2.y) Then ok = True
End If
If ok Then Me.Line (xc, yc)-(pt.x + xc, pt.y + xy)
End Sub
Public Class segment Private _P1 As PointF Private _P2 As PointF Public c As Double 'y = cx+d Public d As Double 'd = y - cx Private _Translation As SizeF Public Sub New(ByVal P1 As PointF, ByVal P2 As PointF, ByVal Translation As SizeF) _Translation = Translation : _P1 = P1 - Translation : _P2 = P2 - Translation If (_P2.X - _P1.X) = 0 Then c = Double.MaxValue : d = _P1.Y Else c = (_P2.Y - _P1.Y) / (_P2.X - _P1.X) d = _P1.Y - (_P1.X * c) End If End Sub Public Function Intersection(ByVal a As Double, ByVal b As Double) As PointF Dim retour As New PointF If a = 0 And c = 0 Then retour = Nothing If a = Double.MaxValue And c = Double.MaxValue Then retour = Nothing If c = 0 Then ' 2 cotés sont horizontaux (résoudre l 'intersection par les y) retour.Y = CSng(_P1.Y) retour.X = CSng((_P1.Y - b) / a) ElseIf c = Double.MaxValue Then ' 2 cotés sont verticaux (résoudre l 'intersection par les x) retour.X = CSng(_P1.X) retour.Y = CSng(_P1.X * a + b) Else 'quelconque If c <> a And a <> 0 Then retour.X = CSng((d - b) / (a - c)) retour.Y = CSng(a * retour.X + b) Else : retour = Nothing End If End If ' Ne pas oublier de faire une translation inverse sur les points trouvés et ensuite vérifier que le résultat appartient ' au segment des cotés (un rectangle.contains peut faire l'affaire) Dim ok As Boolean = False If Not (retour.X >= _P1.X Xor retour.X <= _P2.X) Then If Not (retour.Y >= _P1.Y Xor retour.Y <= _P2.Y) Then ok = True End If If Not IsNothing(retour) And ok Then Return retour + _Translation Else : Return Nothing End If End Function End Class
Le rayon,lui, est dessiné par des Line(x1,y1)-(x2,y2) sur le PictureBox.