derde punt met een x offset berekenen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik wil graag een bezier curve tekenen voor een svg in javascript van punt 1 naar punt 2, maar met een boogje erin afhankelijk van de dikte van de lijn. Het gaat om de volgende situatie:

Afbeeldingslocatie: http://ghanso.com/stuff/upload/vb.png

Ik heb alleen geen idee hoe ik het derde xy-punt bereken voor de bezier met de gegevens die ik heb: punt 1, punt 2, het midden, en een offset van bijvoorbeeld 5 pixels. Iemand die mij op weg kan helpen/de oplossing heeft?

Acties:
  • 0 Henk 'm!

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Door de hoek te nemen tussen beide punten en hier nog 90 graden bij op te tellen weet je welke kant je op moet. Als je dit simpelweg optelt met het middelpunt heb je je offset gevonden :)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<canvas id='cvs' width='100px' height='100px'></canvas>

<script type='text/javascript'>

window.onload = function()
{
    var tau = Math.PI*2; //TAU makes simple calculations using radians easier.
    var p1 = { 'x' : 10, 'y' : 90 }; //First point
    var p2 = { 'x' : 90, 'y' : 10 }; //Second point
    var offset = 5; //distance from center

    //Place p3 in the middle of p1/p2
    var p3 = { 'x' : (p1.x + p2.x) *0.5, 'y' : (p1.y + p2.y) * 0.5 };

    //Calculate the angle between p1 and p2, then rotate 90 deg more
    var a = Math.atan2(p2.y - p1.y, p2.x - p1.x) - tau/4;
    
        //Mutate the point
    p3.x += Math.cos(a) * offset;
    p3.y += Math.sin(a) * offset;

    var cvs = document.getElementById('cvs');
    var ctx = cvs.getContext('2d');

    ctx.fillRect(p1.x, p1.y, 4,4);
    ctx.fillRect(p2.x, p2.y, 4,4);

    ctx.fillRect(p3.x, p3.y, 4,4);

}

</script>

[ Voor 10% gewijzigd door TJHeuvel op 30-01-2012 11:15 . Reden: 45 graden moest natuurlijk 90 zijn ]

Freelance Unity3D developer


Acties:
  • 0 Henk 'm!

  • bwerg
  • Registratie: Januari 2009
  • Niet online

bwerg

Internettrol

Aangezien het toch 90 (niet 45) graden draaiing moet zijn, hoef je niet per se tangensen en sinussen te gebruiken. Als je een vector (x,y) 90 graden wilt draaien naar links is dat (-y,x) en naar rechts is (y,-x)*. Dus een nieuwe vector maken die de 90 graden gedraaide versie is van je oude, normaliseren (delen door de lengte, met pythagoras, lengte = (x2 - x1)2 + (y2 - y1)2) en vermenigvuldigen met de lengte die je wilt (5 pixels). Dat is de offset, dus dat weer optellen bij je middelpunt.

*stiekem is dit ook gewoon met sinus/cosinus maar die zijn van 90 graden gewoon 1/0 dus daardoor kan je bepaalde dingen gewoon weglaten.

[ Voor 23% gewijzigd door bwerg op 30-01-2012 11:28 ]

Heeft geen speciale krachten en is daar erg boos over.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Thanks TJHeuvel, die werkt uitstekend!

En om alles te onderzoeken, bwerg, ben ik zover gekomen met mijn vergane kennis handicap volgens jouw beschrijving:

code:
1
2
3
4
5
6
7
8
9
10
11
//Place p3 in the middle of p1/p2
var p3 = {'x': (p1.x + p2.x)*0.5, 'y': (p1.y + p2.y)*0.5};

var a = {'x': -p3.x, 'y': p3.y};
        
var l = Math.sqrt((p2.x-p1.x)+(p2.y-p1.y));
        
p3.x += (a.x/l) * offset;
p3.y += (a.y/l) * offset;
        
return p3;


maar geeft vooralsnog een verkeerde boog.

Acties:
  • 0 Henk 'm!

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 13:19

Reptile209

- gers -

Definieer "verkeerde boog". Nog beter: geef eens een screenshotje van wat je nu krijgt. Bonuspunt: teken daar eens de boog die je had willen krijgen bij, een (stippel-)lijntje tussen P1 en P2 als hulplijn en een (stippel-)lijntje tussen het middelpunt van de rechte lijn en het midden van de boog (je 'offset').

Bovenstaande klinkt misschien stom, maar het kan erg helpen om te visualiseren wat je aan het doen bent en wat er precies mis gaat. Ik ga niet narekenen wat je code verkeerd doet, maar met je plaatje en een beetje basics in trigonometrie zou je er toch wel uit moeten kunnen komen.

Algemene hint, scoort altijd goed in de buurt van sinussen en cosinussen (ook al zie je ze hier niet): misschien ergens een + en een - omgewisseld? :)

Zo scherp als een voetbal!


Acties:
  • 0 Henk 'm!

  • TheWickedD
  • Registratie: Juli 2002
  • Laatst online: 02-04-2024
Ik schrijf geen Javascript, maar:
code:
1
2
3
4
5
var p3 = {'x': (p1.x + p2.x)*0.5, 'y': (p1.y + p2.y)*0.5};

var a = {'x': -p3.x, 'y': p3.y};
        
var l = Math.sqrt((p2.x-p1.x)+(p2.y-p1.y));

moet iets dergelijks zijn
code:
1
2
3
var vec = {'x': p2.x-p1.x, 'y': p2.y-p1.y}; // vector van punt p1 naar punt p2
var l = Math.sqrt(vec.x*vec.x+vec.y*vec.y); // lengte van die vector (afstand tussen de punten). Pythagoras ken je toch wel??
var a = {'x':-vec.y, 'y': vec.x}; // dat is wat (-y x) betekend, herrinner je je van school hoe je coordinaten opschrijft?

Acties:
  • 0 Henk 'm!

  • Ghanso
  • Registratie: Januari 2005
  • Laatst online: 26-11-2021

Ghanso

Ik gheet Ghanso

Dank allen! Beide werkend.

code:
1
2
3
4
5
6
7
8
9
10
var p3 = {'x': (p1.x + p2.x)*0.5, 'y': (p1.y + p2.y)*0.5};
        
var vec = {'x': p2.x-p1.x, 'y': p2.y-p1.y}; // vector
var l = Math.sqrt(vec.x*vec.x+vec.y*vec.y); // vector length, Pythagoras
var a = {'x': vec.y, 'y': -vec.x}; // shift angle 90 deg
        
p3.x += (a.x/l) * offset;
p3.y += (a.y/l) * offset;
        
return p3;
Pagina: 1