processing: how to display text on a 3d object - geometry

I am new to processing, currently I want to display a 3D ball and also add a text label to the 3D ball.
I am using the code as below:
// this function is called when this sketch is first loaded
void setup()
{
// choose size (width, height) of your sketch
size(720, 546, P3D);
// Choose background color for your sketch
background(0);
}
// This function is called repeatedly to draw stuff on screen.
void draw()
{
lights();
pushMatrix();
translate(500, height*0.35, 0);
fill(236,112,20);
noStroke();
sphere(40);
popMatrix();
//fill(255);
fill(255,112,20);
textAlign(CENTER);
textSize(15);
stroke(10);
text("hihihihi", 500, height*0.35);
}
It turned out that the text "hihihihi" is covered by the ball, but when I do it with 2D object it displays good. Is there anything wrong here, can anyone tell me what might be the problem of my code?Thanks!

Notice that your sphere has a radius of 40 which is means a diameter of 80 and you're drawing both the text and sphere at the same horizontal position(500).
Move the text to the right to avoid the sphere occluding it:
void setup()
{
size(720, 546, P3D);
background(0);
}
void draw()
{
lights();
pushMatrix();
translate(500, height*0.35, 0);
fill(236, 112, 20);
noStroke();
sphere(40);
popMatrix();
fill(255, 112, 20);
textAlign(CENTER);
textSize(15);
stroke(10);
text("hihihihi", 585, height*0.35);//make sure the text isn't occluded by anything else(like a sphere)
}
If you want to render text on a sphere I recommend trying PShape and PGraphics.
Here's a minimal example:
PShape sphere;
void setup()
{
size(720, 546, P3D);
background(0);
PGraphics sphereTexture = createGraphics(40,40);
sphereTexture.beginDraw();
sphereTexture.background(236, 112, 20);
sphereTexture.fill(255);
sphereTexture.text("Hi",20,20);
sphereTexture.endDraw();
sphere = createShape(SPHERE, 40);
sphere.disableStyle();
noStroke();
sphere.setTexture(sphereTexture);
}
void draw()
{
lights();
pushMatrix();
translate(500, height*0.35, 0);
fill(236, 112, 20);
noStroke();
shape(sphere,0,0);
popMatrix();
fill(255, 112, 20);
textAlign(CENTER);
textSize(15);
stroke(10);
text("hihihihi", 585, height*0.35);//make sure the text isn't occluded by anything else(like a sphere)
}

Related

Processing- What could be possible errors of svg file not displayed?

I'm trying to display an svg image with Processing, but it would only show a blank white space. I don't think there is any problem with the code as it works perfectly when I change the shape to ellipse. Do I have to modify any code below to display the svg file, or is there any other possible reasons why it wouldn't show? Thanks in advance!
Table table;
PFont f;
PShape leaf;
color [] c = {color(225, 50, 50), color(225, 100, 0), color(225, 225, 0), color(0, 150, 0), color(0), color(125)};
int i=0;
void setup() {
size(1100, 500);
background(255);
table=loadTable("P3_data.csv", "header");
leaf= loadShape("leaf.svg");
leaf.disableStyle();
}
void draw() {
stroke(255);
strokeWeight(0.1);
for (TableRow row : table.rows()) {
int friend= (row.getInt("Friend"));
int travel= (row.getInt("Travel"));
int selfimprovement= (row.getInt("Self-improvement"));
int club= (row.getInt("Club"));
int schoolwork= (row.getInt("Schoolwork"));
int money= (row.getInt("Money"));
int total= 0;
int [] Daily= {friend, travel, selfimprovement, club, schoolwork, money};
for (int k=0; k<6; k++) {
total +=Daily[k];
}
println (total);
for (int j=0; j<6; j++) {
for (int m=0; m< Daily[j]; m++) {
fill(c[j]);
ellipse((i%120)*10+10, (i/120)*40+10, 3*total, 4*total);
//shape(leaf, (i%120)*10+10, (i/120)*40+10, 3*total, 3*total);
total --;
}
}
if (i>1095) {
break;
}
i++;
}
save("sketch.png");
}
See the documentation of disableStyle()
Shapes are loaded with style information that tells them how to draw (the color, stroke weight, etc.) The disableStyle() method of PShape turns off this information. The enableStyle() method turns it back on.
If you want to display the SVG with its style, the you have to remove the disableStyle call:
leaf = loadShape("leaf.svg");
leaf.disableStyle();
If you want to change the stroke and fill color of the shape generated form the *svg" file, then indeed you have to disable the style:
leaf= loadShape("leaf.svg");
leaf.disableStyle();
In this case the shape is drawn with the current fill and stroke color. This means that all the shape is filled with the same fill color and drawn with the same stroke color:
for (int m=0; m< Daily[j]; m++) {
stroke(0, 0, 255); // blue
fill(255, 0, 0); // red
shape(leaf, (i%120)*10+10, (i/120)*40+10, 3*total, 3*total);
total --;
}

Changing the fill of an SVG image in P5.js

I have a basic program that essentially just displays an imported svg. Is there any way I can change the fill of the svg?
var img;
function preload() {
img = loadImage("assets/svgImage.svg")
}
function setup() {
createCanvas(720, 400);
background(200);
fill(204, 101, 192, 127);
stroke(127, 63, 120);
image(img, 50, 50, 50, 50)
}
I tried something along the lines of:
function setup() {
img.drawingContext.fillStyle = '#475731'
image(img, 50, 50, 50, 50)
}
But that doesn't seem to do anything for me.
http://zenozeng.github.io/p5.js-svg/examples/#manipulating
The example on the "Manipulating existing SVG" page says you need to use the querySVG function to obtain the path/shape components, then you can modify their fill attribute.
This is the example given:
var svg, path;
function preload() {
svg = loadSVG('test.svg');
frameRate(20);
}
function setup() {
createCanvas(600, 200, SVG);
image(svg, 0, 0, 200, 200);
path = querySVG('path')[1];
}
function draw() {
// update line width of 2nd line
path.attribute('stroke-width', frameCount % 20);
if (frameCount === 18) {
noLoop();
save(); // save current SVG graphics
}
}
I imagine in your case it would be:
path.attribute('fill', '#475731');

I am trying to rotate a triangle

I have a circle, and then a triangle in the middle of the circle. I want to rotate the triangle around the center of the triangle. Kind of like rotating it 360 degrees. This is my code so far
public void paintComponent(Graphics g)
{
g.setColor(Color.BLACK);
g.drawArc(120, 120, 100, 100, 0, 360);
g.setColor(Color.RED);
int[] x = {160, 170, 180};
int[] y = {150, 190, 150};
g.drawPolygon(x, y, 3);
}
public static void main (String[] args)
{
JFrame frame = new JFrame("SpinningCircle");
frame.setSize(400, 400);
frame.setLocation(0, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new SpinningCircle());
frame.setVisible(true);
}
`
Thanks for help.

MemDC in OnPaint()-function

My OnPaint() function calls several other drawing functions.
void CGraph::OnPaint ()
{
CPaintDC dc(this);
// CMemDC DC(&dc);
dc.SetViewportOrg (0, 400);
dc.SetMapMode(MM_ISOTROPIC);
dc.SetWindowExt(1000, 800);
dc.SetViewportExt(1000, -800);
ProcessData ();
DrawCoordinateSystem (&dc);
DrawGrid (&dc);
DrawGraph (&dc);
}
Example of DrawCoordianteSystem:
void CGraph::DrawCoordinateSystem (CDC* pDC)
{
CPen PenBlack (PS_SOLID, 1, RGB(0, 0, 0));
pDC->SelectObject (PenBlack);
// Rectangle round the system
pDC->Rectangle (0, -400, 1000, 400);
// Horizontal axis
pDC->MoveTo (0, 0);
pDC->LineTo (1000, 0);
pDC->SetTextColor (RGB(0,0,0));
pDC->SetBkColor (RGB(240, 240, 240));
pDC->TextOut (1001, 0, L"0");
// Vertical axis
pDC->MoveTo (0, -400);
pDC->LineTo (0, 400);
}
I now want to avoid flickering with CMemDC. However, i can't get it to work right. Can somebody show me how to implement CMemDC right?
Thanks
You need to load the memory DC with a bitmap to then BitBlt to the screen DC.
Try something like:
CDC dcMem;
CBitmap bitmap;
dcMem.CreateCompatibleDC( pDC );
bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height())
CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);
... DO ALL YOUR DRAWING TO dcMem ...
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(pOldBitmap)
To avoid flickers you should draw everything on CMemDC and BitBlt it to the real DC.
Secondly add windows message handler for WM_ERASEBKGND message and change the code to
BOOL CGraph::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}

Processing SVG Gradient

I'm having an SVG with 2 layers (back, front).
I need to fill the back with a color (the color will be random).
But the front must stay as it is.
How can I fill the back without affecting the front?
PShape elem;
PShape back;
PShape front;
void setup()
{
size(900,600);
background(255);
fill(100);
elem = loadShape("resources/images/elem.svg");
back = elem.getChild("back");
front = elem.getChild("front");
smooth();
noLoop();
}
void draw(){
elem.disableStyle();
fill(0, 51, 102);
noStroke();
shape(back, 50, 50, 250, 250);
shape(front, 50, 50, 250, 250);
}
Thank you for your help.
Hard to test for your exact setup without the svg.
Still, you should be able to isolate drawing styles for parts of your shapes using pushStyle(),popStyle() pairs.
e.g.
PShape elem;
PShape back;
PShape front;
void setup()
{
size(900,600);
background(255);
fill(100);
elem = loadShape("resources/images/elem.svg");
back = elem.getChild("back");
front = elem.getChild("front");
smooth();
noLoop();
}
void draw(){
elem.disableStyle();
pushStyle();
fill(0, 51, 102);
noStroke();
shape(back, 50, 50, 250, 250);
popStyle();
pushStyle();
shape(front, 50, 50, 250, 250);
popStyle();
}
Indenting is just a visual cue, not actually needed.

Resources