Curve tekenen tussen twee punten

Pagina: 1
Acties:

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:52
Ik heb twee coördinaten x1,y1 en x2,y2 waartussen ik een lijn wil tekenen, maar dan afhankelijk van de afstand met een meer of mindere curve. Dat lukt bijna. Hieronder twee voorbeelden van de werkende curves en de falende.

Afbeeldingslocatie: http://www.pilight.org/voorbeeld.jpg

Afbeeldingslocatie: http://www.pilight.org/fout.jpg

Tussen de blauwe punten is op de curve ook een rode stip te zien. De lijn loopt dus van punt 1 naar punt 2 via de rode stip.

Een collega kwam met de volgende formule die is gebruikt om tot de rode stip te komen (en dus de curve):
code:
1
2
3
4
5
6
dx = x2 - x1
dy = y2 - y1
dr = sqrt(dx * dx + dy * dy)

viaX = 0.5 * (x1 + x2) + sqrt(3) * 0.1 * dr;
viaY = 0.5 * (y1 + y2) + sqrt(3) * 0.1 * dr * -1 * (dx/dy)

Echter schiet de curve in sommige gevallen door.

Het idee achter de formule is om de twee punten als onderdelen van een cirkel te zien om vervolgens te achterhalen waar het punt op de cirkel zou liggen (rode stip) tussen de twee bekende punten (blauwe stippen).

Iemand een idee waar het nu fout gaat en hoe het op te lossen?

Sinds de 2 dagen regel reageer ik hier niet meer


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 05-05 17:38

Janoz

Moderator Devschuur®

!litemod

Ik heb het allemaal niet nagerekend, maar ik vind het wat raar dat de berekening van de coordinaten van het rode punt verschillen. Als ik naar de voorbeelden kijk zie ik dat de variant die misgaat een hele kleine dy heeft. De extra factor bij de viaY wordt veel groter vanwege (dx/dy).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:52
Het was me ook al opgevallen dat de hoek waarin de punten zich tot elkaar verhouden ook invloed had op de curve terwijl eigenlijk alleen de afstand leidend zou moeten zijn. De hoek zou alleen iets moeten zeggen over de kant van de curve.

Sinds de 2 dagen regel reageer ik hier niet meer


  • Sendy
  • Registratie: September 2001
  • Niet online
Een cirkel is gedefinieerd door 3 punten. Dus als je echt cirkels wil gebruiken, en de rode precies in het midden van de boog zit, is er maar de beperkte serie cirkelbogen mogelijk. Het middelpunt ligt dan op de lijn loodrecht op het midden van de lijn door het begin en eindpunt. De rode ligt ook op die lijn.

Jouw foute voorbeeld lijkt echter meer een ellips. Dan heb je een vrijheidsgraad meer.

Welke eisen stel je aan de boog?

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:52
Sendy schreef op donderdag 10 december 2015 @ 21:50:
Welke eisen stel je aan de boog?
Niks. Ik vind het er vooral mooier uit zien (als het werkt).

Sinds de 2 dagen regel reageer ik hier niet meer


  • Sendy
  • Registratie: September 2001
  • Niet online
Waarom is het bovenste plaatje mooi en de onderste niet?

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:52
Ik zoek een subtiele verbinding tussen twee punten. Dus een kleine curve.

Sinds de 2 dagen regel reageer ik hier niet meer


  • Migrator
  • Registratie: Januari 2014
  • Niet online

Migrator

☄️☄️☄️ voorheen Evest

CurlyMo schreef op donderdag 10 december 2015 @ 21:20:
Het was me ook al opgevallen dat de hoek waarin de punten zich tot elkaar verhouden ook invloed had op de curve terwijl eigenlijk alleen de afstand leidend zou moeten zijn. De hoek zou alleen iets moeten zeggen over de kant van de curve.
Janoz zegt het al, het gaat fout door de -1*(dx/dy) die je bij viaY op telt. Als je op deze manier een curve wil trekken van een punt naar een punt met dezelfde y dan zul je zien dat hij naar oneindig schiet. Dat is absoluut niet wat je wil.

Overigens vind ik het assenstelsel ook raar. Bij het tweede plaatje zou er in een conventioneel rechtsdraaiend assenstelsel een positieve (dx/dy) moeten zijn, maar gezien de plaatsing van de rode stip is die negatief?

If you choose not to decide, you still have made a choice.


  • Sendy
  • Registratie: September 2001
  • Niet online
Dat was dubbel. ok, kleine cirkelboog dus

[ Voor 65% gewijzigd door Sendy op 10-12-2015 22:03 ]


  • Mr_gadget
  • Registratie: Juni 2004
  • Laatst online: 05-05 20:47

Mr_gadget

C8H10N4O2 powered

Kijk even naar Béziercurves:
Wikipedia: Bézierkromme

  • Migrator
  • Registratie: Januari 2014
  • Niet online

Migrator

☄️☄️☄️ voorheen Evest

Op zich een mooie methode, maar dan moet het derde punt nog steeds berekend worden aan de hand van de ligging van de andere twee, en daar gaat het op het moment bij CurlyMo mis.

If you choose not to decide, you still have made a choice.


  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:52
Idealiter zou ik voor alle punten zoiets willen kunnen doen:
Afbeeldingslocatie: https://www.pilight.org/circel.jpg

Dus de cirkel uitrekenen tussen de twee punten waarbij er vanuit wordt gegaan dat beide blauwe punten op X% bovenin de cirkel worden geplaatst en het rode punt daar weer tussen op de cirkel.

Daarmee zouden alle curves in verhouding staan tot de afstand tussen de twee blauwe punten.

Sinds de 2 dagen regel reageer ik hier niet meer


  • Migrator
  • Registratie: Januari 2014
  • Niet online

Migrator

☄️☄️☄️ voorheen Evest

Wat ik mis in je code zijn een sinus en een cosinus. Zonder met hoeken te rekenen ga je niet een netjes meedraaiende curve krijgen die gelijk is qua vorm en afmeting voor verschillende punten op dezelfde afstand.
Edit: Met verhoudingen kan dat natuurlijk ook.
De methode die ik in gedachte had maakt gebruik van het volgende:
Afbeeldingslocatie: http://tweakers.net/ext/f/WHbdsEcAhKRX3WqBQcYxHxdL/full.png

Je wil een derde punt op een afstand a op de middelloodlijn van de lijn AB hebben. Dit derde punt kun je vervolgens gebruiken als middelpunt van je cirkel of als derde punt op je cirkel (of als hulppunt voor zo'n Bézierkromme). You name it. Afhankelijk waarvan je het punt gebruikt maak je a groter of kleiner ten opzichte van je afstand r = sqrt(dx^2 + dy^2). Of a positief of negatief is kan je nog een conditie aan hangen zodat curves altijd bovenlangs gaan of iets dergelijks, maar daarvoor kan je zelf waarschijnlijk wel wat verzinnen. Anyway, met de hoek h = tan^-1(dx/dy) kun je de ligging van het derde punt ten opzichte van het punt halverwege de lijn AB bepalen. Voor de x-richting is dat met een - sin en voor de y-richting een cos.
Met de verhoudingen dx/r en dy/r voor de y- en x-richting kun je de coördinaten van het derde punt t.o.v. het middelpunt bepalen.
De code die je nu hebt behoeft niet al te veel aanpassingen om op de juiste manier de punten te berekenen. Hopelijk heb ik je niet al je werk uit handen genomen (code moet in ieder geval nog getypt worden :p), en succes :)

[ Voor 6% gewijzigd door Migrator op 11-12-2015 07:04 ]

If you choose not to decide, you still have made a choice.


  • jip_86
  • Registratie: Juli 2004
  • Laatst online: 00:07
Volgens mij moet je inderdaad die afstand berekenen. Als je dat ziet als lange zijde van een driehoek kun je twee hoeken berekenen die x1,y1 en x2,y2 maken met een rechte hoek van 90 graden die het derde punt opleveren. Dat is een eerste driehoek.

Trek je vervolgens op de helft van die lange zijde tussen die x1,y1 en x2,y2 een lijn met een hoek van 90 graden tot je de overzijde raakt hak je die driehoek in tweeën. De lengte van die lijn is je 'uitslag' die je curve volgens mij moet maken. Mijn driehoekskills zijn vrij roestig, maar als ik even snel een calculator invul is die uitslag in ieder geval aanzienlijk korter als de delta x of delta y heel klein is.

Plaatjes maken denk ik meer duidelijk ;)

Afbeeldingslocatie: https://i.gyazo.com/9469ff601ab7f986352cf6c5b2db28c4.png

Afbeeldingslocatie: https://i.gyazo.com/aff5ddada23a0e141985e30df02bdfda.png

[ Voor 3% gewijzigd door jip_86 op 10-12-2015 23:53 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 14-04 17:27
Waarom zou je sinus of cosinus nodig hebben? Jouw middelloodlijn kruist de lijn AB op het punt { (xA+xB)/2, (yA+yB)/2 } en heeft als richtingscoefficient {yB-yA, xA-xB}. En vervolgens heb je een vrije keuze waar je het middelpunt van de cirkel plaatst.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • Migrator
  • Registratie: Januari 2014
  • Niet online

Migrator

☄️☄️☄️ voorheen Evest

MSalters schreef op donderdag 10 december 2015 @ 23:51:
Waarom zou je sinus of cosinus nodig hebben? Jouw middelloodlijn kruist de lijn AB op het punt { (xA+xB)/2, (yA+yB)/2 } en heeft als richtingscoefficient {yB-yA, xA-xB}. En vervolgens heb je een vrije keuze waar je het middelpunt van de cirkel plaatst.
En hoe bereken je dan de coördinaten van het derde punt op die middelloodlijn? Juist daar heb je wat goniometrie nodig om het punt op een vaste afstand van het middelpunt van de lijn te leggen. Of ik zie zelf wat over het hoofd daarin. Bijvoorbeeld dat je sinus en cosinus gelijk zijn aan respectievelijk dy/r en dx/r. :P

If you choose not to decide, you still have made a choice.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 05-05 17:38

Janoz

Moderator Devschuur®

!litemod

Nope, dat kan gewoon met vectoren. halve (dx,dy) optellen bij x1,y1 en je zit in het midden. Vervolgens een vector loodrecht hierop zetten met een lengte die bepaalt wat de curve gaat worden (stel je doet altijd een kwart van de afstand tussen beide punten)

Dan kom je uiteindelijk op iets als (x1,y1) +.5(dx,dy) +.25(dy,dx) waarbij je die .25 eventueel nog aan kunt passen aan hoe groot je de curve wilt hebben,


(Uiteindelijk gebruik je dan wel de sinus en cosinus, maar aangezien je een vaste hoek van 90o hebt is sin altijd 1 en cos altijd 0 waardoor bij de geroteerde vector gewoon de x en y omruilen)

[ Voor 20% gewijzigd door Janoz op 11-12-2015 10:37 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 14-04 17:27
Migrator schreef op vrijdag 11 december 2015 @ 07:00:
[...]
En hoe bereken je dan de coördinaten van het derde punt op die middelloodlijn? Juist daar heb je wat goniometrie nodig om het punt op een vaste afstand van het middelpunt van de lijn te leggen. Of ik zie zelf wat over het hoofd daarin. Bijvoorbeeld dat je sinus en cosinus gelijk zijn aan respectievelijk dy/r en dx/r. :P
Dat is precies waarom ik de richtingscoëfficient van de middelloodlijn geef. Vermenigvuldig die met een willekeurige constante om verschillende punten op de middelloodlijn te krijgen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 09:52
Het uiteindelijke antwoord:
code:
1
2
3
4
5
dx = x2 - x1,
dy = y2 - y1;

viaX = 0.5 * (x1 + x2) + .2 * -dy;
viaY = 0.5 * (y1 + y2) + .2 * dx;


.2 bepaalt de grootte van de boog. De signedness van de .2 bepaalt of de boog boven- of onderlangs gaat.

[ Voor 8% gewijzigd door CurlyMo op 15-12-2015 10:26 ]

Sinds de 2 dagen regel reageer ik hier niet meer

Pagina: 1