We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi there.
I'm trying to use PVectors to store coordinates that will be input in a class constructor, and getting NullPointerExceptions. As in below:
Coords[] crds = new Coords[20]
int CleanArray[] = {0, 0, 0, 0, 0, 0, 0, 0}; // Meant for testing
void setup() {
crds[0] = new Coords(CleanArray);
}
class Coords {
PVector[] q = new PVector[8];
int j = 0;
Coords(int[] coords) {
int lim = coords.length;
for (int i = 0; i < lim; i= i++) {
q[i].set(coords[j], coords[j+1]); // This is the line that gets a NullPointerException.
j+=2;
}
}
}
I might be misusing PVectors and Class.
What I am trying to do:
1) Whenever a Coords object is created, it receives an array as a parameter.
2) The array gets distributed to PVectors via set() -- so q[0].set(coords[j], coords[j+1]) would set q[0].x to coords[0] and q[0].y to coords[1], and subsequently.
Could anyone shed a light?
If there's a better way to distribute the array values to use later, I'm all ears.
Thanks!
Answers
Hmm... How about this 1? ~O)
Whoa
Nice working answer. Lots of new things to learn! I liked the "..." parameter and the bit shifting on the q[i>>1].
I didn't undestand the shifting back and forth in line 26 though. Could you ellaborate? I understand that len is meant to not let the "for" overflow (it checks if coords.length is over QTY, and if it does, its value becomes QTY). But not the >>1<<1 part.
Would the "final" before PVector in line 22 prevent me from changing crds[1].q contents?
Thank you for your time! (I'm new here, would accepting the answer lock the discussion?)
accepting the answer is a bad idea...
question looks solved then
This creates an array that can hold 8 PVectors, it does not create 8 PVectors so in line 20 when you try to set the values of a PVector in the array there is none - hence NPE
In GoToLoop(s) code
coords.length>>1<<1
finds the largest number <= coords.length that is a multiple of 2
No - you can change the PVectors in the array but it would prevent you changing the array, i.e.
@quark's already answered @XKuei. Nonetheless, gonna append my own complementary explanations too: :-@
>>1 <<1
is analogous to/2 *2
. In Java and many C-derived languages, except JS, if both operands are of whole type, their division's result cuts any fractional part off. That's why3/4
yields0
rather than.75
! @-)In short, it's the quickest way I've found to force an even # of elements, so they're paired up for PVector. :-B
Otherwise, that odd pairless MAX_INT argument in line #15 would throw an NPE too! 8-X
But why
>>1
instead of regular/2
you might ask? Well,>>
is a bit tiny faster than/
! \m/Another reason is
>>1
works correctly in JS, while/2
would bug there b/c there's no whole division in JS!So right behavior is kept whether Java or JS modes are used! =P~
Absolutely not! Keyword
final
only affects the variable itself, locking up its value.It doesn't affect any object's members it may reference to: https://processing.org/reference/final.html
In
final PVector[] q = new PVector[QTY];
, field q is "forever" bound to the newly created array's reference.Therefore, q can't be reassigned to another array reference. Not even
null
is possible.Actually, it can't even be assigned to itself:
q = q
! :))Another very common doubt is the fact that
new PVector[QTY];
only instantiates the[]
array itself.All of their indexed "slots" or elements are still
null
. Or0
,0.0
orfalse
, depending on array's type.That's why we still need to instantiate PVector objects and assign them to the array's "slots".
Once those "slots" are properly initialized, we can use set() method instead to change PVector's values. :-bd
Nope! Actually most of us answerers still check on "answered" threads no matter what! #:-S