how to store an object in a variable in processing - processing

I'm coming from jQuery and JS and would like to go a little bit into Processing.
I like it because it has a quite good reference where I get examples etc.
But one thing I can't get is how I can store objects into a variable.
Example jQuery:
var anydiv = $('#anydiv');
and I have my object stored.
In Processing it does not seem that simple because it has different types.
I can store a number pretty easy:
float anynumber = 10;
or a string etc. But how can I e.g. store a new point in a var?
var anypoint = point(0, 0);
Thanks in advance.

objects need to have classes. Processing comes with some predefined, but "point" isn't one of them. So you write a point class,
class Point {
float x, y;
Point(float _x, float y) {
x = _x;
y = _y;
}
String toString() { return x + "/" + y; }
}
and then you can store it like any other typed object:
Point p = new Point(0,0);
float xcoordinate = p.x;
float ycoordinate = p.y;
p.x += 200;
p.y += 100;
println(p);
And no, capital first letter is not required, but that's the convention. Stick with it (don't go defining classes "point", unless you're never going to show people your code or ask for help. Make sure to get the syntax conventions right =)

Related

Can someone please check my code it won't work, I checked it and i kind find what's wrong. (Processing)

The code is supposed to make a random shape with four points if I click my mouse. but for some reason, it won't work. can someone please overview my code and tell me what the problem is and how to fix
void setup(){
int a = 50;
int b = 50;
int c = 50;
int d = 50;
int e = 50;
int f = 50;
int g = 50;
int h = 50;
int red = 50;
int blue = 50;
int green = 50;
a = random(1,500);
b = random(1,400);
c = random(1,500);
d = random(1,400);
e = random(1,500);
f = random(1,400);
g = random(1,500);
h = random(1,400);
red = random(1,255);
blue = random(1,255);
green = random(1,255);
size(500,400);
}
void drawQuad() {
fill(red,blue,green);
stroke(red,blue,green);
quad(a,b,c,d,e,f,g,h);
}
void draw() {
if (mousePressed) {
drawQuad();
}
}
You didn't actually explain anything you tried or what you think the problem is. Please do so in the future. Read and memorize this article, it'll help you a lot down the line. People tend to not answer your questions if they have to do the work for you.
I took the liberty of running your code locally and I was immediately thrown the following error:
cannot convert from float to int
This should indicate to you that you are trying to convert a float value to an int, which is not allowed in Java (the language that Processing is based on), unless you explicitly cast the float to an integer.
The Processing coding environment even highlights where you went wrong:
At this point you should have taken a look at the documentation of the random function which says the random function returns a float.
Thus, you were trying to fill an integer value with a float. Again, Java cannot implicitly convert a float to an int, and thus throws an exception.
What you want to do is int(random(<value>)), so you convert the float that's returned by the random function to an int. (Note: This does NOT make the original output value an integer, but rounds the outputted float down - 2.0f becomes 2, 2.1f becomes 2, 2.5f becomes 2, and 2.9999999f becomes 2)).
Then there's another problem with your code.
You are setting all your values in the setup() function, which runs only once. You are then reusing these randomly selected values each time you call drawQuad(). If you want them to be random each and every time you click, you need to call the random() function inside the drawQuad() function.
This is kind of interesting:
float a = 50;
float b = 50;
float c = 50;
float d = 50;
float e = 50;
float f = 50;
float g = 50;
float h = 50;
void setup(){
size(500,400);
}
void drawQuad() {
fill(random(1,255),random(1,255),random(1,255));
stroke(random(1,255),random(1,255),random(1,255));
quad(random(1,500),random(1,400),random(1,500),random(1,400),random(1,500),random(1,400),random(1,500),random(1,400));
}
void draw() {
if (mousePressed) {
drawQuad();
}
}

3D Line-of-Sight algorithm

I'm currently implementing a line-of-sight algorithm that will tell me the points I can and cannot see along a line. So, if I am standing atop some hilly terrain, I can know where I can and cannot see.
The line that is generated from point A to point B includes a number of points evenly spaced between A and B. Starting from A, I see what the angle of elevation is between A and B. I note that as my alphaAngle.
Next, for each point between A and B, I get the angle of elevation between A and that point. If that point is the highest angle of elevation so far(excluding alphaAngle), then I mark it as such. Otherwise, it has a lower angle of elevation and therefor I should not be able to see it, and mark that point as having hasLOS = false.
Here are some object definitions I use:
struct TerrainProfilPnt
{
double m_x_lon; //lon
double m_y_lat; //lat
double m_z_elev; //elev
bool m_hasLOS; //Does this point have line of sight from another point?
};
class TerrainProfilePartitioner; // Holds a collection of points that make up the line
Here is my algorithm written out, however it doesn't return the correct results. Either it claims it has LOS when it shouldn't (like going from behind one hill to the opposite side of another hill, I shouldn't be able to see that).
Or it claims that I cannot see the end point when I should (Top of a hill to the valley beneath it). So, I am suspecting that either my implementation of finding the line-of-sight is incorrect, or I am implementing it wrong in code.
using Point = TerrainProfilePnt;
auto pointsInLine = terrainProfilePartitioner->GetPoints();
auto& pointsVec = pointsInLine->GetVector();
std::vector<Point> terrainProfileVec;
terrainProfileVec.reserve(pointsVec.size());
double start_xlon = 0.0f;
double start_ylat = 0.0f;
double start_zelev = 0.0f;
double end_xlon = 0.0f;
double end_ylat = 0.0f;
double end_zelev = 0.0f;
//The angle between the starting point and the ending point
double initialElevAngle = 0.0f;
//Assemble the first and last points
start_xlon = pointsVec.front().x();
start_ylat = pointsVec.front().y();
GetPointElevation(start_xlon, start_ylat, start_zelev);
end_xlon = pointsVec.back().x();
end_ylat = pointsVec.back().y();
GetPointElevation(end_xlon, end_ylat, end_zelev);
//Calculate the angle between the beginning and ending points
initialElevAngle = atan2(start_zelev, end_zelev) * 180 / M_PI;
Point initialPoint;
initialPoint.m_x_lon = start_xlon;
initialPoint.m_y_lat = start_ylat;
initialPoint.m_z_elev = start_zelev;
initialPoint.m_hasLOS = true;
//pointsVec.push_back(initialPoint);
terrainProfileVec.push_back(initialPoint);
double oldAngle = 0.0f;;
bool hasOldAngle = false;
for (std::size_t i = 1; i < pointsVec.size(); ++i)
{
Point p;
p.m_x_lon = pointsVec.at(i).x();
p.m_y_lat = pointsVec.at(i).y();
GetPointElevation(p.m_x_lon, p.m_y_lat, p.m_z_elev);
double newAngle = atan2(start_zelev, p.m_z_elev) * 180 / M_PI;
if (!hasOldAngle)
{
hasOldAngle = true;
oldAngle = newAngle;
p.m_hasLOS = true;
}
else
{
if (newAngle < oldAngle)
{
p.m_hasLOS = false;
}
else
{
oldAngle = newAngle;
p.m_hasLOS = true;
}
}
}
auto terrainPrfileSeq = new Common::ObjectRandomAccessSequence<TerrainProfilePnt>(terrainProfileVec);
return terrainPrfile
atan2(start_zelev, p.m_z_elev) is meaningless. You need
atan2(distance, p.m_z_elev - start_zelev);
where distance is horizontal distance between p and initialPoint.
I see few problems: You are not sorting the points by distance from A ascending and use only elevation. Also using goniometrics for each map location which is probably slow. I would use different approach instead:
set LOS=false for whole map
write a DDA line interpolation
P(t)=A+(B-A).t
where (B-A) is your viewing direction and t is parameter incrementing by step smaller then your grid size (so you do not miss anything). This would give you long,lat without any slow goniometrics.
Then find the object on your map. If it is topology sorted then this is either O(1) or O(log(n).log(m))
test each actual location P(t)
for visibility. If true set LOS=true and loop #2 otherwise stop the whole thing.
btw this is sometimes called ray-casting.

2D Elastic Collision with SFML

I'm a complete beginner to OOP and I'm trying to figure out the best way to write a program for 2D collision of circles of equal mass in SFML C++. I want to generate two or more circles in a box with set starting velocity, but random starting position and direction, then have them interact. I'm having a lot of difficulty with the pseudocode for the mechanics since my physics is very rusty. I found this equation for 2D elastic collisions on wiki:
Does this mean that I should use this for both the x and y coordinates for each ball? I was thinking of doing something like this for the balls and velocities:
std::vector<sf::CircleShape> balls;
std::vector<sf::Vector2f> Xvelocities; // (magnitudes, directions)
std::vector<sf::Vector2f> Yvelocities; // (magnitudes, directions)
and I wrote a collision function like this:
bool Collision_Detection(sf::CircleShape &ball1, sf::CircleShape &ball2)
{
bool collision = false;
float distance = sqrt(pow(ball2.getPosition().x - ball1.getPosition().x, 2) +
pow(ball2.getPosition().y - ball1.getPosition().y, 2));
if (distance <= ball1.getRadius() + ball2.getRadius() + 4)
collision = true;
return collision;
The detection sometimes works and sometimes gets stuck, I'm not sure if it's a problem with the logic or if the performance is bad and I need to do bounding-box collision first.
Does how I'm going about this make any sense? Is there something I'm overlooking or a more standard way that people usually code this?
For rectangles there are sf::Rect<typename T> with the intersects()-method but nothing like sf::Circle<typename T> and such a method. This is because SFML needs a rectangle-class in for example the management of textures. The problem with no support for circles facing other SFML-developers too. So one of them created an SFML "extension" wich add a sf::Circle<typename T>
Here are his code:
namespace sf
{
template <typename T>
class Circle
{
public:
T x, y;
T radius;
Circle<T>()
{
this->x = T(0);
this->y = T(0);
this->radius = T(0);
}
Circle<T>(T _x, T _y, T _radius)
{
this->x = _x + _radius;
this->y = _y + _radius;
this->radius = _radius;
}
Circle<T>(sf::CircleShape cShape)
{
this->x = T(cShape.getRadius() + cShape.getPosition().x);
this->y = T(cShape.getRadius() + cShape.getPosition().y);
this->radius = T(cShape.getRadius());
}
bool intersects(sf::Circle<T> circle)
{
return (sqrt(pow(this->x - circle.x, 2) + pow(this->y - circle.y, 2)) >= this->radius + circle.radius)
}
bool contains(sf::Vector2<T> vecT)
{
return (sqrt(float(pow(float(this->x - vecT.x), (float)2) + pow(float(this->y - vecT.y), (float)2))) <= this->radius)
}
};
typedef sf::Circle<int> IntCircle;
typedef sf::Circle<double> DoubleCircle;
typedef sf::Circle<float> FloatCircle;
typedef sf::Circle<unsigned int> UintCircle;
}
You can use it exactly like the rectangles. The author also provided an example:
sf::CircleShape sfCircle(20);
sfCircle.setPosition(100, 100);
sf::FloatCircle myCircle(sfCircle);
// or:
// sf::FloatCircle myCircle(100, 100, 20);
// ---------------------------------------
// or:
// sf::FloatCircle myCircle;
// myCircle.radius = 20;
// myCircle.x = 100 + myCircle.radius;
// myCircle.y = 100 + myCircle.radius;
if (myCircle.contains((sf::Vector2f)sf::Mouse::getPosition(window)))
{
//Collision.
}
I hope this can help you a bit.

Filter points XY by distance with LINQ

I have a list of points XY and I want to group them by a given distance, let's say all the points that are at x distance between them should be grouped in different list.
Basically if I have A=(0,0), B=(0,1), C=(0,2), I want to group all points that have a maxDistance of 1, in order to obtain :[[A,B],[C]] ;
I didn't really understand your question, so I'm not really sure how you want to do the grouping, but this might start you off in the right direction, at least.
(Written in VB, but near-identical in C# - You also didn't state your language preference):
Dim MyPoints As New List(Of Point)
MyPoints.Add(New Point(0, 0))
MyPoints.Add(New Point(0, 1))
MyPoints.Add(New Point(0, 2))
Dim query = From pt1 In MyPoints
From pt2 In MyPoints
Where Not (pt1.Equals(pt2))
Select New With {.pt1 = pt1, .pt2 = pt2, .dist = Math.Sqrt((pt1.X - pt2.X) ^ 2 + (pt1.Y - pt2.Y) ^ 2)}
What are you trying to do is named clustering, which means grouping a set of data (two dimensional points in your case) into a set of groups with some characteristics (a given distance between points). I strongly recommend to read link provided above to understand it better. You might be interested in two types of clustering:
hierarchical clustering, which creates groups based on distance connectivity,
centroids, which creates groups "surrounding" centers of groups
It all depends how much data you have. For small sets you can try to implement some simple algorithms by yourself. For bigger data, I would prefer to use third-party library like Numl which contains methods for both abovementioned types.
Here is an example code of clustering using Numl. Given class:
class Point
{
[Feature]
public double X { get; set; }
[Feature]
public double Y { get; set; }
public Point(double X, double Y)
{
this.X = X;
this.Y = Y;
}
public override string ToString()
{
return string.Format("({0}; {1})", X, Y);
}
}
you can write:
var model = new HClusterModel();
var desc = Descriptor.Create<Point>();
var linker = new CentroidLinker(new EuclidianDistance());
var data = new List<Point>() { new Point(0.0, 1.0),
new Point(0.0, 2.0),
new Point (10.0, 0.0) };
var result = model.Generate(desc, data, linker);
foreach (var cluster in result.Children)
{
Console.WriteLine("Cluster:");
Console.WriteLine(string.Join(", ", cluster.Members.OfType<Point>()));
}
which results in:
I had a stab at it, although this probably isn't a fantastically efficient way to do things; the link in Konrad's answer seems like a good place to explore.
I'm not entirely sure how you're defining "within range", so I assumed a simple distance calculation.
// Set up some points
List<Point> Points = new List<Point>();
Points.Add(new Point(0, 0));
Points.Add(new Point(0, 1));
Points.Add(new Point(0, 2));
// Distance
int maxDistance = 1;
// Replace as appropriate
Func<Point, Point, int, bool> myDistanceFunction = delegate(Point p1, Point p2, int range)
{
// Same coordinate.
if (p1 == p2)
return true;
int xDelta = p1.X - p2.X;
int yDelta = p1.Y - p2.Y;
double distance = Math.Sqrt(xDelta * xDelta + yDelta * yDelta);
return (distance <= range);
};
// Loop through all points and calculate distance to all other points.
var Results = Points.Select(firstPoint => new
{
TargetPoint = firstPoint,
PointsInRange = Points
.Where(secondPoint =>
(secondPoint != firstPoint) && // Will you allow same coordinates?
myDistanceFunction(secondPoint, firstPoint, maxDistance))
});
// Spit the results out.
foreach (var result in Results)
{
Console.WriteLine("Point {0} - Points within {1} unit(s):", result.TargetPoint, maxDistance);
foreach (var point in result.PointsInRange)
{
Console.WriteLine("\t{0}", point);
}
}
Output:
Point {X=0,Y=0} - Points within 1 unit(s):
{X=0,Y=1}
Point {X=0,Y=1} - Points within 1 unit(s):
{X=0,Y=0}
{X=0,Y=2}
Point {X=0,Y=2} - Points within 1 unit(s):
{X=0,Y=1}
There's room for improvement e.g. it doesn't feel smart to calculate distances for pairs of points twice, and I'm not if you'll allow duplicate coordinates, but there might be something of use in there.
You could also write the distance function as a lamba expression, although I'm not sure it's clearer.
Func<Point, Point, int, bool> myDistanceFunction =
(
(p1, p2, range) => Math.Sqrt(
((p1.X - p2.X) * (p1.X - p2.X)) +
((p1.Y - p2.Y) * (p1.Y - p2.Y))
) <= range
);
Sorry to all, i made a post not so clear, basically im using c# and i was excluding clustering for specific purpose, let's say i have some points and their ids and i need to "cluster them", keeping information about ids , then simply made a medium point on X axis, cos im interested only in grouping by that position attribute.
At the end, points are maximum 10, and keeping information about ids is very important to know who is where, so i thought to collect ids of points close enough and then use that list of list of coordinates to make out results, did it very raw, cos im in a rush, but fully opened to further implementation, just im not able to use linq :)
So i used something like this :
// class to hold information
public class userObject{
public string id;
public Vector3D position=Vector3D.Zero;
public userObject(string Id, Vector3D Position){
id=Id;
position=Position;
}
}
// list of grouped ids (nanocluster :)
public Dictionary<int, List<userObject>> slots ;
private void forceCheck(){
// create list of object from incoming coordinates (ids and point vector3d)
List<userObject> users=new List<userObject>();
for(int a=0;a<FId_In.SliceCount;a++){
userObject uo=new userObject(FId_In[a],FPositions_In[a]);
users.Add(uo);
}
// Clean result, this is different in another version im working on
slots =new Dictionary<int,List<userObject>>();
// check for close points ( a couple of lines should be changed to achieve a real clustring, but this way i can control all points will not create an horizontal cluster, told u raw mode on
for(int k=0;k<users.Count;k++){
List<userObject> matches=new List<userObject>();
// Check if ids is already registered in one slot
int isInSlot=checkIdInSlots(users[k].id);
if(isInSlot==-1){
matches.Add(users[k]);
for(int j=k+1;j<users.Count;j++){
// call a function to check x distance, but can use full vector3d when needed
if(checkClose(users[k].position,users[j].position,FXThreshold_In[0])){
matches.Add(users[j]);
}
}
// finally add entry with grouped ids....sure all this is a line of linq :D
addNewSlot(matches);
}
}
}
WOuld be nice to understand better how linq can be used to achive same result, sure can be more robust, thank you all :)

Fast algorithm for image distortion

I am working on a tool which distorts images, the purpose of the distortion is to project images to a sphere screen. The desired output is as the following image.
The code I use is as follow - for every Point(x, y) in the destination area, I calculate the corresponding pixel (sourceX, sourceY) in the original image to retrieve from.
But this approach is awkwardly slow, in my test, processing the sunset.jpg (800*600) requires more than 1500ms, if I remove the Mathematical/Trigonometrical calculations, calling cvGet2D and cvSet2D alone require more than 1200ms.
Is there a better way to do this? I am using Emgu CV (a .NET wrapper library for OpenCV) but examples in other language is also OK.
private static void DistortSingleImage()
{
System.Diagnostics.Stopwatch stopWatch = System.Diagnostics.Stopwatch.StartNew();
using (Image<Bgr, Byte> origImage = new Image<Bgr, Byte>("sunset.jpg"))
{
int frameH = origImage.Height;
using (Image<Bgr, Byte> distortImage = new Image<Bgr, Byte>(2 * frameH, 2 * frameH))
{
MCvScalar pixel;
for (int x = 0; x < 2 * frameH; x++)
{
for (int y = 0; y < 2 * frameH; y++)
{
if (x == frameH && y == frameH) continue;
int x1 = x - frameH;
int y1 = y - frameH;
if (x1 * x1 + y1 * y1 < frameH * frameH)
{
double radius = Math.Sqrt(x1 * x1 + y1 * y1);
double theta = Math.Acos(x1 / radius);
int sourceX = (int)(theta * (origImage.Width - 1) / Math.PI);
int sourceY = (int)radius;
pixel = CvInvoke.cvGet2D(origImage.Ptr, sourceY, sourceX);
CvInvoke.cvSet2D(distortImage, y, x, pixel);
}
}
}
distortImage.Save("Distort.jpg");
}
Console.WriteLine(stopWatch.ElapsedMilliseconds);
}
}
From my personal experience, I was doing some stereoscopic vision stuff, the best way to talk to openCV is through own wrapper, you could put your method in c++ and call it from c#, that would give you 1 call to native, faster code, and because under the hood Emgu's keeping OpenCV data, it's also possible to create an image with emgu, process it natively and enjoy processed image in c# again.
The get/set methods looks like Gdi's GetPixel / SetPixel ones, and, according to documentation they are "slow but safe way".
For staying with Emgu only, documentation tells that if you want to iterate over pixels, you should access .Data property:
The safe (slow) way
Suppose you are working on an Image. You can obtain the pixel on the y-th row and x-th column by calling
Bgr color = img[y, x];
Setting the pixel on the y-th row and x-th column is also simple
img[y,x] = color;
The fast way
The Image pixels values are stored in the Data property, a 3D array. Use this property if you need to iterate through the pixel values of the image.

Resources