Как потянуть 3D сферу?

Трудно настроить интервал между символами, когда вы используете TextView. Но если вы можете справиться с рисунком самостоятельно, должен быть какой-то способ сделать это.

Мой ответ на этот вопрос: используйте ваш пользовательский диапазон .

Мой код:

public class LetterSpacingSpan extends ReplacementSpan {
    private int letterSpacing = 0;

    public LetterSpacingSpan spacing(int space) {
        letterSpacing = space;

        return this;
    }


    @Override
    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
        return (int) paint.measureText(text, start, end) + (text.length() - 1) * letterSpacing;
    }


    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
        int length = text.length();
        float currentX = x;

        for (int i = 1; i < length; i++) {          
            canvas.drawText(text, i, i + 1, currentX, y, paint);
            currentX += paint.measureText(text, i, i + 1) + letterSpacing;
         }
    }
}

Объясните:

Создание собственного Span может помочь вам достичь многих потрясающих эффектов, таких как создание размытия TextView, изменение фона или переднего плана для вашего TextView, даже создание анимации. Из этого поста я многому научился Span - мощная концепция .

Поскольку вы добавляете интервалы для каждого символа, поэтому мы должны использовать базовый диапазон уровня персонажа, в данном случае ReplacementSpan - это Лучший выбор. Я добавляю метод spacing, поэтому при его использовании вы можете просто передать нужное пространство для каждого символа в качестве параметра.

При создании пользовательского диапазона вам нужно переопределить как минимум два метода, getSize и draw. Метод getSize должен возвращать окончательную ширину после того, как мы добавили интервал для всей последовательности символов, а внутри блока метода draw вы можете управлять Canvas, чтобы сделать желаемую прорисовку.

Итак, как мы используем этот LetterSpacingSpan? Это просто:

Использование:

TextView textView;
Spannable content = new SpannableString("This is the content");
textView.setSpan(new LetterSpacingSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(content);

И все.

19
задан Peter O. 22 November 2012 в 05:34
поделиться

3 ответа

Well, an image of a sphere will always have a circular shape on your screen, so the only thing that matters is the shading. This will be determined by where you place your light source.

As for algorithms, ray tracing is the simplest, but also the slowest by far — so you probably wouldn't want to use it to do anything very complicated in a (especially given the lack of graphics acceleration available in that environment), but it might be fast enough if you just wanted to do a single sphere.

0
ответ дан 30 November 2019 в 04:52
поделиться

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

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

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

Как только вы поймете, как это сделать, или создадите новый примитив, такой как треугольник, используя метод Path, и создадите круг, тогда вы будете готовы переместить его в 3D.

3D - это просто уловка, поскольку вы возьмете свою модель, вероятно, созданную с помощью уравнения, а затем сгладите ее, определяя, какие части будут видны, и затем отобразите ее.

Но, вы захотите изменить цвет треугольников в зависимости от того, как далеко они находятся от источника света, а также в зависимости от угла этой части к источнику света.

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

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

Вот пример этого, а ниже я скопировал часть 3D-сферы, но просмотрите всю статью .

function Sphere3D(radius) {
 this.point = new Array();
 this.color = "rgb(100,0,255)"
 this.radius = (typeof(radius) == "undefined") ? 20.0 : radius;
 this.radius = (typeof(radius) != "number") ? 20.0 : radius;
 this.numberOfVertexes = 0;

 // Loop from 0 to 360 degrees with a pitch of 10 degrees ... 
  for(alpha = 0; alpha <= 6.28; alpha += 0.17) {
   p = this.point[this.numberOfVertexes] = new Point3D();

   p.x = Math.cos(alpha) * this.radius;
   p.y = 0;
   p.z = Math.sin(alpha) * this.radius;

   this.numberOfVertexes++;
 }

 // Loop from 0 to 90 degrees with a pitch of 10 degrees ... 
 // (direction = 1)

 // Loop from 0 to 90 degrees with a pitch of 10 degrees ...
 // (direction = -1)

 for(var direction = 1; direction >= -1; direction -= 2) {
   for(var beta = 0.17; beta < 1.445; beta += 0.17) {

     var radius = Math.cos(beta) * this.radius;
     var fixedY = Math.sin(beta) * this.radius * direction;

     for(var alpha = 0; alpha < 6.28; alpha += 0.17) {
       p = this.point[this.numberOfVertexes] = new Point3D();

       p.x = Math.cos(alpha) * radius;
       p.y = fixedY;
       p.z = Math.sin(alpha) * radius;

       this.numberOfVertexes++;
     }
   }
 }
}
9
ответ дан 30 November 2019 в 04:52
поделиться

Обновить : Этот код довольно старый и ограниченный. Сейчас есть библиотеки для создания трехмерных сфер: http://techslides.com/d3-globe-with-canvas-webgl-and-three-js/


Более десяти лет назад я написал Java-апплет для визуализации текстурированная сфера, фактически выполняя математические вычисления, чтобы определить, где поверхность сферы находилась в сцене (без использования треугольников).

Я переписал его на JavaScript для Canvas, и у меня есть демонстрация, отображающая Землю в виде сферы :

alt text
(источник: haslers.info )

Я получаю около 22 кадров в секунду на моей машине. Это примерно так же быстро, как и версия Java, на которой она была основана на рендеринге, если не немного быстрее!

Я давно не писал код Java - и это было довольно тупо - так что я действительно не помню Как именно это работает, я только что перенес его на JavaScript. Однако это из-за медленной версии кода, и я не уверен, была ли более быстрая версия из-за оптимизации в методах Java, которые я использовал для управления пикселями, или из-за ускорения в математике, которую он делает, чтобы определить, какой пиксель визуализировать из текстура. В то время я также переписывался с кем-то, у кого был похожий апплет, который был намного быстрее моего, но опять же я не знаю, возможно ли какое-либо из улучшений скорости, которые у них были, в JavaScript, поскольку он мог полагаться на библиотеки Java. (Я никогда не видел их кода, поэтому не знаю, как они это сделали. )

Итак, может быть возможным улучшить скорость. Но это хорошо работает как доказательство концепции.

Я попробую преобразовать мою более быструю версию, чтобы посмотреть, смогу ли я получить какие-либо улучшения скорости в версии JavaScript.

6
ответ дан 30 November 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: