Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
Здравствуйте, SergeyOsipov, Вы писали:
SO>Здравствуйте, kov_serg, Вы писали:
_>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>Надо написать функцию проверки: можно ли разместить второй внутри первого
SO>Крутить можно?
Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
return min(a,b)<=min(c,d) && max(a,b)<=max(c,d)
угадал?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
у вложенного прямоугольника все из сторон меньше хотя бы одной стороны прямоугольника включающего его. Это легко записать:
Здравствуйте, Qulac, Вы писали:
Q>Здравствуйте, kov_serg, Вы писали:
_>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>Надо написать функцию проверки: можно ли разместить второй внутри первого
Q>у вложенного прямоугольника все из сторон меньше хотя бы одной стороны прямоугольника включающего его. Это легко записать:
Q>(a>c||b>c)&&(a>d||b>d)
А если вложить "по диагонали"? Очень "тонкий" прямоугольник высотой epsilon, но с длиной немного меньшей длины диагонали включающего прямоугольника. Его сторона будет больше самой большой стороны включающего прямоугольника
Здравствуйте, Михaил, Вы писали:
М>Здравствуйте, Qulac, Вы писали:
Q>>Здравствуйте, kov_serg, Вы писали:
_>>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>>Надо написать функцию проверки: можно ли разместить второй внутри первого
Q>>у вложенного прямоугольника все из сторон меньше хотя бы одной стороны прямоугольника включающего его. Это легко записать:
Q>>(a>c||b>c)&&(a>d||b>d)
М>А если вложить "по диагонали"? Очень "тонкий" прямоугольник высотой epsilon, но с длиной немного меньшей длины диагонали включающего прямоугольника. Его сторона будет больше самой большой стороны включающего прямоугольника
+1.
Я рассматривал случай когда стороны параллельны. А тут надо че-то другое сравнивать. Может периметр или окружности описывающие прямоугольники. Наверное окружности.
UP. Диагональ нужно сравнивать, если диагональ меньше, то влезет. Вроде так...
Здравствуйте, Qulac, Вы писали:
Q>Здравствуйте, Михaил, Вы писали:
М>>Здравствуйте, Qulac, Вы писали:
Q>>>Здравствуйте, kov_serg, Вы писали:
_>>>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>>>Надо написать функцию проверки: можно ли разместить второй внутри первого
Q>>>у вложенного прямоугольника все из сторон меньше хотя бы одной стороны прямоугольника включающего его. Это легко записать:
Q>>>(a>c||b>c)&&(a>d||b>d)
М>>А если вложить "по диагонали"? Очень "тонкий" прямоугольник высотой epsilon, но с длиной немного меньшей длины диагонали включающего прямоугольника. Его сторона будет больше самой большой стороны включающего прямоугольника
Q>+1. Q>Я рассматривал случай когда стороны параллельны. А тут надо че-то другое сравнивать. Может периметр или окружности описывающие прямоугольники. Наверное окружности.
Q>UP. Диагональ нужно сравнивать, если диагональ меньше, то влезет. Вроде так...
Тогда a^2 + b^2 > c^2 + d^2
А как это можно доказать?
Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
bool f(double a,double b, double c,doube d);
вот данные для проверки функции
f(2,2, 1,1)=true
f(1,1, 2,2)=false
f(5,5, 5.5,1)=true
Здравствуйте, Михaил, Вы писали:
М>Здравствуйте, kov_serg, Вы писали:
SO>>>Крутить можно?
_>>Нужно
М>Если в лоб и без хитростей
М>с<a && d<b || c<b && d<a
не правильно. вы не достаточно скуали a=5, b=5, c=5.5 d=1 должно быть да
Здравствуйте, ·, Вы писали:
·>Здравствуйте, kov_serg, Вы писали:
_>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>Надо написать функцию проверки: можно ли разместить второй внутри первого ·>return min(a,b)<=min(c,d) && max(a,b)<=max(c,d) ·>угадал?
Здравствуйте, kov_serg, Вы писали:
_>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>Надо написать функцию проверки: можно ли разместить второй внутри первого
_>bool f(double a,double b, double c,doube d);
_>вот данные для проверки функции _>f(2,2, 1,1)=true _>f(1,1, 2,2)=false _>f(5,5, 5.5,1)=true
Ну да, школьная задача по геометрии.
Тут можно найти, например, максимальный D:
Т.е., дано A, B, C, находим отсюда D(max).
Затем, если исходное D<=Dmax, то true.
Перед этим проверить:
С2 <= A2 + B2, если условие не соблюдается, то поменять (A,B) <=> (C,D)
Значение D можно найти из суммы площадей треугольников:
A1*B1 + A2*B2 = A*B — C*D
и их сторон:
С2 = A12 + B12
D2 = A22 + B22
Расписывать и форматировать решение облом, но понятно, что имеем 3 уравнения для 3-х неизвестных (A1, B1, D).
(ну или 5 уравнений для 5 неизвестных до подстановки: A2=A-A1 и B2=B-B1)
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, kov_serg, Вы писали:
_>>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>>Надо написать функцию проверки: можно ли разместить второй внутри первого
_>>bool f(double a,double b, double c,doube d);
_>>вот данные для проверки функции _>>f(2,2, 1,1)=true _>>f(1,1, 2,2)=false _>>f(5,5, 5.5,1)=true
V>Ну да, школьная задача по геометрии.
V>Тут можно найти, например, максимальный D: V>Image: ABCD.png
V>Т.е., дано A, B, C, находим отсюда D(max). V>Затем, если исходное D<=Dmax, то true.
V>Перед этим проверить: V>С2 <= A2 + B2, если условие не соблюдается, то поменять (A,B) <=> (C,D)
V>Значение D можно найти из суммы площадей треугольников: V>A1*B1 + A2*B2 = A*B — C*D V>и их сторон: V>С2 = A12 + B12 V>D2 = A22 + B22
V>Расписывать и форматировать решение облом, но понятно, что имеем 3 уравнения для 3-х неизвестных (A1, B1, D). V>(ну или 5 уравнений для 5 неизвестных до подстановки: A2=A-A1 и B2=B-B1)
В том то и дело, что расписывать всем в облом, а не только тебе
Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
Здравствуйте, Икс, Вы писали:
Икс>Здравствуйте, kov_serg, Вы писали:
_>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>Надо написать функцию проверки: можно ли разместить второй внутри первого
Икс>Уже написана, "IntersectRect" называется
В задании ничего не говорится про то, как ориентированы прямоугольники.
Здравствуйте, vdimas, Вы писали:
V>Ну да, школьная задача по геометрии.
V>Расписывать и форматировать решение облом, но понятно, что имеем 3 уравнения для 3-х неизвестных (A1, B1, D). V>(ну или 5 уравнений для 5 неизвестных до подстановки: A2=A-A1 и B2=B-B1)
Задача из экзаменационных билетов по информатике для студентов.
Вообще-то получается всего два неравенства для одной переменной.
Делаем замену переменных
a1=d1*cos(f1)
b1=d1*sin(f1)
a2=d2*cos(f2)
b2=d2*sin(f2)
#!/usr/bin/lua
function check_rect(a1,b1,a2,b2)
local find_angles=function (d1,a1,d2,a2)
local q1,q2,p2,r
p2=0.5*math.pi
q2=d1/d2*math.sin(a1)
r={ a2, a2+p2 }
if q2<=1 then
u1=math.acos(q2)
if r[2]<u1 then return {} end
if a2<u1 then r[1]=u1 end
end
q1=d1/d2*math.cos(a1)
if q1>1 then return {r} end
v1=math.asin(q1)
if v1>=r[1] then r={ {r[1],v1} } else r={} end
if a2+v1>=p2 then r[#r+1]={ p2-v1,a2+p2 } end
return r
end
local d1,f1,d2,f2,r
d1=math.sqrt(a1*a1+b1*b1); f1=math.atan2(b1,a1)
d2=math.sqrt(a2*a2+b2*b2); f2=math.atan2(b2,a2)
r=find_angles(d1,f1,d2,f2)
-- for k,v in pairs(r) do print(string.format('%d [%.3f, %.3f]',k,v[1],v[2])) end
return #r>0
end
function check_list(list)
for k,v in pairs(list) do
local r=check_rect(v.a1,v.b1,v.a2,v.b2) and 'possible' or 'impossible'
print(string.format("[%.3f * %.3f] <-- [%.3f * %.3f] - %s",v.a1,v.b1,v.a2,v.b2,r))
end
end
check_list
{
{ a1=2,b1=2, a2=1,b2=1 },
{ a1=1,b1=1, a2=2,b2=2 },
{ a1=5,b1=5, a2=5.5,b2=1 },
}
Здравствуйте, kov_serg, Вы писали:
_>Вообще-то получается всего два неравенства для одной переменной.
Не получается "всего два".
Я не вижу в этих неравенствах формулы вычисления угла a.
Собсно, твои неравенства эквивалентны (математически, после подстановок) моим:
С2 <= A2 + B2, если условие не соблюдается, то поменять (A,B) <=> (C,D)
если исходное D<=Dmax, то true
Но это не есть решение задачи, это всё еще формулировка/уточнение условия. ))
Решение — это найти "угол вписывания" одного прямоугольника в другой и проверить данное условие.
_>Вот код решения на скорую руку
Код решения не соответствует приведенным неравенствам.
===========
В моем случае после 2-х подстановок получилось обычное уравнение 4-й степени.
Расписывать его решение и было облом, сорри.
Upd
Собственно, нахождение треугольника(ов) A1 B1 C на моём рисунке и есть нахождение твоего угла(ов) а.
=============
Есть еще способ решения — через подобие всех треугольников, я там проекцию на C специально оставил.
Здравствуйте, vdimas, Вы писали: _>>Вообще-то получается всего два неравенства для одной переменной. V>Не получается "всего два". V>Я не вижу в этих неравенствах формулы вычисления угла a.
Странно, почему я вижу V>Собсно, твои неравенства эквивалентны (математически, после подстановок) моим:
Ясен пень эквивалентны. Но решение в такой системе координат проще. V>Но это не есть решение задачи, это всё еще формулировка/уточнение условия. )) V>Решение — это найти "угол вписывания" одного прямоугольника в другой и проверить данное условие.
Если вам нужен угол то смотрите
одна неизвестная a — угол поворота второго прямоугольника относительно первого
function find_angles(d1,f1,d2,f2)
local p2,r,rs,q1,q2=0.5*math.pi,{},{}
q1=d1/d2*math.cos(f1)
if q1<=1 then r[#r+1]={ f2, math.acos(q1) } end
q2=d1/d2*math.sin(f1)
if q2<=1 then r[#r+1]={ p2-f2, math.acos(q2) } end
local function rgn(r1,r2) if r1<=r2 then rs[#rs+1]={r1,r2} end end
if #r==0 then rs={ {0,p2} }
else
if #r==2 then
if r[1][1]>r[2][2] then r={ r[2],r[1] } end
if r[1][1]+r[1][2]>=r[2][1]-r[2][2] then
r={{ 0.5*(r[1][1]-r[1][2]+r[2][1]+r[2][2]),
0.5*(r[2][1]+r[2][2]-r[1][1]+r[1][2]) }}
end
end
if #r==1 then
rgn(0,r[1][1]-r[1][2])
rgn(r[1][1]+r[1][2],p2)
else
rgn(0,r[1][1]-r[1][2])
rgn(r[1][1]+r[1][2],r[2][1]-r[2][2])
rgn(r[2][1]+r[2][2],p2)
end
end
return rs
end
find_angles возвращает все решения (допустимые диапазоны) для угла a (границы включаются)
_>>Вот код решения на скорую руку V>Код решения не соответствует приведенным неравенствам.
Точно ошибся. Посыпает голову пеплом.
Вот правильный вариант
#!/usr/bin/lua
function rect_fit(a1,b1,a2,b2)
local d1,f1=math.sqrt(a1*a1+b1*b1), math.atan2(a1,b1)
local d2,f2=math.sqrt(a2*a2+b2*b2), math.atan2(a2,b2)
local function can_fit(d1,f1,d2,f2)
local p2,r,rs,q1,q2=0.5*math.pi,{}
q1=d1/d2*math.cos(f1); if q1<=1 then r[1]={ f2, math.acos(q1) } end
q2=d1/d2*math.sin(f1); if q2<=1 then r[#r+1]={ p2-f2, math.acos(q2) } end
rs=(#r==0) or (#r==1 and ( r[1][1]>=r[1][2] or r[1][1]+r[1][2]<=p2 ))
if #r==2 then
if r[1][1]>r[2][2] then r={ r[2],r[1] } end
rs=math.min(r[1][1]-r[1][2],r[2][1]-r[2][2])>=0
or math.max(r[2][1]+r[2][2],r[1][1]+r[1][2])<=p2
or r[1][1]+r[1][2]<=r[2][1]-r[2][2]
end
return rs
end
return can_fit(d1,f1,d2,f2)
end
function check_list(list)
for k,v in pairs(list) do
local r=rect_fit(v.a1,v.b1,v.a2,v.b2) and 'possible' or 'impossible'
print(string.format("[%.3f * %.3f] <-- [%.3f * %.3f] - %s",v.a1,v.b1,v.a2,v.b2,r))
end
end
check_list
{
{ a1=2,b1=2, a2=1,b2=1 },
{ a1=1,b1=1, a2=2,b2=2 },
{ a1=5,b1=5, a2=5.5,b2=1 },
}
Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
Здравствуйте, Hacker_Delphi, Вы писали:
H_D>Здравствуйте, kov_serg, Вы писали:
_>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>Надо написать функцию проверки: можно ли разместить второй внутри первого
H_D>
Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
bool first_enclose_second(double a, double b, double c, double d)
{
if (a < b)
std::swap(a, b);
if (c < d)
std::swap(c, d);
if (c <= a)
return d <= b;
const auto ss = c * c + d * d;
const auto p = std::sqrt(ss - b * b);
const auto q = std::sqrt(ss - a * a);
return a * b - p * q >= c * d * 2;
}
Случай "прямого" лежания, полагаю, не требует пояснений. Принцип решения для "косого" лежания пояснен рисунком. Решение основано на сравненииплошадей прямоугольников, вписанных в одну окружность (имеющих равные диагонали). Большую площадь будет иметь тот прямоугольник, который по форме более близок к квадрату.
Вписываем прямоугольник cd в окружность. Центр этой окружности совмещаем с центром прямоугольника ab. На точках пересечения окружности и прямоугольника ab строим вспомогательный прямоугольник, он изображен на рисунке зеленым цветом. Нетрудно доказать, что прямоугольник cd полностью размещается в прямоугольнике ab тогда и только тогда, когда площадь прямоугольника cd меньше или равна площади зеленого прямоугольника.
Для нахождения площади зеленого прямоугольника используем векторное произведение векторов его диагоналей (с коэффициентом 1/2). S = |(a,q)x(p,b)| / 2 = (a * b — p * q) / 2. Отрицательное значение площади означает, что диагональ прямоугольника cd больше диагонали прямоугольника ab. Этот случай не требует специальной обработки, т.к. используемые формулы покрывают его автоматически.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, kov_serg, Вы писали:
_>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>Надо написать функцию проверки: можно ли разместить второй внутри первого
Обойдёмся без тригонометрии (точнее, спрячем её внутрь квадратных уравнений)
Дано: C, D — константы, и давайте сразу отнормируем их так, что C = 1, C <= D. Соответственно отнормируем A и B, и пусть A <= B.
Сx — переменная, 0 <= Cx <= 1. Прозорливый читатель узнает в этой величине синус угла поворота.
Cy = √(1-Cx²). Это, соответственно, косинус.
Dy = D·Cx
Dx = D·Cy = D·√(1-Cx²)
Получаем три уравнения
0 <= Cx <= 1
Cx + Dx <= A
Cy + Dy <= B
Здравствуйте, Кодт, Вы писали:
_>>Есть два прямоугольника один со сторонами a,b и второй со сторонами c,d _>>Надо написать функцию проверки: можно ли разместить второй внутри первого
К>Обойдёмся без тригонометрии (точнее, спрячем её внутрь квадратных уравнений)
Если сумма площадей четырех треугольников и меньшего прямоугольника меньше или равна площади большего прямоугольника, то вписывается, если сумма площадей треугольников и меньшего прямоугольника больше площади большего прямоугольника, то не вписывается.
ИМХО, решение можно вывести, используя теорему Пифагора (остатки школьной математики в голове навевают, что можно), но лень не дает взять карандаш в руки