Avatar gives me an error when i try to call it - class

Processing cannot locate my class in the main method.
I tried looking for extra or missing brackets, but didn't find any.
The error reads "Cannot find a class or type named "Avatar"", and i'm not sure what the problem is. I am fairly confident that the class is set up correctly
class Avatar {
int x1; //location variables of the main body parts
int y1;
int x2;
int y2;
int x3;
int y3;
Avatar() {
x1 = 300;
y1 = 200;
x2 = 300;
y2 = 350;
x3 = 300;
y3 = 550;
}//end of constructor
void display() {
//main body
fill(255); //white
noStroke(); //no line on the outside
ellipse(x1, y1, 150, 150); //head
ellipse(x2, y2, 200, 200); //middle portion
ellipse(x3, y3, 300, 300); //bottom portion
//additional parts
//sunglasses
rectMode(CENTER); //sets all rectangles to draw from the center
fill(0);
rect(260, 190, 40, 25);
rect(340, 190, 40, 25);
ellipse(260, 200.5, 40, 19.5);
ellipse(340, 200.5, 40, 19.5);
stroke(0);
line(240, 180, 350, 180);
line(200, 155, 250, 180);
line(400, 155, 359, 180);
//Smile
arc(float(300), float(211), float(65), float(75), float(0), PI);
//Leather Jacket
fill(0);
ellipse(x2, y2, 200, 200);
fill(175);
ellipse(300, 300, 15, 15);
ellipse(300, 350, 15, 15);
ellipse(300, 400, 15, 15);
//Arms
strokeWeight(25);
fill(0);
line(100, 550, 205, 300);
line(500, 550, 395, 300);
ellipse(100, 550, 25, 25);
ellipse(500, 550, 25, 25);
//belt
noStroke();
rectMode(CENTER);
fill(35);
rect(x2, y2+90, 200, 60);
}//end of display function
}//end of avatar class
the main function is just:
Avatar p1Avatar;
Avatar p2Avatar;

Related

How to draw an ellipse in GWT?

There is no context2d.ellipse in GWT, so how can I draw an ellipse? The underlying HTML5 canvas supports it, so I thought I would try and access that using a native method using the following (but it does not work)...
ellipse(context.getCanvas(),(double)x,(double)y,50.,80.,0.,0.,Math.PI*2);
...
public final native void ellipse(CanvasElement e, double x, double y, double rx, double ry, double ro, double sa, double ea)
/*-{
e.getContext("2d").ellipse(x, y, rx, ry, ro, sa, ea, false);
}-*/;
ideas / solutions?
If there is no implementation you can draw it using lines, just needs a bit of trigonometry...
function drawEllipse(x, y, rx, ry) {
ctx.beginPath();
for (i = 0; i <= 360; i++) {
a = i * Math.PI / 180
px = rx * Math.sin(a) + x
py = ry * Math.cos(a) + y
ctx.lineTo(px, py);
}
ctx.stroke();
}
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
drawEllipse(100, 100, 90, 30);
drawEllipse(100, 100, 50, 90);
drawEllipse(100, 100, 50, 25);
<canvas id=canvas width=200 height=200></canvas>

Draw a circle smoothly transforming to a line

I faced the problem in my Flutter app that I can't draw this kind of a shape for my Slider
What I have now is:
final paint = Paint()
..color = Colors.black
..style = PaintingStyle.fill;
final rect = Rect.fromCircle(center: center, radius: thumbRadius);
final rrect = RRect.fromRectAndRadius(
Rect.fromPoints(
Offset(rect.left - 5, rect.top),
Offset(rect.right + 5, rect.bottom),
),
Radius.circular(thumbRadius + 2),
);
canvas.drawRRect(rrect, paint);
Also, it would be great to change height of all bar, because next code changes only the size after player
SliderTheme(
data: SliderThemeData(
trackHeight: 2,
thumbShape: CustomSliderPlayer(),
),
child: Slider(...)
From the comments it looks like you are not familiar with quadratic bezier curves, they are very simple, I would recommend you to start on a Javascript canvas, they are easier to test that way and logic is the same, we move to the starting point then we draw the curve, see sample snippet below
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
function dobleQuad(x, y, w, h) {
ctx.beginPath();
ctx.moveTo(x - w, y);
ctx.quadraticCurveTo(x, y - h, x + w, y);
ctx.moveTo(x - w, y);
ctx.quadraticCurveTo(x, y + h, x + w, y);
ctx.fill();
}
function drawSlider(x, y) {
ctx.moveTo(0, y - 2);
ctx.fillRect(0, y - 2, canvas.width, 4);
dobleQuad(x, y, 20, 22)
}
drawSlider(50, 50)
canvas.addEventListener('mousemove', function(evt) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
var rect = canvas.getBoundingClientRect();
drawSlider( evt.clientX - rect.left, 50 )
})
<canvas id="canvas"></canvas>
Just keep in mind that in JS it's quadraticCurveTo but in flutter quadraticBezierTo
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/quadraticCurveTo
void ctx.quadraticCurveTo(cpx, cpy, x, y);
cpx, cpy
The coordinates of the control point.
x, y
The coordinates of the end point.
https://api.flutter.dev/flutter/dart-ui/Path/quadraticBezierTo.html
void quadraticBezierTo(
double x1, double y1,
double x2, double y2
)
Adds a quadratic bezier segment that curves from the current point
to the given point (x2,y2), using the control point (x1,y1).

Matlab interp2() gives 'monotonically increasing' error

I have many lines that represent a "z" value and want to interpolate at a specific value between them, at a specific x-axis location, to get the y-value. I'm trying interp2() but it throws a 'monotonically increasing' error.
The dataset below is a subset. I broke it out into xyz-1 and xyz-2 just for easy plotting in this question (i.e., making a repeatable example). How can I fix my interp2() or the inputs?
x1 = [0.02, 0.048, 0.108, 0.196, 0.279, 0.401];
y1 = [0.583, 0.43, 0.32, 0.279, 0.262, 0.259];
z1 = [50, 50, 50, 50, 50, 50];
x2 = [0.02, 0.048, 0.108, 0.196, 0.279, 0.401];
y2 = [0.747, 0.591, 0.435, 0.357, 0.326, 0.305];
z2 = [35, 35, 35, 35, 35, 35];
x_all = [x1, x2];
y_all = [y1, y2];
z_all = [z1, z2];
plot(x1, y1, 'blue', 'DisplayName', 'z1')
hold on
plot(x2, y2, 'magenta', 'DisplayName', 'z2')
xlabel('x')
ylabel('y')
legend
want_x = 0.2;
want_z = 40;
need_y = interp2(x_all, y_all, z_all, want_x, want_z, 'linear')
Error:
Error using griddedInterpolant
The grid vectors must be strictly monotonically increasing.
Error in interp2>makegriddedinterp (line 228)
F = griddedInterpolant(varargin{:});
Error in interp2 (line 128)
F = makegriddedinterp({X, Y}, V, method,extrap);
The function griddata is your friend for these tasks, It uses scatteredInterpolant under the hood, but in my opinion is more user friendly.
Keeping the same example code you gave, replacing the last line with:
>> need_y = griddata(x_all,z_all,y_all,want_x, want_z)
need_y =
0.329506024096386
The function can take vector inputs for want_x and want_z and return a vector output of need_y if you need to query more than one point.
You can also specify the interpolation method (linear, cubic, etc ...).
And just to make sure it worked as desired:
>> F = scatteredInterpolant(x_all.', z_all.', y_all.', 'linear'); %NOT y_all, z_all
need_y = F(want_x, want_z)
need_y =
0.329506024096386 % same result, yay!
For more details about using griddata, you can have a look at my answer to this question extremely similar to yours (just worded a bit differently): Interpolation between two curves (matlab)
You can interpolate the value with:
x1 = [0.02, 0.04, 0.09, 0.184, 0.309, 0.667];
y1 = [0.586, 0.447, 0.34, 0.279, 0.256, 0.256];
z1 = [50, 50, 50, 50, 50, 50];
x2 = [0.022, 0.044, 0.076, 0.125, 0.184, 0.293, 0.509, 0.667];
y2 = [0.747, 0.6, 0.49, 0.41, 0.363, 0.326, 0.303, 0.3];
z2 = [35, 35, 35, 35, 35, 35, 35, 35];
want_x = 0.2;
want_z = 40;
y1_ = interp1(x1, y1, want_x);
y2_ = interp1(x2, y2, want_x);
want_y = interp1([50 35], [y1_ y2_], want_z);
This question was answered here:
https://www.mathworks.com/matlabcentral/answers/637955-interp2-monotonically-increasing-error
quoting from that answer, in case the link breaks in the future:
interp2() is only for two-dimensional interpretation over a grid, not for interpolation of vectors. You need something like
F = scatteredInterpolatn(x_all, z_all, y_all, 'linear'); %NOT y_all, z_all
need_y = F(want_x, want_z);

MATLAB Error: "Vectors must be the same length"

I'm getting an error that says "Vectors must be the same length" but I'm not sure why. I'm basically trying to graph a piecewise function with respect to time. I was running into some other issues with the "piecewise" operator earlier, so I decided to use an if statement instead.
figure(1);
t = linspace(0, 30, 200);
v_wind1 = linspace(0, 20, 100);
v_wind2 = linspace(20, 0, 100);
if (0 <= t < 15)
v_wind = v_wind1;
elseif (15 <= t <30)
v_wind = v_wind2;
end
plot(t, v_wind);
Just concatenate v_wind1 and v_wind2.
figure(1);
t = linspace(0, 30, 200);
v_wind1 = linspace(0, 20, 100);
v_wind2 = linspace(20, 0, 100);
v_wind = [v_wind1 v_wind2];
plot(t, v_wind);
This should do the trick!? You want that result, don't you?
Simply use: indexing
t = linspace(0, 30, 200);
v_wind1 = linspace(0, 20, 200);
v_wind2 = linspace(20, 0, 200);
v_wind = zeros(size(t)) ;
idx = t >= 0 & t<15 ;
v_wind(idx) = v_wind1(idx) ;
idx = t >=15 & t < 30 ;
v_wind(idx) = v_wind2(idx) ;
plot(t,v_wind)

I want to use pixel coordinates in my shader

From https://webgl2fundamentals.org/webgl/lessons/webgl-image-processing.html
WebGL2 adds the ability to read a texture using pixel coordinates as well. Which way is best is up to you. I feel like it's more common to use texture coordinates than pixel coordinates.
Nowhere is this mentioned other then passing uniform with texture dimensions in pixels and calculate from there, is there a way to access these pixel coords without calculation as it is supposed here?
You can read individual pixels/texels from a texture in WebGL2 with texelFetch
vec4 color = texelFetch(someUniformSampler, ivec2(pixelX, pixelY), intMipLevel);
For example, compute the average color of a texture by reading each pixel
const vs = `#version 300 es
void main() {
gl_Position = vec4(0, 0, 0, 1);
gl_PointSize = 1.0;
}
`;
const fs = `#version 300 es
precision highp float;
uniform sampler2D tex;
out vec4 outColor;
void main() {
int level = 0;
ivec2 size = textureSize(tex, level);
vec4 color = vec4(0);
for (int y = 0; y < size.y; ++y) {
for (int x = 0; x < size.x; ++x) {
color += texelFetch(tex, ivec2(x, y), level);
}
}
outColor = color / float(size.x * size.y);
}
`;
function main() {
const gl = document.createElement('canvas').getContext('webgl2');
if (!gl) {
return alert('need webgl2');
}
const prg = twgl.createProgram(gl, [vs, fs]);
gl.canvas.width = 1;
gl.canvas.height = 1;
gl.viewport(0, 0, 1, 1);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// so we don't need mips
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
// so we can pass a non multiple of 4 bytes
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
const values = new Uint8Array([10, 255, 13, 70, 56, 45, 89]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, values.length, 1, 0, gl.RED, gl.UNSIGNED_BYTE, values);
gl.useProgram(prg);
gl.drawArrays(gl.POINTS, 0, 1);
const gpuAverage = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, gpuAverage);
const jsAverage = values.reduce((s, v) => s + v) / values.length;
console.log('gpuAverage:', gpuAverage[0]);
console.log('jsAverage:', jsAverage);
}
main();
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
notes: since the canvas is RGBA8 can only get integer result. Could change to some float format but that would complicate the example which is not about rendering it's about texelFetch.
Of course just by changing the data from R8 to RGBA8 we can do 4 arrays as once if we interleave the values
const vs = `#version 300 es
void main() {
gl_Position = vec4(0, 0, 0, 1);
gl_PointSize = 1.0;
}
`;
const fs = `#version 300 es
precision highp float;
uniform sampler2D tex;
out vec4 outColor;
void main() {
int level = 0;
ivec2 size = textureSize(tex, level);
vec4 color = vec4(0);
for (int y = 0; y < size.y; ++y) {
for (int x = 0; x < size.x; ++x) {
color += texelFetch(tex, ivec2(x, y), level);
}
}
outColor = color / float(size.x * size.y);
}
`;
function main() {
const gl = document.createElement('canvas').getContext('webgl2');
if (!gl) {
return alert('need webgl2');
}
const prg = twgl.createProgram(gl, [vs, fs]);
gl.canvas.width = 1;
gl.canvas.height = 1;
gl.viewport(0, 0, 1, 1);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// so we don't need mips
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
// so we can pass a non multiple of 4 bytes
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
const values = new Uint8Array([
10, 100, 200, 1,
12, 150, 231, 9,
50, 129, 290, 3,
45, 141, 300, 2,
12, 123, 212, 4,
]);
const width = 1;
const height = values.length / 4;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, values);
gl.useProgram(prg);
gl.drawArrays(gl.POINTS, 0, 1);
const gpuAverages = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, gpuAverages);
let jsAverages = [0, 0, 0, 0];
for (let i = 0; i < height; ++i) {
for (let j = 0; j < 4; ++j) {
jsAverages[j] += values[i * 4 + j];
}
}
jsAverages = jsAverages.map(v => v / height);
console.log('gpuAverage:', gpuAverages.join(', '));
console.log('jsAverage:', jsAverages.join(', '));
}
main();
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
To do more requires figuring out some way to arrange the data and use an input to the fragment shader to figure out where the data is. For example we again interleave the data, 5 arrays so the data goes 0,1,2,3,4,0,1,2,3,4,0,1,2,3,4.
Let's go back to R8 and do 5 separate arrays. We need to draw 5 pixels. We can tell which pixel is being drawn by looking at gl_FragCoord. We can use that to offset which pixels we look at and pass in how many to skip.
const vs = `#version 300 es
void main() {
gl_Position = vec4(0, 0, 0, 1);
gl_PointSize = 100.0;
}
`;
const fs = `#version 300 es
precision highp float;
uniform sampler2D tex;
uniform int numArrays;
out vec4 outColor;
void main() {
int level = 0;
int start = int(gl_FragCoord.x);
ivec2 size = textureSize(tex, level);
vec4 color = vec4(0);
for (int y = 0; y < size.y; ++y) {
for (int x = start; x < size.x; x += numArrays) {
color += texelFetch(tex, ivec2(x, y), level);
}
}
outColor = color / float(size.x / numArrays * size.y);
}
`;
function main() {
const gl = document.createElement('canvas').getContext('webgl2');
if (!gl) {
return alert('need webgl2');
}
const prg = twgl.createProgram(gl, [vs, fs]);
const numArraysLoc = gl.getUniformLocation(prg, "numArrays");
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// so we don't need mips
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
// so we can pass a non multiple of 4 bytes
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
const numArrays = 5;
const values = new Uint8Array([
10, 100, 200, 1, 70,
12, 150, 231, 9, 71,
50, 129, 290, 3, 90,
45, 141, 300, 2, 80,
12, 123, 212, 4, 75,
]);
const width = values.length;
const height = 1;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8, width, height, 0, gl.RED, gl.UNSIGNED_BYTE, values);
gl.canvas.width = numArrays;
gl.canvas.height = 1;
gl.viewport(0, 0, numArrays, 1);
gl.useProgram(prg);
gl.uniform1i(numArraysLoc, numArrays);
gl.drawArrays(gl.POINTS, 0, 1);
const gpuData = new Uint8Array(4 * numArrays);
gl.readPixels(0, 0, numArrays, 1, gl.RGBA, gl.UNSIGNED_BYTE, gpuData);
const gpuAverages = [];
for (let i = 0; i < numArrays; ++i) {
gpuAverages.push(gpuData[i * 4]); // because we're only using the RED channel
}
const jsAverages = (new Array(numArrays)).fill(0);
const numValues = (width / numArrays) * height;
for (let i = 0; i < width / numArrays; ++i) {
for (let j = 0; j < numArrays; ++j) {
jsAverages[j] += values[i * numArrays + j] / numValues;
}
}
console.log('gpuAverage:', gpuAverages.join(', '));
console.log('jsAverage:', jsAverages.join(', '));
}
main();
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>