I'm working on a project where I create mini galaxies using ellipses, rotate, radians, etc. on mouseX and mouseY. However, I'd love it if each mini galaxy could rotate left or right, so that it looks like a galaxy turning slowly in space. Not sure how I'd do this, though, and would love some guidance. Do I have to create an array that holds the ellipses for each galaxy, and then somehow rotate that? Can I simply set a rotate() for each individual ellipse as it draws to the screen? Thanks for any help!
var bgimg;
function preload(){
//for (var i = 0; i < planetArray.length; i++) {
bgimg = loadImage('Assets/galaxy_background.jpg');
}
function setup(){
createCanvas(1301, 822);
background(bgimg, 100);
//background(25,25,22);
}
function draw() {
//background(0);
fill(255);
noStroke();
textSize(19);
text("Create mini-galaxies by holding your mouse in a location. Move to create another.", 20, 40);
star()
//function mousepressed(){
}
function star(){
//angle = map(mouseX, 0,width, 0,360);
//rotate(radians(angle*100));
noStroke();
//translate(width/2, height/2);
translate(mouseX,mouseY);
fill(0);
rotate(radians(frameCount%360)); //rotates output of ellipses
rotate(radians(1000*frameCount%360));
for(var i =0; i < 20; i++){
push();
noStroke();
tint(255, 127);
fill(random(230),5,random(210),random(230));
// fill(random(125),random(250),random(100));
ellipse(10*frameCount % (width/20),0,5,5);
rotate(radians(mouseX, mouseY));
//image(stars, 10*frameCount % (width/2),0,10,10)
//image((10*frameCount % (width/2),0,10,10)
//
pop();
}
}
You'll have better luck with your questions if you try to narrow them down to an MCVE instead of posting your full sketch. It's hard to answer general "how do I do this" type questions. It's much easier to answer specific "I tried X, expected Y, but got Z instead" type question. That being said, I'll try to answer in a general sense:
You're having trouble because of the fact that you're letting your drawing accumulate by only calling the background() function once instead of clearing it every frame. There's nothing wrong with this, but it does make it impossible to apply transforms and rotations to stuff you've already drawn.
Like I said in your other question, most Processing sketches do this:
Store everything you need to draw in a data structure.
You might store an array of PVectors. Or you might create a Galaxy class that contains variables and functions that allow it to draw itself, which you call from your draw() function. The data structure you use is entirely up to you.
This page and this page contain discussions on creating objects in p5.js, or you might just try a google search. Here is an example that uses a class that knows how to draw itself, and then creates an instance of that class to create a sketch.
Clear previous frames every time draw() is called.
Most sketches call the background() function every frame. That might seem annoying because then you have to redraw everything, but that's what the data structures are for.
Redraw everything you want to be drawn every frame.
Iterate over those data structures and redraw your scene. This might be as simple as iterating over an array of PVectors, or maybe you'll want to create objects that know how to draw themselves.
Like I said, this is very general, and exactly what you do depends on how you think about all of the above. There isn't a single best way to do this, so it's hard to be more specific.
Related
I'm trying to figure out how to draw shapes in UrhoSharp and I'm not getting anywhere with it. I thought it would be pretty straightforward. Searching the internet is not giving me much to go on.
All I want to do is give points so that I can draw lines between the points. 2-dimensional lines. So I can then draw shapes like a rectangle or triangle. I've looked at SkiaSharp, and drawing shapes is pretty straightforward, but for some reason, this concept seems foreign to UrhoSharp, at least from what I've looked at.
I've found a couple of code fragments where people are asking questions but I have no idea what else is going on aside from the bits that they show. If someone can point me to a reference that clearly explains how to do this, or show me here, I would really appreciate it.
Here is your example:
CustomGeometry geom = node.CreateComponent<CustomGeometry>();
geom.BeginGeometry(0, PrimitiveType.LineList);
var material = new Material();
material.SetTechnique(0, CoreAssets.Techniques.NoTextureUnlitVCol, 1, 1);
geom.SetMaterial(material);
float size = 1;
//x
geom.DefineVertex(Vector3.Zero);
geom.DefineColor(Color.Red);
geom.DefineVertex(Vector3.UnitX * size);
geom.DefineColor(Color.Red);
//y
geom.DefineVertex(Vector3.Zero);
geom.DefineColor(Color.Green);
geom.DefineVertex(Vector3.UnitY * size);
geom.DefineColor(Color.Green);
//z
geom.DefineVertex(Vector3.Zero);
geom.DefineColor(Color.Blue);
geom.DefineVertex(Vector3.UnitZ * size);
geom.DefineColor(Color.Blue);
geom.Commit();
Refer here for any future examples.
I'm having a problem that I need to make the words I took from an external file "NOT" overlap each other. I have over 50 words that have random text sizes and places when you run it but they overlap.
How can I make them "NOT" overlap each other? the result would probably look like a word cloud.
if you think my codes would help here they are
String [] words;
int index = 0;
void setup ()
{
size (500,500);
background (255);
String [] lines = loadStrings ("alice_just_text.txt");
String entireplay = join(lines, " "); //splits it by line
words = splitTokens (entireplay, ",.?!:-;:()03 "); //splits it by word
for (int i = 0; i < 50; i++) {
float x = random(width);
float y = random(height);
int index = int(random(words.length));
textSize (random(60)); //random font size
fill (0);
textAlign (CENTER);
text (words[index], x, y, width/2, height/2);
println(words[index]);
index++ ;
}
}
Stack Overflow isn't really designed for general "how do I do this" type questions. You'll have much better luck if you post a more specific "I tried X, expected Y, but got Z instead" type question. But I'll try to help in a general sense:
You need to break your problem down into smaller pieces and then take on those pieces one at a time.
For example, you can isolate your problem to making sure rectangles don't overlap, which you can break down even further. There are a number of ways to do that:
You could use a grid to lay out your rectangles. Figure out how many squares a line of text takes up, then find a place in your grid where that word will fit. You could use something like a 2D array of boolean values, for example.
Or you could generate a random location, and then check whether there's already a rectangle there. If so, pick a new random location until you find a clear spot.
In any case, you'll probably need to use collision detection (either point-rectangle or rectangle-rectangle) to determine whether your rectangles are overlapping.
Start small. Create a small example program that just shows two rectangles on the screen. Hardcode their positions at first, but make it so they turn red if they're colliding. Work your way up from there. Make it so you can add rectangles using the mouse, but only let the user add them if there is no overlap. Then add the random location choosing. If you get stuck on a specific step, then post a MCVE and we'll go from there. Good luck.
I have a 2D matrix with 0s and 1s - respectively representing Water and Land. It is used to generate an animated gif with Perlin noise (moving water and waves clashing on shores...).
However I wish to refactor my code and use polymorphism in the following manner:
For each element in my matrix, based on the value, I wish to create a new WaterTile or LandTile (which will represent a 30x30 set of pixels that are either a mixture of blue for water, and some combinations of green/yellow/blue for land).
WaterTile and LandTile will be inherited from BaseTile (this is an abstract class), having just 2 vars (x, y for coordinates) and a draw() method (this method for the BaseTile class does nothing, its just there if it has to be defined).
Child classes will be overriding the draw() method.
Map will be a 2D array that whose elements will be WaterTiles and LandTiles.
After that, in my main method, I will have this (pseudocode for simplicity, i is index of row, j is index of element in that row):
foreach (row in matrix) {
foreach (element in row) {
if (matrix[i][j] == 0) map[i][j] == new WaterTile();
else map[i][j] == new LandTile();
}
}
After this I will need to invoke more methods for the LandTiles, and then have a new foreach loop, simply having
map[i][j].draw();//invoking draw method based on type
I know this can be done in other ways, but i wish to avoid having if statements that check for the type and call the draw method based on the type, and also practice clean code and learn something new.
If someone can provide me a simple example, ive looked at some already but havent found what I want.
Put the different actions inside the if statement you already have.
Or, just call the draw method, and let each instance do what it is does with draw.
Or encapsulate the if inside a function and use that.
Let's say that I want to calculate the distance between two geometries with JTS, but there is another one in the middle that I can't go across (as if it was a wall). It could look like this :
I wonder how I could calculate that.
In this case, these shapes geom1 and geom2 are 38.45 meters away, as I calculate it straight away. But if I don't want go across that line, I should surround it by the Northern sides, and distance would probably be more than 70 meters away.
We can think that we could have a line a polygon or whatever in the middle.
I wonder if there is any built in function in JTS, or some other thing I could you. I guess if there is anything out there, I should check for some other workaround, as trying to solve complex routing problems is beyond my knowledge.
This is the straight away piece of code using JTS for the distance, which would not still take into account the Geometry in the middle.
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class distanceTest {
private final static Logger logger = Logger.getLogger("distanceTest");
public static void main(String [] args) {
//Projection : EPSG:32631
// We build one of the geometries on one side
String sGeom1="POLYGON ((299621.3240601513 5721036.003245114, 299600.94820609683 5721085.042327096, 299587.7719688322 5721052.9152064435, 299621.3240601513 5721036.003245114))";
Geometry geom1=distanceTest.buildGeometry(sGeom1);
// We build the geometry on the other side
String sGeom2=
"POLYGON ((299668.20990794065 5721092.766132105, 299647.3623194871 5721073.557249224, 299682.8494029705 5721049.148841454, 299668.20990794065 5721092.766132105))";
Geometry geom2=distanceTest.buildGeometry(sGeom2);
// There is a geometry in the middle, as if it was a wall
String split=
"LINESTRING (299633.6804935104 5721103.780167559, 299668.99872434285 5720999.981241705, 299608.8457218057 5721096.601805294)";
Geometry splitGeom=distanceTest.buildGeometry(split);
// We calculate the distance not taking care of the wall in the middle
double distance = geom1.distance(geom2);
logger.error("Distance : " + distance);
}
public static Geometry buildGeometry(final String areaWKT) {
final WKTReader fromText = new WKTReader();
Geometry area;
try {
area = fromText.read(areaWKT);
}
catch (final ParseException e) {
area = null;
}
return area;
}
}
This works for SQL, I hope you have the same or similar methods at your disposal.
In theory, in this instance you could create a ConvexHull containing the two geometries AND your "unpassable" geometry.
Geometry convexHull = sGeom1.STUnion(sGeom2).STUnion(split).STConvexHull();
Next, extract the border of the ConvexHull to a linestring (use STGeometry(1) - I think).
Geometry convexHullBorder = convexHull.STGeometry(1);
EDIT: Actually, with Geometry you can use STExteriorRing().
Geometry convexHullBorder = convexHull.STExteriorRing();
Lastly, pick one of your geometries, and for each shared point with the border of the ConvexHull, walk the border from that point until you reach the first point that is shared with the other geometry, adding the distance between the current and previous point at each point reached. If the second point you hit belongs to the same geometry as you are walking from, exit the loop and move on to the next to reduce time. Repeat for the second geometry.
When you've done this for all possibilities, you can simply take the minimum value (there will be only two - Geom1 to Geom2 and Geom2 to Geom1) and there is your answer.
Of course, there are plenty of scenarios in which this is too simple, but if all scenarios simply have one "wall" in them, it will work.
Some ideas of where it will not work:
The "wall" is a polygon, fully enveloping both geometries - but then how would you ever get there anyway?
There are multiple "walls" which do not intersect each other (gaps between them) - this method will ignore those passes in between "walls". If however multiple "walls" intersect, creating essentially one larger "wall" the theory will still work.
Hope that makes sense?
EDIT: Actually, upon further reflection there are other scenarios where the ConvexHull approach will not work, for instance the shape of your polygon could cause the ConvexHull to not produce the shortest path between geometries and your "walls". This will not get you 100% accuracy.
For a project we are trying to make a circle into a line (and back again) while it is rotating along a linear path, much like a tire rotates and translates when rolling on a road, or a curled fore finger is extended and recurled into the palm.
In this Fiddle, I have a static SVG (the top circle) that rotates along the linear black path (which is above the circle, to mimic a finger extending) that is defined in the HTML.
I also use d3 to generate a "circle" that is made up of connected points (and can unfurl if you click on/in the circle thanks to #ChrisJamesC here ), and is translated and rotated
in the function moveAlongLine when you click on the purple Line:
function moveAlongLine() {
circle.data([lineData])
.attr("transform", "translate(78.5,0) rotate(-90, 257.08 70) ")
.duration(1000)
circle.on("click", transitionToCircle)
}
The first problem is that the .duration(1000) is not recognized and throws a Uncaught TypeError: Object [object Array] has no method 'duration' in the console, so there is a difference between the static definition of dur in SVG and dynamically setting it in JS/D3, but this is minor.
The other is should the transform attributes be abstracted from one another like in the static circle? in the static circle, the translate is one animation, and the rotation is another, they just have the same star and duration, so they animate together. How would you apply both in d3?
The challenge that I can not get, is how to let it unroll upwards(and also re-roll back), with the static point being the top center of the circle also being the same as the leftmost point on the line.
these seem better:
I should try to get the unfurl animation to occur while also rotating? This seems like it would need to be stepwise/sequential based...
Or Consider an octogon (defined as a path), and if it were to rotate 7 of the sides, then 6, then 5.... Do this for a rather large number of points on a polyhedron? (the circle only needs to be around 50 or so pixels, so 100 points would be more than enough) This is the middle example in the fiddle. Maybe doing this programmatically?
Or This makes me think of a different way: (in the case of the octogon), I could have 8 line paths (with no Z, just an additional closing point), and transition between them? Like this fiddle
Or anything todo with keyframes? I have made an animation in Synfig, but am unsure ho get it to SVG. The synfig file is at http://specialorange.org/filedrop/unroll.sifz if you can convert to SVG, but the xsl file here doesn't correctly convert it for me using xsltproc.
this seems really complicated but potential:
Define a path (likely a bézier curve with the same number of reference points) that the points follow, and have the reference points dynamically translate as well... see this for an concept example
this seems complicated and clunky:
Make a real circle roll by, with a growing mask in front of it, all while a line grows in length
A couple of notes:
The number of points in the d3 circle can be adjusted in the JS, it is currently set low so that you can see a bit of a point in the rendering to verify the rotation has occurred (much like the gradient is in the top circle).
this is to help students learn what is conserved between a number line and a circle, specifically to help learn fractions. For concept application, take a look at compthink.cs.vt.edu:3000 to see our prototype, and this will help with switching representations, to help you get a better idea...
I ended up using the same function that generates the circle as in the question, and did a bit of thinking, and it seemed like I wanted an animation that looked like a finger unrolling like this fiddle. This lead me to the math and idea needed to make it happen in this fiddle.
The answer is an array of arrays, with each nested array being a line in the different state, and then animate by interpolating between the points.
var circleStates = [];
for (i=0; i<totalPoints; i++){
//circle portion
var circleState = $.map(Array(numberOfPoints), function (d, j) {
var x = marginleft + radius + lineDivision*i + radius * Math.sin(2 * j * Math.PI / (numberOfPoints - 1));
var y = margintop + radius - radius * Math.cos(2 * j * Math.PI / (numberOfPoints - 1));
return { x: x, y: y};
})
circleState.splice(numberOfPoints-i);
//line portion
var lineState = $.map(Array(numberOfPoints), function (d, j) {
var x = marginleft + radius + lineDivision*j;
var y = margintop;
return { x: x, y: y};
})
lineState.splice(i);
//together
var individualState = lineState.concat(circleState);
circleStates.push(individualState);
}
and the animation(s)
function all() {
for(i=0; i<numberOfPoints; i++){
circle.data([circleStates[i]])
.transition()
.delay(dur*i)
.duration(dur)
.ease("linear")
.attr('d', pathFunction)
}
}
function reverse() {
for(i=0; i<numberOfPoints; i++){
circle.data([circleStates[numberOfPoints-1-i]])
.transition()
.delay(dur*i)
.duration(dur)
.ease("linear")
.attr('d', pathFunction)
}
}
(Note: This should be in comments but not enough spacing)
Circle Animation
Try the radial wipe from SO. Need to tweak it so angle starts at 180 and ends back at same place (line#4-6,19) and move along the X-axis (line#11) on each interation. Change the <path... attribute to suit your taste.
Line Animation Grow a line from single point to the length (perimeter) of the circle.
Sync both animation so that it appears good on all browsers (major headache!).