Reputation: 984
I'd like to draw a line between a sphere and another sphere. The line should change its color from the color of the first sphere to the next. How do I do that?
Upvotes: 0
Views: 562
Reputation: 51857
xImperiak's solution is correct (+1).
If speed/efficiently becomes an issue the pixels[]
can be accessed directly.
e.g.
loadPixels();
// for...
pixels[(int)newRelPoint.x + (int)newRelPoint.y * height] = colorAtPoint;
Since you mention spheres, you could potentially take advantage of the P3D
renderer to change vertex colours to achieve a gradient effect:
color firstColor = 0xffb957ce;
color secondColor = 0xff5994ce;
void setup(){
size(600, 600, P3D);
sphereDetail(9);
}
void draw(){
background(#3a4e93);
translate(width * 0.5, height * 0.5, 0);
noFill();
float sphere1Y = sin(frameCount * 0.01) * 30;
float sphere2Y = sin((frameCount * 0.01) + PI) * 30;
// draw 1st sphere
drawSphere(-150, sphere1Y, 0, 90, firstColor);
// draw 2nd sphere
drawSphere( 150, sphere2Y, 0, 90, secondColor);
//draw gradient line
drawGradientLine(-150, sphere1Y, 0,
150, sphere2Y, 0,
firstColor, secondColor);
}
void drawGradientLine(float x1, float y1, float z1,
float x2, float y2, float z2,
color colorFrom, color colorTo){
noStroke();
// draw gradient line
beginShape();
// change vertex colours between vertices to achieve gradient look
fill(colorFrom);
vertex(x1, y1, z1);
// slight offset to fake thickness
vertex(x1, y1-3, z1);
fill(colorTo);
vertex(x2, y2, z2);
// slight offset to fake thickness
vertex(x2, y2+3, z2);
endShape(CLOSE);
}
void drawSphere(float x, float y, float z, float radius, color strokeColor){
stroke(strokeColor);
pushMatrix();
translate(x, y, z);
sphere(radius);
popMatrix();
}
Notice a thin rectangle is drawn using 4 points: the two points between spheres and slight vertical offsets for each.
This is more of a workaround. Normally you would need to compute the angle between lines to correctly rotate coordinates, but since this is a stroke this could work well enough.
Additionally it might be possible to use @micycle's PeasyGradients libraries and mask()
the lines you need.
Upvotes: 5
Reputation: 384
You will have to calculate the mathematical function of the line you want to draw. This is easly done just by substracting the vector of one of the points to the other point vector. This will be the direction vector, which will go multiplied by the variable, and then add one of the points. Afterwards you will have to use the set() (to change the color of the pixels) and the lerpColor() function (to do the gradient) provided by processing.
The final code would be something like this given:
PVector point1;
PVector point2;
color color1;
color color2;
void drawGradientLine(PVector point1, PVector point2, color color1, color color2){
PVector direcVector = PVector.sub(point2, point1);
for(float f = 0; f < 1; f += 0.0001){ //0.0001 or the value that you prefer 0<k<1.
PVector newRelPoint = PVector.mult(direcVector, f); //Rel from relative to, in this case, point1
color colorAtPoint = lerpColor(color1, color2, f);
set((int)newRelPoint.x, (int)newRelPoint.y, colorAtPoint);
}
}
Upvotes: 3