How to draw a line on really low resolution - geometry

I am currently working on a project on arduino which involves drawing a line on a 8x8 rgb led display, given 2 random coordinates, how do I determine which pixels between them should be painted?
Any help is apprecieated

Here is a simple implementation of the line drawing algorithm mentioned above.
Note that this example will only work if x1 is less than x2.
void drawLine(int x1, int y1, int x2, int y2) {
int dx = x2 - x1;
int dy = y2 - y1;
for (int x = x1; x < x2; x++){
int y = y1 + dy * (x - x1) / dx;
plot(x, y);
}
}
void plot(int x, int y) {
// Draw each pixel
}

Related

Undefined reference error in arduino ide while compiling for teensy 4.0 board

I HAVE TONS OF UNDEFIND REFERENCE ERORS IN MY CODE but heres one example
the out put:
C:\Users\Hp\AppData\Local\Temp\arduino_build_183093\sketch\arduinomegachess2_ino.ino.cpp.o: In function `show_steps(int)':
C:\Users\Hp\Downloads\arduinomegachess2_ino/arduinomegachess2_ino.ino:217: undefined reference to `Adafruit_GFX::fillRoundRect(short, short, short, short, short, unsigned short)'
the definition in .h file
void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
int16_t radius, uint16_t color);
the declartion in another .h file
void fillRoundRect(int x1, int y1, int x2, int y2) {
int w = x2 - x1 + 1, h = y2 - y1 + 1;
if (w < 0) { x1 = x2; w = -w; }
if (h < 0) { y1 = y2; h = -h; }
MCUFRIEND_kbv::fillRoundRect(x1, y1, w, h, _radius, _fcolor);
}

How to simplify this Blockly program drawing a snowflake?

The question says that:
The program shown below on the left draws a snowflake. It uses 33 code blocks.
Can you re-write it so that it uses at least one function and less than 30 blocks.
How can I draw this using Blockly?
After some research I don't think recursive function is the solution in this case but in python I would try something like this
def drawLeaf(direction):
// Draw your leaf in this direction using your blocks code
for direction in [0, 72, 144, 216, 288]:
drawLeaf(direction)
First, please have a look at Finding coordinates of Koch Curve
And here's a Java code snippet (for Android) to draw koch snowflake.It's a simple recursive function
public void drawfractal1(Canvas canvas , float x1 , float y1 , float x2 , float y2, int level){
Paint paint = new Paint();
int r = ThreadLocalRandom.current().nextInt(0, 256);
int g = ThreadLocalRandom.current().nextInt(0, 256);
int b = ThreadLocalRandom.current().nextInt(0, 256);
paint.setColor(Color.rgb(r,g,b));
paint.setStrokeWidth(7);
if(level==0) {
canvas.drawLine(x1,y1,x2,y2,paint);
}
else{
float ux = x2-x1;
float uy = y2-y1;
float vx = y1-y2;
float vy = x2-x1;
float xa = x1 + ux/3;
float ya = y1 + uy/3;
float xb = x1 + ux/2 + (float) sqrt(3)*vx/6;
float yb = y1 +uy/2 + (float)sqrt(3)*vy/6;
float xc = x1 + 2*ux/3;
float yc = y1 + 2*uy/3;
drawfractal1(canvas , x1,y1,xa,ya,level-1);
drawfractal1(canvas , xa,ya,xb,yb,level-1);
drawfractal1(canvas , xb,yb,xc,yc,level-1);
drawfractal1(canvas , xc,yc,x2,y2,level-1);
}
}

Is there a better way to generate points on a circle than trying out points in the equation x^2 + y^2 = r^2?

I have seen many apps which draw circles e.g pygame for python, p5.js for javascript. But I cannot find a method to find out points on a circle efficiently. My current solution to the problem involves trying out all the numbers in the square in which the circle can be inscribed.
This can't be the most efficient method to do it. What is the method used at the industry level? Does it involve optimization or is it a whole new method?
A Midpoint Circle Algorithm could be used.
And an implementation e.g. in C from rosettacode.org:
#define plot(x, y) put_pixel_clip(img, x, y, r, g, b)
void raster_circle(
image img,
unsigned int x0,
unsigned int y0,
unsigned int radius,
color_component r,
color_component g,
color_component b )
{
int f = 1 - radius;
int ddF_x = 0;
int ddF_y = -2 * radius;
int x = 0;
int y = radius;
plot(x0, y0 + radius);
plot(x0, y0 - radius);
plot(x0 + radius, y0);
plot(x0 - radius, y0);
while(x < y)
{
if(f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x + 1;
plot(x0 + x, y0 + y);
plot(x0 - x, y0 + y);
plot(x0 + x, y0 - y);
plot(x0 - x, y0 - y);
plot(x0 + y, y0 + x);
plot(x0 - y, y0 + x);
plot(x0 + y, y0 - x);
plot(x0 - y, y0 - x);
}
}

Circle Rasterization Algorithm - center between pixels

I have a problem where I have to select all squares (think pixels) that are partially within a circle (even if the circle only cuts through a small corner of the square, but not if it goes through one of the corner vertices). The radius is an integer multiple of the pixel size.
The problem is that the center of the circle is between pixels, i.e. on the corner vertices of four pixels.
I want to visit each pixel only once.
For example, I would like to select all white pixels in the following images:
R = 8 px
R = 10 px
For a circle with the center in the center of a pixel, this wouldn't be a problem, and I could use the usual form of the Bresenham algorithm:
public void checkCircle(int x0, int y0, int radius) {
int x = radius;
int y = 0;
int err = -x;
while (x > 0) {
while (err <= 0) {
y++;
err += 2 * y + 1;
}
checkVLine(x0 + x, y0 - y, y0 + y);
checkVLine(x0 - x, y0 - y, y0 + y);
x--;
err -= 2 * x + 1;
}
checkVLine(x0, y0 - radius, y0 + radius);
}
public void checkVLine(int x, int y0, int y1) {
assert(y0 <= y1);
for (int y = y0; y <= y1; y++)
checkPixel(x, y);
}
Sadly, I don't see how to adapt it to support inter-pixel circles.
For the first quadrant - cell should be marked if its left bottom corner lies inside circle, so you can rasterize with simple loops
for dy = 0 to R-1
dx = 0
sq = R * R - dy * dy
while dx * dx < sq
mark (dx, dy)
mark (dx, -dy-1)
mark (-dx-1, dy)
mark (-dx-1, -dy-1)
To fill whole horizontal lines, you can calculate max value for dx
for dy = 0 to R-1
mdx = Floor(Sqrt(R * R - dy * dy))
fill line (-mdx-1,dy)-(mdx,dy)
fill line (-mdx-1,-dy-1)-(mdx,-dy-1)

Line Segment Circle Intersection

I am trying to determine the point at which a line segment intersect a circle. For example, given any point between P0 and P3 (And also assuming that you know the radius), what is the easiest method to determine P3?
Generally,
find the angle between P0 and P1
draw a line at that angle from P0 at a distance r, which will give you P3
In pseudocode,
theta = atan2(P1.y-P0.y, P1.x-P0.x)
P3.x = P0.x + r * cos(theta)
P3.y = P0.y + r * sin(theta)
From the center of the circle and the radius you can write the equation describing the circle.
From the two points P0 and P1 you can write the equation describing the line.
So you have 2 equations in 2 unknowns, which you can solved through substitution.
Let (x0,y0) = coordinates of the point P0
And (x1,y1) = coordinates of the point P1
And r = the radius of the circle.
The equation for the circle is:
(x-x0)^2 + (y-y0)^2 = r^2
The equation for the line is:
(y-y0) = M(x-x0) // where M = (y1-y0)/(x1-x0)
Plugging the 2nd equation into the first gives:
(x-x0)^2*(1 + M^2) = r^2
x - x0 = r/sqrt(1+M^2)
Similarly you can find that
y - y0 = r/sqrt(1+1/M^2)
The point (x,y) is the intersection point between the line and the circle, (x,y) is your answer.
P3 = (x0 + r/sqrt(1+M^2), y0 + r/sqrt(1+1/M^2))
Go for this code..its save the time
private boolean circleLineIntersect(float x1, float y1, float x2, float y2, float cx, float cy, float cr ) {
float dx = x2 - x1;
float dy = y2 - y1;
float a = dx * dx + dy * dy;
float b = 2 * (dx * (x1 - cx) + dy * (y1 - cy));
float c = cx * cx + cy * cy;
c += x1 * x1 + y1 * y1;
c -= 2 * (cx * x1 + cy * y1);
c -= cr * cr;
float bb4ac = b * b - 4 * a * c;
// return false No collision
// return true Collision
return bb4ac >= 0;
}
You have a system of equations. The circle is defined by: x^2 + y^2 = r^2. The line is defined by y = y0 + [(y1 - y0) / (x1 - x0)]·(x - x0). Substitute the second into the first, you get x^2 + (y0 + [(y1 - y0) / (x1 - x0)]·(x - x0))^2 = r^2. Solve this and you'll get 0-2 values for x. Plug them back into either equation to get your values for y.
MATLAB CODE
function [ flag] = circleLineSegmentIntersection2(Ax, Ay, Bx, By, Cx, Cy, R)
% A and B are two end points of a line segment and C is the center of
the circle, % R is the radius of the circle. THis function compute
the closest point fron C to the segment % If the distance to the
closest point > R return 0 else 1
Dx = Bx-Ax;
Dy = By-Ay;
LAB = (Dx^2 + Dy^2);
t = ((Cx - Ax) * Dx + (Cy - Ay) * Dy) / LAB;
if t > 1
t=1;
elseif t<0
t=0;
end;
nearestX = Ax + t * Dx;
nearestY = Ay + t * Dy;
dist = sqrt( (nearestX-Cx)^2 + (nearestY-Cy)^2 );
if (dist > R )
flag=0;
else
flag=1;
end
end

Resources