Положение камеры и управление устройством на примере волн

Феликс уже дал отличный ответ, но я думал, что сделаю сравнение скорости различных методов:

  1. 10,59 сек (105,9us / itn) - copy.deepcopy(old_list)
  2. 10.16 сек (101.6us / itn) - метод чистого питона Copy(), копирующий классы с глубокой копией
  3. 1.488 сек (14.88us / itn) - чистый питон Copy() метод не копирует классы (только dicts / lists / tuples)
  4. 0,325 с (3,25us / itn) - for item in old_list: new_list.append(item)
  5. 0.217 sec (2.17us / itn) - [i for i in old_list] (понимание списка )
  6. 0,186 с (1,86us / itn) - copy.copy(old_list)
  7. 0,075 сек (0,75 us / itn) - list(old_list)
  8. 0,053 сек (0,53us / itn) - new_list = []; new_list.extend(old_list)
  9. 0,039 сек (0,39us / itn) - old_list[:] ( list slicing )

Таким образом, самая быстрая сортировка списка. Но имейте в виду, что copy.copy(), list[:] и list(list), в отличие от copy.deepcopy() и версии python, не копируют списки, словари и экземпляры класса в списке, поэтому, если оригиналы меняются, они будут меняться в скопированный список тоже и наоборот.

(Вот скрипт, если кто-то заинтересован или хочет поднять какие-либо проблемы:)

from copy import deepcopy

class old_class:
    def __init__(self):
        self.blah = 'blah'

class new_class(object):
    def __init__(self):
        self.blah = 'blah'

dignore = {str: None, unicode: None, int: None, type(None): None}

def Copy(obj, use_deepcopy=True):
    t = type(obj)

    if t in (list, tuple):
        if t == tuple:
            # Convert to a list if a tuple to 
            # allow assigning to when copying
            is_tuple = True
            obj = list(obj)
        else: 
            # Otherwise just do a quick slice copy
            obj = obj[:]
            is_tuple = False

        # Copy each item recursively
        for x in xrange(len(obj)):
            if type(obj[x]) in dignore:
                continue
            obj[x] = Copy(obj[x], use_deepcopy)

        if is_tuple: 
            # Convert back into a tuple again
            obj = tuple(obj)

    elif t == dict: 
        # Use the fast shallow dict copy() method and copy any 
        # values which aren't immutable (like lists, dicts etc)
        obj = obj.copy()
        for k in obj:
            if type(obj[k]) in dignore:
                continue
            obj[k] = Copy(obj[k], use_deepcopy)

    elif t in dignore: 
        # Numeric or string/unicode? 
        # It's immutable, so ignore it!
        pass 

    elif use_deepcopy: 
        obj = deepcopy(obj)
    return obj

if __name__ == '__main__':
    import copy
    from time import time

    num_times = 100000
    L = [None, 'blah', 1, 543.4532, 
         ['foo'], ('bar',), {'blah': 'blah'},
         old_class(), new_class()]

    t = time()
    for i in xrange(num_times):
        Copy(L)
    print 'Custom Copy:', time()-t

    t = time()
    for i in xrange(num_times):
        Copy(L, use_deepcopy=False)
    print 'Custom Copy Only Copying Lists/Tuples/Dicts (no classes):', time()-t

    t = time()
    for i in xrange(num_times):
        copy.copy(L)
    print 'copy.copy:', time()-t

    t = time()
    for i in xrange(num_times):
        copy.deepcopy(L)
    print 'copy.deepcopy:', time()-t

    t = time()
    for i in xrange(num_times):
        L[:]
    print 'list slicing [:]:', time()-t

    t = time()
    for i in xrange(num_times):
        list(L)
    print 'list(L):', time()-t

    t = time()
    for i in xrange(num_times):
        [i for i in L]
    print 'list expression(L):', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(L)
    print 'list extend:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        for y in L:
            a.append(y)
    print 'list append:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(i for i in L)
    print 'generator expression extend:', time()-t

EDIT: добавлены классы старого стиля и задает тесты, и сделал версию python намного быстрее и добавил еще несколько методов, включая выражения списков и extend().

0
задан ODB8 25 March 2019 в 16:41
поделиться

1 ответ

Исправлено. Код работает, движение оси Y отключено.

console.log("Desktop");
if (WEBGL.isWebGLAvailable() === false) {
	document.body.appendChild(WEBGL.getWebGLErrorMessage());
}
var SEPARATION = 100,
	AMOUNTX = 50,
	AMOUNTY = 50;
var container;
var camera, scene, renderer, controls;
var particles, count = 0;
var mouseX = 0,
	mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

// var isMobile = isOSMobile();
var isMobile = true;

init();
animate();

function init() {
	container = document.createElement('div');
	document.body.appendChild(container);
	camera = new THREE.PerspectiveCamera(75, window.innerWidth /
		window.innerHeight, 1, 10000);
	if (isMobile) {
		controls = new THREE.DeviceOrientationControls(camera);
	}
	camera.position.z = 1000;
	scene = new THREE.Scene();
	//
	var numParticles = AMOUNTX * AMOUNTY;
	var positions = new Float32Array(numParticles * 3);
	var scales = new Float32Array(numParticles);
	var i = 0,
		j = 0;
	for (var ix = 0; ix < AMOUNTX; ix++) {
		for (var iy = 0; iy < AMOUNTY; iy++) {
			positions[i] = ix * SEPARATION - ((AMOUNTX *
				SEPARATION) / 2); // x
			positions[i + 1] = 0; // y
			positions[i + 2] = iy * SEPARATION - ((AMOUNTY *
				SEPARATION) / 2); // z
			scales[j] = 1;
			i += 3;
			j++;
		}
	}
	var geometry = new THREE.BufferGeometry();
	geometry.addAttribute('position', new THREE.BufferAttribute(
		positions, 3));
	geometry.addAttribute('scale', new THREE.BufferAttribute(scales,
		1));
	var material = new THREE.ShaderMaterial({
		uniforms: {
			color: {
				value: new THREE.Color(isMobile ? 0xffffff : 0x8D8D8F)
			},
		},
		vertexShader: document.getElementById(
			'vertexshader').textContent,
		fragmentShader: document.getElementById(
			'fragmentshader').textContent
	});

	particles = new THREE.Points(geometry, material);
	scene.add(particles);

	renderer = new THREE.WebGLRenderer({
		antialias: true
	});
	renderer.setPixelRatio(window.devicePixelRatio);
	renderer.setSize(window.innerWidth, window.innerHeight);
	container.appendChild(renderer.domElement);
	document.addEventListener('mousemove', onDocumentMouseMove,
		false);
	window.addEventListener('resize', onWindowResize, false);
	if (isMobile) {
		window.addEventListener("deviceorientation", handleOrientation, true);
	}
}

function handleOrientation(e) {
	var absolute = e.absolute;
	var alpha = e.alpha;// x -90 ... 90
	var beta = e.beta;// y 180 ... 0
	var gamma = e.gamma;// x -90 ... 90

	mouseX = -5 * windowHalfX * (gamma / 90);
	//mouseY = -windowHalfY * ((beta - 90) / 90);

	// console.log(mouseX.toFixed(2), ' x ', mouseY.toFixed(2));
}

function onWindowResize() {
	windowHalfX = window.innerWidth / 2;
	windowHalfY = window.innerHeight / 2;
	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();
	renderer.setSize(window.innerWidth, window.innerHeight);
}
//
function onDocumentMouseMove(event) {
	mouseX = event.clientX - windowHalfX;
	mouseY = event.clientY - windowHalfY;
}

//
function animate() {
	requestAnimationFrame(animate);
	render();
	if (isMobile) {
		controls.update();
	}
}

function render() {
	camera.position.x += (mouseX - camera.position.x) * .05;
	if(isMobile) {
		camera.position.y = 550;
	} else {
		camera.position.y += (-mouseY - camera.position.y) * .05;
	}
	camera.lookAt(scene.position);
	var positions = particles.geometry.attributes.position.array;
	var scales = particles.geometry.attributes.scale.array;
	var i = 0,
		j = 0;
	for (var ix = 0; ix < AMOUNTX; ix++) {
		for (var iy = 0; iy < AMOUNTY; iy++) {
			positions[i + 1] = (Math.sin((ix + count) * 0.3) * 50) +
				(Math.sin((iy + count) * 0.5) * 50);
			scales[j] = (Math.sin((ix + count) * 0.3) + 1) * 8 +
				(Math.sin((iy + count) * 0.5) + 1) * 8;
			i += 3;
			j++;
		}
	}
	particles.geometry.attributes.position.needsUpdate = true;
	particles.geometry.attributes.scale.needsUpdate = true;
	renderer.render(scene, camera);
	count += 0.1;
}

function isOSMobile() {
	var userAgent = navigator.userAgent || navigator.vendor || window.opera;

	if (/android/i.test(userAgent)) {
		return true;
	}
	if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
		return true;
	}

	return false;
}

0
ответ дан ODB8 25 March 2019 в 16:41
поделиться
Другие вопросы по тегам:

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