/*********************************************************************/
/* */
/* Copyright 2022-2023 Rémi Synave - remi.synave@univ-littoral.fr */
/* */
/* This file is part of DSL. */
/* This software uses Qt to build the Graphical User Interface */
/* https://www.qt.io/ */
/* */
/* DSL is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published */
/* by the Free Software Foundation, either version 3 of the License, */
/* or (at your option) any later version. */
/* */
/* DSL is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with DSL. If not, see . */
/* */
/*********************************************************************/
#include
#include
#include
#include "StrengthLine.hpp"
StrengthLine::StrengthLine (QPoint * p1, QPoint * p2)
{
if (p1 == NULL || p2 == NULL)
throw std::
invalid_argument ("Points defining a strength line can't be NULL.");
if (p1->x () == p2->x () && p1->y () == p2->y ())
throw std::
invalid_argument ("Points defining a strength line can't be equals.");
this->p1 = p1;
this->p2 = p2;
}
QPoint*
StrengthLine::getP1() const
{
return new QPoint(*p1);
}
QPoint*
StrengthLine::getP2() const
{
return new QPoint(*p2);
}
std::pair < float, float >
StrengthLine::equation () const
{
// This method can be called only if a and b are
// not aligned into a vertical or horizontal line
float a = ((p1->y () - p2->y ()) * 1.0) / (p1->x () - p2->x ());
float b = p1->y () - a * p1->x ();
return std::make_pair (a, b);
}
std::pair < QPoint *, QPoint * >StrengthLine::toDraw (QImage * img) const
{
// Methode qui va calculer les points pour l'affichage des droites
// sur l'image passées en paramètre. Calcul rapide donc
// les points peuvent sortir de l'image.
// ligne verticale
if (p1->x () == p2->x ())
return std::make_pair (new QPoint (p1->x (), 0),
new QPoint (p1->x (), img->height ()));
// ligne horizontale
if (p1->y () == p2->y ())
return std::make_pair (new QPoint (0, p1->y ()),
new QPoint (img->width (), p1->y ()));
// Equation de la droite et on prend les points gauche et droite de la ligne
std::pair < float, float >
eq = this->equation ();
float
a = std::get < 0 > (eq);
float
b = std::get < 1 > (eq);
return std::make_pair (new QPoint (0, b),
new QPoint (img->width (), a * img->width () + b));
}
std::pair < QPoint *, QPoint * >StrengthLine::interpolateToEdge (QImage * img) const
{
// Methode qui va calculer les points sur les bords des images
// en fonction des deux points attributs qui définissent
// la ligne.
// ligne verticale
if (p1->x () == p2->x ())
return std::make_pair (new QPoint (p1->x (), 0),
new QPoint (p1->x (), img->height ()));
// ligne horizontale
if (p1->y () == p2->y ())
return std::make_pair (new QPoint (0, p1->y ()),
new QPoint (img->width (), p1->y ()));
// Equation de la droite et on prend les points gauche et droite de la ligne
std::pair < float, float >
eq = this->equation ();
float
a = std::get < 0 > (eq);
float
b = std::get < 1 > (eq);
if(a>0)
{
if(b<0)
{
if((a*img->width()+b) > img->height())
{
// |------------------------------------------|
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// |------------------------------------------|
return std::make_pair (new QPoint (-1*(b/a), 0),
new QPoint ((img->height()-b)/a, img->height ()));
}
else
{
// |------------------------------------------|
// | *** |
// | *** |
// | *** |
// | *** |
// | ***|
// | |
// | |
// | |
// | |
// |------------------------------------------|
return std::make_pair (new QPoint (-1*(b/a), 0),
new QPoint (img->width (), a * img->width () + b));
}
}
else // a>0 and b>0
{
if((a*img->width()+b) > img->height())
{
// |------------------------------------------|
// | |
// | |
// |* |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// |------------------------------------------|
return std::make_pair (new QPoint (0, b),
new QPoint ((img->height () -b )/a, img->height ()));
}
else
{
// |------------------------------------------|
// | |
// |******** |
// | ******** |
// | ******** |
// | ******** |
// | ******** |
// | **|
// | |
// | |
// |------------------------------------------|
return std::make_pair (new QPoint (0, b),
new QPoint (img->width(), a*img->width ()+b));
}
}
}
else // a<0
{
if((a*img->width()+b)>0)
{
if(b > img->height())
{
// |------------------------------------------|
// | |
// | |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// |------------------------------------------|
return std::make_pair (new QPoint ((img->height()-b)/a, img->height()),
new QPoint (img->width(), a*img->width()+b));
}
else
{
// |------------------------------------------|
// | |
// | |
// | **|
// | ******** |
// | ******** |
// | ******** |
// | ******** |
// |******** |
// | |
// |------------------------------------------|
return std::make_pair (new QPoint (0, b),
new QPoint (img->width (), a * img->width () + b));
}
}
else // a>0 and (a*img->width()+b) < 0
{
if(b > img->height())
{
// |------------------------------------------|
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// | * |
// |------------------------------------------|
return std::make_pair (new QPoint (-1*(b/a), 0),
new QPoint ((img->height()-b)/a, img->height ()));
}
else
{
// |------------------------------------------|
// | * |
// | * |
// | * |
// | * |
// |* |
// | |
// | |
// | |
// | |
// |------------------------------------------|
return std::make_pair (new QPoint (0, b),
new QPoint (-1*(b/a), 0));
}
}
}
return std::make_pair (new QPoint (*p1),
new QPoint (*p2));
}
StrengthLine* StrengthLine::getRandomLine (QImage * img)
{
std::srand(static_cast(std::time(nullptr)+std::rand()));
int x1rand = std::rand() % img->width();
int x2rand = std::rand() % img->width();
int y1rand = std::rand() % img->height();
int y2rand = std::rand() % img->height();
while ( x1rand == x2rand && y1rand==y2rand )
{
x2rand = std::rand() % img->width();
y2rand = std::rand() % img->height();
}
return new StrengthLine( new QPoint(x1rand, y1rand), new QPoint(x2rand, y2rand) );
}
StrengthLine* StrengthLine::getRandomLine (int width, int height)
{
std::srand(static_cast(std::time(nullptr)+std::rand()));
int x1rand = std::rand() % width;
int x2rand = std::rand() % width;
int y1rand = std::rand() % height;
int y2rand = std::rand() % height;
while ( x1rand == x2rand && y1rand==y2rand )
{
x2rand = std::rand() % width;
y2rand = std::rand() % height;
}
return new StrengthLine( new QPoint(x1rand, y1rand), new QPoint(x2rand, y2rand) );
}