How can i get interpolated Polar coordinates? - c++

I have a problem to get a discrete Sequence of a contour.
My idea: I want to place an anchor in a middle of a closed contour in an image and use polar coordinates to get a length for each degree of the polar coordinates.
I already have created a vector of fixed length 360 and iterate through all contour points(ca. 4000) with length l=contour.length/360. Here i get 360 values along the contour with length l. But i want to have a discrete value for each integer degree from 1 to 360.
Can i interpolate my array to fix values from 1 to 360?
vector<cv::Point> cn;
double theta = 0;
double dis = 0;
int polsize = 360;
int psize = 0;
for (int k = 0; k < cnts[0].size(); k++) {
cn.push_back(cnts[0].at(k));
}
double pstep = cn.size() / polsize;
for (int m = 1; m < polsize; m++) {
psize = (int)(m * pstep);
polar(cn[psize].x, cn[psize].y, &dis, &theta);
outputFile << theta << "/" << dis << ";";
}
void polar(int x, int y, double* r, double* theta)
{
double toDegrees = 180 / 3.141593;
*r = sqrt((pow(x, 2)) + (pow(y, 2)));
double xt = x, yt = y;
yt = 1024 - yt;
if (xt == 0) xt = 0.1;
if (yt == 0) yt = 0.1;
*theta = atan(yt / xt) * toDegrees;
if (*theta < 0) *theta = *theta+180;
return;
}

You seem to miss some of the C++ basics. E.g.
1) If you use at() you add unnecessary range checking. As you are looping until cnts[0].size() you're doing that twice now.
2) you don't need to use return in void functions.
3) don't use pointers for return. This is C++, not C. Use references, or std::tuple return type.
Then you're actually replicating the std::complex type.
The code can be really simple.
#include <vector>
//#include <algorithm> // if using std::copy
#include <cmath>
#include <sstream> // only for the temporary output.
static constexpr auto toDeg = 180 / 3.141593;
struct Point{
double x,y;
double abs() const {
return std::sqrt(std::pow(x,2) + std::pow(y,2));
}
double arg() const {
return std::atan2(y, x) * toDeg;
}
};
int main(){
std::vector<std::vector<Point>> cnts = {{{1,1}}};
// copy constructor
std::vector<Point> cn(cnts[0]);
// range-based constructor
//std::vector<Point> cn(std::cbegin(cnts[0]), std::cend(cnts[0]));
// or copy-insert
//std::vector<Point> cn
//cn.reserve(cnts[0].size());
//std::copy(std::cbegin(cnts[0]), std::cend(cnts[0]), std::back_inserter(cn));
std::stringstream outputFile; // temp
for (auto const& el : cn) {
outputFile << el.arg() << "/" << el.abs() << ";";
}
}

Related

Lennard-Jones / WCA Potential Simulation

i am trying to implement a molecular dynamics simulation with the Lennard Jones potential.
I have the time evolution of the positions and velocities of the particles in multiple config files (n = 0,...,99) in steps of dt, such that t=n dt. So the actual simulation part is taken care of in that sense, for now i only have to calculate the potential energy and the force on each particle.
I already implemented a function to read in the config.dat files and put them in vectors, that part works as far as i know without an error. Then i wrote functions that calculate the force and the potential energy with a given distance r_ij between two particles (also used Newtown's third law so that i don't have to calculate the forces multiple times for the same interaction).
I also (hopefully correctly) implemented the periodic boundary conditions so that the particles can interact with their own images in the image boxes.
To test if my code works, i wanted to plot the total potential energy for all t=n dt.
However that does not work as intended because for some reason the potential energy that is written into the output files is always zero (the function for the potential energy returns zero if r_ij > r_cut, r_cut is where the potential is set to zero).
#include <iostream>
#include <math.h>
#include <fstream>
#include <stdlib.h>
#include <vector>
#include <string>
#include <utility>
#include <stdexcept>
#include <sstream>
using namespace std;
// Python >> C/C++
// Reads the initial states from the files
// The whole simulation in Python would have been as long as the function in c++ that just reads in the input
void read_input(int num_file, vector<double>& n, vector<double>& x, vector<double>& y, vector<double>& vx, vector<double>& vy, double& lx, double& ly) {
// Variable file name + opening it
ifstream file("configurations/config_" + to_string(num_file) + ".dat");
// Temp variables for reading in the file
double num, temp_x, temp_y, temp_vx, temp_vy;
// Looping over it
if (file.is_open()) {
string line;
while (getline(file, line)) {
// For the header; The header contains only the dimensions, e.g, 14 14, there are only 5 characters
if (line.length() == 5) {
stringstream dim_str(line);
dim_str >> lx >> ly;
continue;
}
// For the rest files
stringstream temp_str(line);
temp_str >> num >> temp_x >> temp_y >> temp_vx >> temp_vy;
n.push_back(num);
x.push_back(temp_x);
y.push_back(temp_y);
vx.push_back(temp_vx);
vy.push_back(temp_vy);
}
file.close();
}
}
// Calculates the potential for rij
double calc_pot(double r) {
double sigma = 1.0;
double epsilon = 1.0;
if (r <= pow(2, (1.0 / 6)) * sigma) {
double res = 4.0 * epsilon * (pow(sigma / r, 12) - pow(sigma / r, 6)) + epsilon;
return res;
}
else {
return 0;
}
}
// Calculates the force for rij
double calc_force(double r) {
double sigma = 1.0;
// Replaced the sigma^n with 1 bcs sigma = 1
double epsilon = 1.0;
if (r <= pow(2, (1.0 / 6)) * sigma) {
double res = (48.0 * epsilon / pow(r, 13)) - (24 * epsilon / pow(r, 7));
return res;
}
else {
return 0;
}
}
// Calculates the distance of the
double dist(double rx, double ry) {
return sqrt(rx * rx + ry * ry);
}
int main() {
// Misc. parameters
int N = 144;
double mass = 1.0;
double sigma = 1.0;
double epsilon = 1.0;
// Tau = sqrt(mass*sigma^2/epsilon) = (here) 1
double tau = 1.0;
double dt = 0.02;
// Vectors for the read in values for i and i+1
vector<double> n, x, y, vx, vy;
double lx, ly;
// Vector for the potential and two for the force, x and y
vector<double> epot(N), f_x(N), f_y(N);
for (int i = 0; i < N; i++) {
epot[i], f_x[i], f_y[i] = 0;
}
// Outerloop for time steps (in this case the files n = {0,..,99})
for (int k = 0; k <= 99; k++) {
string fname = "output/epot_" + to_string(k) + ".txt";
ofstream output(fname);
read_input(k, n, x, y, vx, vy, lx, ly);
// Inner two loops to accses every possible interaction without doing them twice
for (int i = 0; i < N - 1; i++) {
// Vecctor for particle i
double rix = x[i];
double riy = y[i];
for (int j = i + 1; j < N; j++) {
// Vector for particle i+1
double rjx = x[j];
double rjy = y[j];
// Periodic boundary cond.
if (rix > lx) {
rix -= lx;
}
if (riy > ly) {
riy -= ly;
}
if (rjx > lx) {
rjx -= lx;
}
if (rjy > ly) {
rjy -= ly;
}
if (rix < 0) {
rix += lx;
}
if (riy < 0) {
riy += ly;
}
if (rjx < 0) {
rjx += lx;
}
if (rjy < 0) {
rjy += ly;
}
// Component wise distance for the force
double dist_x = rix - rjx;
double dist_y = riy - rjy;
// Minimum image convention
if (abs(dist_x) > lx / 2) {
dist_x = (lx - abs(dist_x)) * (-dist_x) / abs(dist_x);
}
if (abs(dist_y) > ly / 2) {
dist_y = (ly - abs(dist_y)) * (-dist_y) / abs(dist_y);
}
// Normalized Force/R
f_x[i] += calc_force(dist_x) * (1 / dist(dist_x, dist_y));
f_y[i] += calc_force(dist_y) * (1 / dist(dist_x, dist_y));
f_y[j] += -calc_force(dist_x) * (1 / dist(dist_x, dist_y));
f_y[j] += -calc_force(dist_y) * (1 / dist(dist_x, dist_y));
// Potential energy
epot[i] += calc_pot(dist(dist_x, dist_y));
}
// Potential energy per particle
output << fixed << std::setprecision(4) << epot[i] / (N) << endl;
}
}
}
A config file looks something like this
14 14
0 0 0 1.0292605474705 0.394157727758591
1 0 1.16666666666667 1.05721528014223 1.9850461002085
2 0 2.33333333333333 1.18385526103892 0.143930912297367
3 0 3.5 -0.938850340823852 1.71993225409788
4 0 4.66666666666667 1.99468650405917 0.952210892864475
5 0 5.83333333333333 -0.985361963654284 3.05201529674118
6 0 7 2.84071317501321 0.0689241023507716
7 0 8.16666666666667 3.56152464385237 2.88858201933488
8 0 9.33333333333333 0.147896423269195 1.40592679110988
The header contains the dimensions of the simulation box, here (14,14).
Then all the lines have the corresponding values of {#Particle, x, y, velocity x, Velocity y).
The file above shows this for the first 9 particles.
I am relatively new to c/c++ so have mercy with me 😄.
Also i am aware that the code has still potential to be optimised but i will deal with that when i can calculate the force on each particle correctly.
Edit:
Here is the formula for the potential energy:
The force can be calculated via F= -d/dr U(r).

Cross the yard without getting wet

Here is the question:
There is a house with a backyard which is square bounded by
coordinates (0,0) in the southwest to (1000,1000) in
the northeast. In this yard there are a number of water sprinklers
placed to keep the lawn soaked in the middle of the summer. However,
it might or might not be possible to cross the yard without getting
soaked and without leaving the yard?
Input The input starts with a line containing an integer 1≤n≤1000, the
number of water sprinklers. A line follows for each sprinkler,
containing three integers: the (x,y)(x,y) location of the sprinkler
(0≤x,y,≤10000) and its range r (1≤r≤1000). The sprinklers will soak
anybody passing strictly within the range of the sprinkler (i.e.,
within distance strictly less than r).
The house is located on the west side (x=0) and a path is needed to
the east side of the yard (x=1000).
Output If you can find a path through the yard, output four real
numbers, separated by spaces, rounded to two digits after the decimal
place. These should be the coordinates at which you may enter and
leave the yard, respectively. If you can enter and leave at several
places, give the results with the highest y. If there is no way to get
through the yard without getting soaked, print a line containing
“IMPOSSIBLE”.
Sample Input
3
500 500 499
0 0 999
1000 1000 200
Sample output
0.00 1000.00 1000.00 800.00
Here is my thought process:
Define circle objects with x,y,r and write a function to determine if a given point is wet or not(inside the circle or not) on the circumference is not wet btw.
class circle {
int h;
int k;
int r;
public:
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
};
bool iswet(pair<int,int>* p){
if (pow(this->r - 0.001, 2) > (pow(p->first - this->h, 2) +
pow(p->second - this->k, 2) ) ) {
return true;
}
else
return false;
};
Then implement a depth first search, prioritizing to go up and right whenever possible.
However since circles are not guaranteed to be pass on integer coordinates an the result is expected in floats with double precision (xxx.xx). So if we keep everything in integers the grid suddenly becomes 100,000 x 100,000 which is way too big. Also the time limit is 1 sec.
So I thought ok lets stick to 1000x1000 and work with floats instead. Loop over int coordinates and whenever I hit a sprinkle just snap in the perimeter of the circle since we are safe in the perimeter. But in that case could not figure out how DFS work.
Here is the latest trial
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <utility>
#include <unordered_set>
#include <iomanip>
using namespace std;
const int MAXY = 1e3;
const int MAXX = 1e3;
const int MINY = 0;
const int MINX = 0;
struct pair_hash {
inline std::size_t operator()(const std::pair<int,int> & v) const {
return v.first*31+v.second;
}
};
class circle {
int h;
int k;
int r;
public:
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
};
bool iswet(pair<float,float>* p){
if (pow(this->r - 0.001, 2) > (pow(p->first - this->h, 2) + pow(p->second - this->k, 2) ) ) {
this->closest_pair(p);
return true;
}
else
return false;
};
void closest_pair(pair<float,float>* p){
float vx = p->first - this->h;
float vy = p->second - this->k;
float magv = sqrt(vx * vx + vy * vy);
p->first = this->h + vx / magv * this->r;
p->second = this->k + vy / magv * this->r;
}
};
static bool test_sprinkles(vector<circle> &sprinkles, pair<float,float>* p){
for (int k = 0; k < sprinkles.size(); k++)
if (sprinkles[k].iswet(p)) return false;
return true;
}
int main(){
int n; // number of sprinkles
while (cin >> n){
vector<circle> sprinkles_array;
sprinkles_array.reserve(n);
int h, k, r;
while (n--){
cin >> h >> k >> r;
sprinkles_array.push_back(circle(h, k, r));
}/* code */
pair<float,float> enter = make_pair(0, MAXY);
deque<pair<float,float>> mystack;
mystack.push_back(enter);
pair<float,float>* cp;
bool found = false;
unordered_set<pair<float, float>, pair_hash> visited;
while (!mystack.empty()){
cp = &mystack.back();
if (cp->first == MAXX) {
found = true;
break;
}
visited.insert(*cp);
if (cp->second > MAXY || cp->second < MINY || cp ->first < MINX ) {
visited.insert(*cp);
mystack.pop_back();
continue;
}
if (!test_sprinkles(sprinkles_array,cp)) {
continue;
}
pair<int,int> newpair = make_pair(cp->first, cp->second + 1);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first + 1 , cp->second);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first, cp->second - 1);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first - 1, cp->second);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
mystack.pop_back();
}
cout << setprecision(2);
cout << fixed;
if (found){
double xin = mystack.front().first;
double yin = mystack.front().second;
pair <float, float> p = mystack.back();
p.second++;
for (int k = 0; k < sprinkles_array.size(); k++)
if (sprinkles_array[k].iswet(&p)) break;
double xout = p.first;
double yout = p.second;
cout << xin << " " << yin << " " << xout << " " << yout << endl;
}
else
{
cout << "IMPOSSIBLE" << endl;
}
}
}
Yes #JosephIreland is right. Solved it with grouping intersecting (not touching) circles. Then these groups have maxy and min y coordinates. If it exceeds the yard miny and maxy the way is blocked.
Then these groups also have upper and lower intersection points with x=0 and x=1000 lines. If the upper points are larger than the yard maxy then the maximum entry/exit points are lower entery points.
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <utility>
#include <iomanip>
using namespace std;
const int MAXY = 1e3;
const int MAXX = 1e3;
const int MINY = 0;
const int MINX = 0;
struct circle {
int h;
int k;
int r;
float maxy;
float miny;
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
this->miny = this->k - r;
this->maxy = this->k + r;
};
};
struct group {
float maxy = -1;
float miny = -1;
vector<circle*> circles;
float upper_endy = -1;
float upper_starty = -1;
float lower_endy = -1;
float lower_starty = -1;
void add_circle(circle& c){
if ((c.maxy > this->maxy) || this->circles.empty() ) this->maxy = c.maxy;
if ((c.miny < this->miny) || this->circles.empty() ) this->miny = c.miny;
this->circles.push_back(&c);
// find where it crosses x=minx and x= maxx
float root = sqrt(pow(c.r, 2) - pow(MINX - c.h, 2));
float y1 = root + c.k;
float y2 = -root + c.k;
if (y1 > this->upper_starty) this->upper_starty = y1;
if (y2 > this->lower_starty) this->lower_starty = y2;
root = sqrt(pow(c.r, 2) - pow(MAXX - c.h, 2));
y1 = root + c.k;
y2 = -root + c.k;
if (y1 > this->upper_endy) this->upper_endy = y1;
if (y2 > this->lower_endy) this->lower_endy = y2;
};
bool does_intersect(circle& c1){
for(circle* c2 : circles){
float dist = sqrt(pow(c1.h - c2->h,2)) + sqrt(pow(c1.k - c2->k,2));
(dist < (c1.r + c2->r)) ? true : false;
};
};
};
int main(){
int n; // number of sprinkles
while (cin >> n){
vector<circle> sprinkles_array;
sprinkles_array.reserve(n);
int h, k, r;
while (n--){
cin >> h >> k >> r;
sprinkles_array.push_back(circle(h, k, r));
}/* code */
vector<group> groups;
group newgroup;
newgroup.add_circle(sprinkles_array[0]);
groups.push_back(newgroup);
for (int i = 1; i < sprinkles_array.size(); i++){
bool no_group = true;
for (group g:groups){
if (g.does_intersect(sprinkles_array[i])){
g.add_circle(sprinkles_array[i]);
no_group = false;
break;
}
}
if (no_group) {
group newgroup;
newgroup.add_circle(sprinkles_array[i]);
groups.push_back(newgroup);
}
}
float entery = MAXY;
float exity = MAXY;
bool found = true;
for (group g : groups){
if ((g.miny < MINY) && (g.maxy > MAXY)){
found = false;
break;
}
if (g.upper_starty > entery)
entery = g.lower_starty;
if (g.upper_endy > exity)
exity = g.lower_endy;
}
cout << setprecision(2);
cout << fixed;
if (found){
cout << float(MINX) << " " << entery << " " << float(MAXX) << " " << exity << endl;
}
else
{
cout << "IMPOSSIBLE" << endl;
}
}
}

Passing Arrays through Fuctions - "Error: Cannot Convert 'float**' to 'float*' for argument '1'"

Long time Reader, First time Asker.
So I'm working on a coding project of which the long term goal is to make a solar system simulator. The idea is that that it whips up a randomized solar system with a few rules like 'at formation the first planet after the frostline has to be the largest gas giant' etc, and calculates the orbits to check for stability.
Obviously it's not done yet, I'm having some trouble with using the arrays in the subroutines. I know that you can't directly take arrays in and out of functions, but you can take pointers to said arrays in and out of functions if you do it right.
I apparently have not done it right below. I've tried to comment and make the code as readable as possible, here it is.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <tuple>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <complex>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <algorithm>
//#include "mpi.h"
using namespace std;
double MyRandom(){
//////////////////////////
//Random Number Generator
//Returns number between 0-99
//////////////////////////
double y = 0;
unsigned seed = time(0);
srand(seed);
uint64_t x = rand();
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
x = (1070739 * x) % 2199023255530;
y = x / 21990232555.31 ;
return y;
}
////////////////////////
///////////////////////
tuple< char& , float& , float& , float& , int& > Star(){
////////////////////////////
//Star will generate a Star
//Randomly or User Selected
//Class, Luminosity, Probability, Radius, Mass, Temperature
//Stars always take up 99% of the mass of the system.
///////////////////////////
char Class;
string Choice;
float L, R, M;
int T;
tuple< char& , float& , float& , float& , int& > star( Class = 'i', L = 1 , R = 1 , M = 1 , T = 3000) ;
cout << "Select Star Class (OBAFGKM) or Select R for Random: ";
cin >> Choice;
if ( Choice == "R" ) {
double y;
y = MyRandom();
if (y <= 0.003) Class = 'O';
if ((y > 0.003) && (y <= 0.133)) Class = 'B';
if ((y > 0.133) && (y <= 0.733)) Class = 'A';
if ((y > 0.733) && (y <= 3.733)) Class = 'F';
if ((y > 3.733) && (y <= 11.333)) Class = 'G';
if ((y > 11.333) && (y <= 23.433)) Class = 'K';
else Class = 'M';
}
if (Class == 'O') {
L = 30000;
R = 0.0307;
M = 16;
T = 30000;
}
if (Class == 'B') {
L = 15000;
R = 0.0195;
M = 9;
T = 20000;
}
if (Class == 'A') {
L = 15;
R = 0.00744;
M = 1.7;
T = 8700;
}
if (Class == 'F') {
L = 3.25;
R = 0.00488;
M = 1.2;
T = 6750;
}
if (Class == 'G') {
L = 1;
R = 0.00465;
M = 1;
T = 5700;
}
if (Class == 'K') {
L = 0.34;
R = 0.00356;
M = 0.62;
T = 4450;
}
if (Class == 'M') {
L = 0.08;
R = 0.00326;
M = 0.26;
T = 3000;
}
return star;
}
////////////
////////////
float* Planet( float &L, float &R, float &M, int &T, int &n){
///////////////////////////
//Planet generates the Planets
//Random 1 - 10, Random distribution 0.06 - 6 JAU unless specified by User
//Frost line Calculated, First Planet after Frost line is the Jupiter
//The Jupiter will have the most mass of all Jovian worlds
//Otherwise divided into Jovian and Terrestrial Worlds, Random Masses within groups
//Also calculates if a planet is in the Habitable Zone
////////////////////////////
float frostline, innerCHZ, outerCHZ;
float a = 0.06; // a - albedo
float m = M / 100; //Mass of the Jupiter always 1/100th mass of the Star.
float sys[n];
float* system[n][5] = {{0}};
for (int i = 0 ; i < n ; i++){
sys[i] = MyRandom()/10 * 3; //Distances in terms of Sol AU
}
sort(sys, sys + n );
for (int i = 0 ; i < n ; i++){
system[i][0] = &sys[i];
system[i][1] = 0; //system[i][0] is x, system[i][1] is y
}
frostline = (0.6 * T / 150) * (0.6 * T/150) * R / sqrt(1 - a);
innerCHZ = sqrt(L / 1.1);
outerCHZ = sqrt(L / 0.53);
for (int i = 0 ; i < n ; i++){
if (system[i][0] <= &frostline) {
float tmass = m * 0.0003 * MyRandom();
system[i][2] = &tmass ; //system[i][2] is mass, [3] is marker for the Jupter
system[i][3] = 0 ;
}
if ((system[i][0] >= &frostline) && (system[i-1][0] < &frostline)){
system[i][2] = &m ;
float J = 1;
system[i][3] = &J ;
}
if ((system[i][0] >= &frostline) && (system[i-1][0] >= &frostline)) {
float jmass = m * 0.01 * MyRandom();
system[i][2] = &jmass ;
system[i][3] = 0 ;
}
if ((system[i][0] >= &innerCHZ) && (system[i][0] <= &outerCHZ)){
float H = 1;
system[i][4] = &H;
}
else system[i][4] = 0; //[4] is habitable marker
}
return system[n][5];
}
////////////
////////////
float* Time( float *system , int n){
///////////////////////////
//Time advances the solar system.
//Plots the Orbits
//Uses MPI to spread it's calculations.
///////////////////////////
return system;
}
////////////
////////////
void FinalCheck( float system){
///////////////////////////
//Final Checks
//Reports if a Planet spent the whole Time in the Habitable Zone
///////////////////////////
/*for (int i = 0 ; i < row ; i++){
if (system[i][4] == 1.0) {
cout << "Planet " << i << " in this system is Habitable." ;
}
// The Habitable stat only means liquid water can exist on the surface
// Add pi if planet enters habitable zone, minus 1 if it leaves.
// If planet was habitable but left, assuming all life was destroyed
}
*/
}
////////////
int main(){
char Class;
int T;
float L, R, M;
tuple< char , float , float , float , int > star( Class , L , R , M , T );
star = Star();
int n = MyRandom()/10 + 1;
float * system[n][5] = {{0}};
float system1[n][5] = {{0}};
system[n][5] = Planet( L , R , M, T, n);
for (int i = 0 ; i < 100 ; i++) {
system1[n][5] = Time( *system, n );
system[n][5] = &system1[n][5];
}
FinalCheck( *system[n][5]);
///////////////////////////
//Report cleans everything up and gives the results
//Shows the plot, lists the Planets
//Reports the Positions and Masses of all Planets
//Reports which was the Jupiter and which if any were Habitable
//////////////////////////
return 0;
}
The problem is when I run a compiler over this line 227 gets flagged -
system1[n][5] = Time( *system, n );
With the following error:
error: cannot convert 'float**' to 'float*' for argument '1' to 'float* Time(float*, int)
I get that this means that the compiler things I'm trying to equate a pointer-to-a-pointer with a pointer, but I'm not sure how it arrived at that conclusion or how to fix it. I'd appreciate help with this, especially the second part. I also would love to hear anything about passing arrays through subroutines as apparently I'm not doing it right, or at least not well.
Update 1 : - Got the short-term fix in and the compiler makes it through but gives a segmentation fault (core dumped) error when I try to run it. Looks like I have some reading and updates to do though with the namespace, the pointers, and possibly changing the arrays into vectors instead. Feels like if I concentrate on those first it might fix the segmentation error.
Your variable system is declared as
float * system[n][5] = {{0}};
which is a pointer to a 2D array (which will decay to float*** when passed to a function).
Your Time function is declared as
float* Time( float *system , int n);
where the 1st argument needs to be a float*.
That means this call
system1[n][5] = Time( *system, n );
should actually be something like
system1[n][5] = Time( **system, n );
That being said, there are a number of issues in your code.
To start off, don't do using namespace std;.
Also, this line float sys[n]; is not allowed. You can't have variable length arrays in c++.
float* system[n][5]
system here is a 2D array of float*s, not floats.
So, in other words, system decays to float***, *system decays to float**, **system decays to float*, and ***system decays to float.
So, the compiler is correct. You're passing what decays to a float** to Time() which expects a float*.
You're going to have to reconfigure your code to pass the right thing, whatever that is.
Side note: please be advised that the way you're creating arrays isn't valid C++ and may cause issues later.

2D Poisson-disk sampling in a specific square (not a unit square) with specific minimum distance

Is there any way I can modify the poisson-disk points generator finding here.I need to generate new poisson points using the coordinates of points in the textfile.txt to improve the distribution. below the c++ code of poisson-disk sampling in a unit square.
poissonGenerator.h:
#include <vector>
#include <random>
#include <stdint.h>
#include <time.h>
namespace PoissoGenerator
{
class DefaultPRNG
{
public:
DefaultPRNG()
: m_Gen(std::random_device()())
, m_Dis(0.0f, 1.f)
{
// prepare PRNG
m_Gen.seed(time(nullptr));
}
explicit DefaultPRNG(unsigned short seed)
: m_Gen(seed)
, m_Dis(0.0f, 1.f)
{
}
double RandomDouble()
{
return static_cast <double>(m_Dis(m_Gen));
}
int RandomInt(int Max)
{
std::uniform_int_distribution<> DisInt(0, Max);
return DisInt(m_Gen);
}
private:
std::mt19937 m_Gen;
std::uniform_real_distribution<double> m_Dis;
};
struct sPoint
{
sPoint()
: x(0)
, y(0)
, m_valid(false){}
sPoint(double X, double Y)
: x(X)
, y(Y)
, m_valid(true){}
double x;
double y;
bool m_valid;
//
bool IsInRectangle() const
{
return x >= 0 && y >= 0 && x <= 1 && y <= 1;
}
//
bool IsInCircle() const
{
double fx = x - 0.5f;
double fy = y - 0.5f;
return (fx*fx + fy*fy) <= 0.25f;
}
};
struct sGridPoint
{
sGridPoint(int X, int Y)
: x(X)
, y(Y)
{}
int x;
int y;
};
double GetDistance(const sPoint& P1, const sPoint& P2)
{
return sqrt((P1.x - P2.x)*(P1.x - P2.x) + (P1.y - P2.y)*(P1.y - P2.y));
}
sGridPoint ImageToGrid(const sPoint& P, double CellSize)
{
return sGridPoint((int)(P.x / CellSize), (int)(P.y / CellSize));
}
struct sGrid
{
sGrid(int W, int H, double CellSize)
: m_W(W)
, m_H(H)
, m_CellSize(CellSize)
{
m_Grid.resize((m_H));
for (auto i = m_Grid.begin(); i != m_Grid.end(); i++){ i->resize(m_W); }
}
void Insert(const sPoint& P)
{
sGridPoint G = ImageToGrid(P, m_CellSize);
m_Grid[G.x][G.y] = P;
}
bool IsInNeighbourhood(sPoint Point, double MinDist, double CellSize)
{
sGridPoint G = ImageToGrid(Point, CellSize);
//number of adjacent cell to look for neighbour points
const int D = 5;
// Scan the neighbourhood of the Point in the grid
for (int i = G.x - D; i < G.x + D; i++)
{
for (int j = G.y - D; j < G.y + D; j++)
{
if (i >= 0 && i < m_W && j >= 0 && j < m_H)
{
sPoint P = m_Grid[i][j];
if (P.m_valid && GetDistance(P, Point) < MinDist){ return true; }
}
}
}
return false;
}
private:
int m_H;
int m_W;
double m_CellSize;
std::vector< std::vector< sPoint> > m_Grid;
};
template <typename PRNG>
sPoint PopRandom(std::vector<sPoint>& Points, PRNG& Generator)
{
const int Idx = Generator.RandomInt(Points.size() - 1);
const sPoint P = Points[Idx];
Points.erase(Points.begin() + Idx);
return P;
}
template <typename PRNG>
sPoint GenerateRandomPointAround(const sPoint& P, double MinDist, PRNG& Generator)
{
// Start with non-uniform distribution
double R1 = Generator.RandomDouble();
double R2 = Generator.RandomDouble();
// radius should be between MinDist and 2 * MinDist
double Radius = MinDist * (R1 + 1.0f);
//random angle
double Angle = 2 * 3.141592653589f * R2;
// the new point is generated around the point (x, y)
double X = P.x + Radius * cos(Angle);
double Y = P.y + Radius * sin(Angle);
return sPoint(X, Y);
}
// Return a vector of generated points
// NewPointsCount - refer to bridson-siggraph07-poissondisk.pdf
// for details (the value 'k')
// Circle - 'true' to fill a circle, 'false' to fill a rectangle
// MinDist - minimal distance estimator, use negative value for default
template <typename PRNG = DefaultPRNG>
std::vector<sPoint> GeneratePoissonPoints(rsize_t NumPoints, PRNG& Generator, int NewPointsCount = 30,
bool Circle = true, double MinDist = -1.0f)
{
if (MinDist < 0.0f)
{
MinDist = sqrt(double(NumPoints)) / double(NumPoints);
}
std::vector <sPoint> SamplePoints;
std::vector <sPoint> ProcessList;
// create the grid
double CellSize = MinDist / sqrt(2.0f);
int GridW = (int)(ceil)(1.0f / CellSize);
int GridH = (int)(ceil)(1.0f / CellSize);
sGrid Grid(GridW, GridH, CellSize);
sPoint FirstPoint;
do
{
FirstPoint = sPoint(Generator.RandomDouble(), Generator.RandomDouble());
} while (!(Circle ? FirstPoint.IsInCircle() : FirstPoint.IsInRectangle()));
//Update containers
ProcessList.push_back(FirstPoint);
SamplePoints.push_back(FirstPoint);
Grid.Insert(FirstPoint);
// generate new points for each point in the queue
while (!ProcessList.empty() && SamplePoints.size() < NumPoints)
{
#if POISSON_PROGRESS_INDICATOR
// a progress indicator, kind of
if (SamplePoints.size() % 100 == 0) std::cout << ".";
#endif // POISSON_PROGRESS_INDICATOR
sPoint Point = PopRandom<PRNG>(ProcessList, Generator);
for (int i = 0; i < NewPointsCount; i++)
{
sPoint NewPoint = GenerateRandomPointAround(Point, MinDist, Generator);
bool Fits = Circle ? NewPoint.IsInCircle() : NewPoint.IsInRectangle();
if (Fits && !Grid.IsInNeighbourhood(NewPoint, MinDist, CellSize))
{
ProcessList.push_back(NewPoint);
SamplePoints.push_back(NewPoint);
Grid.Insert(NewPoint);
continue;
}
}
}
#if POISSON_PROGRESS_INDICATOR
std::cout << std::endl << std::endl;
#endif // POISSON_PROGRESS_INDICATOR
return SamplePoints;
}
}
and the main program is:
poisson.cpp
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <memory.h>
#define POISSON_PROGRESS_INDICATOR 1
#include "PoissonGenerator.h"
const int NumPoints = 20000; // minimal number of points to generate
int main()
{
PoissonGenerator::DefaultPRNG PRNG;
const auto Points =
PoissonGenerator::GeneratePoissonPoints(NumPoints,PRNG);
std::ofstream File("Poisson.txt", std::ios::out);
File << "NumPoints = " << Points.size() << std::endl;
for (const auto& p : Points)
{
File << " " << p.x << " " << p.y << std::endl;
}
system("PAUSE");
return 0;
}
Suppose you have a point in the space [0,1] x [0,1], in the form of a std::pair<double, double>, but desire points in the space [x,y] x [w,z].
The function object
struct ProjectTo {
double x, y, w, z;
std::pair<double, double> operator(std::pair<double, double> in)
{
return std::make_pair(in.first * (y - x) + x, in.second * (z - w) + w);
}
};
will transform such an input point into the desired output point.
Suppose further you have a std::vector<std::pair<double, double>> points, all drawn from the input distribution.
std::copy(points.begin(), points.end(), points.begin(), ProjectTo{ x, y, w, z });
Now you have a vector of points in the output space.

Perlin noise, blocky,c++

Okay first of all, I am trying to implement the Perlin noise algorithm, and I managed to achived something strange, and I can't find the solution. I am using matlab to visualize the results I have already checked this question:
"Blocky" Perlin noise
I am doing it from this website:
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
And another website which I can't find right now but I will update as soon as I can.
So here are some pictures about the problem:
This is the problem if increase zoom
http://i.stack.imgur.com/KkD7u.png
And here are the .cpp-s:
//perlin.cpp
#include "Perlin_H.h"
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <random>
using namespace std;
double Perlin::interp1(double a, double b, double x) {
double ft = x * 3.1415927;
double f = (1.0-cos(ft)) * 0.5;
//return (b-x > b-1/2) ? b-x : a+x;
return a * (1.0-f) + b * f;
}
double Perlin::smoothNoise(double x,double y) {
double corners = ( rand2(x-1, y-1)+rand2(x+1, y-1)+rand2(x-1, y+1)+rand2(x+1, y+1) ) / 16;
double sides = ( rand2(x-1, y) +rand2(x+1, y) +rand2(x, y-1) +rand2(x, y+1) ) / 8;
double center = rand2(x,y)/4;
return corners + sides +center;
}
double Perlin::lininterp1(double a,double b, double x) {
return a*(1-x) + b * x;
}
double Perlin::rand2(double x, double y) {
int n = (int)x + (int)y*57;
//n=pow((n<<13),n);
n=(n<<13)^n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
double Perlin::noise(double x, double y) {
double floorX = (double)floor(x);
double floorY = (double)floor(y);
double s,t,u,v;
s = smoothNoise(floorX,floorY);
t = smoothNoise(floorX+1,floorY);
u = smoothNoise(floorY,floorY+1);
v = smoothNoise(floorX+1,floorY+1);
double int1 = interp1(s,t,x-floorX);
double int2 = interp1(u,v,x-floorX);
return interp1(int1,int2,y-floorY);
}
//main.cpp
#include "Perlin_H.h"
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <fstream>;
using namespace std;
int main() {
const int h=64,w=64,octaves=2;
double p=1/1;
double zoom = 30;
Perlin perlin;
double map[h][w];
ofstream output;
output.open("map.txt");
for(int i = 0; i < h ; i++) {
for(int j = 0; j < w ; j++) {
map[i][j] = 0;
}
}
double freq = 2;
for(int i = 0; i < h ; i++) {
for(int j = 0; j < w ; j++) {
double getnoise = 0;
for(int a=0; a < octaves; a++) {
double freq = pow(2,a);
double amp = pow(p,a);
getnoise = perlin.noise((((double)i)*freq)/zoom-(a*10),
((((double)j))*freq)/zoom+(a*10))*amp;
int color = (int)((getnoise * 128.0) + 128.0);
if(color > 255) color = 255;
if(color < 0) color = 0;
map[i][j] = color;
}
output << map[i][j] << "\t";
}
output << "\n";
}
output.close();
system("PAUSE");
return 0;
}
It's a typo!
s = smoothNoise(floorX,floorY);
t = smoothNoise(floorX+1,floorY);
u = smoothNoise(floorY,floorY+1);
v = smoothNoise(floorX+1,floorY+1);
Try:
u = smoothNoise(floorX, floorY +1)
This explains why the diagonal didn't have the blocky appearance (where x=y), and why many of the common feature shapes are subtly off in a mirrored and skewed fashion.
Since it is generally obvious that rand2(floor(y), floor(y)+1) != rand2(floor(x), floor(y+1)) the cell discontinuity will result.
Finding no mathematical error in your implementation, I suspect this is a number format issue.
Such block patterns are created when the grid point values are not actually the same when fetched from different sides - when rand2(floor(n) +1 ,y) != rand2(floor(n+1) ,y)
To fix it, declare floorX to be an int or long instead, and pass it as such to smoothNoise() and rand2().
This can happen due to floating point error in the representation of the Integer values floorX , floorX + 1. The epsilon of magnitude ulp or less can have either sign. the results of addition [floor(n) + 1] and flooring directly [floor(n+1)] are bound by different code, and so need not share a pattern of choosing which side to err on. When the results err on different sides, the int type cast strips the 0.99999999999 and the 0.0000000001 equally, treating the mathematically equivalent numbers as different.