#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# Why is lights() not lighting sphere in a class?

edited January 2018

Why is lights() not lighting sphere in a class in this example?

``````float th_6 = 0;
Orbital Orb_3;

void setup()
{
size(1280, 1024, P3D);

//Class initialization
Orb_3 = new Orbital();
}

void draw()
{
background(0);
lights();
noStroke();
translate(width/2, height/2, 0);
sphere(20); //lights work on this!
th_6=th_6+TWO_PI/360;
seq_D();
}

class Orbital
{
int A = 200; //diameter
float x, y, z;
float th = 0;

void Circle()
{
for(th=0;th<TWO_PI;th+=TWO_PI/360)
{
x=A*cos(th);
y=A*sin(th);
point(x, y, 0);
}
}

void Traj()
{
x = A*cos(th_6);
y = A*sin(th_6);
translate(x,y);
}
}

void seq_D()
{
strokeWeight(2);
rotateY(th_6);
stroke(255, 0, 255);
Orb_3.Circle();
Orb_3.Traj();
sphere(20);       //lights DO NOT work on this!
}
``````
Tagged:

• Please edit post, highlight code, press Ctrl-o

• Thanks for tip.

• edited October 2016

``````void seq_D()
{
strokeWeight(2);
rotateY(th_6);
stroke(255, 0, 255);
Orb_3.Circle();
Orb_3.Traj();
sphere(50);
}
``````

@GLV -- good catch -- it doesn't have anything to do with a class, it seems like each `sphere()` needs there to be `noStroke()` in order to have default lighting. In order to consistently isolate stroke/noStroke in your sketch try using pushStyle/popStyle.

A few suggestions:

1. Set the whole sketch to `noStroke()` in `setup()` -- then all your spheres will draw correctly without needing to remember to remove stroke each time.
2. If you need to change styles (for example, for your purple points of your orbital circle), wrap that `pushStyle()` / `popStyle()` so that your later spheres don't all turn purple as well.
3. Draw your very first central sphere(20) after the rotate -- you can't see a difference now, but if you used a globe of the earth or other textures later, then that would make it spin correctly with the camera.
4. Right now your Orbital.circle and Orbital.traj both use the same Orbital.x,y as scratch variables for different reasons -- but this could cause nasty bugs in the future. Orbital.x,y should probably be used to store translation offsets if you draw more than one member of the class.

Other thoughts:

• If Orbital.circle is going to draw, why not have Orbital.traj draw as well? Consistently of class methods as a sketch grows.
• Adding arguments for class methods: purple and thick vs. green and thin, for example.
• Adding an Orbital constructor so that you can set the diameter etc.

Sketch:

``````//// https:// forum.processing.org/two/discussion/18352/why-is-lights-not-lighting-sphere-in-a-class

color purple = color(255, 0, 255);
color green = color(0, 255, 0);
float th_6 = 0;
Orbital Orb_3;
Orbital Orb_3b;

void setup() {
size(300, 300, P3D);
noStroke(); // default so sphere() is lighted
//Class initialization
Orb_3 = new Orbital(100);
Orb_3b = new Orbital(50,0,0,0);
}

void draw() {
background(0);
lights();
translate(width/2, height/2, 0);
sphere(20);
th_6+=TWO_PI/360;
rotateY(th_6);
Orb_3.center(30);
Orb_3.circle(3, purple);
Orb_3.traj(15, th_6);

rotateY(th_6);
rotateZ(th_6);
Orb_3b.circle(2, green);
Orb_3b.traj(5, th_6/2);
}

class Orbital {
int diam = 200; //diameter
float x, y, z;
float th = 0;

Orbital(int diam_){
this(diam_, 0.0, 0.0, 0.0);
}
Orbital(int diam_, float x_, float y_, float z_){
diam = diam_;
x = x_;
y = y_;
z = z_;
}

void center(float size) {
pushMatrix();
translate(x, y, z);
sphere(size);
popMatrix();
}

void circle(int weight, color c) {
float cx, cy;
for (th=0; th<TWO_PI; th+=TWO_PI/360)
{
cx=diam*cos(th);
cy=diam*sin(th);
pushMatrix();
translate(x,y,z);
pushStyle();
strokeWeight(weight);
stroke(c);
point(cx, cy, 0);
popStyle();
popMatrix();
}
}

void traj(float size, float angle) {
float tx = diam*cos(angle);
float ty = diam*sin(angle);
pushMatrix();
translate(tx + x, ty + y, z);
sphere(size);
popMatrix();
}
}
``````

• edited October 2016

Hello, Thanks for taking the time to provide great feedback! My background is embedded C with no object oriented programming. :) and :( ! I have been programming for a couple of months now with Processing and gradually transitioning from "procedural" to "object-oriented" and enjoying the ride. Converting all the code (1000s of lines and dozens of tabs!) I wrote for this and other projects to object-oriented and already seeing the benefits:

GLV

• @GLV -- this is really beautiful work! Thank you for sharing the video.

I hope that the project is still going well.

• edited October 2016 Answer ✓

@GLV --

Later, I found myself wondering if the noStroke() lighting behavior was actually bug and should be reported.

It looks like it is by-design -- however it can be confusing trying to light a sphere by trial-and-error.

The problem above was that your stroke weight / sphere distance was creating a mesh that completely covered your fill so that it couldn't interact with the lighting source.

Essentially:

1. lighting interacts with non-black fill
2. stroke covers fill, and does not interact with light.

Therefor, the only light-able spheres are: - filled - non-black - have no stroke - or have stroke that show fill through the mesh.

See demo sketch for examples. Out of these eighteen spheres with different settings, only four of them respond to the light source.

``````/**
* Sphere Lighting
* 2016-10-30 Jeremy Douglass - Processing 3.2.1
* https:// forum.processing.org/two/discussion/18352/
**/

float sw, sh, sr; // sphere width, height, radius
float lightX, lightY;

void setup() {
size(800, 400, P3D);
textAlign(CENTER,CENTER);
textSize(12);
textMode(SHAPE);
sw = width/7.0;
sh = height/3.0;
sr = width/14.0;
}
void draw() {
background(64);
translate(0,0,-70);

styleSphere ( sw * 0, sh * 0, sr, "noStroke", 0,  "noFill");
styleSphere ( sw * 1, sh * 0, sr, "noStroke", 0,  "0");
styleSphere ( sw * 2, sh * 0, sr, "noStroke", 0,  "255");
styleSphere ( sw * 0, sh * 1, sr, "0",        1,  "noFill");
styleSphere ( sw * 1, sh * 1, sr, "0",        1,  "0");
styleSphere ( sw * 2, sh * 1, sr, "0",        1,  "255");
styleSphere ( sw * 0, sh * 2, sr, "255",      1,  "noFill");
styleSphere ( sw * 1, sh * 2, sr, "255",      1,  "0");
styleSphere ( sw * 2, sh * 2, sr, "255",      1,  "255");

styleSphere ( sw * 4, sh * 0, sr, "noStroke", 0, "noFill");
styleSphere ( sw * 5, sh * 0, sr, "noStroke", 0, "0");
styleSphere ( sw * 6, sh * 0, sr, "noStroke", 0, "255");
styleSphere ( sw * 4, sh * 1, sr, "0",        10, "noFill");
styleSphere ( sw * 5, sh * 1, sr, "0",        10, "0");
styleSphere ( sw * 6, sh * 1, sr, "0",        10, "255");
styleSphere ( sw * 4, sh * 2, sr, "255",      10, "noFill");
styleSphere ( sw * 5, sh * 2, sr, "255",      10, "0");
styleSphere ( sw * 6, sh * 2, sr, "255",      10, "255");
}

void styleSphere(float x, float y, float r, String strStroke, int strWeight, String strFill){
pushMatrix();
translate(x, y, 0);
translate(r, r, 0);

//// draw sphere
pushStyle();
lightControl();
strokeWeight(strWeight);
if(strStroke == "noStroke") { noStroke(); }
else { stroke(int(strStroke)); }
if(strFill == "noFill") { noFill(); }
else { fill(int(strFill)); }
sphere(r);
popStyle();

//// draw label
translate(0,0,80);
pushStyle();
strokeWeight(1);
fill(255);
noLights();
rect(-36,-24,72,48);
fill(0);
text(strStroke + "/" + strWeight + "\n" + strFill, 0,0,0);
popStyle();

popMatrix();
}

void lightControl(){
// lights();
directionalLight(255, 204, 204,
-(mouseX / float(width)  - 0.5) * 2,
-(mouseY / float(height) - 0.5) * 2,
-1);
}
``````

• @jeremydouglass Thanks for the great demo! And excellent formatting as well. Only thing I did was add ortho() to settings to change the view. This was prompted by a friend looking at this and asking about this... which spawned off to another hour of discussion! Have a great new year!

• Interesting discussion here

I always use sphere with noStroke();

But with stroke being active it would depend on the size of the sphere and maybe also on the value of sphereDetail how much actual fill area you see that reacts to light (as has been said)

I just wanted to mention size and sphereDetail() here as possible factors

Happy new year!

Chrisir

@GLV -- very glad that it was helpful! Good `ortho` tip.
@Chrisir -- great point about `sphereDetail()` also affecting the mesh and how much surface the stroke covers -- at higher detail, there are more lines per unit of sphere surface. That would be a good thing to add to a revised demo -- possibly with sliders for: