Trait, courbe, ligne, points tillés, etc...

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Trait, courbe, ligne, points tillés, etc...

Message par blendman »

Salut

J'aimerai trouver la position d'un point C(x,y) par rapport à deux point A et B et à une distance.

Par exemple, si j'ai :
A (10,10)
B (25,10)
et distance = 10

Je voudrais obtenir C(20,10).
Là, c'est facile, car y ne change pas.
Mais ça se complique avec des x et des Y qui ne sont pas identiques ^^.

Pour trouver la distance, j'utilise cette formule :

Code : Tout sélectionner

Int(Sqr((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)))


La chose qui me manque c'est de trouver les coordonnées du nouveau point C (qui remplacera donc le B).
Si c'est le milieu, c'est facile, c'est C((x1+x2)/2,(y1+y2)/2)
Je pense qu'il doit y avoir un rapport avec pi, mais je n'arrive pas à remettre la main sur cette formule ^^

Savez-vous comment je peux trouver ce point C(x,y) ?

EDIT : j'ai changé le titre pour que ce soit plus général.
L'idée c'est que j'essaie de trouver le moyen d'obtenir un joli trait, comme ce qu'on obtiens en dessinant dans photoshop, par exemple. Donc avec :
- la possibilité de gérer un espacement régulier entre les points
- une courbe lissée (bézier ?)
- un trait avec antialiasing, même si l'épaisseur est de 1 pixel
Dernière modification par blendman le lun. 20/juil./2015 17:03, modifié 1 fois.
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Trouver un point entre deux points

Message par falsam »

La distance entre le vecteur A et C et B et C est la même ?
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Trouver un point entre deux points

Message par G-Rom »

Dis moi ce que tu veut faire avec ses 2 points , B est une direction ?
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Trouver un point entre deux points

Message par blendman »

falsam a écrit :La distance entre le vecteur A et C et B et C est la même ?
non.
Dis moi ce que tu veut faire avec ses 2 points , B est une direction ?
Je veux simplement dessiner des courbes avec points tillés par exemple ou dont les points sont tous à égale distance les uns avec les autres. Pour avoir des jolis traits ;).

C'est pour animatoon, mon soft de dessin.
En fait, je pose un premier point en A(10,10).
B c'est le point suivant que je vais obtenir (obtenu avec un mouseX(), MouseY() par exemple).

Je veux que le second point (qui ne sera donc pas B qui est mal placé souvent, mais qui sera alors un C(x,y) corrigé), quelque soit l'angle, soit à Dist = 10 par rapport à A.

Autrement dit, je veux que :

Code : Tout sélectionner

Dist = Int(Sqr((xC-xA)*(xC-xA) + (yC-yA)*(yC-yA))) 
; moi, je veux  :
Dist = 10 ; si j'ai choisi 10 comme distance entre deux points
Enfin, à peu près ^^.
La problème est que je ne connais pas encore C (car je le cherche), mais je connais B, le deuxième point que j' obtiens (en dessinant).

Donc, j'ai :

Code : Tout sélectionner

DistAB = Int(Sqr((xB-xA)*(xB-xA) + (yB-yA)*(yB-yA)))
Angle = ATan2((yB- yA),(xB- xA))

; je vérifie si cette distance est supérieure ou égale à celle que je cherche et si oui, je voudrais posé le point C, en fonction de l'angle (A,B), à distance = 10 par rapport à A

if DistAB >= 10 ; je choisis une distance entre mes points de 10 par exemple
; je cherche C(x,y) mais c'est là que je bloque ^^
X_C = ?
Y_C = ?
endif
Je ne sais pas si c'est clair, voici un petit dessin pour bien expliquer :
Image
En haut c'est quand je vais vite. Du coup certains points dépasse la distance, mais je les garde qd même.
En bas c'est ce que je veux obtenir (ça fonctionne si je vais lentement, car je n'ai pas le temps de dépasser trop largement la distance souhaitée entre deux points) :
- en fait je veux dessiner des courbes avec des points ayant toujours la même distance (comme ça, j'aurai des courbes avec pointillés par exemple, en fonction de ce que je suis en train de dessiner.
- donc j'enregistre dans une list ou un tableau les points que je dessine, si je dépasse la distance souhaite. Mais il m'arrive souvent de dépasser (en gros être > Dist et < dist*2). Moi, je voudrais recalculer la place du point pour être bon à chaque fois.

C'est plus clair ?

Sur mon dessin c'est une droite, mais je veux que ça fonctionne sur n'importe quelle courbe que je dessine :) (je ne suis pas très loin, ça marche si je dessine très lentement ^^)
Dernière modification par blendman le mer. 24/juin/2015 10:10, modifié 2 fois.
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Trouver un point entre deux points

Message par falsam »

En fait tu cherche la distance entres deux vecteurs A (X,Y) et B(X,Y).
Si cette distance est par exemple de 10px alors tu dessines le motif suivant ?

PS: B est toujours le dernier point actif
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Trouver un point entre deux points

Message par blendman »

falsam a écrit :En fait tu cherche la distance entres deux vecteurs A (X,Y) et B(X,Y).
Si cette distance est par exemple de 10px alors tu dessines le motif suivant ?

PS: B est toujours le dernier point actif
je pense que ça pourrait fonctionner oui.
Avec ça je pourrais dessiner des lignes en pointillé ou dont les points ont tous la même distance entre eux par exemple (comme sur mon dessin) ?

EDIT :

voici pour le moment, la procédure que j'utilise pour obtenir mes points :

Code : Tout sélectionner

Macro point_distance(x1,y1,x2,y2)   
  Int(Sqr((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) )       
EndMacro
Macro point_direction(x1,y1,x2,y2) ; = getangle
  ATan2((y2- y1),(x2- x1))
EndMacro


Procedure AddDot(x1,y1,size.d,alpha)
  
   i = ArraySize(listDot())
    
    If i >0
      
      xx =  x1 
      yy =  y1   
      StartX = listDot(i-1)\x
      StartY = listDot(i-1)\y
      
      dist.d  = point_distance(xx,yy,StartX,StartY)   ; to find the distance between two brush dots
   
      If dist >= size * brush\pas * 0.01 ;  c'est la distance souhaitée entre les points 
        ok = 1      
      EndIf
      
    Else
      ok = 1
    EndIf
    
  
    If ok
      
      ListDot(i)\x = x1
      ListDot(i)\y = y1
      
      listDot(i)\Size = size
      listDot(i)\Alpha = alpha
      
      ReDim ListDot(i+1)
      
    EndIf
  
EndProcedure
ça marche si je ne vais pas vite, mais si je vais trop vite, forcément, certains points sont pris en étant un peu plus loin que la distance (vu que je fais >= . En vérifiant si c'est = , ça ne marche pas.
Dernière modification par blendman le mer. 24/juin/2015 10:02, modifié 2 fois.
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Trouver un point entre deux points

Message par falsam »

Je vais faire un test en partant de ce calcul pour voir ce que ça donne

Code : Tout sélectionner

;Distance entres deux points (2D)
Procedure.d Distance(*p.Point, *q.Point)
  Protected Distance.d
  
  ;Distance horizontale
  dx.d = *p\x - *q\x   
  
  ;Distance verticale
  dy.d = *p\y - *q\y
  
  ;Théoréme de Pythagore
  Distance.d = Sqr(dx*dx + dy*dy )
  
  ProcedureReturn Distance
EndProcedure


;Définition du point A
A.point 
A\x = 15
A\y = 8

;Définition du point B
B.point 
B\x = 10
B\y = 20

Debug Distance(A, B)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Trouver un point entre deux points

Message par G-Rom »

un truc tout con , connaitre le milieu entre 2 points :

Code : Tout sélectionner

Structure vector2f
  x.f
  y.f
EndStructure


A.Vector2f
B.Vector2f

A\x = 20
A\y = 20

B\x = 40
B\y = 60



Middle.Vector2f

Middle\x = (A\x + B\x) * 0.5
Middle\y = (A\y + B\y) * 0.5


Debug Middle\x
Debug Middle\y
Tu peu répéter l'opération autant de fois que tu veut pour les point intermédiaire , c'est fiable est plus rapide que de calculer une distance avec sqr()
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Trouver un point entre deux points

Message par blendman »

G-Rom a écrit :un truc tout con , connaitre le milieu entre 2 points :

Code : Tout sélectionner

Structure vector2f
  x.f
  y.f
EndStructure


A.Vector2f
B.Vector2f

A\x = 20
A\y = 20

B\x = 40
B\y = 60



Middle.Vector2f

Middle\x = (A\x + B\x) * 0.5
Middle\y = (A\y + B\y) * 0.5


Debug Middle\x
Debug Middle\y
Tu peu répéter l'opération autant de fois que tu veut pour les point intermédiaire , c'est fiable est plus rapide que de calculer une distance avec sqr()
Oui, mais c'est pas ça que je cherche ^^.

Moi, je veux trouver la position du point entre A et B. Dans ton exemple, la position c'est la moitié de la distance A, B.
Mais moi ça peut être n'importe quoi ;).
Dernière modification par blendman le mer. 24/juin/2015 10:11, modifié 1 fois.
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: Trouver un point entre deux points

Message par Marc56 »

Si tu connais l'angle et la distance, et s'agissant d'un triangle rectangle (puisque tu as utilisé Pythagore)

DistAB = Hypoténuse

Sinus = Opposé (Y) / Hypoténuse (DistAB) donc Opposé (Y) = Sinus * Hypoténuse (DistAB)

Cosinus = Adjacent (X) / Hypoténuse (DistAB) donc Adjacent (X) = Cosinus * Hypoténuse (DistAB)

(gaffe aux radians)

:wink:
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Trouver un point entre deux points

Message par G-Rom »

J'ai compris , je te fait un autre code ^^
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Trouver un point entre deux points

Message par G-Rom »

Fonction à éprouvé , normalement ca marche ^^
tu lui passe une liste de point brute, il te renvois une autre liste contenant tout les points intermédiaire suivant une intervalle

Code : Tout sélectionner


Structure vector2f
  x.f
  y.f
EndStructure


Procedure GenerateIntervalPoint( List in.vector2f(), List out.vector2f() , interval.l = 10  )
    
  ClearList(out())

  Protected size.l = ListSize(in())

  For i = 1 To size-1
    
    A.vector2f
    B.vector2f
    
    SelectElement(in(),i-1)
    A\x = in()\x
    A\y = in()\y
    
    SelectElement(in(),i)
    B\x = in()\x
    B\y = in()\y
    
    
    dist.d = Sqr((B\x-A\x)*(B\x-A\x) + (B\y-A\y)*(B\y-A\y))

    If dist > interval And dist > 0
      
      direction.vector2f
        direction\x = B\x - A\x
        direction\y = B\y - A\y
        
      lenght.f =  Sqr(direction\x * direction\x + direction\y * direction\y)
      
      If lenght > 0
        direction\x / lenght
        direction\y / lenght
      EndIf 

      insertNumber.l = (dist / interval)-1

      Start.vector2f
      
      Start\x = A\x
      Start\y = A\y
      
      
      For i = 0 To insertNumber - 1
        
        AddElement(out())
        
        offset.i = insertNumber + 1
        
        out()\x = Start\x + (direction\x * interval)
        out()\y = Start\y + (direction\y * interval)
        
        Start\x + (direction\x * interval)
        Start\y + (direction\y * interval)
        
      Next 
      
    EndIf 
    
    Next 

EndProcedure



NewList MesPoints.vector2f()
NewList MesPointsIntermediaires.vector2f()




AddElement(MesPoints())
MesPoints()\x = 10 
MesPoints()\y = 10


AddElement(MesPoints())
MesPoints()\x = 100 
MesPoints()\y = 100

GenerateIntervalPoint( MesPoints(), MesPointsIntermediaires())



ForEach MesPointsIntermediaires()
Debug MesPointsIntermediaires()\x  
Debug MesPointsIntermediaires()\y
Debug ""
Next 


Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Trouver un point entre deux points

Message par blendman »

C'est sympa, mais ça ne marche pas tout à fait ;)

Exemple :

Code : Tout sélectionner

Structure vector2f
  x.f
  y.f
EndStructure


Procedure GenerateIntervalPoint( List in.vector2f(), List out.vector2f() , interval.l = 10  )
   
  ClearList(out())

  Protected size.l = ListSize(in())

  For i = 1 To size-1
   
    A.vector2f
    B.vector2f
   
    SelectElement(in(),i-1)
    A\x = in()\x
    A\y = in()\y
   
    SelectElement(in(),i)
    B\x = in()\x
    B\y = in()\y
   
   
    dist.d = Sqr((B\x-A\x)*(B\x-A\x) + (B\y-A\y)*(B\y-A\y))

    If dist > interval And dist > 0
     
      direction.vector2f
        direction\x = B\x - A\x
        direction\y = B\y - A\y
       
      lenght.f =  Sqr(direction\x * direction\x + direction\y * direction\y)
     
      If lenght > 0
        direction\x / lenght
        direction\y / lenght
      EndIf

      insertNumber.l = (dist / interval)-1

      Start.vector2f
     
      Start\x = A\x
      Start\y = A\y
     
     
      For i = 0 To insertNumber - 1
       
        AddElement(out())
       
        offset.i = insertNumber + 1
       
        out()\x = Start\x + (direction\x * interval)
        out()\y = Start\y + (direction\y * interval)
       
        Start\x + (direction\x * interval)
        Start\y + (direction\y * interval)
       
      Next
     
    EndIf
   
    Next

EndProcedure



NewList MesPoints.vector2f()
NewList MesPointsIntermediaires.vector2f()




AddElement(MesPoints())
MesPoints()\x = 10
MesPoints()\y = 10


AddElement(MesPoints())
MesPoints()\x = 100
MesPoints()\y = 100


AddElement(MesPoints())
MesPoints()\x = 122
MesPoints()\y = 114

AddElement(MesPoints())
MesPoints()\x = 141
MesPoints()\y = 256

GenerateIntervalPoint( MesPoints(), MesPointsIntermediaires(), 20)

Debug ListSize(MesPoints())
Debug ListSize( MesPointsIntermediaires())

; ForEach MesPointsIntermediaires()
;   Debug MesPointsIntermediaires()\x 
;   Debug MesPointsIntermediaires()\y
;   Debug ""
; Next 




w = 1024
h= 768

OpenWindow(0, 0, 0, w,h, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)


CanvasGadget(0,0,0,w,h)
If StartDrawing(CanvasOutput(0))
; en rouge, les points de base
  ForEach MesPoints()
    Circle(MesPoints()\x ,MesPoints()\y,6,RGBA(255,0,0,255))
  Next   
; en noir, les points obtenus, il en manque ^^
  ForEach MesPointsIntermediaires()
    Circle(MesPointsIntermediaires()\x ,MesPointsIntermediaires()\y,4,0)
  Next   
  StopDrawing()
EndIf

Repeat
  Event = WaitWindowEvent()
    
Until Event = #PB_Event_CloseWindow
Il manque les points après le second ^^
Dernière modification par blendman le mer. 24/juin/2015 10:42, modifié 1 fois.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Trouver un point entre deux points

Message par G-Rom »

Code : Tout sélectionner

Structure vector2f
  x.f
  y.f
EndStructure


Procedure GenerateIntervalPoint( List in.vector2f(), List out.vector2f() , interval.l = 10  )
   
  ClearList(out())

  Protected size.l = ListSize(in())
  
  
  
  For i = 1 To size-1
    
 
    A.vector2f
    B.vector2f
   
    SelectElement(in(),i-1)
    A\x = in()\x
    A\y = in()\y
   
    SelectElement(in(),i)
    B\x = in()\x
    B\y = in()\y
   
   
    dist.d = Sqr((B\x-A\x)*(B\x-A\x) + (B\y-A\y)*(B\y-A\y))

    If dist > interval And dist > 0
     
      direction.vector2f
        direction\x = B\x - A\x
        direction\y = B\y - A\y
       
      lenght.f =  Sqr(direction\x * direction\x + direction\y * direction\y)
     
      If lenght > 0
        direction\x / lenght
        direction\y / lenght
      EndIf

      insertNumber.l = (dist / interval)-1

      Start.vector2f
     
      Start\x = A\x
      Start\y = A\y
      
      AddElement(out())
      out()\x = Start\x
      out()\y = Start\y
     
      For j = 0 To insertNumber - 1
       
        AddElement(out())
       
        offset.i = insertNumber + 1
       
        out()\x = Start\x + (direction\x * interval)
        out()\y = Start\y + (direction\y * interval)
       
        Start\x + (direction\x * interval)
        Start\y + (direction\y * interval)
       
      Next
    EndIf
   
    Next

EndProcedure



NewList MesPoints.vector2f()
NewList MesPointsIntermediaires.vector2f()




AddElement(MesPoints())
MesPoints()\x = 10
MesPoints()\y = 10


AddElement(MesPoints())
MesPoints()\x = 100
MesPoints()\y = 100


AddElement(MesPoints())
MesPoints()\x = 200
MesPoints()\y = 10

AddElement(MesPoints())
MesPoints()\x = 300
MesPoints()\y = 100

GenerateIntervalPoint( MesPoints(), MesPointsIntermediaires(), 20)

Debug ListSize(MesPoints())
Debug ListSize( MesPointsIntermediaires())

; ForEach MesPointsIntermediaires()
;   Debug MesPointsIntermediaires()\x 
;   Debug MesPointsIntermediaires()\y
;   Debug ""
; Next 




w = 1024
h= 768

OpenWindow(0, 0, 0, w,h, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)


CanvasGadget(0,0,0,w,h)
If StartDrawing(CanvasOutput(0))
  ForEach MesPointsIntermediaires()
    Circle(MesPointsIntermediaires()\x ,MesPointsIntermediaires()\y,4,0)
  Next   
  StopDrawing()
EndIf

Repeat
  Event = WaitWindowEvent()
   
Until Event = #PB_Event_CloseWindow
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Trouver un point entre deux points

Message par falsam »

Bien entendu je suppose que tu veux une fonction pour dessiner à main levée ?
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre