Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Color gradient distance calculation for polygons  (Read 2707 times)

0 Members and 1 Guest are viewing this topic.

Bogdan

  • Jr. Member
  • **
  • Posts: 93
    • View Profile
Color gradient distance calculation for polygons
« on: October 05, 2017, 09:17:06 pm »
Hi people,
finally I've made color gradients for polygons and it works ok,
but the inner point calculation doesn't seem to be right, because the gradients
have a varying width instead of a fixed one. (Width should be more like the black lines are showing)
The outer coordinates are given and the angle bisectors are calculated from them. (calculations are right)
Distance is given with 30 pixels, but that seems to be the problem, because I somehow need a dynamic distance?
The smaller the angle, the longer the distance should be and vice versa....

My formula for calculation of the inner coordinates
(pseudocode for convex shape (concave points--> -distance)):

distance = 30
InnerCoordA(x,y) = OuterCoordA.x+distance*cos(anglebisectorA),OuterCoordA.y+distance*sin(anglebisectorA)

Is there any formula or mathematical concept which could solve my problem? Thx for any help.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Color gradient distance calculation for polygons
« Reply #1 on: October 05, 2017, 10:30:59 pm »
The thicknesses on each corner are, as you mentioned, all the same length. This is, though, incorrect. The sharper the angle, the longer that distance should be. You will need dot product calculations to work out this (it's the point where the two outer lines cross).

I did this in Selba Ward's Spline:

I'm pretty sure it's somewhere in this section of code... ;D


Note: you could use Selba Ward's Spline as a control path; it even provides for you the scale for each corner...
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Bogdan

  • Jr. Member
  • **
  • Posts: 93
    • View Profile
Re: Color gradient distance calculation for polygons
« Reply #2 on: October 18, 2017, 03:03:59 pm »
I've looked into the selba wards code, but I've still got some flaws in my code. What part of my calculations is wrong? I need only the right distance from each corner (or the coordinates for the inner triangle edges), but I somehow can't find the right solution. A static calculation example is given below:


#include <SFML/Graphics.hpp>

int main()
{
        sf::RenderWindow window(sf::VideoMode(800,800), "Map", sf::Style::Close);
       
        sf::VertexArray triangle(sf::Triangles, 3);
        triangle[0].position = sf::Vector2f(170, 20);
        triangle[1].position = sf::Vector2f(100, 700);
        triangle[2].position = sf::Vector2f(172, 550);
       
        sf::VertexArray triangle2(sf::Triangles, 3);
       
        float anglebisector1=1.6194, anglebisector2=-1.29575,anglebisector3=3.36187;
        float distance1=0,distance2=0,distance3=0;
       
        triangle2[0].color = triangle2[1].color = triangle2[2].color = sf::Color::Red;
       
        // distance calculation:
        sf::Vector2f vectorac = sf::Vector2f(triangle[0].position.x - triangle[2].position.x,triangle[0].position.y - triangle[2].position.y);
        sf::Vector2f vectorab = sf::Vector2f(triangle[0].position.x - triangle[1].position.x,triangle[0].position.y - triangle[1].position.y);
                                                       
        sf::Vector2f vectorba = sf::Vector2f(triangle[1].position.x - triangle[0].position.x,triangle[1].position.y - triangle[0].position.y);
        sf::Vector2f vectorbc = sf::Vector2f(triangle[1].position.x - triangle[2].position.x,triangle[1].position.y - triangle[2].position.y);
                                               
        sf::Vector2f vectorca = sf::Vector2f(triangle[2].position.x - triangle[0].position.x,triangle[2].position.y - triangle[0].position.y);
        sf::Vector2f vectorcb = sf::Vector2f(triangle[2].position.x - triangle[1].position.x,triangle[2].position.y - triangle[1].position.y);
       
        // dot product:
        float dotproducta = vectorac.x*vectorab.x+vectorac.y*vectorab.y;
        float dotproductb = vectorba.x*vectorbc.x+vectorba.y*vectorbc.y;
        float dotproductc = vectorca.x*vectorcb.x+vectorca.y*vectorcb.y;
       
        // length:
        float vectorlengtha = sqrtf(abs(dotproducta));
        float vectorlengthb = sqrtf(abs(dotproductb));
        float vectorlengthc = sqrtf(abs(dotproductc));
       
        // distance:
        distance1 = vectorlengtha*0.1f;
        distance2 = vectorlengthb*0.1f;
        distance3 = vectorlengthc*0.1f;
       
        // inner triangle positions:
        triangle2[0].position = sf::Vector2f(triangle[0].position.x+distance1*cosf(anglebisector1),triangle[0].position.y+distance1*sinf(anglebisector1));
        triangle2[1].position = sf::Vector2f(triangle[1].position.x+distance2*cosf(anglebisector2),triangle[1].position.y+distance2*sinf(anglebisector2));
        triangle2[2].position = sf::Vector2f(triangle[2].position.x+distance3*cosf(anglebisector3),triangle[2].position.y+distance3*sinf(anglebisector3));

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        switch (event.type)
                        {
                        case sf::Event::Closed:
                                window.close();
                                break;
                        }
                }
       
        window.clear();
        window.draw(triangle);
        window.draw(triangle2);
        window.display();
        }
        return 0;
}

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Color gradient distance calculation for polygons
« Reply #3 on: October 18, 2017, 08:59:58 pm »
I can't say that I remember exactly how I calculated it in Selba Ward's Spline; I reduced it to remove some unnecessary (in Spline's case) calculations and to work with the other calculations.

As I mentioned previously, though, instead of copying the code, Spline can do the work for you. Maybe something like:
sw::Spline spline{ { 150.f, 300.f }, { 150.f, 100.f }, { 300.f, 200.f } }; // 3 vertices
spline.setThickness(40); // very thick spline
spline.update();
std::vector<sf::Vector2f> outer;
std::vector<sf::Vector2f> inner;
for (unsigned int i{ 0u }; i < spline.getVertexCount(); ++i)
{
    outer.push_back(spline.getPosition(i) +
        spline.getInterpolatedPositionNormal(i) *
        spline.getInterpolatedPositionThickness(i) *
        spline.getInterpolatedPositionThicknessCorrectionScale(i));
    inner.push_back(spline.getPosition(i) -
        spline.getInterpolatedPositionNormal(i) *
        spline.getInterpolatedPositionThickness(i) *
        spline.getInterpolatedPositionThicknessCorrectionScale(i));
}
Although I am currently unable to test this, it should mean that:
outer contains the three points of the corners on the outside of the shape, and
inner contains the three points of the corners on the inside of the shape.
You can then do what you want with these points ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

 

anything