Задача.
Реализовать оконное приложение, имеющее следующий функционал:
При нажатии на левую кнопку мыши и до отпускания отмечается описанный прямоугольник, в который вписывается искомый эллипс.
Проблема в том, что
на данном рисунке эллипс слегка вылазит за прямоугольник, не знаете как это исправить?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace labar2
{
public partial class Form1 : Form
{
int x0, x1, y0, y1, a, b;
//private Bitmap pixelBitmap;
private List<Point> points = new List<Point>();
public Form1()
{
InitializeComponent();
}
Bitmap pixelBitmap = new Bitmap(800, 600);
public void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
x0 = e.X;
y0 = e.Y;
}
public void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Bitmap pixelBitmap1 = new Bitmap(800, 600);//Создаёт пустой
pixelBitmap = pixelBitmap1; //Присваивает основному свойства пустого
pictureBox1.Image = pixelBitmap;
pictureBox1.Image = pixelBitmap;
x1 = e.X;
y1 = e.Y;
//labelx1.Text = System.Convert.ToString(x1);
//labely1.Text = System.Convert.ToString(y1);
DrawRectangle(x0,y0,x1,y1);
a = Math.Abs(x0 - x1) / 2;
b = Math.Abs(y0 - y1) / 2;
draw_ellipse(Math.Abs(x0 - x1), Math.Abs(y0 - y1), a, b);
}
//int F(int x, int y)
//{
// int a = (x1 - x0) / 2;
// int b = (y1 - y0) / 2;
// return ();
//}
void pixel4(int x, int y, int _x, int _y) // Рисование пикселя для первого квадранта, и, симметрично, для остальных
{
pixelBitmap.SetPixel(_x+x0+a, _y+y0+b, Color.Red);
pixelBitmap.SetPixel(_x + x0 + a,- _y + y0 + b, Color.Red);
pixelBitmap.SetPixel(- _x + x0 + a,- _y+ y0 + b, Color.Red);
pixelBitmap.SetPixel(-_x + x0 + a, _y + y0 + b, Color.Red);
pictureBox1.Image = pixelBitmap;
}
void draw_ellipse(int x, int y, int a, int b)
{
{
int _x = 0; // Компонента x
int _y = b; // Компонента y
int a_sqr = a * a;// a^2, a - большая полуось
int b_sqr = b * b; // b^2, b - малая полуось
int delta = 4 * b_sqr * ((_x + 1) * (_x + 1)) + a_sqr * ((2 * _y - 1) * (2 * _y - 1)) - 4 * a_sqr * b_sqr; // Функция координат точки (x+1, y-1/2)
while (a_sqr * (2 * _y - 1) > 2 * b_sqr * (_x + 1)) // Первая часть дуги
{
pixel4(x, y, _x, _y);
if (delta < 0) // Переход по горизонтали
{
_x++;
delta += 4 * b_sqr * (2 * _x + 3);
}
else // Переход по диагонали
{
_x++;
delta = delta - 8 * a_sqr * (_y - 1) + 4 * b_sqr * (2 * _x + 3);
_y--;
}
}
delta = b_sqr * ((2 * _x + 1) * (2 * _x + 1)) + 4 * a_sqr * ((_y + 1) * (_y + 1)) - 4 * a_sqr * b_sqr; // Функция координат точки (x+1/2, y-1)
while (_y + 1 != 0) // Вторая часть дуги, если не выполняется условие первого цикла, значит выполняется a^2(2y - 1) <= 2b^2(x + 1)
{
pixel4(x, y, _x, _y);
if (delta < 0) // Переход по вертикали
{
_y--;
delta += 4 * a_sqr * (2 * _y + 3);
}
else // Переход по диагонали
{
_y--;
delta = delta - 8 * b_sqr * (_x + 1) + 4 * a_sqr * (2 * _y + 3);
_x++;
}
}
}
}
private void DrawRectangle(int xa, int ya, int xb, int yb)
{
x1 = Math.Max(xa, xb);
x0 = Math.Min(xa, xb);
y1 = Math.Max(ya, yb);
y0 = Math.Min(ya, yb);
for (int x=x0; x<=x1; x++)
{
//textBox1.Text = "Bresenheim";
pixelBitmap.SetPixel(x, y0, Color.Black);
pixelBitmap.SetPixel(x, y1, Color.Black);
}
for (int y = y0; y <= y1;y++)
{
pixelBitmap.SetPixel(x0, y, Color.Black);
pixelBitmap.SetPixel(x1, y, Color.Black);
}
pictureBox1.Image = pixelBitmap;
}
void crug()
{
int R = 50;
int x = x0;
int y = R+y0;
int d = 1 - R;
int delta1 = 3;
int delta2 = -2 * R + 5;
while(x<y)
{
if(d<0)
{
d+=delta1;
delta1+=2;
delta2+=2;
x++;
}
else
{
d+=delta2;
delta2+=4;
delta1+=2;
x++;
y--;
}
pixelBitmap.SetPixel(x, y, Color.Black);
pixelBitmap.SetPixel(y, x, Color.Black);
pixelBitmap.SetPixel(2*x0-x, y, Color.Black);
}
}
}
}