Angle bisectors calculation

Hi people,
I'm trying to calculate the angle bisectors for different types of triangles by drawing one triangle per click (for every three clicks on the map the triangle will be regenerated with new coordinates)

In addition an exemplaric quad will be generated, which represents a gradient of one edge to show what I want to achieve. (glitchy; wrong angle calculations?)

The idea is to set the quad[2] and quad[3] positions at a distance of 30 pixels from the edges quad[0] and quad[1] along the corresponding angle bisectors inside of the triangle.

The problem now is, that I don't know how to do it correctly. I've got some calculations, but in most cases it doesn't draw the inner corners of the quad at the right positions.

I know that I've to use some conditions for the many cases (what do the look like) that can occur, but how to formulate the cases and which formulas to fill in? Many thanks in advance for any hints?

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
	sf::RenderWindow window(sf::VideoMode(1000,1000), "Map", sf::Style::Close);
	sf::VertexArray triangle(sf::Triangles, 3);
	sf::VertexArray quad(sf::Quads, 4),quad2(sf::Quads, 4),quad3(sf::Quads, 4);
	std::vector<sf::Vector2f> CoordVector;
	std::vector<sf::VertexArray> RegionVector;
	int clickcounter = 0;
	
	while (window.isOpen())
	{
	    sf::Event event;
		bool leftclicked = false;
	
	    while (window.pollEvent(event))
	    {
			switch (event.type)
			{
			case sf::Event::Closed:
				window.close();
				break;		
			case sf::Event::MouseButtonPressed:
				if (event.mouseButton.button == sf::Mouse::Left) 
				{
					leftclicked = true;
					break;
				}
			}
		}
		if(leftclicked)	
		{
		sf::Vector2i pixel_pos = sf::Mouse::getPosition(window);
		sf::Vector2f coord_pos = window.mapPixelToCoords(pixel_pos);
		
		CoordVector.push_back(coord_pos);
		
		if(clickcounter==2)
		{
			RegionVector.clear();
			
			for(int i=0;i<CoordVector.size();i++)
			{
				triangle[i].position = sf::Vector2f(CoordVector[i].x,CoordVector[i].y);
			}
			
			RegionVector.push_back(triangle);
			
			float distance = 30;
			
			float slopea = static_cast<float>(CoordVector[1].y-CoordVector[2].y)/(CoordVector[1].x-CoordVector[2].x);
			float slopeb = static_cast<float>(CoordVector[0].y-CoordVector[2].y)/(CoordVector[0].x-CoordVector[2].x);
			float slopec = static_cast<float>(CoordVector[1].y-CoordVector[0].y)/(CoordVector[1].x-CoordVector[0].x);
			
			float slopeanglea = atan(slopea);
			float slopeangleb = atan(slopeb);
			float slopeanglec = atan(slopec);
			
			float angle1 = static_cast<float>((slopeanglec+slopeangleb-3.14f)/2.0f);
			float angle2 = static_cast<float>((slopeanglea+slopeanglec-2*3.14f)/2.0f);
			float angle3 = static_cast<float>((slopeanglea+slopeangleb)/2.0f);
			
			quad[0].color = sf::Color::Red,quad[1].color = sf::Color::Red,quad[2].color = sf::Color::Blue,quad[3].color = sf::Color::Yellow;
			quad[0].position = sf::Vector2f(CoordVector[0].x,CoordVector[0].y), quad[1].position = sf::Vector2f(CoordVector[1].x,CoordVector[1].y);
			
			if(CoordVector[2].x>=CoordVector[1].x)				//???
			{	
			}
			else
			{
			}
			
			if(CoordVector[2].x>=CoordVector[0].x)				//???
			{
			}
			else
			{
			}
			
			if(CoordVector[1].x>=CoordVector[0].x)			//???
			{
				quad[2].position = sf::Vector2f(quad[1].position.x+distance*static_cast<float>(cosf(angle2)),quad[1].position.y+distance*static_cast<float>(sinf(angle2))); // blue
				quad[3].position = sf::Vector2f(quad[0].position.x+distance*static_cast<float>(cosf(angle1)),quad[0].position.y+distance*static_cast<float>(sinf(angle1))); // yellow
			}
			else
			{
				quad[2].position = sf::Vector2f(quad[1].position.x+distance*static_cast<float>(cosf(angle2)),quad[1].position.y+distance*static_cast<float>(sinf(angle2))); // blue
				quad[3].position = sf::Vector2f(quad[0].position.x+distance*static_cast<float>(cosf(angle1)),quad[0].position.y+distance*static_cast<float>(sinf(angle1))); // yellow
			}	
		}
		
		if(clickcounter<2)
		{
			clickcounter++;
		}
		else
		{
			CoordVector.clear();
			clickcounter = 0;
		}
	}
	window.clear();
	for (auto& it=RegionVector.begin(); it!=RegionVector.end(); ++it)
	{
		window.draw(*it);
	}
	window.draw(quad);
	window.display();
	}
	return 0;
}
Last edited on
> I'm trying to calculate the angle bisectors
¿where?

> for every three clicks on the map the triangle will be regenerated with new coordinates
¿is that relevant to your problem? ¿can't you just hardcode the triangle coordinates?
¿do I have to input the vertex in cw or ccw order?

> to show what I want to achieve
¿what do you want to achieve?

> I know that I've to use some conditions for the many cases (what do the look like) that can occur,
¿what special cases?


You started too big.
Get three points, define one (and only one) angle, get one point that lies on the bisection and draw a line from it to the vertex.
Later add the other two angles.
Later draw quads (or better, draw triangles so don't have to worry about vertex order)
Angle bisector calculation --> angle1,2,3 (term angle is misleading: angle=anglebisector)

I've found the solution and there are at least 12 different "cases" and if all are handled correctly, it doesn't matter if you draw it in cw or ccw order.

In the conditions I'm comparing the VertexArray x positions and the slopes of the edges and the only difference in the anglebisector (nr. 1 and nr. 2) formulas is the addition/subtraction of PI or 2*PI or removing it from the formula depending on the case. If someone wants to see the source code, I can upload it when I complete and bugfix it.
Last edited on
Topic archived. No new replies allowed.