In the following code, the console.log from the line 92 and 93 (switchPosition function) doesn't provide the same result. I am, I have to admit, stuck.
Any thoughts, ideas, explanations?
Thanks you for the time taken,
var Carrousel = (function () {
var self = {},
config = {
item: 3, // item to be displayed
scroll: 2 // number of items to be scrolled
},
container = null,
items = null,
nbItems = null,
nbSlide = null,
position = [],
searchPositionDepending = []
;
self.init = function (opts) {
options = opts || {}
execute();
}
// Private Method
execute = function () {
container = document.getElementById('carrousel');
items = document.getElementsByClassName('flux');
var containerWidth = container.offsetWidth;
var containerHeight = items[0].offsetHeight * 1.5;
container.style.height = '' + containerHeight + '';
nbItems = document.getElementsByClassName('flux').length;
nbSlide = nbItems / config.item;
// Initialisation du Carrousel
for (i = 0; i < nbItems; i++) {
items[i].style.width = '' + (containerWidth / config.item) + '';
items[i].style.display = 'none';
items[i].style.position = 'absolute';
items[i].style.top = "0";
items[i].style.left = "0";
items[i].setAttribute('data-position', '' + (i + 1) + '');
items[i].setAttribute('data-number', '' + i + '');
}
searchPosition();
placement();
document.getElementById('next').onclick = function () {
next();
searchPosition();
switchPosition();
placement();
// position();
}
document.getElementById('previous').onclick = function () {
// previous();
// searchPosition();
// position();
}
}
searchPosition = function () {
for (i = 0; i < config.item; i++) {
searchPositionDepending[i] = (function () { //Appending a function searchPosition per item displayed
for (j = 1; j <= config.item; j++) { //Passing through the first items to get their position
if (items[i].dataset.position === '' + j + '') {
position[j] = items[i];
return true;
} else {
}
}
;
})();
}
}
switchPosition = function () {
for (i = 0, j = 0; i < nbItems; i++, j++) {
if (items[i].dataset.position === '' + j + '') {
position[i] = position[i];
}
}
for (i = config.item, j = 1; i < nbItems; i++, j++) { //Replacing in good order, except for the one that are place into the variable position[];
items[i] = items[j];
}
for (i = (nbItems - config.item +1), j = 1; i <= nbItems; i++, j++) { //Replacing in good order the one that are place into variable position[];
items[i] = position[j];
console.log(i);
console.log(j);
console.log(position[j]);
console.log(items[i]);
}
for (i = 0; i < nbItems; i++) {
console.log(items[i]);
}
console.log(items[10]);
}
placement = function () {
for (i = 1; i <= config.item; i++) {
var rect = items[0].getBoundingClientRect();
item_width = Math.floor(rect.width);
item_height = Math.floor(rect.height);
var x = item_width * (i - 1) * 1.1;
items[i].style.display = 'block';
items[i].style.transform = "translate3D(" + x + "px, 0px, 0px)";
}
}
next = function () {
for (i = config.item, j = 1; i < nbItems; i++, j++) { //Updating all dataset position, except for the items that are displayed.
items[i].dataset.position = j;
}
for (i = 1, j = 2; i <= config.item; i++, j--) {
position[i].dataset.position = nbItems - j;
position[i].style.display = "none";
}
}
return self;
})();
Related
I have this code, in script (p5.js), I am running it and works as expected, but the moment I include the path code, that helps in finding the previous parents to form a path to the end goal, the browser crushes, as the images show. It fist colors the 3 cells then crashes. Here is the code.
var col = 12, row = 12, grid = new Array(col), openSet = [], closeSet = [], start, end, w, h, path = [];
function removefromArray(array_, element){
for(var i = array_.length - 1; i >= 0; i--){
if(array_[i] == element){
array_.splice(i, 1);
}
}
}
function heuristic(a, b){
var distance = abs(a.i - b.i) + abs(a.j - b.j);
return distance;
}
function Spot(i, j){
this.i = i;
this.j = j;
this.f = 0;
this.g = 0;
this.h = 0;
this.neighbor = [];
this.parent = undefined;
this.wall = false;
this.show = function (color){
fill(color);
if(this.wall){
fill(0);
}
noStroke();
rect(this.i * w, this.j * h, w - 1, h - 1);
}
this.addNeighbor = function(grid){
var i = this.i, j = this.j;
if(i < col - 1){
this.neighbor.push(grid[i+1] [j]);
}
if(i > 0){
this.neighbor.push(grid[i-1] [j]);
}
if(j < row-1){
this.neighbor.push(grid[i] [j+1]);
}
if(j > 0){
this.neighbor.push(grid[i] [j-1]);
}
}
}
function setup(){
createCanvas(500,500);
console.log("A*");
w = width / col;
h = height / row;
for( var i = 0; i< col; i++){
grid[i] = new Array(row);
}
//Adding a spot
for( var i = 0; i< col; i++){
for( var j = 0; j< row; j++){
grid[i][j] = new Spot(i,j);
}
}
//Adding a neighbor
for( var i = 0; i< col; i++){
for( var j = 0; j< row; j++){
grid[i][j].addNeighbor(grid);
}
}
start = grid[0][0];
end = grid[col - 1][row - 1];
openSet.push(start);
}
function draw(){
var winner = 0;
if(openSet.length > 0){
for( var i = 0; i< openSet.length; i++){
if(openSet[i].f < openSet[winner].f){
winner = i;
}
}
var current = openSet[winner];
if(current === end){
noLoop();
console.log("Done!");
}
removefromArray(openSet, current);
closeSet.push(current);
var neighbors = current.neighbor;
for(var i = 0; i < neighbors.length; i++){
var the_neighbor = neighbors[i];
if(!closeSet.includes(the_neighbor)){
var tempG = current.g + 1;
}
if(openSet.includes(the_neighbor)){
if(tempG < the_neighbor.g){
the_neighbor.g = tempG;
}
}
else{
the_neighbor.g = tempG;
openSet.push(the_neighbor);
}
the_neighbor.h = heuristic(the_neighbor, end);
the_neighbor.f = the_neighbor.g + the_neighbor.h;
the_neighbor.parent = current; // the previous node
}
}
else{
// no solution
}
background(0)
for( var i = 0; i< col; i++){
for( var j = 0; j< row; j++){
grid[i][j].show(color(255));
}
}
for( var i = 0; i< openSet.length; i++){
openSet[i].show(color("green"));
}
for( var i = 0; i< closeSet.length; i++){
closeSet[i].show(color("red"));
}
// path = [];
// var temp = current;
// path.push(temp);
// while(temp.parent){
// path.push(temp.parent);
// temp = temp.parent;
// }
// for(var i = 0; i < path.length; i++){
// path[i].show(color(0,0,255));
// }
}
If I try to remove the comments slash for this last part, the system will run for about 5secs then crashes. Someone with the solution, I will highly appreciate.
Result when the path part is uncommented
You are generating a cycle somehow in the chain of parents (i.e. Spot A has parent Spot B and Spot B has parent Spot A), which is causing an infinite loop. I'm not sure exactly where/why this is happening. Your code is a bit hard to read. You should avoid nondescript one letter variable & property names.
Also there are several scoping issues that may be causing unexpected behavior. The keyword var is the worst element of any programming language since goto and it should be scoured from the face of the internet with the fire of 1000 suns. Please use let. See the comments below for more explanation.
var col = 12,
row = 12,
grid = new Array(col),
openSet = [],
closeSet = [],
start, end, w, h, path = [];
function removefromArray(array_, element) {
for (let i = array_.length - 1; i >= 0; i--) {
if (array_[i] == element) {
array_.splice(i, 1);
}
}
}
function heuristic(a, b) {
var distance = abs(a.i - b.i) + abs(a.j - b.j);
return distance;
}
function Spot(i, j) {
this.i = i;
this.j = j;
this.f = 0;
this.g = 0;
this.h = 0;
this.neighbor = [];
this.parent = undefined;
this.wall = false;
this.show = function(color) {
fill(color);
if (this.wall) {
fill(0);
}
noStroke();
rect(this.i * w, this.j * h, w - 1, h - 1);
}
this.addNeighbor = function(grid) {
let i = this.i,
j = this.j;
if (i < col - 1) {
this.neighbor.push(grid[i + 1][j]);
}
if (i > 0) {
this.neighbor.push(grid[i - 1][j]);
}
if (j < row - 1) {
this.neighbor.push(grid[i][j + 1]);
}
if (j > 0) {
this.neighbor.push(grid[i][j - 1]);
}
}
}
function setup() {
createCanvas(500, 500);
console.log("A*");
w = width / col;
h = height / row;
for (let i = 0; i < col; i++) {
grid[i] = new Array(row);
}
//Adding a spot
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
grid[i][j] = new Spot(i, j);
}
}
//Adding a neighbor
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
grid[i][j].addNeighbor(grid);
}
}
start = grid[0][0];
end = grid[col - 1][row - 1];
openSet.push(start);
}
function draw() {
let winner = 0;
let current
if (openSet.length > 0) {
for (let i = 0; i < openSet.length; i++) {
if (openSet[i].f < openSet[winner].f) {
winner = i;
}
}
current = openSet[winner];
if (current === end) {
noLoop();
console.log("Done!");
}
removefromArray(openSet, current);
closeSet.push(current);
var neighbors = current.neighbor;
for (let i = 0; i < neighbors.length; i++) {
var the_neighbor = neighbors[i];
// The use of var here results in very weird behavior
// where tempG's value is preserved from the previous
// iteration of this loop even when it is not assigned
// a value. If that is desired you should declare this
// variable outside of the for loop.
//
// If you always use let isntead of var you will get
// errors instead of bizarre behavior. That will help
// you be deliberate about your variable scoping.
if (!closeSet.includes(the_neighbor)) {
var tempG = current.g + 1;
} else {
print('tempG not set');
}
if (openSet.includes(the_neighbor)) {
if (tempG < the_neighbor.g) {
the_neighbor.g = tempG;
}
} else {
print(`tempG: ${tempG}`);
the_neighbor.g = tempG;
openSet.push(the_neighbor);
print(`openSet: ${openSet.length}`);
}
the_neighbor.h = heuristic(the_neighbor, end);
the_neighbor.f = the_neighbor.g + the_neighbor.h;
the_neighbor.parent = current; // the previous node
}
} else {
// no solution
}
background(0)
for (let i = 0; i < col; i++) {
for (var j = 0; j < row; j++) {
grid[i][j].show(color(255));
}
}
for (let i = 0; i < openSet.length; i++) {
openSet[i].show(color("green"));
}
for (let i = 0; i < closeSet.length; i++) {
closeSet[i].show(color("red"));
}
path = [];
let temp = current;
path.push(temp);
while (temp.parent) {
if (path.includes(temp.parent)) {
print('Cycle detected!');
console.log({ current: { i: temp.i, j: temp.j }, parent: { i: temp.parent.i, j: temp.parent.j } });
break;
}
path.push(temp.parent);
temp = temp.parent;
}
for (let i = 0; i < path.length; i++) {
path[i].show(color(0, 0, 255));
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.js"></script>
Update: Infinite Loop Fix
The part of your code that updates neighbors deviates from the definition of A* pretty substantially. Here's what I came up with (single letter variable names replaces with meaningful names):
let tentativePathScore = current.shortestPathScore + 1;
if (the_neighbor.heuristicScore === undefined) {
the_neighbor.heuristicScore = heuristic(the_neighbor, end);
}
if (the_neighbor.combinedScore === undefined ||
tentativePathScore + the_neighbor.heuristicScore < the_neighbor.combinedScore) {
// Update the path score and combined score for this neighbor.
the_neighbor.shortestPathScore = tentativePathScore;
the_neighbor.combinedScore = the_neighbor.shortestPathScore + the_neighbor.heuristicScore;
the_neighbor.parent = current; // the previous node
if (!openSet.includes(the_neighbor)) {
openSet.push(the_neighbor);
}
}
And here's a working snippet with walls added:
let col = 12,
row = 12,
grid = new Array(col),
openSet = [],
closeSet = [],
start, end, w, h, path = [];
function removefromArray(array_, element) {
for (let i = array_.length - 1; i >= 0; i--) {
if (array_[i] == element) {
array_.splice(i, 1);
}
}
}
function heuristic(a, b) {
if (a.wall) {
return Infinity;
}
return abs(a.i - b.i) + abs(a.j - b.j);
}
function Spot(i, j) {
this.i = i;
this.j = j;
this.combinedScore = undefined;
this.shortestPathScore = undefined;
this.heuristicScore = undefined;
this.neighbor = [];
this.parent = undefined;
this.wall = false;
this.show = function(color) {
fill(color);
if (this.wall) {
fill(0);
}
noStroke();
rect(this.i * w, this.j * h, w - 1, h - 1);
}
this.addNeighbor = function(grid) {
let i = this.i,
j = this.j;
if (i < col - 1) {
this.neighbor.push(grid[i + 1][j]);
}
if (i > 0) {
this.neighbor.push(grid[i - 1][j]);
}
if (j < row - 1) {
this.neighbor.push(grid[i][j + 1]);
}
if (j > 0) {
this.neighbor.push(grid[i][j - 1]);
}
}
}
function setup() {
createCanvas(500, 500);
console.log("A*");
w = width / col;
h = height / row;
for (let i = 0; i < col; i++) {
grid[i] = new Array(row);
}
//Adding a spot
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
grid[i][j] = new Spot(i, j);
}
}
//Adding a neighbor
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
grid[i][j].addNeighbor(grid);
}
}
// make walls
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
if ((i > 1 || j > 1) && (i < col - 2 || j < row - 2) && random() < 0.2) {
grid[i][j].wall = true;
}
}
}
start = grid[0][0];
end = grid[col - 1][row - 1];
start.shortestPathScore = 0;
start.heuristicScore = heuristic(start, end);
start.combinedScore = start.shortestPathScore + start.heuristicScore;
openSet.push(start);
}
function draw() {
let winner = 0;
let current;
if (openSet.length > 0) {
for (let i = 0; i < openSet.length; i++) {
if (openSet[i].combinedScore < openSet[winner].combinedScore) {
winner = i;
}
}
current = openSet[winner];
if (current === end) {
noLoop();
console.log("Done!");
}
removefromArray(openSet, current);
closeSet.push(current);
var neighbors = current.neighbor;
for (let i = 0; i < neighbors.length; i++) {
var the_neighbor = neighbors[i];
let tentativePathScore = current.shortestPathScore + 1;
if (the_neighbor.heuristicScore === undefined) {
the_neighbor.heuristicScore = heuristic(the_neighbor, end);
}
if (the_neighbor.combinedScore === undefined ||
tentativePathScore + the_neighbor.heuristicScore < the_neighbor.combinedScore) {
// Update the path score and combined score for this neighbor.
the_neighbor.shortestPathScore = tentativePathScore;
the_neighbor.combinedScore = the_neighbor.shortestPathScore + the_neighbor.heuristicScore;
the_neighbor.parent = current; // the previous node
if (!openSet.includes(the_neighbor)) {
openSet.push(the_neighbor);
}
}
}
} else {
// no solution
}
background(0)
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
grid[i][j].show(color(255));
}
}
for (let i = 0; i < openSet.length; i++) {
openSet[i].show(color("green"));
}
for (let i = 0; i < closeSet.length; i++) {
closeSet[i].show(color("red"));
}
path = [];
let temp = current;
path.push(temp);
while (temp.parent) {
if (path.includes(temp.parent)) {
print('Cycle detected!');
break;
}
path.push(temp.parent);
temp = temp.parent;
}
for (let i = 0; i < path.length; i++) {
path[i].show(color(0, 0, 255));
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.js"></script>
I want to make something awesome for Bootstrap 5.
As I search for week now, there aren't many good Tabs-responsive tabs solutions for Bootstrap 5 and most of them are not really good solution for mobile phones.
But in my search I encountered this one: https://codepen.io/Ayn_/pen/xdVBVg
https://github.com/Aynn/Bootstrap-Responsive-Tabs
So far my try with bs5: https://codepen.io/xkpx/pen/ExWXKRy
How can I convert this to work with bs5?
$(document).ready(function() {
rTab();
});
$(window).resize(function() {
rTab_resize();
});
function rTab()
{
$('.nav-tabs').each(function() {
var li = [];
var le = [];
var ddtab_w;
var currentw = $(this).outerWidth();
for(var i = 0; i < $(this)[0].children.length; i++)
{
li.push($(this)[0].children[i].outerHTML);
le.push($(this)[0].children[i].offsetWidth);
if(i == $(this)[0].children.length-1)
{
//$(this)[0].children[i].innerHTML = "<a href='#' data-toggle='tab'> Tab ("+ (i+1) +") <span class='caret'></span></a></a>";
ddtab_w = $(this)[0].children[i].offsetWidth;
}
}
var total_tabs = $(this)[0].children.length;
var wTracker = 0;
var tabs;
$(this).html('');
for(var i = 0; i < li.length; i++)
{
if((le[i] + wTracker) <= currentw)
{
wTracker += le[i];
tabs = i;
if (i == li.length-1)
{
for(var i = 0; i < li.length; i++)
{
$(this).append(li[i]);
}
}
} else {
i = li.length-1;
while(ddtab_w + wTracker >= currentw)
{
wTracker -= le[tabs--];
}
if(tabs < 0) { tabs = 0; }
for(var x = 0; x < tabs; x++)
{
$(this).append(li[x]);
}
var dropdown_tabs = ddTab(total_tabs-tabs, "Tabs");
$(this)[0].appendChild(dropdown_tabs[0]);
wTracker += $(this)[0].children[$(this)[0].children.length-1].offsetWidth;
while(tabs<li.length)
{
dropdown_tabs[1].innerHTML += li[tabs++];
}
}
}
if($(this)[0].children[$(this)[0].children.length-1].classList[1] == "pull-right")
{
isActive(dropdown_tabs, $(this)[0].children[$(this)[0].children.length-1]);
}
if($(this)[0].children.length == 1)
{
dropdown_tabs[0].style.paddingLeft = "10px";
dropdown_tabs[0].style.marginRight = "-10px";
dropdown_tabs[0].style.textAlign = "center";
dropdown_tabs[0].style.position = "relative";
dropdown_tabs[0].style.width = "100%";
dropdown_tabs[0].setAttribute("class","dropdown pull-right active");
dropdown_tabs[1].style.left = "7px";
dropdown_tabs[2].data = dropdown_tabs[1].children[0].innerText + " (" + dropdown_tabs[1].children.length + ")";
$(dropdown_tabs[1]).click(function() {
dropdown_tabs[2].data =event.target.text + " (" + dropdown_tabs[1].children.length + ")";
});
}
});
}
function rTab_resize()
{
reset();
rTab();
}
function reset()
{
$('.nav-tabs').each(function() {
if($(this)[0].children[$(this)[0].children.length-1].classList[1] == "pull-right")
{
var drop_down_tab = $(this)[0].children[$(this)[0].children.length-1].children[1];
var initial_value = drop_down_tab.children.length;
for(var i = 0; i < initial_value; i++)
{
$(this).append(drop_down_tab.children[0]);
}
$(this)[0].children[$(this)[0].children.length-(1+initial_value)].remove();
}
});
}
function ddTab(total_dropdown, tabName)
{
var n_li = document.createElement("li");
n_li.setAttribute("class","dropdown pull-right");
n_li.style.position = "relative";
n_li.style.right = "13px";
var n_a = document.createElement("a");
n_a.setAttribute("class","dropdown-toggle");
n_a.setAttribute("data-toggle","dropdown");
n_a.setAttribute("href","#");
var n_sp = document.createElement("span");
n_sp.setAttribute("class","caret");
var n_ul = document.createElement("ul");
n_ul.setAttribute("class","dropdown-menu");
var n_tx = document.createTextNode(tabName + " (" + total_dropdown + ")");
n_a.appendChild(n_tx);
n_a.appendChild(n_sp);
n_li.appendChild(n_a);
n_li.appendChild(n_ul);
return [n_li, n_ul, n_tx];
}
function isActive(dropdown_tabs, child)
{
for (var i = 0; i < dropdown_tabs[1].children.length; i++)
{
if(dropdown_tabs[1].children[i].classList[0] == "active")
{
child.setAttribute("class","dropdown pull-right active");
}
}
}
I want to make a dynamic water pipe with water flowing. The front picture is an error message.
The following picture is a method in the method in the vue page. I don't know if it will report an error. If you don't call this method, nothing will be reported.
The following code is the js file that introduces the vue page
//构造函数
function Createline(config) {
this.c = 0;
this.lines = [];
var self = this;
//初始化线
(function (self){
if(config.fx == "w"){
var number = config.canvas_w / (config.width + config.width/2 + config.jiange*2);
number = Math.ceil(number) + 1;
for(var n = 0 ; n < number ; n++){
var mxx = config.canvas_w - n*(config.width+config.width/2+config.jiange*2);
var lines_data = {
mx:mxx,
lx:mxx - config.width,
my:config.my,
ly:config.ly,
vx:config.vx,
vy:config.vy,
}
self.lines.push(lines_data);
var lines_data2 = {
mx:mxx-config.width-config.jiange,
lx:mxx-config.width-config.jiange-config.width/2,
my:config.my,
ly:config.ly,
vx:config.vx,
vy:config.vy,
}
self.lines.push(lines_data2);
}
}
if(config.fx == "h"){
var number = config.canvas_w / (config.width + config.width/2 + config.jiange*2);
number = Math.ceil(number) + 1;
for(var n = 0 ; n < number ; n++){
var myy = config.canvas_h - n*(config.width+config.width/2+config.jiange*2);
var lines_data3 = {
mx:config.mx,
lx:config.lx,
my:myy,
ly:myy - config.width,
vx:config.vx,
vy:config.vy,
}
self.lines.push(lines_data3);
var lines_data4 = {
mx:config.mx,
lx:config.lx,
my:myy-config.width-config.jiange,
ly:myy-config.width-config.jiange-config.width/2,
vx:config.vx,
vy:config.vy,
}
self.lines.push(lines_data4);
}
}
})(self);
}
//开始
Createline.prototype.begin = function (element,config) {
var canvasObj = document.getElementById(element);
var self = this;
var canvas = {
line_w: config.line_w || 3, //线条厚度
vx: config.vx || 0,//x轴运动速度
vy:config.vy || 0,//Y轴速度
color:config.color || "blue",//线条颜色
canvas_w:config.canvas_w || 0,//画布宽度
canvas_h:config.canvas_h || 0,//画布高度
mx: config.mx || 0,//线的开始位置X坐标
my: config.my || 0,//线的开始位置Y坐标
lx: config.lx || 0,//线的结束位置X坐标
ly: config.ly || 0,//线的结束位置Y坐标
fx:config.fx || "w",//运动方向 w 水平 ,h: 垂直
width:config.width || 20,//线的长度
jiange:config.jiange || 10, //线的间隔
}
if(canvasObj.getContext("2d")){
canvas.ctx = canvasObj.getContext("2d"),
canvasObj.width = canvas.canvas_w;
canvasObj.height = canvas.canvas_h;
}else{
console.log("当前环境不支持canvas");
return null;
}
setInterval(function(){
self.createline(self,canvas);
if(canvas.fx == "w"){
self.updateline_w(self,canvas);
}
if(canvas.fx == "h"){
self.updateline_h(self,canvas);
}
self.addline(self,canvas);
},config.time);
return canvas.ctx;
}
//画线
Createline.prototype.createline = function(self,canvas){
var content = canvas.ctx;
content.clearRect(0,0,canvas.canvas_w,canvas.canvas_h);
for(var i = 0 ; i < self.lines.length ; i++){
content.beginPath();
content.moveTo(self.lines[i].mx,self.lines[i].my);
//线经过的转折点或结束点
content.lineTo(self.lines[i].lx,self.lines[i].ly);
//线条宽度
content.lineWidth = canvas.line_w;
content.strokeStyle = canvas.color;
content.stroke();
//线条颜色
content.closePath();
//画线
}
}
//改变数据 水平运动
Createline.prototype.updateline_w = function(self,canvas){
for (var i = 0 ; i < self.lines.length ; i++) {
self.lines[i].mx = self.lines[i].mx + self.lines[i].vx;
self.lines[i].lx = self.lines[i].lx + self.lines[i].vx;
}
//超出画布的线条从数组内删除,减少系统消耗
var cnt = [];
for (var j = 0 ;j < self.lines.length ; j++) {
if(self.lines[j].lx > canvas.canvas_w){
cnt.push(j);
}
}
for(var k = 0; k < cnt.length ; k++){
self.lines.splice(k,1);
}
}
//改变数据 垂直运动
Createline.prototype.updateline_h = function(self,canvas){
for (var i = 0 ; i < self.lines.length ; i++) {
self.lines[i].my = self.lines[i].my + lines[i].vy;
self.lines[i].ly = self.lines[i].ly + lines[i].vy;
}
//超出画布的线条从数组内删除,减少系统消耗
var cnt = [];
for (var j = 0 ;j < self.lines.length ; j++) {
if( self.lines[j].ly > canvas.canvas_h){
cnt.push(j);
}
}
for(var k = 0; k < cnt.length ; k++){
self.lines.splice(k,1);
}
}
//增加线
Createline.prototype.addline = function(self,canvas){
var length = self.lines.length;
//横线
if(canvas.fx == "w"){
//判断是否需要生成线
if(self.lines[length-1].lx > 0){
//起点位置 等于 左右一根线的坐标减去间隔
var ww = self.lines[length - 1].lx - canvas.jiange;
//判断长短
if(self.c == 0){
var jg = canvas.width;
self.c = 10;
}else{
var jg = canvas.width/2;
self.c = 0;
}
var lxx = ww - jg;
var data = {
mx:ww,
lx:lxx,
my:canvas.my,
ly:canvas.ly,
vx:canvas.vx,
vy:canvas.vy,
}
self.lines.push(data);
}
}
//垂直
if(canvas.fx == "h"){
if(length>0){
//判断是否需要生成线
if(self.lines[length-1].ly > 0){
//起点位置 等于 左右一根线的坐标减去间隔
var my = self.lines[length - 1].ly - canvas.jiange;
//判断长短
if(c == 0){
var jg = canvas.width;
c = 10;
}else{
var jg = canvas.width/2;
c = 0;
}
var ly = my - jg;
var data = {
mx:canvas.mx,
lx:canvas.lx,
my:my,
ly:ly,
vx:canvas.vx,
vy:canvas.vy,
}
self.lines.push(data);
}
}else{
var data = {
mx:canvas.mx,
my:canvas.my,
lx:canvas.lx,
ly:canvas.ly,
vx:canvas.vx,
vy:canvas.vy,
}
self.lines.push(data);
}
}
}
export{
Createline
}
You need to use new when creating a instance for a constructor that uses this:
var cre = new Createline(data);
When a function is executed using new it does the following:
function User(name) {
// this = {}; (implicitly)
// add properties to this
this.name = name;
this.isAdmin = false;
// return this; (implicitly)
}
I am trying to sum the ranged values but for some reason it's not summing. Any idea why?
I am not a very good in JavaScript but I have some knowledge...
function bag(input) {
var sheet = SpreadsheetApp.getActiveSpreadsheet()
var AllValues = sheet.getRange(input).getValues();
var FValue = "";
var TotalGold = 0;
var TotalSilver = 0;
var TotalBronze = 0;
for(i = 0; i < AllValues.length; i++) {
var total = AllValues[i][0].split(" ");
for(i = 0; i < total.length; i++){
if (total[i].indexOf("g") >= 0) {
var value = total[i].replace("g","");
var gold = value * 1;
TotalGold = TotalGold + gold;
}
else if (total[i].indexOf("s") >= 0) {
var value = total[i].replace("s","");
var silver = value * 1;
TotalSilver = TotalSilver + silver;
}
else if (total[i].indexOf("b") >= 0) {
var value = total[i].replace("b","");
var bronze = value * 1;
TotalBronze = TotalBronze + bronze;
}
else {
return null;
}
}
}
return TotalGold + "g " + TotalSilver + "s " + TotalBronze + "b";
}
It appears you are overwriting your value of i in the nested iteration. Pick another identifier. E.g: for (var j = 0; j < total.length; j++) { ... }
I am getting an error saying Arc is not a constructor. I have checked my code and can't understand why.
/*
Exception: Arc is not a constructor
RouteFinder/this.getPairs#Scratchpad/8:72:6
#Scratchpad/8:5:3
*/
The other answers for this error suggest that this because Arc has previously been defined, but I cant find anywhere that it is. This is a big chunk of code, so scroll down for the error - it is commented where it is
var lats = [ 51.445371, 51.45526, 51.426765, 51.441304 ]
var lons = [ -0.077581, -0.113248, -0.13091, -0.060596 ]
var finder = new RouteFinder(lats, lons);
finder.getPairs();
var nodeList = ''
for(var count = 1; count < lats.length; count++) {
nodeList += count;
}
finder.permutation("", nodeList);
finder.removeDuplicateRoutes();
var shortestRoute = finder.getShortestRoute();
var finalRouteOrder = [];
shortestRoute.nodeList.forEach(function(node) {
finalRouteOrder.push(+node);
});
alert(finalRouteOrder);
var Route = function() {
this.totalWeight = 0;
this.nodeList = [];
};
var Node = function() {
this.lat = 0;
this.lon = 0;
this.number = 0;
};
var Arc = function() {
this.startNode = new Node();
this.endNode = new Node();
this.weight = 0;
};
function reverseString(initialString) {
var reversed = '';
for(var count = initialString.length -1; count > -1; count--) {
reversed += initialString.charAt(count);
}
return reversed;
}
function calcDistance(lat1, lng1, lat2, lng2) {
var earthRadius = 6371;
var dLat = (lat2 - lat1)/180*Math.PI;
var dLng = (lng2 - lng1)/180*Math.PI;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1/180*Math.PI) * Math.cos(lat2/180*Math.PI) * Math.sin(dLng/2) * Math.sin(dLng/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var dist = earthRadius * c;
return dist;
}
function RouteFinder(lats, lons) {
this.latArray = lats;
this.lonArray = lons;
this.orders = [];
this.arcArray = [];
this.routes = [];
this.shortestRoute;
this.numOfPoints = lats.length - 1;
this.shortestRouteLength = -1;
this.getPairs = function() {
var timesLooped = 0;
for(var count1 = 0; count1 < this.numOfPoints; count1++) {
for(var count2 = 0; count2 < (this.numOfPoints - count1); count2++) {
//I get an error here for new Arc()
this.arcArray.push(new Arc());
this.arcArray[timesLooped].startNode = {
number: count1,
};
this.arcArray[timesLooped].endNode = {
number: this.numOfPoints - count2,
};
this.arcArray[timesLooped].weight = calcDistance(this.latArray[count1], this.lonArray[count1], this.latArray[this.numOfPoints - count2], this.lonArray[this.numOfPoints - count2]);
timesLooped++;
}
}
};
this.permutation = function(prefix, str) {
var n = str.length;
if(n === 0) this.orders.push('0' + prefix + '0');
else {
for(var i = 0; i <n; i++) {
this.permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n));
}
}
};
this.removeDuplicateRoutes = function() {
var numberOfPermutations = this.orders.length -1;
var temp;
var size;
var toRemove = [];
for(var count1 = 0; count1 < numberOfPermutations; count1++) {
for(var count2 = 0; count2 < (numberOfPermutations - count1); count2++) {
if(this.orders[count1] == reverseString(this.orders[numberOfPermutations - count2])) {
toRemove.push(count1);
}
}
}
size = toRemove.length;
for(var count3 = 0; count3 < size; count3++) {
temp = toRemove[size - 1- count3];
var index = this.orders.indexOf(temp);
if(index > -1) {
temp.splice(index, 1);
}
}
};
this.getShortestRoute = function() {
var routesMade = 0;
for(var routeNumber = 0; routeNumber < (this.orders.length -1); routeNumber++) {
this.routes.push(new Route());
this.routes[routesMade].totalWeight = 0;
for(var count1 = 0; count1 < this.orders[routeNumber].length; count1++) {
this.routes[routesMade].nodeList.push(+this.orders[routeNumber].charAt(count1));
}
for(var count2 = 1; count2 < this.orders[routeNumber].length; count2++) {
for(var count3 = 0; count3 < this.arcArray.length; count3++) {
if(this.routes[routesMade].nodeList[count2 - 1] === this.arcArray[count3].startNode.number) {
if(this.routes[routesMade].nodeList[count2] === this.arcArray[count3].endNode.number) {
this.routes[routesMade].totalWeight += this.arcArray[count3].weight;
}
} else if (this.routes[routesMade].nodeList[count2 - 1] === this.arcArray[count3].endNode.number) {
if(this.routes[routesMade].nodeList[count2] === this.arcArray[count3].startNode.number) {
this.routes[routesMade].totalWeight += this.arcArray[count3].weight;
}
}
}
}
if(!this.shortestRoute) {
this.shortestRoute = this.routes[routesMade];
} else if(this.routes[routesMade].totalWeight < this.shortestRoute.totalWeight) {
this.shortestRoute = this.routes[routesMade];
}
routesMade++;
}
return this.shortestRoute;
};
}
I'm tearing my hair out trying to work out the problem. Help is greatly appreciated, thanks!
This
var finder = new RouteFinder(lats, lons);
gets executed before Arc variable gets its value (function). Thus at the moment of RouteFinder call that Arc variable is undefined and cannot be used as a constructor.
Update: it is about finder.getPairs(); actually where you try to call that new Arc();
You need to have Route, Node, and Arc like this:
function Route() {
this.totalWeight = 0;
this.nodeList = [];
}
function Node() {
this.lat = 0;
this.lon = 0;
this.number = 0;
}
function Arc() {
this.startNode = new Node();
this.endNode = new Node();
this.weight = 0;
}
The issue is that Arc is not yet defined. Either move your function expression assignment (var Arc = function ...) to the top of your script or convert them to function definition statements like this
function Arc() {
this.startNode = new Node();
this.endNode = new Node();
this.weight = 0;
}
Statements are hoisted and their order does not matter, but assignment to var happens in the order they appear in the file (the declaration is hoisted, but the assignment isn't).
Same goes for your Route and Node functions.
Read more about var hoisting on MDN.