I wrote code to assign the values to struct nngNode,but when I checked the result inside nngNode,the result displays -nan.I don't know why the -nan comes out.Before the result of nngNode,I can see the correct result from array.Here is the code :
1.
struct nngNode{
int x;
int y;
int pixelval;
int pixelnum;
double ndist;
nngNode(int x, int y, int pixelVal,int pixelNum,double ndist) : x(x), y(y), pixelval(pixelval),pixelnum(pixelnum),ndist(ndist) {}
};
struct cmp2{
bool operator()(nngNode ¶1, nngNode ¶2) {
return para1.ndist > para2.ndist;
}
};
template<class T1>
class Array2D{
public:
int arows=0;
int acols=0;
T1** __restrict matImg;
Array2D(int rows,int cols,T1 defaultVal):arows(rows),acols(cols){
matImg=new T1*[rows];
for(int i=0;i<rows;i++){
matImg[i]=new T1[cols];
memset(matImg[i],defaultVal,sizeof(T1)*cols);
}
}
T1 &operator()(int m, const int n){
return matImg[m][n];
}
T1 *operator()(int k){
return matImg[k];
}
~Array2D(){
for(int i=0;i<arows;i++){
delete[] matImg[i];
}
delete [] matImg;
}
};
int ragNode=0;
int pixelSum[id]={0};
int pixelNum[id]={0}
(After calculation the pixelSum and pixelNum have numbers.)
priority_queue<nngNode,vector<nngNode>,cmp2>nngprioq;
Array2D<double> neighDist(id,id,0);
//#pragma omp parallel for reduction(+:ragNode)
for(int i=0;i<id;i++){
for(int j=0;j<id;j++){
if(idArr(i,j)==1&&pixelNum[i]>0&&pixelNum[j]>0){
ragNode++;
// double powerDis=((pixelSum[i]/pixelNum[i]-pixelSum[j]/pixelNum[j])/(rows*cols))*((pixelSum[i]/pixelNum[i]-pixelSum[j]/pixelNum[j])/(ros));oll
double powerDis=pow((((double)pixelSum[i])/(double)pixelNum[i]-((double)pixelSum[j])/(double)pixelNum[j]),2);
double mulelement=((double)pixelNum[i])*((double)pixelNum[j]);
double divelement=(double)(pixelNum[i]+pixelNum[j]);
cout<<"------------------------------------"<<endl;
cout<<"powerDis:"<<powerDis<<endl;
cout<<"mulelement:"<<mulelement<<endl;
cout<<"divelement:"<<divelement<<endl;
cout<<"("<<i<<","<<j<<")"<<endl;
cout<<"psum"<<pixelSum[i]<<endl;
cout<<"pnum"<<pixelNum[i]<<endl;
cout<<"distance of"<<"("<<i<<","<<j<<"):"<<((mulelement*powerDis)/divelement)<<endl;
neighDist(i,j)=((mulelement*powerDis)/divelement)+1.0;
nngNode newnode=nngNode(i,j,pixelSum[i],pixelNum[i],neighDist(i,j));
nngprioq.push(newnode);
}
}
}
Here is the result from above :(only part from the whole result)
------------------------------------
powerDis:0.681595
mulelement:47124
divelement:1711
(240,255)
psum61
pnum28
distance of(240,255):18.7724
------------------------------------
powerDis:0.425937
mulelement:26376
divelement:970
(240,268)
psum61
pnum28
distance of(240,268):11.582
------------------------------------
powerDis:4.33408
mulelement:295656
divelement:1718
(241,170)
psum1055
pnum194
distance of(241,170):745.865
------------------------------------
powerDis:8.18913
mulelement:285374
divelement:1665
(241,201)
psum1055
pnum194
distance of(241,201):1403.58
------------------------------------
powerDis:1.25224
mulelement:295462
divelement:1717
(241,247)
psum1055
pnum194
distance of(241,247):215.487
------------------------------------
powerDis:0.0334138
mulelement:25050
divelement:551
(242,219)
psum129
pnum50
distance of(242,219):1.51908
------------------------------------
powerDis:1.1664
mulelement:100
divelement:52
(242,233)
psum129
pnum50
distance of(242,233):2.24308
------------------------------------
powerDis:1.84341
mulelement:246
divelement:47
(243,251)
psum122
pnum41
distance of(243,251):9.6485
------------------------------------
powerDis:0.00629865
mulelement:46986
divelement:1187
(243,267)
psum122
pnum41
distance of(243,267):0.249325
------------------------------------
powerDis:0.0911844
mulelement:10521
divelement:522
(244,219)
psum44
pnum21
distance of(244,219):1.83784
------------------------------------
Here is the nngNode ode of priority queue,the weird thing is pixelval coming from pixelSum[i],pixelnum coming from pixelNum[i] are 1,and 0.I don't understand the why the result comes out.Because from above in array,the number of ndist,pixelval and pixelnum can be seen as result.
int ncounter=0;
cout<<"---------------------nng queue---------------------------"<<endl;
while(!nngprioq.empty()){
cout<<"---------------------------------------------"<<endl;
cout<<ncounter<<"st Element:"<<endl;
cout<<"distanceValue:"<<(double)nngprioq.top().ndist<<endl;
cout<<"x:"<<nngprioq.top().x<<endl;
cout<<"y:"<<nngprioq.top().y<<endl;
cout<<"sumPixel:"<<nngprioq.top().pixelval<<endl;
cout<<"numPixel:"<<nngprioq.top().pixelnum<<endl;
nngprioq.pop();
ncounter++;
}
Here is the result with -nan:
x:1
y:6
sumPixel:1
numPixel:0
---------------------------------------------
913st Element:
distanceValue:-nan
x:1
y:0
sumPixel:1
numPixel:0
---------------------------------------------
914st Element:
distanceValue:-nan
x:1
y:4
sumPixel:1
numPixel:0
---------------------------------------------
915st Element:
distanceValue:-nan
x:0
y:26
sumPixel:1
numPixel:0
---------------------------------------------
916st Element:
distanceValue:-nan
x:0
y:11
sumPixel:1
numPixel:0
---------------------------------------------
917st Element:
distanceValue:-nan
x:0
y:20
Could someone provide any hint or suggestions?Thanks in advance!
Thank you all who share your time to review my quesion.I have found the issue which are about struct parameter and name of parameter.By changing pixelSum into pixelsum and add ndist(ndist).The issue is solved.
Related
I am implementing a simple version of Prim's algorithm using adjacency list using basic graph implementation idea.Here is my approach for this algorithm-
1.Pick an index.
2.Inside the Prims function,mark the index as visited.
3.If any adjacent vertex is not visited and cost of that vertex is less than mi(which is initialized as INF at the start of the function) then mi stores the cost and parent stores the index.
4.At the last adjacent vertex mi stores the smallest cost and parent stores the smallest cost index.
5.Again call the prims for parent vertex.
6.At last return the total cost.
But the problem in my approach is when I am comparing cost[v] with mi then it gives me an error cause I am comparing int with vector.I have tried using mi as a vector but then it gives me error in result section.My code is given below-
#include<bits/stdc++.h>
using namespace std;
#define mx 10005
#define INF 1000000007
vector<int>graph[mx],cost[mx];
int visited[mx]={0};
int result=0,parent;
int n,e,x,y,w,mi;
int prims(int u)
{
mi=INF;
visited[u]=1;
for(int i=0;i<graph[u].size();++i)
{
int v=graph[u][i];
if(visited[v]==0 and cost[v]<mi)
{
mi=cost[v];
parent=v;
}
if(i==graph[u].size()-1)
{
result+=mi;
prims(parent);
}
}
return result;
}
int main()
{
cin>>n>>e;
for(int i=1;i<=e;++i)
{
cin>>x>>y>>w;
graph[x].push_back(y);
graph[y].push_back(x);
cost[x].push_back(w);
cost[y].push_back(w);
}
int src;cin>>src;
int p=prims(src);
cout<<p<<endl;
return 0;
}
I'm trying to use CGAL to find the intersection between two objects: a Circle_2 and a Line_2. The code compiles but the result is not correct.
This is my code:
typedef CGAL::Exact_circular_kernel_2 Circular_k;
typedef CGAL::Point_2<Circular_k> Point_2;
typedef CGAL::Circular_arc_point_2<Circular_k> CircularArcPoint_2;
typedef CGAL::Direction_2<Circular_k> Direction_2;
typedef CGAL::Line_2<Circular_k> Line_2;
typedef CGAL::Circle_2<Circular_k> Circle_2;
typedef CGAL::CK2_Intersection_traits<Circular_k, Circle_2, Circle_2>::type Intersection_cc_result;
typedef CGAL::CK2_Intersection_traits<Circular_k, Circle_2, Line_2>::type Intersection_cl_result;
int main() {
Point_2 a(0.15, 0.15), b(-0.15, -0.15), c(-0.15, 0.15), d(0.15, -0.15);
double u = 0.5;
double theta = atan(u);
Line_2 r2(b, Direction_2(sin(-1.5708+theta),cos(-1.5708+theta)));
Circle_2 cir(Point_2 (0,0), 4);
std::vector<Intersection_cl_result> out1s;
intersection(cir,r2,back_inserter(out1s));
std::cout<<"size intersection: "<<out1s.size()<<std::endl;
CircularArcPoint_2 v1s;
assign(v1s, out1s[0]);
std::cout <<"v1s = "<< v1s << std::endl;
return 0;
}
This is my output:
size intersection: 2
v1s = EXT[0/1,0/1,0/1] EXT[0/1,0/1,0/1]
I don't understand why i get this: "v1s = EXT[0/1,0/1,0/1] EXT[0/1,0/1,0/1]
". The point "v1s" should be the first result from the intersection of the
Circle_2: "cir" and the Line_2: "r2".
What could i do to define this intersection point?
Solved.
Changed my code to:
using boostRetVal = std::pair<CGAL::Circular_arc_point_2< CGAL::Filtered_bbox_circular_kernel_2<CGAL::Circular_kernel_2<CGAL::Cartesian<CGAL::Gmpq>, CGAL::Algebraic_kernel_for_circles_2_2<CGAL::Gmpq>>>> , unsigned >;
std::vector<Intersection_cl_result> out1s;
intersection(cir,r2,back_inserter(out1s));
const auto v1_s =std::get<0>( boost::get<boostRetVal>(out1s[0]));
const auto v1s =Point_2(to_double(v1_s.x()), to_double(v1_s.y()));
I am writing a program for K-means clustering, to find the clusters that each point should belong to. There are 8 points and 3 clusters for this code. Somehow in my code the 'entries' function is executing infinitely. I couldn't find where I have gone wrong. This is the logic that I'm following:
Hard coded input of the 8 points
Randomly generate 3 cluster centers
Calculate distance of each point from the 3 cluster centers and use arr1[][] to store the distances.
In cent_tally[][], store the number of the cluster that each point should belong to. eg. 0 for cluster 1, 1 for cluster 2 and 2 for cluster 3. (Also storing the same values in the 4th column of the 2-D array, 'arr1').
Calculate the mean centroids (cluster centers) by using the clusters nos. for each point.
Again call the 'entries' function to calculate the distances and the cluster no. to which each point should belong, but this time using the 2nd set of centroids.i.e. the mean centroids.
If the second set of cluster nos. for each point, (stored in the 2nd column of cent_tally[][]), tallies with the cluster nos. for each point using the randomly generated centroids(first column of cent_tally[][]), then print cent_tally[][], print arr1[][] and stop.
Here is the code:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
using namespace std;
class points
{
float x;
float y;
static int point_cnt;
static int flag;
int cent_tally[8][4];
int count2;
struct centroids
{
float cx;
float cy;
}c[3];
public:
points()
{
count2=0;
for(int i=0;i<3;i++)
{
c[i].cx=0;
c[i].cy=0;
}
for(int i=0;i<8;i++)
{
for(int j=0;j<4;j++)
{
cent_tally[i][j]=0;
}
}
}
void means(points * );
float dist(float a,float b,float c,float d);
int entries(float c11x,float c11y,float c22x,float c22y,float c33x,float c33y,float arr[8][4],points *p);
};
int points::point_cnt=8;
int points::flag=0;
int points::entries(float c11x,float c11y,float c22x,float c22y,float c33x,float c33y,float arr[8][4],points *p)
{
float sum1x,sum1y,sum2x,sum2y,sum3x,sum3y; //to calC mean centroids
sum1x=0;
sum1y=0;
sum2x=0;
sum2y=0;
sum3x=0;
sum3y=0;
int cnt1,cnt2,cnt3;
cnt1=0;
cnt2=0;
cnt3=0; //to calC mean centroids
//count2=0;
//in the first iteration of entries, count2=0
cout<<"count 2 value:"<<count2<<endl;
for(int k=0;k<8;k++) //0 to 7 for 8 points
{
arr[k][0]=dist(p[k].x,p[k].y,c11x,c11y);
arr[k][1]=dist(p[k].x,p[k].y,c22x,c22y);
arr[k][2]=dist(p[k].x,p[k].y,c33x,c33y);
float temp,min;
temp = (arr[k][0] < arr[k][1]) ? arr[k][0] : arr[k][1];
min = (arr[k][2] < temp) ? arr[k][2] : temp;
//cout<<"mins:"<<min<<endl;
for(int l=0;l<3;l++)
{
if(arr[k][l]==min)
{
arr[k][3]=l; //0 for c1, 1 for c2, 2 for c3 in 4th column of table
cent_tally[k][count2]=l;
if(l==0)
{
sum1x+=p[k].x;
sum1y+=p[k].y;
cnt1++;
}
else if (l==1)
{
sum2x+=p[k].x;
sum2y+=p[k].y;
cnt2++;
}
else if (l==2)
{ sum3x+=p[k].x;
sum3y+=p[k].y;
cnt3++;
}
else
{
cout<<"";
}
}
}
}
count2++;//for index into cent_tally
//finding mean centroid ...
//re entering values of mean centroid into the same structure created for 3 centroid coordinates ...
c[0].cx=sum1x/cnt1;
c[0].cy=sum1y/cnt1;
c[1].cx=sum2x/cnt2;
c[1].cy=sum2y/cnt2;
c[2].cx=sum3x/cnt3;
c[2].cy=sum3y/cnt3;
//now the struct contains mean centroids
for(int i=0;i<8;i++)
{ int temp=0;
temp=count2-1;
if(cent_tally[i][temp]==cent_tally[i][count2])
{
flag++;
}
else
{
break;
}
}
if(flag==8)
{
cout<<"centroids found: "<<endl;
for(int i=0;i<8;i++)
{
for(int j=0;j<4;j++)
{
cout<<" "<<cent_tally[i][j];
}
cout<<endl;
}
return 0;
}
else
{
return flag;
}
//while(flag!=8) //WHILE ALL 8 entries of latest 2 columns of cent_tally are not matching
//{
//entries(c[0].cx,c[0].cy,c[1].cx,c[1].cy,c[2].cx,c[2].cy,arr,&p[0]);
//}
}
float points::dist(float a,float b,float c,float d)
{
return (abs(a-c)+abs(b-d));
}
void points:: means(points * p)
{
float arr1[8][4]; //array to store dist b/w each point and cluster center and cluster values for each point after distance calculation
float arr2[8][4];
//let c1 c2 and c3 be initial cluster centers
//float c1x,c2x,c1y,c2y,c3x,c3y;
//Can take input from a file also...
p[0].x=2;
p[0].y=2;
p[1].x=1;
p[1].y=14;
p[2].x=10;
p[2].y=7;
p[3].x=1;
p[3].y=11;
p[4].x=3;
p[4].y=4;
p[5].x=11;
p[5].y=8;
p[6].x=4;
p[6].y=3;
p[7].x=12;
p[7].y=2;
srand ( time(NULL) );
for(int i=0;i<3;i++) //for 3 cluster centers, we need 3 centroids
{
int randIndex=1+rand()%(point_cnt-i-1);//where 8 is the no. of points
c[i].cx=p[randIndex].x;
c[i].cy=p[randIndex].y;
}
int val;
val=entries(c[0].cx,c[0].cy,c[1].cx,c[1].cy,c[2].cx,c[2].cy,arr1,&p[0]);
while(val!=8)
{
val=entries(c[0].cx,c[0].cy,c[1].cx,c[1].cy,c[2].cx,c[2].cy,arr1,&p[0]);
}
for(int i=0;i<8;i++)
{
for(int j=0;j<4;j++)
{
cout<<arr1[i][j]<<" ";
}
cout<<endl;
}
//displaying 1st table
//2.1 calculate mean centroid
//2.2 re enter new values in same table
//2.3 first 2 columns of cent_tally
//2.4 if not same repeat step 2.1
}
int main()
{
int c=8;
points p[8];
points obj;
obj.means(&p[0]);
return 0;
}
Another mistake I made, was not initialising flag=0 at the beginning of the 'entries' function!
Now my entries function is not running infinitely, but I have the following problems now:
Mean centroid(Second set of centroids onwards) is computed wrong after the first set of centroids are used
I'm trying to copy the fourth column of arr[][]into the first column and next columns eventually, of cent_tally[][] by using count2 as index , but the first column of cent-tally does not match the 4th column of arr[][]
I'm unable to figure where I have gone wrong.
Due to this logic in entries function
if(flag==8)
{
cout<<"centroids found: "<<endl;
for(int i=0;i<8;i++)
{
for(int j=0;j<4;j++)
{
cout<<" "<<cent_tally[i][j];
}
cout<<endl;
}
return 0;
}
else
{
return flag;
}
8 will never be returned from entries function.
On the other hand, this logic in means function
while(val!=8)
{
val=entries(c[0].cx,c[0].cy,c[1].cx,c[1].cy,c[2].cx,c[2].cy,arr1,&p[0]);
}
loops until 8 is returned from the entries function.
This seems to be the cause of the infinite loop. Consider adjusting the behavior of one of these two point.
Reasons for incorrect mean centroid computation:
Most Important: Inside the for loop where l runs from 0 to 2, if two values of distances are the same, the counts get incremented for two values of l, hence a flag can be used to ensure that only one minimum distance is taken into consideration, for deciding the centroid to which the point belongs to.
Abs takes integer values and hear we are dealing with float, so we need to define a function which handles float values .
Flag should be initialised to 0 in the beginning of 'entries' function.
If two randomly generated centroids are the same, you may not get the right answer.
I'm working on programming my own little game which should have a visibility effect as described here. My world consists of Polygons which each have a list of Edges (sorted CW). I now want (as described in the article) to cast Rays towards the Edges of the polygons, find the intersections and retrieve a Polygon that defines the visible area.
So I wrote a classes for Vectors, Points, Edges and Polygons and adjusted the intersection-algorithm so it works with my code.
I then tested it and everything worked fine, but as I ran the Intersection algorithm in a for-loop to simulate a large amount of Edges processed(starting with 100, until 1000) the fps dropped drastically, with 100 Edges "only" 300fps (3000 before), and with 300 it dropped below 60 i think. This seems to be way to much drop for me as i wanted to reuse this code for my Lightsources and then i think i would quickly come up with processing way more than 300 Edges and it should run fast on way less powerful processors(i got an xeon e1230v3).
I figured out that only calling the EdgeIntersection the program runs many times faster, but I definitely need to loop through the Edges in my polygons so this is no option.
My Source-Code:
Vector.h/.cpp: Basic Vector class with two floats(X,Y), getters&setters, rotating
Vertex.h/.cpp: Basic Point class with a Position Vector, getters&setters and a boolean that indicates whether it is a Intersection Vertex
Edge.h/.cpp Basic Edge class with start/end-Verticies, getters&setters and rotating function(uses Vector.rotate())
Polygon.h:
#pragma once
#include <vector>
#include "Edge.h"
namespace geo
{
class Polygon
{
private:
std::vector<Edge> edges;
public:
Polygon();
Polygon(std::vector<Edge> edges);
~Polygon();
std::vector<Edge> getEdges();
Edge getEdge(int index);
int getEdgeCount();
void setEdges(std::vector<Edge> edges);
void setEdge(Edge e, int index);
void addEdge(Edge e);
void removeEdge(int index);
};
}
Ray.h:
#pragma once
#include "Vertex.h"
class Ray
{
private:
geo::Vertex origin;
geo::Vector dir;
public:
Ray();
Ray(geo::Vertex origin, geo::Vector dir);
~Ray();
geo::Vertex getOrigin();
geo::Vector getDirection();
void setOrigin(geo::Vertex origin);
void setDirection(geo::Vector dir);
};
LightModule.h:
#pragma once
#include "Polygon.h"
#include "Ray.h"
class LightModule
{
private:
//List of blocking Polygons
std::vector<geo::Polygon>* blockingPolygons;
std::vector<Ray> rays;
geo::Polygon bounds;
geo::Polygon visible;
/*geo::Polygon blocked;*/
//HitDetection Class later
geo::Vertex getIntersection(Ray r, geo::Edge* e);
geo::Vertex getClosestIntersection(Ray r, geo::Polygon *p);
public:
LightModule();
LightModule(std::vector<geo::Polygon>* blockingPolygons);
~LightModule();
//Set the Blocking Polygons
void setBlockingPolygons(std::vector<geo::Polygon>* blockingPolygons);
geo::Vertex callCI(Ray r, geo::Polygon* p);
geo::Vertex callI(Ray r, geo::Edge* e);
//Cast Rays towards Vertecies and store them in rays
void updateRays();
//Update Visibility Polygon
void updateVisible();
//Return Visibility Polygon
geo::Polygon* getVisible();
};
LightMModule.cpp:
#include "LightModule.h"
LightModule::LightModule()
{
rays.clear();
}
LightModule::LightModule(std::vector<geo::Polygon>* blockingPolygons)
{
this->blockingPolygons = blockingPolygons;
rays.clear();
}
LightModule::~LightModule()
{
}
void LightModule::setBlockingPolygons(std::vector<geo::Polygon>* blockingPolygons)
{
this->blockingPolygons = blockingPolygons;
}
//Test-cast a Ray (will follow mouse in the Test)
void LightModule::updateRays()
{
Ray r(geo::Vertex(geo::Vector(200, 100)), geo::Vector(-100, 0));
rays.push_back(r);
}
void LightModule::updateVisible()
{
}
//Both for Testing will later be part of a seperate class
geo::Vertex LightModule::callCI(Ray r, geo::Polygon *p)
{
return this->getClosestIntersection(r, p);
}
geo::Vertex LightModule::callI(Ray r, geo::Edge* e)
{
return this->getIntersection(r, e);
}
//TEST
geo::Vertex LightModule::getIntersection(Ray r, geo::Edge* e)
{
geo::Vertex v;
v.setIntersectVert(false);
float r_px = r.getOrigin().getPosition().getX();
float r_py = r.getOrigin().getPosition().getY();
float r_dx = r.getDirection().getX();
float r_dy = r.getDirection().getY();
float s_px = e->getOrigin().getPosition().getX();
float s_py = e->getOrigin().getPosition().getY();
float s_dx = e->getDirection().getX();
float s_dy = e->getDirection().getY();
float r_mag = sqrt(r_dx*r_dx + r_dy*r_dy);
float s_mag = sqrt(s_dx*s_dx + s_dy*s_dy);
if (r_dx / r_mag == s_dx / s_mag && r_dy / r_mag == s_dy / s_mag)
{
return v;
}
float T2 = (r_dx*(s_py - r_py) + r_dy*(r_px - s_px)) / (s_dx*r_dy - s_dy*r_dx);
float T1 = (s_px + s_dx*T2 - r_px) / r_dx;
if (T1 < 0 /*|| T1 > 1 For Lines*/)
{
return v;
}
if (T2 < 0 || T2 > 1)
{
return v;
}
v.setIntersectVert(true);
v.setPosition(geo::Vector(r_px + r_dx*T1, r_py + r_dy*T1));
return v;
}
geo::Vertex LightModule::getClosestIntersection(Ray r, geo::Polygon *p)
{
geo::Vertex v;
v.setIntersectVert(false);
geo::Vertex v_nearest(geo::Vector(0, 0));
v_nearest.setIntersectVert(false);
geo::Vector h1;
geo::Vector h2;
for (int i = 0; i < p->getEdges().size(); i++)
{
v = this->getIntersection(r, &p->getEdges().at(i));
h1.setX(v.getPosition().getX() - r.getOrigin().getPosition().getX());
h1.setY(v.getPosition().getY() - r.getOrigin().getPosition().getY());
h2.setX(v_nearest.getPosition().getX() - r.getOrigin().getPosition().getX());
h2.setY(v_nearest.getPosition().getY() - r.getOrigin().getPosition().getY());
if (i < 1)
v_nearest = v;
else if (v.isIntersectVert() == true && h1.getLength() < h2.getLength())
{
v_nearest = v;
}
}
return v_nearest;
}
For the Testing i create a Polygon a LightModule and call updateRays and then call the helper-Function callCI().
I know my code gets pretty messy when i have to cascade my getters and setters, ill have to fix that but for the Rest i hope everything is understandable and if not feel free to ask. And just to have mentioned it, I Test-draw my Objects with Vertex-Arrays but I don't need Graphical output of the intersection process, i just need the visible polygon.
Just to point out again: I need a faster way of finding the Intersection-Point between a Ray and a Polygon and as I didn't know if i did something wrong in my code I posted it all here so someone can maybe help me making my code more efficient or show me a different method to solve my problem.
Have a nice day and thank you for your answers :)
Paul
EDIT: Would it be meaningfully faster to first triangulate my polygons and then do a Ray-Triangle intersection Test?
I can't speak to the algorithm (which is possibly what you need) but some immediate thoughts on speeding up what you have.
First off you can define all your getters and setters inline (put them in the class in the header, not the separate source file) so the compiler can optimize the function calls away.
Then these changes might buy you a few frames:
// make sure your getters and setters are inline so the compiler
// can optimize them away
geo::Vertex LightModule::getClosestIntersection(Ray r, geo::Polygon* p)
{
geo::Vertex v;
v.setIntersectVert(false);
geo::Vector h1;
geo::Vector h2;
// cache these
Vector ray_position = r.getOrigin().getPosition();
geo::Vertex v_nearest(geo::Vector(0, 0));
v_nearest.setIntersectVert(false);
// cache size (don't dereference each time)
size_t size = p->getEdges().size();
// avoid acces violation
if(!size)
return v_nearest;
// preset item 0
v_nearest = this->getIntersection(r, &p->getEdges()[0]);
// start from 1 not 0
for(int i = 1; i < size; i++)
{
// don't use at() its slower
// v = this->getIntersection(r, &p->getEdges().at(i));
v = this->getIntersection(r, &p->getEdges()[i]);
// used cached ray position rather than call functions
h1.setX(v.getPosition().getX() - ray_position.getX());
h1.setY(v.getPosition().getY() - ray_position.getY());
h2.setX(v_nearest.getPosition().getX() - ray_position.getX());
h2.setY(v_nearest.getPosition().getY() - ray_position.getY());
// this if not needed because presetting item 0
//if(i < 1)
// v_nearest = v;
if(v.isIntersectVert() == true && h1.getLength() < h2.getLength())
{
v_nearest = v;
}
}
return v_nearest;
}
I removed one of the if statements by calculating the 0 item before the loop and starting the loop from 1, the rest is just caching a much used value and avoiding at() which is slower because it does bound-checking.
I am trying to modify the default behavior of ceres which is computing the squared sum of residuals as cost function. I want it to compute only a sum ( the residuals are already computed in a manner that they can only be positive)
according to the documentation I should use ConditionedCostFunction
this is what I have done:
I define the conditioner that takes 1 residuals and 1 parameter
struct Conditioners : ceres::CostFunction
{
public:
Conditioners()
{
set_num_residuals(1);
mutable_parameter_block_sizes()->push_back(1);
}
~Conditioners()
{}
template<typename T>
T operator() (T x)
{
return T(x * x);
}
bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const
{
return true;
}
};
I put conditioners inside a vector
std::vector<ceres::CostFunction*> conditioners;
for(int i = 0; i < 1; i++)
conditioners.push_back(new Conditioners());
ceres::ConditionedCostFunction* ccf =
new ceres::ConditionedCostFunction(cost_function, conditioners, ceres::TAKE_OWNERSHIP);
problem.AddResidualBlock(ccf, NULL, &x);
it compiles and everything. But it does not solve the problem. it does not even start. it says :
Ceres Solver Report: Iterations: 0, Initial cost: 4.512500e+01, Final cost: 4.512500e+01, Termination: CONVERGENCE
x : 0.5 -> 0.5
instead of :
iter cost cost_change |gradient| |step| tr_ratio tr_radius ls_iter iter_time total_time
0 4.512500e+01 0.00e+00 9.50e+00 0.00e+00 0.00e+00 1.00e+04 0 2.99e-04 1.04e-03
1 4.511598e-07 4.51e+01 9.50e-04 9.50e+00 1.00e+00 3.00e+04 1 3.84e-04 9.72e-03
2 5.012552e-16 4.51e-07 3.17e-08 9.50e-04 1.00e+00 9.00e+04 1 2.98e-05 9.92e-03
Ceres Solver Report: Iterations: 2, Initial cost: 4.512500e+01, Final cost: 5.012552e-16, Termination: CONVERGENCE
x : 0.5 -> 10
(if you want to try it yourself, this example modifies the helloword example)
Do you have any direction on what went wrong ?? (ceres report was not more specific)
I found the solution, which is :
struct Conditioners : ceres::CostFunction
{
public:
Conditioners()
{
set_num_residuals(1);
mutable_parameter_block_sizes()->push_back(1);
}
~Conditioners()
{}
template<typename T>
T operator() (T x)
{
return T(x * x);
}
bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const
{
residuals[0] = parameters[0][0] * parameters[0][0]
if (jacobians)
jacobians[0][0] = 2.0 * parameters[0][0]
return true;
}
};
My error was to thought I only had to re implement the () operator and that ceres will found out automatically the jacobian. It doesnot.