balloon-imageLufi image processing
Ez a program a légellenállás működését hivatott szemléltetni. A részletes cikk elérhető a https://johetajava.hu weboldalon.
Ez a program a légellenállás működését hivatott szemléltetni. A részletes cikk elérhető a https://johetajava.hu weboldalon.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import processing.video.*; | ||
|
||
class Video { | ||
String title; | ||
String path; | ||
float x, y, w, h; | ||
|
||
Video(String _title, String _path) { | ||
title = _title; | ||
path = _path; | ||
} | ||
|
||
void start() { | ||
if (movie != null) { | ||
movie.pause(); | ||
movie = null; | ||
} | ||
ps = new ArrayList<PVector>(); | ||
aps = new ArrayList<PVector>(); | ||
movie = new Movie(context, path); | ||
movie.play(); | ||
} | ||
|
||
void setPos(float x, float y, float w, float h) { | ||
this.x = x; | ||
this.y = y; | ||
this.w = w; | ||
this.h = h; | ||
} | ||
|
||
void drawButton() { | ||
if (mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h) { | ||
fill(0, 255, 255); | ||
} else { | ||
fill(0, 255, 255, 128); | ||
} | ||
stroke(0, 255, 255); | ||
strokeWeight(1); | ||
|
||
rect(x, y, w, h); | ||
|
||
noStroke(); | ||
|
||
if (mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h) { | ||
fill(0); | ||
} | ||
|
||
textAlign(CENTER, CENTER); | ||
text(title, x, y, w, h); | ||
textAlign(LEFT, TOP); | ||
} | ||
|
||
void mousePressed() { | ||
if (mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h) { | ||
currentVideo = this; | ||
isPlaying = true; | ||
start(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
boolean startVideo = true; | ||
void draw() { | ||
if (startVideo) { | ||
startVideo = false; | ||
currentVideo.start(); | ||
} | ||
background(0); | ||
image(movie, 0, 0, showWidth, showHeight); | ||
|
||
noStroke(); | ||
|
||
fill(0, 130); | ||
rect(0, 0, movieWidth*0.3, movieHeight); | ||
rect(movieWidth*0.6f, 0, movieWidth*0.4, movieHeight); | ||
|
||
|
||
// IF NOT PLAYING GET CURRENT FRAME | ||
if (!isPlaying) { | ||
ps = getPs(); | ||
avgPos = getAvgPos(ps).copy(); | ||
} | ||
// DRAW CURSOR ===================================== | ||
strokeWeight(1.5); | ||
|
||
stroke(0, 0, 0); | ||
|
||
line(0, avgPos.y, showWidth, avgPos.y); | ||
line(avgPos.x, 0, avgPos.x, showHeight); | ||
|
||
stroke(0, 255, 255); | ||
|
||
pushMatrix(); | ||
//translate(1, 1); | ||
line(0, avgPos.y, showWidth, avgPos.y); | ||
line(avgPos.x, 0, avgPos.x, showHeight); | ||
popMatrix(); | ||
|
||
stroke(0, 0, 0); | ||
noFill(); | ||
pushMatrix(); | ||
translate(avgPos.x, avgPos.y); | ||
circle(0, 0, 120); | ||
line(-90, 10, -90, -10); | ||
line(90, 10, 90, -20); | ||
line(-10, 90, 10, 90); | ||
line(-10, -90, 10, -90); | ||
popMatrix(); | ||
|
||
stroke(0, 255, 255); | ||
pushMatrix(); | ||
//translate(1, 1); | ||
noFill(); | ||
pushMatrix(); | ||
translate(avgPos.x, avgPos.y); | ||
circle(0, 0, 120); | ||
line(-90, 10, -90, -10); | ||
line(90, 10, 90, -20); | ||
line(-10, 90, 10, 90); | ||
line(-10, -90, 10, -90); | ||
popMatrix(); | ||
popMatrix(); | ||
|
||
|
||
fill(0, 255, 255); | ||
textSize(18); | ||
text("(x: "+avgPos.x/cmInPixels/100+" m; y: " + avgPos.y/cmInPixels/100 + " m)", avgPos.x + 50, avgPos.y + 50); | ||
text("y: " + avgPos.y/cmInPixels/100 + " m", 10, avgPos.y+20); | ||
text("x: " + avgPos.x/cmInPixels/100 + " m", avgPos.x + 10, 20); | ||
|
||
|
||
|
||
// DRAW BALLOON | ||
stroke(0, 255, 255); | ||
strokeWeight(3); | ||
for (int i = 0; i < aps.size()-1; i++) { | ||
line(aps.get(i).x, aps.get(i).y, aps.get(i+1).x, aps.get(i+1).y); | ||
} | ||
|
||
stroke(0, 255, 255); | ||
strokeWeight(1); | ||
if (highlightBalloon) { | ||
for (int i = 0; i < ps.size(); i+=1) { | ||
point(ps.get(i).x, ps.get(i).y); | ||
} | ||
} | ||
|
||
|
||
// DRAW GRAPH ========================================================================= | ||
fill(0); | ||
noStroke(); | ||
rect(0, showHeight, showWidth, height - showHeight); | ||
final float zoomConstantX = 20; | ||
final float zoomConstantY = 0.4; | ||
|
||
stroke(0, 255, 255); | ||
fill(0, 255, 255, 128); | ||
|
||
pushMatrix(); | ||
beginShape(); | ||
translate(0, showHeight); | ||
|
||
vertex(0, 0); | ||
for (int i = 1; i < aps.size(); i++) { | ||
vertex(i*zoomConstantX, getVel(i) * zoomConstantY); | ||
} | ||
vertex((aps.size()-1) * zoomConstantX, 0); | ||
|
||
endShape(CLOSE); | ||
popMatrix(); | ||
|
||
if (mouseX < zoomConstantX * (aps.size() - 1) && mouseY > showHeight) { | ||
textSize(18); | ||
int pos = (int)(mouseX/zoomConstantX + 0.5f); | ||
|
||
line(zoomConstantX*pos, showHeight, zoomConstantX*pos, height); | ||
float time = pos / movie.frameRate; | ||
text(round(time*1000)/1000f + "s", pos * zoomConstantX + 10, showHeight + 0); | ||
|
||
|
||
float vel = getVel(pos); | ||
line(0, vel * zoomConstantY + showHeight , width, vel * zoomConstantY + showHeight); | ||
text(vel/100 + " m/s", 10, vel * zoomConstantY + showHeight); | ||
textAlign(RIGHT, TOP); | ||
text(vel/100 + " m/s", width - 10, vel * zoomConstantY + showHeight); | ||
textAlign(LEFT, TOP); | ||
|
||
noStroke(); | ||
fill(0, 255, 255); | ||
circle(pos * zoomConstantX, vel * zoomConstantY + showHeight, 10); | ||
if (mousePressed && !isPlaying) { | ||
movie.jump(time); | ||
movie.read(); | ||
} | ||
} | ||
|
||
// DRAW RANDOM STATS =================================================================== | ||
float velSum = 0; | ||
for (int i = 1; i < aps.size(); i++) { | ||
velSum += getVel(i); | ||
} | ||
textSize(20); | ||
text("Átlagsebesség: " + velSum / (aps.size()-1) / 100 + " m/s", showWidth + 20, 30); | ||
text("Végsebesség: " + getVel(aps.size()-1) / 100 + " m/s", showWidth + 20, 60); | ||
text("Esés időtartama: " + movie.duration() + " s", showWidth + 20, 90); | ||
// DRAW VIDEO SELECTION BUTTONS ======================================================== | ||
for (Video v : videos) { | ||
v.drawButton(); | ||
} | ||
|
||
// DRAW STOP/PLAY BUTTON =============================================================== | ||
ssVideo.draw(); | ||
|
||
stroke(255, 0, 0); | ||
|
||
|
||
// RESTART MOVIE IF NEEDED ============================================================= | ||
if (movie.time() == movie.duration()) { | ||
if (!ssVideo.isStopped) { | ||
currentVideo.start(); | ||
} else { | ||
isPlaying = false; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
ArrayList<PVector> getPs(){ | ||
ArrayList<PVector> tempPs = new ArrayList<PVector>(); | ||
|
||
for (int x = (int) (movieWidth*0.3f); x < movieWidth*0.6f; x++) { | ||
for (int y = 0; y < movieHeight; y++) { | ||
cc = movie.get(x, y); | ||
cr=red(cc); | ||
cg=green(cc); | ||
cb=blue(cc); | ||
|
||
if (cr+cg+cb>200 && cr *1.2f < cb && cg * 0.3f < cb) { | ||
tempPs.add(new PVector(x, y)); | ||
} | ||
} | ||
} | ||
|
||
return tempPs; | ||
} | ||
|
||
PVector getAvgPos(ArrayList<PVector> ps){ | ||
PVector avg = new PVector(); | ||
for(PVector p: ps){ | ||
avg.add(p); | ||
} | ||
return avg.div(ps.size()+1); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import processing.video.*; | ||
|
||
Movie movie; | ||
float movieWidth = 1280; | ||
float movieHeight = 720; | ||
float showWidth = 1280; | ||
float showHeight = 720; | ||
|
||
ArrayList<PVector> ps; | ||
ArrayList<PVector> aps; // average positions | ||
|
||
imageProcessing context; | ||
|
||
Video[] videos = new Video[]{ | ||
new Video("Kicsi 1", "kicsi1.mov"), | ||
new Video("Kicsi 2", "kicsi2.mov"), | ||
new Video("Közepes 1", "kozepes1.mov"), | ||
new Video("Közepes 2", "kozepes2.mov"), | ||
new Video("Nagy 1", "nagy1.mov"), | ||
new Video("Nagy 2", "nagy2.mov"), | ||
}; | ||
|
||
Video currentVideo; | ||
StartStopVideo ssVideo; | ||
boolean isPlaying = true; | ||
void setup() { | ||
size(1600, 900); | ||
background(0); | ||
|
||
textFont(createFont("VT323-Regular.ttf", 100)); | ||
|
||
textSize(250); | ||
textAlign(CENTER, CENTER); | ||
fill(0, 255, 255); | ||
text("LOADING...", 0, 0, width, height); | ||
textAlign(LEFT, TOP); | ||
context = this; | ||
|
||
currentVideo = videos[0]; | ||
|
||
float w = 130; | ||
float h = 60; | ||
for(int i = 0; i < videos.length; i++){ | ||
videos[i].setPos(showWidth + 20 + (w + 20)*(i%2),((int)(i/2))*(h+20) + 150, w, h); | ||
} | ||
|
||
ssVideo = new StartStopVideo(showWidth + 20, videos[videos.length-1].y + videos[videos.length-1].h + 20, 130, 60); | ||
} | ||
int cc; | ||
float cr; | ||
float cg; | ||
float cb; | ||
|
||
float cmInPixels = 50f/20f; // 50 pixels are 20cm | ||
PVector avgPos = new PVector(); | ||
|
||
int movieFrameCount = 0; | ||
|
||
boolean highlightBalloon = true; | ||
|
||
|
||
float getVel(int i) { | ||
return getVel(i, true); | ||
} | ||
|
||
float getVel(int i, boolean allowRecursion) { | ||
if (i >= aps.size() || i < 1) return 0; | ||
float deltaY = (aps.get(i).y - aps.get(i-1).y) / cmInPixels; | ||
|
||
float vel = deltaY * movie.frameRate; | ||
if (vel <= 10 && allowRecursion) { | ||
if (i > 1 && i < aps.size() - 1) { | ||
vel = (getVel(i-1, false) + getVel(i+1, false))/2f; | ||
} else if (i > 1) { | ||
vel = getVel(i-1, false); | ||
} else if (i < aps.size() - 1) { | ||
vel = getVel(i+1, false); | ||
} | ||
} | ||
return vel; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
void keyPressed() { | ||
if (keyCode == 32) { // Stop / start loop | ||
ssVideo.isStopped = !ssVideo.isStopped; | ||
if (!ssVideo.isStopped) { | ||
currentVideo.start(); | ||
} | ||
} else if (keyCode == 72) { | ||
highlightBalloon = !highlightBalloon; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
void mousePressed(){ | ||
for(Video v: videos){ | ||
v.mousePressed(); | ||
} | ||
ssVideo.mousePressed(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
void movieEvent(Movie movie) { | ||
movie.read(); | ||
ps = getPs(); | ||
avgPos = getAvgPos(ps).copy(); | ||
aps.add(avgPos); | ||
} |