How would one draw an arbitrary curve in createJS - createjs

I am attempting to write a function using createJS to draw an arbitrary function and I'm having some trouble. I come from a d3 background so I'm having trouble breaking out of the data-binding mentality.
Suppose I have 2 arrays xData = [-10, -9, ... 10] and yData = Gaussian(xData) which is psuedocode for mapping each element of xData to its value on the bell curve. How can I now draw yData as a function of xData?
Thanks

To graph an arbitrary function in CreateJS, you draw lines connecting all the data points you have. Because, well, that's what graphing is!
The easiest way to do this is a for loop going through each of your data points, and calling a lineTo() for each. Because the canvas drawing API starts a line where you last 'left off', you actually don't even need to specify the line start for each line, but you DO have to move the canvas 'pen' to the first point before you start drawing. Something like:
// first make our shape to draw into.
let graph = new createjs.Shape();
let g = graph.graphics
g.beginStroke("#000");
xStart = xData[0];
yStart = yourFunction(xData[0]);
g.moveTo(xStart, yStart);
for( let i = 1; i < xData.length; i++){
nextX = xData[i], but normalized to fit on your graph area;
nextY = yourFunction(xData[i]), but similarly normalized;
g.lineTo(nextX, nextY);
}
This should get a basic version of the function drawing! Note that the line will be pretty jagged if you don't have a lot of data points, and you'll have to treat (normalize) your data to make it fit onto your screen. For instance, if you start at -10 for X, that's off the screen to the left by 10 pixels - and if it only runs from -10 to +10, your entire graph will be squashed into only 20 pixels of width.
I have a codepen showing this approach to graphing here. It's mapped to hit every pixel on the viewport and calculate a Y value for it, though, rather than your case where you have input X values. And FYI, the code for graphing is all inside the 'run' function at the top - everything in the PerlinNoiseMachine class is all about data generation, so you can ignore it for the purposes of this question.
Hope that helps! If you have any specific follow-up questions or code samples, please amend your question.

Related

Moving player on Y axis in Godot 2D

I'm new to Godot.
I'm trying to make my player move vertically just like when it's moving horizontally.
I've tried a couple of thoughts, but unfortunately, I couldn't move him the I want him to move.
I want to code my vertical movement in a similar way to my following horizontal movement code if possible:
var direction: = Vector2(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"), 0.0
)
velocity = speed * direction
velocity = move_and_slide(velocity)
And if it's not possible, how can I code it?
Once upon a time there were vectors. I'm not in the mood to make yet another Introduction to Vector Algebra or to explain How to Work With Arbitrarily Oriented Vectors. Perhaps you might be interested in Math for Game Devs.
In this case, what you need to know is that 2D Vectors have an horizontal an a vertical component (usually called x and y respectively). And you are leaving your vertical component at zero, here:
var direction: = Vector2(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"), 0.0
)
So… Er… Don't do that. You say you want it to be like the horizontal, so something like this:
var direction: = Vector2(
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
)
In computer graphics the vertical component in 2D often goes downwards, due to historical reasons. There are different conventions for 3D, but that is not the issue at hand, pun intended.
The other lines you have already work with arbitrary vectors. You don't need to change them, nor repeat them.

Constructing a bubble trellis plot with lattice in R

First off, this is a homework question. The problem is ex. 2.6 from pg.26 of An Introduction to Applied Multivariate Analysis. It's laid out as:
Construct a bubble plot of the earthquake data using latitude and longitude as the scatterplot and depth as the circles, with greater depths giving smaller circles. In addition, divide the magnitudes into three equal ranges and label the points in your bubble plot with a different symbol depending on the magnitude group into which the point falls.
I have figured out that symbols, which is in base graphics does not work well with lattice. Also, I haven't figured out if lattice has the functionality to change symbol size (i.e. bubble size). I bought the lattice book in a fit of desperation last night, and as I see in some of the examples, it is possible to symbol color and shape for each "cut" or panel. I am then working under the assumption that symbol size could then also be manipulated, but I haven't been able to figure out how.
My code looks like:
plot(xyplot(lat ~ long | cut(mag, 3), data=quakes,
layout=c(3,1), xlab="Longitude", ylab="Latitude",
panel = function(x,y){
grid.circle(x,y,r=sqrt(quakes$depth),draw=TRUE)
}
))
Where I attempt to use the grid package to draw the circles, but when this executes, I just get a blank plot. Could anyone please point me in the right direction? I would be very grateful!
Here is the some code for creating the plot that you need without using the lattice package. I obviously had to generate my own fake data so you can disregard all of that stuff and go straight to the plotting commands if you want.
####################################################################
#Pseudo Data
n = 20
latitude = sample(1:100,n)
longitude = sample(1:100,n)
depth = runif(n,0,.5)
magnitude = sample(1:100,n)
groups = rep(NA,n)
for(i in 1:n){
if(magnitude[i] <= 33){
groups[i] = 1
}else if (magnitude[i] > 33 & magnitude[i] <=66){
groups[i] = 2
}else{
groups[i] = 3
}
}
####################################################################
#The actual code for generating the plot
plot(latitude[groups==1],longitude[groups==1],col="blue",pch=19,ylim=c(0,100),xlim=c(0,100),
xlab="Latitude",ylab="Longitude")
points(latitude[groups==2],longitude[groups==2],col="red",pch=15)
points(latitude[groups==3],longitude[groups==3],col="green",pch=17)
points(latitude[groups==1],longitude[groups==1],col="blue",cex=1/depth[groups==1])
points(latitude[groups==2],longitude[groups==2],col="red",cex=1/depth[groups==2])
points(latitude[groups==3],longitude[groups==3],col="green",cex=1/depth[groups==3])
You just need to add default.units = "native" to grid.circle()
plot(xyplot(lat ~ long | cut(mag, 3), data=quakes,
layout=c(3,1), xlab="Longitude", ylab="Latitude",
panel = function(x,y){
grid.circle(x,y,r=sqrt(quakes$depth),draw=TRUE, default.units = "native")
}
))
Obviously you need to tinker with some of the settings to get what you want.
I have written a package called tactile that adds a function for producing bubbleplots using lattice.
tactile::bubbleplot(depth ~ lat*long | cut(mag, 3), data=quakes,
layout=c(3,1), xlab="Longitude", ylab="Latitude")

Adding a second x axis to a TGraph in the CERN ROOT program

does anyone know the method or code to add a second x axis to a TGraph in CERN's ROOT program? Ive been searching the root website and its documentation almost always confuses me. What i need is just one plot of data, but a second X axis on top whose values are a function of the bottom x axis' values. Its basically so lazy people dont have to convert from the numbers of the bottom x axis to the top x axis.
For a simple example (if i wasnt clear)
Say you have a sine curve which is some function of theta. On the top x axis we could have degrees whereas on the bottom we could have radians with 360deg corresponding to 2pi rad...
Any help would be appreciated!
TGaxis is the class you are looking for to draw extra axes wherever you desire. Grabbing the world coordinate for your pad you can then superimpose like so. Replace low and high with the appropriate limits.
// your graph code here...
TGraph->Draw("AP");
TGaxis *axis = new TGaxis(gPad->GetUxmin(),gPad->GetUymax(),gPad->GetUxmax(),gPad->GetUymax(),low,high,510,"+L");
axis->Draw();
Check out TGaxis documentation for more examples.
(A previous answer I had was deleted as it was just a link to the site listed as a reference below. I hope this is more in line with the community guidelines.)
I think this might do what you want.
void axis2() {
TH1F *h = new TH1F("h","test",30,-3,3);
h->FillRandom("gaus",10000);
h->Draw();
TText t;
t.SetTextSize(0.02);
t.SetTextAlign(22);
Double_t yt = - h->GetMaximum()/15.;
for (Int_t i=1;i<=30;i++) t.DrawText(h->GetBinCenter(i),yt,Form("%d",i%10));
}
It doesn't create another taxis but shows you how to draw text at the same location of the axis. The answer comes from Rene Brun himself (one of the main authors of root) so I don't think you can have two x axes.
Source:
http://root.cern.ch/phpBB3/viewtopic.php?f=3&t=7110
Here is an example showing how to proceed.
https://root.cern/doc/master/twoscales_8C.html

Draw a scatterplot matrix using glut, opengl

I am new to GLUT and opengl. I need to draw a scatterplot matrix for n dimensional array.
I have saved the data from csv to a vector of vectors and each vector corresponds to a row. I have plotted just one scatterplot. And used GL_LINES to draw the grid. My questions
1. How do I draw points in a particular grid? Using GL_POINTS I can only draw points in the entire window.
Please let me know need any further info to answer this question
Thanks
What you need to do is be able to transform your data's (x,y) coordinates into screen coordinates. The most straightforward way to do it actually does not rely on OpenGL or GLUT. All you have to do is use a little math. Determine the screen (x,y) coordinates of the place where you want a datapoint for (0,0) to be on the screen, and then determine how far apart you want one increment to be on the screen. Simply take your original data points, apply the offset, and then scale them, to get your screen coordinates, which you then pass into glVertex2f() (or whatever function you are using to specify points in your API).
For instance, you might decide you want point (0,0) in your data to be at location (200,0) on your screen, and the distance between 0 and 1 in your data to be 30 pixels on the screen. This operation will look like this:
int x = 0, y = 0; //Original data points
int scaleX = 30, scaleY = 30; //Scaling values for each component
int offsetX = 100, offsetY = 100; //Where you want the origin of your graph to be
// Apply the scaling values and offsets:
int screenX = x * scaleX + offsetX;
int screenY = y * scaleY + offsetY;
// Calls to your drawing functions using screenX and screenY as your coordinates
You will have to determine values that make sense for the scalaing and offsets. You can also have your program use different values for different sets of data, so you can display multiple graphs on the same screen. But this is a simple way to do it.
There are also other ways you can go about this. OpenGL has very powerful coordinate transformation functions and matrix math capabilities. Those may become more useful when you develop increasingly elaborate programs. They're most useful if you're going to be moving things around the screen in real-time, or operating on incredibly large data sets, as they allow you to perform these mathematical calculations very quickly using your graphics hardware (which is able to do them much faster than the CPU). However, the time it takes for the CPU to do simple calculations like those where you only are going to do them once or very infrequently on limited sets of data is not a problem for computers today.

OpenGL models show grid-like lines

Shading problem solved; grid lines persist. See Update 5
I'm working on an .obj file loader for OpenGL using Objective-C.
I'm trying to get objects to load and render them with shading. I'm not using any textures, materials, etc. to modify the model besides a single light source. When I render any model, the shading is not distributed properly (as seen in the pictures below). I believe this has something to do with the normals, but I'm not sure.
These are my results:
And this is the type of effect I'm trying to achieve:
I thought the problem was that the normals I parsed from the file were incorrect, but after calculating them myself and getting the same results, I found that this wasn't true. I also thought not having GL_SMOOTH enabled was the issue, but I was wrong there too.
So I have no idea what I'm doing wrong here, so sorry if the question seems vague. If any more info is needed, I'll add it.
Update:
Link to larger picture of broken monkey head: http://oi52.tinypic.com/2re5y69.jpg
Update 2: If there's is a mistake in the process of me calculating normals, this is what I'm doing:
Create a triangle for each group of indices.
Calculate the normals for the triangle and store it in a vector.
Ensure the vector is normalized with the following function
:
static inline void normalizeVector(Vector3f *vector) {
GLfloat vecMag = VectorMagnitude(*vector);
if (vecMag == 0.0) {
vector->x /= 1.0;
vector->y /= 0.0;
vector->z /= 0.0;
}
vector->x /= vecMag;
vector->y /= vecMag;
vector->z /= vecMag;
}
Update 3: Here's the code I'm using to create the normals:
- (void)calculateNormals {
for (int i = 0; i < numOfIndices; i += 3) {
Triangle triangle;
triangle.v1.x = modelData.vertices[modelData.indices[i]*3];
triangle.v1.y = modelData.vertices[modelData.indices[i]*3+1];
triangle.v1.z = modelData.vertices[modelData.indices[i]*3+2];
triangle.v2.x = modelData.vertices[modelData.indices[i+1]*3];
triangle.v2.y = modelData.vertices[modelData.indices[i+1]*3+1];
triangle.v2.z = modelData.vertices[modelData.indices[i+1]*3+2];
triangle.v3.x = modelData.vertices[modelData.indices[i+2]*3];
triangle.v3.y = modelData.vertices[modelData.indices[i+2]*3+1];
triangle.v3.z = modelData.vertices[modelData.indices[i+2]*3+2];
Vector3f normals = calculateNormal(triangle);
normalizeVector(&normals);
modelData.normals[modelData.surfaceNormals[i]*3] = normals.x;
modelData.normals[modelData.surfaceNormals[i]*3+1] = normals.y;
modelData.normals[modelData.surfaceNormals[i]*3+2] = normals.z;
modelData.normals[modelData.surfaceNormals[i+1]*3] = normals.x;
modelData.normals[modelData.surfaceNormals[i+1]*3+1] = normals.y;
modelData.normals[modelData.surfaceNormals[i+1]*3+2] = normals.z;
modelData.normals[modelData.surfaceNormals[i+2]*3] = normals.x;
modelData.normals[modelData.surfaceNormals[i+2]*3+1] = normals.y;
modelData.normals[modelData.surfaceNormals[i+2]*3+2] = normals.z;
}
Update 4: Looking further into this, it seems like the .obj file's normals are surface normals, while I need the vertex normals. (Maybe)
If the vertex normals are what I need, if anybody can explain the theory behind calculating them, that'd be great. I tried looking it up but I only found examples, not a theory. (e.g. "get the cross product of each face and normalize it"). If I know what I have to do, I can look it up an individual process if I get stuck and won't have to keep updating this.
Update 5: I re-wrote my whole loader, and got it to work, somehow. Although it shades properly, I still have those grid-like lines that you can see on my original results.
Your normalizeVector function is clearly wrong. Dividing by zero is never a good idea. Should be working when vecMag != 0.0 though. How are you calculating the normals? Using cross-product? When happens if you let OpenGL calculate the normals?
It may be the direction of your normals that's at fault - if they're the wrong way around then you'll only see the polygons that are supposed to be pointing away from you.
Try calling:
glDisable(GL_CULL_FACE);
and see whether your output changes.
Given that we're seeing polygon edges I'd also check for:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);