#include <math.h>
#include <iostream>
const double arrow_head_length = 3 ;
const double PI = 3.14159265 ;
const double arrow_head_angle = PI/ 6 ;
//returns the angle between two points, with coordinate1 describing the centre of the circle, starting at (theta = 0 == y=0,x>0) and progressing clockwise
double angle_between_points( std:: pair < double ,double > coordinate1, std:: pair < double ,double > coordinate2)
{
return atan2 ( coordinate2.second - coordinate1.second , coordinate1.first - coordinate2.first ) ;
}
//calculate the position of a new point [displacement] away from an original point at an angle of [angle]
std:: pair < double ,double > displacement_angle_offset( std:: pair < double ,double > coordinate_base, double displacement, double angle)
{
return std:: make_pair
(
coordinate_base.first - displacement * cos ( angle) ,
coordinate_base.second + displacement * sin ( angle)
) ;
}
int main( )
{
std:: pair < double ,double > arrow_tail( 0 , 0 ) ;
std:: pair < double ,double > arrow_head( 15 ,- 15 ) ;
//find the angle of the arrow
double angle = angle_between_points( arrow_head, arrow_tail) ;
//calculate the new positions
std:: pair < double ,double > head_point_1 = displacement_angle_offset( arrow_head, arrow_head_length, angle + arrow_head_angle) ;
std:: pair < double ,double > head_point_2 = displacement_angle_offset( arrow_head, arrow_head_length, angle - arrow_head_angle) ;
//output the points in order: tail->head->point1->point2->head so if you follow them it draws the arrow
std:: cout << arrow_tail.first << ',' << arrow_tail.second << '\n '
<< arrow_head.first << ',' << arrow_head.second << '\n '
<< head_point_1.first << ',' << head_point_1.second << '\n '
<< head_point_2.first << ',' << head_point_2.second << '\n '
<< arrow_head.first << ',' << arrow_head.second << std:: endl ;
}
I2luY2x1ZGUgPG1hdGguaD4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKY29uc3QgZG91YmxlIGFycm93X2hlYWRfbGVuZ3RoID0gMzsKY29uc3QgZG91YmxlIFBJID0gMy4xNDE1OTI2NTsKY29uc3QgZG91YmxlIGFycm93X2hlYWRfYW5nbGUgPSBQSS82OwoKLy9yZXR1cm5zIHRoZSBhbmdsZSBiZXR3ZWVuIHR3byBwb2ludHMsIHdpdGggY29vcmRpbmF0ZTEgZGVzY3JpYmluZyB0aGUgY2VudHJlIG9mIHRoZSBjaXJjbGUsIHN0YXJ0aW5nIGF0ICh0aGV0YSA9IDAgPT0geT0wLHg+MCkgYW5kIHByb2dyZXNzaW5nIGNsb2Nrd2lzZQpkb3VibGUgYW5nbGVfYmV0d2Vlbl9wb2ludHMoIHN0ZDo6cGFpcjxkb3VibGUsZG91YmxlPiBjb29yZGluYXRlMSwgIHN0ZDo6cGFpcjxkb3VibGUsZG91YmxlPiBjb29yZGluYXRlMikKewogIHJldHVybiBhdGFuMihjb29yZGluYXRlMi5zZWNvbmQgLSBjb29yZGluYXRlMS5zZWNvbmQsIGNvb3JkaW5hdGUxLmZpcnN0IC0gY29vcmRpbmF0ZTIuZmlyc3QpOwp9CgovL2NhbGN1bGF0ZSB0aGUgcG9zaXRpb24gb2YgYSBuZXcgcG9pbnQgW2Rpc3BsYWNlbWVudF0gYXdheSBmcm9tIGFuIG9yaWdpbmFsIHBvaW50IGF0IGFuIGFuZ2xlIG9mIFthbmdsZV0Kc3RkOjpwYWlyPGRvdWJsZSxkb3VibGU+IGRpc3BsYWNlbWVudF9hbmdsZV9vZmZzZXQoc3RkOjpwYWlyPGRvdWJsZSxkb3VibGU+IGNvb3JkaW5hdGVfYmFzZSwgZG91YmxlIGRpc3BsYWNlbWVudCwgZG91YmxlIGFuZ2xlKQp7CglyZXR1cm4gc3RkOjptYWtlX3BhaXIKCSgKCQljb29yZGluYXRlX2Jhc2UuZmlyc3QgIC0gZGlzcGxhY2VtZW50ICogY29zKGFuZ2xlKSwKCQljb29yZGluYXRlX2Jhc2Uuc2Vjb25kICsgZGlzcGxhY2VtZW50ICogc2luKGFuZ2xlKQoJKTsKfQoJCmludCBtYWluKCkKewogIHN0ZDo6cGFpcjxkb3VibGUsZG91YmxlPiBhcnJvd190YWlsKCAwLCAwKTsKICBzdGQ6OnBhaXI8ZG91YmxlLGRvdWJsZT4gYXJyb3dfaGVhZCggMTUsLTE1KTsKICAKICAvL2ZpbmQgdGhlIGFuZ2xlIG9mIHRoZSBhcnJvdwogIGRvdWJsZSBhbmdsZSA9IGFuZ2xlX2JldHdlZW5fcG9pbnRzKGFycm93X2hlYWQsIGFycm93X3RhaWwpOwogIAogIC8vY2FsY3VsYXRlIHRoZSBuZXcgcG9zaXRpb25zCiAgc3RkOjpwYWlyPGRvdWJsZSxkb3VibGU+IGhlYWRfcG9pbnRfMSA9IGRpc3BsYWNlbWVudF9hbmdsZV9vZmZzZXQoYXJyb3dfaGVhZCwgYXJyb3dfaGVhZF9sZW5ndGgsIGFuZ2xlICsgYXJyb3dfaGVhZF9hbmdsZSk7CiAgc3RkOjpwYWlyPGRvdWJsZSxkb3VibGU+IGhlYWRfcG9pbnRfMiA9IGRpc3BsYWNlbWVudF9hbmdsZV9vZmZzZXQoYXJyb3dfaGVhZCwgYXJyb3dfaGVhZF9sZW5ndGgsIGFuZ2xlIC0gYXJyb3dfaGVhZF9hbmdsZSk7CiAgCiAgLy9vdXRwdXQgdGhlIHBvaW50cyBpbiBvcmRlcjogdGFpbC0+aGVhZC0+cG9pbnQxLT5wb2ludDItPmhlYWQgc28gaWYgeW91IGZvbGxvdyB0aGVtIGl0IGRyYXdzIHRoZSBhcnJvdwogIHN0ZDo6Y291dCA8PCBhcnJvd190YWlsLmZpcnN0ICAgPDwgJywnIDw8IGFycm93X3RhaWwuc2Vjb25kICAgPDwgJ1xuJwogICAgICAgICAgICA8PCBhcnJvd19oZWFkLmZpcnN0ICAgPDwgJywnIDw8IGFycm93X2hlYWQuc2Vjb25kICAgPDwgJ1xuJwoJCQk8PCBoZWFkX3BvaW50XzEuZmlyc3QgPDwgJywnIDw8IGhlYWRfcG9pbnRfMS5zZWNvbmQgPDwgJ1xuJwoJCQk8PCBoZWFkX3BvaW50XzIuZmlyc3QgPDwgJywnIDw8IGhlYWRfcG9pbnRfMi5zZWNvbmQgPDwgJ1xuJwoJCQk8PCBhcnJvd19oZWFkLmZpcnN0ICAgPDwgJywnIDw8IGFycm93X2hlYWQuc2Vjb25kICAgPDwgc3RkOjplbmRsOwp9