Categories
discuss

How can I fill enclosed shapes in a line?

I’ve used a html canvas to create this line:

a squiggly line, which loops over itself in some places to create enclosed circle and balloon shapes

I want the loops in the line filled, so that it looks like this:

the enclosed shapes are filled in with red

However when I fill this it simply turns into:

the beginning and end of the line have been invisibly connected, and the whole area filled in, enclosed shapes included

I did try using paths, it was the exact same result, just with a line connecting the start to finish.

Abstraction of code:

var canvas = $("canvas")[0], ctx=canvas.getContext("2d");
ctx.moveto(0,0);
// code to stroke path of mouse cursor;

How can I get my desired result and fill in just the enclosed shapes in the line?

Answer

Updated

The problem is as Brett points out that fill() will implicitly close the path. There is nothing we can do about this using the API so we need to use a manual approach to fill the loops as separate closed paths.

Finding intersections

This algorithm does the following (have not checked for cases where these loops might overlap, but it should get you started). It can also be rewritten to do this in real-time while moving the mouse.

  • We can iterate over all segments in the path. Compare each segment to all the others, but from current + two as the end-point of current segment would otherwise self-intersect with start point of next segment.
  • If an intersection is found:
    • Build a path from the intersection point then add points using the segments between first and last intersecting line

Example

result

var points = [49,40,49,41,49,42,49,43,49,45,49,48,49,50,49,53,49,56,49,59,49,63,49,67,49,72,50,77,51,82,53,88,53,91,55,96,58,99,60,104,62,106,64,109,65,113,68,116,70,118,72,120,74,121,76,124,78,125,81,126,87,129,92,130,98,133,104,134,109,135,113,135,117,135,121,135,127,135,131,135,135,135,141,132,148,128,153,126,159,122,161,120,164,118,164,116,165,112,165,110,165,107,165,105,165,104,165,101,165,100,164,96,163,94,162,93,160,91,159,90,158,88,157,88,156,88,154,88,151,88,147,88,141,90,135,92,130,94,126,96,121,99,118,101,114,104,111,108,108,110,107,113,104,117,103,120,100,125,99,129,96,135,95,139,95,144,95,148,95,152,95,155,95,158,96,162,97,166,99,170,102,173,106,177,109,181,111,182,113,184,115,185,117,186,119,186,121,186,124,186,127,186,132,185,135,183,141,179,146,175,152,172,158,168,165,165,172,162,178,159,185,158,191,157,195,156,199,156,202,156,206,156,209,156,212,157,216,160,220,163,221,168,224,170,224,173,225,177,227,182,228,186,229,192,229,197,230,203,230,208,230,212,230,219,230,225,230,230,228,236,226,240,221,246,217,251,214,255,210,257,204,260,199,260,194,261,189,261,184,261,181,261,177,261,175,261,173,260,173,256,171,252,170,245,170,237,169,231,168,226,168,221,168,218,168,215,168,212,168,211,169,207,172,205,175,201,180,199,187,198,194,196,201,194,208,194,214,194,221,194,225,194,230,195,235,196,240,199,245,202,247,204,251,207,253,210,254,214,255,216,259,223,263,229,266,235,270,241,273,245,277,253,279,257,283,262,287,269,292,274,297,280,302,285,308,290,314,294,321,295,327,296,336,298,343,298,352,298,359,298,367,292,374,286,379,278,381,269,381,262,381,254,381,246,381,241,379,232,377,229,372,224,369,221,364,219,361,219,355,218,347,218,339,218,330,218,320,221,310,228,300,235,290,242,282,249,276,257,271,263,269,269,267,276,266,281,266,287,266,291,267,297,272,305,279,312,286,319,296,327,305,332,316,338,325,341,333,344,340,348,342,348,344,349,345,349,345,350,346,351,347,353,347,355,347,356,347,358,347,361,347,363,347,366,347,370,347,374,344,379,343,384,342,393,339,400,335,406,331,414,323,421,317,426,310,430,302,435,295,437],
    ctx = c.getContext("2d"),
    i, y, ip, t, l = points.length;

// compare each segments
for(i = 0; i < points.length - 4; i += 2) {
  for(y = i + 4; y < points.length - 2; y += 2) {
    
    ip = intersection(points[i], points[i+1], points[i+2], points[i+3],
                      points[y], points[y+1], points[y+2], points[y+3]);
    
    // any intersction? create a sub-path with segments between the intersecting lines
    if (ip) {
      ctx.moveTo(ip.x, ip.y);
      for(t = i + 2; t < y; t += 2) ctx.lineTo(points[t], points[t+1]);
    }
  } 
}

// fill all sub-paths at once
ctx.fillStyle = "red";
ctx.fill();

// stroke path itself
ctx.beginPath();
ctx.moveTo(points[0], points[1]);
for(i = 0; i < l; i += 2) ctx.lineTo(points[i], points[i+1]);
ctx.stroke();

function intersection(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) {

  var d1x = p1x - p0x, d1y = p1y - p0y,
      d2x = p3x - p2x, d2y = p3y - p2y,
      d = d1x * d2y - d2x * d1y,
      px, py, s, t;

    if (d) {
      px = p0x - p2x;
      py = p0y - p2y;
      s = (d1x * py - d1y * px) / d;
      if (s >= 0 && s <= 1) {
        t = (d2x * py - d2y * px) / d;
        if (t >= 0 && t <= 1) return {x: p0x + (t * d1x), y: p0y + (t * d1y)};
      }
    }
    return null
}
<canvas id=c width=500 height=500></canvas>
Categories
discuss

How to avoid “incompatible parameter types in lambda expression” when adding to an ArrayList?

I have the following code

public static List<Integer> topKFrequent(int[] nums, int k) {
  List<Integer> myList = new ArrayList<>();
  HashMap<Integer, Integer> map = new HashMap<>();

  for (int n : nums) {
    if (!map.containsKey(n)) map.put(n, 1);
    else map.put(n, map.get(n) + 1);
  }

  map.entrySet().stream()
    .sorted(Map.Entry.<Integer, Integer>comparingByValue().reversed())
    .limit(k)
    .forEach((key, value) -> myList.add(key));

  return myList;
}

The forEach throws the error

Error:(20, 16) java: incompatible types: incompatible parameter types in lambda expression

How can I fix/avoid this error? I’m not quite sure how to apply the answer here that explains the problem: Lambda Expression and generic method

Edit:

Given the answer, the correction is to replace the lambda inside the forEach with

.forEach((entry) -> myList.add(entry.getKey()));

Answer

You are going about it in a java7-ish way. Modifying external data structures from inside forEach is not how Streams API was meant to be used. Streams API documentation specifically warns against such use in the Side-Effects section of java.util.stream package summary

Instead of appending to list or map from inside forEach, use collect:

import static java.util.Comparator.reverseOrder;
import static java.util.Map.Entry.comparingByValue;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;


public static List<Integer> topKFrequent(int[] nums, int k) {
    Map<Integer, Long> freq = Arrays.stream(nums).boxed()
            .collect(groupingBy(x->x, counting()));

    return freq.entrySet()
            .stream()
            .sorted(comparingByValue(reverseOrder()))
            .limit(k)
            .map(Map.Entry::getKey)
            .collect(toList());
}
Categories
discuss

Spring Data: Not an managed type: class java.lang.Object

I am trying to expose my db tables via spring boot by following different spring tutorials and I am running into following exception (I will post exception at the end).

Here are the classes that I am using

package com.xxx.xxx.db;

import org.springframework.data.repository.Repository;

import java.io.Serializable;

public interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID>{
  T findOne(ID id);
  T save(T entity);
}

And here is my specific service class

package com.xxx.xxx.tablename;

import com.xxx.xxx.db.BaseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TableNameService {

  @Autowired
  private BaseRepository<TableName, Long> repository;

  public TableName findById(Long id){
    return repository.findOne(id);
  }
}

and here is my entity

package com.xxx.xxx.tablename;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Getter
@Setter
@Entity
@Table(name="table_name")
public class TableName {

  @Id
  private long id;

  @NotNull
  private String name;

  public TableName() {
  }

  public TableName(long id){
    this.id = id;
  }

  public TableName(String name){
    this.name = name;
  }

  public TableName(long id, String name){
    this.id = id;
    this.name = name;
  }
}

My spring configurations are being done by application.yml file. The file currently have only database connection informaiton and nothing more than that

I also have a class named BeansConfig which is annotated by @Configuration. But this class is being used to validate if db properties which are being provided by application.yml are valid.

And now here is the exception

springframework.beans.factory.BeanCreationException: Error creating bean with name 'TableNameService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.xxx.db.BaseRepository com.xxx.xxx.tablename.TableNameService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766)
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180)
    at com.xxx.xxx.Application.main(Application.java:12)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.xxx.db.BaseRepository com.xxx.xxx.tablename.TableNameService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 17 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:545)
    ... 19 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object
    at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:219)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:67)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:152)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:99)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:81)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:185)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    ... 29 common frames omitted

Answer

That’s not possible the way you are trying. Since T needs to be an Entity, you need to type-restrict it. One option would be to make one repository per concrete Entity, but here you have a more generic way of implementing it:

Use a BaseClass for your entities:

@Entity
public abstract class BaseClass<IdType extends Serializable>{

    private IdType id;

    //Getter and setters

}

Define a @Repository for your base class:

@Repository
public interface Dao<T extends BaseClass, IdType extends Serializable> extends
        CrudRepository<T, IdType> {

}

You can define the shared entity operations in this interface and inherit from them for more concrete ones in the cases demanding it.

See also:

Categories
discuss

Iterator and a Generator in Javascript?

On Mozilla’s page iterators and generators there is a statement:

While custom iterators are a useful tool, their creation requires careful programming due to the need to explicitly maintain their internal state. Generators provide a powerful alternative: they allow you to define an iterative algorithm by writing a single function which can maintain its own state.

Regarding above explanation, isn’t it possible to write an iterative algorithm without Generators, such as:

Array[Symbol.iterator] = function(){
    return {
        next: function(){
            //logic
            return {
                value: "",
                done:false
            }
        }
    }
}

Can’t get my head around. Could someone explain what is the main reason they created an alternative, seems not much different to me.

Answer

They might look pretty similar on the surface, but they can be used in very different ways.

Iterators and Iterables

Iterators are rather strictly defined: they are object (the iterators) which contains a next (and possibly a few other) function. Every time the next function is called, it is expected to return an object with two properties:

  • value: the current value of the iterator
  • done: is the iterator finished?

An iterable on the other hand is an object which has a property with a Symbol.iterator key (which represents the well know symbol @@iterator). That key contains a function, which when called, returns a new iterator. An example of an iterable:

const list = {
    entries: { 0: 'a', 1: 'b' },
    [Symbol.iterator]: function(){
        let counter = 0;
        const entries = this.entries;
        return {
            next: function(){
                return {
                    value: entries[counter],
                    done: !entries.hasOwnProperty(counter++)
                }
            }
        }
    }
};

Their main purpose, as their name suggests, is to provide an interface which can be iterated:

for (let item of list) { console.log(item); }
// 'a'
// 'b'

Generators

Generators on the other hand are much more versatile. It helps to think of them as functions which can be paused and resumed.

While they can be iterated (their iterables provide a next method), they can implement much more sophisticated procedures and provide a input/output communication through their next method.

A simple generator:

function *mygen () {
   var myVal = yield 12;
   return myVal * 2;
}

const myIt = mygen();

const firstGenValue = myIt.next().value;
// Generator is paused and yields the first value

const result = myIt.next(firstGenValue * 2).value;

console.log(result); // 48

Generator delegation

Generators can delegate to another generator:

function *mydelgen(val) {
    yield val * 2;
}

function *mygen () {
    var myVal = yield 12;
    yield* mydelgen(myVal); // delegate to another generator
}

const myIt = mygen();
const val = myIt.next().value;
console.log(val);
console.log(myIt.next(val).value);
console.log(myIt.next().value);

Generators & Promises

Generators and Promises together can create a sort of automatic asynchronous iterator with the help of utilities such as co.

co(function *(){
  // resolve multiple promises in parallel
  var a = Promise.resolve(1);
  var b = Promise.resolve(2);
  var c = Promise.resolve(3);
  var res = yield [a, b, c];
  console.log(res);
  // => [1, 2, 3]
}).catch(onerror);

In Conclusion

So in conclusion one could say that the main purpose of iterators is to create an interface for custom objects to be iterated, whereas generators provide a plethora of possibilities for synchronous and asynchronous workflows:

  • stateful functions
  • generator delegation
  • generators & promises
  • CSP

etc.

Categories
discuss

Cannot create Android emulator for Android 4.03 (API Level 15)

I have installed all the packages but the emulator for 4.0.3 (api level 15) in Android Studio (version 2.1) not appear. It is supported?

As you can see in the images, all is installed for api level 15.

SDK packages for API 15

ARM

X86

Answer

From the command line!

List All System Images Available For Download:

sdkmanager --list | grep system-images

Download System Image:

sdkmanager --install "system-images;android-15;default;x86"

Create the Emulator

echo "no" | avdmanager --verbose create avd --force --name "NAME_OF_EMULATOR" --package "system-images;android-15;default;x86" --tag "default" --abi "x86"

Run the Emulator

emulator @NAME_OF_EMULATOR -skin 768x1280 &

Gist with more information:

Install and Create Emulators using AVDMANAGER and SDKMANAGER

Emulator running 4.0.3

Finally, add the following to ~/.android/avd/generic_10.avd/config.ini to make sure it starts with an appropriate resolution and typing with your Laptop Keyboard is enabled. (This will make it so you don’t have ot type -skin 768×1280 when starting the emulator.

skin.name=1080x1920
hw.lcd.density=480
hw.keyboard=yes
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..