Recently, I have been trying to build a kind of sailing simulator in Processing, and have encountered a problem. I'm not going to go into details on the project itself because I don't think it's really relevant.
Here's my problem: I need to find a way for the camera to look around while still focusing on the object in the middle (the boat). By this I mean that I'd like to find a circular path for the camera, while it orbits the boat. This is used in many simulators and video games, so I thought it could work in my project.
I have already thought about rotating every object instead of the camera, but I would prefer not to do that because dealing with the boat, sail, and wind is already going to cause lots of rotation and it would just complicate things to rotate it all again every time the player drags the mouse to pivot the point that they are looking from. So, I think finding this path for the camera is my only option right now and I have no idea how to even start to do the math out (going into 9th grade).
If anyone reading this has encountered this problem before, (using the mouse to rotate the camera around an object) please try to give me some tips. Thanks!
Code:
float x,y,z,ry;
int trimmingLimit;
void setup()
{
size(800, 600, P3D);
x = width/2;
y = height/2;
z = 0;
ry = 10;
trimmingLimit = int(random(75,84)); //randomizing sheet length length
}
void draw()
{
background(#FF844B);
stroke(255);
translate(x,y,z);
pushMatrix();
rotateY(radians(ry)); //mainsheet trimming and easing
triangle(-120, 50, 0, -140, 0, 50); //sail
ry=mouseY/(height/trimmingLimit); //since 80 to 85^o is the maximum amount
//the sail can be drawn, the height of the window is adjustable
//and divided by 90.
popMatrix();
noStroke();
pushMatrix();
translate(0,500,0);
fill(98,122,255,50);
cylinder(1000,500,15);
rectMode(CENTER);
popMatrix();
fill(#AD8B7C);
stroke(255);
pushMatrix();
translate(0,75);
rotateX(radians(0));
translate(0,75);
triangle(-180,100,0,-50,180,100);
popMatrix();
fill(100);
}
float d(float n) //converting to the correct type of degrees (with 0 being wind)
{
return n-90;
}
Related
I'm looking to have an algorithm that can randomly draw a "squiggly wiggly" pattern as per the picture.
It would be nice if it were progressively drawn as you would draw it with a pen and if it were based on speed, acceleration and forces like a double pendulum animation might be.
This would be for javascript in the p5 library.
Is there some way of producing this that a) looks hand drawn and b) fills a page, somewhat like a Hilbert curve?
Very interested to hear ideas of how this could be produced, regardless of whether there is some kind of formal algorithm, although a formal algorithm would be best.
Cheers
I can think of two solutions, but there could be more as I'm not very good at coding in general yet.
First of all, you can use perlin noise. With the code
var noiseSeeds = [];
//This changes the noise value over time
var noiseTime = 0;
var x = 0;
var y = 0;
function setup() {
createCanvas(400, 400);
//This will help for making two separate noise values later
noiseSeeds = [random(100), random(100)];
}
function draw() {
//Finding the x value
noiseSeed(noiseSeeds[0]);
x = noise(noiseTime)*400;
//Finding the y value
noiseSeed(noiseSeeds[1]);
y = noise(noiseTime)*400;
//Increasing the noise Time so the next value is slightly different
noiseTime += 0.01;
//Draw the point
stroke(0);
strokeWeight(10);
point(x, y);
}
You can create a scribble on screen. You would have to use createGraphics()in some way to make this more efficient. This method isn't the best because the values are generally closer to the center.
The second solution is to make a point that has two states - far away from an edge and close to an edge. While it is far away, the point would keep going in relatively the same direction with small velocity changes. However, the closer the point gets to the edges, the (exponentially) bigger the velocity changes so that the point curves away from the edge. I don't know exactly how you could implement this, but it could work.
I'm putting together a p5 sketch with little wiggling snakes that move randomly across the screen.
Unfortunately, the tail keeps catching up to the head every time it does a sharpish turn.
Here is the function I'm using to calculate the move, I've tried with a few different ways of calculating the speed, fixed numbers, relative to the snake's length.
It's supposed to work by moving the snakes head (points[3]) in a semi-random direction and then having each body point move towards the one before it by the same amount. This isn't working, and I feel there's something wrong with my algorithm itself. I'm not familiar with these kinds of intermediate random-walks, so I've just been going by guesswork for the most part.
this["moveCurve"] = function() {
let newDir = this["oldDir"] + (random() - 1/2)*PI/6;
let velocity = createVector(1,0);
velocity.setMag(5);
velocity.setHeading(newDir);
this["points"][3].add(velocity);
for (let i = 2; i >= 0; i--) {
this["points"][i].add(p5.Vector.sub(this["points"][i + 1],this["points"][i]).setMag(5));
}
this["oldDir"] = newDir;
}
If you have any idea what I could do to make this work properly, I'd love to hear your advice. Thanks!
This does look like an algorithmic issue / not a bug with how you implemented it.
Here's my go at explaining why the gap between two points must decrease in this algorithm:
Let's consider just a two point snake, with two points Hi (head) and Ti (tail) at an initial locations Hi: (20, 0), and Ti: (0, 0). So, the heading here is 0 radians.
What happens when moveCurve is called? A new heading is chosen (let's use PI/2, a right angle to make it easy to imagine) and using a fixed velocity of 5 we calculate a new position for the head of (20, 5), let's call it Hf. T also moves, but it also moves toward Hf at the same 5 unit velocity, ending up at about (4.85, 1.21). The distance between these two final positions is now 15.62657, which is smaller than the initial distance.
To visualize this, think of the triangle formed between Ti, Hi, and Hf. Ti, and Hi, form the base of this triangle. Ti will move along the hypotenuse to get to Tf, while Hi will move along the other side. The directions they are moving in form an angle which is smaller than PI radians and both points are moving at the same speed so intuitively the points must be getting closer together.
So how to solve this? Well if we consider our tiny snake's movement, the tail moved in a decent direction but too far. One solution might be to scale the velocity vector in order to maintain a fixed distance between points instead of using a fixed velocity. For example instead of stepping 5 units along the hypotenuse from Ti toward Hf in the example, you could step 20 units along the hypotenuse from Hf toward Ti. I'm not sure how this would work out for your snake, just an idea!
Keep slithering!
Fortunately, it turns out p5's documentation itself had the answer for me. By adapting the code from here to use p5 Vectors, I was able to get it all working.
The segLengths property is defined when the object is made, just takes the distances between all the points.
this["moveCurve"] = function() {
let newDir = this["oldDir"] + (random() - 1/2)*PI/6;
let velocity = p5.Vector.fromAngle(newDir).setMag(5);
this["points"][3].add(velocity);
for (let i = 2; i >= 0; i--) {
this["points"][i].set(p5.Vector.sub(this["points"][i+1], p5.Vector.fromAngle(p5.Vector.sub(this["points"][i+1],this["points"][i]).heading()).setMag(this["segLengths"][i])));
}
this["oldDir"] = newDir;
}
I might spend a little time trying to clean up the code a bit, it's a jot messy for my tastes at the moment. But it works.
I'm making a simple game in JavaScript and using the Phaser library. I'm new to this, so hopefully this is not a silly question.
I have made it all work perfectly but I would love to know how to get the rocks to bounce of the walls, rather than go through them and appear on the other side.
It has something to do with this function:
I was told by someone to
"If it hits Width: 940 then x = 940 and you start going back 939, i--, etc. Height will continue as normal. Rather than resetting i.e shot.reset(x, y);.
If you hit the bottom or top then do the same to height, keeping width the same."
However, I am not sure how to implement this into the code. I have tried but failed :) Its very frustrating, so any help on this matter would be amazing.
Thanks.
Usually, I create a velocity vector, wich represents the "speed" of my objects.
On each frame, I add that velocity vector to the position vector. When I want my object to move to the opposite direction, I multiply my vector by -1.
Create a vector like that, and when your object collid an edge, multiply it by -1.
You can make a lot of things with this type of vector, such as smooth speed decrease, inspace-like movements etc...
e.g:
//on init
var velocity = {x: 10; y: 10};
var pos = {x: 10; y:10};
//on frame update
pos.x += velocity.x;
pos.y += velocity.y
//on edge collision
velocity.x = velocity.x * -1;
velocity.y = velocity.y * -1;
I am coding with processing.js. I want the size variable to get greater as the cursor (mouse) approches the ellipse and to get smaller as the cursor moves away from the ellipse. The size should (if possible) be limited between minimum 50 and maximum 200. Is there any way to accomplish that ?
I've looked online, but there doesn't seem to be lots of documentation (at least for what I was searching for) about this.
Here is my code :
void setup()
{
// Setting up the page
size(screen.width, screen.height);
smooth();
background(0, 0, 0);
// Declaring the variable size ONCE
size = 50;
}
void draw()
{
background(0, 0, 0);
// I want the size variable to be greater as the cursor approches the ellipse and to be smaller as the cursor moves away from the ellipse. The size is limited if possible between 50 and 200
// Here is the variable that needs to be changed
size = 50;
// Drawing the concerned ellipse
ellipse(width/2, height/2, size, size);
}
Thanks.
First, you need to get the distance from the mouse to the ellipse:
float distance = dist(mouseX,mouseY, width/2,height/2);
Then, you need to convert that distance into a more usable range. We'll call the result dia, since size() is also the name of a command in Processing. We also want dia to get larger as the distance gets smaller.
For both those things, we'll use map() which takes an input value, it's range, and an output range:
float dia = map(distance, 0,width/2, 200,50);
When distance is 0, dia = 200 and when distance is the width of the screen divided by 2, dia = 50.
I am currently working on a game using javascript and processing.js and I am having trouble trying to figure out how to move stuff diagonally. In this game, there is an object in the center that shoots other objects around it. Now I have no problem moving the bullet only vertically or only horizontally, however I am having difficulty implementing a diagonal motion for the bullet algorithm.
In terms of attempts, I tried putting on my math thinking cap and used the y=mx+b formula for motion along a straight line, but this is what my code ends up looking like:
ellipse(shuriken.xPos, shuriken.yPos, shuriken.width, shuriken.height); //this is what I want to move diagonally
if(abs(shuriken.slope) > 0.65) {
if(shuriken.targetY < shuriken.OrigYPos) {
shuriken.yPos -= 4;
} else {
shuriken.yPos += 4;
}
shuriken.xPos = (shuriken.yPos - shuriken.intercept)/shuriken.slope;
} else {
if(shuriken.targetX < shuriken.OrigXPos) {
shuriken.xPos -= 4;
} else {
shuriken.xPos += 4;
}
shuriken.yPos = shuriken.slope * shuriken.xPos + shuriken.intercept;
}
The above code is very bad and hacky as the speed varies with the slope of the line.
I tried implementing a trigonometry relationship but still in vain.
Any help/advice will be greatly appreciated!
Think of it this way: you want the shuriken to move s pixels. If the motion is horizontal, it should move s pixels horizontally; if vertical, s pixels vertically. However, if it's anything else, it will be a combination of pixels horizontally/vertically. What's the correct combination? Well, what shape do you get if you project s distance in any direction from a given point? That's right, a circle with radius s. Let's represent the direction in terms of an angle, a. So we have this picture:
How do we get the x and the y? If you notice, we have a triangle. If you recall your trigonometry, this is precisely what the sine, cosine, and tangent functions are for. I learned their definitions via the mnemonic SOHCAHTOA. That is: Sin (a) = Opposite/Hypotenuse, Cos(a) = Adjacent/Hypotenuse, Tan(a) = Opposite/Adjacent. In this case, opposite of angle a is y, and adjacent of angle a is x. Thus we have:
cos(a) = x / s
sin(a) = y / s
Solving for x and y:
x = s * cos(a)
y = s * sin(a)
So, given the angle a, and that you want to move your shuriken s pixels, you want to move it s * cos(a) horizontally and s * sin(a) vertically.
Just be sure you pass a in radians, not degrees, to javascript's Math.sin and Math.cos functions:
radians = degrees * pi / 180.0
This may be why your trigonometric solution didn't work as this has bitten me a bunch in the past.
If you know the angle and speed you are trying to move at, you can treat it as a polar coordinate, then convert to cartesian coordinates to get an x,y vector you would need to move the object by to go in that direction and speed.
If you don't know the angle, you could also come up with the vector by taking the difference in X and difference in Y (this I know you can do as you are able to calculate the slope between the 2 points). Then take the resulting vector and divide by the length of the vector to get a unit vector, which you can then scale to your speed to get a final vector in which you can move your object by.
(This is what probably what kennypu means by sticking with vectors?)