Java рисует пятиконечную звезду.

Вы опубликуете его завтра, обещаете?

ok это меня заинтересовало и я немного погуглил

звезду можно сделать из правильной фигуры. так, пятиконечная звезда может быть сделана из пятиугольника, шестиконечная — из шестиугольника и так далее

так что нарисовать правильную фигуру с N сторонами легко (или, по крайней мере, проще).

не уверен насчет тригонометрии. я давно не занимался этим, и этот код мне в голову не приходит.

anyhoo этот код *должен* получить координаты x/y каждой точки правильной формы, которые *должны* также быть координатами вашей звезды

.

теперь просто соедините точки. соедините их одну за другой и получите правильную форму. для 5-точечной звезды соедините их, пропуская одну. если вы меня поняли. так точка 1 соединяется с точкой 3, 2 -> 4, 3 -> 5, 4 -> 1

.

надеюсь, это объясняет. но вы ищете решение для N-гранной звезды. я этого не знаю, но из того, что я могу сказать, количество вершин, которые вы пропускаете при соединении точек, максимально возможное, при условии, что вы не пересекаете линию 180 градусов. ну это не имеет смысла. со звездой выше, проведите воображаемую линию от точки в вершине, через середину звезды и вниз к основанию. точки, с которыми соединяется вершина, это те, которые ближе всего к противоположной стороне.

как же у меня плохо получается объяснять вещи устно, не просто бессвязно.

в любом случае вы можете получить это число с помощью

(// = разделить, отбросив остаток)
почему 179.9? Просто догадка, но я думаю, что 180 вызовет проблемы с углами, которые точно соответствуют 180 (то есть 8 сторон = 45 градусов = 4 пропущенных вершины, если вы используете значение 180, что неправильно, если вы рисуете это на бумаге, как я — серьезно, ребята, ручка и бумага FTMFW.)

Ну, это было весело. Еще раз повторюсь, у меня нет способа протестировать все это, кроме калькулятора и бумаги, так что никаких гарантий, что это работает

Спасибо, что поделились.

Но все должно быть гораздо проще.

<Все, что нужно, — это несколько рисунков линии и координаты для их соединения.

Я подумал, что это звучит забавно; я никогда не пытался программно нарисовать звезду и не занимался свингом больше года. Я приложил свое решение (как исходный текст, так и запускаемый JAR). JAR находится в zip-архиве под /Star/dist/Star.jar.

Исходный код не прокомментирован, но, надеюсь, вы сможете его понять.

  • Star.zip (42,8 КБ)
  • star.jpg (42.6 КБ)

Хорошо, поскольку мне было скучно, я решил выяснить, смогу ли я «портировать» алгоритм Барона на PHP.

<?php
$noPoints = 5 ;
$innerRadius = 100 ;
$outerRadius = 200 ;
$drawCircles = false ;
$drawDots = false ;

$imageSize = ( 2 * $outerRadius ) + 50 ;
$centre = $imageSize / 2 ;

$img = imagecreatetruecolor ( $imageSize , $imageSize );

$white = imagecolorallocate ( $img , 255 , 255 , 255 );
$red = imagecolorallocate ( $img , 255 , 0 , 0 );
$black = imagecolorallocate ( $img , 0 , 0 , 0 );

imagefill ( $img , 0 , 0 , $white );
if ( $drawCircles ) <
imagearc ( $img , $centre , $centre , 2 * $innerRadius , 2 * $innerRadius , 0 , 0 , $red );
imagearc ( $img , $centre , $centre , 2 * $outerRadius , 2 * $outerRadius , 0 , 0 , $red );
>

for ( $ii = 0 ; $ii < $noPoints ; $ii ++) <
$innerX = $innerRadius * cos ( deg2rad (( $ii + 0.5 ) * ( 360 / $noPoints ))) + $centre ;
$innerY = $innerRadius * sin ( deg2rad (( $ii + 0.5 ) * ( 360 / $noPoints ))) + $centre ;

$outerX = $outerRadius * cos ( deg2rad ( $ii * ( 360 / $noPoints ))) + $centre ;
$outerY = $outerRadius * sin ( deg2rad ( $ii * ( 360 / $noPoints ))) + $centre ;

if ( $drawDots ) <
imagefilledarc ( $img , $innerX , $innerY , 5 , 5 , 0 , 0 , 0 , $black , IMG_ARC_PIE );
imagefilledarc ( $img , $outerX , $outerY , 5 , 5 , 0 , 0 , 0 , $black , IMG_ARC_PIE );
>

$starDots [ ‘innerX’ ][] = $innerX ;
$starDots [ ‘innerY’ ][] = $innerY ;
$starDots [ ‘outerX’ ][] = $outerX ;
$starDots [ ‘outerY’ ][] = $outerY ;
>

for ( $zz = 0 ; $zz < $noPoints ; $zz ++) <
$extra = ( $zz == $noPoints — 1 ? — $noPoints + 1 : 1 );

imageline ( $img , $starDots [ ‘innerX’ ][ $zz ], $starDots [ ‘innerY’ ][ $zz ], $starDots [ ‘outerX’ ][ $zz ], $starDots [ ‘outerY’ ][ $zz ], $black );
imageline ( $img , $starDots [ ‘innerX’ ][ $zz ], $starDots [ ‘innerY’ ][ $zz ], $starDots [ ‘outerX’ ][ $zz + $extra ], $starDots [ ‘outerY’ ][ $zz + $extra ], $black );
>

header («Content-type: image/png» );
imagepng ( $img );

Хорошо, вот псевдокод с комментариями, надеюсь, это поможет вам понять.

Перед этим, однако, вам нужно понять следующее: Звезда генерируется с помощью 2 окружностей, точки определяются путем деления 2*pi (полная окружность) на количество точек.

Таким образом, для 5 окружностей необходимо 5 точек.

Так, для 5 точек: 2pi/5 будет «углом разделения» между каждой точкой на внешней окружности.

У нас будет еще одна окружность меньшего размера (в идеале — половина радиуса внешней окружности), и в ней тоже будет 5 точек! Таким образом, угол разделения = 5pi/2 BUT разница в том, что он будет расположен «между» точками внешней окружности. Вот посмотрите на этот рисунок, который иллюстрирует то, что я имею в виду:

Изображение

Ну а теперь псевдокод:

var noPoints = 5 ; // Сколько точек должно быть у звезды?
var innerRadius = 100 ; // Радиус в пикселях внутренней окружности
var outerRadius = 200 ; // Радиус в пикселях внешней окружности
var drawCircles = false ; // Нужно ли рисовать 2 окружности на экране? (Просто для ориентира)
var drawDots = false ; // Хотим ли мы, чтобы «соединительные точки» были нарисованы на экране? (Только для ориентира)

// Вычислите размер изображения, который должен быть в два раза больше внешнего радиуса (так как он самый большой) и еще несколько пикселей, я выбрал +50.
imageSize = ( 2 * outerRadius ) + 50 ;
centre = imageSize / 2 ; // Вычислите центр изображения, довольно просто.

// Создайте пустое изображение.

// Создайте пустое изображение размером imageSize на imageSize пикселей (другими словами, идеально квадратное изображение)
create_new_image ( imageSize , imageSize );

// Залейте это изображение белым фоном
fill_image ( 0 , 0 , white );

// Если drawCircles = true, то нарисуйте 2 полные окружности в начале координат x = центр, y = центр красным цветом
// Нарисуйте одну для innerRadius (диаметр = 2 * radius) и одну для outerRadius
if ( drawCircles ) <
draw_circle ( center , center , 2 * innerRadius , 2 * innerRadius , red );
draw_circle ( center , center , 2 * outerRadius , 2 * outerRadius , red );
>

// Loop for 0 to noPoints (exclusive, so thats 0 to 4 for noPoints = 5, etc)
for (var ii = 0 ; ii < noPoints ; ii ++) <
// Вычисляем x координату того места, где должна быть ii’th точка
// Это просто математический триггер, посмотрите полярные координаты, если вы не знаете, что здесь происходит.
// Центр добавляется, чтобы сдвинуть координату в нужное положение.
// В этом случае мы также умножаем значение ii на 0.5, чтобы точки внутреннего круга
// оказались в середине внешнего круга
innerX = innerRadius * cos ( deg2rad (( ii + 0.5 ) * ( 360 / noPoints ))) + center ;
// То же самое, но теперь мы вычисляем координату y (поэтому используется sin, а не cos)
innerY = innerRadius * sin ( deg2rad (( ii + 0.5 ) * ( 360 / noPoints ))) + центр ;

// То же самое, что и выше, но теперь для внешней окружности
// И на этот раз мы НЕ умножаем на 0.5, так как нам это не нужно, потому что мы сдвинули точки внутренней окружности
// Поэтому их не нужно сдвигать
outerX = outerRadius * cos ( deg2rad ( ii * ( 360 / noPoints ))) + center ;
// Координата Y
outerY = outerRadius * sin ( deg2rad ( ii * ( 360 / noPoints ))) + центр ;

// deg2rad(), кстати, конвертирует из градусов в радианы

// Если drawDots = true, то рисуем вторую точку в точке x=innerX, y=innerY
// И еще одну в точке x=outerX, y=outerY (для внешней окружности)
if ( drawDots ) <
draw_circle_filled_in ( innerX , innerY , 5 , 5 , black ); // 5, 5 — это горизонтальная и вертикальная высота этой заполненной окружности.
draw_circle_filled_in ( outerX , outerY , 5 , 5 , black ); // Так что думайте об этом как о маленьком круге черного цвета радиусом 2.5
>

// Наконец, сохраните вычисленные внутренние и внешние координаты для ii-й точки в двумерном массиве под названием ‘starDots’
// Убедитесь, что вы поместили их в конец массива. (В PHP [] действует как push into array)
starDots [ ‘innerX’ ][] = innerX ;
starDots [ ‘innerY’ ][] = innerY ;
starDots [ ‘outerX’ ][] = outerX ;
starDots [ ‘outerY’ ][] = outerY ;
>

.

// Выполните цикл от 0 до noPoints (эксклюзивный, то есть от 0 до 4 для noPoints = 5 и т.д.)
// На самом деле мы выполняем цикл для количества элементов в массиве starDots. Но поскольку оно всегда будет равно
// noPoints, нет необходимости делать лишние вычисления
for (var zz = 0 ; zz < noPoints ; zz ++) <
// Нам нужно провести 2 линии, одну соединяющую внутреннюю точку zz с внешней точкой zz
// И другую от внутренней точки zz до внешней точки zz+1 (следующей точки)
// Таким образом, это 2 линии на цикл
// Всего 2*noPoints линий, что геометрически правильно
// Но если мы находимся в конце массива, и пытаемся соединиться с outerDot + 1, мы попытаемся
// получить доступ к несуществующему элементу. Вот что делает эта проверка if, если мы находимся на последнем элементе,
// то выдаст нам -(noPoints + 1). Это значение мы должны добавить к outerDot, чтобы получить доступ к 0-му элементу, он же первая точка/точка
// outerDot

if ( zz == noPoints ) < // Если мы находимся на последнем элементе
var extra = 1 ; // Добавляем 1 для доступа к следующей точке
> else <
var extra = — noPoints + 1 ; // Добавляем это значение для доступа к 0-му элементу (он же первая точка)
>

// Рисуем линию от внутренней точки к внешней
draw_line ( starDots [ ‘innerX’ ][ zz ], starDots [ ‘innerY’ ][ zz ], starDots [ ‘outerX’ ][ zz ], starDots [ ‘outerY’ ][ zz ], black );

// Проведите линию от innerDot до (outerDot + extra)
draw_line ( starDots [ ‘innerX’ ][ zz ], starDots [ ‘innerY’ ][ zz ], starDots [ ‘outerX’ ][ zz + extra ], starDots [ ‘outerY’ ][ zz + extra ], black );

/.

//draw_line(fromX, fromY, toX, toY, color)
>

draw_image (); // Рисуем изображение на экране

Так понятнее?

Справедливости ради, это простой способ рисования. Я не вижу ничего проще этого, если только у вас нет волшебной встроенной функции под названием: draw_star();

.

Также, чтобы решить подобные проблемы. Вам нужно взять бумагу и ручку и нарисовать звезду. Затем посмотрите, что характерно для звезд. Попробуйте вывести для них выражения и определить математический смысл. И только после этого приступайте к программированию.

Круг — это звезда с бесконечным количеством точек с двумя «направляющими» окружностями равного радиуса, в реальности это, вероятно, не так. Но вы можете думать об этом так, если это поможет вам понять приведенный выше код.