We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello, I made this mandelbrot renderer with the help of a friend, you can see it works fine: click to move/zoom https://www.dropbox.com/s/u6vql2ccmw1binb/mb2D_06.7z?dl=0
I then noticed the loss off precision when zoomed in, so today I tried to convert whatever I had to, to double precision. I made my own 2D vector class which processes double pres. values, but now everything is whacked. I can draw the circle, but when I run mandelbrot function it just makes a white screen.. here is the attempted adapted code: https://www.dropbox.com/s/8i37kmuefdbfwj0/mb2D_08.7z?dl=0
in its current state when you run it you will see a circle, my last attempt at debugging before I gave up.. for today. if anyone would mind having a look it would be really helpful. Thank you.
Answers
https://forum.Processing.org/two/discussion/15473/readme-how-to-format-code-and-text
Only revised your class Vec2D and made some mods on it.
No idea whether it might work for ya now though: :-??
You should take a look at PVector class' source code too: ~O)
https://GitHub.com/processing/processing/blob/master/core/src/processing/core/PVector.java
hello! I replaced the class with your revised version. This totally works now. But the syntax and stuff you have used is confounding. I don't understand the concept of using final as a type for the input in the class functions.
I am curious, what is the reason for the "set" functions
e.g. you define a new Vec2D ( a, b) as A
what is the difference between updating it as B, using set, compared to just making it equal B:
Also no idea what the last two things are doing, esp. clone:
The first set() function is calling the second set function, so it is the second set function the one that is doing all the work. Having multiple set functions to handle different situations is common (and quite useful) and having one of them to do the final operation ensures consistency across all the functions. Consistency is important when the functionality is literally the same.
For the final part, it ensures the vector is not changed during this operation. It is more for practice (and a good habit) since setting should not modify the passed reference. I let @GoToLoop add any other comment...
@GoToLoop: Wouldn't be possible to extend Vec2D from PVector and just provide a constructor that takes double arguments and internally create a PVector with the arguments casted to float? I am thinking more of to be able to reuse all the code implemented in the PVector class. Would that be a valid approach or I am overlooking something?
For annotations:
https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html
@nnenov
https://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html
@GoToLoop This guarantees you do a deep copy for this class without any other implementation?
Kf
In a hackish way yes! But it'd demand many changes. And still it'd be very buggy. :-&
Here's some partial attempt. Not trustful at all though: :@)
Keyword
final
isn't a datatype in the same veinpublic
isn't it either. It is a modifier. :-BWhen used on a variable,
final
makes it impossible to use operator=
and its siblings on it after it's got its initial value: https://Processing.org/reference/final.htmlIt's huge that difference! Assigning an object variable to another variable using the operator
=
makes them both alias for the very same object! :-SSRegardless the alias variable we use to mutate the object it points to, if we use the other alias, we'll realize the mutation was mirrored there too. @-)
That's why I've implemented a clone() method for class Vec2D! ;;)
So we can avoid the trap of having alias for the same object. $-)
You see, when we invoke clone(), a
new
Vec2D object is created, but w/the same content as the original.We can safely mutate this cloned object w/o fearing of having the changes reflected on the original! \m/
For example, if we call
vecA.add(vecB);
, vecA is mutated by the add() method's result.However, if we call clone() before add():
Vec2D vecC = vecA.clone().add(vecB);
We get the result of the add() operation on the newly cloned object rather than directly in vecA.
So now we've got a 3rd Vec2D object assigned to variable vecC w/ the result of vecA + vecB. :)>-
@kfrajer, clone() method creates a shallow copy:
http://docs.Oracle.com/javase/8/docs/api/java/lang/Object.html#clone--
However, since class Vec2D doesn't have any fields w/ a mutable object datatype, rather it's just 2 primitive fields x & y, a shallow copy is all we need here. :P
Otherwise we'd need to clone() each mutable object as well! #:-S
@kfrajer , why does the second set function return "this"?? I can see how the first takes a vector and calls the next function of the same name with the vector components as separate fields, but what is the actual purpose / practical application for these functions? Is it so you can have the option to say foo.set(foo1) rather than foo = foo1?
Is the second set function just returning itself/ the current object, a 2D double prec. vector object? if so, why do all the other functions not return "this"
@GoToLoop , I don't understand why final is used in these functions' input fields. is it to help save memory/ speed things up? why do they need to be protected?
By "functions' input fields" I believe you mean functions' parameters, right? L-)
Neither
final
norpublic
are necessary for thisclass
. You can simply remove them! ;)Like I've said, if we assign an object variable to another object variable they both become alias for the same object. :-@
Therefore,
foo.set(foo1)
isn't the same thing asfoo = foo1
!Rather
foo.set(foo1)
is equivalent offoo.x = foo1.x; fox.y = foo1.y;
. :-BIn order to allow method chaining like this:
vecA.set(Math.PI, 1e3d).add(vecB).mul(-3.57d);
$-)https://GitHub.com/processing/processing/blob/master/core/src/processing/core/PVector.java
@GoToLoop I'm sorry I didn't see your previous reply about mutation for some reason! I didn't know this was a thing, I think I heard about this happening in python..
when you said "Regardless the alias variable we use to mutate the object it points to, if we use the other alias, we'll realise the mutation was mirrored there too."
Would you mind sharing a practical example of this occurring in processing? I always "set" stuff just using = and haven't noticed this mirrored behaviour, but I am not exactly a seasoned coder.
Object alias example:
Object clone example:
New Object followed by set() example:
Thank you, this really cleared it up for me. I need to go through, check and revise my code now to make sure I am conforming to this.