There are two things here
- create a new class (i.e. create and compile the source code for a new user defined class at runtime)
- instantiate an instance (object) of an existing class.
There are a couple of 3rd party libraries that should enable to do the first item. JavaParser and ASM but they are not suitable for beginners. I used ASM in my Processing library, Jasmine, but I found it very hard use.
Now item 2 is a common design pattern called the Factory Method and is really useful if there are a number of ways to instantiate (create an object / instance) a class.
Consider the Circle class, it would have fields for its center {cx, cy] and its radius [r] so it would be simple to create a class and constructor e.g.
class Circle {
private float cx, cy, radius;
public Circle(float cx, float cy, float radius) {
this.cx = cx;
this.cy = cy;
this.radius = radius;
}
}
There are other ways to uniquely uniquely specify a circle e.g.
- given a center position and the area of the circle
- the smallest circle that touches two non-intersecting circles
- given 3 unique points on the circumference of a circle
The following code demonstrates a Circle class that has 2 factory methods covering scenarios (1) and (2) above.
When using class (static) methods as factory methods it is common practice to make the constructors private. This means only the factory methods can be used to instantiate objects of this class. To overcome this I have provided a factory method to utilize the standard parameter constructor.
Circle c0, c1, c2;
void setup() {
size(300, 300);
c0 = Circle.fromCR(50, 40, 30);
c1 = Circle.fromCA(200, 220, 9000);
c2 = Circle.fromCC(c0, c1);
}
void draw() {
background(255, 250, 240);
c0.draw(this, 0xFF88FF88, 0x80448844, 1.5); // small green circle
c1.draw(this, 0xFF4466FF, 0x80222288, 1.5); // medium blue circle
c2.draw(this, 0xFFFFFF88, 0x80CCCC22, 2.0); // large yellow circle
}
public static class Circle {
// Get circle given center position and radius
static Circle fromCR(float cx, float cy, float radius) {
return new Circle(cx, cy, radius);
}
// Get circle for given center and area
static Circle fromCA(float cx, float cy, float area) {
float r = sqrt(area / PI);
return new Circle(cx, cy, r);
}
// Get smallest circle that touches two others
static Circle fromCC(Circle c0, Circle c1) {
float radius = (dist(c0.cx, c0.cy, c1.cx, c1.cy) - c0.radius - c1.radius)/2;
float ang = atan2(c1.cy - c0.cy, c1.cx - c0.cx);
float cx = c0.cx + (radius + c0.radius) * cos(ang);
float cy = c0.cy + (radius + c0.radius) * sin(ang);
return new Circle(cx, cy, radius);
}
private float cx, cy, radius;
private Circle(float cx, float cy, float radius) {
this.cx = cx;
this.cy = cy;
this.radius = radius;
}
void draw(PApplet pa, int fc, int sc, float sw) {
pa.fill(fc);
pa.stroke(sc);
pa.strokeWeight(sw);
pa.ellipse(this.cx, this.cy, 2 * this.radius, 2 * this.radius);
}
}