I am trying to do a theoretically simple effect. For example, I have two white circles bouncing around the window. When they intersect, I want the parts of the circle which are intersecting to be black while the rest of the circles remain white, like this:
Is there a way to do this?
So far I have this:
for(int i = 0; i < balls.length; i++)
{
balls[i].move();
for(int j = 0; j < balls.length; j++)
{
if(i != j && balls[i].intersect(balls[j]) && !changed[i] && !changed[j])
{
balls[j].swapColor();
changed[j] = true;
}
else
changed[j] = false;
}
balls[i].display();
}
but it turns the circles entirely to black when they intersect, whereas I only want the intersection itself to change.
edit:
I tried using blend() with two 200x200 pngs, magenta and red to better see the blending work. The blend() parameters don't seem to help with positioning the circles correctly, however.
void setup() {
size(300, 300);
background(255);
}
void draw() {
PImage img = loadImage("circle.png");
PImage img2 = loadImage("circle2.png");
img.blend(img2,0,0,200,200,10,10,200,200,DIFFERENCE);
image(img,0,0);
image(img2,50,50);
}
gives me this:
Here give this a try. It's the blend approach using two PGraphics, instead of PImages. A simple example. EDIT: There is a strange artifact in upper corner of base ellipse when they overlap though, don't now why... I'm looking for, If i find I'll post it here.
EDIT2: it seems to be related to the antialias, if you skip smooth() the artifact is gone...
PGraphics c;
PGraphics d;
void setup() {
size(300, 300);
background(255);
c = createGraphics(width, height, JAVA2D);
d = createGraphics(width, height, JAVA2D);
c.beginDraw();
c.smooth();
c.endDraw();
d.beginDraw();
d.smooth();
d.endDraw();
}
void draw() {
background(255);
c.beginDraw();
c.background(0, 0);
c.fill(255);
c.stroke(0);
c.ellipse(mouseX, mouseY, 30, 30);
c.endDraw();
d.beginDraw();
d.background(0, 0);
d.fill(255);
d.stroke(0);
d.ellipse(width/2, height/2, 30, 30);
d.endDraw();
d.blend(c, 0, 0, width, height, 0, 0, width, height, DIFFERENCE);
image(d, 0, 0);
}
Unfortunately I can't provide a runnable sample now, but for the visual effect you can use the blend() function (probably on the DIFFERENCE mode).
You can draw an ellipse into a PImage using createGraphics btw.
I thought of an amusing way to do this. Create a new sketch with the following code and move your mouse around within the canvas.
void setup() {
size(600,600);
}
void draw() {
background(0);
int c1x = width/2;
int c1y = height/2;
int c2x = mouseX;
int c2y = mouseY;
int d = 100;
boolean intersect = false;
if(dist(c1x, c1y, c2x, c2y) < d) intersect = true;
fill(255);
stroke(0);
ellipse(c1x, c1y, d, d);
ellipse(c2x, c2y, d, d);
noFill();
ellipse(c1x, c1y, d, d);
stroke(0, 0, 255);
line(c1x, c1y, c2x, c2y);
stroke(255, 0, 0);
if(intersect) stroke(0, 255, 0);
rectMode(CORNERS);
int mx = (c1x+c2x)/2;
int my = (c1y+c2y)/2;
int r = d/2;
rect(mx-r, my-r, mx+r, my+r);
if(intersect) {
for(int j = my-r; j <= my+r; j++) {
for(int i = mx-r; i <= mx+r; i++) {
if(dist(i, j, c1x, c1y) <= r && dist(i, j, c2x, c2y) <= r) {
stroke(0);
point(i, j);
}
}
}
}
}
This is a dirty mock-up showing the concept. I know the center points of the two circles. I imagine a square with a width and height equal to the diameter of the circles, and I center that square at the midpoint between the two circles. When the circles collide, I check each pixel within that square, and if the pixel is within both circles, I draw a point there.
I simplified by having the circles with identical diameter, but it's trivial to modify it for variable diameters.
Obviously you don't have to draw the green square and blue line, those are there just for reference.
they intersect if distance between their centers is smaller than sum of their radius
This would be dark ellipses with a white intersection and background and is quick and dirty but works.
with a white background:
background(255);
call something like this:
blendMode(SUBTRACT);
fill(0);
ball1.display();
fill(255);
ball2.display();
If you want to take a look at the math behind it check out this link. I think you also might be able to do this with a library like toxiclibs.geom.
Related
I am trying to create a round brush with blurred edges in Processing through the following code. The circle shape is drawn pixel by pixel because in the actual version, I try to draw with pixels taken from the PGraphic pg.
PFont font;
PGraphics pg;
int X;
int Y;
int rad = 20;
void setup (){
size(800, 800, P2D);
background(0);
noStroke();
pg = createGraphics(800, 800, JAVA2D);
pg.beginDraw();
pg.fill(255);
pg.noStroke();
pg.textFont(font);
pg.textSize(400);
pg.pushMatrix();
pg.translate(width/2, height/2-140);
pg.textAlign(CENTER, CENTER);
pg.text("b", 0 , 0);
pg.popMatrix();
pg.endDraw();
}
void draw () {
image(pg,0,0);
}
void mousePressed(){
X = mouseX;
Y = mouseY;
}
void mouseDragged(){
for (int x=0; x<rad; x++) {
for (int y=0; y<rad; y++) {
float distance = sqrt(pow(x,2)+pow(y,2));
float alpha = 255-map(distance,0,rad,0,255);
if (sqrt(pow(x,2)+pow(y,2)) < rad){
pg.beginDraw();
pg.set(mouseX+x,mouseY+y,color(255,255,255, alpha));
pg.set(mouseX-x,mouseY+y,color(255,255,255, alpha));
pg.set(mouseX+x,mouseY-y,color(255,255,255, alpha));
pg.set(mouseX-x,mouseY-y,color(255,255,255, alpha));
pg.endDraw();
}
}
}
}
Create a function which draw a single dot to a PGraphics object:
void DrawPen(PGraphics pg, int cptX, int cptY, int r) {
pg.beginDraw();
for (int x = 0; x < r; ++x) {
for (int y = 0; y < r; ++y) {
float distance = sqrt(x*x + y*y);
float alpha = 255-map(distance,0,r,0,255);
if (distance < r) {
pg.set(cptX+x,cptY+y,color(255,255,255, alpha));
pg.set(cptX-x,cptY+y,color(255,255,255, alpha));
pg.set(cptX+x,cptY-y,color(255,255,255, alpha));
pg.set(cptX-x,cptY-y,color(255,255,255, alpha));
}
}
}
pg.endDraw();
}
Draw a dot to a separate PGraphics object in setup
PGraphics pg;
PGraphics pg_pen;
int rad = 20;
void setup (){
size(800, 800, P2D);
pg = createGraphics(800, 800, JAVA2D);
pg.beginDraw();
// [...]
pg.endDraw();
pg_pen = createGraphics(2*rad, 2*rad, JAVA2D);
DrawPen(pg_pen, rad, rad, rad);
}
When the mouse is dragged then blend the pg_pen to the common PGraphics object (pg) at the current mouse position:
void mouseDragged(){
pg.beginDraw();
pg.image(pg_pen, mouseX-rad, mouseY-rad);
pg.endDraw();
}
For the seek of completeness the draw function:
void draw () {
background(0);
image(pg,0,0);
}
[...] and tried to get the color from the white part to draw on the black part.
Add a color parameter to the DrawPen function and clear the pen PGraphics before drawing to it:
void DrawPen(PGraphics pg, int cptX, int cptY, int r, color c) {
pg.beginDraw();
pg.clear();
for (int x = 0; x < r; ++x) {
for (int y = 0; y < r; ++y) {
float distance = sqrt(x*x + y*y);
float alpha = 255-map(distance,0,r,0,255);
if (distance < r) {
color pc = color(red(c),green(c),blue(c), alpha);
pg.set(cptX+x,cptY+y,pc);
pg.set(cptX-x,cptY+y,pc);
pg.set(cptX+x,cptY-y,pc);
pg.set(cptX-x,cptY-y,pc);
}
}
}
pg.endDraw();
}
Get the color in the mouse pressed event call back and change the color of the pen:
void mousePressed() {
color c = pg.get(mouseX, mouseY);
println(c);
DrawPen(pg_pen, rad, rad, rad, c);
}
Note, the color is get from the pg object and not from the screen. If you want to get the color from the screen then it has to be (without .pg):
color c = get(mouseX, mouseY);
Further the color is changed any time when any mouse is pressed (pressed not dragged). Possibly you want to change the color when the right mouse button is pressed and paint when the left mouse button is pressed:
void mousePressed() {
if (mouseButton == RIGHT) {
color c = pg.get(mouseX, mouseY);
println(c);
DrawPen(pg_pen, rad, rad, rad, c);
}
}
add a "background(0);" before "image(pg,0,0);" in your drawing method, that way you reset the background every time, if you don't do that the program will keep drawing every frame images on top of each other's, which will make the low opacity pixel gain opacity slowly every frame until reaching 100%
void draw () {
background(0);
image(pg,0,0);
}
Edit:
After testing your code I noticed there was a problem with the way you were creating those circles, making it super slow to run (every frame you go through that double for loop to draw one circle ) and also gave that weird black edges problem, so here is what I did:
First I used your variable pg and drew one circle on it on the startup, Then I declared another PGraphics 'pg_all', where I drew one pg every call of the mousedrag method, I tested it on multiple backgrounds it seems like working fine, here is the final code, let me know if you didn't understand a part or want to do it differently:
PFont font;
PGraphics pg;
PGraphics pg_all;
int X;
int Y;
int rad = 20;
void setup (){
size(800, 800, P2D);
background(0);
noStroke();
pg_all = createGraphics(800, 800, JAVA2D);
pg_all.beginDraw();
pg_all.endDraw();
pg = createGraphics(800, 800, JAVA2D);
pg.beginDraw();
for (int x=0; x<rad; x++) {
for (int y=0; y<rad; y++) {
float distance = sqrt(pow(x,2)+pow(y,2));
float alpha = 255-map(distance,0,rad,0,255);
if (sqrt(pow(x,2)+pow(y,2)) < rad){
pg.beginDraw();
pg.set(20+x,20+y,color(255,255,255, alpha));
pg.set(20-x,20+y,color(255,255,255, alpha));
pg.set(20+x,20-y,color(255,255,255, alpha));
pg.set(20-x,20-y,color(255,255,255, alpha));
pg.endDraw();
}
}
}
pg.endDraw();
}
void draw () {
background(0);
image(pg_all,0,0);
}
void mouseDragged(){
X = mouseX;
Y = mouseY;
pg_all.beginDraw();
pg_all.image(pg,X-rad,Y-rad);
pg_all.endDraw();
}
I was steered over to this forum when I asked my lecturer for advice on a piece of code for a group project. The general idea is that there are two images on top of each other, the user can wipe the top image away to reveal the one underneath.
Using some other projects from this forum, I have managed to get the basics running, however I am struggling to get the code to the starting point once the user lets go of the mouse.
I would also appreciate any advice regarding how to convert this to using a touch screen. I have looked at the multitouch code within the processing app, however it does not allow me to add images to this, and if I try and use the computer software it does not seem to like the multitouch. Is there any way around this?
The code I currently have is below, I will be greatful so any advice or input- thanks in advance!
PImage img, front;
int xstart, ystart, xend, yend;
int ray;
void setup()
{
size(961, 534);
img = loadImage("back.jpg");
front = loadImage("front.jpg");
xstart = 0;
ystart = 0;
xend = img.width;
yend = img.height;
ray = 50;
}
void draw()
{
{
img.loadPixels();
front.loadPixels();
// loop over image pixels
for (int x = xstart; x < xend; x++)
{
for (int y = ystart; y < yend; y++ )
{
int loc = x + y*img.width;
float dd = dist(mouseX, mouseY, x, y);
// pixels distance less than ray
if (mousePressed && dd < 50)
{
// set equal pixel
front.pixels[loc] = img.pixels[loc];
}
else
{
if (!mousePressed)
{
// reset- this is what I have not been able to work as of yet
front.pixels[loc] = ;
}
}
}
}
img.updatePixels();
front.updatePixels();
// show front image
image(front, 0, 0);
}
}
I recommend to use a mask instead of changing the pixels of the image. Create an empty image and associated it as mask to the the image:
img = loadImage("back.jpg");
front = loadImage("front.jpg");
mask = createImage(img.width, img.height, RGB);
img.mask(mask);
If you now draw both images, then you can only "see" the front image:
image(front, 0, 0);
image(img, 0, 0);
Set the color of the mask (255, 255, 255) instead of changing the pixel of front:
mask.pixels[loc] = color(255, 255, 255);
and reapply the mask to the image
img.mask(mask);
When the mouse button is released, the pixels of the mask have to be changed back to (0, 0, 0) or simply create a new and empty mask:
mask = createImage(img.width, img.height, RGB);
See the example where I applied the suggestions to your original code:
PImage img, front, mask;
int xstart, ystart, xend, yend;
int ray;
void setup() {
size(961, 534);
img = loadImage("back.jpg");
front = loadImage("front.jpg");
mask = createImage(img.width, img.height, RGB);
img.mask(mask);
xstart = 0;
ystart = 0;
xend = img.width;
yend = img.height;
ray = 50;
}
void draw() {
img.loadPixels();
front.loadPixels();
// loop over image pixels
for (int x = xstart; x < xend; x++) {
for (int y = ystart; y < yend; y++ ) {
int loc = x + y*img.width;
float dd = dist(mouseX, mouseY, x, y);
if (mousePressed && dd < 50) {
mask.pixels[loc] = color(255, 255, 255);
}
else {
if (!mousePressed) {
//mask = createImage(img.width, img.height, RGB);
mask.pixels[loc] = color(0, 0, 0);
}
}
}
}
mask.updatePixels();
img.mask(mask);
// show front image
image(front, 0, 0);
image(img, 0, 0);
}
i have an arraylist RecArray of objects with each object containing two int values, one for the width and for the height of a rectangle. Each rectangle's height and width are a multiple of ten. the rectangles have to be passed on to the surface as in the given order in RecArray from left to right and from top to bottom. my problem is i can not find the x,y coordinates of the next rectangle. what im trying to do is, starting at the coordinate (0,0) i generate the first rectangle, add it to an arraylist RecList. Then i set the x and y coordinates. x becomes x = x+RecArray.get(0).getLength1() + 1. if x is greater than the width of the jpanel surface then it becomes 0 and y becomes y = y + 10 . starting from the second object in the RecArray i try to generate rectangles with the given coordinates and width&height. Then i try to compare them with all the previous rectangles to see if there is any overlapping. if there is no overlapping, the rectangle will be drawn, if there is overlapping, the x coordinate of the rec becomes x = RecList.get(j).width+1 and if that exceeds the width x becomes 0 and y is y=y+10. Then i regenate the current rectangle with the new coordinates and compare with the other rectangles in RecList again till i find the right spot for the current rectangle.ive been dealing with that issue for the last 5 days and am really fed up now. i would greatly appreciate any tipps. and Please be patient with me. im still learning programming.
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Rectangle rec = new Rectangle(x, y, RecArray.get(0).getWidth(),
RecArray.get(0).getHeight());
RecList.add(rec);
recPaint(g2,RecArray.get(0));
x = x + RecArray.get(0).getWidth() + 1;
int i;
for (i = 1; i < RecArray.size(); i++) {
if (x >= this.getArea().getWidth()) {
x = 0;
y = y + 10;
}
Rectangle rec1 = new Rectangle(x, y, RecArray.get(i)
.getWidth(), RecArray.get(i).getheight());
for (int j= 0; j < RecList.size(); j++) {
if (!recIntersect(rec1, RecList.get(j))) {
RecList.add(rec1);
recPaint(g2,RecArray.get(i));
break;
}
else {
x = RecList.get(j).width;
if (x >= this.getFlaeche().getLength1()) {
x = 0;
y = y + 10;
}
rec1 = new Rectangle(x, y,RecArray.get(i). .getWidth(),
RecArray.get(i).getHeight());
}
x = x + RecArray.get(i).getWidth();
}
//With this method using the given rec parameter a rectangle will be drawn on the g2 and filled in blue colour
private void recPaint (Graphics2D g2, RecType rec){
g2.setColor(Color.BLUE);
g2.fillRect(x, y, rec.getWidth(),
rec.getLength2());
g2.setColor(Color.BLACK);
g2.drawRect(x, y, rec.getHeight(),
rec.getLength2());
}
// returns true, if two rectangles overlap
private boolean recIntersect(Rectangle rec1, Rectangle rec2) {
if( rec1.intersects(rec2)){
return true;
}
return false;
}
Edit: apparently i haven't stated clearly what my problem is. my problem is, that the way i generate (x,y) coordinates of the rectangles is obviously wrong. the way my algorithm works doesnt get the results i want. i want my rectangles to be placed neatly next to/above/below each other WITHOUT overlapping, which is not the case.
Separate out your List of Rectangles. Calculate the X, Y coordinates once.
Since I didn't have your object class, I used the Dimension class, which holds a width and a length. I used the Rectangle class to hold the objects that will eventually be drawn in your Swing GUI.
Divide and conquer. Separate out your GUI model, view, and controller(s). This way, you can focus on one piece of the puzzle at a time.
Here are the results of my test code when I ran it with a drawing area of 500, 400.
java.awt.Rectangle[x=0,y=0,width=100,height=100]
java.awt.Rectangle[x=100,y=0,width=20,height=10]
java.awt.Rectangle[x=120,y=0,width=40,height=20]
java.awt.Rectangle[x=160,y=0,width=60,height=40]
java.awt.Rectangle[x=220,y=0,width=80,height=60]
java.awt.Rectangle[x=300,y=0,width=20,height=10]
java.awt.Rectangle[x=320,y=0,width=120,height=110]
Here are the results of my test code when I ran it with a drawing area of 200, 200.
java.awt.Rectangle[x=0,y=0,width=100,height=100]
java.awt.Rectangle[x=100,y=0,width=20,height=10]
java.awt.Rectangle[x=120,y=0,width=40,height=20]
java.awt.Rectangle[x=0,y=100,width=60,height=40]
java.awt.Rectangle[x=60,y=100,width=80,height=60]
java.awt.Rectangle[x=140,y=100,width=20,height=10]
And here's the code. I fit rectangles on the X axis until I can't fit another rectangle. Then I add the maximum height to Y, reset the X to zero, reset the maximum height and fit the next row of rectangles.
Create test applications like I did here and make sure that you can create the GUI model long before you create the GUI view and GUI controller.
package com.ggl.testing;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
public class CalculatingRectangles {
public static void main(String[] args) {
CalculatingRectangles calculatingRectangles = new CalculatingRectangles();
Dimension drawingArea = new Dimension(200, 200);
List<Dimension> dimensions = new ArrayList<>();
dimensions.add(new Dimension(100, 100));
dimensions.add(new Dimension(20, 10));
dimensions.add(new Dimension(40, 20));
dimensions.add(new Dimension(60, 40));
dimensions.add(new Dimension(80, 60));
dimensions.add(new Dimension(20, 10));
dimensions.add(new Dimension(120, 110));
List<Rectangle> rectangles = calculatingRectangles
.calculatingRectangles(drawingArea, dimensions);
System.out.println(displayRectangles(rectangles));
}
private static String displayRectangles(List<Rectangle> rectangles) {
StringBuilder builder = new StringBuilder();
for (Rectangle r : rectangles) {
builder.append(r);
builder.append(System.getProperty("line.separator"));
}
return builder.toString();
}
public List<Rectangle> calculatingRectangles(Dimension drawingArea,
List<Dimension> dimensions) {
int width = drawingArea.width;
int height = drawingArea.height;
int x = 0;
int y = 0;
int index = 0;
int maxHeight = 0;
boolean hasRoom = dimensions.size() > index;
List<Rectangle> rectangles = new ArrayList<>();
while (hasRoom) {
Dimension d = dimensions.get(index);
maxHeight = Math.max(maxHeight, d.height);
if ((x + d.width) <= width && (y + maxHeight) <= height) {
Rectangle r = new Rectangle(x, y, d.width, d.height);
x += d.width;
rectangles.add(r);
index++;
if (index >= dimensions.size()) {
hasRoom = false;
}
} else {
y += maxHeight;
if (y > height) {
hasRoom = false;
}
x = 0;
}
}
return rectangles;
}
}
So if you run this sketch you'll see a grid of plus signs. I want to rotate each individual but i can't seem to figure it out. I tried translate, pushMatrix/popMatrix. But maybe it's not on the right place. I removed it now, maybe someone can point out how to rotate each individual plus sign around its own axis.
int rib;
void setup() {
size(1200, 800);
rib = 7;
}
void draw() {
background(0);
for (int i = -100; i < width+100; i = i + rib * 10) {
for (int j = -100; j < height+100; j = j + rib * 10) {
noStroke();
fill(255);
plus(i, j);
plus(3*rib+i, 1*rib+j);
plus(6*rib+i, 2*rib+j);
plus(9*rib+i, 3*rib+j);
plus(2*rib+i, 4*rib+j);
plus(5*rib+i, 5*rib+j);
plus(8*rib+i, 6*rib+j);
plus(1*rib+i, 7*rib+j);
plus(4*rib+i, 8*rib+j);
plus(7*rib+i, 9*rib+j);
}
}
}
void plus(int x, int y) {
pushMatrix();
beginShape();
vertex(x+0, y+0);
vertex(x+0, y+-rib);
vertex(x+rib, y+-rib);
vertex(x+rib, y+0);
vertex(x+2*rib, y+0);
vertex(x+2*rib, y+rib);
vertex(x+rib, y+rib);
vertex(x+rib, y+2*rib);
vertex(x+0, y+2*rib);
vertex(x+0, y+rib);
vertex(x+-rib, y+rib);
vertex(x+-rib, y+0);
endShape(CLOSE);
popMatrix();
}
Step 1: Use pushMatrix() to save the state of the current matrix.
You need to do this because you don't want the rotations to accumulate. If you rotate one shape 30 degrees and another one 45 degrees, you don't want the second shape to be rotated (30+45) degrees.
Here is the reference for pushMatrix().
Step 2: Use translate() to move your shape where it needs to be.
Make sure you then draw your shape with that coordinate as the origin! Right now you're drawing the shapes with x,y as the origin, when you need to be using 0,0 as the origin after a translate.
Here is the reference for translate().
Step 3: Use rotate() to rotate your shape around the origin.
Remember, you've now "moved" 0,0 to the x,y you passsed into the translate() function!
Step 4: Draw your shape.
Again, remember to use 0,0 as the origin, not x,y.
Here is the reference for rotate().
Step 5: Call popMatrix() to restore the matrix you had when you called `pushMatrix()'.
This restores the rotation and translation back to normal, so the next translation and rotations don't accumulate.
Here is the reference for popMatrix().
Step 6: Repeat.
Put all of the above into a function and then call it from a for loop to draw more than one shape.
Here is a simplified examples that draws rectangles:
void setup() {
size(500, 500);
}
void draw() {
background(0);
noStroke();
fill(255);
plus(100, 100);
plus(200, 200);
}
void plus(float x, float y) {
pushMatrix();
translate(x, y);
rotate(mouseX);
rect(-20, -40, 40, 80);
popMatrix();
}
Rotation axis is always at origin (0,0). So we gotta translate the origin to where we want the axis of rotation to be. In your case, draw the plus with it's center at (0,0) and use translate to move it to desired position. I made this example using a simpler square, but the idea is the same. (I'm out of time here:)
See if this can help you.
void setup() {
size(1200, 800);
noStroke();
fill(255);
}
void draw() {
background(0);
float a = map(mouseY, 0, height, 30, 270);
for (int i = -100; i < width+100; i+=40) {
for (int j = -100; j < height+100; j+=40) {
plus(i, j, a);
}
}
}
void plus(int x, int y, float a) {
pushMatrix();
translate(x, y);
rotate(radians(a));
beginShape();
vertex(-10, -10);
vertex(10, -10);
vertex(10, 10);
vertex(-10, 10);
endShape(CLOSE);
popMatrix();
}
You might like these tutorials:
http://processing.org/tutorials/transform2d/
https://processing.org/tutorials/pshape/
If I want to create a 'glowing halo effect' using Processing 2.0 (Java) how could I do that?
Is there any built-in method/transformation that I can apply to my object in order to them to glow?
If not, is there any visual trick that would accomplish the same effect?
I do not know of a built-in way, at least generically (you don't mention how your code is organized). But, here's a quick demo for a DIY approach. The idea is that you draw a series of progressively larger and dimmer ellipses behind your object. You'll probably want to tweak the hard-coded numbers to your liking, and maybe have it go transparent non-linearly (be dimmer for longer, perhaps?).
Thing thing1;
Thing thing2;
void setup(){
size(300,300);
smooth();
thing1 = new Thing(1*width/3,height/2,false);
thing2 = new Thing(2*width/3,height/2,true);
}
void draw(){
background(100);
stroke(0);
line(100,100,250,250);
line(150,100,300,250);
thing1.display();
thing2.display();
}
class Thing
{
PVector loc;
boolean glowing;
Thing(int x, int y, boolean glow){
loc = new PVector(x,y);
glowing = glow;
}
void display(){
if(glowing){
//float glowRadius = 100.0;
float glowRadius = 100.0 + 15 * sin(frameCount/(3*frameRate)*TWO_PI);
strokeWeight(2);
fill(255,0);
for(int i = 0; i < glowRadius; i++){
stroke(255,255.0*(1-i/glowRadius));
ellipse(loc.x,loc.y,i,i);
}
}
//irrelevant
stroke(0);
fill(0);
ellipseMode(CENTER);
ellipse(loc.x,loc.y,40,40);
stroke(0,255,0);
line(loc.x,loc.y+30,loc.x,loc.y-30);
line(loc.x+30,loc.y,loc.x-30,loc.y);
}
}
Additionally, if your object isn't circularly symmetric, you can do something like the following. It looks at the object's pixels and draws an almost transparent ellipse anywhere it finds a non-blank pixel. It's a rather... messy solution, though. It might be better to follow the edge of the object, or perhaps some other method. I hope this gives you some ideas!
Thing thing1;
void setup(){
size(300,300);
background(0);
thing1 = new Thing();
thing1.display();
}
void draw(){}
class Thing
{
PGraphics pg;
Thing(){
pg = createGraphics(200,200);
}
void display(){
pg.beginDraw();
pg.background(0,0);
pg.strokeWeight(10);
pg.stroke(255,100,0);
pg.line(100,50,100,150);
pg.line(75,50,125,50);
pg.line(75,150,125,150);
pg.line(30,100,170,100);
pg.endDraw();
PGraphics glow = createGraphics(200,200);
glow.beginDraw();
glow.image(pg,0,0);
glow.loadPixels();
glow.fill(255,3);
glow.noStroke();
//change the +=2 for different effects
for(int x = 0; x < glow.width; x+=2){
for(int y = 0; y < glow.height; y+=2){
if(alpha(glow.pixels[y*glow.width+x]) != 0) glow.ellipse(x,y,40,40);
}
}
glow.endDraw();
//draw the glow:
image(glow,50,50);
//draw the sprite:
image(pg,50,50);
}
}