All streams
Search
Write a publication
Pull to refresh
147
0
Алексей Борисов @Imp5

Программный инженер

Send message
Однако, на практике оказалось довольно непросто реализовать поиск нужных коэффициентов на платформе Android

Похоже, коэффициенты были подогнаны вообще под конкретную картинку.

Например, через линейный фильтр

medianBlur — это не линейный фильтр.
по стебались

Погоди, только сначала с безграмотности постебёмся.
… Мой отец вернулся с работы в частной школе в Доббс-Ферри, Нью-Йорк. Он бросил свой мешок на пол и спросил меня...

Что же было у него в мешке?
Вот ещё предложение по улучшению трёхмерной визуализации: сглаженные пиксели и интенсивность, зависящая от глубины.
<script></script>
<script>
var canvas;
var canvasData;
var context;
var massiv;
var angls=[[45,180],[-45,90],[-45,90],[45,180]];

function createRequestObject() {
  if (typeof XMLHttpRequest === 'undefined') {
    XMLHttpRequest = function() {
      try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
        catch(e) {}
      try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
        catch(e) {}
      try { return new ActiveXObject("Msxml2.XMLHTTP"); }
        catch(e) {}
      try { return new ActiveXObject("Microsoft.XMLHTTP"); }
        catch(e) {}
      throw new Error("This browser does not support XMLHttpRequest.");
    };
  }
  return new XMLHttpRequest();
}
function selecter(num){
  req = new XMLHttpRequest();
  if (req) {
    req.open("POST", '/geom3d/', true);
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.onreadystatechange = processReqChange;
    var postmyplease="num="+num;
    req.send(postmyplease);
  }
}
function processReqChange(){
  try {
    if (req.readyState == 4) {
      if (req.status == 200) {
        var ang=JSON.parse(req.responseText);
        angls=ang.response;
        massiv=sfera(angls);
        droveLines(canvas, 0, 0, massiv);
        var logger=document.getElementById('logger');
        logger.innerHTML=" <br />";
        var link="";
        for (i=0, len=angls.length; i<len; i++) {
          //logger.innerHTML += "("+angls[i][0]+", "+angls[i][1]+") <br />";
          link+=angls[i][0]+"/"+angls[i][1]+"/";
        }
        logger.innerHTML="<a href=\"http://fractal.xcont.com/geom3d/"+link+"\">"+link+"</a>";
      } else {
          alert("Не удалось получить данные:\n" + req.statusText);
      }
    }
  }
  catch( e ) {}
}

function rotate(v, p, cos, sin, mcos){
  var x=v[0], y=v[1], z=v[2]; // вектор, вокруг которого вращаем
  var xp=p[0], yp=p[1], zp=p[2]; // точка, которую вращаем
  var a11=(mcos*x*x+cos), a12=(mcos*x*y-sin*z), a13=(mcos*x*z+sin*y); // матрица поворота вокруг вектора
  var a21=(mcos*x*y+sin*z), a22=(mcos*y*y+cos), a23=(mcos*z*y-sin*x);
  var a31=(mcos*x*z-sin*y), a32=(mcos*z*y+sin*x), a33=(mcos*z*z+cos);
  var xx=xp*a11+yp*a12+zp*a13; // умножаем точку на матрицу
  var yy=xp*a21+yp*a22+zp*a23;
  var zz=xp*a31+yp*a32+zp*a33;
  return [xx, yy, zz];
}
function find_point(a, b, c, angls){
  var alfa=angls[0]*Math.PI/180, betta=angls[1]*Math.PI/180;
  var x1=a[0], y1=a[1], z1=a[2]; //A
  var x2=b[0], y2=b[1]; z2=b[2]; //B - ось вращения AB
  var x3=c[0], y3=c[1], z3=c[2]; //C - третья точка нужна для задания плоскости
  var xa=x2-x1, ya=y2-y1, za=z2-z1; // вектор AB
  var xc=x3-x1, yc=y3-y1, zc=z3-z1; // вектор AC
  var xv=(ya*zc-za*yc), yv=-(xa*zc-za*xc), zv=(xa*yc-ya*xc); // векторное произведение векторов AB и AC (получаем вектор-перпиндикуляр к плоскости)
  var cosa=Math.cos(alfa); // всю тригонометрию из матрицы поворота считаем заранее (оптимизация)
  var sina=Math.sin(alfa);
  var mcosa=1-Math.cos(alfa);
  var cosb=Math.cos(betta);
  var sinb=Math.sin(betta);
  var mcosb=1-Math.cos(betta);
  var r=Math.sqrt(Math.pow(xv,2)+Math.pow(yv,2)+Math.pow(zv,2)); // длина вектора-перпиндикуляра
  var vector=[xv/r, yv/r, zv/r]; // нормированный вектор
  var point=[xa, ya, za]; // вокруг вектора-перпендикуляра делаем поворот точки A на угол alfa
  var d=rotate(vector, point, cosa, sina, mcosa); // точка после поворота
  r=Math.sqrt(Math.pow(xa,2)+Math.pow(ya,2)+Math.pow(za,2)); // длина вектора AB
  vector=[xa/r, ya/r, za/r]; // нормированный вектор
  point=[d[0]*Math.cos(alfa),d[1]*Math.cos(alfa),d[2]*Math.cos(alfa)]; // угол ADC=90°
  d=rotate(vector, point, cosb, sinb, mcosb); // вращаем точку D вокруг AB
  d=[d[0]+x1, d[1]+y1, d[2]+z1]; // сдвигаем точку D
  return d;
}
function recurs(array, n, a, b, d, angls){
  if (n==0){
    return array;
  }else{
    if (!array[0][n]) array[0][n]=0;
    var d=find_point(a, b, d, angls[array[0][n]]);
    array[1].push(d);
    array[0][n]++;
    if (array[0][n]==angls.length) array[0][n]=0;
    recurs(array, n-1, a, d, b, angls);
    recurs(array, n-1, d, b, a, angls);
    return array;
  }
}
function sfera(angls){
  var massiv=new Array();
  var x1=0; y1=10; z1=0;
  var x2=0; y2=-10; z2=0;
  var x3=0; y3=0; z3=-10;
  massiv[0]=[x1, y1, z1];
  massiv[1]=[x2, y2, z2];
  massiv[2]=[x3, y3, z3];
  var d=find_point(massiv[0], massiv[1], massiv[2], [angls[0][0], 0]);
  massiv[2]=d;
  var m1=new Array();
  var m2=new Array();
  var array=[m1,m2];
  d=recurs(array, 15, massiv[0], massiv[1], massiv[2], angls);
  massiv = massiv.concat(d[1]);
  return massiv;
}
  
  
window.onload=function(){
  canvas=document.getElementById('myCanvas');
  context=canvas.getContext('2d');
  canvas.width=600;
  canvas.height=600;
  canvasData=context.getImageData(0, 0, canvas.width, canvas.height);
  
  massiv=sfera(angls);
  droveLines(canvas, 0, 0, massiv);
  
  canvas.addEventListener('mousemove', function(evt){
      var mousePos=getMousePos(canvas, evt);
      droveLines(canvas, mousePos.x, mousePos.y, massiv);
    }, false);
    
  function getMousePos(canvas, evt){
    var obj=canvas;
    var top=0;
    var left=0;
    while (obj && obj.tagName != 'BODY') {
      top+=obj.offsetTop;
      left+=obj.offsetLeft;
      obj=obj.offsetParent;
    }
   
    var mouseX=evt.clientX-left+window.pageXOffset;
    var mouseY=evt.clientY-top+window.pageYOffset;
    return {
      x: mouseX,
      y: mouseY
    };
  }
}

function droveLines(canvas, xMouse, yMouse, massiv){
  clearCanvas();
  var xCenter=canvas.width/2;
  var yCenter=canvas.height/2;
  var focus=800;
  var i, x, y, z, xx, yy, zz;
  var arr=new Array();
  var arr2=new Array();
  var alfa=yMouse*Math.PI/180; 
  var betta=xMouse*Math.PI/180;
  var cosa=Math.cos(alfa);
  var cosb=Math.cos(betta);
  var sina=Math.sin(alfa);
  var sinb=Math.sin(betta);
  
  for (i=0, len=massiv.length; i<len; i++) {
    x=massiv[i][0];
    y=massiv[i][1];
    z=massiv[i][2];
    yy=y*cosa-z*sina;
    zz=z*cosa+y*sina;
    z=zz;
    xx=x*cosb+z*sinb;
    zz=z*cosb-x*sinb;
    y=yy; x=xx;  z=zz;
    z+=64;
    xx=focus*x/z+xCenter;
    yy=focus*y/z+yCenter;

    var fade = Math.max(Math.min(0.8 - z / 100.0, 1.0), 0.0);
    fade = (fade * fade + fade) * 0.5;

    drawPixel(xx, yy, 450 * fade, 370 * fade, 150 * fade);
  }
  updateCanvas();
}

function drawPixel(x, y, r, g, b) {
  var ix = Math.floor(x);
  var iy = Math.floor(y);
  var dx = x - ix;
  var dy = y - iy;
  var v00 = (1.0 - dx) * (1.0 - dy);
  var v10 = dx * (1.0 - dy);
  var v01 = (1.0 - dx) * dy;
  var v11 = dx * dy;

  var index = (ix + iy * canvas.width) * 4;
  var d = canvasData.data;

  index = Math.max(Math.min(index, d.length - canvas.width * 4 - 4), 0);

  d[index + 0] = Math.min(d[index + 0] + r * v00, 255);
  d[index + 1] = Math.min(d[index + 1] + g * v00, 255);
  d[index + 2] = Math.min(d[index + 2] + b * v00, 255);
  d[index + 3] = 255;

  d[index + 4] = Math.min(d[index + 4] + r * v10, 255);
  d[index + 5] = Math.min(d[index + 5] + g * v10, 255);
  d[index + 6] = Math.min(d[index + 6] + b * v10, 255);
  d[index + 7] = 255;

  index += canvas.width * 4;

  d[index + 0] = Math.min(d[index + 0] + r * v01, 255);
  d[index + 1] = Math.min(d[index + 1] + g * v01, 255);
  d[index + 2] = Math.min(d[index + 2] + b * v01, 255);
  d[index + 3] = 255;

  d[index + 4] = Math.min(d[index + 4] + r * v11, 255);
  d[index + 5] = Math.min(d[index + 5] + g * v11, 255);
  d[index + 6] = Math.min(d[index + 6] + b * v11, 255);
  d[index + 7] = 255;
}

function updateCanvas() {
  context.putImageData(canvasData, 0, 0);
}

function clearCanvas() {
  for (var i=0; i<canvasData.data.length; i+=4){
    canvasData.data[i]=0;
    canvasData.data[i+1]=0;
    canvasData.data[i+2]=0;
    canvasData.data[i+3]=255;
  }
  context.putImageData(canvasData, 0, 0);
}

</script>




Ещё надо придумать что делать с std::abs. В лучшем случае код не скомпилируется, в худшем, компилятор приведёт к double.
Хорошую вещь делаете.
В меру свободного времени потестировал, занёс найденное в issues. Но это было очень поверхностное тестирование, далеко от того которое требуется для числовой библиотеки.
Вот таким нехитрым образом жаргон продавщиц попал на geektimes в название статьи :)
для проверки неликвидных компонентов в конструкции

Что означает слово «неликвидных» в названии?
Не скомпилируется.
Вы пропустили пробел в слове «coming»
Это же pixlr.
Второй ворованный редактор на этом сайте — SumoPaint
Вот только выключать надо будет всё что с процессорами.
Если обратить внимание на частоту использования, то «флуктуация» в техническом контексте явно впереди: google:«флюктуация тока»
Вообще, «флюктуации» — это медицинский термин, но я уже не первый раз вижу его употребление на хабре.
Я играл ещё с факториалами, корнями и степенями.
А по-моему, что-то в этом есть, полирует атмосферу декадентства, которое идёт через всю статью.
Человек плохо знающий язык «C» и русский язык, загорается желанием сделать управление машинками через интернет, невзирая на то, что аналогичные проекты умерли. Заказав устройство, сталкивается сначала с обманом продавца, а затем его постигает глубокое разочарование при попытке подключить камеру. Продираясь через терни настройки видеопотока и GPIO, он готов уже обратиться к фрилансерам, но они заняты и отказывают ему в помощи. И в итоге, пройдя все испытания, автор замеряет задержку управления и получает 0.2 секунды, с которыми будет крайне сложно управлять машинкой.
В завершении мы узнаём о сломанной игрушке его сына, которая послужила донором для проекта и не дала умереть надежде.
Если уменьшить количество элементов для Блума — то нет.

Information

Rating
Does not participate
Registered
Activity