Polymorphism in Processing, access derived class variables
in
Programming Questions
•
10 months ago
I'm trying polymorphism in Processing for the first time and have a class Sphere that extends class Shape. I have an ArrayList<Shape> called objects and when I try to access a variable that is in Shape like:
- println(objects.get(0).n);
There is no problem. The variable, n, above does not appear in Sphere, only in Shape (Sphere inherits it). On the other hand accessing something that is in Sphere but not in Shape does not seem to work:
- println(objects.get(0).radius);
I get an error message that tells me "radius cannot be resolved or is not a field". How can I go about accessing this? Code in case that is helpful:
- ArrayList<Shape> objects;
- PVector light, prp, vrp;
- float uMin, uMax, vMin, vMax;
- void setup() {
- size(800, 800, P2D);
- loadPixels();
- /* Just one light for now:
- Without the code to handle otherwise, it is assumed
- that the light produces pure white color */
- light = new PVector(20.0, 20.0, -5.0);
- // Prepare Viewing-Reference Coordinate System
- prp = new PVector(0.0, 0.0, 0.0);
- vrp = new PVector(0.0, -20.0, -40.0);
- uMin = -40.0;
- uMax = 40.0;
- vMin = -40.0;
- vMax = 40.0;
- // Prepare objects
- objects = new ArrayList<Shape>();
- // Silver Sphere
- PVector ssCen = new PVector(15.0, -5.0, -80.0);
- Color ssKa = new Color(0.231, 0.231, 0.231);
- Color ssKd = new Color(0.278, 0.278, 0.278);
- Color ssKs = new Color(0.774, 0.774, 0.774);
- objects.add(new Sphere(ssCen, 12.0, ssKa, ssKd, ssKs, 89.6, true));
- // Test Silver Sphere duplicate 1
- PVector test = new PVector(-10.0, 0.0, -80.0);
- objects.add(new Sphere(test, 12.0, ssKa, ssKd, ssKs, 89.6, true));
- // Test Silver Sphere duplicate 2
- PVector test2 = new PVector(0.0, -25.0, -80.0);
- objects.add(new Sphere(test2, 12.0, ssKa, ssKd, ssKs, 89.6, true));
- }
- void draw() {
- println(objects.get(0).radius);
- // Delta i and j
- float di = (uMax-uMin)/width;
- float dj = (vMax-vMin)/height;
- // Fire a ray that bounces recursively
- float left = uMin+vrp.x;
- for (int i = 0; i < width; i++) {
- float top = vMax+vrp.y; // Up is up, not down!
- for (int j = 0; j < height; j++) {
- // Rays fire from the prp to a point on the vrp
- PVector direction = new PVector(left, top, vrp.z);
- Color intensity = rayTrace(prp, direction, 0);
- // Map the colors and make sure none exceed 255
- int r = (int)(min(intensity.r, 1.0)*255.0);
- int g = (int)(min(intensity.g, 1.0)*255.0);
- int b = (int)(min(intensity.b, 1.0)*255.0);
- pixels[i+j*width] = (255<<24)|(r<<16)|(g<<8)|b;
- top -= dj;
- }
- left += di;
- }
- updatePixels();
- }
- class Color {
- float r, g, b;
- Color(float inR, float inG, float inB) {
- r = inR;
- g = inG;
- b = inB;
- }
- }
- class Shape {
- boolean reflects;
- float n;
- Color ka, kd, ks;
- Shape(Color inKa, Color inKd, Color inKs, float inN, boolean inRe) {
- ka = inKa;
- kd = inKd;
- ks = inKs;
- n = inN;
- reflects = inRe;
- }
- float intersection(PVector a, PVector b) {
- return -1.0;
- }
- PVector surfaceNormal(PVector in) {
- PVector out = new PVector(0.0, 0.0, 0.0);
- return out;
- }
- }
- class Sphere extends Shape {
- float radius, radSq;
- PVector center;
- Sphere(PVector inC, float inR, Color inKa, Color inKd, Color inKs, float inN, boolean inRe) {
- super(inKa, inKd, inKs, inN, inRe);
- center = inC;
- radius = inR;
- // Math simplification
- radSq = radius*radius;
- }
- float intersection(PVector a, PVector b) {
- // Delta x, y, and z
- float dx = b.x-a.x;
- float dy = b.y-a.y;
- float dz = b.z-a.z;
- // Math simplifications
- float rxa = a.x-center.x;
- float rya = a.y-center.y;
- float rza = a.z-center.z;
- // Prepare Quadratic Formula
- float qa = dx*dx+dy*dy+dz*dz;
- float qb = 2*(dx*rxa+dy*rya+dz*rza);
- float qc = rxa*rxa+rya*rya+rza*rza-radSq;
- // Parametric t value
- float t = -1;
- // Calculate (up to) two intersections
- float qRight = sqrt(qb*qb-4*qa*qc);
- if (!Float.isNaN(qRight)) {
- float twoQa = 2*qa;
- t = min((-qb+qRight)/twoQa, (-qb-qRight)/twoQa);
- }
- return t;
- }
- PVector surfaceNormal(PVector in) {
- PVector out = new PVector(
- (in.x-center.x)/radius,
- (in.y-center.y)/radius,
- (in.z-center.z)/radius);
- return out;
- }
- }
- Color rayTrace(PVector a, PVector b, int depth) {
- Color out = new Color(0.0, 0.0, 0.0);
- // Determine which object (if any) is closest
- float t = 1000000; // Arbitrarily large
- int id = -1;
- for (int i = 0; i < objects.size(); i++) {
- float objDist = objects.get(i).intersection(a, b);
- if (objDist > 0 && objDist < t) {
- t = objDist;
- id = i;
- }
- }
- // If an object was intersected
- if (id != -1) {
- // Add ambient light
- out.r += objects.get(id).ka.r;
- out.g += objects.get(id).ka.g;
- out.b += objects.get(id).ka.b;
- // Point of intersection
- PVector intVec = new PVector(
- a.x+t*(b.x-a.x),
- a.y+t*(b.y-a.y),
- a.z+t*(b.z-a.z));
- // Get normalized surface normal vector
- PVector surNor = objects.get(id).surfaceNormal(intVec);
- // Get normalized light direction vector
- PVector ligVec = new PVector(light.x-intVec.x, light.y-intVec.y, light.z-intVec.z);
- ligVec.normalize();
- // Calculate (N*L)
- float dotNL = surNor.dot(ligVec);
- if (dotNL > 0) {
- // Add diffuse light
- out.r += objects.get(id).kd.r*dotNL;
- out.g += objects.get(id).kd.g*dotNL;
- out.b += objects.get(id).kd.b*dotNL;
- // Get normalized reflection direction vector
- PVector refVec = new PVector(2*surNor.x*dotNL-ligVec.x,
- 2*surNor.y*dotNL-ligVec.y,
- 2*surNor.z*dotNL-ligVec.z);
- refVec.normalize();
- // Get normalized viewer direction vector
- PVector vieVec = new PVector(a.x-intVec.x, a.y-intVec.y, a.z-intVec.z);
- vieVec.normalize();
- // Calculate (R*V) to the nth power
- float dotRVSq = refVec.dot(vieVec);
- dotRVSq = pow(dotRVSq, objects.get(id).n);
- if (dotRVSq > 0) {
- // Add specular light
- out.r += objects.get(id).ks.r*dotRVSq;
- out.g += objects.get(id).ks.g*dotRVSq;
- out.b += objects.get(id).ks.b*dotRVSq;
- }
- // Recursively get the bounce light
- if (objects.get(id).reflects && depth < 3) {
- PVector direction = new PVector(intVec.x+refVec.x, intVec.y+refVec.y, intVec.z+refVec.z);
- Color reflection = rayTrace(intVec, direction, depth+1);
- out.r += reflection.r*objects.get(id).ks.r;
- out.g += reflection.g*objects.get(id).ks.g;
- out.b += reflection.b*objects.get(id).ks.b;
- }
- }
- }
- return out;
- }
Edit: Realized highlighting would probably be helpful
1