there's anther question here: why after loading the image the coordinate of the image is minus X +) , minus Y(+) for example image(photo,-1000,-1500); is choosing a part from downstairs
Function scale() belongs to Processing's transformation group. That is, it changes the whole PGraphics coordinate system!
By default, coordinates (0,0) at the far top-left is the point of origin. Coords. go from left to right and up to down.
But when we issue a scale(-1, -1), the (0, 0) is transported to the far down-right! And it's now from right to left and down to up!
However, if we wanna place a mirrored image at the very same place, we gotta compensate the coordinate change.
I've devised a simple math for it when I've tweaked a "Bouncing Angry Bird" program.
It's bugged online! You gotta copy it to run offline though: :-&
how to '' compensate the coordinate change.'' ??? by adding '-'??? (i am not good at math and new to Processing,so i can't understand some part of your code)
x & y are the coordinates we wanna place the img at canvas;
w & h are the PImage's dimensions. That is: img.width & img.height;
sigX & sigY are either +1 or -1. +1 is no modification. While -1 is mirroring.
When there's no mirror, that is sigX or sigY is +1, we don't subtract neither w nor h from x*sigX or x*sigX.
There's nothing to compensate!
On the other hand, when it's -1, we gotta do x*sigX - w or y*sigY - h. In short: -x - w or -(x + w).
B/c the canvas coordinate origin's direction is backwards. That is, it's now from right to left or bottom to top!
It's as if the whole canvas (PGraphics) was transported to another quadrant Cartesian plane! @-)
That's when it comes in w*(sigX>>1) or h*(sigY>>1). When it's +1, sig >> 1 returns 0, nullifying w or h!
However, when it's -1, >> 1 returns the very same -1. This time w or h's subtraction against x or y kicks in! :ar!
Just ask again if you haven't understood some point! ;;)
@GoToLoop : image(img, XsigX + w(sigX>>1), YsigY + h(sigY>>1));
why the x parameter is XsigX + w(sigX>>1) and the y is YsigY + h(sigY>>1) , where this math expression coming from ??
The other 1 I've got is the optimized pick a random opaque color -> (int) random(#000000),
rather than the clumsy common 1 we see around -> (int) random(256), (int) random(256), (int) random(256).
You see, when the bird is flying towards the right side, we display its unaltered sprite. Its x coordinate placement is intact.
But when it bounces towards the left side, we gotta use scale(-1, 0) in order to display its horizontal mirrored sprite.
Problem is, scale() alters the whole canvas, transporting its matrix coordinate system even to another quadrant! @-)
Therefore, the value of x isn't the same anymore! So in order to display the sprite at the same place, we gotta find its new x.
sigX = -1;
scale(sigX, 0);
x = x*sigX + img.width*(sigX>>1);
sigX is either -1 or 1, representing whether it's horizontally mirroring or not.
And x is the original x coordinate we wanna place the sprite at the canvas.
So when sigX = 1, x stays the same -> x * 1 = x. While 1 >> 1 results 0. Thus img.width*(0) = 0.
Final result is the very same x! =:) . And that's the aim, since there's no scale() changes -> scale(0, 0);
Now w/ sigX = -1, x becomes negative -> x * -1 = -x. And -1 >> 1 returns the very same -1.
This time, img.width*(-1) = -img.width, rather than 0. That's a small additional adjustment to the x value though.
Take notice that expression math is for when we got a dynamic sigX or sigY. When they keep swapping +1 & -1 states.
Otherwise, when we wanna display an always horizontally mirrored image, simply use: (*)
scale(-1, 0);
image(img, -(x + img.width), y);
A more easier to understand, but slower & bigger alternative version:
@GoToLoop: rotate(angle, x, y, z) mimics glRotate(angle, x, y, z). x, y and z are just multipliers for the equally named axes. rotate(TWO_PI, 0.5, 0.25, 0.0) for example will rotate the transformation matrix by PI around the x axis, by HALF_PI around the y axis and by 0 around the z axis.
@Chrisir: In case number is an boolean/byte/char/short/int/long (/Boolean/Byte/etc.) use bitwise and, it's much faster than modulo:
int number = 4;
if ((number & 1) == 0) {
println(number + "is not odd");
} else {
println(number + "is odd");
}
I try to use bitwise AND all the time, as long the divisor is a power of 2:
static final int NUM = 1<<5; // 2^5 = 32
final PImage[] imgs = PImage[NUM];
void draw() {
final int idx = frameCount & NUM-1; // same as frameCount % NUM
set(0, 0, imgs[idx]);
}
In case number is an int/long...
To be fairer, don't forget that byte, short, char are also whole types as well! :-h
Even though Java coerces them to int before executing the operation. But at least it's auto! :-@
And thx for the 4-parameter rotate() explanation, @Poersch ! =D>
Answers
I guess this might work: :-/
try
scale(1,-1);
to flip
save - see reference
http://processing.org/reference/save_.html
as the effect the code show ,seems scale no effect,any tips???
here...
there seems some problem in the code , can somebody figure it out??? no correct image show but the black......
I think with scale you rotate the image out of the canvas
bring it back in with image(photo, -photo.width, 0); like in my code above
Or simply write yourself an flipImage() function:
there's anther question here: why after loading the image the coordinate of the image is minus X +) , minus Y(+) for example image(photo,-1000,-1500); is choosing a part from downstairs
Function scale() belongs to Processing's transformation group. That is, it changes the whole PGraphics coordinate system!
By default, coordinates (0,0) at the far top-left is the point of origin. Coords. go from left to right and up to down.
But when we issue a scale(-1, -1), the (0, 0) is transported to the far down-right! And it's now from right to left and down to up!
However, if we wanna place a mirrored image at the very same place, we gotta compensate the coordinate change.
I've devised a simple math for it when I've tweaked a "Bouncing Angry Bird" program.
It's bugged online! You gotta copy it to run offline though: :-&
http://studio.processingtogether.com/sp/pad/export/ro.9lSicL0a3WMfi/latest
Here's a simple sketch demoing that: :bz
how to '' compensate the coordinate change.'' ??? by adding '-'??? (i am not good at math and new to Processing,so i can't understand some part of your code)
Look @ line #47:
image(img, x*sigX + w*(sigX>>1), y*sigY + h*(sigY>>1));
+1
or-1
.+1
is no modification. While-1
is mirroring.When there's no mirror, that is sigX or sigY is
+1
, we don't subtract neither w nor h fromx*sigX
orx*sigX
.There's nothing to compensate!
On the other hand, when it's
-1
, we gotta dox*sigX - w
ory*sigY - h
. In short:-x - w
or-(x + w)
.B/c the canvas coordinate origin's direction is backwards. That is, it's now from right to left or bottom to top!
It's as if the whole canvas (PGraphics) was transported to another quadrant Cartesian plane! @-)
That's when it comes in
w*(sigX>>1)
orh*(sigY>>1)
. When it's+1
,sig >> 1
returns 0, nullifying w or h!However, when it's
-1
,>> 1
returns the very same-1
. This time w or h's subtraction against x or y kicks in! :ar!Just ask again if you haven't understood some point! ;;)
rotate is not available with this renderer. ???? why it show me this???
@GoToLoop: what's this 4 array definitioned for
final int sigX = (int) sigs[idx].x
what's .x meaning and the 'final' type
Processing 2+ got 4 rendering engines:
JAVA2D, which is the default, uses raster rendering. The next 2 are OpenGL based!
Many Processing functions would only make sense in a 3D context!
http://processing.org/reference/size_.html
In order to represent the signum values +1, -1 for the 4 (x, y) coordinate pairs, there were at least 2 obvious choices:
byte
arrays. 1 for the sigX and the other for the sigY.Obviously, a PVector[] is more easy visually. Just outta curiosity, check out how the
byte[]
way would be:processing.org/reference/PVector.html
That's the dot operator, which lets us access methods & fields from an object through its reference.
http://processing.org/reference/dot.html
In that case
sigs[idx].x
,sigs[idx]
provides the reference for a PVector object, while the x is the field we wanna access!Keyword
final
isn't a data type! It just means a variable can't be changed anymore until the end of its scoped lifespan:http://processing.org/reference/final.html
@GoToLoop : image(img, XsigX + w(sigX>>1), YsigY + h(sigY>>1)); why the x parameter is XsigX + w(sigX>>1) and the y is YsigY + h(sigY>>1) , where this math expression coming from ??
I can rotate a shape with JAVA2D Why can't rotate the image??? what's wrong with the image function??? and the solution please , thanks!
Actually I've "invented" it while pursuing the "fastest" way to display "Bouncing Angry Bird", either it's flying to right or to left!
http://studio.processingtogether.com/sp/pad/export/ro.9lSicL0a3WMfi/latest
The other 1 I've got is the optimized pick a random opaque color ->
(int) random(#000000)
,rather than the clumsy common 1 we see around ->
(int) random(256), (int) random(256), (int) random(256)
.You see, when the bird is flying towards the right side, we display its unaltered sprite. Its x coordinate placement is intact.
But when it bounces towards the left side, we gotta use
scale(-1, 0)
in order to display its horizontal mirrored sprite.Problem is, scale() alters the whole canvas, transporting its matrix coordinate system even to another quadrant! @-)
Therefore, the value of x isn't the same anymore! So in order to display the sprite at the same place, we gotta find its new x.
sigX is either -1 or 1, representing whether it's horizontally mirroring or not.
And x is the original x coordinate we wanna place the sprite at the canvas.
So when
sigX = 1
, x stays the same ->x * 1 = x
. While1 >> 1
results 0. Thusimg.width*(0) = 0
.Final result is the very same x! =:) . And that's the aim, since there's no scale() changes ->
scale(0, 0);
Now w/ sigX = -1, x becomes negative ->
x * -1 = -x
. And-1 >> 1
returns the very same -1.This time,
img.width*(-1) = -img.width
, rather than 0. That's a small additional adjustment to the x value though.Take notice that expression math is for when we got a dynamic sigX or sigY. When they keep swapping +1 & -1 states.
Otherwise, when we wanna display an always horizontally mirrored image, simply use: (*)
A more easier to understand, but slower & bigger alternative version:
I can rotate a shape with JAVA2D Why can't rotate the image??? what's wrong with the image function??? and the solution please , thanks!
can u give me some more tips with the problem??? @GoToLoop
for example I can use point rect line to create a shape , and can rotate it ,but why can't the image ???
Sorry I can't help you out w/ 3D stuff. No good at it at all! :(
Anyways, I've managed to use rotate() in my example w/ JAVA2D:
idx = frameCount % NUM;
what's the meaning of it???
hey GotoLoop : all code is the same but this changed : rotate(QUARTER_PI/4,1,1,0); and you rotate will fail why can't rotate with a another point ?
final int idx = frameCount % NUM;
Variable frameCount is the # of times draw() was invoked:
http://processing.org/reference/frameCount.html
NUM is a constant for the # of PVector[] objects. That is, the length of that array.
Arithmetic operator modulo
%
is the remainder of a division:http://processing.org/reference/modulo.html
In short, it makes sure that idx is in the range of
0
up toNUM-1
, no matter the current value of frameCount. B-)rotate(QUARTER_PI/4, 1, 1, 0);
I don't even know what those extra 3 arguments do. Processing's reference doesn't even explain that overloaded case:
http://processing.org/reference/rotate_.html
there is another question : how to judge odd number or not , does Processing has the function??
maybe like this. The % sign means modulo
see
http://en.wikipedia.org/wiki/Modulo_operation
@GoToLoop: rotate(angle, x, y, z) mimics glRotate(angle, x, y, z). x, y and z are just multipliers for the equally named axes. rotate(TWO_PI, 0.5, 0.25, 0.0) for example will rotate the transformation matrix by PI around the x axis, by HALF_PI around the y axis and by 0 around the z axis.
@Chrisir: In case number is an boolean/byte/char/short/int/long (/Boolean/Byte/etc.) use bitwise and, it's much faster than modulo:
I try to use bitwise AND all the time, as long the divisor is a power of 2:
To be fairer, don't forget that
byte
,short
,char
are also whole types as well! :-hEven though Java coerces them to
int
before executing the operation. But at least it's auto! :-@And thx for the 4-parameter rotate() explanation, @Poersch ! =D>
@GoToLoop: You are right! Totally forgot to mention those! It was way to late while I wrote this. Updated my last post. :D
I guess you already know this page, but just in case you don't and for anyone else of course: Bit Twiddling Hacks
It's a great site about all kinds of usefull bitwise operations you should know about. ;)
Thx for the link! I was learning some bitwise tricks along the way! :bz